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).
Identidad de usuario, sesiones en base de datos, roles y permisos (RBAC)
con "authenticated" implícito, contraseñas con Argon2id, tokens de
un solo uso para verificación de email y restablecimiento de contraseña,
y la UI de administración completa (usuarios, roles, permisos) sobre
pagetop-admin.
Incluye datos de demostración opcionales tras la feature `demo-data`.
Gestión centralizada y persistente de menús: entidades y migraciones
SeaORM, sistema de acciones para declarar menús/ítems por código, caché
in-process del árbol y los componentes `MenuBlock`/`MenuBreadcrumb`.
Panel de administración extensible: registro de secciones/páginas/
tareas/acciones vía acciones `Declare*`, formularios de configuración
automáticos (ConfigForm + SettingsSchema) y persistencia en la tabla
`settings`.
- Añade Dialog como modal de Bootstrap, con el JS de soporte para
`htmx:confirm` y el saneado de su posición fija.
- Adapta Nav, Navbar y Dropdown al reuso de los tipos movidos al core, y
traduce BootsierColors/Intent en Button y Badge, con soporte para
Light/Dark vía with_color().
- Reexporta en el tema los componentes de PageTop que faltaban: Block,
Breadcrumb, Messages, Pager, Table y form::Number.
- `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()`.
`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()`
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.
Centraliza la paginación genérica junto con `Paginated::map_items()`
para enriquecer los elementos de una página con datos de otra tabla sin
perder la metadata de paginación.
Nuevo método `oob()` para incluir fragmentos adicionales marcados con
`hx-swap-oob` en el cuerpo de la respuesta, sin necesidad de construir
el envoltorio a mano ni depender del `hx-target` de la petición.
De paso, `set_header()` usa ya las constantes de `hx::response` en vez
de literales repetidos, y se revisan comentarios.
- Nuevo `SortDir` en `pagetop::html` para representar direcciones de
orden (asc/desc) y calcular la siguiente al pulsar una cabecera.
- `hx_table::sort_link()` construye el enlace de ordenación con los
cuatro atributos `hx-*` fijos, reutilizable en cualquier tabla.
- `HtmxResponse` usa `RoutePath` en `location`/`push_url`/`replace_url`/
`redirect` para preservar "lang"; `location_json()` se separa de
`location()` para el caso de configuración JSON personalizada.
- Añade el módulo `prelude` y una batería de tests para hx, hx_table,
request, response y extension.
Amplía también los tipos reexportados (Condition, DbBackend, NotSet,
Order, Set, TransactionError, Unchanged) y habilita el mismo
re-export en migration.rs.
`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`.
Consolida los handlers de estos campos en la capa del tema. Además,
`with_floating_label()` usa un valor extra que lee en `setup()` para
forzar `multiple`/`rows` en 'select` y `textarea`.
Permite sustituir una o varias clases por otras nuevas en una sola
operación, preservando su posición. Adapta el tema Bootsier para usarla
en `Button` y elimina el handler duplicado sin referencias.
- 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.
Nuevo tipo `Preload` (junto a `StyleSheet` y `JavaScript`) que emite
`<link rel="preload">` con soporte para fuentes, estilos, scripts e
imágenes (WebP y AVIF incluidos). Bootsier lo usa para precargar las
fuentes Source Sans 3 y eliminar el FOUT en la carga inicial.
- Elimina `run_now` y convierte `initialize()` en `async fn`.
- `DBCONN` pasa de `LazyLock` a `OnceLock`; `MigratorBase` adopta
`#[pagetop::async_trait]` con métodos async nativos.
Añade `#[async_trait]` a todos los `impl Extension`, `Theme` y
`Component`. Convierte `prepare()` en `async fn` y añade `.await` a las
llamadas `render()` y `render_offcanvas()`.
`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.
Diferencia el patrón para aplicaciones (activan el motor via *feature*
en su `Cargo.toml`) y extensiones (sin *features*; la selección es
responsabilidad de la aplicación).
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.
Integra AdminLTE 4.0.0 (SCSS y JS), Bootstrap Icons 1.13.1 y las fuentes
Source Sans 3 VF; reorganiza los SCSS del tema con la nueva estructura
de *pagetop-build*.
Añade `compile_scss()`, `copy_dir()`, `copy_file()`,
`copy_file_replacing()` y `minify_js()` para preparar activos en
`build.rs`. Adopta el patrón `assets/ -> static/`: los archivos
estáticos se mueven a `assets/` y `static/` se añade a `.gitignore`. Los
`build.rs` de *pagetop* y *pagetop-htmx* se actualizan con el nuevo
patrón. La documentación del módulo se reescribe para reflejar los
nuevos cambios.
Constantes `hx-*`, `HtmxRequestExt` y `HtmxResponse` cubren el ciclo
completo: escribir atributos, leer la petición y construir la respuesta.
La extensión Htmx inyecta el script automáticamente.
Añade `IntoResponse` y `Response` al prelude de PageTop.