From 165cb498800189b9cebcc779ed7e1de112cf2855 Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Sat, 26 Sep 2026 14:21:39 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20(base):=20A=C3=B1ade=20with=5Fmenu?= =?UTF-8?q?=5Fend()=20para=20men=C3=BA=20al=20final?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/css/basic.css | 5 ++ .../pagetop-bootsier/src/theme/bs/dropdown.rs | 15 +++++- .../pagetop-bootsier/src/theme/bs/nav.rs | 7 ++- .../tests/breakpoint_class.rs | 53 +++++++++++++++++++ src/base/component/dropdown/component.rs | 25 ++++++++- src/base/component/nav/item.rs | 2 +- tests/component_dropdown.rs | 50 +++++++++++++++++ 7 files changed, 152 insertions(+), 5 deletions(-) create mode 100644 tests/component_dropdown.rs diff --git a/assets/css/basic.css b/assets/css/basic.css index b323e0e0..92e1b943 100644 --- a/assets/css/basic.css +++ b/assets/css/basic.css @@ -425,6 +425,11 @@ body { .dropdown-menu.show { display: block; } +/* Anchors the menu's right edge to the button's right edge, so it opens inwards. */ +.dropdown-menu-end { + left: auto; + right: 0; +} /* Options and headers stay on one line, so the menu grows to fit the longest one. */ .dropdown-item { diff --git a/extensions/pagetop-bootsier/src/theme/bs/dropdown.rs b/extensions/pagetop-bootsier/src/theme/bs/dropdown.rs index 829f0f24..f988605f 100644 --- a/extensions/pagetop-bootsier/src/theme/bs/dropdown.rs +++ b/extensions/pagetop-bootsier/src/theme/bs/dropdown.rs @@ -56,6 +56,11 @@ pub trait DropdownBootsier { fn with_direction(self, direction: Direction) -> Self; /// Configura la alineación horizontal (con posible comportamiento *responsive* adicional). + /// + /// Si se deja en [`MenuAlign::Start`] (por defecto), se respeta [`with_menu_end()`]; cualquier + /// otra alineación prevalece sobre él. + /// + /// [`with_menu_end()`]: pagetop::base::component::Dropdown::with_menu_end fn with_menu_align(self, align: MenuAlign) -> Self; /// Configura la posición del menú. @@ -135,9 +140,15 @@ pub(crate) async fn render( let direction = dropdown .props() .extra_or(EXTRA_DIRECTION, Direction::default()); - let menu_align = dropdown + let menu_align = match dropdown .props() - .extra_or(EXTRA_MENU_ALIGN, MenuAlign::default()); + .extra_or(EXTRA_MENU_ALIGN, MenuAlign::default()) + { + // `with_menu_end()` del núcleo se traduce a `MenuAlign::End`, pero sólo si no hay una + // alineación propia diferente a la predeterminada (`Start`), que prevalece. + MenuAlign::Start if *dropdown.menu_end() => MenuAlign::End, + align => align, + }; let menu_position = dropdown .props() .extra_or(EXTRA_MENU_POSITION, MenuPosition::default()); diff --git a/extensions/pagetop-bootsier/src/theme/bs/nav.rs b/extensions/pagetop-bootsier/src/theme/bs/nav.rs index 5567bef9..90373526 100644 --- a/extensions/pagetop-bootsier/src/theme/bs/nav.rs +++ b/extensions/pagetop-bootsier/src/theme/bs/nav.rs @@ -169,6 +169,11 @@ pub(crate) async fn item_render(item: &Item, cx: &mut Context) -> Result Result String { + let mut dropdown = dropdown + .with_title(Lc::n("Menu")) + .with_item(bs::dropdown::Item::link(Lc::n("Home"), "/")); + dropdown.render(&mut cx()).await.into_string() +} + +#[pagetop::test] +async fn dropdown_menu_end_maps_to_the_end_alignment() { + let html = dropdown_menu_html(bs::Dropdown::new().with_menu_end(true)).await; + assert!(html.contains(r#"