From 6c5e1b118898eb0f30e33d65aaaea97e25e1b499 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Sat, 25 Oct 2025 10:52:33 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=9A=A7=20Cambia=20el=20uso=20de=20`BreakP?= =?UTF-8?q?oint`=20para=20`Container`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extensions/pagetop-bootsier/src/theme.rs | 2 +- .../src/theme/aux/breakpoint.rs | 43 +++---- .../pagetop-bootsier/src/theme/container.rs | 108 +++++++++++------- 3 files changed, 87 insertions(+), 66 deletions(-) diff --git a/extensions/pagetop-bootsier/src/theme.rs b/extensions/pagetop-bootsier/src/theme.rs index 51073d4..ec95165 100644 --- a/extensions/pagetop-bootsier/src/theme.rs +++ b/extensions/pagetop-bootsier/src/theme.rs @@ -4,7 +4,7 @@ pub mod aux; // Container. mod container; -pub use container::{Container, ContainerType}; +pub use container::{Container, ContainerType, ContainerWidth}; // Dropdown. pub mod dropdown; diff --git a/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs b/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs index 963bb3b..601aa54 100644 --- a/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs +++ b/extensions/pagetop-bootsier/src/theme/aux/breakpoint.rs @@ -7,10 +7,6 @@ use std::fmt; /// - `"sm"`, `"md"`, `"lg"`, `"xl"` o `"xxl"` para los puntos de ruptura `SM`, `MD`, `LG`, `XL` o /// `XXL`, respectivamente. /// - `""` (cadena vacía) para `None`. -/// - `"fluid"` para las variantes `Fluid` y `FluidMax(_)`, útil para modelar `container-fluid` en -/// [`Container`](crate::theme::Container). Se debe tener en cuenta que `"fluid"` **no** es un -/// sufijo de *breakpoint*. Para construir clases válidas con prefijo (p. ej., `"col-md"`), se -/// recomienda usar `to_class()` (Self::to_class) o `try_class()` (Self::try_class). /// /// # Ejemplos /// @@ -18,13 +14,14 @@ use std::fmt; /// # use pagetop_bootsier::prelude::*; /// assert_eq!(BreakPoint::MD.to_string(), "md"); /// assert_eq!(BreakPoint::None.to_string(), ""); -/// assert_eq!(BreakPoint::Fluid.to_string(), "fluid"); /// /// // Forma correcta para clases con prefijo: -/// //assert_eq!(BreakPoint::MD.to_class("col"), "col-md"); -/// //assert_eq!(BreakPoint::Fluid.to_class("offcanvas"), "offcanvas"); +/// assert_eq!(BreakPoint::MD.to_class("col"), "col-md"); +/// assert_eq!(BreakPoint::None.to_class("offcanvas"), "offcanvas"); +/// +/// assert_eq!(BreakPoint::XXL.try_class("col"), Some("col-xxl".to_string())); +/// assert_eq!(BreakPoint::None.try_class("offcanvas"), None); /// ``` -#[rustfmt::skip] #[derive(AutoDefault)] pub enum BreakPoint { /// **Menos de 576px**. Dispositivos muy pequeños: teléfonos en modo vertical. @@ -40,11 +37,6 @@ pub enum BreakPoint { XL, /// **1400px o más** - Dispositivos extragrandes: puestos de escritorio más grandes. XXL, - /// Para [`Container`](crate::theme::Container), ocupa el 100% del ancho del dispositivo. - Fluid, - /// Para [`Container`](crate::theme::Container), ocupa el 100% del ancho del dispositivo hasta - /// un ancho máximo indicado. - FluidMax(UnitValue) } impl BreakPoint { @@ -53,7 +45,7 @@ impl BreakPoint { /// Devuelve `true` si el valor es `SM`, `MD`, `LG`, `XL` o `XXL`; y `false` en otro caso. #[inline] pub const fn is_breakpoint(&self) -> bool { - matches!(self, Self::SM | Self::MD | Self::LG | Self::XL | Self::XXL) + !matches!(self, Self::None) } /// Genera un nombre de clase CSS basado en el punto de ruptura. @@ -65,11 +57,12 @@ impl BreakPoint { /// # Ejemplo /// /// ```rust + /// # use pagetop_bootsier::prelude::*; /// let breakpoint = BreakPoint::MD; /// let class = breakpoint.to_class("col"); /// assert_eq!(class, "col-md".to_string()); /// - /// let breakpoint = BreakPoint::Fluid; + /// let breakpoint = BreakPoint::None; /// let class = breakpoint.to_class("offcanvas"); /// assert_eq!(class, "offcanvas".to_string()); /// ``` @@ -91,12 +84,13 @@ impl BreakPoint { /// # Ejemplo /// /// ```rust + /// # use pagetop_bootsier::prelude::*; /// let breakpoint = BreakPoint::MD; /// let class = breakpoint.try_class("col"); /// assert_eq!(class, Some("col-md".to_string())); /// - /// let breakpoint = BreakPoint::Fluid; - /// let class = breakpoint.try_class("navbar-expanded"); + /// let breakpoint = BreakPoint::None; + /// let class = breakpoint.try_class("navbar-expand"); /// assert_eq!(class, None); /// ``` #[inline] @@ -113,15 +107,12 @@ impl BreakPoint { impl fmt::Display for BreakPoint { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { - Self::None => Ok(()), - Self::SM => f.write_str("sm"), - Self::MD => f.write_str("md"), - Self::LG => f.write_str("lg"), - Self::XL => f.write_str("xl"), - Self::XXL => f.write_str("xxl"), - // Devuelven "fluid" (para modelar `container-fluid`). - Self::Fluid => f.write_str("fluid"), - Self::FluidMax(_) => f.write_str("fluid"), + Self::None => Ok(()), + Self::SM => f.write_str("sm"), + Self::MD => f.write_str("md"), + Self::LG => f.write_str("lg"), + Self::XL => f.write_str("xl"), + Self::XXL => f.write_str("xxl"), } } } diff --git a/extensions/pagetop-bootsier/src/theme/container.rs b/extensions/pagetop-bootsier/src/theme/container.rs index 65ce923..22f7fc6 100644 --- a/extensions/pagetop-bootsier/src/theme/container.rs +++ b/extensions/pagetop-bootsier/src/theme/container.rs @@ -2,11 +2,12 @@ use pagetop::prelude::*; use crate::prelude::*; +// **< ContainerType >****************************************************************************** + /// Tipo de contenedor ([`Container`]). /// /// Permite aplicar la etiqueta HTML apropiada (`
`, `
`, etc.) manteniendo una API /// común a todos los contenedores. -#[rustfmt::skip] #[derive(AutoDefault)] pub enum ContainerType { /// Contenedor genérico (`
`). @@ -24,22 +25,42 @@ pub enum ContainerType { Article, } -/// Componente genérico para crear un contenedor de componentes. +// **< ContainerWidth >***************************************************************************** + +/// Define el comportamiento para ajustar el ancho de un contenedor ([`Container`]). +#[derive(AutoDefault)] +pub enum ContainerWidth { + /// Comportamiento por defecto, aplica los anchos máximos predefinidos para cada punto de + /// ruptura. Por debajo del menor punto de ruptura ocupa el 100% del ancho disponible. + #[default] + Default, + /// Aplica los anchos máximos predefinidos a partir del punto de ruptura indicado. Por debajo de + /// ese punto de ruptura ocupa el 100% del ancho disponible. + From(BreakPoint), + /// Ocupa el 100% del ancho disponible siempre. + Fluid, + /// Ocupa el 100% del ancho disponible hasta un ancho máximo explícito. + FluidMax(UnitValue), +} + +// **< Container >********************************************************************************** + +/// Componente para crear un **contenedor de componentes**. /// /// Envuelve el contenido con la etiqueta HTML indicada por [`ContainerType`]. Sólo se renderiza si /// existen componentes hijos (*children*). #[rustfmt::skip] #[derive(AutoDefault)] pub struct Container { - id : AttrId, - classes : AttrClasses, - container_type: ContainerType, - breakpoint : BreakPoint, - children : Children, - bg_color : BgColor, - text_color : TextColor, - border : Border, - rounded : Rounded, + id : AttrId, + classes : AttrClasses, + container_type : ContainerType, + container_width: ContainerWidth, + bg_color : BgColor, + text_color : TextColor, + border : Border, + rounded : Rounded, + children : Children, } impl Component for Container { @@ -55,7 +76,16 @@ impl Component for Container { self.alter_classes( ClassesOp::Prepend, [ - join_pair!("container", "-", self.breakpoint().to_string()), + join_pair!( + "container", + "-", + match self.width() { + ContainerWidth::Default => String::new(), + ContainerWidth::From(bp) => bp.to_string(), + ContainerWidth::Fluid => "fluid".to_string(), + ContainerWidth::FluidMax(_) => "fluid".to_string(), + } + ), self.bg_color().to_string(), self.text_color().to_string(), self.border().to_string(), @@ -70,8 +100,8 @@ impl Component for Container { if output.is_empty() { return PrepareMarkup::None; } - let style = match self.breakpoint() { - BreakPoint::FluidMax(w) if w.is_measurable() => { + let style = match self.width() { + ContainerWidth::FluidMax(w) if w.is_measurable() => { Some(join!("max-width: ", w.to_string(), ";")) } _ => None, @@ -168,24 +198,10 @@ impl Container { self } - /// Establece el *punto de ruptura* del contenedor. + /// Establece el comportamiento del ancho para el contenedor. #[builder_fn] - pub fn with_breakpoint(mut self, bp: BreakPoint) -> Self { - self.breakpoint = bp; - self - } - - /// Añade un nuevo componente hijo al contenedor. - pub fn add_child(mut self, component: impl Component) -> Self { - self.children - .alter_child(ChildOp::Add(Child::with(component))); - self - } - - /// Modifica la lista de hijos (`children`) aplicando una operación [`ChildOp`]. - #[builder_fn] - pub fn with_child(mut self, op: ChildOp) -> Self { - self.children.alter_child(op); + pub fn with_width(mut self, width: ContainerWidth) -> Self { + self.container_width = width; self } @@ -225,6 +241,20 @@ impl Container { self } + /// Añade un nuevo componente hijo al contenedor. + #[inline] + pub fn add_child(mut self, component: impl Component) -> Self { + self.children.add(Child::with(component)); + self + } + + /// Modifica la lista de componentes (`children`) aplicando una operación [`ChildOp`]. + #[builder_fn] + pub fn with_child(mut self, op: ChildOp) -> Self { + self.children.alter_child(op); + self + } + // **< Container GETTERS >********************************************************************** /// Devuelve las clases CSS asociadas al contenedor. @@ -237,14 +267,9 @@ impl Container { &self.container_type } - /// Devuelve el *punto de ruptura* actualmente configurado. - pub fn breakpoint(&self) -> &BreakPoint { - &self.breakpoint - } - - /// Devuelve la lista de hijos (`children`) del contenedor. - pub fn children(&self) -> &Children { - &self.children + /// Devuelve el comportamiento para el ancho del contenedor. + pub fn width(&self) -> &ContainerWidth { + &self.container_width } /// Devuelve el color de fondo del contenedor. @@ -266,4 +291,9 @@ impl Container { pub fn rounded(&self) -> &Rounded { &self.rounded } + + /// Devuelve la lista de componentes (`children`) del contenedor. + pub fn children(&self) -> &Children { + &self.children + } }