♻️ (bootsier): Reorganiza en capas token/class/bs

Sustituye `attrs/` y `classes/` por tres capas diferenciadas:
- `token/`: primitivas CSS (BreakPoint, Color, ScaleSize, etc.).
- `class/`: tipos compuestos (Border, Background, Margin, etc.).
- `bs/*/props.rs`: props tipadas para cada componente de Bootstrap.

El patrón de construcción es `suffix()` -> `push_to()` -> `to_class()`.
`push_to()` es `pub` en `class/` y `bs/*/props.rs` para que los temas
derivados puedan acceder a los mismos mecanismos de construcción.
This commit is contained in:
Manuel Cillero 2026-06-29 20:32:20 +02:00
parent 64db114eb0
commit f37db56ec5
47 changed files with 1307 additions and 1201 deletions

View file

@ -0,0 +1,87 @@
use pagetop::prelude::*;
// **< ScaleSize >**********************************************************************************
/// Escala discreta de tamaños para clases utilitarias de Bootstrap.
///
/// Se usa como parámetro de tamaño en [`Border`](crate::theme::class::Border),
/// [`Margin`](crate::theme::class::Margin) y [`Padding`](crate::theme::class::Padding). La
/// variante `Auto` no aplica en `Padding`.
#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)]
pub enum ScaleSize {
/// Sin tamaño (no define ninguna clase).
#[default]
None,
/// Tamaño automático.
Auto,
/// Escala cero.
Zero,
/// Escala uno.
One,
/// Escala dos.
Two,
/// Escala tres.
Three,
/// Escala cuatro.
Four,
/// Escala cinco.
Five,
}
impl ScaleSize {
// Devuelve el sufijo de tamaño (`"-0"`, `"-1"`, etc.), o `None` si no define ninguna clase.
// `Auto` devuelve `Some("")` para que `push_to` emita sólo el prefijo, sin sufijo de tamaño.
#[rustfmt::skip]
#[inline]
const fn suffix(self) -> Option<&'static str> {
match self {
Self::None => None,
Self::Auto => Some(""),
Self::Zero => Some("-0"),
Self::One => Some("-1"),
Self::Two => Some("-2"),
Self::Three => Some("-3"),
Self::Four => Some("-4"),
Self::Five => Some("-5"),
}
}
// Añade el tamaño a la cadena de clases usando el prefijo dado.
#[inline]
pub(crate) fn push_to(self, classes: &mut String, prefix: &str) {
if !prefix.is_empty() {
if let Some(suffix) = self.suffix() {
if !classes.is_empty() {
classes.push(' ');
}
classes.push_str(prefix);
classes.push_str(suffix);
}
}
}
}
// **< Side >***************************************************************************************
/// Lados sobre los que aplicar una clase utilitaria (respetando LTR/RTL).
///
/// Se usa como selector de lado en [`Border`](crate::theme::class::Border),
/// [`Margin`](crate::theme::class::Margin) y [`Padding`](crate::theme::class::Padding).
#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)]
pub enum Side {
/// Todos los lados.
#[default]
All,
/// Lado superior.
Top,
/// Lado inferior.
Bottom,
/// Lado lógico de inicio (respetando RTL).
Start,
/// Lado lógico de fin (respetando RTL).
End,
/// Lados lógicos laterales (abreviatura *x*).
LeftAndRight,
/// Lados superior e inferior (abreviatura *y*).
TopAndBottom,
}