use std::fmt::Display;
use leptos::prelude::*;
use crate::{components::Description, Name};
use strum::VariantArray;
#[component]
pub fn Select<T>(
#[prop(into)] label: TextProp,
#[prop(into, default = None)] description: Option<TextProp>,
name: Name,
value: RwSignal<T>,
) -> impl IntoView
where
T: Clone
+ Copy
+ Into<&'static str>
+ VariantArray
+ PartialEq
+ Display
+ Send
+ Sync
+ 'static,
{
view! {
<div class="field select-field">
<label for=name.to_string()>{label.get()}</label>
<select
name=name.to_string()
id=name.to_string()
on:change=move |ev| {
let selected_value = event_target_value(&ev);
if let Some(&option) = T::VARIANTS.iter().find(|&&variant| {
let variant_str: &'static str = variant.into();
variant_str == selected_value
}) {
value.set(option);
}
}
>
{ T::VARIANTS.iter().map(move |&option| {
let option_value: &'static str = option.into();
let is_selected = move || value.get() == option;
view! {
<option
value=option_value
selected=is_selected
>
{format!("{}", option)}
</option>
}
}).collect::<Vec<_>>() }
<Description description={description} />
</select>
</div>
}
}