♻️ (locale): Renombra L10n a Lc

Simplifica el nombre del tipo de localización. Actualiza todas las
referencias en el crate principal, extensiones, ejemplos y tests.
This commit is contained in:
Manuel Cillero 2026-08-12 22:56:09 +02:00
parent 3198b74399
commit be10dd28a1
65 changed files with 612 additions and 621 deletions

View file

@ -65,9 +65,9 @@ async fn homepage(request: HttpRequest) -> Result<Markup, ErrorPage> {
.with_theme(&Bootsier)
.with_child(
Block::new()
.with_title(L10n::l("sample_title"))
.with_title(Lc::l("sample_title"))
.with_child(Html::with(|cx| html! {
p { (L10n::l("sample_content").using(cx)) }
p { (Lc::l("sample_content").using(cx)) }
})),
)
.render().await
@ -102,12 +102,12 @@ pub struct Bootsier;
#[async_trait]
impl Extension for Bootsier {
fn name(&self) -> L10n {
L10n::t("extension_name", &LOCALES_BOOTSIER)
fn name(&self) -> Lc {
Lc::t("extension_name", &LOCALES_BOOTSIER)
}
fn description(&self) -> L10n {
L10n::t("extension_description", &LOCALES_BOOTSIER)
fn description(&self) -> Lc {
Lc::t("extension_description", &LOCALES_BOOTSIER)
}
fn theme(&self) -> Option<ThemeRef> {

View file

@ -15,7 +15,7 @@ const EXTRA_TEXT_BG: &str = "bootsier.badge.text_bg";
/// use pagetop::prelude::*;
/// use pagetop_bootsier::theme::*;
///
/// let admin = bs::Badge::labeled(L10n::n("Admin")).with_text_bg(ThemeColor::Danger);
/// let admin = bs::Badge::labeled(Lc::n("Admin")).with_text_bg(ThemeColor::Danger);
/// ```
pub trait BadgeBootsier {
#[builder_fn]

View file

@ -5,7 +5,7 @@
//! navegación, botones de acción, encabezados o divisores visuales.
//!
//! Los ítems pueden estar activos, deshabilitados o abrirse en nueva ventana según su contexto y
//! configuración, y permiten incluir etiquetas localizables usando [`L10n`](pagetop::locale::L10n).
//! configuración, y permiten incluir etiquetas localizables usando [`Lc`](pagetop::locale::Lc).
mod props;
pub use props::{AutoClose, Direction, MenuAlign, MenuPosition};

View file

@ -27,22 +27,22 @@ use crate::theme::*;
/// use pagetop_bootsier::theme::*;
///
/// let dd = bs::Dropdown::new()
/// .with_title(L10n::n("Menu"))
/// .with_title(Lc::n("Menu"))
/// .with_button_color(class::ButtonColor::solid(token::Color::Secondary))
/// .with_auto_close(bs::dropdown::AutoClose::ClickableInside)
/// .with_direction(bs::dropdown::Direction::Dropend)
/// .with_item(bs::dropdown::Item::link(L10n::n("Home"), |_| "/".into()))
/// .with_item(bs::dropdown::Item::link_blank(L10n::n("Doc"), |_| "https://docs.rs".into()))
/// .with_item(bs::dropdown::Item::link(Lc::n("Home"), "/"))
/// .with_item(bs::dropdown::Item::link_blank(Lc::n("Doc"), "https://docs.rs"))
/// .with_item(bs::dropdown::Item::divider())
/// .with_item(bs::dropdown::Item::header(L10n::n("User session")))
/// .with_item(bs::dropdown::Item::button(L10n::n("Sign out")));
/// .with_item(bs::dropdown::Item::header(Lc::n("User session")))
/// .with_item(bs::dropdown::Item::button(Lc::n("Sign out")));
/// ```
#[derive(AutoDefault, Clone, Debug, Getters)]
pub struct Dropdown {
/// Devuelve identificador, clases CSS, atributos HTML y valores extra del componente.
props: Props,
/// Devuelve el título del menú desplegable.
title: L10n,
title: Lc,
/// Devuelve el tamaño configurado del botón.
button_size: class::ButtonSize,
/// Devuelve el color/estilo configurado del botón.
@ -133,7 +133,7 @@ impl Component for Dropdown {
aria-expanded="false"
{
span class="visually-hidden" {
(L10n::t("dropdown_toggle", &LOCALES_BOOTSIER).using(cx))
(Lc::t("dropdown_toggle", &LOCALES_BOOTSIER).using(cx))
}
}
};
@ -194,7 +194,7 @@ impl Dropdown {
/// Establece el título del menú desplegable.
#[builder_fn]
pub fn with_title(mut self, title: L10n) -> Self {
pub fn with_title(mut self, title: Lc) -> Self {
self.title = title;
self
}

View file

@ -13,21 +13,20 @@ pub enum ItemKind {
#[default]
Void,
/// Etiqueta sin comportamiento interactivo.
Label(L10n),
/// Elemento de navegación basado en una [`RoutePath`] dinámica devuelta por
/// [`FnPathByContext`]. Opcionalmente, puede abrirse en una nueva ventana y estar inicialmente
/// deshabilitado.
Label(Lc),
/// Elemento de navegación basado en una [`RoutePath`] dinámica resuelta por una [`Route`].
/// Opcionalmente, puede abrirse en una nueva ventana y estar inicialmente deshabilitado.
Link {
label: L10n,
route: FnPathByContext,
label: Lc,
route: Route,
blank: bool,
disabled: bool,
},
/// Acción ejecutable en la propia página, sin navegación asociada. Inicialmente puede estar
/// deshabilitado.
Button { label: L10n, disabled: bool },
Button { label: Lc, disabled: bool },
/// Título o encabezado que separa grupos de opciones.
Header(L10n),
Header(Lc),
/// Separador visual entre bloques de elementos.
Divider,
}
@ -79,7 +78,7 @@ impl Component for Item {
blank,
disabled,
} => {
let route_link = route(cx);
let route_link = route.resolve(cx);
let current_path = cx.request().map(|request| request.path());
let is_current = !*disabled && (current_path == Some(route_link.path()));
@ -156,7 +155,7 @@ impl Component for Item {
impl Item {
/// Crea un elemento de tipo texto, mostrado sin interacción.
pub fn label(label: L10n) -> Self {
pub fn label(label: Lc) -> Self {
Self {
item_kind: ItemKind::Label(label),
..Default::default()
@ -165,14 +164,14 @@ impl Item {
/// Crea un enlace para la navegación.
///
/// La ruta se obtiene invocando [`FnPathByContext`], que devuelve dinámicamente una
/// La ruta se obtiene invocando [`Route::resolve()`], que devuelve dinámicamente una
/// [`RoutePath`] en función del [`Context`]. El enlace se marca como `active` si la ruta actual
/// del *request* coincide con la ruta de destino (devuelta por `RoutePath::path`).
pub fn link(label: L10n, route: FnPathByContext) -> Self {
pub fn link(label: Lc, route: impl Into<Route>) -> Self {
Self {
item_kind: ItemKind::Link {
label,
route,
route: route.into(),
blank: false,
disabled: false,
},
@ -181,11 +180,11 @@ impl Item {
}
/// Crea un enlace deshabilitado que no permite la interacción.
pub fn link_disabled(label: L10n, route: FnPathByContext) -> Self {
pub fn link_disabled(label: Lc, route: impl Into<Route>) -> Self {
Self {
item_kind: ItemKind::Link {
label,
route,
route: route.into(),
blank: false,
disabled: true,
},
@ -194,11 +193,11 @@ impl Item {
}
/// Crea un enlace que se abre en una nueva ventana o pestaña.
pub fn link_blank(label: L10n, route: FnPathByContext) -> Self {
pub fn link_blank(label: Lc, route: impl Into<Route>) -> Self {
Self {
item_kind: ItemKind::Link {
label,
route,
route: route.into(),
blank: true,
disabled: false,
},
@ -207,11 +206,11 @@ impl Item {
}
/// Crea un enlace inicialmente deshabilitado que se abriría en una nueva ventana.
pub fn link_blank_disabled(label: L10n, route: FnPathByContext) -> Self {
pub fn link_blank_disabled(label: Lc, route: impl Into<Route>) -> Self {
Self {
item_kind: ItemKind::Link {
label,
route,
route: route.into(),
blank: true,
disabled: true,
},
@ -220,7 +219,7 @@ impl Item {
}
/// Crea un botón de acción local, sin navegación asociada.
pub fn button(label: L10n) -> Self {
pub fn button(label: Lc) -> Self {
Self {
item_kind: ItemKind::Button {
label,
@ -231,7 +230,7 @@ impl Item {
}
/// Crea un botón deshabilitado.
pub fn button_disabled(label: L10n) -> Self {
pub fn button_disabled(label: Lc) -> Self {
Self {
item_kind: ItemKind::Button {
label,
@ -242,7 +241,7 @@ impl Item {
}
/// Crea un encabezado para un grupo de elementos dentro del menú.
pub fn header(label: L10n) -> Self {
pub fn header(label: Lc) -> Self {
Self {
item_kind: ItemKind::Header(label),
..Default::default()

View file

@ -18,8 +18,8 @@ const EXTRA_FLOATING_LABEL: &str = "bootsier.form.input.floating_label";
///
/// let nombre = bs::form::input::Field::text()
/// .with_name("name")
/// .with_label(L10n::n("Name"))
/// .with_placeholder(L10n::n("Enter your name"))
/// .with_label(Lc::n("Name"))
/// .with_placeholder(Lc::n("Enter your name"))
/// .with_floating_label(true);
/// ```
pub trait InputBootsier {
@ -83,7 +83,7 @@ pub(crate) fn render(field: &Field, cx: &mut Context) -> Result<Markup, Componen
@if *field.required() {
span
class="form-required"
title=[L10n::l("field_required").lookup(cx)]
title=[Lc::l("field_required").lookup(cx)]
{
"*"
}

View file

@ -18,11 +18,11 @@ const EXTRA_FLOATING_LABEL: &str = "bootsier.form.select.floating_label";
///
/// let language = bs::form::select::Field::new()
/// .with_name("language")
/// .with_label(L10n::n("Language"))
/// .with_label(Lc::n("Language"))
/// .with_floating_label(true)
/// .with_item(bs::form::select::Item::new("", L10n::n("— Choose —")).with_selected(true))
/// .with_item(bs::form::select::Item::new("es", L10n::n("Spanish")))
/// .with_item(bs::form::select::Item::new("en", L10n::n("English")));
/// .with_item(bs::form::select::Item::new("", Lc::n("— Choose —")).with_selected(true))
/// .with_item(bs::form::select::Item::new("es", Lc::n("Spanish")))
/// .with_item(bs::form::select::Item::new("en", Lc::n("English")));
/// ```
pub trait SelectBootsier {
/// Establece si la etiqueta se muestra flotante sobre el campo.
@ -70,7 +70,7 @@ pub(crate) fn render(field: &Field, cx: &mut Context) -> Result<Markup, Componen
@if *field.required() {
span
class="form-required"
title=[L10n::l("field_required").lookup(cx)]
title=[Lc::l("field_required").lookup(cx)]
{
"*"
}

View file

@ -18,8 +18,8 @@ const EXTRA_FLOATING_LABEL: &str = "bootsier.form.textarea.floating_label";
///
/// let comentario = bs::form::Textarea::new()
/// .with_name("comment")
/// .with_label(L10n::n("Comment"))
/// .with_placeholder(L10n::n("Write here..."))
/// .with_label(Lc::n("Comment"))
/// .with_placeholder(Lc::n("Write here..."))
/// .with_floating_label(true);
/// ```
pub trait TextareaBootsier {
@ -76,7 +76,7 @@ pub(crate) fn render(field: &Textarea, cx: &mut Context) -> Result<Markup, Compo
@if *field.required() {
span
class="form-required"
title=[L10n::l("field_required").lookup(cx)]
title=[Lc::l("field_required").lookup(cx)]
{
"*"
}

View file

@ -11,7 +11,7 @@ use crate::theme::*;
/// - Configurar sus **dimensiones** ([`with_size()`](Self::with_size)), **borde**
/// ([`Border`](crate::theme::class::Border)) y **redondeo de esquinas**
/// ([`Rounded`](crate::theme::class::Rounded)).
/// - Aplicar el texto alternativo `alt` con **localización** mediante [`L10n`].
/// - Aplicar el texto alternativo `alt` con **localización** mediante [`Lc`].
#[derive(AutoDefault, Clone, Debug, Getters)]
pub struct Image {
/// Devuelve identificador, clases CSS, atributos HTML y valores extra del componente.
@ -21,7 +21,7 @@ pub struct Image {
/// Devuelve el origen de la imagen.
source: bs::image::Source,
/// Devuelve el texto alternativo localizado.
alternative: Attr<L10n>,
alternative: Attr<Lc>,
}
#[async_trait]
@ -112,12 +112,12 @@ impl Image {
self
}
/// Define un *texto localizado* ([`L10n`]) alternativo para la imagen.
/// Define un *texto localizado* ([`Lc`]) alternativo para la imagen.
///
/// Se recomienda siempre aportar un texto alternativo salvo que la imagen sea puramente
/// decorativa.
#[builder_fn]
pub fn with_alternative(mut self, alt: L10n) -> Self {
pub fn with_alternative(mut self, alt: Lc) -> Self {
self.alternative.alter_value(alt);
self
}

View file

@ -5,7 +5,7 @@
//! desplegables [`Dropdown`](crate::theme::bs::Dropdown).
//!
//! Los ítems pueden estar activos, deshabilitados o abrirse en nueva ventana según su contexto y
//! configuración, y permiten incluir etiquetas localizables usando [`L10n`](pagetop::locale::L10n).
//! configuración, y permiten incluir etiquetas localizables usando [`Lc`](pagetop::locale::Lc).
mod props;
pub use props::{Kind, Layout};

View file

@ -20,17 +20,17 @@ use crate::theme::*;
///
/// let nav = bs::Nav::tabs()
/// .with_layout(bs::nav::Layout::End)
/// .with_item(bs::nav::Item::link(L10n::n("Home"), |_| "/".into()))
/// .with_item(bs::nav::Item::link_blank(L10n::n("External"), |_| "https://docs.rs".into()))
/// .with_item(bs::nav::Item::link(Lc::n("Home"), "/"))
/// .with_item(bs::nav::Item::link_blank(Lc::n("External"), "https://docs.rs"))
/// .with_item(bs::nav::Item::dropdown(
/// bs::Dropdown::new()
/// .with_title(L10n::n("Options"))
/// .with_title(Lc::n("Options"))
/// .with_item(ChildOp::AddMany(vec![
/// bs::dropdown::Item::link(L10n::n("Action"), |_| "/action".into()).into(),
/// bs::dropdown::Item::link(L10n::n("Another"), |_| "/another".into()).into(),
/// bs::dropdown::Item::link(Lc::n("Action"), "/action").into(),
/// bs::dropdown::Item::link(Lc::n("Another"), "/another").into(),
/// ])),
/// ))
/// .with_item(bs::nav::Item::link_disabled(L10n::n("Disabled"), |_| "#".into()));
/// .with_item(bs::nav::Item::link_disabled(Lc::n("Disabled"), "#"));
/// ```
#[derive(AutoDefault, Clone, Debug, Getters)]
pub struct Nav {

View file

@ -16,13 +16,12 @@ pub enum ItemKind {
#[default]
Void,
/// Etiqueta sin comportamiento interactivo.
Label(L10n),
/// Elemento de navegación basado en una [`RoutePath`] dinámica devuelta por
/// [`FnPathByContext`]. Opcionalmente, puede abrirse en una nueva ventana y estar inicialmente
/// deshabilitado.
Label(Lc),
/// Elemento de navegación basado en una [`RoutePath`] dinámica resuelta por una [`Route`].
/// Opcionalmente, puede abrirse en una nueva ventana y estar inicialmente deshabilitado.
Link {
label: L10n,
route: FnPathByContext,
label: Lc,
route: Route,
blank: bool,
disabled: bool,
},
@ -97,7 +96,7 @@ impl Component for Item {
blank,
disabled,
} => {
let route_link = route(cx);
let route_link = route.resolve(cx);
let current_path = cx.request().map(|request| request.path());
let is_current = !*disabled && (current_path == Some(route_link.path()));
@ -145,7 +144,7 @@ impl Component for Item {
return Ok(html! {});
}
let title = dd.title().lookup(cx).unwrap_or_else(|| {
L10n::t("dropdown", &LOCALES_BOOTSIER)
Lc::t("dropdown", &LOCALES_BOOTSIER)
.lookup(cx)
.unwrap_or_else(|| "Dropdown".to_string())
});
@ -175,7 +174,7 @@ impl Component for Item {
impl Item {
/// Crea un elemento de tipo texto, mostrado sin interacción.
pub fn label(label: L10n) -> Self {
pub fn label(label: Lc) -> Self {
Self {
item_kind: ItemKind::Label(label),
..Default::default()
@ -184,14 +183,14 @@ impl Item {
/// Crea un enlace para la navegación.
///
/// La ruta se obtiene invocando [`FnPathByContext`], que devuelve dinámicamente una
/// La ruta se obtiene invocando [`Route::resolve()`], que devuelve dinámicamente una
/// [`RoutePath`] en función del [`Context`]. El enlace se marca como `active` si la ruta actual
/// del *request* coincide con la ruta de destino (devuelta por `RoutePath::path`).
pub fn link(label: L10n, route: FnPathByContext) -> Self {
pub fn link(label: Lc, route: impl Into<Route>) -> Self {
Self {
item_kind: ItemKind::Link {
label,
route,
route: route.into(),
blank: false,
disabled: false,
},
@ -200,11 +199,11 @@ impl Item {
}
/// Crea un enlace deshabilitado que no permite la interacción.
pub fn link_disabled(label: L10n, route: FnPathByContext) -> Self {
pub fn link_disabled(label: Lc, route: impl Into<Route>) -> Self {
Self {
item_kind: ItemKind::Link {
label,
route,
route: route.into(),
blank: false,
disabled: true,
},
@ -213,11 +212,11 @@ impl Item {
}
/// Crea un enlace que se abre en una nueva ventana o pestaña.
pub fn link_blank(label: L10n, route: FnPathByContext) -> Self {
pub fn link_blank(label: Lc, route: impl Into<Route>) -> Self {
Self {
item_kind: ItemKind::Link {
label,
route,
route: route.into(),
blank: true,
disabled: false,
},
@ -226,11 +225,11 @@ impl Item {
}
/// Crea un enlace inicialmente deshabilitado que se abriría en una nueva ventana.
pub fn link_blank_disabled(label: L10n, route: FnPathByContext) -> Self {
pub fn link_blank_disabled(label: Lc, route: impl Into<Route>) -> Self {
Self {
item_kind: ItemKind::Link {
label,
route,
route: route.into(),
blank: true,
disabled: true,
},

View file

@ -2,7 +2,7 @@
//!
//! Cada [`navbar::Item`](crate::theme::bs::navbar::Item) representa un elemento individual de la
//! barra de navegación [`Navbar`], con distintos comportamientos según su finalidad, como menús
//! [`Nav`](crate::theme::bs::Nav) o *textos localizados* usando [`L10n`](pagetop::locale::L10n).
//! [`Nav`](crate::theme::bs::Nav) o *textos localizados* usando [`Lc`](pagetop::locale::Lc).
//!
//! También puede añadir una marca de identidad ([`navbar::Brand`](crate::theme::bs::navbar::Brand))
//! que identifique la compañía, producto o nombre del proyecto asociado a la solución web.

View file

@ -16,13 +16,13 @@ pub struct Brand {
/// Devuelve la imagen de marca (si la hay).
image: Embed<bs::Image>,
/// Devuelve el título de la identidad de marca.
#[default(_code = "L10n::n(&global::SETTINGS.app.name)")]
title: L10n,
#[default(_code = "Lc::n(&global::SETTINGS.app.name)")]
title: Lc,
/// Devuelve el eslogan de la marca.
slogan: L10n,
/// Devuelve la función que resuelve la URL asociada a la marca (si existe).
#[default(_code = "Some(|cx| cx.route(\"/\"))")]
route: Option<FnPathByContext>,
slogan: Lc,
/// Devuelve la ruta asociada a la marca (si existe).
#[default(_code = "Some(\"/\".into())")]
route: Option<Route>,
}
#[async_trait]
@ -40,7 +40,7 @@ impl Component for Brand {
let slogan = self.slogan().using(cx);
Ok(html! {
@if let Some(route) = self.route() {
a class="navbar-brand" href=(route(cx)) { (image) (title) (slogan) }
a class="navbar-brand" href=(route.resolve(cx)) { (image) (title) (slogan) }
} @else {
span class="navbar-brand" { (image) (title) (slogan) }
}
@ -60,21 +60,21 @@ impl Brand {
/// Establece el título de la identidad de marca.
#[builder_fn]
pub fn with_title(mut self, title: L10n) -> Self {
pub fn with_title(mut self, title: Lc) -> Self {
self.title = title;
self
}
/// Define el eslogan de la marca.
#[builder_fn]
pub fn with_slogan(mut self, slogan: L10n) -> Self {
pub fn with_slogan(mut self, slogan: Lc) -> Self {
self.slogan = slogan;
self
}
/// Define la URL de destino. Si es `None`, la marca no será un enlace.
/// Define la ruta de destino. Si es `None`, la marca no será un enlace.
#[builder_fn]
pub fn with_route(mut self, route: Option<FnPathByContext>) -> Self {
pub fn with_route(mut self, route: Option<Route>) -> Self {
self.route = route;
self
}

View file

@ -26,9 +26,9 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
/// let navbar = bs::Navbar::simple()
/// .with_item(bs::navbar::Item::nav(
/// bs::Nav::new()
/// .with_item(bs::nav::Item::link(L10n::n("Home"), |_| "/".into()))
/// .with_item(bs::nav::Item::link(L10n::n("About"), |_| "/about".into()))
/// .with_item(bs::nav::Item::link(L10n::n("Contact"), |_| "/contact".into()))
/// .with_item(bs::nav::Item::link(Lc::n("Home"), "/"))
/// .with_item(bs::nav::Item::link(Lc::n("About"), "/about"))
/// .with_item(bs::nav::Item::link(Lc::n("Contact"), "/contact"))
/// ));
/// ```
///
@ -38,12 +38,12 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let navbar = bs::Navbar::simple_toggle()
/// .with_expand(token::BreakPoint::MD)
/// .with_expand(BreakPoint::MD)
/// .with_item(bs::navbar::Item::nav(
/// bs::Nav::new()
/// .with_item(bs::nav::Item::link(L10n::n("Home"), |_| "/".into()))
/// .with_item(bs::nav::Item::link_blank(L10n::n("Doc"), |_| "https://docs.rs".into()))
/// .with_item(bs::nav::Item::link(L10n::n("Support"), |_| "/support".into()))
/// .with_item(bs::nav::Item::link(Lc::n("Home"), "/"))
/// .with_item(bs::nav::Item::link_blank(Lc::n("Doc"), "https://docs.rs"))
/// .with_item(bs::nav::Item::link(Lc::n("Support"), "/support"))
/// ));
/// ```
///
@ -53,24 +53,24 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let brand = bs::navbar::Brand::new()
/// .with_title(L10n::n("PageTop"))
/// .with_route(Some(|cx| cx.route("/")));
/// .with_title(Lc::n("PageTop"))
/// .with_route(Some("/".into()));
///
/// let navbar = bs::Navbar::brand_left(brand)
/// .with_item(bs::navbar::Item::nav(
/// bs::Nav::new()
/// .with_item(bs::nav::Item::link(L10n::n("Home"), |_| "/".into()))
/// .with_item(bs::nav::Item::link(Lc::n("Home"), "/"))
/// .with_item(bs::nav::Item::dropdown(
/// bs::Dropdown::new()
/// .with_title(L10n::n("Tools"))
/// .with_title(Lc::n("Tools"))
/// .with_item(bs::dropdown::Item::link(
/// L10n::n("Generator"), |_| "/tools/gen".into())
/// Lc::n("Generator"), "/tools/gen")
/// )
/// .with_item(bs::dropdown::Item::link(
/// L10n::n("Reports"), |_| "/tools/reports".into())
/// Lc::n("Reports"), "/tools/reports")
/// )
/// ))
/// .with_item(bs::nav::Item::link_disabled(L10n::n("Disabled"), |_| "#".into()))
/// .with_item(bs::nav::Item::link_disabled(Lc::n("Disabled"), "#"))
/// ));
/// ```
///
@ -80,15 +80,15 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let brand = bs::navbar::Brand::new()
/// .with_title(L10n::n("Intranet"))
/// .with_route(Some(|cx| cx.route("/")));
/// .with_title(Lc::n("Intranet"))
/// .with_route(Some("/".into()));
///
/// let navbar = bs::Navbar::brand_right(brand)
/// .with_expand(token::BreakPoint::LG)
/// .with_expand(BreakPoint::LG)
/// .with_item(bs::navbar::Item::nav(
/// bs::Nav::pills()
/// .with_item(bs::nav::Item::link(L10n::n("Dashboard"), |_| "/dashboard".into()))
/// .with_item(bs::nav::Item::link(L10n::n("Users"), |_| "/users".into()))
/// .with_item(bs::nav::Item::link(Lc::n("Dashboard"), "/dashboard"))
/// .with_item(bs::nav::Item::link(Lc::n("Users"), "/users"))
/// ));
/// ```
///
@ -99,20 +99,20 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
/// # use pagetop_bootsier::theme::*;
/// let oc = bs::Offcanvas::new()
/// .with_id("main_offcanvas")
/// .with_title(L10n::n("Main menu"))
/// .with_title(Lc::n("Main menu"))
/// .with_placement(bs::offcanvas::Placement::Start)
/// .with_backdrop(bs::offcanvas::Backdrop::Enabled);
///
/// let navbar = bs::Navbar::offcanvas(oc)
/// .with_item(bs::navbar::Item::nav(
/// bs::Nav::new()
/// .with_item(bs::nav::Item::link(L10n::n("Home"), |_| "/".into()))
/// .with_item(bs::nav::Item::link(L10n::n("Profile"), |_| "/profile".into()))
/// .with_item(bs::nav::Item::link(Lc::n("Home"), "/"))
/// .with_item(bs::nav::Item::link(Lc::n("Profile"), "/profile"))
/// .with_item(bs::nav::Item::dropdown(
/// bs::Dropdown::new()
/// .with_title(L10n::n("More"))
/// .with_item(bs::dropdown::Item::link(L10n::n("Settings"), |_| "/settings".into()))
/// .with_item(bs::dropdown::Item::link(L10n::n("Help"), |_| "/help".into()))
/// .with_title(Lc::n("More"))
/// .with_item(bs::dropdown::Item::link(Lc::n("Settings"), "/settings"))
/// .with_item(bs::dropdown::Item::link(Lc::n("Help"), "/help"))
/// ))
/// ));
/// ```
@ -123,16 +123,16 @@ const TOGGLE_OFFCANVAS: &str = "offcanvas";
/// # use pagetop::prelude::*;
/// # use pagetop_bootsier::theme::*;
/// let brand = bs::navbar::Brand::new()
/// .with_title(L10n::n("Main App"))
/// .with_route(Some(|cx| cx.route("/")));
/// .with_title(Lc::n("Main App"))
/// .with_route(Some("/".into()));
///
/// let navbar = bs::Navbar::brand_left(brand)
/// .with_position(bs::navbar::Position::FixedTop)
/// .with_item(bs::navbar::Item::nav(
/// bs::Nav::new()
/// .with_item(bs::nav::Item::link(L10n::n("Dashboard"), |_| "/".into()))
/// .with_item(bs::nav::Item::link(L10n::n("Donors"), |_| "/donors".into()))
/// .with_item(bs::nav::Item::link(L10n::n("Stock"), |_| "/stock".into()))
/// .with_item(bs::nav::Item::link(Lc::n("Dashboard"), "/"))
/// .with_item(bs::nav::Item::link(Lc::n("Donors"), "/donors"))
/// .with_item(bs::nav::Item::link(Lc::n("Stock"), "/stock"))
/// ));
/// ```
#[derive(AutoDefault, Clone, Debug, Getters)]
@ -140,7 +140,7 @@ pub struct Navbar {
/// Devuelve identificador, clases CSS, atributos HTML y valores extra del componente.
props: Props,
/// Devuelve el punto de ruptura configurado.
expand: token::BreakPoint,
expand: BreakPoint,
/// Devuelve la disposición configurada para la barra de navegación.
layout: bs::navbar::Layout,
/// Devuelve la posición configurada para la barra de navegación.
@ -189,7 +189,7 @@ impl Component for Navbar {
data-bs-target=(id_content_target)
aria-controls=(id_content)
aria-expanded=[aria_expanded]
aria-label=[L10n::t("toggle", &LOCALES_BOOTSIER).lookup(cx)]
aria-label=[Lc::t("toggle", &LOCALES_BOOTSIER).lookup(cx)]
{
span class="navbar-toggler-icon" {}
}
@ -350,7 +350,7 @@ impl Navbar {
///
/// También acepta clases predefinidas para:
///
/// - Modificar el color de fondo ([`Background`]).
/// - Modificar el color de fondo ([`Bg`]).
/// - Definir la apariencia del texto ([`Text`]).
#[builder_fn]
pub fn with_prop(mut self, op: PropsOp) -> Self {
@ -360,7 +360,7 @@ impl Navbar {
/// Define a partir de qué punto de ruptura la barra de navegación deja de colapsar.
#[builder_fn]
pub fn with_expand(mut self, bp: token::BreakPoint) -> Self {
pub fn with_expand(mut self, bp: BreakPoint) -> Self {
self.expand = bp;
self
}

View file

@ -23,7 +23,7 @@ pub enum Item {
/// Representa un menú de navegación [`Nav`](crate::theme::bs::Nav).
Nav(Embed<bs::Nav>),
/// Representa un *texto localizado* libre.
Text(L10n),
Text(Lc),
}
#[async_trait]
@ -92,7 +92,7 @@ impl Item {
}
/// Crea un elemento con un *texto localizado*, mostrado sin interacción.
pub fn text(item: L10n) -> Self {
pub fn text(item: Lc) -> Self {
Self::Text(item)
}
}

View file

@ -29,16 +29,16 @@ use crate::theme::*;
///
/// let panel = bs::Offcanvas::new()
/// .with_id("offcanvas_example")
/// .with_title(L10n::n("Offcanvas title"))
/// .with_title(Lc::n("Offcanvas title"))
/// .with_placement(bs::offcanvas::Placement::End)
/// .with_backdrop(bs::offcanvas::Backdrop::Enabled)
/// .with_body_scroll(bs::offcanvas::BodyScroll::Enabled)
/// .with_visibility(bs::offcanvas::Visibility::Default)
/// .with_child(bs::Dropdown::new()
/// .with_title(L10n::n("Menu"))
/// .with_item(bs::dropdown::Item::label(L10n::n("Label")))
/// .with_item(bs::dropdown::Item::link_blank(L10n::n("Doc"), |_| "https://docs.rs".into()))
/// .with_item(bs::dropdown::Item::link(L10n::n("Sign out"), |_| "/signout".into()))
/// .with_title(Lc::n("Menu"))
/// .with_item(bs::dropdown::Item::label(Lc::n("Label")))
/// .with_item(bs::dropdown::Item::link_blank(Lc::n("Doc"), "https://docs.rs"))
/// .with_item(bs::dropdown::Item::link(Lc::n("Sign out"), "/signout"))
/// );
/// ```
#[derive(AutoDefault, Clone, Debug, Getters)]
@ -46,9 +46,9 @@ pub struct Offcanvas {
/// Devuelve identificador, clases CSS, atributos HTML y valores extra del componente.
props: Props,
/// Devuelve el título del panel.
title: L10n,
title: Lc,
/// Devuelve el punto de ruptura configurado para cambiar el comportamiento del panel.
breakpoint: token::BreakPoint,
breakpoint: BreakPoint,
/// Devuelve el comportamiento configurado para la capa de fondo.
backdrop: bs::offcanvas::Backdrop,
/// Indica si la página principal puede desplazarse mientras el panel está abierto.
@ -109,7 +109,7 @@ impl Offcanvas {
/// Establece el título del encabezado.
#[builder_fn]
pub fn with_title(mut self, title: L10n) -> Self {
pub fn with_title(mut self, title: Lc) -> Self {
self.title = title;
self
}
@ -124,7 +124,7 @@ impl Offcanvas {
/// directamente en pantallas grandes. Por defecto usa `BreakPoint::None` para que sea
/// *offcanvas* siempre.
#[builder_fn]
pub fn with_breakpoint(mut self, bp: token::BreakPoint) -> Self {
pub fn with_breakpoint(mut self, bp: BreakPoint) -> Self {
self.breakpoint = bp;
self
}
@ -210,7 +210,7 @@ impl Offcanvas {
class="btn-close"
data-bs-dismiss="offcanvas"
data-bs-target=(id_target)
aria-label=[L10n::t("offcanvas_close", &LOCALES_BOOTSIER).lookup(cx)]
aria-label=[Lc::t("offcanvas_close", &LOCALES_BOOTSIER).lookup(cx)]
{}
}
div class="offcanvas-body" {

View file

@ -27,15 +27,15 @@ pub enum ButtonColorStyle {
/// use pagetop_bootsier::theme::*;
///
/// // Botón sólido.
/// let save = bs::Button::submit(L10n::n("Save"))
/// let save = bs::Button::submit(Lc::n("Save"))
/// .with_prop(PropsOp::add_classes(class::ButtonColor::solid(ThemeColor::Primary)));
///
/// // Botón con contorno.
/// let cancel = bs::Button::plain(L10n::n("Cancel"))
/// let cancel = bs::Button::plain(Lc::n("Cancel"))
/// .with_prop(PropsOp::add_classes(class::ButtonColor::outline(ThemeColor::Secondary)));
///
/// // Botón tipo enlace.
/// let back = bs::Button::plain(L10n::n("Back"))
/// let back = bs::Button::plain(Lc::n("Back"))
/// .with_prop(PropsOp::add_classes(class::ButtonColor::link()));
/// ```
#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)]
@ -148,10 +148,10 @@ pub enum ButtonSizeKind {
/// use pagetop::prelude::*;
/// use pagetop_bootsier::theme::*;
///
/// let small = bs::Button::submit(L10n::n("Save"))
/// let small = bs::Button::submit(Lc::n("Save"))
/// .with_prop(PropsOp::add_classes(class::ButtonSize::small()));
///
/// let large = bs::Button::submit(L10n::n("Save"))
/// let large = bs::Button::submit(Lc::n("Save"))
/// .with_prop(PropsOp::add_classes(class::ButtonSize::large()));
/// ```
#[derive(AutoDefault, Clone, Copy, Debug, PartialEq)]