Commit graph

292 commits

Author SHA1 Message Date
16eec316c4 ♻️ (base): Reorganiza el componente Intro 2026-09-20 23:53:18 +02:00
c6cd4fcd7d ✨ (base): Añade with_width() a Container 2026-09-19 03:14:21 +02:00
9143f1eb26 ✨ (pagetop): Añade with_expand() a Navbar
Navbar guarda el punto de corte a partir del cual deja de colapsar
(`Breakpoint::Md` por defecto) y añade la clase `navbar-expand-{nombre}`
o `navbar-expand` si no tiene ancho mínimo. El nombre lo resuelve el
tema activo con `Theme::breakpoint_entry()`.
2026-09-19 01:52:55 +02:00
307ca6f62c ✨ (pagetop): Añade Grid y extrae Flex de Container 2026-09-18 16:49:09 +02:00
dfff12881f 🚧 (pagetop): Comparte align entre Flex y Grid
Extrae `Align`/`AlignContent`/`ItemAlign`/`Gap` de Flexbox a un nuevo
módulo neutral `html::align` (`Items`/`Content`/`ItemSelf`/`Gap`) para
que tambien lo use CSS Grid.
2026-09-13 23:08:39 +02:00
3c3ffc91e6 ♻️ (pagetop): with_prop() acepta impl Into<PropsOp>
`FlexItem`, `Margin` y `Padding` se pasan directamente gracias a `From`
 hacia `PropsOp`, sin `PropsOp::flex_item()`/`margin()`/`padding()` ni
`.into()` explícito. Revisadas todas las llamadas en el código para
simplificarlas.
2026-09-13 01:38:33 +02:00
50e4b42fe4 ✨ (pagetop): Añade Margin y Padding nativos
- Nuevo módulo `html::spacing` con `Margin`/`Padding`: igual que
  `FlexItem`, se resuelven generando clases CSS dinámicamente y se
  aplican con `PropsOp::margin()`/`PropsOp::padding()` sobre cualquier
  componente.
- Elimina `Margin`/`Padding` de `pagetop-bootsier`.
- Añade el ejemplo `intro-spacing` con los patrones de uso típicos.
2026-09-13 00:48:11 +02:00
64113aff09 ♻️ (pagetop): Sustituye StyleSheet::inline
- `StyleSheet::inline` se resuelve ahora con `ResponsiveStyles`.
- `StyleSheet` se simplifica a sólo hojas de estilo externas.
- `ResponsiveStyles` añade `add_styles()` para declarar varias
  propiedades en una sola llamada.
- `AssetsOp` gana un constructor por variante y conversiones
  "From<Favicon/Preload/StyleSheet/JavaScript>" para pasarlos
  directamente a `with_assets()`.
2026-09-12 20:44:17 +02:00
0b8f3f3000 ✨ (pagetop): Añade puntos de corte a Flex/FlexItem
- `Breakpoint` gana variante `Xxxl` y métodos `name()`/`min_width()`/
  `resolved()`, para consultarse contra el tema activo.
- `Theme::breakpoint_entry()` sustituye a `breakpoint_min_width()`:
  devuelve un `BreakpointEntry` con nombre y ancho mínimo.
- Nuevo `Responsive<T>`, valor en cascada mobile-first por punto de
  corte.
- Ejemplo `examples/intro-responsive.rs` con los patrones de uso.
2026-09-12 11:13:19 +02:00
8577ca8a59 ♻️ (pagetop): Props::unpack() exige &mut Context 2026-09-08 07:28:50 +02:00
ee1b48ff3f ♻️ (pagetop): Divide props.rs en varios módulos 2026-09-06 20:36:12 +02:00
28f1eee391 ♻️ (pagetop): Separa handle_component() en 2 métodos
`Theme::handle_component()` se divide en `setup_component()` (síncrono,
muta por tipo con la macro homónima) y `render_component()` (async,
decide el renderizado con su propia macro). Aplica mismo criterio que ya
separa `Component::setup()` de `prepare()`.
2026-09-06 13:07:01 +02:00
1e2d171805 ♻️ (pagetop): setup() recibe &mut Context
Antes sólo mutaba el propio componente; ahora también puede aplicar
ajustes síncronos sobre el Context, visibles para las extensiones que
intercepten BeforeRender. La frontera con prepare() pasa a ser de
sincronía, no de qué puede mutar cada uno.
2026-09-06 09:04:44 +02:00
f2a7507317 ✨ (theme): Añade Breakpoint y ResponsiveStyles
- Nuevo `Breakpoint` (`Xs`/`Sm`/`Md`/`Lg`/`Xl`/`Xxl`) y
  `Theme::breakpoint_min_width()`, que traduce cada variante al ancho
  mínimo CSS del tema activo (mismo patrón que `Theme::intent_color()`).
- `ResponsiveStyles` acumula declaraciones `property: value` agrupadas
  por punto de corte (opcional: `None` para reglas siempre activas, sin
  depender del tema) y por clase o clases. Aplica first-write-wins para
  clases utilitarias repetidas por muchos componentes. `render()` las
  agrupa en bloques `@media (min-width: ...)` mobile-first, sin saltos
  de línea.
