✨ [bootsier] Añade paneles deslizables Offcanvas
This commit is contained in:
parent
b6b26c23da
commit
5c818b463f
6 changed files with 331 additions and 306 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
dropdown_toggle = Toggle Dropdown
|
dropdown_toggle = Toggle Dropdown
|
||||||
|
|
||||||
# Offcanvas
|
# Offcanvas
|
||||||
close = Close
|
offcanvas_close = Close
|
||||||
|
|
||||||
# Navbar
|
# Navbar
|
||||||
toggle = Toggle navigation
|
toggle = Toggle navigation
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
dropdown_toggle = Mostrar/ocultar menú
|
dropdown_toggle = Mostrar/ocultar menú
|
||||||
|
|
||||||
# Offcanvas
|
# Offcanvas
|
||||||
close = Cerrar
|
offcanvas_close = Cerrar
|
||||||
|
|
||||||
# Navbar
|
# Navbar
|
||||||
toggle = Mostrar/ocultar navegación
|
toggle = Mostrar/ocultar navegación
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ pub mod navbar;
|
||||||
pub use navbar::{Navbar, NavbarToggler};
|
pub use navbar::{Navbar, NavbarToggler};
|
||||||
|
|
||||||
// Offcanvas.
|
// Offcanvas.
|
||||||
mod offcanvas;
|
pub mod offcanvas;
|
||||||
pub use offcanvas::{
|
#[doc(inline)]
|
||||||
Offcanvas, OffcanvasBackdrop, OffcanvasBodyScroll, OffcanvasPlacement, OffcanvasVisibility,
|
pub use offcanvas::Offcanvas;
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -1,302 +1,7 @@
|
||||||
use pagetop::prelude::*;
|
//! Definiciones para crear paneles laterales deslizantes [`Offcanvas`].
|
||||||
|
|
||||||
use crate::prelude::*;
|
mod props;
|
||||||
use crate::LOCALES_BOOTSIER;
|
pub use props::{Backdrop, BodyScroll, Placement, Visibility};
|
||||||
|
|
||||||
use std::fmt;
|
mod component;
|
||||||
|
pub use component::Offcanvas;
|
||||||
// **< OffcanvasPlacement >*************************************************************************
|
|
||||||
|
|
||||||
/// Posición de aparición del panel **deslizante** ([`Offcanvas`]).
|
|
||||||
///
|
|
||||||
/// Define desde qué borde de la ventana entra y se ancla el panel.
|
|
||||||
#[derive(AutoDefault)]
|
|
||||||
pub enum OffcanvasPlacement {
|
|
||||||
/// Opción por defecto, desde el borde inicial según dirección de lectura (respetando LTR/RTL).
|
|
||||||
#[default]
|
|
||||||
Start,
|
|
||||||
/// Desde el borde final según dirección de lectura (respetando LTR/RTL).
|
|
||||||
End,
|
|
||||||
/// Desde la parte superior.
|
|
||||||
Top,
|
|
||||||
/// Desde la parte inferior.
|
|
||||||
Bottom,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[rustfmt::skip]
|
|
||||||
impl fmt::Display for OffcanvasPlacement {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
OffcanvasPlacement::Start => f.write_str("offcanvas-start"),
|
|
||||||
OffcanvasPlacement::End => f.write_str("offcanvas-end"),
|
|
||||||
OffcanvasPlacement::Top => f.write_str("offcanvas-top"),
|
|
||||||
OffcanvasPlacement::Bottom => f.write_str("offcanvas-bottom"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// **< OffcanvasVisibility >************************************************************************
|
|
||||||
|
|
||||||
/// Estado inicial del panel ([`Offcanvas`]).
|
|
||||||
#[derive(AutoDefault)]
|
|
||||||
pub enum OffcanvasVisibility {
|
|
||||||
/// El panel **permanece oculto** desde el principio.
|
|
||||||
#[default]
|
|
||||||
Default,
|
|
||||||
/// El panel **se muestra abierto** al cargar.
|
|
||||||
Show,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl fmt::Display for OffcanvasVisibility {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
match self {
|
|
||||||
OffcanvasVisibility::Default => Ok(()),
|
|
||||||
OffcanvasVisibility::Show => f.write_str("show"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// **< OffcanvasBodyScroll >************************************************************************
|
|
||||||
|
|
||||||
/// Controla si la página principal puede **desplazarse** al abrir el panel ([`Offcanvas`]).
|
|
||||||
#[derive(AutoDefault)]
|
|
||||||
pub enum OffcanvasBodyScroll {
|
|
||||||
/// Opción por defecto, la página principal se **bloquea** centrando la interacción en el panel.
|
|
||||||
#[default]
|
|
||||||
Disabled,
|
|
||||||
/// **Permite** el desplazamiento de la página principal.
|
|
||||||
Enabled,
|
|
||||||
}
|
|
||||||
|
|
||||||
// **< OffcanvasBackdrop >**************************************************************************
|
|
||||||
|
|
||||||
/// Comportamiento de la **capa de fondo** (*backdrop*) del panel ([`Offcanvas`]) al desplegarse.
|
|
||||||
#[derive(AutoDefault)]
|
|
||||||
pub enum OffcanvasBackdrop {
|
|
||||||
/// **Sin capa** de fondo; la página principal permanece visible e interactiva.
|
|
||||||
Disabled,
|
|
||||||
/// Opción por defecto, se **oscurece** el fondo; un clic fuera del panel suele cerrarlo.
|
|
||||||
#[default]
|
|
||||||
Enabled,
|
|
||||||
/// Se muestra capa de fondo pero **no** se cierra al pulsar fuera (útil cuando se requiere
|
|
||||||
/// completar una acción antes de salir).
|
|
||||||
Static,
|
|
||||||
}
|
|
||||||
|
|
||||||
// **< Offcanvas >**********************************************************************************
|
|
||||||
|
|
||||||
/// Panel lateral **deslizante** para contenido complementario.
|
|
||||||
///
|
|
||||||
/// Útil para navegación, filtros, formularios o menús contextuales. Incluye las siguientes
|
|
||||||
/// características principales:
|
|
||||||
///
|
|
||||||
/// - **Entrada configurable desde un borde** de la ventana.
|
|
||||||
/// - **Encabezado con título** y **botón de cierre** integrado.
|
|
||||||
/// - **Accesibilidad**: asocia título y controles a un identificador único y expone atributos
|
|
||||||
/// adecuados para lectores de pantalla y navegación por teclado.
|
|
||||||
/// - **Opcionalmente** bloquea el desplazamiento del documento y/o muestra una capa de fondo para
|
|
||||||
/// centrar la atención del usuario.
|
|
||||||
/// - **Responsive**: puede cambiar su comportamiento según el punto de ruptura indicado.
|
|
||||||
/// - **No se renderiza** si no tiene contenido.
|
|
||||||
#[rustfmt::skip]
|
|
||||||
#[derive(AutoDefault)]
|
|
||||||
pub struct Offcanvas {
|
|
||||||
id : AttrId,
|
|
||||||
classes : AttrClasses,
|
|
||||||
title : L10n,
|
|
||||||
breakpoint: BreakPoint,
|
|
||||||
placement : OffcanvasPlacement,
|
|
||||||
visibility: OffcanvasVisibility,
|
|
||||||
scrolling : OffcanvasBodyScroll,
|
|
||||||
backdrop : OffcanvasBackdrop,
|
|
||||||
children : Children,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Component for Offcanvas {
|
|
||||||
fn new() -> Self {
|
|
||||||
Offcanvas::default()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn id(&self) -> Option<String> {
|
|
||||||
self.id.get()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn setup_before_prepare(&mut self, _cx: &mut Context) {
|
|
||||||
self.alter_classes(
|
|
||||||
ClassesOp::Prepend,
|
|
||||||
[
|
|
||||||
self.breakpoint().to_class("offcanvas"),
|
|
||||||
self.placement().to_string(),
|
|
||||||
self.visibility().to_string(),
|
|
||||||
]
|
|
||||||
.join(" "),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
|
|
||||||
let body = self.children().render(cx);
|
|
||||||
if body.is_empty() {
|
|
||||||
return PrepareMarkup::None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let id = cx.required_id::<Self>(self.id());
|
|
||||||
let id_label = join!(id, "-label");
|
|
||||||
let id_target = join!("#", id);
|
|
||||||
|
|
||||||
let body_scroll = match self.body_scroll() {
|
|
||||||
OffcanvasBodyScroll::Disabled => None,
|
|
||||||
OffcanvasBodyScroll::Enabled => Some("true"),
|
|
||||||
};
|
|
||||||
|
|
||||||
let backdrop = match self.backdrop() {
|
|
||||||
OffcanvasBackdrop::Disabled => Some("false"),
|
|
||||||
OffcanvasBackdrop::Enabled => None,
|
|
||||||
OffcanvasBackdrop::Static => Some("static"),
|
|
||||||
};
|
|
||||||
|
|
||||||
let title = self.title().using(cx);
|
|
||||||
|
|
||||||
PrepareMarkup::With(html! {
|
|
||||||
div
|
|
||||||
id=(id)
|
|
||||||
class=[self.classes().get()]
|
|
||||||
tabindex="-1"
|
|
||||||
data-bs-scroll=[body_scroll]
|
|
||||||
data-bs-backdrop=[backdrop]
|
|
||||||
aria-labelledby=(id_label)
|
|
||||||
{
|
|
||||||
div class="offcanvas-header" {
|
|
||||||
@if !title.is_empty() {
|
|
||||||
h5 class="offcanvas-title" id=(id_label) { (title) }
|
|
||||||
}
|
|
||||||
button
|
|
||||||
type="button"
|
|
||||||
class="btn-close"
|
|
||||||
data-bs-dismiss="offcanvas"
|
|
||||||
data-bs-target=(id_target)
|
|
||||||
aria-label=[L10n::t("close", &LOCALES_BOOTSIER).lookup(cx)]
|
|
||||||
{}
|
|
||||||
}
|
|
||||||
div class="offcanvas-body" {
|
|
||||||
(body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Offcanvas {
|
|
||||||
// **< Offcanvas BUILDER >**********************************************************************
|
|
||||||
|
|
||||||
/// Establece el identificador único (`id`) del panel.
|
|
||||||
#[builder_fn]
|
|
||||||
pub fn with_id(mut self, id: impl AsRef<str>) -> Self {
|
|
||||||
self.id.alter_value(id);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Modifica la lista de clases CSS aplicadas al panel.
|
|
||||||
#[builder_fn]
|
|
||||||
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
|
|
||||||
self.classes.alter_value(op, classes);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Establece el **título** del encabezado.
|
|
||||||
#[builder_fn]
|
|
||||||
pub fn with_title(mut self, title: L10n) -> Self {
|
|
||||||
self.title = title;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Configura el **punto de ruptura** para activar el comportamiento responsive del panel.
|
|
||||||
#[builder_fn]
|
|
||||||
pub fn with_breakpoint(mut self, bp: BreakPoint) -> Self {
|
|
||||||
self.breakpoint = bp;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Indica la **posición** desde la que entra el panel.
|
|
||||||
#[builder_fn]
|
|
||||||
pub fn with_placement(mut self, placement: OffcanvasPlacement) -> Self {
|
|
||||||
self.placement = placement;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Fija el **estado inicial** del panel (oculto o visible al cargar).
|
|
||||||
#[builder_fn]
|
|
||||||
pub fn with_visibility(mut self, visibility: OffcanvasVisibility) -> Self {
|
|
||||||
self.visibility = visibility;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Permite o bloquea el **desplazamiento** de la página principal mientras el panel está
|
|
||||||
/// abierto.
|
|
||||||
#[builder_fn]
|
|
||||||
pub fn with_body_scroll(mut self, scrolling: OffcanvasBodyScroll) -> Self {
|
|
||||||
self.scrolling = scrolling;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ajusta la **capa de fondo** del panel para definir su comportamiento al interactuar fuera.
|
|
||||||
#[builder_fn]
|
|
||||||
pub fn with_backdrop(mut self, backdrop: OffcanvasBackdrop) -> Self {
|
|
||||||
self.backdrop = backdrop;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Añade un nuevo componente hijo al panel.
|
|
||||||
pub fn add_child(mut self, child: impl Component) -> Self {
|
|
||||||
self.children.add(Child::with(child));
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Modifica la lista de hijos (`children`) aplicando una operación [`ChildOp`].
|
|
||||||
#[builder_fn]
|
|
||||||
pub fn with_children(mut self, op: ChildOp) -> Self {
|
|
||||||
self.children.alter_child(op);
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
// **< Offcanvas GETTERS >**********************************************************************
|
|
||||||
|
|
||||||
/// Devuelve las clases CSS asociadas al panel.
|
|
||||||
pub fn classes(&self) -> &AttrClasses {
|
|
||||||
&self.classes
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Devuelve el título del panel como [`L10n`].
|
|
||||||
pub fn title(&self) -> &L10n {
|
|
||||||
&self.title
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Devuelve el punto de ruptura configurado.
|
|
||||||
pub fn breakpoint(&self) -> &BreakPoint {
|
|
||||||
&self.breakpoint
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Devuelve la posición del panel.
|
|
||||||
pub fn placement(&self) -> &OffcanvasPlacement {
|
|
||||||
&self.placement
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Devuelve el estado inicial del panel.
|
|
||||||
pub fn visibility(&self) -> &OffcanvasVisibility {
|
|
||||||
&self.visibility
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Indica si la página principal puede desplazarse mientras el panel está abierto.
|
|
||||||
pub fn body_scroll(&self) -> &OffcanvasBodyScroll {
|
|
||||||
&self.scrolling
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Devuelve la configuración de la capa de fondo.
|
|
||||||
pub fn backdrop(&self) -> &OffcanvasBackdrop {
|
|
||||||
&self.backdrop
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Devuelve la lista de hijos (`children`) del panel.
|
|
||||||
pub fn children(&self) -> &Children {
|
|
||||||
&self.children
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
261
extensions/pagetop-bootsier/src/theme/offcanvas/component.rs
Normal file
261
extensions/pagetop-bootsier/src/theme/offcanvas/component.rs
Normal file
|
|
@ -0,0 +1,261 @@
|
||||||
|
use pagetop::prelude::*;
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
use crate::LOCALES_BOOTSIER;
|
||||||
|
|
||||||
|
/// Componente para crear un **panel lateral deslizante** con contenidos adicionales.
|
||||||
|
///
|
||||||
|
/// Útil para navegación, filtros, formularios o menús contextuales. Incluye las siguientes
|
||||||
|
/// características principales:
|
||||||
|
///
|
||||||
|
/// - Puede mostrar una capa de fondo para centrar la atención del usuario en el panel
|
||||||
|
/// ([`with_backdrop()`](Self::with_backdrop)); o puede bloquear el desplazamiento del documento
|
||||||
|
/// principal ([`with_body_scroll()`](Self::with_body_scroll)).
|
||||||
|
/// - Se puede configurar el borde de la ventana desde el que se desliza el panel
|
||||||
|
/// ([`with_placement()`](Self::with_placement)).
|
||||||
|
/// - Encabezado con título ([`with_title()`](Self::with_title)) y **botón de cierre** integrado.
|
||||||
|
/// - Puede cambiar su comportamiento a partir de un punto de ruptura
|
||||||
|
/// ([`with_breakpoint()`](Self::with_breakpoint)).
|
||||||
|
/// - Asocia título y controles de accesibilidad a un identificador único y expone atributos
|
||||||
|
/// adecuados para lectores de pantalla y navegación por teclado.
|
||||||
|
/// - **No se renderiza** si no tiene contenido.
|
||||||
|
///
|
||||||
|
/// # Ejemplo
|
||||||
|
///
|
||||||
|
/// ```rust
|
||||||
|
/// # use pagetop::prelude::*;
|
||||||
|
/// # use pagetop_bootsier::prelude::*;
|
||||||
|
/// let panel = Offcanvas::new()
|
||||||
|
/// .with_id("offcanvas_example")
|
||||||
|
/// .with_title(L10n::n("Offcanvas title"))
|
||||||
|
/// .with_placement(offcanvas::Placement::End)
|
||||||
|
/// .with_backdrop(offcanvas::Backdrop::Enabled)
|
||||||
|
/// .with_body_scroll(offcanvas::BodyScroll::Enabled)
|
||||||
|
/// .with_visibility(offcanvas::Visibility::Default)
|
||||||
|
/// .add_child(Dropdown::new()
|
||||||
|
/// .with_button_title(L10n::n("Menu"))
|
||||||
|
/// .add_item(dropdown::Item::label(L10n::n("Label")))
|
||||||
|
/// .add_item(dropdown::Item::link_blank(L10n::n("Google"), |_| "https://www.google.es"))
|
||||||
|
/// .add_item(dropdown::Item::link(L10n::n("Sign out"), |_| "/signout"))
|
||||||
|
/// );
|
||||||
|
/// ```
|
||||||
|
#[rustfmt::skip]
|
||||||
|
#[derive(AutoDefault)]
|
||||||
|
pub struct Offcanvas {
|
||||||
|
id : AttrId,
|
||||||
|
classes : AttrClasses,
|
||||||
|
title : L10n,
|
||||||
|
breakpoint: BreakPoint,
|
||||||
|
backdrop : offcanvas::Backdrop,
|
||||||
|
scrolling : offcanvas::BodyScroll,
|
||||||
|
placement : offcanvas::Placement,
|
||||||
|
visibility: offcanvas::Visibility,
|
||||||
|
children : Children,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Component for Offcanvas {
|
||||||
|
fn new() -> Self {
|
||||||
|
Offcanvas::default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn id(&self) -> Option<String> {
|
||||||
|
self.id.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[rustfmt::skip]
|
||||||
|
fn setup_before_prepare(&mut self, _cx: &mut Context) {
|
||||||
|
self.alter_classes(
|
||||||
|
ClassesOp::Prepend,
|
||||||
|
[
|
||||||
|
self.breakpoint().to_class("offcanvas"),
|
||||||
|
match self.placement() {
|
||||||
|
offcanvas::Placement::Start => "offcanvas-start",
|
||||||
|
offcanvas::Placement::End => "offcanvas-end",
|
||||||
|
offcanvas::Placement::Top => "offcanvas-top",
|
||||||
|
offcanvas::Placement::Bottom => "offcanvas-bottom",
|
||||||
|
}.to_string(),
|
||||||
|
match self.visibility() {
|
||||||
|
offcanvas::Visibility::Default => "",
|
||||||
|
offcanvas::Visibility::Show => "show",
|
||||||
|
}.to_string(),
|
||||||
|
]
|
||||||
|
.join(" "),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn prepare_component(&self, cx: &mut Context) -> PrepareMarkup {
|
||||||
|
let body = self.children().render(cx);
|
||||||
|
if body.is_empty() {
|
||||||
|
return PrepareMarkup::None;
|
||||||
|
}
|
||||||
|
|
||||||
|
let id = cx.required_id::<Self>(self.id());
|
||||||
|
let id_label = join!(id, "-label");
|
||||||
|
let id_target = join!("#", id);
|
||||||
|
|
||||||
|
let body_scroll = match self.body_scroll() {
|
||||||
|
offcanvas::BodyScroll::Disabled => None,
|
||||||
|
offcanvas::BodyScroll::Enabled => Some("true"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let backdrop = match self.backdrop() {
|
||||||
|
offcanvas::Backdrop::Disabled => Some("false"),
|
||||||
|
offcanvas::Backdrop::Enabled => None,
|
||||||
|
offcanvas::Backdrop::Static => Some("static"),
|
||||||
|
};
|
||||||
|
|
||||||
|
let title = self.title().using(cx);
|
||||||
|
|
||||||
|
PrepareMarkup::With(html! {
|
||||||
|
div
|
||||||
|
id=(id)
|
||||||
|
class=[self.classes().get()]
|
||||||
|
tabindex="-1"
|
||||||
|
data-bs-scroll=[body_scroll]
|
||||||
|
data-bs-backdrop=[backdrop]
|
||||||
|
aria-labelledby=(id_label)
|
||||||
|
{
|
||||||
|
div class="offcanvas-header" {
|
||||||
|
@if !title.is_empty() {
|
||||||
|
h5 class="offcanvas-title" id=(id_label) { (title) }
|
||||||
|
}
|
||||||
|
button
|
||||||
|
type="button"
|
||||||
|
class="btn-close"
|
||||||
|
data-bs-dismiss="offcanvas"
|
||||||
|
data-bs-target=(id_target)
|
||||||
|
aria-label=[L10n::t("offcanvas_close", &LOCALES_BOOTSIER).lookup(cx)]
|
||||||
|
{}
|
||||||
|
}
|
||||||
|
div class="offcanvas-body" {
|
||||||
|
(body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Offcanvas {
|
||||||
|
// **< Offcanvas BUILDER >**********************************************************************
|
||||||
|
|
||||||
|
/// Establece el identificador único (`id`) del panel.
|
||||||
|
#[builder_fn]
|
||||||
|
pub fn with_id(mut self, id: impl AsRef<str>) -> Self {
|
||||||
|
self.id.alter_value(id);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Modifica la lista de clases CSS aplicadas al panel.
|
||||||
|
#[builder_fn]
|
||||||
|
pub fn with_classes(mut self, op: ClassesOp, classes: impl AsRef<str>) -> Self {
|
||||||
|
self.classes.alter_value(op, classes);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Establece el título del encabezado.
|
||||||
|
#[builder_fn]
|
||||||
|
pub fn with_title(mut self, title: L10n) -> Self {
|
||||||
|
self.title = title;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Establece el punto de ruptura a partir del cual cambia el comportamiento del panel.
|
||||||
|
///
|
||||||
|
/// - **Por debajo** de ese tamaño de pantalla, el componente actúa como panel deslizante
|
||||||
|
/// ([`Offcanvas`]).
|
||||||
|
/// - **Por encima**, el contenido del panel se muestra tal cual, integrado en la página.
|
||||||
|
///
|
||||||
|
/// Por ejemplo, con `BreakPoint::LG`, será *offcanvas* en móviles y tabletas, y visible
|
||||||
|
/// directamente en pantallas grandes. Por defecto usa `BreakPoint::None` para que sea
|
||||||
|
/// *offcanvas* siempre.
|
||||||
|
#[builder_fn]
|
||||||
|
pub fn with_breakpoint(mut self, bp: BreakPoint) -> Self {
|
||||||
|
self.breakpoint = bp;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Ajusta la capa de fondo del panel para definir su comportamiento al hacer clic fuera del
|
||||||
|
/// panel.
|
||||||
|
#[builder_fn]
|
||||||
|
pub fn with_backdrop(mut self, backdrop: offcanvas::Backdrop) -> Self {
|
||||||
|
self.backdrop = backdrop;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Permite o bloquea el desplazamiento de la página principal mientras el panel está abierto.
|
||||||
|
#[builder_fn]
|
||||||
|
pub fn with_body_scroll(mut self, scrolling: offcanvas::BodyScroll) -> Self {
|
||||||
|
self.scrolling = scrolling;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Indica desde qué borde de la ventana entra y se ancla el panel.
|
||||||
|
#[builder_fn]
|
||||||
|
pub fn with_placement(mut self, placement: offcanvas::Placement) -> Self {
|
||||||
|
self.placement = placement;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Fija el estado inicial del panel (oculto o visible al cargar).
|
||||||
|
#[builder_fn]
|
||||||
|
pub fn with_visibility(mut self, visibility: offcanvas::Visibility) -> Self {
|
||||||
|
self.visibility = visibility;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Añade un nuevo componente hijo al panel.
|
||||||
|
#[inline]
|
||||||
|
pub fn add_child(mut self, child: impl Component) -> Self {
|
||||||
|
self.children.add(Child::with(child));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Modifica la lista de componentes (`children`) aplicando una operación [`ChildOp`].
|
||||||
|
#[builder_fn]
|
||||||
|
pub fn with_children(mut self, op: ChildOp) -> Self {
|
||||||
|
self.children.alter_child(op);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
// **< Offcanvas GETTERS >**********************************************************************
|
||||||
|
|
||||||
|
/// Devuelve las clases CSS asociadas al panel.
|
||||||
|
pub fn classes(&self) -> &AttrClasses {
|
||||||
|
&self.classes
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Devuelve el título del panel.
|
||||||
|
pub fn title(&self) -> &L10n {
|
||||||
|
&self.title
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Devuelve el punto de ruptura configurado para cambiar el comportamiento del panel.
|
||||||
|
pub fn breakpoint(&self) -> &BreakPoint {
|
||||||
|
&self.breakpoint
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Devuelve el comportamiento configurado para la capa de fondo.
|
||||||
|
pub fn backdrop(&self) -> &offcanvas::Backdrop {
|
||||||
|
&self.backdrop
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Indica si la página principal puede desplazarse mientras el panel está abierto.
|
||||||
|
pub fn body_scroll(&self) -> &offcanvas::BodyScroll {
|
||||||
|
&self.scrolling
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Devuelve la posición de inicio del panel.
|
||||||
|
pub fn placement(&self) -> &offcanvas::Placement {
|
||||||
|
&self.placement
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Devuelve el estado inicial del panel.
|
||||||
|
pub fn visibility(&self) -> &offcanvas::Visibility {
|
||||||
|
&self.visibility
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Devuelve la lista de componentes (`children`) del panel.
|
||||||
|
pub fn children(&self) -> &Children {
|
||||||
|
&self.children
|
||||||
|
}
|
||||||
|
}
|
||||||
60
extensions/pagetop-bootsier/src/theme/offcanvas/props.rs
Normal file
60
extensions/pagetop-bootsier/src/theme/offcanvas/props.rs
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
use pagetop::prelude::*;
|
||||||
|
|
||||||
|
// **< Backdrop >***********************************************************************************
|
||||||
|
|
||||||
|
/// Comportamiento de la capa de fondo (*backdrop*) de un panel
|
||||||
|
/// [`Offcanvas`](crate::theme::Offcanvas) al deslizarse.
|
||||||
|
#[derive(AutoDefault)]
|
||||||
|
pub enum Backdrop {
|
||||||
|
/// Sin capa de fondo, la página principal permanece visible e interactiva.
|
||||||
|
Disabled,
|
||||||
|
/// Opción por defecto, se oscurece el fondo; un clic fuera del panel suele cerrarlo.
|
||||||
|
#[default]
|
||||||
|
Enabled,
|
||||||
|
/// Muestra la capa de fondo pero no se cierra al hacer clic fuera del panel. Útil si se
|
||||||
|
/// requiere completar una acción antes de salir.
|
||||||
|
Static,
|
||||||
|
}
|
||||||
|
|
||||||
|
// **< BodyScroll >*********************************************************************************
|
||||||
|
|
||||||
|
/// Controla si la página principal puede desplazarse al abrir un panel
|
||||||
|
/// [`Offcanvas`](crate::theme::Offcanvas).
|
||||||
|
#[derive(AutoDefault)]
|
||||||
|
pub enum BodyScroll {
|
||||||
|
/// Opción por defecto, la página principal se bloquea centrando la interacción en el panel.
|
||||||
|
#[default]
|
||||||
|
Disabled,
|
||||||
|
/// Permite el desplazamiento de la página principal.
|
||||||
|
Enabled,
|
||||||
|
}
|
||||||
|
|
||||||
|
// **< Placement >**********************************************************************************
|
||||||
|
|
||||||
|
/// Posición de aparición de un panel [`Offcanvas`](crate::theme::Offcanvas) al deslizarse.
|
||||||
|
///
|
||||||
|
/// Define desde qué borde de la ventana entra y se ancla el panel.
|
||||||
|
#[derive(AutoDefault)]
|
||||||
|
pub enum Placement {
|
||||||
|
/// Opción por defecto, desde el borde inicial según dirección de lectura (respetando LTR/RTL).
|
||||||
|
#[default]
|
||||||
|
Start,
|
||||||
|
/// Desde el borde final según dirección de lectura (respetando LTR/RTL).
|
||||||
|
End,
|
||||||
|
/// Desde la parte superior.
|
||||||
|
Top,
|
||||||
|
/// Desde la parte inferior.
|
||||||
|
Bottom,
|
||||||
|
}
|
||||||
|
|
||||||
|
// **< Visibility >*********************************************************************************
|
||||||
|
|
||||||
|
/// Estado inicial de un panel [`Offcanvas`](crate::theme::Offcanvas).
|
||||||
|
#[derive(AutoDefault)]
|
||||||
|
pub enum Visibility {
|
||||||
|
/// El panel permanece oculto desde el principio.
|
||||||
|
#[default]
|
||||||
|
Default,
|
||||||
|
/// El panel se muestra abierto al cargar.
|
||||||
|
Show,
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue