From 3b01894024610481cd9bb925b5e27bb6e6c68d79 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Thu, 6 Aug 2026 22:37:28 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20(base):=20A=C3=B1ade=20componente?= =?UTF-8?q?=20Pager?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Incluye soporte HTMX vía `sort_link()`/`hx_pager` para navegación sin recarga. --- examples/form-controls.rs | 18 +- extensions/pagetop-htmx/src/hx.rs | 7 + extensions/pagetop-htmx/src/hx_pager.rs | 32 ++ extensions/pagetop-htmx/src/hx_table.rs | 37 +- extensions/pagetop-htmx/src/lib.rs | 2 + extensions/pagetop-htmx/tests/hx_table.rs | 2 +- src/base/component.rs | 3 + src/base/component/form/hidden.rs | 10 + src/base/component/pager.rs | 422 ++++++++++++++++++++++ src/html/route_path.rs | 14 +- src/html/sort_dir.rs | 20 +- src/locale/en-US/base.ftl | 7 + src/locale/es-ES/base.ftl | 7 + tests/component_pager.rs | 331 +++++++++++++++++ 14 files changed, 881 insertions(+), 31 deletions(-) create mode 100644 extensions/pagetop-htmx/src/hx_pager.rs create mode 100644 src/base/component/pager.rs create mode 100644 tests/component_pager.rs diff --git a/examples/form-controls.rs b/examples/form-controls.rs index 29010de6..3e9a3f3d 100644 --- a/examples/form-controls.rs +++ b/examples/form-controls.rs @@ -137,11 +137,7 @@ async fn form_controls(request: HttpRequest) -> Result { ), ) // Campo oculto (form::Hidden). - .with_child( - form::Hidden::new() - .with_name("origin") - .with_value("form-selections"), - ) + .with_child(form::Hidden::field("origin", "form-selections")) // Botones de acción. .with_child(Button::submit(L10n::t("btn_submit", &LOC)).with_prop( PropsOp::add_classes(class::ButtonColor::solid( @@ -261,11 +257,7 @@ async fn form_controls(request: HttpRequest) -> Result { ), ) // Campo oculto (form::Hidden). - .with_child( - form::Hidden::new() - .with_name("origin") - .with_value("form-text"), - ) + .with_child(form::Hidden::field("origin", "form-text")) // Botones de acción. .with_child(Button::submit(L10n::t("btn_submit", &LOC)).with_prop( PropsOp::add_classes(class::ButtonColor::solid( @@ -415,11 +407,7 @@ fn form_lists() -> Form { form // Campo oculto (form::Hidden). - .with_child( - form::Hidden::new() - .with_name("origin") - .with_value("form-lists"), - ) + .with_child(form::Hidden::field("origin", "form-lists")) // Botones de acción. .with_child( Button::submit(L10n::t("btn_submit", &LOC)).with_prop(PropsOp::add_classes( diff --git a/extensions/pagetop-htmx/src/hx.rs b/extensions/pagetop-htmx/src/hx.rs index fb4ae54b..2b5c08dc 100644 --- a/extensions/pagetop-htmx/src/hx.rs +++ b/extensions/pagetop-htmx/src/hx.rs @@ -490,6 +490,13 @@ pub mod swap { pub const INNER_HTML: &str = "innerHTML"; /// Reemplaza el elemento objetivo completo. pub const OUTER_HTML: &str = "outerHTML"; + /// Reemplaza el elemento objetivo completo y desplaza la vista al borde superior tras el + /// intercambio (combina [`OUTER_HTML`] con el modificador `scroll:top`). + /// + /// Pensado para listados paginados/ordenables cuyo `hx-swap` sustituye un contenedor completo + /// (tabla + paginador) al variar el número de filas entre páginas. Sin este anclaje la posición + /// del scroll tras el intercambio queda desajustada. + pub const OUTER_HTML_SCROLL_TOP: &str = "outerHTML scroll:top"; /// Inserta la respuesta antes de la etiqueta de apertura del objetivo. pub const BEFORE_BEGIN: &str = "beforebegin"; /// Inserta la respuesta al inicio del contenido del objetivo. diff --git a/extensions/pagetop-htmx/src/hx_pager.rs b/extensions/pagetop-htmx/src/hx_pager.rs new file mode 100644 index 00000000..7a126d17 --- /dev/null +++ b/extensions/pagetop-htmx/src/hx_pager.rs @@ -0,0 +1,32 @@ +//! Soporte HTMX al componente [`Pager`]. +//! +//! [`Pager`] no conoce HTMX ni ninguna otra librería de interactividad. Cada enlace de página ya +//! funciona como una petición normal, y el elemento `