🎨 (bootsier): Normaliza id's y revisa Checkbox
Renombra los sufijos de `id` de los controles internos para que cada
tipo tenga su propio identificador: `-checkbox`, `-check-{n}` y
`-radio-{n}`. Elimina además el atributo booleano `switch` inválido en
HTML (basta con `role="switch"` y `class="form-switch"`).
This commit is contained in:
parent
5b7e13e52b
commit
ffba175985
4 changed files with 40 additions and 12 deletions
|
|
@ -144,9 +144,9 @@ impl Component for Group {
|
||||||
.name()
|
.name()
|
||||||
.get()
|
.get()
|
||||||
.unwrap_or_else(|| cx.required_id::<Self>(self.id(), 3));
|
.unwrap_or_else(|| cx.required_id::<Self>(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! {
|
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) {
|
@if let Some(label) = self.label().lookup(cx) {
|
||||||
label class="form-label" { (label) }
|
label class="form-label" { (label) }
|
||||||
}
|
}
|
||||||
|
|
@ -157,7 +157,7 @@ impl Component for Group {
|
||||||
};
|
};
|
||||||
@for (item, i) in self.items().iter().zip(1..) {
|
@for (item, i) in self.items().iter().zip(1..) {
|
||||||
@let i = i.to_string();
|
@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() {
|
@let item_name = if let Some(item_name) = item.name().get() {
|
||||||
util::join!(&name, "_", &item_name)
|
util::join!(&name, "_", &item_name)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,8 @@ pub struct Checkbox {
|
||||||
label: Attr<L10n>,
|
label: Attr<L10n>,
|
||||||
/// Devuelve si el control debe estar marcado/activo por defecto.
|
/// Devuelve si el control debe estar marcado/activo por defecto.
|
||||||
checked: bool,
|
checked: bool,
|
||||||
|
/// Devuelve si el control recibe el foco automáticamente al cargar la página.
|
||||||
|
autofocus: bool,
|
||||||
/// Devuelve si el campo es obligatorio.
|
/// Devuelve si el campo es obligatorio.
|
||||||
required: bool,
|
required: bool,
|
||||||
/// Devuelve si el control está deshabilitado.
|
/// Devuelve si el control está deshabilitado.
|
||||||
|
|
@ -93,23 +95,24 @@ impl Component for Checkbox {
|
||||||
.name()
|
.name()
|
||||||
.get()
|
.get()
|
||||||
.unwrap_or_else(|| cx.required_id::<Self>(self.id(), 1));
|
.unwrap_or_else(|| cx.required_id::<Self>(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;
|
let is_switch = *self.checkbox_kind() == form::CheckboxKind::Switch;
|
||||||
Ok(html! {
|
Ok(html! {
|
||||||
div class=[self.classes().get()] {
|
div id=(&container_id) class=[self.classes().get()] {
|
||||||
input
|
input
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
role=[is_switch.then_some("switch")]
|
role=[is_switch.then_some("switch")]
|
||||||
id=(&id)
|
id=(&checkbox_id)
|
||||||
class="form-check-input"
|
class="form-check-input"
|
||||||
name=(&name)
|
name=(&name)
|
||||||
value="true"
|
value="true"
|
||||||
checked[*self.checked()]
|
checked[*self.checked()]
|
||||||
|
autofocus[*self.autofocus()]
|
||||||
required[*self.required()]
|
required[*self.required()]
|
||||||
disabled[*self.disabled()]
|
disabled[*self.disabled()];
|
||||||
switch[is_switch];
|
|
||||||
@if let Some(label) = self.label().lookup(cx) {
|
@if let Some(label) = self.label().lookup(cx) {
|
||||||
label class="form-check-label" for=(&id) {
|
label class="form-check-label" for=(&checkbox_id) {
|
||||||
(label)
|
(label)
|
||||||
@if *self.required() {
|
@if *self.required() {
|
||||||
span
|
span
|
||||||
|
|
@ -187,6 +190,13 @@ impl Checkbox {
|
||||||
self
|
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.
|
/// Establece si el campo es obligatorio.
|
||||||
#[builder_fn]
|
#[builder_fn]
|
||||||
pub fn with_required(mut self, required: bool) -> Self {
|
pub fn with_required(mut self, required: bool) -> Self {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,24 @@ use pagetop::prelude::*;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::fmt;
|
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 >*******************************************************************************
|
// **< Autocomplete >*******************************************************************************
|
||||||
|
|
||||||
/// Valor del atributo HTML `autocomplete`.
|
/// Valor del atributo HTML `autocomplete`.
|
||||||
|
|
|
||||||
|
|
@ -134,9 +134,9 @@ impl Component for Group {
|
||||||
.name()
|
.name()
|
||||||
.get()
|
.get()
|
||||||
.unwrap_or_else(|| cx.required_id::<Self>(self.id(), 3));
|
.unwrap_or_else(|| cx.required_id::<Self>(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! {
|
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) {
|
@if let Some(label) = self.label().lookup(cx) {
|
||||||
label class="form-label" {
|
label class="form-label" {
|
||||||
(label)
|
(label)
|
||||||
|
|
@ -163,7 +163,7 @@ impl Component for Group {
|
||||||
c
|
c
|
||||||
};
|
};
|
||||||
@let i = i.to_string();
|
@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) {
|
div class=(item_classes) {
|
||||||
input
|
input
|
||||||
type="radio"
|
type="radio"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue