diff --git a/src/lib.rs b/src/lib.rs index 30c388b..09c7dc3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -10,6 +10,7 @@ mod menu; pub mod mobile; mod modal; mod progress; +mod select; mod slider; mod space; mod table; diff --git a/src/select/mod.rs b/src/select/mod.rs new file mode 100644 index 0000000..3431206 --- /dev/null +++ b/src/select/mod.rs @@ -0,0 +1,72 @@ +use crate::teleport::Teleport; +use leptos::*; +use std::hash::Hash; + +#[derive(Clone, PartialEq, Eq, Hash)] +pub struct SelectOption { + pub label: String, + pub value: T, +} + +#[component] +pub fn Select( + cx: Scope, + #[prop(into)] value: RwSignal>, + #[prop(optional, into)] options: MaybeSignal>>, +) -> impl IntoView +where + T: Eq + Hash + Clone + 'static, +{ + let is_show_popover = create_rw_signal(cx, false); + let trigger_ref = create_node_ref::(cx); + let popover_ref = create_node_ref::(cx); + let show_popover = move |_| { + let rect = trigger_ref.get().unwrap().get_bounding_client_rect(); + is_show_popover.set(true); + if let Some(popover_ref) = popover_ref.get() { + popover_ref + .style("width", format!("{}px", rect.width())) + .style( + "transform", + format!( + "translateX({}px) translateY({}px) translateX(-50%)", + rect.x() + rect.width() / 2.0, + rect.y() + rect.height() + ), + ); + } + }; + + let temp_options = options.clone(); + let select_option_label = create_memo(cx, move |_| match value.get() { + Some(value) => temp_options + .get() + .iter() + .find(move |v| v.value == value) + .map_or(String::new(), |v| v.label.clone()), + None => String::new(), + }); + view! { cx, +
+ { + move || select_option_label.get() + } +
+ +
+ + { item.label } +
+ } + } + > + + +
+ } +}