2026-09-06 01:46:06 +02:00
b163b7726e ♻️ (util): Simplifica normalize_ascii*
`normalize_ascii_or_empty()` pasa a llamarse `normalize_ascii()` (la
variante indulgente, la más usada); la antigua `normalize_ascii()` pasa
a `normalize_ascii_non_blank()`.
2026-09-05 21:19:15 +02:00
ab1d4f0efb ♻️ (pagetop): Incorpora Context al render de Props 2026-09-05 00:19:39 +02:00
17e16652e4 ✨ (pagetop): Añade Flex/FlexItem para usar Flexbox
Container y Navbar lo adoptan vía `with_flex()`/`PropsOp::flex_item()`.
Y se elimina `ButtonSet` porque su funcionalidad queda cubierta por este
mecanismo más general. Incluye el ejemplo `examples/intro-flex.rs` con
los patrones de uso.
2026-09-04 01:04:53 +02:00
4e4fdf7b10 📝 Resalta términos en docs de Block y Breadcrumb 2026-08-29 19:52:45 +02:00
1be3d88888 ♻️ Migra #[builder_fn] a #[builder_impl]
Sustituye las ~400 anotaciones `#[builder_fn]` método a método por un
único `#[builder_impl]` por `impl`/`trait`, en 74 ficheros de pagetop y
sus extensiones (admin, bootsier, menu, user).
2026-08-29 19:25:58 +02:00
c34dc02357 ✨ (macros): Añade #[builder_impl]
Aplica `#[builder_fn]` a todos los métodos `with_...()` de un bloque
`impl` o de una definición de trait de una vez, sin anotarlos uno a uno.
2026-08-29 19:19:58 +02:00
35ae5bb6a8 ✨ (base): Añade componentes Nav y Navbar
Dropdown incorpora tamaño y estilo de botón configurables
(`button::Size`/`Style`), reutilizados también por Navbar. El tema Basic
sirve `basic.min.css` y añade el JS de inicialización de Navbar.
2026-08-28 18:24:43 +02:00
da959183f6 ✨ (button): Añade Button::anchor() para navegación
- Renderiza un `<a href>` real con el aspecto de un botón, distinto del
  estilo puramente visual `button::Style::Link`.
- Renombra `ButtonKind`/`ButtonStyle` a `Kind`/`Style`.
- Añade `button::Size` (`button-sm`/`button-lg`).
2026-08-28 11:38:57 +02:00
434d31c5eb 📝 (doc): Sustituye "..." por "etc." 2026-08-28 11:16:58 +02:00
56a6691c87 🚧 (theme): Renombra variantes de Intent
Renombra `Intent::Secondary`/`Danger` a `Neutral`/`Severe` y actualiza
Badge y su CSS por defecto (basic.css) al nuevo vocabulario.

Introduce el punto de extensión `Theme::intent_color()`, que traduce una
`Intent` al nombre de color de la paleta propia de cada tema, con
`Intent::color(cx)` como atajo de uso desde los componentes.
2026-08-28 01:10:45 +02:00
af53cd4b52 ♻️ (dropdown): Integra Dropdown con accessible-menu
Renombra `dropdown.init.js` a `basic.dropdown.init.js` y añade cierre
cruzado entre menús abiertos y cierre al clicar fuera. Corrige el icono
de apertura/cierre y el estado cerrado por defecto de dropdown-menu.
Migra `with_item` de `ChildOp` a `TypedOp<dropdown::Item>`.
2026-08-26 23:58:33 +02:00
76c5cb9b76 ✨ (base): Añade componente Dialog
Sustituye `PropsOp::Translate` por `Rename` para que los temas traduzcan
atributos `data-dialog-*` al vocabulario propio (p. ej. `data-bs-*` en
Bootsier).
2026-08-26 21:56:10 +02:00
3c67d9d04c ✨ (props): Añade la operación PropsOp::translate
Permite a un tema traducir el vocabulario de atributos de un componente
al suyo propio (p. ej. `data-dialog-*` -> `data-bs-*`) sin conocer su
valor, respetando el que ya tuviera el destino si existía.
2026-08-26 06:55:37 +02:00
99a4837e11 ✨ (button): Añade componentes Button y ButtonSet 2026-08-24 20:18:29 +02:00
c8654a5742 ✨ (core): Añade TypedOp<C> para restringir Children
Mismo repertorio de operaciones que `ChildOp`, pero cada variante exige
un componente de tipo `C`, evitando que un componente ajeno a ese tipo
acabe en una lista pensada para un único tipo de elemento.
2026-08-24 20:00:12 +02:00
d8f82ea1d2 ♻️ (response): Renombra Waypoint::as_str a as_deref 2026-08-23 13:39:38 +02:00
e24b9ab9de ♻️ (pagetop): Logotipo embebido y Badge en Intent
- `PageTopSvg::markup_with()` fusiona `Props` y controla la etiqueta
  accesible directamente en el `<svg>`.
