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)
|
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! {
|
view! {
|
||||||
<LayoutHeader style>
|
<LayoutHeader style>
|
||||||
<Space>
|
<Space>
|
||||||
|
@ -42,6 +85,7 @@ pub fn SiteHeader() -> impl IntoView {
|
||||||
</div>
|
</div>
|
||||||
</Space>
|
</Space>
|
||||||
<Space>
|
<Space>
|
||||||
|
<AutoComplete value=search_value placeholder="Search" options=search_options/>
|
||||||
<Button
|
<Button
|
||||||
variant=ButtonVariant::Text
|
variant=ButtonVariant::Text
|
||||||
on:click=move |_| {
|
on:click=move |_| {
|
||||||
|
@ -81,3 +125,29 @@ pub fn SiteHeader() -> impl IntoView {
|
||||||
</LayoutHeader>
|
</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 {
|
pub(crate) struct MenuGroupOption {
|
||||||
label: String,
|
pub label: String,
|
||||||
children: Vec<MenuItemOption>,
|
pub children: Vec<MenuItemOption>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoView for MenuGroupOption {
|
impl IntoView for MenuGroupOption {
|
||||||
|
@ -61,9 +61,9 @@ impl IntoView for MenuGroupOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MenuItemOption {
|
pub(crate) struct MenuItemOption {
|
||||||
label: String,
|
pub label: String,
|
||||||
value: String,
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoView for MenuItemOption {
|
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![
|
vec![
|
||||||
MenuGroupOption {
|
MenuGroupOption {
|
||||||
label: "Common Components".into(),
|
label: "Common Components".into(),
|
||||||
|
|
|
@ -36,7 +36,7 @@ pub fn GuidePage() -> impl IntoView {
|
||||||
<LayoutSider>
|
<LayoutSider>
|
||||||
<Menu value=selected>
|
<Menu value=selected>
|
||||||
{
|
{
|
||||||
gen_menu_data().into_view()
|
gen_guide_menu_data().into_view()
|
||||||
}
|
}
|
||||||
</Menu>
|
</Menu>
|
||||||
</LayoutSider>
|
</LayoutSider>
|
||||||
|
@ -48,9 +48,9 @@ pub fn GuidePage() -> impl IntoView {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MenuGroupOption {
|
pub(crate) struct MenuGroupOption {
|
||||||
label: String,
|
pub label: String,
|
||||||
children: Vec<MenuItemOption>,
|
pub children: Vec<MenuItemOption>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoView for MenuGroupOption {
|
impl IntoView for MenuGroupOption {
|
||||||
|
@ -66,9 +66,9 @@ impl IntoView for MenuGroupOption {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct MenuItemOption {
|
pub(crate) struct MenuItemOption {
|
||||||
label: String,
|
pub label: String,
|
||||||
value: String,
|
pub value: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IntoView for MenuItemOption {
|
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 {
|
vec![MenuGroupOption {
|
||||||
label: "Getting Started".into(),
|
label: "Getting Started".into(),
|
||||||
children: vec![
|
children: vec![
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12),
|
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);
|
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;
|
z-index: 2000;
|
||||||
}
|
}
|
||||||
.thaw-auto-complete__menu-item {
|
.thaw-auto-complete__menu-item {
|
||||||
|
|
Loading…
Add table
Reference in a new issue