(bootsier): Añade componentes esenciales

- 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.
This commit is contained in:
Manuel Cillero 2026-08-28 19:46:56 +02:00
parent eb63a7ef37
commit c0a5a8c3ab
47 changed files with 2135 additions and 1818 deletions

View file

@ -0,0 +1,46 @@
// Verifies `BadgeBootsier::with_color()`: it overrides the Bootstrap color that `Badge` would
// otherwise derive from its `Intent`, without disturbing the class that `Badge::setup()` (core)
// already generated from that `Intent`.
use pagetop::prelude::*;
use pagetop_bootsier::Bootsier;
use pagetop_bootsier::theme::*;
#[pagetop::test]
async fn without_an_override_the_color_comes_from_the_intent() {
let mut badge = Badge::labeled(Lc::n("Admin")).with_intent(Intent::Severe);
let html = badge
.render(&mut Context::default().with_theme(&Bootsier))
.await
.into_string();
assert!(html.contains("text-bg-danger"));
}
#[pagetop::test]
async fn with_color_overrides_the_intent_derived_color() {
let mut badge = Badge::labeled(Lc::n("Beta"))
.with_intent(Intent::Severe)
.with_color(BootsierColors::Dark);
let html = badge
.render(&mut Context::default().with_theme(&Bootsier))
.await
.into_string();
assert!(html.contains("text-bg-dark"));
assert!(!html.contains("text-bg-danger"));
}
#[pagetop::test]
async fn with_color_none_restores_the_intent_derived_color() {
let mut badge = Badge::labeled(Lc::n("Beta"))
.with_intent(Intent::Severe)
.with_color(BootsierColors::Dark)
.with_color(None);
let html = badge
.render(&mut Context::default().with_theme(&Bootsier))
.await
.into_string();
assert!(html.contains("text-bg-danger"));
}

View file

@ -0,0 +1,29 @@
// Verifies that `Bootsier` overrides `Theme::intent_color()` to translate `Intent` to its own
// Bootstrap color names, instead of PageTop's own semantic vocabulary.
use pagetop::prelude::*;
use pagetop_bootsier::Bootsier;
#[pagetop::test]
async fn bootsier_translates_button_intent_to_its_bootstrap_color() {
let mut button = Button::submit(Lc::n("Save")).with_style(button::Style::Solid(Intent::Severe));
let html = button
.render(&mut Context::default().with_theme(&Bootsier))
.await
.into_string();
assert!(html.contains("btn-danger"));
assert!(!html.contains("severe"));
}
#[pagetop::test]
async fn bootsier_translates_badge_intent_to_its_bootstrap_color() {
let mut badge = Badge::labeled(Lc::n("Admin")).with_intent(Intent::Severe);
let html = badge
.render(&mut Context::default().with_theme(&Bootsier))
.await
.into_string();
assert!(html.contains("text-bg-danger"));
assert!(!html.contains("severe"));
}