WIP: Añade nueva extensión para dar soporte a bases de datos #12
43 changed files with 315 additions and 348 deletions
|
|
@ -1,6 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use pagetop_bootsier::prelude::*;
|
||||
use pagetop_bootsier::theme::*;
|
||||
|
||||
include_locales!(LOC from "examples/locale");
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use pagetop_bootsier::prelude::*;
|
||||
use pagetop_bootsier::theme::*;
|
||||
|
||||
include_locales!(LOC from "examples/locale");
|
||||
|
||||
|
|
|
|||
|
|
@ -96,12 +96,6 @@ pub mod config;
|
|||
|
||||
pub mod theme;
|
||||
|
||||
/// *Prelude* del tema.
|
||||
pub mod prelude {
|
||||
pub use crate::config::*;
|
||||
pub use crate::theme::*;
|
||||
}
|
||||
|
||||
/// Plantillas que Bootsier añade.
|
||||
#[derive(AutoDefault)]
|
||||
pub enum BootsierTemplate {
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ impl BorderColor {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// assert_eq!(BorderColor::Theme(Color::Primary).to_class(), "border-primary");
|
||||
/// assert_eq!(BorderColor::Subtle(Color::Warning).to_class(), "border-warning-subtle");
|
||||
/// assert_eq!(BorderColor::Black.to_class(), "border-black");
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ impl BreakPoint {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let bp = BreakPoint::MD;
|
||||
/// assert_eq!(bp.class_with("col", ""), "col-md");
|
||||
/// assert_eq!(bp.class_with("col", "6"), "col-md-6");
|
||||
|
|
|
|||
|
|
@ -76,7 +76,7 @@ impl ButtonColor {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// assert_eq!(
|
||||
/// ButtonColor::Background(Color::Primary).to_class(),
|
||||
/// "btn-primary"
|
||||
|
|
@ -132,7 +132,7 @@ impl ButtonSize {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// assert_eq!(ButtonSize::Small.to_class(), "btn-sm");
|
||||
/// assert_eq!(ButtonSize::Large.to_class(), "btn-lg");
|
||||
/// assert_eq!(ButtonSize::Default.to_class(), "");
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ impl Color {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// assert_eq!(Color::Primary.to_class(), "primary");
|
||||
/// assert_eq!(Color::Danger.to_class(), "danger");
|
||||
/// ```
|
||||
|
|
@ -124,7 +124,7 @@ impl Opacity {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// assert_eq!(Opacity::Opaque.class_with(""), "opacity-100");
|
||||
/// assert_eq!(Opacity::Half.class_with("bg"), "bg-opacity-50");
|
||||
/// assert_eq!(Opacity::SemiTransparent.class_with("text"), "text-opacity-25");
|
||||
|
|
@ -156,7 +156,7 @@ impl Opacity {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// assert_eq!(Opacity::Opaque.to_class(), "opacity-100");
|
||||
/// assert_eq!(Opacity::Half.to_class(), "opacity-50");
|
||||
/// assert_eq!(Opacity::Default.to_class(), "");
|
||||
|
|
@ -237,7 +237,7 @@ impl ColorBg {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// assert_eq!(ColorBg::Body.to_class(), "bg-body");
|
||||
/// assert_eq!(ColorBg::Theme(Color::Primary).to_class(), "bg-primary");
|
||||
/// assert_eq!(ColorBg::Subtle(Color::Warning).to_class(), "bg-warning-subtle");
|
||||
|
|
@ -321,7 +321,7 @@ impl ColorText {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// assert_eq!(ColorText::Body.to_class(), "text-body");
|
||||
/// assert_eq!(ColorText::Theme(Color::Primary).to_class(), "text-primary");
|
||||
/// assert_eq!(ColorText::Emphasis(Color::Danger).to_class(), "text-danger-emphasis");
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ impl ScaleSize {
|
|||
/// # Ejemplo
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// assert_eq!(ScaleSize::Auto.class_with("border"), "border");
|
||||
/// assert_eq!(ScaleSize::Zero.class_with("m"), "m-0");
|
||||
/// assert_eq!(ScaleSize::Three.class_with("p"), "p-3");
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ impl RoundedRadius {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// assert_eq!(RoundedRadius::Scale2.class_with(""), "rounded-2");
|
||||
/// assert_eq!(RoundedRadius::Zero.class_with("rounded-top"), "rounded-top-0");
|
||||
/// assert_eq!(RoundedRadius::Scale3.class_with("rounded-top-end"), "rounded-top-end-3");
|
||||
|
|
@ -103,7 +103,7 @@ impl RoundedRadius {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// assert_eq!(RoundedRadius::Default.to_class(), "rounded");
|
||||
/// assert_eq!(RoundedRadius::Zero.to_class(), "rounded-0");
|
||||
/// assert_eq!(RoundedRadius::Scale3.to_class(), "rounded-3");
|
||||
|
|
|
|||
|
|
@ -19,8 +19,9 @@ use crate::theme::{ButtonAction, ButtonColor, ButtonSize};
|
|||
/// # Ejemplo
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// use pagetop::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// let save = Button::submit(L10n::n("Save"))
|
||||
/// .with_color(ButtonColor::Background(Color::Primary));
|
||||
///
|
||||
|
|
|
|||
|
|
@ -26,45 +26,33 @@ use crate::theme::attrs::{BorderColor, Opacity, ScaleSize, Side};
|
|||
///
|
||||
/// # Ejemplos
|
||||
///
|
||||
/// **Borde global:**
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// // Borde global.
|
||||
/// let b = classes::Border::with(ScaleSize::Two);
|
||||
/// assert_eq!(b.to_class(), "border-2");
|
||||
/// ```
|
||||
///
|
||||
/// **Aditivo (solo borde superior):**
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// // Aditivo (sólo borde superior):
|
||||
/// let b = classes::Border::default().with_side(Side::Top, ScaleSize::One);
|
||||
/// assert_eq!(b.to_class(), "border-top-1");
|
||||
/// ```
|
||||
///
|
||||
/// **Sustractivo (borde global menos el superior):**
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// // Sustractivo (borde global menos el superior):
|
||||
/// let b = classes::Border::new().with_side(Side::Top, ScaleSize::Zero);
|
||||
/// assert_eq!(b.to_class(), "border border-top-0");
|
||||
/// ```
|
||||
///
|
||||
/// **Ancho por lado (lado lógico inicial a 2 y final a 4):**
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// // Ancho por lado (lado lógico inicial a 2 y final a 4):
|
||||
/// let b = classes::Border::default()
|
||||
/// .with_side(Side::Start, ScaleSize::Two)
|
||||
/// .with_side(Side::End, ScaleSize::Four);
|
||||
/// assert_eq!(b.to_class(), "border-end-4 border-start-2");
|
||||
/// ```
|
||||
///
|
||||
/// **Combinado (ejemplo completo):**
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// // Combinado (ejemplo completo):
|
||||
/// let b = classes::Border::new() // Borde por defecto.
|
||||
/// .with_side(Side::Top, ScaleSize::Zero) // Quita borde superior.
|
||||
/// .with_side(Side::End, ScaleSize::Three) // Ancho 3 para el lado lógico final.
|
||||
/// .with_color(BorderColor::Theme(Color::Primary))
|
||||
/// .with_opacity(Opacity::Half);
|
||||
///
|
||||
/// assert_eq!(b.to_class(), "border border-top-0 border-end-3 border-primary border-opacity-50");
|
||||
/// ```
|
||||
#[rustfmt::skip]
|
||||
|
|
@ -158,7 +146,7 @@ impl Border {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// // Convertir explícitamente con `From::from`:
|
||||
/// let b = classes::Border::from(ScaleSize::Two);
|
||||
/// assert_eq!(b.to_class(), "border-2");
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ use crate::theme::attrs::{ColorBg, ColorText, Opacity};
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// // Sin clases.
|
||||
/// let s = classes::Background::new();
|
||||
/// assert_eq!(s.to_class(), "");
|
||||
|
|
@ -90,7 +91,7 @@ impl From<(ColorBg, Opacity)> for Background {
|
|||
/// # Ejemplo
|
||||
///
|
||||
/// ```
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let s: classes::Background = (ColorBg::White, Opacity::SemiTransparent).into();
|
||||
/// assert_eq!(s.to_class(), "bg-white bg-opacity-25");
|
||||
/// ```
|
||||
|
|
@ -105,7 +106,7 @@ impl From<ColorBg> for Background {
|
|||
/// # Ejemplo
|
||||
///
|
||||
/// ```
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let s: classes::Background = ColorBg::Black.into();
|
||||
/// assert_eq!(s.to_class(), "bg-black");
|
||||
/// ```
|
||||
|
|
@ -121,7 +122,8 @@ impl From<ColorBg> for Background {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// // Sin clases.
|
||||
/// let s = classes::Text::new();
|
||||
/// assert_eq!(s.to_class(), "");
|
||||
|
|
@ -202,7 +204,7 @@ impl From<(ColorText, Opacity)> for Text {
|
|||
/// # Ejemplo
|
||||
///
|
||||
/// ```
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let s: classes::Text = (ColorText::Theme(Color::Danger), Opacity::Opaque).into();
|
||||
/// assert_eq!(s.to_class(), "text-danger text-opacity-100");
|
||||
/// ```
|
||||
|
|
@ -218,7 +220,7 @@ impl From<ColorText> for Text {
|
|||
/// # Ejemplo
|
||||
///
|
||||
/// ```
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let s: classes::Text = ColorText::Black.into();
|
||||
/// assert_eq!(s.to_class(), "text-black");
|
||||
/// ```
|
||||
|
|
|
|||
|
|
@ -10,7 +10,8 @@ use crate::theme::BreakPoint;
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// let m = classes::Margin::with(Side::Top, ScaleSize::Three);
|
||||
/// assert_eq!(m.to_class(), "mt-3");
|
||||
///
|
||||
|
|
@ -97,7 +98,8 @@ impl Margin {
|
|||
/// # Ejemplos
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// let p = classes::Padding::with(Side::LeftAndRight, ScaleSize::Two);
|
||||
/// assert_eq!(p.to_class(), "px-2");
|
||||
///
|
||||
|
|
|
|||
|
|
@ -14,42 +14,30 @@ use crate::theme::attrs::RoundedRadius;
|
|||
///
|
||||
/// # Ejemplos
|
||||
///
|
||||
/// **Radio global:**
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// // Radio global:
|
||||
/// let r = classes::Rounded::with(RoundedRadius::Default);
|
||||
/// assert_eq!(r.to_class(), "rounded");
|
||||
/// ```
|
||||
///
|
||||
/// **Sin redondeo:**
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// // Sin redondeo:
|
||||
/// let r = classes::Rounded::new();
|
||||
/// assert_eq!(r.to_class(), "");
|
||||
/// ```
|
||||
///
|
||||
/// **Radio en las esquinas de un lado lógico:**
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// // Radio en las esquinas de un lado lógico:
|
||||
/// let r = classes::Rounded::new().with_end(RoundedRadius::Scale2);
|
||||
/// assert_eq!(r.to_class(), "rounded-end-2");
|
||||
/// ```
|
||||
///
|
||||
/// **Radio en una esquina concreta:**
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// // Radio en una esquina concreta:
|
||||
/// let r = classes::Rounded::new().with_top_start(RoundedRadius::Scale3);
|
||||
/// assert_eq!(r.to_class(), "rounded-top-start-3");
|
||||
/// ```
|
||||
///
|
||||
/// **Combinado (ejemplo completo):**
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// // Combinado (ejemplo completo):
|
||||
/// let r = classes::Rounded::new()
|
||||
/// .with_top(RoundedRadius::Default) // Añade redondeo arriba.
|
||||
/// .with_bottom_start(RoundedRadius::Scale4) // Añade una esquina redondeada concreta.
|
||||
/// .with_bottom_end(RoundedRadius::Circle); // Añade redondeo extremo en otra esquina.
|
||||
///
|
||||
/// assert_eq!(r.to_class(), "rounded-top rounded-bottom-start-4 rounded-bottom-end-circle");
|
||||
/// ```
|
||||
#[rustfmt::skip]
|
||||
|
|
|
|||
|
|
@ -6,16 +6,6 @@
|
|||
//! Con [`container::Width`](crate::theme::container::Width) se puede definir el ancho y el
|
||||
//! comportamiento *responsive* del contenedor. También permite aplicar utilidades de estilo para el
|
||||
//! fondo, texto, borde o esquinas redondeadas.
|
||||
//!
|
||||
//! # Ejemplo
|
||||
//!
|
||||
//! ```rust
|
||||
//! # use pagetop::prelude::*;
|
||||
//! # use pagetop_bootsier::prelude::*;
|
||||
//! let main = Container::main()
|
||||
//! .with_id("main-page")
|
||||
//! .with_width(container::Width::From(BreakPoint::LG));
|
||||
//! ```
|
||||
|
||||
mod props;
|
||||
pub use props::{Kind, Width};
|
||||
|
|
|
|||
|
|
@ -1,11 +1,23 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
|
||||
/// Componente para crear un **contenedor de componentes**.
|
||||
/// Componente para crear un **contenedor de componentes** ([`container`]).
|
||||
///
|
||||
/// Envuelve un contenido con la etiqueta HTML indicada por [`container::Kind`]. Sólo se renderiza
|
||||
/// si existen componentes hijos (*children*).
|
||||
/// Envuelve un conjunto de componentes en un contenedor establecido que se crea aplicando uno de
|
||||
/// los tipos definidos en [`container::Kind`].
|
||||
///
|
||||
/// Si no contiene elementos, el componente **no se renderiza**.
|
||||
///
|
||||
/// # Ejemplo
|
||||
///
|
||||
/// ```rust
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// let main = Container::main()
|
||||
/// .with_id("main-page")
|
||||
/// .with_width(container::Width::From(BreakPoint::LG));
|
||||
/// ```
|
||||
#[derive(AutoDefault, Clone, Debug, Getters)]
|
||||
pub struct Container {
|
||||
#[getters(skip)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Definiciones para crear menús desplegables [`Dropdown`].
|
||||
//! Definiciones para crear menús desplegables ([`Dropdown`]).
|
||||
//!
|
||||
//! Cada [`dropdown::Item`](crate::theme::dropdown::Item) representa un elemento individual del
|
||||
//! desplegable [`Dropdown`], con distintos comportamientos según su finalidad, como enlaces de
|
||||
|
|
@ -6,23 +6,6 @@
|
|||
//!
|
||||
//! 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).
|
||||
//!
|
||||
//! # Ejemplo
|
||||
//!
|
||||
//! ```rust
|
||||
//! # use pagetop::prelude::*;
|
||||
//! # use pagetop_bootsier::prelude::*;
|
||||
//! let dd = Dropdown::new()
|
||||
//! .with_title(L10n::n("Menu"))
|
||||
//! .with_button_color(ButtonColor::Background(Color::Secondary))
|
||||
//! .with_auto_close(dropdown::AutoClose::ClickableInside)
|
||||
//! .with_direction(dropdown::Direction::Dropend)
|
||||
//! .with_item(dropdown::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
//! .with_item(dropdown::Item::link_blank(L10n::n("External"), |_| "https://docs.rs".into()))
|
||||
//! .with_item(dropdown::Item::divider())
|
||||
//! .with_item(dropdown::Item::header(L10n::n("User session")))
|
||||
//! .with_item(dropdown::Item::button(L10n::n("Sign out")));
|
||||
//! ```
|
||||
|
||||
mod props;
|
||||
pub use props::{AutoClose, Direction, MenuAlign, MenuPosition};
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
use crate::LOCALES_BOOTSIER;
|
||||
|
||||
/// Componente para crear un **menú desplegable**.
|
||||
/// Componente para crear un **menú desplegable** ([`dropdown`]).
|
||||
///
|
||||
/// Renderiza un botón (único o desdoblado, ver [`with_button_split()`](Self::with_button_split))
|
||||
/// para mostrar un menú desplegable de elementos [`dropdown::Item`], que se muestra/oculta según la
|
||||
/// interacción del usuario. Admite variaciones de tamaño/color del botón, también dirección de
|
||||
/// apertura, alineación o política de cierre.
|
||||
/// para mostrar un menú desplegable de elementos [`dropdown::Item`], que se muestra u oculta según
|
||||
/// la interacción del usuario. Admite variaciones para el tamaño y el color del botón, también para
|
||||
/// la dirección de apertura, alineación o política de cierre.
|
||||
///
|
||||
/// Si no tiene título (ver [`with_title()`](Self::with_title)) se muestra únicamente la lista de
|
||||
/// elementos sin ningún botón para interactuar.
|
||||
|
|
@ -17,8 +17,25 @@ use crate::LOCALES_BOOTSIER;
|
|||
/// cuenta **el título** (si no existe le asigna uno por defecto) y **la lista de elementos**; el
|
||||
/// resto de propiedades no afectarán a su representación en [`Nav`].
|
||||
///
|
||||
/// Ver ejemplo en el módulo [`dropdown`].
|
||||
/// Si no contiene elementos, el componente **no se renderiza**.
|
||||
///
|
||||
/// # Ejemplo
|
||||
///
|
||||
/// ```rust
|
||||
/// use pagetop::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// let dd = Dropdown::new()
|
||||
/// .with_title(L10n::n("Menu"))
|
||||
/// .with_button_color(ButtonColor::Background(Color::Secondary))
|
||||
/// .with_auto_close(dropdown::AutoClose::ClickableInside)
|
||||
/// .with_direction(dropdown::Direction::Dropend)
|
||||
/// .with_item(dropdown::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
/// .with_item(dropdown::Item::link_blank(L10n::n("External"), |_| "https://docs.rs".into()))
|
||||
/// .with_item(dropdown::Item::divider())
|
||||
/// .with_item(dropdown::Item::header(L10n::n("User session")))
|
||||
/// .with_item(dropdown::Item::button(L10n::n("Sign out")));
|
||||
/// ```
|
||||
#[derive(AutoDefault, Clone, Debug, Getters)]
|
||||
pub struct Dropdown {
|
||||
#[getters(skip)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
|
||||
// **< AutoClose >**********************************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -1,36 +1,4 @@
|
|||
//! Definiciones para crear formularios ([`Form`]).
|
||||
//!
|
||||
//! # Ejemplo
|
||||
//!
|
||||
//! ```rust
|
||||
//! use pagetop::prelude::*;
|
||||
//! use pagetop_bootsier::prelude::*;
|
||||
//!
|
||||
//! let form_login = Form::new()
|
||||
//! .with_id("login")
|
||||
//! .with_action("/login")
|
||||
//! .with_child(
|
||||
//! form::input::Field::email()
|
||||
//! .with_name("email")
|
||||
//! .with_label(L10n::n("Email"))
|
||||
//! .with_required(true),
|
||||
//! )
|
||||
//! .with_child(
|
||||
//! form::input::Field::password()
|
||||
//! .with_name("password")
|
||||
//! .with_label(L10n::n("Password"))
|
||||
//! .with_required(true),
|
||||
//! )
|
||||
//! .with_child(
|
||||
//! form::Checkbox::check()
|
||||
//! .with_name("remember")
|
||||
//! .with_label(L10n::n("Remember me")),
|
||||
//! )
|
||||
//! .with_child(
|
||||
//! Button::submit(L10n::n("Sign in"))
|
||||
//! .with_color(ButtonColor::Background(Color::Primary)),
|
||||
//! );
|
||||
//! ```
|
||||
|
||||
mod props;
|
||||
pub use props::{Autocomplete, AutofillField, CheckboxKind, Method};
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use pagetop::prelude::*;
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let item = form::check::Item::new("apple", L10n::n("Apple")).with_checked(true);
|
||||
/// ```
|
||||
#[derive(AutoDefault, Clone, Debug, Getters)]
|
||||
|
|
@ -82,7 +82,7 @@ impl Item {
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let interests = form::check::Field::new()
|
||||
/// .with_name("interests")
|
||||
/// .with_label(L10n::n("Areas of interest"))
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use crate::LOCALES_BOOTSIER;
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let accept_terms = form::Checkbox::check() // También sirve new() o default().
|
||||
/// .with_name("terms_accepted")
|
||||
/// .with_label(L10n::n("I accept the terms and conditions"))
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@ use pagetop::prelude::*;
|
|||
|
||||
use crate::theme::form;
|
||||
|
||||
/// Componente para crear un **formulario**.
|
||||
/// Componente para crear un **formulario** ([`form`]).
|
||||
///
|
||||
/// Este componente renderiza un `<form>` estándar con soporte para los atributos más habituales:
|
||||
/// Este componente renderiza un formulario estándar con soporte para los atributos más habituales:
|
||||
///
|
||||
/// - `id`: identificador opcional del formulario.
|
||||
/// - `classes`: clases CSS adicionales (p. ej. utilidades CSS).
|
||||
|
|
@ -17,13 +17,33 @@ use crate::theme::form;
|
|||
/// # Ejemplo
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// let search = Form::new()
|
||||
/// .with_id("search")
|
||||
/// .with_action("/search")
|
||||
/// .with_method(form::Method::Get)
|
||||
/// .with_child(form::input::Field::search().with_name("q"));
|
||||
/// use pagetop::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// let form_login = Form::new()
|
||||
/// .with_id("login")
|
||||
/// .with_action("/login")
|
||||
/// .with_child(
|
||||
/// form::input::Field::email()
|
||||
/// .with_name("email")
|
||||
/// .with_label(L10n::n("Email"))
|
||||
/// .with_required(true),
|
||||
/// )
|
||||
/// .with_child(
|
||||
/// form::input::Field::password()
|
||||
/// .with_name("password")
|
||||
/// .with_label(L10n::n("Password"))
|
||||
/// .with_required(true),
|
||||
/// )
|
||||
/// .with_child(
|
||||
/// form::Checkbox::check()
|
||||
/// .with_name("remember")
|
||||
/// .with_label(L10n::n("Remember me")),
|
||||
/// )
|
||||
/// .with_child(
|
||||
/// Button::submit(L10n::n("Sign in"))
|
||||
/// .with_color(ButtonColor::Background(Color::Primary)),
|
||||
/// );
|
||||
/// ```
|
||||
#[derive(AutoDefault, Clone, Debug, Getters)]
|
||||
pub struct Form {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ use pagetop::prelude::*;
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let personal_data = form::Fieldset::new()
|
||||
/// .with_legend(L10n::n("Personal data"))
|
||||
/// .with_description(L10n::n("Enter your full name and contact email."))
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ use pagetop::prelude::*;
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let token = form::Hidden::new()
|
||||
/// .with_name("csrf_token")
|
||||
/// .with_value("a1b2c3d4e5");
|
||||
|
|
|
|||
|
|
@ -106,7 +106,7 @@ impl fmt::Display for Mode {
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let email = form::input::Field::email()
|
||||
/// .with_name("email")
|
||||
/// .with_label(L10n::n("Email address"))
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ pub enum CheckboxKind {
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// // Correo electrónico con sugerencia semántica del navegador.
|
||||
/// let ac = form::Autocomplete::email();
|
||||
///
|
||||
|
|
@ -244,7 +244,7 @@ impl fmt::Display for Autocomplete {
|
|||
/// # Ejemplo
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let ac = form::Autocomplete::token(form::AutofillField::Username);
|
||||
/// let ac = form::Autocomplete::shipping(form::AutofillField::StreetAddress);
|
||||
/// let ac = form::Autocomplete::section("job", form::AutofillField::Email);
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use crate::LOCALES_BOOTSIER;
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let item = form::radio::Item::new("monthly", L10n::n("Monthly")).with_checked(true);
|
||||
/// ```
|
||||
#[derive(AutoDefault, Clone, Debug, Getters)]
|
||||
|
|
@ -76,7 +76,7 @@ impl Item {
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let plan = form::radio::Field::new()
|
||||
/// .with_name("plan")
|
||||
/// .with_label(L10n::n("Subscription plan"))
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use pagetop::prelude::*;
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let volume = form::Range::new()
|
||||
/// .with_name("volume")
|
||||
/// .with_label(L10n::n("Volume"))
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ use crate::LOCALES_BOOTSIER;
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let item = form::select::Item::new("es", L10n::n("Spanish")).with_selected(true);
|
||||
/// ```
|
||||
#[derive(AutoDefault, Clone, Debug, Getters)]
|
||||
|
|
@ -76,7 +76,7 @@ impl Item {
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let group = form::select::Group::new(L10n::n("Europe"))
|
||||
/// .with_item(form::select::Item::new("es", L10n::n("Spanish")))
|
||||
/// .with_item(form::select::Item::new("fr", L10n::n("French")));
|
||||
|
|
@ -149,7 +149,7 @@ pub enum Entry {
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let idioma = form::select::Field::new()
|
||||
/// .with_name("language")
|
||||
/// .with_label(L10n::n("Language"))
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use crate::LOCALES_BOOTSIER;
|
|||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let descripcion = form::Textarea::new()
|
||||
/// .with_name("description")
|
||||
/// .with_label(L10n::n("Description"))
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
|
||||
const DEFAULT_VIEWBOX: &str = "0 0 16 16";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,14 +1,16 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
|
||||
/// Componente para renderizar una **imagen**.
|
||||
/// Componente para renderizar una **imagen** ([`image`]).
|
||||
///
|
||||
/// - Ajusta su disposición según el origen definido en [`image::Source`].
|
||||
/// - Permite configurar **dimensiones** ([`with_size()`](Self::with_size)), **borde**
|
||||
/// A una imagen se le puede:
|
||||
///
|
||||
/// - Establecer su contenido a partir del origen definido en [`image::Source`].
|
||||
/// - Configurar sus **dimensiones** ([`with_size()`](Self::with_size)), **borde**
|
||||
/// ([`classes::Border`](crate::theme::classes::Border)) y **redondeo de esquinas**
|
||||
/// ([`classes::Rounded`](crate::theme::classes::Rounded)).
|
||||
/// - Resuelve el texto alternativo `alt` con **localización** mediante [`L10n`].
|
||||
/// - Aplicar el texto alternativo `alt` con **localización** mediante [`L10n`].
|
||||
#[derive(AutoDefault, Clone, Debug, Getters)]
|
||||
pub struct Image {
|
||||
#[getters(skip)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Definiciones para crear menús [`Nav`] o alguna de sus variantes de presentación.
|
||||
//! Definiciones para crear menús ([`Nav`]).
|
||||
//!
|
||||
//! Cada [`nav::Item`](crate::theme::nav::Item) representa un elemento individual del menú [`Nav`],
|
||||
//! con distintos comportamientos según su finalidad, como enlaces de navegación o menús
|
||||
|
|
@ -6,26 +6,6 @@
|
|||
//!
|
||||
//! 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).
|
||||
//!
|
||||
//! # Ejemplo
|
||||
//!
|
||||
//! ```rust
|
||||
//! # use pagetop::prelude::*;
|
||||
//! # use pagetop_bootsier::prelude::*;
|
||||
//! let nav = Nav::tabs()
|
||||
//! .with_layout(nav::Layout::End)
|
||||
//! .with_item(nav::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
//! .with_item(nav::Item::link_blank(L10n::n("External"), |_| "https://docs.rs".into()))
|
||||
//! .with_item(nav::Item::dropdown(
|
||||
//! Dropdown::new()
|
||||
//! .with_title(L10n::n("Options"))
|
||||
//! .with_item(ChildOp::AddMany(vec![
|
||||
//! dropdown::Item::link(L10n::n("Action"), |_| "/action".into()).into(),
|
||||
//! dropdown::Item::link(L10n::n("Another"), |_| "/another".into()).into(),
|
||||
//! ])),
|
||||
//! ))
|
||||
//! .with_item(nav::Item::link_disabled(L10n::n("Disabled"), |_| "#".into()));
|
||||
//! ```
|
||||
|
||||
mod props;
|
||||
pub use props::{Kind, Layout};
|
||||
|
|
|
|||
|
|
@ -1,15 +1,35 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
|
||||
/// Componente para crear un **menú** o alguna de sus variantes ([`nav::Kind`]).
|
||||
/// Componente para crear un **menú** ([`nav`]).
|
||||
///
|
||||
/// Presenta un menú con una lista de elementos usando una vista básica, o alguna de sus variantes
|
||||
/// como *pestañas* (`Tabs`), *botones* (`Pills`) o *subrayado* (`Underline`). También permite
|
||||
/// controlar su distribución y orientación ([`nav::Layout`](crate::theme::nav::Layout)).
|
||||
/// ([`nav::Kind`]) como *pestañas* (`Tabs`), *botones* (`Pills`) o *subrayado* (`Underline`).
|
||||
/// También permite controlar su distribución y orientación ([`nav::Layout`](crate::theme::nav::Layout)).
|
||||
///
|
||||
/// Ver ejemplo en el módulo [`nav`].
|
||||
/// Si no contiene elementos, el componente **no se renderiza**.
|
||||
///
|
||||
/// # Ejemplo
|
||||
///
|
||||
/// ```rust
|
||||
/// use pagetop::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// let nav = Nav::tabs()
|
||||
/// .with_layout(nav::Layout::End)
|
||||
/// .with_item(nav::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
/// .with_item(nav::Item::link_blank(L10n::n("External"), |_| "https://docs.rs".into()))
|
||||
/// .with_item(nav::Item::dropdown(
|
||||
/// Dropdown::new()
|
||||
/// .with_title(L10n::n("Options"))
|
||||
/// .with_item(ChildOp::AddMany(vec![
|
||||
/// dropdown::Item::link(L10n::n("Action"), |_| "/action".into()).into(),
|
||||
/// dropdown::Item::link(L10n::n("Another"), |_| "/another".into()).into(),
|
||||
/// ])),
|
||||
/// ))
|
||||
/// .with_item(nav::Item::link_disabled(L10n::n("Disabled"), |_| "#".into()));
|
||||
/// ```
|
||||
#[derive(AutoDefault, Clone, Debug, Getters)]
|
||||
pub struct Nav {
|
||||
#[getters(skip)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
use crate::LOCALES_BOOTSIER;
|
||||
|
||||
// **< ItemKind >***********************************************************************************
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
//! Definiciones para crear barras de navegación [`Navbar`].
|
||||
//! Definiciones para crear barras de navegación ([`Navbar`]).
|
||||
//!
|
||||
//! Cada [`navbar::Item`](crate::theme::navbar::Item) representa un elemento individual de la barra
|
||||
//! de navegación [`Navbar`], con distintos comportamientos según su finalidad, como menús
|
||||
|
|
@ -6,126 +6,6 @@
|
|||
//!
|
||||
//! También puede mostrar una marca de identidad ([`navbar::Brand`](crate::theme::navbar::Brand))
|
||||
//! que identifique la compañía, producto o nombre del proyecto asociado a la solución web.
|
||||
//!
|
||||
//! # Ejemplos
|
||||
//!
|
||||
//! Barra **simple**, sólo con un menú horizontal:
|
||||
//!
|
||||
//! ```rust
|
||||
//! # use pagetop::prelude::*;
|
||||
//! # use pagetop_bootsier::prelude::*;
|
||||
//! let navbar = Navbar::simple()
|
||||
//! .with_item(navbar::Item::nav(
|
||||
//! Nav::new()
|
||||
//! .with_item(nav::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
//! .with_item(nav::Item::link(L10n::n("About"), |_| "/about".into()))
|
||||
//! .with_item(nav::Item::link(L10n::n("Contact"), |_| "/contact".into()))
|
||||
//! ));
|
||||
//! ```
|
||||
//!
|
||||
//! Barra **colapsable**, con botón de despliegue y contenido en el desplegable cuando colapsa:
|
||||
//!
|
||||
//! ```rust
|
||||
//! # use pagetop::prelude::*;
|
||||
//! # use pagetop_bootsier::prelude::*;
|
||||
//! let navbar = Navbar::simple_toggle()
|
||||
//! .with_expand(BreakPoint::MD)
|
||||
//! .with_item(navbar::Item::nav(
|
||||
//! Nav::new()
|
||||
//! .with_item(nav::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
//! .with_item(nav::Item::link_blank(L10n::n("Docs"), |_| "https://docs.rs".into()))
|
||||
//! .with_item(nav::Item::link(L10n::n("Support"), |_| "/support".into()))
|
||||
//! ));
|
||||
//! ```
|
||||
//!
|
||||
//! Barra con **marca de identidad a la izquierda** y menú a la derecha, típica de una cabecera:
|
||||
//!
|
||||
//! ```rust
|
||||
//! # use pagetop::prelude::*;
|
||||
//! # use pagetop_bootsier::prelude::*;
|
||||
//! let brand = navbar::Brand::new()
|
||||
//! .with_title(L10n::n("PageTop"))
|
||||
//! .with_route(Some(|cx| cx.route("/")));
|
||||
//!
|
||||
//! let navbar = Navbar::brand_left(brand)
|
||||
//! .with_item(navbar::Item::nav(
|
||||
//! Nav::new()
|
||||
//! .with_item(nav::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
//! .with_item(nav::Item::dropdown(
|
||||
//! Dropdown::new()
|
||||
//! .with_title(L10n::n("Tools"))
|
||||
//! .with_item(dropdown::Item::link(
|
||||
//! L10n::n("Generator"), |_| "/tools/gen".into())
|
||||
//! )
|
||||
//! .with_item(dropdown::Item::link(
|
||||
//! L10n::n("Reports"), |_| "/tools/reports".into())
|
||||
//! )
|
||||
//! ))
|
||||
//! .with_item(nav::Item::link_disabled(L10n::n("Disabled"), |_| "#".into()))
|
||||
//! ));
|
||||
//! ```
|
||||
//!
|
||||
//! Barra con **botón de despliegue a la izquierda** y **marca de identidad a la derecha**:
|
||||
//!
|
||||
//! ```rust
|
||||
//! # use pagetop::prelude::*;
|
||||
//! # use pagetop_bootsier::prelude::*;
|
||||
//! let brand = navbar::Brand::new()
|
||||
//! .with_title(L10n::n("Intranet"))
|
||||
//! .with_route(Some(|cx| cx.route("/")));
|
||||
//!
|
||||
//! let navbar = Navbar::brand_right(brand)
|
||||
//! .with_expand(BreakPoint::LG)
|
||||
//! .with_item(navbar::Item::nav(
|
||||
//! Nav::pills()
|
||||
//! .with_item(nav::Item::link(L10n::n("Dashboard"), |_| "/dashboard".into()))
|
||||
//! .with_item(nav::Item::link(L10n::n("Users"), |_| "/users".into()))
|
||||
//! ));
|
||||
//! ```
|
||||
//!
|
||||
//! Barra con el **contenido en un *offcanvas***, ideal para dispositivos móviles o menús largos:
|
||||
//!
|
||||
//! ```rust
|
||||
//! # use pagetop::prelude::*;
|
||||
//! # use pagetop_bootsier::prelude::*;
|
||||
//! let oc = Offcanvas::new()
|
||||
//! .with_id("main_offcanvas")
|
||||
//! .with_title(L10n::n("Main menu"))
|
||||
//! .with_placement(offcanvas::Placement::Start)
|
||||
//! .with_backdrop(offcanvas::Backdrop::Enabled);
|
||||
//!
|
||||
//! let navbar = Navbar::offcanvas(oc)
|
||||
//! .with_item(navbar::Item::nav(
|
||||
//! Nav::new()
|
||||
//! .with_item(nav::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
//! .with_item(nav::Item::link(L10n::n("Profile"), |_| "/profile".into()))
|
||||
//! .with_item(nav::Item::dropdown(
|
||||
//! Dropdown::new()
|
||||
//! .with_title(L10n::n("More"))
|
||||
//! .with_item(dropdown::Item::link(L10n::n("Settings"), |_| "/settings".into()))
|
||||
//! .with_item(dropdown::Item::link(L10n::n("Help"), |_| "/help".into()))
|
||||
//! ))
|
||||
//! ));
|
||||
//! ```
|
||||
//!
|
||||
//! Barra **fija arriba**:
|
||||
//!
|
||||
//! ```rust
|
||||
//! # use pagetop::prelude::*;
|
||||
//! # use pagetop_bootsier::prelude::*;
|
||||
//! let brand = navbar::Brand::new()
|
||||
//! .with_title(L10n::n("Main App"))
|
||||
//! .with_route(Some(|cx| cx.route("/")));
|
||||
//!
|
||||
//! let navbar = Navbar::brand_left(brand)
|
||||
//! .with_position(navbar::Position::FixedTop)
|
||||
//! .with_item(navbar::Item::nav(
|
||||
//! Nav::new()
|
||||
//! .with_item(nav::Item::link(L10n::n("Dashboard"), |_| "/".into()))
|
||||
//! .with_item(nav::Item::link(L10n::n("Donors"), |_| "/donors".into()))
|
||||
//! .with_item(nav::Item::link(L10n::n("Stock"), |_| "/stock".into()))
|
||||
//! ));
|
||||
//! ```
|
||||
|
||||
mod props;
|
||||
pub use props::{Layout, Position};
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
|
||||
/// Marca de identidad para mostrar en una barra de navegación [`Navbar`].
|
||||
///
|
||||
|
|
|
|||
|
|
@ -1,19 +1,139 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
use crate::LOCALES_BOOTSIER;
|
||||
|
||||
const TOGGLE_COLLAPSE: &str = "collapse";
|
||||
const TOGGLE_OFFCANVAS: &str = "offcanvas";
|
||||
|
||||
/// Componente para crear una **barra de navegación**.
|
||||
/// Componente para crear una **barra de navegación** ([`navbar`]).
|
||||
///
|
||||
/// Permite mostrar enlaces, menús y una marca de identidad en distintas disposiciones (simples, con
|
||||
/// botón de despliegue o dentro de un [`offcanvas`]), controladas por [`navbar::Layout`]. También
|
||||
/// puede fijarse en la parte superior o inferior del documento mediante [`navbar::Position`].
|
||||
///
|
||||
/// Ver ejemplos en el módulo [`navbar`].
|
||||
/// Si no contiene elementos, el componente **no se renderiza**.
|
||||
///
|
||||
/// # Ejemplos
|
||||
///
|
||||
/// Barra **simple**, sólo con un menú horizontal:
|
||||
///
|
||||
/// ```rust
|
||||
/// use pagetop::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// let navbar = Navbar::simple()
|
||||
/// .with_item(navbar::Item::nav(
|
||||
/// Nav::new()
|
||||
/// .with_item(nav::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
/// .with_item(nav::Item::link(L10n::n("About"), |_| "/about".into()))
|
||||
/// .with_item(nav::Item::link(L10n::n("Contact"), |_| "/contact".into()))
|
||||
/// ));
|
||||
/// ```
|
||||
///
|
||||
/// Barra **colapsable**, con botón de despliegue y contenido en el desplegable cuando colapsa:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let navbar = Navbar::simple_toggle()
|
||||
/// .with_expand(BreakPoint::MD)
|
||||
/// .with_item(navbar::Item::nav(
|
||||
/// Nav::new()
|
||||
/// .with_item(nav::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
/// .with_item(nav::Item::link_blank(L10n::n("Docs"), |_| "https://docs.rs".into()))
|
||||
/// .with_item(nav::Item::link(L10n::n("Support"), |_| "/support".into()))
|
||||
/// ));
|
||||
/// ```
|
||||
///
|
||||
/// Barra con **marca de identidad a la izquierda** y menú a la derecha, típica de una cabecera:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let brand = navbar::Brand::new()
|
||||
/// .with_title(L10n::n("PageTop"))
|
||||
/// .with_route(Some(|cx| cx.route("/")));
|
||||
///
|
||||
/// let navbar = Navbar::brand_left(brand)
|
||||
/// .with_item(navbar::Item::nav(
|
||||
/// Nav::new()
|
||||
/// .with_item(nav::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
/// .with_item(nav::Item::dropdown(
|
||||
/// Dropdown::new()
|
||||
/// .with_title(L10n::n("Tools"))
|
||||
/// .with_item(dropdown::Item::link(
|
||||
/// L10n::n("Generator"), |_| "/tools/gen".into())
|
||||
/// )
|
||||
/// .with_item(dropdown::Item::link(
|
||||
/// L10n::n("Reports"), |_| "/tools/reports".into())
|
||||
/// )
|
||||
/// ))
|
||||
/// .with_item(nav::Item::link_disabled(L10n::n("Disabled"), |_| "#".into()))
|
||||
/// ));
|
||||
/// ```
|
||||
///
|
||||
/// Barra con **botón de despliegue a la izquierda** y **marca de identidad a la derecha**:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let brand = navbar::Brand::new()
|
||||
/// .with_title(L10n::n("Intranet"))
|
||||
/// .with_route(Some(|cx| cx.route("/")));
|
||||
///
|
||||
/// let navbar = Navbar::brand_right(brand)
|
||||
/// .with_expand(BreakPoint::LG)
|
||||
/// .with_item(navbar::Item::nav(
|
||||
/// Nav::pills()
|
||||
/// .with_item(nav::Item::link(L10n::n("Dashboard"), |_| "/dashboard".into()))
|
||||
/// .with_item(nav::Item::link(L10n::n("Users"), |_| "/users".into()))
|
||||
/// ));
|
||||
/// ```
|
||||
///
|
||||
/// Barra con el **contenido en un *offcanvas***, ideal para dispositivos móviles o menús largos:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let oc = Offcanvas::new()
|
||||
/// .with_id("main_offcanvas")
|
||||
/// .with_title(L10n::n("Main menu"))
|
||||
/// .with_placement(offcanvas::Placement::Start)
|
||||
/// .with_backdrop(offcanvas::Backdrop::Enabled);
|
||||
///
|
||||
/// let navbar = Navbar::offcanvas(oc)
|
||||
/// .with_item(navbar::Item::nav(
|
||||
/// Nav::new()
|
||||
/// .with_item(nav::Item::link(L10n::n("Home"), |_| "/".into()))
|
||||
/// .with_item(nav::Item::link(L10n::n("Profile"), |_| "/profile".into()))
|
||||
/// .with_item(nav::Item::dropdown(
|
||||
/// Dropdown::new()
|
||||
/// .with_title(L10n::n("More"))
|
||||
/// .with_item(dropdown::Item::link(L10n::n("Settings"), |_| "/settings".into()))
|
||||
/// .with_item(dropdown::Item::link(L10n::n("Help"), |_| "/help".into()))
|
||||
/// ))
|
||||
/// ));
|
||||
/// ```
|
||||
///
|
||||
/// Barra **fija arriba**:
|
||||
///
|
||||
/// ```rust
|
||||
/// # use pagetop::prelude::*;
|
||||
/// # use pagetop_bootsier::theme::*;
|
||||
/// let brand = navbar::Brand::new()
|
||||
/// .with_title(L10n::n("Main App"))
|
||||
/// .with_route(Some(|cx| cx.route("/")));
|
||||
///
|
||||
/// let navbar = Navbar::brand_left(brand)
|
||||
/// .with_position(navbar::Position::FixedTop)
|
||||
/// .with_item(navbar::Item::nav(
|
||||
/// Nav::new()
|
||||
/// .with_item(nav::Item::link(L10n::n("Dashboard"), |_| "/".into()))
|
||||
/// .with_item(nav::Item::link(L10n::n("Donors"), |_| "/donors".into()))
|
||||
/// .with_item(nav::Item::link(L10n::n("Stock"), |_| "/stock".into()))
|
||||
/// ));
|
||||
/// ```
|
||||
#[derive(AutoDefault, Clone, Debug, Getters)]
|
||||
pub struct Navbar {
|
||||
#[getters(skip)]
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
|
||||
/// Elementos que puede contener una barra de navegación [`Navbar`](crate::theme::Navbar).
|
||||
///
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
|
||||
// **< Layout >*************************************************************************************
|
||||
|
||||
|
|
|
|||
|
|
@ -1,24 +1,4 @@
|
|||
//! Definiciones para crear paneles laterales deslizantes [`Offcanvas`].
|
||||
//!
|
||||
//! # 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)
|
||||
//! .with_child(Dropdown::new()
|
||||
//! .with_title(L10n::n("Menu"))
|
||||
//! .with_item(dropdown::Item::label(L10n::n("Label")))
|
||||
//! .with_item(dropdown::Item::link_blank(L10n::n("Docs"), |_| "https://docs.rs".into()))
|
||||
//! .with_item(dropdown::Item::link(L10n::n("Sign out"), |_| "/signout".into()))
|
||||
//! );
|
||||
//! ```
|
||||
//! Definiciones para crear paneles laterales deslizantes ([`Offcanvas`]).
|
||||
|
||||
mod props;
|
||||
pub use props::{Backdrop, BodyScroll, Placement, Visibility};
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
use pagetop::prelude::*;
|
||||
|
||||
use crate::prelude::*;
|
||||
use crate::theme::*;
|
||||
use crate::LOCALES_BOOTSIER;
|
||||
|
||||
/// Componente para crear un **panel lateral deslizante** con contenidos adicionales.
|
||||
/// Componente para crear un **panel lateral deslizante** ([`offcanvas`]).
|
||||
///
|
||||
/// Útil para navegación, filtros, formularios o menús contextuales. Incluye las siguientes
|
||||
/// características principales:
|
||||
|
|
@ -19,8 +19,28 @@ use crate::LOCALES_BOOTSIER;
|
|||
/// - Asocia título y controles de accesibilidad a un identificador único y expone atributos
|
||||
/// adecuados para lectores de pantalla y navegación por teclado.
|
||||
///
|
||||
/// Ver ejemplo en el módulo [`offcanvas`].
|
||||
/// Si no contiene elementos, el componente **no se renderiza**.
|
||||
///
|
||||
/// # Ejemplo
|
||||
///
|
||||
/// ```rust
|
||||
/// use pagetop::prelude::*;
|
||||
/// use pagetop_bootsier::theme::*;
|
||||
///
|
||||
/// 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)
|
||||
/// .with_child(Dropdown::new()
|
||||
/// .with_title(L10n::n("Menu"))
|
||||
/// .with_item(dropdown::Item::label(L10n::n("Label")))
|
||||
/// .with_item(dropdown::Item::link_blank(L10n::n("Docs"), |_| "https://docs.rs".into()))
|
||||
/// .with_item(dropdown::Item::link(L10n::n("Sign out"), |_| "/signout".into()))
|
||||
/// );
|
||||
/// ```
|
||||
#[derive(AutoDefault, Clone, Debug, Getters)]
|
||||
pub struct Offcanvas {
|
||||
#[getters(skip)]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue