♻️ Refactoriza Dropdown para separar propiedades
This commit is contained in:
parent
6c5e1b1188
commit
b6b26c23da
3 changed files with 110 additions and 107 deletions
|
|
@ -10,9 +10,11 @@
|
||||||
//! Su propósito es ofrecer una base uniforme sobre la que construir menús consistentes, adaptados
|
//! Su propósito es ofrecer una base uniforme sobre la que construir menús consistentes, adaptados
|
||||||
//! al contexto de cada aplicación.
|
//! al contexto de cada aplicación.
|
||||||
|
|
||||||
|
mod props;
|
||||||
|
pub use props::{AutoClose, Direction, MenuAlign, MenuPosition};
|
||||||
|
|
||||||
mod component;
|
mod component;
|
||||||
pub use component::Dropdown;
|
pub use component::Dropdown;
|
||||||
pub use component::{AutoClose, Direction, MenuAlign, MenuPosition};
|
|
||||||
|
|
||||||
mod item;
|
mod item;
|
||||||
pub use item::{Item, ItemKind};
|
pub use item::{Item, ItemKind};
|
||||||
|
|
|
||||||
|
|
@ -3,91 +3,6 @@ use pagetop::prelude::*;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use crate::LOCALES_BOOTSIER;
|
use crate::LOCALES_BOOTSIER;
|
||||||
|
|
||||||
// **< AutoClose >**********************************************************************************
|
|
||||||
|
|
||||||
/// Estrategia para el cierre automático de un menú [`Dropdown`].
|
|
||||||
///
|
|
||||||
/// Define cuándo se cierra el menú desplegado según la interacción del usuario.
|
|
||||||
#[derive(AutoDefault)]
|
|
||||||
pub enum AutoClose {
|
|
||||||
/// Comportamiento por defecto, se cierra con clics dentro y fuera del menú, o pulsando `Esc`.
|
|
||||||
#[default]
|
|
||||||
Default,
|
|
||||||
/// Sólo se cierra con clics dentro del menú.
|
|
||||||
ClickableInside,
|
|
||||||
/// Sólo se cierra con clics fuera del menú.
|
|
||||||
ClickableOutside,
|
|
||||||
/// Cierre manual, no se cierra con clics; sólo al pulsar nuevamente el botón del menú
|
|
||||||
/// (*toggle*), o pulsando `Esc`.
|
|
||||||
ManualClose,
|
|
||||||
}
|
|
||||||
|
|
||||||
// **< Direction >**********************************************************************************
|
|
||||||
|
|
||||||
/// Dirección de despliegue de un menú [`Dropdown`].
|
|
||||||
///
|
|
||||||
/// Controla desde qué posición se muestra el menú respecto al botón.
|
|
||||||
#[derive(AutoDefault)]
|
|
||||||
pub enum Direction {
|
|
||||||
/// Comportamiento por defecto (despliega el menú hacia abajo desde la posición inicial,
|
|
||||||
/// respetando LTR/RTL).
|
|
||||||
#[default]
|
|
||||||
Default,
|
|
||||||
/// Centra horizontalmente el menú respecto al botón.
|
|
||||||
Centered,
|
|
||||||
/// Despliega el menú hacia arriba.
|
|
||||||
Dropup,
|
|
||||||
/// Despliega el menú hacia arriba y centrado.
|
|
||||||
DropupCentered,
|
|
||||||
/// Despliega el menú desde el lateral final, respetando LTR/RTL.
|
|
||||||
Dropend,
|
|
||||||
/// Despliega el menú desde el lateral inicial, respetando LTR/RTL.
|
|
||||||
Dropstart,
|
|
||||||
}
|
|
||||||
|
|
||||||
// **< MenuAlign >**********************************************************************************
|
|
||||||
|
|
||||||
/// Alineación horizontal del menú desplegable [`Dropdown`].
|
|
||||||
///
|
|
||||||
/// Permite alinear el menú al inicio o al final del botón (respetando LTR/RTL) y añadirle una
|
|
||||||
/// alineación diferente a partir de un punto de ruptura ([`BreakPoint`]).
|
|
||||||
#[derive(AutoDefault)]
|
|
||||||
pub enum MenuAlign {
|
|
||||||
/// Alineación al inicio (comportamiento por defecto).
|
|
||||||
#[default]
|
|
||||||
Start,
|
|
||||||
/// Alineación al inicio a partir del punto de ruptura indicado.
|
|
||||||
StartAt(BreakPoint),
|
|
||||||
/// Alineación al inicio por defecto, y al final a partir de un punto de ruptura válido.
|
|
||||||
StartAndEnd(BreakPoint),
|
|
||||||
/// Alineación al final.
|
|
||||||
End,
|
|
||||||
/// Alineación al final a partir del punto de ruptura indicado.
|
|
||||||
EndAt(BreakPoint),
|
|
||||||
/// Alineación al final por defecto, y al inicio a partir de un punto de ruptura válido.
|
|
||||||
EndAndStart(BreakPoint),
|
|
||||||
}
|
|
||||||
|
|
||||||
// **< MenuPosition >*******************************************************************************
|
|
||||||
|
|
||||||
/// Posición relativa del menú desplegable [`Dropdown`].
|
|
||||||
///
|
|
||||||
/// Permite indicar un desplazamiento (*offset*) manual o referenciar al elemento padre para el
|
|
||||||
/// cálculo de la posición.
|
|
||||||
#[derive(AutoDefault)]
|
|
||||||
pub enum MenuPosition {
|
|
||||||
/// Posicionamiento automático por defecto.
|
|
||||||
#[default]
|
|
||||||
Default,
|
|
||||||
/// Desplazamiento manual en píxeles `(x, y)` aplicado al menú. Se admiten valores negativos.
|
|
||||||
Offset(i8, i8),
|
|
||||||
/// Posiciona el menú tomando como referencia el botón padre. Especialmente útil cuando
|
|
||||||
/// [`button_split()`](crate::theme::Dropdown::button_split) es `true`.
|
|
||||||
Parent,
|
|
||||||
}
|
|
||||||
|
|
||||||
// **< Dropdown >**********************************************************************************
|
|
||||||
|
|
||||||
/// Componente para crear un **menú desplegable**.
|
/// Componente para crear un **menú desplegable**.
|
||||||
///
|
///
|
||||||
/// Renderiza un botón (único o desdoblado, ver [`with_button_split()`](Self::with_button_split))
|
/// Renderiza un botón (único o desdoblado, ver [`with_button_split()`](Self::with_button_split))
|
||||||
|
|
@ -146,13 +61,13 @@ impl Component for Dropdown {
|
||||||
self.alter_classes(ClassesOp::Prepend, [
|
self.alter_classes(ClassesOp::Prepend, [
|
||||||
if g { "btn-group" } else { "" },
|
if g { "btn-group" } else { "" },
|
||||||
match self.direction() {
|
match self.direction() {
|
||||||
Direction::Default if g => "",
|
dropdown::Direction::Default if g => "",
|
||||||
Direction::Default => "dropdown",
|
dropdown::Direction::Default => "dropdown",
|
||||||
Direction::Centered => "dropdown-center",
|
dropdown::Direction::Centered => "dropdown-center",
|
||||||
Direction::Dropup => "dropup",
|
dropdown::Direction::Dropup => "dropup",
|
||||||
Direction::DropupCentered => "dropup-center",
|
dropdown::Direction::DropupCentered => "dropup-center",
|
||||||
Direction::Dropend => "dropend",
|
dropdown::Direction::Dropend => "dropend",
|
||||||
Direction::Dropstart => "dropstart",
|
dropdown::Direction::Dropstart => "dropstart",
|
||||||
}
|
}
|
||||||
].join(" "));
|
].join(" "));
|
||||||
}
|
}
|
||||||
|
|
@ -176,30 +91,30 @@ impl Component for Dropdown {
|
||||||
&self.button_color().to_string(),
|
&self.button_color().to_string(),
|
||||||
].join(" "));
|
].join(" "));
|
||||||
@let (offset, reference) = match self.menu_position() {
|
@let (offset, reference) = match self.menu_position() {
|
||||||
MenuPosition::Default => (None, None),
|
dropdown::MenuPosition::Default => (None, None),
|
||||||
MenuPosition::Offset(x, y) => (Some(format!("{x},{y}")), None),
|
dropdown::MenuPosition::Offset(x, y) => (Some(format!("{x},{y}")), None),
|
||||||
MenuPosition::Parent => (None, Some("parent")),
|
dropdown::MenuPosition::Parent => (None, Some("parent")),
|
||||||
};
|
};
|
||||||
@let auto_close = match self.auto_close {
|
@let auto_close = match self.auto_close {
|
||||||
AutoClose::Default => None,
|
dropdown::AutoClose::Default => None,
|
||||||
AutoClose::ClickableInside => Some("inside"),
|
dropdown::AutoClose::ClickableInside => Some("inside"),
|
||||||
AutoClose::ClickableOutside => Some("outside"),
|
dropdown::AutoClose::ClickableOutside => Some("outside"),
|
||||||
AutoClose::ManualClose => Some("false"),
|
dropdown::AutoClose::ManualClose => Some("false"),
|
||||||
};
|
};
|
||||||
@let menu_classes = AttrClasses::new("dropdown-menu")
|
@let menu_classes = AttrClasses::new("dropdown-menu")
|
||||||
.with_value(ClassesOp::Add, match self.menu_align() {
|
.with_value(ClassesOp::Add, match self.menu_align() {
|
||||||
MenuAlign::Start => String::new(),
|
dropdown::MenuAlign::Start => String::new(),
|
||||||
MenuAlign::StartAt(bp) => bp.try_class("dropdown-menu")
|
dropdown::MenuAlign::StartAt(bp) => bp.try_class("dropdown-menu")
|
||||||
.map_or(String::new(), |class| join!(class, "-start")),
|
.map_or(String::new(), |class| join!(class, "-start")),
|
||||||
MenuAlign::StartAndEnd(bp) => bp.try_class("dropdown-menu")
|
dropdown::MenuAlign::StartAndEnd(bp) => bp.try_class("dropdown-menu")
|
||||||
.map_or(
|
.map_or(
|
||||||
"dropdown-menu-start".into(),
|
"dropdown-menu-start".into(),
|
||||||
|class| join!("dropdown-menu-start ", class, "-end")
|
|class| join!("dropdown-menu-start ", class, "-end")
|
||||||
),
|
),
|
||||||
MenuAlign::End => "dropdown-menu-end".into(),
|
dropdown::MenuAlign::End => "dropdown-menu-end".into(),
|
||||||
MenuAlign::EndAt(bp) => bp.try_class("dropdown-menu")
|
dropdown::MenuAlign::EndAt(bp) => bp.try_class("dropdown-menu")
|
||||||
.map_or(String::new(), |class| join!(class, "-end")),
|
.map_or(String::new(), |class| join!(class, "-end")),
|
||||||
MenuAlign::EndAndStart(bp) => bp.try_class("dropdown-menu")
|
dropdown::MenuAlign::EndAndStart(bp) => bp.try_class("dropdown-menu")
|
||||||
.map_or(
|
.map_or(
|
||||||
"dropdown-menu-end".into(),
|
"dropdown-menu-end".into(),
|
||||||
|class| join!("dropdown-menu-end ", class, "-start")
|
|class| join!("dropdown-menu-end ", class, "-start")
|
||||||
|
|
@ -237,7 +152,7 @@ impl Component for Dropdown {
|
||||||
};
|
};
|
||||||
// Orden según dirección (en `dropstart` el *toggle* se sitúa antes).
|
// Orden según dirección (en `dropstart` el *toggle* se sitúa antes).
|
||||||
@match self.direction() {
|
@match self.direction() {
|
||||||
Direction::Dropstart => {
|
dropdown::Direction::Dropstart => {
|
||||||
(btn_toggle)
|
(btn_toggle)
|
||||||
ul class=[menu_classes.get()] { (items) }
|
ul class=[menu_classes.get()] { (items) }
|
||||||
(btn)
|
(btn)
|
||||||
|
|
|
||||||
86
extensions/pagetop-bootsier/src/theme/dropdown/props.rs
Normal file
86
extensions/pagetop-bootsier/src/theme/dropdown/props.rs
Normal file
|
|
@ -0,0 +1,86 @@
|
||||||
|
use pagetop::prelude::*;
|
||||||
|
|
||||||
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
// **< AutoClose >**********************************************************************************
|
||||||
|
|
||||||
|
/// Estrategia para el cierre automático de un menú [`Dropdown`].
|
||||||
|
///
|
||||||
|
/// Define cuándo se cierra el menú desplegado según la interacción del usuario.
|
||||||
|
#[derive(AutoDefault)]
|
||||||
|
pub enum AutoClose {
|
||||||
|
/// Comportamiento por defecto, se cierra con clics dentro y fuera del menú, o pulsando `Esc`.
|
||||||
|
#[default]
|
||||||
|
Default,
|
||||||
|
/// Sólo se cierra con clics dentro del menú.
|
||||||
|
ClickableInside,
|
||||||
|
/// Sólo se cierra con clics fuera del menú.
|
||||||
|
ClickableOutside,
|
||||||
|
/// Cierre manual, no se cierra con clics; sólo al pulsar nuevamente el botón del menú
|
||||||
|
/// (*toggle*), o pulsando `Esc`.
|
||||||
|
ManualClose,
|
||||||
|
}
|
||||||
|
|
||||||
|
// **< Direction >**********************************************************************************
|
||||||
|
|
||||||
|
/// Dirección de despliegue de un menú [`Dropdown`].
|
||||||
|
///
|
||||||
|
/// Controla desde qué posición se muestra el menú respecto al botón.
|
||||||
|
#[derive(AutoDefault)]
|
||||||
|
pub enum Direction {
|
||||||
|
/// Comportamiento por defecto (despliega el menú hacia abajo desde la posición inicial,
|
||||||
|
/// respetando LTR/RTL).
|
||||||
|
#[default]
|
||||||
|
Default,
|
||||||
|
/// Centra horizontalmente el menú respecto al botón.
|
||||||
|
Centered,
|
||||||
|
/// Despliega el menú hacia arriba.
|
||||||
|
Dropup,
|
||||||
|
/// Despliega el menú hacia arriba y centrado.
|
||||||
|
DropupCentered,
|
||||||
|
/// Despliega el menú desde el lateral final, respetando LTR/RTL.
|
||||||
|
Dropend,
|
||||||
|
/// Despliega el menú desde el lateral inicial, respetando LTR/RTL.
|
||||||
|
Dropstart,
|
||||||
|
}
|
||||||
|
|
||||||
|
// **< MenuAlign >**********************************************************************************
|
||||||
|
|
||||||
|
/// Alineación horizontal del menú desplegable [`Dropdown`].
|
||||||
|
///
|
||||||
|
/// Permite alinear el menú al inicio o al final del botón (respetando LTR/RTL) y añadirle una
|
||||||
|
/// alineación diferente a partir de un punto de ruptura ([`BreakPoint`]).
|
||||||
|
#[derive(AutoDefault)]
|
||||||
|
pub enum MenuAlign {
|
||||||
|
/// Alineación al inicio (comportamiento por defecto).
|
||||||
|
#[default]
|
||||||
|
Start,
|
||||||
|
/// Alineación al inicio a partir del punto de ruptura indicado.
|
||||||
|
StartAt(BreakPoint),
|
||||||
|
/// Alineación al inicio por defecto, y al final a partir de un punto de ruptura válido.
|
||||||
|
StartAndEnd(BreakPoint),
|
||||||
|
/// Alineación al final.
|
||||||
|
End,
|
||||||
|
/// Alineación al final a partir del punto de ruptura indicado.
|
||||||
|
EndAt(BreakPoint),
|
||||||
|
/// Alineación al final por defecto, y al inicio a partir de un punto de ruptura válido.
|
||||||
|
EndAndStart(BreakPoint),
|
||||||
|
}
|
||||||
|
|
||||||
|
// **< MenuPosition >*******************************************************************************
|
||||||
|
|
||||||
|
/// Posición relativa del menú desplegable [`Dropdown`].
|
||||||
|
///
|
||||||
|
/// Permite indicar un desplazamiento (*offset*) manual o referenciar al elemento padre para el
|
||||||
|
/// cálculo de la posición.
|
||||||
|
#[derive(AutoDefault)]
|
||||||
|
pub enum MenuPosition {
|
||||||
|
/// Posicionamiento automático por defecto.
|
||||||
|
#[default]
|
||||||
|
Default,
|
||||||
|
/// Desplazamiento manual en píxeles `(x, y)` aplicado al menú. Se admiten valores negativos.
|
||||||
|
Offset(i8, i8),
|
||||||
|
/// Posiciona el menú tomando como referencia el botón padre. Especialmente útil cuando
|
||||||
|
/// [`button_split()`](crate::theme::Dropdown::button_split) es `true`.
|
||||||
|
Parent,
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue