mirror of
https://github.com/adoyle0/thaw.git
synced 2025-02-02 08:34:15 -05:00
feat: site_header add search
This commit is contained in:
parent
f59928fdb2
commit
d2ff826ca7
4 changed files with 86 additions and 15 deletions
|
@ -26,6 +26,49 @@ pub fn SiteHeader() -> impl IntoView {
|
|||
format!("height: 64px; display: flex; align-items: center; justify-content: space-between; padding: 0 20px; border-bottom: 1px solid {}", theme.common.border_color)
|
||||
})
|
||||
});
|
||||
let search_value = create_rw_signal(String::new());
|
||||
let search_all_options = store_value(gen_search_all_options());
|
||||
let search_options = create_memo(move |_| {
|
||||
let search_value = search_value.get();
|
||||
if search_value.is_empty() {
|
||||
return vec![];
|
||||
}
|
||||
fn match_value(pattern: &str, value: String) -> bool {
|
||||
if pattern.is_empty() {
|
||||
return true;
|
||||
}
|
||||
if value.is_empty() {
|
||||
return false;
|
||||
}
|
||||
if pattern.chars().next() == value.chars().next() {
|
||||
return match_value(pattern.split_at(1).1, value.split_at(1).1.to_string());
|
||||
}
|
||||
match_value(pattern, value.split_at(1).1.to_string())
|
||||
}
|
||||
search_all_options.with_value(|options| {
|
||||
let search_value = search_value
|
||||
.to_lowercase()
|
||||
.replace(" ", "")
|
||||
.replace("-", "");
|
||||
let search_value = if search_value.len() > 20 {
|
||||
search_value.split_at(20).0
|
||||
} else {
|
||||
&search_value
|
||||
};
|
||||
options
|
||||
.iter()
|
||||
.filter(|option| {
|
||||
let label = option
|
||||
.label
|
||||
.to_lowercase()
|
||||
.replace(" ", "")
|
||||
.replace("-", "");
|
||||
match_value(search_value, label)
|
||||
})
|
||||
.cloned()
|
||||
.collect()
|
||||
})
|
||||
});
|
||||
view! {
|
||||
<LayoutHeader style>
|
||||
<Space>
|
||||
|
@ -42,6 +85,7 @@ pub fn SiteHeader() -> impl IntoView {
|
|||
</div>
|
||||
</Space>
|
||||
<Space>
|
||||
<AutoComplete value=search_value placeholder="Search" options=search_options/>
|
||||
<Button
|
||||
variant=ButtonVariant::Text
|
||||
on:click=move |_| {
|
||||
|
@ -81,3 +125,29 @@ pub fn SiteHeader() -> impl IntoView {
|
|||
</LayoutHeader>
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_search_all_options() -> Vec<AutoCompleteOption> {
|
||||
use crate::pages::{gen_guide_menu_data, gen_menu_data};
|
||||
let mut options: Vec<_> = gen_menu_data()
|
||||
.into_iter()
|
||||
.map(|group| {
|
||||
group.children.into_iter().map(|item| AutoCompleteOption {
|
||||
value: format!("/components/{}", item.value),
|
||||
label: item.label,
|
||||
})
|
||||
})
|
||||
.flatten()
|
||||
.collect();
|
||||
options.extend(
|
||||
gen_guide_menu_data()
|
||||
.into_iter()
|
||||
.map(|group| {
|
||||
group.children.into_iter().map(|item| AutoCompleteOption {
|
||||
value: format!("/guide/{}", item.value),
|
||||
label: item.label,
|
||||
})
|
||||
})
|
||||
.flatten(),
|
||||
);
|
||||
options
|
||||
}
|
||||
|
|
|
@ -43,9 +43,9 @@ pub fn ComponentsPage() -> impl IntoView {
|
|||
}
|
||||
}
|
||||
|
||||
struct MenuGroupOption {
|
||||
label: String,
|
||||
children: Vec<MenuItemOption>,
|
||||
pub(crate) struct MenuGroupOption {
|
||||
pub label: String,
|
||||
pub children: Vec<MenuItemOption>,
|
||||
}
|
||||
|
||||
impl IntoView for MenuGroupOption {
|
||||
|
@ -61,9 +61,9 @@ impl IntoView for MenuGroupOption {
|
|||
}
|
||||
}
|
||||
|
||||
struct MenuItemOption {
|
||||
label: String,
|
||||
value: String,
|
||||
pub(crate) struct MenuItemOption {
|
||||
pub label: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl IntoView for MenuItemOption {
|
||||
|
@ -75,7 +75,7 @@ impl IntoView for MenuItemOption {
|
|||
}
|
||||
}
|
||||
|
||||
fn gen_menu_data() -> Vec<MenuGroupOption> {
|
||||
pub(crate) fn gen_menu_data() -> Vec<MenuGroupOption> {
|
||||
vec![
|
||||
MenuGroupOption {
|
||||
label: "Common Components".into(),
|
||||
|
|
|
@ -36,7 +36,7 @@ pub fn GuidePage() -> impl IntoView {
|
|||
<LayoutSider>
|
||||
<Menu value=selected>
|
||||
{
|
||||
gen_menu_data().into_view()
|
||||
gen_guide_menu_data().into_view()
|
||||
}
|
||||
</Menu>
|
||||
</LayoutSider>
|
||||
|
@ -48,9 +48,9 @@ pub fn GuidePage() -> impl IntoView {
|
|||
}
|
||||
}
|
||||
|
||||
struct MenuGroupOption {
|
||||
label: String,
|
||||
children: Vec<MenuItemOption>,
|
||||
pub(crate) struct MenuGroupOption {
|
||||
pub label: String,
|
||||
pub children: Vec<MenuItemOption>,
|
||||
}
|
||||
|
||||
impl IntoView for MenuGroupOption {
|
||||
|
@ -66,9 +66,9 @@ impl IntoView for MenuGroupOption {
|
|||
}
|
||||
}
|
||||
|
||||
struct MenuItemOption {
|
||||
label: String,
|
||||
value: String,
|
||||
pub(crate) struct MenuItemOption {
|
||||
pub label: String,
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
impl IntoView for MenuItemOption {
|
||||
|
@ -80,7 +80,7 @@ impl IntoView for MenuItemOption {
|
|||
}
|
||||
}
|
||||
|
||||
fn gen_menu_data() -> Vec<MenuGroupOption> {
|
||||
pub(crate) fn gen_guide_menu_data() -> Vec<MenuGroupOption> {
|
||||
vec![MenuGroupOption {
|
||||
label: "Getting Started".into(),
|
||||
children: vec![
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
box-sizing: border-box;
|
||||
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
||||
0 6px 16px 0 rgba(0, 0, 0, 0.08), 0 9px 28px 8px rgba(0, 0, 0, 0.05);
|
||||
overflow: auto;
|
||||
z-index: 2000;
|
||||
}
|
||||
.thaw-auto-complete__menu-item {
|
||||
|
|
Loading…
Add table
Reference in a new issue