- `Image` ya no duplica accesibilidad para el logotipo y corrige el
  `alt` vacío en el resto de fuentes (Responsive/Thumbnail/Plain).
- Sustituye `BadgeKind` y el `ColorName`/`IntoColor` de `core/theme`
  por un `Intent` compartido.
2026-08-22 09:44:28 +02:00
4ba66f5995 🚧 (base): Añade BadgeKind para el tipo de Badge 2026-08-21 11:18:16 +02:00
997017bb75 🎨 (core): Retoques de estilo menores 2026-08-21 08:23:39 +02:00
b50d186fb1 ✨ (theme): Añade IntoColor para colores opcionales
Permite que métodos como `with_color(color: impl IntoColor)` acepten un
color directo o uno opcional (`Some(...)`/`None`) sin la ambigüedad que
produce un `Into<Option<C>>` genérico.
2026-08-21 08:18:28 +02:00
bb6855e41f ✨ (theme): Añade ColorName y CoreColors
Nuevo trait `ColorName` para que cada tema aporte su propia paleta de
colores; `CoreColors` es la paleta por defecto.

Aprovecha para refactorizar `core/theme.rs` en submódulos por concepto.
2026-08-20 21:54:12 +02:00
fe2b2c176f ♻️ (bootsier): Mueve Brand al core de PageTop 2026-08-17 05:53:55 +02:00
bf4c635e59 ♻️ (pagetop): Sustituye Attr<T> por Option<T>
`Attr<T>` no aportaba nada sobre `Option<T>` directo: `Getters` ya trata
los campos `Option<T>` como caso especial (`Option<&T>`, o `Option<T>`
con `#[getters(copy)]`) y `#[builder_fn]` funciona igual sobre ellos.
2026-08-17 05:28:12 +02:00
213aa18b12 ♻️ (locale): Sustituye Attr<Lc> por Lc::none() 2026-08-17 03:16:49 +02:00
c3ff8a6ff8 ♻️ (bootsier): Mueve Image al core de PageTop
`Image`, `Size` y `Source` pasan a `pagetop::base::component` como
componente genérico reutilizable por cualquier tema. Bootsier
sustituye las clases semánticas por las de Bootstrap (`img-fluid`,
`img-thumbnail`) interceptando `setup()`.
2026-08-17 00:55:35 +02:00
745d492d5b ✨ (html): Evita duplicar atributos de Props
`html!` recopila los atributos literales de cada elemento y evita que
`Props` los duplique al renderizar.
2026-08-17 00:02:20 +02:00
ed30b2ae17 ✨ (props): Añade ReplaceAllClasses
Sustituye clases sólo si están todas las indicadas en el primer valor; a
diferencia de `ReplaceClasses`, no actúa parcialmente si falta alguna.
Renombra `Props::has_class()`/`has_any_class()` a `has_all_classes()`/
`has_classes()`, que la nueva variante usa internamente para comprobar
la condición.
2026-08-16 13:58:47 +02:00
946d335664 ✨ (base): Añade componente Dropdown 2026-08-14 20:01:15 +02:00
e5431bc7d7 ✨ (base): Añade componente Messages
Muestra los mensajes acumulados en el Context por severidad.
2026-08-13 17:35:23 +02:00
3930499664 🐛 (table): Añade conversión From<C> a Cell 2026-08-13 15:29:54 +02:00
5842ea6efc ✨ (base): Añade componente Table
Incluye columnas ordenables (`table::SortLink`), paso de props/atributos
a filas y celdas para HTMX, y un mensaje de "sin datos" traducible con
valor por defecto.
2026-08-13 15:17:23 +02:00
17a9f0c9e0 ♻️ (form): Añade #[builder_fn] a Item y Group
Uniforma el criterio con el resto de elementos de componente (`Row`/
`Cell`/`Column`/`SortLink` en table, `Crumb` en breadcrumb) generando su
`alter_...` equivalente para poder mutarse con `&mut self`.
2026-08-13 11:01:32 +02:00
aa8c4100b0 ✨ (base): Añade conversión de Lc a Child/ChildOp 2026-08-12 23:57:31 +02:00
be10dd28a1 ♻️ (locale): Renombra L10n a Lc
Simplifica el nombre del tipo de localización. Actualiza todas las
referencias en el crate principal, extensiones, ejemplos y tests.
2026-08-12 22:56:09 +02:00
3198b74399 🐛 (locale): Corrige escapado de L10n::using()
`L10n::using()` insertaba el texto de `L10n::n()` sin escapar,
tratándolo igual que una traducción de confianza (`l()`/`t()`); ahora se
escapa como cualquier otro valor interpolado con `html!`.

Además, `using()` no debe usarse en valores de atributo. Su marcado de
confianza para `l()`/`t()` podría romper el delimitador si la traducción
contuviera una comilla. Se sustituye por `lookup()`
2026-08-12 14:28:47 +02:00
6bea4a5793 ✨ (base): Añade componente Breadcrumb 2026-08-11 00:46:45 +02:00