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() .collect()
}) })
}); });
let on_search_select = move |path: String| {
let navigate = use_navigate();
navigate(&path, Default::default());
};
view! { view! {
<LayoutHeader style> <LayoutHeader style>
<Space> <Space>
@ -85,7 +89,13 @@ pub fn SiteHeader() -> impl IntoView {
</div> </div>
</Space> </Space>
<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 <Button
variant=ButtonVariant::Text variant=ButtonVariant::Text
on:click=move |_| { on:click=move |_| {

View file

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

View file

@ -1,7 +1,11 @@
mod theme; mod theme;
use crate::{ 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::*; use leptos::*;
pub use theme::AutoCompleteTheme; pub use theme::AutoCompleteTheme;
@ -17,6 +21,8 @@ pub fn AutoComplete(
#[prop(optional, into)] value: MaybeRwSignal<String>, #[prop(optional, into)] value: MaybeRwSignal<String>,
#[prop(optional, into)] placeholder: MaybeSignal<String>, #[prop(optional, into)] placeholder: MaybeSignal<String>,
#[prop(optional, into)] options: MaybeSignal<Vec<AutoCompleteOption>>, #[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 { ) -> impl IntoView {
mount_style("auto-complete", include_str!("./auto-complete.css")); mount_style("auto-complete", include_str!("./auto-complete.css"));
let theme = use_theme(Theme::light); let theme = use_theme(Theme::light);
@ -38,6 +44,7 @@ pub fn AutoComplete(
let is_show_menu = create_rw_signal(false); let is_show_menu = create_rw_signal(false);
let auto_complete_ref = create_node_ref::<html::Div>(); let auto_complete_ref = create_node_ref::<html::Div>();
let auto_complete_menu_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 || { let show_menu = move || {
is_show_menu.set(true); is_show_menu.set(true);
let rect = auto_complete_ref let rect = auto_complete_ref
@ -96,7 +103,14 @@ pub fn AutoComplete(
.map(|v| { .map(|v| {
let AutoCompleteOption { value: option_value, label } = v; let AutoCompleteOption { value: option_value, label } = v;
let on_click = move |_| { let on_click = move |_| {
value.set(option_value.clone()); 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); is_show_menu.set(false);
}; };
let on_mousedown = move |ev: ev::MouseEvent| { let on_mousedown = move |ev: ev::MouseEvent| {