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#"