🎨 [theme] Mejora gestión de regiones en páginas
This commit is contained in:
parent
512a406ede
commit
75eec8bebc
7 changed files with 174 additions and 49 deletions
|
@ -1,5 +1,5 @@
|
|||
use crate::core::component::{Child, ChildOp, Children};
|
||||
use crate::core::theme::{ThemeRef, CONTENT_REGION_NAME};
|
||||
use crate::core::theme::ThemeRef;
|
||||
use crate::{builder_fn, AutoDefault, UniqueId};
|
||||
|
||||
use parking_lot::RwLock;
|
||||
|
@ -7,15 +7,71 @@ use parking_lot::RwLock;
|
|||
use std::collections::HashMap;
|
||||
use std::sync::LazyLock;
|
||||
|
||||
// Regiones globales con componentes para un tema dado.
|
||||
// Conjunto de regiones globales asociadas a un tema específico.
|
||||
static THEME_REGIONS: LazyLock<RwLock<HashMap<UniqueId, ChildrenInRegions>>> =
|
||||
LazyLock::new(|| RwLock::new(HashMap::new()));
|
||||
|
||||
// Regiones globales con componentes para cualquier tema.
|
||||
// Conjunto de regiones globales comunes a todos los temas.
|
||||
static COMMON_REGIONS: LazyLock<RwLock<ChildrenInRegions>> =
|
||||
LazyLock::new(|| RwLock::new(ChildrenInRegions::default()));
|
||||
|
||||
// Estructura interna para mantener los componentes de una región.
|
||||
/// Nombre de la región de contenido por defecto (`"content"`).
|
||||
pub const REGION_CONTENT: &str = "content";
|
||||
|
||||
/// Identificador de una región de página.
|
||||
///
|
||||
/// Incluye una **clave estática** ([`key()`](Self::key)) que identifica la región en el tema, y un
|
||||
/// **nombre normalizado** ([`name()`](Self::name)) en minúsculas para su uso en atributos HTML
|
||||
/// (p.ej., clases `region__{name}`).
|
||||
///
|
||||
/// Se utiliza para declarar las regiones que componen una página en un tema (ver
|
||||
/// [`declared_regions()`](crate::core::theme::Theme::declared_regions)).
|
||||
pub struct Region {
|
||||
key: &'static str,
|
||||
name: String,
|
||||
}
|
||||
|
||||
impl Default for Region {
|
||||
#[inline]
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
key: REGION_CONTENT,
|
||||
name: String::from(REGION_CONTENT),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Region {
|
||||
/// Declara una región a partir de su clave estática.
|
||||
///
|
||||
/// Genera además un nombre normalizado de la clave, eliminando espacios iniciales y finales,
|
||||
/// convirtiendo a minúsculas y sustituyendo los espacios intermedios por guiones (`-`).
|
||||
///
|
||||
/// Esta clave se usará para añadir componentes a la región; por ello se recomiendan nombres
|
||||
/// sencillos, limitando los caracteres a `[a-z0-9-]` (p.ej., `"sidebar"` o `"main-menu"`), cuyo
|
||||
/// nombre normalizado coincidirá con la clave.
|
||||
#[inline]
|
||||
pub fn declare(key: &'static str) -> Self {
|
||||
Self {
|
||||
key,
|
||||
name: key.trim().to_ascii_lowercase().replace(' ', "-"),
|
||||
}
|
||||
}
|
||||
|
||||
/// Devuelve la clave estática asignada a la región.
|
||||
#[inline]
|
||||
pub fn key(&self) -> &'static str {
|
||||
self.key
|
||||
}
|
||||
|
||||
/// Devuelve el nombre normalizado de la región (para atributos y búsquedas).
|
||||
#[inline]
|
||||
pub fn name(&self) -> &str {
|
||||
&self.name
|
||||
}
|
||||
}
|
||||
|
||||
// Contenedor interno de componentes agrupados por región.
|
||||
#[derive(AutoDefault)]
|
||||
pub struct ChildrenInRegions(HashMap<&'static str, Children>);
|
||||
|
||||
|
@ -48,25 +104,24 @@ impl ChildrenInRegions {
|
|||
}
|
||||
}
|
||||
|
||||
/// Permite añadir componentes a regiones globales o regiones de temas concretos.
|
||||
/// Punto de acceso para añadir componentes a regiones globales o específicas de un tema.
|
||||
///
|
||||
/// Dada una región, según la variante seleccionada, se le podrán añadir ([`add()`](Self::add))
|
||||
/// componentes que se mantendrán durante la ejecución de la aplicación.
|
||||
/// Según la variante, se pueden añadir componentes ([`add()`](Self::add)) que permanecerán
|
||||
/// disponibles durante toda la ejecución.
|
||||
///
|
||||
/// Estas estructuras de componentes se renderizarán automáticamente al procesar los documentos HTML
|
||||
/// que las usan, como las páginas de contenido ([`Page`](crate::response::page::Page)), por
|
||||
/// ejemplo.
|
||||
/// Estos componentes se renderizarán automáticamente al procesar los documentos HTML que incluyen
|
||||
/// estas regiones, como las páginas de contenido ([`Page`](crate::response::page::Page)).
|
||||
pub enum InRegion {
|
||||
/// Representa la región por defecto en la que se pueden añadir componentes.
|
||||
/// Región de contenido por defecto.
|
||||
Content,
|
||||
/// Representa la región con el nombre del argumento.
|
||||
/// Región identificada por el nombre proporcionado.
|
||||
Named(&'static str),
|
||||
/// Representa la región con el nombre y del tema especificado en los argumentos.
|
||||
/// Región identificada por un nombre y asociada a un tema concreto.
|
||||
OfTheme(&'static str, ThemeRef),
|
||||
}
|
||||
|
||||
impl InRegion {
|
||||
/// Permite añadir un componente en la región de la variante seleccionada.
|
||||
/// Añade un componente a la región indicada por la variante.
|
||||
///
|
||||
/// # Ejemplo
|
||||
///
|
||||
|
@ -88,7 +143,7 @@ impl InRegion {
|
|||
InRegion::Content => {
|
||||
COMMON_REGIONS
|
||||
.write()
|
||||
.alter_child_in_region(CONTENT_REGION_NAME, ChildOp::Add(child));
|
||||
.alter_child_in_region(REGION_CONTENT, ChildOp::Add(child));
|
||||
}
|
||||
InRegion::Named(name) => {
|
||||
COMMON_REGIONS
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue