♻️ (bootsier): Adapta componentes a nueva API

Sustituye `Classes`/`ClassesOp` por `Props`/`PropsOp` en todos los
componentes: campo, *builder* `with_prop()`, `setup()` y `prepare()`.
This commit is contained in:
Manuel Cillero 2026-06-14 23:07:57 +02:00
parent 1bd97d5705
commit 8d0103c257
31 changed files with 218 additions and 220 deletions

View file

@ -57,7 +57,7 @@ impl BorderColor {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// assert_eq!(BorderColor::Theme(Color::Primary).to_class(), "border-primary");
/// assert_eq!(BorderColor::Subtle(Color::Warning).to_class(), "border-warning-subtle");

View file

@ -69,7 +69,7 @@ impl BreakPoint {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// let bp = BreakPoint::MD;
/// assert_eq!(bp.class_with("col", ""), "col-md");

View file

@ -75,7 +75,7 @@ impl ButtonColor {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// assert_eq!(
/// ButtonColor::Background(Color::Primary).to_class(),
@ -131,7 +131,7 @@ impl ButtonSize {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// assert_eq!(ButtonSize::Small.to_class(), "btn-sm");
/// assert_eq!(ButtonSize::Large.to_class(), "btn-lg");

View file

@ -43,7 +43,7 @@ impl Color {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// assert_eq!(Color::Primary.to_class(), "primary");
/// assert_eq!(Color::Danger.to_class(), "danger");
@ -123,7 +123,7 @@ impl Opacity {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// assert_eq!(Opacity::Opaque.class_with(""), "opacity-100");
/// assert_eq!(Opacity::Half.class_with("bg"), "bg-opacity-50");
@ -155,7 +155,7 @@ impl Opacity {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// assert_eq!(Opacity::Opaque.to_class(), "opacity-100");
/// assert_eq!(Opacity::Half.to_class(), "opacity-50");
@ -236,7 +236,7 @@ impl ColorBg {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// assert_eq!(ColorBg::Body.to_class(), "bg-body");
/// assert_eq!(ColorBg::Theme(Color::Primary).to_class(), "bg-primary");
@ -320,7 +320,7 @@ impl ColorText {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// assert_eq!(ColorText::Body.to_class(), "text-body");
/// assert_eq!(ColorText::Theme(Color::Primary).to_class(), "text-primary");

View file

@ -60,7 +60,7 @@ impl ScaleSize {
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// assert_eq!(ScaleSize::Auto.class_with("border"), "border");
/// assert_eq!(ScaleSize::Zero.class_with("m"), "m-0");

View file

@ -70,7 +70,7 @@ impl RoundedRadius {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// assert_eq!(RoundedRadius::Scale2.class_with(""), "rounded-2");
/// assert_eq!(RoundedRadius::Zero.class_with("rounded-top"), "rounded-top-0");
@ -102,7 +102,7 @@ impl RoundedRadius {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// assert_eq!(RoundedRadius::Default.to_class(), "rounded");
/// assert_eq!(RoundedRadius::Zero.to_class(), "rounded-0");

View file

@ -18,7 +18,7 @@ use crate::theme::{ButtonAction, ButtonColor, ButtonSize};
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// use pagetop::prelude::*;
/// use pagetop_bootsier::theme::*;
///
@ -47,8 +47,8 @@ use crate::theme::{ButtonAction, ButtonColor, ButtonSize};
pub struct Button {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS del botón.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del botón.
props: Props,
/// Devuelve el comportamiento del botón al activarse.
kind: ButtonAction,
/// Devuelve el esquema de color del botón.
@ -80,7 +80,7 @@ impl Component for Button {
let mut classes = "btn".to_string();
(*self.color()).push_class(&mut classes);
(*self.size()).push_class(&mut classes);
self.alter_classes(ClassesOp::Prepend, classes);
self.alter_prop(PropsOp::prepend_classes(classes));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -88,7 +88,7 @@ impl Component for Button {
button
id=[self.id()]
type=(self.kind())
class=[self.classes().get()]
(self.props())
name=[self.name().get()]
value=[self.value().get()]
autofocus[*self.autofocus()]
@ -147,10 +147,10 @@ impl Button {
self
}
/// Modifica la lista de clases CSS aplicadas al botón.
/// Modifica los atributos HTML o las clases CSS del botón.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -26,7 +26,7 @@ use crate::theme::attrs::{BorderColor, Opacity, ScaleSize, Side};
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// use pagetop_bootsier::theme::*;
///
/// // Borde global.
@ -145,7 +145,7 @@ impl Border {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// // Convertir explícitamente con `From::from`:
/// let b = classes::Border::from(ScaleSize::Two);

View file

@ -9,7 +9,7 @@ use crate::theme::attrs::{ScaleSize, Side};
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// use pagetop_bootsier::theme::*;
///
/// let m = classes::Margin::with(Side::Top, ScaleSize::Three);
@ -97,7 +97,7 @@ impl Margin {
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// use pagetop_bootsier::theme::*;
///
/// let p = classes::Padding::with(Side::LeftAndRight, ScaleSize::Two);

View file

@ -14,7 +14,7 @@ use crate::theme::attrs::RoundedRadius;
///
/// # Ejemplos
///
/// ```rust
/// ```rust,no_run
/// use pagetop_bootsier::theme::*;
///
/// // Radio global:

View file

@ -11,7 +11,7 @@ use crate::theme::*;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// use pagetop_bootsier::theme::*;
///
/// let main = Container::main()
@ -22,8 +22,8 @@ use crate::theme::*;
pub struct Container {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS asociadas al contenedor.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del contenedor.
props: Props,
/// Devuelve el tipo semántico del contenedor.
container_kind: container::Kind,
/// Devuelve el comportamiento para el ancho del contenedor.
@ -42,7 +42,7 @@ impl Component for Container {
}
fn setup(&mut self, _cx: &Context) {
self.alter_classes(ClassesOp::Prepend, self.container_width().to_class());
self.alter_prop(PropsOp::prepend_classes(self.container_width().to_class()));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -58,32 +58,32 @@ impl Component for Container {
};
Ok(match self.container_kind() {
container::Kind::Default => html! {
div id=[self.id()] class=[self.classes().get()] style=[style] {
div id=[self.id()] (self.props()) style=[style] {
(output)
}
},
container::Kind::Main => html! {
main id=[self.id()] class=[self.classes().get()] style=[style] {
main id=[self.id()] (self.props()) style=[style] {
(output)
}
},
container::Kind::Header => html! {
header id=[self.id()] class=[self.classes().get()] style=[style] {
header id=[self.id()] (self.props()) style=[style] {
(output)
}
},
container::Kind::Footer => html! {
footer id=[self.id()] class=[self.classes().get()] style=[style] {
footer id=[self.id()] (self.props()) style=[style] {
(output)
}
},
container::Kind::Section => html! {
section id=[self.id()] class=[self.classes().get()] style=[style] {
section id=[self.id()] (self.props()) style=[style] {
(output)
}
},
container::Kind::Article => html! {
article id=[self.id()] class=[self.classes().get()] style=[style] {
article id=[self.id()] (self.props()) style=[style] {
(output)
}
},
@ -141,7 +141,7 @@ impl Container {
self
}
/// Modifica la lista de clases CSS aplicadas al contenedor.
/// Modifica los atributos HTML o las clases CSS del contenedor.
///
/// También acepta clases predefinidas para:
///
@ -150,8 +150,8 @@ impl Container {
/// - Establecer bordes ([`classes::Border`]).
/// - Redondear las esquinas ([`classes::Rounded`]).
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -21,7 +21,7 @@ use crate::theme::*;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// use pagetop::prelude::*;
/// use pagetop_bootsier::theme::*;
///
@ -40,8 +40,8 @@ use crate::theme::*;
pub struct Dropdown {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS asociadas al menú desplegable.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del menú desplegable.
props: Props,
/// Devuelve el título del menú desplegable.
title: L10n,
/// Devuelve el tamaño configurado del botón.
@ -74,10 +74,9 @@ impl Component for Dropdown {
}
fn setup(&mut self, _cx: &Context) {
self.alter_classes(
ClassesOp::Prepend,
self.alter_prop(PropsOp::prepend_classes(
self.direction().class_with(*self.button_grouped()),
);
));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -91,23 +90,23 @@ impl Component for Dropdown {
let title = self.title().using(cx);
Ok(html! {
div id=[self.id()] class=[self.classes().get()] {
div id=[self.id()] (self.props()) {
@if !title.is_empty() {
@let mut btn_classes = Classes::new({
@let btn_base = {
let mut classes = "btn".to_string();
self.button_size().push_class(&mut classes);
self.button_color().push_class(&mut classes);
classes
});
};
@let pos = self.menu_position();
@let offset = pos.data_offset();
@let reference = pos.data_reference();
@let auto_close = self.auto_close.as_str();
@let menu_classes = Classes::new({
@let menu_classes = {
let mut classes = "dropdown-menu".to_string();
self.menu_align().push_class(&mut classes);
classes
});
};
// Renderizado en modo split (dos botones) o simple (un botón).
@if *self.button_split() {
@ -115,18 +114,18 @@ impl Component for Dropdown {
@let btn = html! {
button
type="button"
class=[btn_classes.get()]
class=(&btn_base)
{
(title)
}
};
// Botón *toggle* que abre/cierra el menú asociado.
@let btn_toggle_classes =
util::join!(&btn_base, " dropdown-toggle dropdown-toggle-split");
@let btn_toggle = html! {
button
type="button"
class=[btn_classes.alter_classes(
ClassesOp::Add, "dropdown-toggle dropdown-toggle-split"
).get()]
class=(&btn_toggle_classes)
data-bs-toggle="dropdown"
data-bs-offset=[offset]
data-bs-reference=[reference]
@ -142,22 +141,21 @@ impl Component for Dropdown {
@match self.direction() {
dropdown::Direction::Dropstart => {
(btn_toggle)
ul class=[menu_classes.get()] { (items) }
ul class=(&menu_classes) { (items) }
(btn)
}
_ => {
(btn)
(btn_toggle)
ul class=[menu_classes.get()] { (items) }
ul class=(&menu_classes) { (items) }
}
}
} @else {
// Botón único con funcionalidad de *toggle*.
@let btn_toggle_classes = util::join!(&btn_base, " dropdown-toggle");
button
type="button"
class=[btn_classes.alter_classes(
ClassesOp::Add, "dropdown-toggle"
).get()]
class=(&btn_toggle_classes)
data-bs-toggle="dropdown"
data-bs-offset=[offset]
data-bs-reference=[reference]
@ -166,7 +164,7 @@ impl Component for Dropdown {
{
(title)
}
ul class=[menu_classes.get()] { (items) }
ul class=(&menu_classes) { (items) }
}
} @else {
// Sin botón: sólo el listado como menú contextual.
@ -187,10 +185,10 @@ impl Dropdown {
self
}
/// Modifica la lista de clases CSS aplicadas al menú desplegable.
/// Modifica los atributos HTML o las clases CSS del menú desplegable.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -47,8 +47,8 @@ pub enum ItemKind {
pub struct Item {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS asociadas al elemento.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del elemento.
props: Props,
/// Devuelve el tipo de elemento representado.
item_kind: ItemKind,
}
@ -67,7 +67,7 @@ impl Component for Item {
ItemKind::Void => html! {},
ItemKind::Label(label) => html! {
li id=[self.id()] class=[self.classes().get()] {
li id=[self.id()] (self.props()) {
span class="dropdown-item-text" {
(label.using(cx))
}
@ -101,7 +101,7 @@ impl Component for Item {
let tabindex = disabled.then_some("-1");
html! {
li id=[self.id()] class=[self.classes().get()] {
li id=[self.id()] (self.props()) {
a
class=(classes)
href=[href]
@ -127,7 +127,7 @@ impl Component for Item {
let disabled_attr = disabled.then_some("disabled");
html! {
li id=[self.id()] class=[self.classes().get()] {
li id=[self.id()] (self.props()) {
button
class=(classes)
type="button"
@ -141,7 +141,7 @@ impl Component for Item {
}
ItemKind::Header(label) => html! {
li id=[self.id()] class=[self.classes().get()] {
li id=[self.id()] (self.props()) {
h6 class="dropdown-header" {
(label.using(cx))
}
@ -149,7 +149,7 @@ impl Component for Item {
},
ItemKind::Divider => html! {
li id=[self.id()] class=[self.classes().get()] { hr class="dropdown-divider" {} }
li id=[self.id()] (self.props()) { hr class="dropdown-divider" {} }
},
})
}
@ -267,10 +267,10 @@ impl Item {
self
}
/// Modifica la lista de clases CSS aplicadas al elemento.
/// Modifica los atributos HTML o las clases CSS del elemento.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}
}

View file

@ -15,7 +15,7 @@ use pagetop::prelude::*;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let item = form::check::Item::new("apple", L10n::n("Apple")).with_checked(true);
@ -80,7 +80,7 @@ impl Item {
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let interests = form::check::Field::new()
@ -110,8 +110,8 @@ impl Item {
pub struct Field {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS del contenedor del grupo.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del contenedor del grupo.
props: Props,
/// Devuelve el nombre base compartido por todas las casillas del grupo.
name: AttrName,
/// Devuelve la etiqueta del grupo.
@ -136,7 +136,7 @@ impl Component for Field {
}
fn setup(&mut self, _cx: &Context) {
self.alter_classes(ClassesOp::Prepend, "form-field form-field-checkboxes");
self.alter_prop(PropsOp::prepend_classes("form-field form-field-checkboxes"));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -146,7 +146,7 @@ impl Component for Field {
.unwrap_or_else(|| cx.required_id::<Self>(self.id(), 3));
let container_id = self.id().unwrap_or_else(|| util::join!("edit-", &name));
Ok(html! {
div id=(&container_id) class=[self.classes().get()] {
div id=(&container_id) (self.props()) {
@if let Some(label) = self.label().lookup(cx) {
label class="form-label" { (label) }
}
@ -195,10 +195,10 @@ impl Field {
self
}
/// Modifica la lista de clases CSS aplicadas al contenedor del grupo de casillas.
/// Modifica los atributos HTML o las clases CSS del contenedor del grupo de casillas.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -15,7 +15,7 @@ use crate::theme::form;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let accept_terms = form::Checkbox::check() // También sirve new() o default().
@ -45,8 +45,8 @@ use crate::theme::form;
pub struct Checkbox {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS del contenedor del control.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del contenedor del control.
props: Props,
/// Devuelve la variante visual del control.
checkbox_kind: form::CheckboxKind,
/// Devuelve el nombre del campo.
@ -87,7 +87,7 @@ impl Component for Checkbox {
if *self.reverse() {
classes.push_str(" form-check-reverse");
}
self.alter_classes(ClassesOp::Prepend, classes);
self.alter_prop(PropsOp::prepend_classes(classes));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -99,7 +99,7 @@ impl Component for Checkbox {
let checkbox_id = util::join!(&container_id, "-checkbox");
let is_switch = *self.checkbox_kind() == form::CheckboxKind::Switch;
Ok(html! {
div id=(&container_id) class=[self.classes().get()] {
div id=(&container_id) (self.props()) {
input
type="checkbox"
role=[is_switch.then_some("switch")]
@ -152,10 +152,10 @@ impl Checkbox {
self
}
/// Modifica la lista de clases CSS aplicadas al contenedor del control.
/// Modifica los atributos HTML o las clases CSS del contenedor del control.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -16,7 +16,7 @@ use crate::theme::form;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// use pagetop::prelude::*;
/// use pagetop_bootsier::theme::*;
///
@ -49,8 +49,8 @@ use crate::theme::form;
pub struct Form {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS del formulario.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del formulario.
props: Props,
/// Devuelve la URL/ruta de destino del formulario.
action: AttrValue,
/// Devuelve el método para enviar el formulario.
@ -72,7 +72,7 @@ impl Component for Form {
}
fn setup(&mut self, _cx: &Context) {
self.alter_classes(ClassesOp::Prepend, "form");
self.alter_prop(PropsOp::prepend_classes("form"));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -83,7 +83,7 @@ impl Component for Form {
Ok(html! {
form
id=[self.id()]
class=[self.classes().get()]
(self.props())
action=[self.action().get()]
method=[method]
accept-charset=[self.charset().get()]
@ -104,10 +104,10 @@ impl Form {
self
}
/// Modifica la lista de clases CSS aplicadas al formulario.
/// Modifica los atributos HTML o las clases CSS del formulario.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -13,7 +13,7 @@ use pagetop::prelude::*;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let personal_data = form::Fieldset::new()
@ -26,8 +26,8 @@ use pagetop::prelude::*;
pub struct Fieldset {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS del `fieldset`.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del `fieldset`.
props: Props,
/// Devuelve la leyenda del `fieldset`.
legend: Attr<L10n>,
/// Devuelve la descripción del `fieldset`.
@ -55,7 +55,7 @@ impl Component for Fieldset {
}
Ok(html! {
fieldset id=[self.id()] class=[self.classes().get()] disabled[*self.disabled()] {
fieldset id=[self.id()] (self.props()) disabled[*self.disabled()] {
@if let Some(legend) = self.legend().lookup(cx) {
legend { (legend) }
}
@ -78,10 +78,10 @@ impl Fieldset {
self
}
/// Modifica la lista de clases CSS aplicadas al `fieldset`.
/// Modifica los atributos HTML o las clases CSS del `fieldset`.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -10,7 +10,7 @@ use pagetop::prelude::*;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let token = form::Hidden::new()

View file

@ -104,7 +104,7 @@ impl fmt::Display for Mode {
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let email = form::input::Field::email()
@ -128,8 +128,8 @@ impl fmt::Display for Mode {
pub struct Field {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS del contenedor del campo.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del contenedor del campo.
props: Props,
/// Devuelve el tipo de campo.
kind: Kind,
/// Devuelve el nombre del campo.
@ -175,12 +175,12 @@ impl Component for Field {
fn setup(&mut self, _cx: &Context) {
if *self.floating_label() {
self.alter_classes(ClassesOp::Prepend, "form-floating");
self.alter_prop(PropsOp::prepend_classes("form-floating"));
}
self.alter_classes(
ClassesOp::Prepend,
util::join!("form-field form-field-", self.kind().to_string()),
);
self.alter_prop(PropsOp::prepend_classes(util::join!(
"form-field form-field-",
self.kind().to_string()
)));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -217,7 +217,7 @@ impl Component for Field {
None => html! {},
};
Ok(html! {
div id=[container_id.as_deref()] class=[self.classes().get()] {
div id=[container_id.as_deref()] (self.props()) {
@if !*self.floating_label() {
(label)
}
@ -320,10 +320,10 @@ impl Field {
self
}
/// Modifica la lista de clases CSS aplicadas al contenedor del campo.
/// Modifica los atributos HTML o las clases CSS del contenedor del campo.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -50,7 +50,7 @@ pub enum CheckboxKind {
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// // Correo electrónico con sugerencia semántica del navegador.
@ -243,7 +243,7 @@ impl fmt::Display for Autocomplete {
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop_bootsier::theme::*;
/// let ac = form::Autocomplete::token(form::AutofillField::Username);
/// let ac = form::Autocomplete::shipping(form::AutofillField::StreetAddress);

View file

@ -14,7 +14,7 @@ use crate::LOCALES_BOOTSIER;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let item = form::radio::Item::new("monthly", L10n::n("Monthly")).with_checked(true);
@ -74,7 +74,7 @@ impl Item {
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let plan = form::radio::Field::new()
@ -98,8 +98,8 @@ impl Item {
pub struct Field {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS del contenedor del grupo.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del contenedor del grupo.
props: Props,
/// Devuelve el nombre compartido por todos los botones de opción del grupo.
name: AttrName,
/// Devuelve la etiqueta del grupo.
@ -126,7 +126,7 @@ impl Component for Field {
}
fn setup(&mut self, _cx: &Context) {
self.alter_classes(ClassesOp::Prepend, "form-field form-field-radios");
self.alter_prop(PropsOp::prepend_classes("form-field form-field-radios"));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -136,7 +136,7 @@ impl Component for Field {
.unwrap_or_else(|| cx.required_id::<Self>(self.id(), 3));
let container_id = self.id().unwrap_or_else(|| util::join!("edit-", &name));
Ok(html! {
div id=(&container_id) class=[self.classes().get()] {
div id=(&container_id) (self.props()) {
@if let Some(label) = self.label().lookup(cx) {
label class="form-label" {
(label)
@ -197,10 +197,10 @@ impl Field {
self
}
/// Modifica la lista de clases CSS aplicadas al contenedor del grupo de opciones.
/// Modifica los atributos HTML o las clases CSS del contenedor del grupo de opciones.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -8,7 +8,7 @@ use pagetop::prelude::*;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let volume = form::Range::new()
@ -33,8 +33,8 @@ use pagetop::prelude::*;
pub struct Range {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS del contenedor del control deslizante.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del contenedor del control deslizante.
props: Props,
/// Devuelve el nombre del campo.
name: AttrName,
/// Devuelve la etiqueta del campo.
@ -65,7 +65,7 @@ impl Component for Range {
}
fn setup(&mut self, _cx: &Context) {
self.alter_classes(ClassesOp::Prepend, "form-field form-field-range");
self.alter_prop(PropsOp::prepend_classes("form-field form-field-range"));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -74,7 +74,7 @@ impl Component for Range {
.or_else(|| self.name().get().map(|n| util::join!("edit-", n)));
let range_id = container_id.as_deref().map(|id| util::join!(id, "-range"));
Ok(html! {
div id=[container_id.as_deref()] class=[self.classes().get()] {
div id=[container_id.as_deref()] (self.props()) {
@if let Some(label) = self.label().lookup(cx) {
label for=[range_id.as_deref()] class="form-label" { (label) }
}
@ -107,10 +107,10 @@ impl Range {
self
}
/// Modifica la lista de clases CSS aplicadas al contenedor del control deslizante.
/// Modifica los atributos HTML o las clases CSS del contenedor del control deslizante.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -18,7 +18,7 @@ use crate::theme::form;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let item = form::select::Item::new("es", L10n::n("Spanish")).with_selected(true);
@ -74,7 +74,7 @@ impl Item {
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let group = form::select::Group::new(L10n::n("Europe"))
@ -147,7 +147,7 @@ pub enum Entry {
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let idioma = form::select::Field::new()
@ -193,8 +193,8 @@ pub enum Entry {
pub struct Field {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS del contenedor de la lista de selección.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del contenedor de la lista de selección.
props: Props,
/// Devuelve el nombre del campo.
name: AttrName,
/// Devuelve la etiqueta del campo.
@ -230,11 +230,11 @@ impl Component for Field {
fn setup(&mut self, _cx: &Context) {
if *self.floating_label() {
self.multiple = false;
self.rows.alter_opt(None::<u16>);
self.alter_classes(ClassesOp::Prepend, "form-floating");
self.alter_multiple(false);
self.alter_rows(None::<u16>);
self.alter_prop(PropsOp::prepend_classes("form-floating"));
}
self.alter_classes(ClassesOp::Prepend, "form-field form-field-select");
self.alter_prop(PropsOp::prepend_classes("form-field form-field-select"));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -259,7 +259,7 @@ impl Component for Field {
None => html! {},
};
Ok(html! {
div id=[container_id.as_deref()] class=[self.classes().get()] {
div id=[container_id.as_deref()] (self.props()) {
@if !*self.floating_label() {
(label)
}
@ -325,10 +325,10 @@ impl Field {
self
}
/// Modifica la lista de clases CSS aplicadas al contenedor de la lista de selección.
/// Modifica los atributos HTML o las clases CSS del contenedor de la lista de selección.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -11,7 +11,7 @@ use crate::theme::form;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let descripcion = form::Textarea::new()
@ -36,8 +36,8 @@ use crate::theme::form;
pub struct Textarea {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS del contenedor del área de texto.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del contenedor del área de texto.
props: Props,
/// Devuelve el nombre del campo.
name: AttrName,
/// Devuelve el valor inicial del área de texto.
@ -79,10 +79,10 @@ impl Component for Textarea {
fn setup(&mut self, _cx: &Context) {
if *self.floating_label() {
self.rows.alter_opt(None::<u16>);
self.alter_classes(ClassesOp::Prepend, "form-floating");
self.alter_rows(None::<u16>);
self.alter_prop(PropsOp::prepend_classes("form-floating"));
}
self.alter_classes(ClassesOp::Prepend, "form-field form-field-textarea");
self.alter_prop(PropsOp::prepend_classes("form-field form-field-textarea"));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -116,7 +116,7 @@ impl Component for Textarea {
None => html! {},
};
Ok(html! {
div id=[container_id.as_deref()] class=[self.classes().get()] {
div id=[container_id.as_deref()] (self.props()) {
@if !*self.floating_label() {
(label)
}
@ -159,10 +159,10 @@ impl Textarea {
self
}
/// Modifica la lista de clases CSS aplicadas al contenedor del campo.
/// Modifica los atributos HTML o las clases CSS del contenedor del campo.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -15,8 +15,8 @@ pub enum IconKind {
#[derive(AutoDefault, Clone, Debug, Getters)]
pub struct Icon {
/// Devuelve las clases CSS asociadas al icono.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del icono.
props: Props,
icon_kind: IconKind,
aria_label: AttrL10n,
}
@ -28,10 +28,10 @@ impl Component for Icon {
fn setup(&mut self, _cx: &Context) {
if !matches!(self.icon_kind(), IconKind::None) {
self.alter_classes(ClassesOp::Prepend, "icon");
self.alter_prop(PropsOp::prepend_classes("icon"));
}
if let IconKind::Font(font_size) = self.icon_kind() {
self.alter_classes(ClassesOp::Add, font_size.as_str());
self.alter_prop(PropsOp::add_classes(font_size.as_str()));
}
}
@ -43,7 +43,7 @@ impl Component for Icon {
let has_label = aria_label.is_some();
html! {
i
class=[self.classes().get()]
(self.props())
role=[has_label.then_some("img")]
aria-label=[aria_label]
aria-hidden=[(!has_label).then_some("true")]
@ -60,7 +60,7 @@ impl Component for Icon {
viewBox=(viewbox)
fill="currentColor"
focusable="false"
class=[self.classes().get()]
(self.props())
role=[has_label.then_some("img")]
aria-label=[aria_label]
aria-hidden=[(!has_label).then_some("true")]
@ -98,10 +98,10 @@ impl Icon {
// **< Icon BUILDER >***************************************************************************
/// Modifica la lista de clases CSS aplicadas al icono.
/// Modifica los atributos HTML o las clases CSS del icono.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_value(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -15,8 +15,8 @@ use crate::theme::*;
pub struct Image {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS asociadas a la imagen.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS de la imagen.
props: Props,
/// Devuelve las dimensiones de la imagen.
size: image::Size,
/// Devuelve el origen de la imagen.
@ -35,7 +35,7 @@ impl Component for Image {
}
fn setup(&mut self, _cx: &Context) {
self.alter_classes(ClassesOp::Prepend, self.source().to_class());
self.alter_prop(PropsOp::prepend_classes(self.source().to_class()));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -47,7 +47,7 @@ impl Component for Image {
return Ok(html! {
span
id=[self.id()]
class=[self.classes().get()]
(self.props())
style=[dimensions]
role=[(!is_decorative).then_some("img")]
aria-label=[(!is_decorative).then_some(alt_text)]
@ -66,7 +66,7 @@ impl Component for Image {
src=[source]
alt=(alt_text)
id=[self.id()]
class=[self.classes().get()]
(self.props())
style=[dimensions] {}
})
}
@ -87,15 +87,15 @@ impl Image {
self
}
/// Modifica la lista de clases CSS aplicadas a la imagen.
/// Modifica los atributos HTML o las clases CSS de la imagen.
///
/// También acepta clases predefinidas para:
///
/// - Establecer bordes ([`classes::Border`]).
/// - Redondear las esquinas ([`classes::Rounded`]).
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -12,7 +12,7 @@ use crate::theme::*;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// use pagetop::prelude::*;
/// use pagetop_bootsier::theme::*;
///
@ -34,8 +34,8 @@ use crate::theme::*;
pub struct Nav {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS asociadas al menú.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del menú.
props: Props,
/// Devuelve el estilo visual seleccionado.
nav_kind: nav::Kind,
/// Devuelve la distribución y orientación seleccionada.
@ -54,12 +54,12 @@ impl Component for Nav {
}
fn setup(&mut self, _cx: &Context) {
self.alter_classes(ClassesOp::Prepend, {
self.alter_prop(PropsOp::prepend_classes({
let mut classes = "nav".to_string();
self.nav_kind().push_class(&mut classes);
self.nav_layout().push_class(&mut classes);
classes
});
}));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -69,7 +69,7 @@ impl Component for Nav {
}
Ok(html! {
ul id=[self.id()] class=[self.classes().get()] {
ul id=[self.id()] (self.props()) {
(items)
}
})
@ -101,10 +101,10 @@ impl Nav {
self
}
/// Modifica la lista de clases CSS aplicadas al menú.
/// Modifica los atributos HTML o las clases CSS del menú.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -80,8 +80,8 @@ impl ItemKind {
pub struct Item {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS asociadas al elemento.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del elemento.
props: Props,
/// Devuelve el tipo de elemento representado.
item_kind: ItemKind,
}
@ -96,7 +96,7 @@ impl Component for Item {
}
fn setup(&mut self, _cx: &Context) {
self.alter_classes(ClassesOp::Prepend, self.item_kind().to_class());
self.alter_prop(PropsOp::prepend_classes(self.item_kind().to_class()));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -104,7 +104,7 @@ impl Component for Item {
ItemKind::Void => html! {},
ItemKind::Label(label) => html! {
li id=[self.id()] class=[self.classes().get()] {
li id=[self.id()] (self.props()) {
span class="nav-link disabled" aria-disabled="true" {
(label.using(cx))
}
@ -137,7 +137,7 @@ impl Component for Item {
let aria_disabled = (*disabled).then_some("true");
html! {
li id=[self.id()] class=[self.classes().get()] {
li id=[self.id()] (self.props()) {
a
class=(classes)
href=[href]
@ -153,7 +153,7 @@ impl Component for Item {
}
ItemKind::Html(html) => html! {
li id=[self.id()] class=[self.classes().get()] {
li id=[self.id()] (self.props()) {
(html.render(cx))
}
},
@ -170,7 +170,7 @@ impl Component for Item {
.unwrap_or_else(|| "Dropdown".to_string())
});
html! {
li id=[self.id()] class=[self.classes().get()] {
li id=[self.id()] (self.props()) {
a
class="nav-link dropdown-toggle"
data-bs-toggle="dropdown"
@ -290,10 +290,10 @@ impl Item {
self
}
/// Modifica la lista de clases CSS aplicadas al elemento.
/// Modifica los atributos HTML o las clases CSS del elemento.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}
}

View file

@ -18,7 +18,7 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
///
/// Barra **simple**, sólo con un menú horizontal:
///
/// ```rust
/// ```rust,no_run
/// use pagetop::prelude::*;
/// use pagetop_bootsier::theme::*;
///
@ -33,7 +33,7 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
///
/// Barra **colapsable**, con botón de despliegue y contenido en el desplegable cuando colapsa:
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let navbar = Navbar::simple_toggle()
@ -48,7 +48,7 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
///
/// Barra con **marca de identidad a la izquierda** y menú a la derecha, típica de una cabecera:
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let brand = navbar::Brand::new()
@ -75,7 +75,7 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
///
/// Barra con **botón de despliegue a la izquierda** y **marca de identidad a la derecha**:
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let brand = navbar::Brand::new()
@ -93,7 +93,7 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
///
/// Barra con el **contenido en un *offcanvas***, ideal para dispositivos móviles o menús largos:
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let oc = Offcanvas::new()
@ -118,7 +118,7 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
///
/// Barra **fija arriba**:
///
/// ```rust
/// ```rust,no_run
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let brand = navbar::Brand::new()
@ -138,8 +138,8 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
pub struct Navbar {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS asociadas a la barra de navegación.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS de la barra de navegación.
props: Props,
/// Devuelve el punto de ruptura configurado.
expand: BreakPoint,
/// Devuelve la disposición configurada para la barra de navegación.
@ -160,12 +160,12 @@ impl Component for Navbar {
}
fn setup(&mut self, _cx: &Context) {
self.alter_classes(ClassesOp::Prepend, {
self.alter_prop(PropsOp::prepend_classes({
let mut classes = "navbar".to_string();
self.expand().push_class(&mut classes, "navbar-expand", "");
self.position().push_class(&mut classes);
classes
});
}));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -202,7 +202,7 @@ impl Component for Navbar {
let id = cx.required_id::<Self>(self.id(), 1);
Ok(html! {
nav id=(&id) class=[self.classes().get()] {
nav id=(&id) (self.props()) {
div class="container-fluid" {
@match self.layout() {
// Barra más sencilla: sólo contenido.
@ -342,15 +342,15 @@ impl Navbar {
self
}
/// Modifica la lista de clases CSS aplicadas a la barra de navegación.
/// Modifica los atributos HTML o las clases CSS de la barra de navegación.
///
/// También acepta clases predefinidas para:
///
/// - Modificar el color de fondo ([`classes::Background`]).
/// - Definir la apariencia del texto ([`classes::Text`]).
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}

View file

@ -41,7 +41,7 @@ impl Component for Item {
fn setup(&mut self, _cx: &Context) {
if let Self::Nav(nav) = self {
if let Some(mut nav) = nav.get() {
nav.alter_classes(ClassesOp::Prepend, "navbar-nav");
nav.alter_prop(PropsOp::prepend_classes("navbar-nav"));
}
}
}
@ -57,7 +57,7 @@ impl Component for Item {
return Ok(html! {});
}
html! {
ul id=[nav.id()] class=[nav.classes().get()] {
ul id=[nav.id()] (nav.props()) {
(items)
}
}

View file

@ -23,7 +23,7 @@ use crate::theme::*;
///
/// # Ejemplo
///
/// ```rust
/// ```rust,no_run
/// use pagetop::prelude::*;
/// use pagetop_bootsier::theme::*;
///
@ -45,8 +45,8 @@ use crate::theme::*;
pub struct Offcanvas {
#[getters(skip)]
id: AttrId,
/// Devuelve las clases CSS asociadas al panel.
classes: Classes,
/// Devuelve los atributos HTML y clases CSS del panel.
props: Props,
/// Devuelve el título del panel.
title: L10n,
/// Devuelve el punto de ruptura configurado para cambiar el comportamiento del panel.
@ -73,13 +73,13 @@ impl Component for Offcanvas {
}
fn setup(&mut self, _cx: &Context) {
self.alter_classes(ClassesOp::Prepend, {
self.alter_prop(PropsOp::prepend_classes({
let mut classes = "offcanvas".to_string();
self.breakpoint().push_class(&mut classes, "offcanvas", "");
self.placement().push_class(&mut classes);
self.visibility().push_class(&mut classes);
classes
});
}));
}
fn prepare(&self, cx: &mut Context) -> Result<Markup, ComponentError> {
@ -97,10 +97,10 @@ impl Offcanvas {
self
}
/// Modifica la lista de clases CSS aplicadas al panel.
/// Modifica los atributos HTML o las clases CSS del panel.
#[builder_fn]
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
self.classes.alter_classes(op, classes);
pub fn with_prop(mut self, op: PropsOp) -> Self {
self.props.alter_prop(op);
self
}
@ -192,7 +192,7 @@ impl Offcanvas {
html! {
div
id=(&id)
class=[self.classes().get()]
(self.props())
tabindex="-1"
data-bs-scroll=[body_scroll]
data-bs-backdrop=[backdrop]