Fix checkbox/radio list button interference #24

Merged
BobdaFett merged 2 commits from fix/checkbox-interference into main 2025-11-23 22:14:28 +00:00
5 changed files with 28 additions and 9 deletions

No files matched your search

+8 -2
View File
@@ -1,16 +1,20 @@
use crate::common::ValueType;
use leptos::prelude::*;
use std::collections::HashMap;
use crate::components::utils::create_unique_id;
#[component]
pub fn Checkbox(
#[prop()] checked: Signal<bool>,
#[prop(into)] on_change: Callback<(), ()>,
#[prop(into)] value: String,
#[prop(into)] name: String,
#[prop(default = RwSignal::new(false))] disabled: RwSignal<bool>,
) -> impl IntoView {
let id = create_unique_id(&name, &value);
view! {
<label for=value class="flex items-center">
<label for=id class="flex items-center">
<input
// Using the "peer" class links this input with the div "peer" at the same level.
// By using the "peer-checked" selector this div can toggle states based on this
@@ -19,7 +23,8 @@ pub fn Checkbox(
relative peer shrink-0
hidden"
type="checkbox"
id=value.clone()
id=id.clone()
name=name.clone()
on:change=move |_| on_change.run(())
prop:checked=checked
disabled=disabled
@@ -109,6 +114,7 @@ pub fn CheckboxList(
on_change=on_change
// The actual selected values are tracked by this element, not by the checkboxes themselves.
value=item.clone()
name=data_member.clone()
disabled=disabled
/>
}
+2 -4
View File
@@ -1,6 +1,7 @@
use std::collections::HashMap;
use leptos::prelude::*;
use crate::common::ValueType;
use crate::components::utils::create_unique_id;
/// # Chip Component
///
@@ -31,10 +32,7 @@ pub fn Chip(
) -> impl IntoView {
// Generate a unique id - ensure that the value doesn't contain spaces.
// Without this id, checkbox/radio inputs can interfere with each other.
let value_no_spaces = value.clone().chars()
.filter(|c| !c.is_whitespace())
.collect::<String>();
let id = format!("{}-{}", name.clone(), value_no_spaces);
let id = create_unique_id(&name, &value);
view! {
<label for=id>
+1
View File
@@ -8,6 +8,7 @@ mod row;
mod select;
mod text_field;
mod chips;
mod utils;
pub use self::{
action_button::*, checkbox::*, loading::*, multi_entry::*, panel::*, radio::*, row::*,
+9 -3
View File
@@ -1,16 +1,20 @@
use crate::common::ValueType;
use leptos::prelude::*;
use std::collections::HashMap;
use crate::components::utils::create_unique_id;
#[component]
pub fn Radio(
#[prop()] checked: Signal<bool>,
#[prop(into)] on_change: Callback<(), ()>,
#[prop(into)] value: String,
#[prop(into)] name: String,
#[prop(default = RwSignal::new(false))] disabled: RwSignal<bool>,
) -> impl IntoView {
let id = create_unique_id(&name, &value);
view! {
<label for=value class="flex items-center">
<label for=id class="flex items-center">
<input
// Using the "peer" class links this input with the div "peer" at the same level.
// By using the "peer-checked" selector this div can toggle states based on this
@@ -18,8 +22,9 @@ pub fn Radio(
class="
relative peer shrink-0
hidden"
type="checkbox"
id=value.clone()
type="radio"
id=id.clone()
name=name.clone()
on:change=move |_| on_change.run(())
prop:checked=checked
disabled=disabled
@@ -96,6 +101,7 @@ pub fn RadioList(
on_change=on_change
// The actual selected values are tracked by this element, not by the checkboxes themselves.
value=item.clone()
name=data_member.clone()
disabled=disabled
/>
}
+8
View File
@@ -0,0 +1,8 @@
/// Creates a unique ID for use in components like the [`CheckboxList`],
/// [`RadioList`], and [`ChipsList`].
pub fn create_unique_id(name: &String, value: &String) -> String {
let value_no_spaces = value.clone().chars()
.filter(|c| !c.is_whitespace())
.collect::<String>();
format!("{}-{}", name.clone(), value_no_spaces)
}