diff --git a/extensions/pagetop-bootsier/src/theme/form/check.rs b/extensions/pagetop-bootsier/src/theme/form/check.rs index 59208382..1dc45e4d 100644 --- a/extensions/pagetop-bootsier/src/theme/form/check.rs +++ b/extensions/pagetop-bootsier/src/theme/form/check.rs @@ -144,9 +144,9 @@ impl Component for Group { .name() .get() .unwrap_or_else(|| cx.required_id::(self.id(), 3)); - let group_id = self.id().unwrap_or_else(|| util::join!("edit-", &name)); + let container_id = self.id().unwrap_or_else(|| util::join!("edit-", &name)); Ok(html! { - div id=(&group_id) class=[self.classes().get()] { + div id=(&container_id) class=[self.classes().get()] { @if let Some(label) = self.label().lookup(cx) { label class="form-label" { (label) } } @@ -157,7 +157,7 @@ impl Component for Group { }; @for (item, i) in self.items().iter().zip(1..) { @let i = i.to_string(); - @let item_id = util::join!(&group_id, "-", &i); + @let item_id = util::join!(&container_id, "-check-", &i); @let item_name = if let Some(item_name) = item.name().get() { util::join!(&name, "_", &item_name) } else { diff --git a/extensions/pagetop-bootsier/src/theme/form/checkbox.rs b/extensions/pagetop-bootsier/src/theme/form/checkbox.rs index 2296ac1d..063902f2 100644 --- a/extensions/pagetop-bootsier/src/theme/form/checkbox.rs +++ b/extensions/pagetop-bootsier/src/theme/form/checkbox.rs @@ -55,6 +55,8 @@ pub struct Checkbox { label: Attr, /// Devuelve si el control debe estar marcado/activo por defecto. checked: bool, + /// Devuelve si el control recibe el foco automáticamente al cargar la página. + autofocus: bool, /// Devuelve si el campo es obligatorio. required: bool, /// Devuelve si el control está deshabilitado. @@ -93,23 +95,24 @@ impl Component for Checkbox { .name() .get() .unwrap_or_else(|| cx.required_id::(self.id(), 1)); - let id = self.id().unwrap_or_else(|| util::join!("edit-", &name)); + let container_id = self.id().unwrap_or_else(|| util::join!("edit-", &name)); + let checkbox_id = util::join!(&container_id, "-checkbox"); let is_switch = *self.checkbox_kind() == form::CheckboxKind::Switch; Ok(html! { - div class=[self.classes().get()] { + div id=(&container_id) class=[self.classes().get()] { input type="checkbox" role=[is_switch.then_some("switch")] - id=(&id) + id=(&checkbox_id) class="form-check-input" name=(&name) value="true" checked[*self.checked()] + autofocus[*self.autofocus()] required[*self.required()] - disabled[*self.disabled()] - switch[is_switch]; + disabled[*self.disabled()]; @if let Some(label) = self.label().lookup(cx) { - label class="form-check-label" for=(&id) { + label class="form-check-label" for=(&checkbox_id) { (label) @if *self.required() { span @@ -187,6 +190,13 @@ impl Checkbox { self } + /// Establece si el control recibe el foco automáticamente al cargar la página. + #[builder_fn] + pub fn with_autofocus(mut self, autofocus: bool) -> Self { + self.autofocus = autofocus; + self + } + /// Establece si el campo es obligatorio. #[builder_fn] pub fn with_required(mut self, required: bool) -> Self { diff --git a/extensions/pagetop-bootsier/src/theme/form/props.rs b/extensions/pagetop-bootsier/src/theme/form/props.rs index 7fedb036..24593045 100644 --- a/extensions/pagetop-bootsier/src/theme/form/props.rs +++ b/extensions/pagetop-bootsier/src/theme/form/props.rs @@ -3,6 +3,24 @@ use pagetop::prelude::*; use std::borrow::Cow; use std::fmt; +// **< CheckboxKind >******************************************************************************* + +/// Variante visual para [`form::Checkbox`](crate::theme::form::Checkbox) en un formulario. +/// +/// Determina si el control se renderiza como una casilla de verificación estándar o como un +/// interruptor (*toggle switch*). +#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)] +pub enum CheckboxKind { + /// Casilla de verificación estándar. Es el tipo por defecto. + #[default] + Check, + /// Interruptor de encendido/apagado. + Switch, + // TODO: Añadir variante `NativeSwitch` cuando el atributo `switch` de la propuesta WHATWG + // (https://github.com/whatwg/html/issues/9546) sea estándar y tenga soporte amplio. Safari ya + // lo soporta. También se añadiría el constructor `Checkbox::native_switch()`. +} + // **< Autocomplete >******************************************************************************* /// Valor del atributo HTML `autocomplete`. diff --git a/extensions/pagetop-bootsier/src/theme/form/radio.rs b/extensions/pagetop-bootsier/src/theme/form/radio.rs index 377710f2..3ea88b45 100644 --- a/extensions/pagetop-bootsier/src/theme/form/radio.rs +++ b/extensions/pagetop-bootsier/src/theme/form/radio.rs @@ -134,9 +134,9 @@ impl Component for Group { .name() .get() .unwrap_or_else(|| cx.required_id::(self.id(), 3)); - let group_id = self.id().unwrap_or_else(|| util::join!("edit-", &name)); + let container_id = self.id().unwrap_or_else(|| util::join!("edit-", &name)); Ok(html! { - div id=(&group_id) class=[self.classes().get()] { + div id=(&container_id) class=[self.classes().get()] { @if let Some(label) = self.label().lookup(cx) { label class="form-label" { (label) @@ -163,7 +163,7 @@ impl Component for Group { c }; @let i = i.to_string(); - @let item_id = util::join!(&group_id, "-", &i); + @let item_id = util::join!(&container_id, "-radio-", &i); div class=(item_classes) { input type="radio"