use crate::{mount_style, teleport::Teleport, utils::maybe_rw_signal::MaybeRwSignal, Input}; use leptos::*; #[derive(Clone, PartialEq)] pub struct AutoCompleteOption { pub label: String, pub value: String, } #[component] pub fn AutoComplete( #[prop(optional, into)] value: MaybeRwSignal, #[prop(optional, into)] placeholder: MaybeSignal, #[prop(optional, into)] options: MaybeSignal>, ) -> impl IntoView { mount_style("auto-complete", include_str!("./auto-complete.css")); let is_show_menu = create_rw_signal(false); let auto_complete_ref = create_node_ref::(); let auto_complete_menu_ref = create_node_ref::(); let show_menu = move || { is_show_menu.set(true); let rect = auto_complete_ref .get_untracked() .unwrap() .get_bounding_client_rect(); let auto_complete_menu = auto_complete_menu_ref.get_untracked().unwrap(); auto_complete_menu .style("width", format!("{}px", rect.width())) .style( "transform", format!( "translateX({}px) translateY({}px)", rect.x(), rect.y() + rect.height() ), ); }; let allow_value = move |_| { if !is_show_menu.get_untracked() { show_menu(); } true }; view! {
{move || { options .get() .into_iter() .map(|v| { let AutoCompleteOption { value: option_value, label } = v; let on_click = move |_| { value.set(option_value.clone()); is_show_menu.set(false); }; let on_mousedown = move |ev: ev::MouseEvent| { ev.prevent_default(); }; view! {
{label}
} }) .collect_view() }}
} }