feat: auto complete component add clear after select

This commit is contained in:
luoxiao 2023-11-08 21:53:49 +08:00
parent d2ff826ca7
commit d6730d0e23
3 changed files with 39 additions and 14 deletions

View file

@ -69,6 +69,10 @@ pub fn SiteHeader() -> impl IntoView {
.collect()
})
});
let on_search_select = move |path: String| {
let navigate = use_navigate();
navigate(&path, Default::default());
};
view! {
<LayoutHeader style>
<Space>
@ -85,7 +89,13 @@ pub fn SiteHeader() -> impl IntoView {
</div>
</Space>
<Space>
<AutoComplete value=search_value placeholder="Search" options=search_options/>
<AutoComplete
value=search_value
placeholder="Search"
options=search_options
clear_after_select=true
on_select=on_search_select
/>
<Button
variant=ButtonVariant::Text
on:click=move |_| {

View file

@ -6,30 +6,31 @@ use thaw::*;
#[component]
pub fn ComponentsPage() -> impl IntoView {
let navigate = use_navigate();
let selected = create_rw_signal({
let loaction = use_location();
let mut pathname = loaction.pathname.get_untracked();
if pathname.starts_with("/thaw/components/") {
let select_name = create_rw_signal(String::new());
create_effect(move |_| {
let mut pathname = loaction.pathname.get();
let name = if pathname.starts_with("/thaw/components/") {
pathname.drain(17..).collect()
} else {
String::new()
}
};
select_name.set(name);
});
create_effect(move |value| {
let selected = selected.get();
if value.is_some() {
navigate(&format!("/components/{selected}"), Default::default());
_ = select_name.watch(move |name| {
let pathname = loaction.pathname.get_untracked();
if !pathname.starts_with(&format!("/thaw/components/{name}")) {
navigate(&format!("/components/{name}"), Default::default());
}
selected
});
view! {
<Layout position=LayoutPosition::Absolute>
<SiteHeader/>
<Layout has_sider=true position=LayoutPosition::Absolute style="top: 64px;">
<LayoutSider>
<Menu value=selected>
<Menu value=select_name>
{
gen_menu_data().into_view()
}

View file

@ -1,7 +1,11 @@
mod theme;
use crate::{
mount_style, teleport::Teleport, use_theme, utils::maybe_rw_signal::MaybeRwSignal, Input, Theme,
mount_style,
teleport::Teleport,
use_theme,
utils::{maybe_rw_signal::MaybeRwSignal, StoredMaybeSignal},
Input, Theme,
};
use leptos::*;
pub use theme::AutoCompleteTheme;
@ -17,6 +21,8 @@ pub fn AutoComplete(
#[prop(optional, into)] value: MaybeRwSignal<String>,
#[prop(optional, into)] placeholder: MaybeSignal<String>,
#[prop(optional, into)] options: MaybeSignal<Vec<AutoCompleteOption>>,
#[prop(optional, into)] clear_after_select: MaybeSignal<bool>,
#[prop(optional, into)] on_select: Option<Callback<String>>,
) -> impl IntoView {
mount_style("auto-complete", include_str!("./auto-complete.css"));
let theme = use_theme(Theme::light);
@ -38,6 +44,7 @@ pub fn AutoComplete(
let is_show_menu = create_rw_signal(false);
let auto_complete_ref = create_node_ref::<html::Div>();
let auto_complete_menu_ref = create_node_ref::<html::Div>();
let options = StoredMaybeSignal::from(options);
let show_menu = move || {
is_show_menu.set(true);
let rect = auto_complete_ref
@ -96,7 +103,14 @@ pub fn AutoComplete(
.map(|v| {
let AutoCompleteOption { value: option_value, label } = v;
let on_click = move |_| {
if clear_after_select.get_untracked() {
value.set(String::new());
} else {
value.set(option_value.clone());
}
if let Some(on_select) = on_select {
on_select.call(option_value.clone());
}
is_show_menu.set(false);
};
let on_mousedown = move |ev: ev::MouseEvent| {