pagetop/extensions/pagetop-bootsier/tests/navbar_offcanvas.rs
Manuel Cillero c47724bb68 ✨ (base): Implementa Navbar con funcionalidad base
Añade `Navbar::with_position()` y `navbar::Position` al núcleo, con las
clases de Basic para barras fijas y pegajosas, y `navbar::Item::form()`
para mostrar un formulario dentro de la barra.

Las barras sin botón de despliegue (`Simple` y `SimpleBrandLeft`) ya no
colapsan: el punto de corte no les afecta y su menú se mantiene en
línea, con salto de línea si no cabe. En Bootsier usan `navbar-expand` y
`SimpleBrandLeft` agrupa los contenidos junto a la marca.
2026-09-21 16:27:44 +02:00

62 lines
2.4 KiB
Rust

// Verifies that a `Navbar` with its content in an `Offcanvas` renders a working panel: the toggle
// button must point to the `id` of the panel, and the panel must carry its own placement class.
use pagetop::prelude::*;
use pagetop_bootsier::theme::*;
fn cx() -> Context {
Context::default().with_theme(&pagetop_bootsier::Bootsier)
}
fn panel(placement: bs::offcanvas::Placement) -> bs::Offcanvas {
bs::Offcanvas::new().with_placement(placement)
}
#[pagetop::test]
async fn offcanvas_button_points_to_the_panel_id() {
let brand = || Brand::new().with_title(Lc::n("PageTop"));
let navbars = [
bs::Navbar::offcanvas(panel(bs::offcanvas::Placement::Start)),
bs::Navbar::offcanvas_brand_left(brand(), panel(bs::offcanvas::Placement::Start)),
bs::Navbar::offcanvas_brand_right(brand(), panel(bs::offcanvas::Placement::Start)),
];
for mut navbar in navbars {
navbar = navbar.with_item(bs::navbar::Item::nav(
bs::Nav::new().with_item(bs::nav::Item::link(Lc::n("Home"), "/")),
));
let html = navbar.render(&mut cx()).await.into_string();
// The panel is rendered by the navbar, so the navbar must set its `id` up.
let target = html
.split(r##"data-bs-target="#"##)
.nth(1)
.and_then(|rest| rest.split('"').next())
.unwrap_or_default();
assert!(!target.is_empty(), "the button has no target in {html}");
assert!(html.contains(&format!(r#"aria-controls="{target}""#)));
assert!(
html.contains(&format!(r#"id="{target}""#)),
"no panel with id `{target}` in {html}"
);
}
}
#[pagetop::test]
async fn offcanvas_panel_gets_its_own_classes() {
for (placement, class) in [
(bs::offcanvas::Placement::Start, "offcanvas-start"),
(bs::offcanvas::Placement::End, "offcanvas-end"),
] {
let mut navbar = bs::Navbar::offcanvas(panel(placement)).with_item(bs::navbar::Item::nav(
bs::Nav::new().with_item(bs::nav::Item::link(Lc::n("Home"), "/")),
));
let html = navbar.render(&mut cx()).await.into_string();
// Without them Bootstrap would show the panel inline instead of hiding and placing it.
assert!(
html.contains(&format!(r#"class="offcanvas {class}""#)),
"missing `offcanvas {class}` in {html}"
);
}
}