feat: reorganize and add single selection to chip lists
This commit is contained in:
1 parent
105e6b3e55
commit
8d9faf126d
6 files changed
+214
-61
No files matched your search
@@ -8,8 +8,8 @@ pub fn ActionButton(
|
||||
) -> impl IntoView {
|
||||
view! {
|
||||
<button
|
||||
class="m-1.5 p-2.5 rounded-lg font-semibold text-white transition-all duration-400"
|
||||
class=(["bg-red-700", "hover:bg-red-800"], move || !disabled.get())
|
||||
class="m-1.5 p-2.5 rounded-lg font-semibold text-white transition-all duration-400 cursor-pointer"
|
||||
class=(["bg-red-800", "hover:bg-red-900"], move || !disabled.get())
|
||||
class=(["bg-gray-600", "pointer-events-none"], move || disabled.get())
|
||||
r#type=button_type
|
||||
disabled=move || disabled.get()
|
||||
|
||||
@@ -70,13 +70,22 @@ pub fn Chip(
|
||||
/// passed to the `on_change` prop for each individual `Chip` component.
|
||||
#[component]
|
||||
pub fn ChipsList(
|
||||
/// The member in the data map that this input affects.
|
||||
#[prop(into)] data_member: String,
|
||||
/// The data map that contains the list of values. This will be edited as the input changes.
|
||||
#[prop()] data_map: RwSignal<HashMap<String, ValueType>>,
|
||||
/// The list of strings that should be displayed in the list.
|
||||
#[prop(into)] displayed_text: Signal<Vec<String>>,
|
||||
/// The list of values that should be displayed in the list.
|
||||
#[prop(into)] values: Signal<Vec<String>>,
|
||||
/// Indicates if the input should be disabled.
|
||||
#[prop(optional, into)] disabled: Signal<bool>,
|
||||
/// The label for the header of the input.
|
||||
#[prop(optional, into)] label: String,
|
||||
#[prop(optional, into)] required: Signal<bool>
|
||||
/// Indicates if this input is required.
|
||||
#[prop(optional, into)] required: Signal<bool>,
|
||||
/// Determines if this list behaves like a checkbox or radio list.
|
||||
#[prop(default = true.into(), into)] allows_multiple: Signal<bool>,
|
||||
) -> impl IntoView {
|
||||
let controller = use_selectable_list(
|
||||
data_member.clone(),
|
||||
@@ -88,41 +97,49 @@ pub fn ChipsList(
|
||||
<div class="flex flex-col">
|
||||
<div class="m-1.5 mt-0 mb-0">
|
||||
<span class="font-bold">{label}</span>
|
||||
{displayed_text.get().into_iter().zip(values.get())
|
||||
.into_iter()
|
||||
.map(|(text, value)| {
|
||||
let value = RwSignal::new(value);
|
||||
<div class="flex flex-row flex-wrap gap-2 mb-1">
|
||||
{move || displayed_text.get().into_iter().zip(values.get())
|
||||
.into_iter()
|
||||
.map(|(text, value)| {
|
||||
let value = RwSignal::new(value);
|
||||
|
||||
let checked = Signal::derive(move || {
|
||||
controller.selected_list.get().contains(&value.get())
|
||||
});
|
||||
|
||||
let on_change = move || {
|
||||
// Update the data list by checking if the value is present in it. If so,
|
||||
// remove it. If not, add it.
|
||||
controller.selected_list.update(|list| {
|
||||
let value = value.get();
|
||||
if list.contains(&value) {
|
||||
list.retain(|val| *val != value);
|
||||
} else {
|
||||
list.push(value.clone());
|
||||
}
|
||||
let checked = Signal::derive(move || {
|
||||
controller.selected_list.get().contains(&value.get())
|
||||
});
|
||||
controller.dirty.set(true);
|
||||
};
|
||||
|
||||
view! {
|
||||
<Chip
|
||||
checked=checked
|
||||
on_change=on_change
|
||||
value=value
|
||||
display_text=text
|
||||
name=data_member.clone()
|
||||
disabled=disabled
|
||||
/>
|
||||
}
|
||||
})
|
||||
.collect_view()}
|
||||
let on_change = move || {
|
||||
// Update the data list by checking if the value is present in it. If so,
|
||||
// remove it. If not, add it.
|
||||
let value = value.get();
|
||||
let list = controller.selected_list.get();
|
||||
|
||||
if list.contains(&value) {
|
||||
allows_multiple.get()
|
||||
.then(|| controller.selected_list.update(|list| list.retain(|v| v != &value)))
|
||||
.or_else(|| Some(controller.selected_list.set(Vec::new())));
|
||||
} else {
|
||||
allows_multiple.get()
|
||||
.then(|| controller.selected_list.update(|list| list.push(value.clone())))
|
||||
.or_else(|| Some(controller.selected_list.set(vec![value.clone()])));
|
||||
}
|
||||
|
||||
controller.dirty.set(true);
|
||||
};
|
||||
|
||||
view! {
|
||||
<Chip
|
||||
checked=checked
|
||||
on_change=on_change
|
||||
value=value
|
||||
display_text=text
|
||||
name=data_member.clone()
|
||||
disabled=disabled
|
||||
/>
|
||||
}
|
||||
})
|
||||
.collect_view()
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<Show when=move || controller.show_errors.get()>
|
||||
<div class="text-red-600 text-sm mr-1.5 ml-1.5">
|
||||
|
||||
@@ -98,7 +98,7 @@ pub fn Select(
|
||||
value=""
|
||||
disabled
|
||||
hidden
|
||||
selected=raw_value.get().is_empty()
|
||||
selected={move || raw_value.get().is_empty()}
|
||||
>"Select one..."</option>
|
||||
{move || {
|
||||
value_list.iter().map(
|
||||
|
||||
Reference in new issue
Block a user