`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()`.
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.
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).
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.
- 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`).
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.
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>`.
Sustituye `PropsOp::Translate` por `Rename` para que los temas traduzcan
atributos `data-dialog-*` al vocabulario propio (p. ej. `data-bs-*` en
Bootsier).
- `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.
`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.
`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()`.
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.
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`.
`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()`
Sustituye el bool de `summary` por `PagerVisibility`, con `Auto` como
valor por defecto: se activa igual que los botones de navegación y el
formulario de salto, sólo cuando el listado se trunca.
Ajusta el cálculo de la ventana de páginas cerca de los extremos,
convierte la elipsis en una celda `.page-link` real (antes texto suelto
sin borde/fondo), separa el texto visible del aria-label accesible en
los botones anterior/siguiente, añade `with_align()` y ajusta el ancho
del campo de salto al número de dígitos.
Introduce `CoreRegions::Aside` como nueva región de plantilla, entre
Header y Content, y Template ahora envuelve el cuerpo en `div.wrapper`,
omitiendo el renderizado si no hay contenido.
`CoreRegion`, `ReservedRegion` y `CoreTemplate` pasan a plural
(`CoreRegions`, `ReservedRegions`, `CoreTemplates`) para no confundirlos
con otras definiciones, y se amplía la documentación del módulo theme.
Añade nuevas variantes `Kind::StrictText` y `StrictPassword`
(`Field::strict_text()` y `strict_password()`) para forzar en el campo
`autocomplete=off`, desactivar spellcheck y autocorrect, aplicar
`readonly+onfocus`, y enmascarar las contraseñas vía CSS en vez de
`type="password"`. Replicado en pagetop-bootsier.
- Añade `#[builder_fn]` a `with_width()`/`with_floating_label()`.
- `Rounded::new()` pasa a aplicar el radio por defecto
(`Rounded::default()` queda sin redondeo).
- `Form::action` usa `Route` en lugar de `AttrValue`, y `check::Item`
expone `value` en vez de `name` para generar casillas con `name`
compartido valores distintos.
Introduce Region y Template (`base::component::layout`) para componer el
`<body>` de una página, con captura explícita vía `handle_component()`
en lugar de maquetado implícito:
- `RegionName`/`TemplateName` (`core/theme.rs`) como interfaces de
identidad; `CoreRegion` (`Header`/`Content`/`Footer`) y `CoreTemplate`
(`Standard`/`Admin`) como catálogo por defecto.
- `ReservedRegion` (`PageTop`/`PageBottom`, en `response/page.rs`) queda
fuera de `CoreRegion`. `Page::render()` las renderiza siempre,
envolviendo `Theme::render_page_body()`, con independencia de la
plantilla o el tema activos.
- Elimina `TemplateSource` en `Context`: la plantilla pasa a ser un
`TemplateRef` fijo, sin resolución por tema (ese mecanismo nunca llegó
a implementarse).
- La personalización por tema es por captura (`handle_component()` +
`downcast_ref()`), no por sustituir qué constante se resuelve.
- Corrige referencias obsoletas a `DefaultRegions` por `CoreRegion`.
- Sustituye `tests/theme_template.rs` (API anterior) por
`tests/component_template.rs`, que cubre el patrón de captura con el
API nuevo.
`Route` resuelve URLs sensibles al `Context`/idioma en propiedades de
componentes; `RoutePath` (renombrado desde html/route.rs) es el valor
concreto de ruta + query. `Waypoint` transporta la URL de retorno entre
pantallas de listado/alta/edición vía query string.
Ajusta `Context::route()`, `Redirect` y los componentes que aceptan
rutas para integrarse con el nuevo tipo `Route`.
`Container` y `Kind` pasan a `pagetop::base::component` como componente
genérico reutilizable por cualquier tema. Bootsier conserva `Width` y
añade el *trait* `ContainerBootsier`, que guarda el ancho como valor
extra en `Props`.
- Reordena campos, variantes y métodos para mayor consistencia interna.
- Añade `extra_or`, `extra_or_default` y `extra_or_else` a `Props`.
- Mejora la documentación y amplía los tests de integración.
`prepare()` de `Component`, `render()` de `Region` y `Template`, y la
implementación de `ComponentRender` pasan a ser funciones async. Se
actualizan todos los componentes base, helpers, tests y ejemplos.
Introduce `Props`/`PropsOp` para gestionar pares `atributo="valor"` y
clases CSS para aplicar en componentes.
- Constructores `Props::new()`, `Props::classes()` y `Props::default()`.
- `Page.body_classes` reemplazado por `body_props` (permite atributos
arbitrarios en `<body>`, no sólo clases).
- Tests nuevos para atributos y reescritos para clases.