♻️ (pagetop): Renombra Slot a Embed
This commit is contained in:
parent
d10d546418
commit
f1295c74df
8 changed files with 95 additions and 95 deletions
|
|
@ -28,9 +28,9 @@ pub enum ItemKind {
|
||||||
},
|
},
|
||||||
/// Contenido HTML arbitrario. El componente [`Html`] se renderiza tal cual como elemento del
|
/// Contenido HTML arbitrario. El componente [`Html`] se renderiza tal cual como elemento del
|
||||||
/// menú, sin añadir ningún comportamiento de navegación adicional.
|
/// menú, sin añadir ningún comportamiento de navegación adicional.
|
||||||
Html(Slot<Html>),
|
Html(Embed<Html>),
|
||||||
/// Elemento que despliega un menú [`Dropdown`].
|
/// Elemento que despliega un menú [`Dropdown`].
|
||||||
Dropdown(Slot<Dropdown>),
|
Dropdown(Embed<Dropdown>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ItemKind {
|
impl ItemKind {
|
||||||
|
|
@ -264,7 +264,7 @@ impl Item {
|
||||||
/// con las clases de navegación asociadas a [`Item`].
|
/// con las clases de navegación asociadas a [`Item`].
|
||||||
pub fn html(html: Html) -> Self {
|
pub fn html(html: Html) -> Self {
|
||||||
Self {
|
Self {
|
||||||
item_kind: ItemKind::Html(Slot::with(html)),
|
item_kind: ItemKind::Html(Embed::with(html)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -276,7 +276,7 @@ impl Item {
|
||||||
/// a su representación en [`Nav`].
|
/// a su representación en [`Nav`].
|
||||||
pub fn dropdown(menu: Dropdown) -> Self {
|
pub fn dropdown(menu: Dropdown) -> Self {
|
||||||
Self {
|
Self {
|
||||||
item_kind: ItemKind::Dropdown(Slot::with(menu)),
|
item_kind: ItemKind::Dropdown(Embed::with(menu)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ pub struct Brand {
|
||||||
#[getters(skip)]
|
#[getters(skip)]
|
||||||
id: AttrId,
|
id: AttrId,
|
||||||
/// Devuelve la imagen de marca (si la hay).
|
/// Devuelve la imagen de marca (si la hay).
|
||||||
image: Slot<Image>,
|
image: Embed<Image>,
|
||||||
/// Devuelve el título de la identidad de marca.
|
/// Devuelve el título de la identidad de marca.
|
||||||
#[default(_code = "L10n::n(&global::SETTINGS.app.name)")]
|
#[default(_code = "L10n::n(&global::SETTINGS.app.name)")]
|
||||||
title: L10n,
|
title: L10n,
|
||||||
|
|
|
||||||
|
|
@ -179,37 +179,37 @@ impl Navbar {
|
||||||
|
|
||||||
/// Crea una barra de navegación **con marca a la izquierda**, siempre visible.
|
/// Crea una barra de navegación **con marca a la izquierda**, siempre visible.
|
||||||
pub fn simple_brand_left(brand: navbar::Brand) -> Self {
|
pub fn simple_brand_left(brand: navbar::Brand) -> Self {
|
||||||
Self::default().with_layout(navbar::Layout::SimpleBrandLeft(Slot::with(brand)))
|
Self::default().with_layout(navbar::Layout::SimpleBrandLeft(Embed::with(brand)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Crea una barra de navegación con **marca a la izquierda** y **botón a la derecha**.
|
/// Crea una barra de navegación con **marca a la izquierda** y **botón a la derecha**.
|
||||||
pub fn brand_left(brand: navbar::Brand) -> Self {
|
pub fn brand_left(brand: navbar::Brand) -> Self {
|
||||||
Self::default().with_layout(navbar::Layout::BrandLeft(Slot::with(brand)))
|
Self::default().with_layout(navbar::Layout::BrandLeft(Embed::with(brand)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Crea una barra de navegación con **botón a la izquierda** y **marca a la derecha**.
|
/// Crea una barra de navegación con **botón a la izquierda** y **marca a la derecha**.
|
||||||
pub fn brand_right(brand: navbar::Brand) -> Self {
|
pub fn brand_right(brand: navbar::Brand) -> Self {
|
||||||
Self::default().with_layout(navbar::Layout::BrandRight(Slot::with(brand)))
|
Self::default().with_layout(navbar::Layout::BrandRight(Embed::with(brand)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Crea una barra de navegación cuyo contenido se muestra en un **offcanvas**.
|
/// Crea una barra de navegación cuyo contenido se muestra en un **offcanvas**.
|
||||||
pub fn offcanvas(oc: Offcanvas) -> Self {
|
pub fn offcanvas(oc: Offcanvas) -> Self {
|
||||||
Self::default().with_layout(navbar::Layout::Offcanvas(Slot::with(oc)))
|
Self::default().with_layout(navbar::Layout::Offcanvas(Embed::with(oc)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Crea una barra de navegación con **marca a la izquierda** y contenido en **offcanvas**.
|
/// Crea una barra de navegación con **marca a la izquierda** y contenido en **offcanvas**.
|
||||||
pub fn offcanvas_brand_left(brand: navbar::Brand, oc: Offcanvas) -> Self {
|
pub fn offcanvas_brand_left(brand: navbar::Brand, oc: Offcanvas) -> Self {
|
||||||
Self::default().with_layout(navbar::Layout::OffcanvasBrandLeft(
|
Self::default().with_layout(navbar::Layout::OffcanvasBrandLeft(
|
||||||
Slot::with(brand),
|
Embed::with(brand),
|
||||||
Slot::with(oc),
|
Embed::with(oc),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Crea una barra de navegación con **marca a la derecha** y contenido en **offcanvas**.
|
/// Crea una barra de navegación con **marca a la derecha** y contenido en **offcanvas**.
|
||||||
pub fn offcanvas_brand_right(brand: navbar::Brand, oc: Offcanvas) -> Self {
|
pub fn offcanvas_brand_right(brand: navbar::Brand, oc: Offcanvas) -> Self {
|
||||||
Self::default().with_layout(navbar::Layout::OffcanvasBrandRight(
|
Self::default().with_layout(navbar::Layout::OffcanvasBrandRight(
|
||||||
Slot::with(brand),
|
Embed::with(brand),
|
||||||
Slot::with(oc),
|
Embed::with(oc),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@ pub enum Item {
|
||||||
/// Útil cuando el [`navbar::Layout`] no incluye marca, y se quiere incluir dentro del área
|
/// Útil cuando el [`navbar::Layout`] no incluye marca, y se quiere incluir dentro del área
|
||||||
/// colapsable/*offcanvas*. Si el *layout* ya muestra una marca, esta variante no la sustituye,
|
/// colapsable/*offcanvas*. Si el *layout* ya muestra una marca, esta variante no la sustituye,
|
||||||
/// sólo añade otra dentro del bloque de contenidos.
|
/// sólo añade otra dentro del bloque de contenidos.
|
||||||
Brand(Slot<navbar::Brand>),
|
Brand(Embed<navbar::Brand>),
|
||||||
/// Representa un menú de navegación [`Nav`](crate::theme::Nav).
|
/// Representa un menú de navegación [`Nav`](crate::theme::Nav).
|
||||||
Nav(Slot<Nav>),
|
Nav(Embed<Nav>),
|
||||||
/// Representa un *texto localizado* libre.
|
/// Representa un *texto localizado* libre.
|
||||||
Text(L10n),
|
Text(L10n),
|
||||||
}
|
}
|
||||||
|
|
@ -80,12 +80,12 @@ impl Item {
|
||||||
/// Pensado para barras colapsables u offcanvas donde se quiere que la marca aparezca en la zona
|
/// Pensado para barras colapsables u offcanvas donde se quiere que la marca aparezca en la zona
|
||||||
/// desplegable.
|
/// desplegable.
|
||||||
pub fn brand(brand: navbar::Brand) -> Self {
|
pub fn brand(brand: navbar::Brand) -> Self {
|
||||||
Self::Brand(Slot::with(brand))
|
Self::Brand(Embed::with(brand))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Crea un elemento de tipo [`Nav`] para añadir al contenido de [`Navbar`].
|
/// Crea un elemento de tipo [`Nav`] para añadir al contenido de [`Navbar`].
|
||||||
pub fn nav(item: Nav) -> Self {
|
pub fn nav(item: Nav) -> Self {
|
||||||
Self::Nav(Slot::with(item))
|
Self::Nav(Embed::with(item))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Crea un elemento con un *texto localizado*, mostrado sin interacción.
|
/// Crea un elemento con un *texto localizado*, mostrado sin interacción.
|
||||||
|
|
|
||||||
|
|
@ -19,24 +19,24 @@ pub enum Layout {
|
||||||
/// Barra simple, con marca de identidad a la izquierda y sin botón de despliegue.
|
/// Barra simple, con marca de identidad a la izquierda y sin botón de despliegue.
|
||||||
///
|
///
|
||||||
/// La barra de navegación no se colapsa.
|
/// La barra de navegación no se colapsa.
|
||||||
SimpleBrandLeft(Slot<navbar::Brand>),
|
SimpleBrandLeft(Embed<navbar::Brand>),
|
||||||
|
|
||||||
/// Barra con marca de identidad a la izquierda y botón de despliegue a la derecha.
|
/// Barra con marca de identidad a la izquierda y botón de despliegue a la derecha.
|
||||||
BrandLeft(Slot<navbar::Brand>),
|
BrandLeft(Embed<navbar::Brand>),
|
||||||
|
|
||||||
/// Barra con botón de despliegue a la izquierda y marca de identidad a la derecha.
|
/// Barra con botón de despliegue a la izquierda y marca de identidad a la derecha.
|
||||||
BrandRight(Slot<navbar::Brand>),
|
BrandRight(Embed<navbar::Brand>),
|
||||||
|
|
||||||
/// Contenido en [`Offcanvas`], con botón de despliegue a la izquierda y sin marca de identidad.
|
/// Contenido en [`Offcanvas`], con botón de despliegue a la izquierda y sin marca de identidad.
|
||||||
Offcanvas(Slot<Offcanvas>),
|
Offcanvas(Embed<Offcanvas>),
|
||||||
|
|
||||||
/// Contenido en [`Offcanvas`], con marca de identidad a la izquierda y botón de despliegue a la
|
/// Contenido en [`Offcanvas`], con marca de identidad a la izquierda y botón de despliegue a la
|
||||||
/// derecha.
|
/// derecha.
|
||||||
OffcanvasBrandLeft(Slot<navbar::Brand>, Slot<Offcanvas>),
|
OffcanvasBrandLeft(Embed<navbar::Brand>, Embed<Offcanvas>),
|
||||||
|
|
||||||
/// Contenido en [`Offcanvas`], con botón de despliegue a la izquierda y marca de identidad a la
|
/// Contenido en [`Offcanvas`], con botón de despliegue a la izquierda y marca de identidad a la
|
||||||
/// derecha.
|
/// derecha.
|
||||||
OffcanvasBrandRight(Slot<navbar::Brand>, Slot<Offcanvas>),
|
OffcanvasBrandRight(Embed<navbar::Brand>, Embed<Offcanvas>),
|
||||||
}
|
}
|
||||||
|
|
||||||
// **< Position >***********************************************************************************
|
// **< Position >***********************************************************************************
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ pub use definition::{Component, ComponentClone, ComponentRender};
|
||||||
mod children;
|
mod children;
|
||||||
pub use children::Children;
|
pub use children::Children;
|
||||||
pub use children::ComponentGuard;
|
pub use children::ComponentGuard;
|
||||||
pub use children::{Child, ChildOp, Slot};
|
pub use children::{Child, ChildOp, Embed};
|
||||||
|
|
||||||
mod message;
|
mod message;
|
||||||
pub use message::{MessageLevel, StatusMessage};
|
pub use message::{MessageLevel, StatusMessage};
|
||||||
|
|
|
||||||
|
|
@ -69,18 +69,18 @@ impl Child {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Component + 'static> From<Slot<C>> for Child {
|
impl<C: Component + 'static> From<Embed<C>> for Child {
|
||||||
/// Convierte un [`Slot<C>`] en un [`Child`], consumiendo el componente tipado.
|
/// Convierte un [`Embed<C>`] en un [`Child`], consumiendo el componente tipado.
|
||||||
///
|
///
|
||||||
/// Útil cuando se tiene un [`Slot`] y se necesita añadirlo a una lista [`Children`]:
|
/// Útil cuando se tiene un [`Embed`] y se necesita añadirlo a una lista [`Children`]:
|
||||||
///
|
///
|
||||||
/// ```rust,ignore
|
/// ```rust,ignore
|
||||||
/// children.with_child(Child::from(my_slot));
|
/// children.with_child(Child::from(my_embed));
|
||||||
/// // o equivalentemente:
|
/// // o equivalentemente:
|
||||||
/// children.with_child(my_slot.into());
|
/// children.with_child(my_embed.into());
|
||||||
/// ```
|
/// ```
|
||||||
fn from(typed: Slot<C>) -> Self {
|
fn from(embed: Embed<C>) -> Self {
|
||||||
if let Some(m) = typed.0 {
|
if let Some(m) = embed.0 {
|
||||||
Child(Some(Mutex::new(
|
Child(Some(Mutex::new(
|
||||||
Box::new(m.into_inner()) as Box<dyn Component>
|
Box::new(m.into_inner()) as Box<dyn Component>
|
||||||
)))
|
)))
|
||||||
|
|
@ -118,49 +118,48 @@ impl From<Child> for ChildOp {
|
||||||
|
|
||||||
/// Contenedor tipado para un *único* componente de un tipo concreto conocido.
|
/// Contenedor tipado para un *único* componente de un tipo concreto conocido.
|
||||||
///
|
///
|
||||||
/// A diferencia de [`Child`], que encapsula cualquier componente como `dyn Component`, `Slot`
|
/// A diferencia de [`Child`], que encapsula cualquier componente como `dyn Component`, `Embed`
|
||||||
/// mantiene el tipo concreto `C` y permite acceder directamente a sus métodos específicos a través
|
/// mantiene el tipo concreto `C` y permite acceder directamente a sus métodos específicos a través
|
||||||
/// de [`get()`](Slot::get).
|
/// de [`get()`](Embed::get).
|
||||||
///
|
///
|
||||||
/// Se usa habitualmente para incluir un componente dentro de otro cuando no se necesita una lista
|
/// Se usa habitualmente para incrustar un componente dentro de otro cuando no se necesita una lista
|
||||||
/// completa de hijos ([`Children`]), sino un único componente tipado en un campo concreto.
|
/// completa de hijos ([`Children`]), sino un único componente tipado en un campo concreto.
|
||||||
#[derive(AutoDefault)]
|
#[derive(AutoDefault)]
|
||||||
pub struct Slot<C: Component>(Option<Mutex<C>>);
|
pub struct Embed<C: Component>(Option<Mutex<C>>);
|
||||||
|
|
||||||
impl<C: Component + Clone> Clone for Slot<C> {
|
impl<C: Component + Clone> Clone for Embed<C> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Slot(self.0.as_ref().map(|m| Mutex::new(m.lock().clone())))
|
Embed(self.0.as_ref().map(|m| Mutex::new(m.lock().clone())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Component> fmt::Debug for Slot<C> {
|
impl<C: Component> fmt::Debug for Embed<C> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
match &self.0 {
|
match &self.0 {
|
||||||
None => write!(f, "Slot(None)"),
|
None => write!(f, "Embed(None)"),
|
||||||
Some(c) => write!(f, "Slot({})", c.lock().name()),
|
Some(c) => write!(f, "Embed({})", c.lock().name()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Component> Slot<C> {
|
impl<C: Component> Embed<C> {
|
||||||
/// Crea un nuevo `Slot` a partir de un componente.
|
/// Crea un nuevo `Embed` a partir de un componente.
|
||||||
pub fn with(component: C) -> Self {
|
pub fn with(component: C) -> Self {
|
||||||
Slot(Some(Mutex::new(component)))
|
Embed(Some(Mutex::new(component)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// **< Slot BUILDER >*********************************************************************
|
// **< Embed BUILDER >**************************************************************************
|
||||||
|
|
||||||
/// Establece un componente nuevo, o lo vacía.
|
/// Establece un componente nuevo, o lo vacía.
|
||||||
///
|
///
|
||||||
/// Si se proporciona `Some(component)`, se encapsula como [`Slot`]; y si es `None`, se
|
/// Si se proporciona `Some(component)`, se encapsula como [`Embed`]; y si es `None`, se limpia.
|
||||||
/// limpia.
|
|
||||||
#[builder_fn]
|
#[builder_fn]
|
||||||
pub fn with_component(mut self, component: Option<C>) -> Self {
|
pub fn with_component(mut self, component: Option<C>) -> Self {
|
||||||
self.0 = component.map(Mutex::new);
|
self.0 = component.map(Mutex::new);
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
// **< Slot GETTERS >*********************************************************************
|
// **< Embed GETTERS >**************************************************************************
|
||||||
|
|
||||||
/// Devuelve el identificador del componente, si existe y está definido.
|
/// Devuelve el identificador del componente, si existe y está definido.
|
||||||
#[inline]
|
#[inline]
|
||||||
|
|
@ -168,38 +167,38 @@ impl<C: Component> Slot<C> {
|
||||||
self.0.as_ref().and_then(|c| c.lock().id())
|
self.0.as_ref().and_then(|c| c.lock().id())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Devuelve un acceso al componente interno.
|
/// Devuelve un acceso al componente incrustado.
|
||||||
///
|
///
|
||||||
/// - Devuelve `Some(ComponentGuard<C>)` si existe el componente, o `None` si está vacío.
|
/// - Devuelve `Some(ComponentGuard<C>)` si existe el componente, o `None` si está vacío.
|
||||||
/// - El acceso es **exclusivo**: mientras el *guard* esté activo, no habrá otros accesos.
|
/// - El acceso es **exclusivo**: mientras el *guard* esté activo, no habrá otros accesos.
|
||||||
/// - Se recomienda mantener el *guard* **el menor tiempo posible** para evitar bloqueos
|
/// - Se recomienda mantener el *guard* **el menor tiempo posible** para evitar bloqueos
|
||||||
/// innecesarios.
|
/// innecesarios.
|
||||||
/// - Para modificar el componente, declara el *guard* como `mut`:
|
/// - Para modificar el componente, declara el *guard* como `mut`:
|
||||||
/// `if let Some(mut c) = child.get() { c.alter_title(...); }`.
|
/// `if let Some(mut c) = embed.get() { c.alter_title(...); }`.
|
||||||
///
|
///
|
||||||
/// # Ejemplo
|
/// # Ejemplo
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use pagetop::prelude::*;
|
/// # use pagetop::prelude::*;
|
||||||
/// let child = Slot::with(Html::with(|_| html! { "Prueba" }));
|
/// let embed = Embed::with(Html::with(|_| html! { "Prueba" }));
|
||||||
/// {
|
/// {
|
||||||
/// if let Some(component) = child.get() {
|
/// if let Some(component) = embed.get() {
|
||||||
/// assert_eq!(component.name(), "Html");
|
/// assert_eq!(component.name(), "Html");
|
||||||
/// }
|
/// }
|
||||||
/// }; // El *guard* se libera aquí, antes del *drop* de `child`.
|
/// }; // El *guard* se libera aquí, antes del *drop* de `embed`.
|
||||||
///
|
///
|
||||||
/// let child = Slot::with(Block::new().with_title(L10n::n("Título")));
|
/// let embed = Embed::with(Block::new().with_title(L10n::n("Título")));
|
||||||
/// {
|
/// {
|
||||||
/// if let Some(mut component) = child.get() {
|
/// if let Some(mut component) = embed.get() {
|
||||||
/// component.alter_title(L10n::n("Nuevo título"));
|
/// component.alter_title(L10n::n("Nuevo título"));
|
||||||
/// }
|
/// }
|
||||||
/// }; // El *guard* se libera aquí, antes del *drop* de `child`.
|
/// }; // El *guard* se libera aquí, antes del *drop* de `embed`.
|
||||||
/// ```
|
/// ```
|
||||||
pub fn get(&self) -> Option<ComponentGuard<'_, C>> {
|
pub fn get(&self) -> Option<ComponentGuard<'_, C>> {
|
||||||
self.0.as_ref().map(|m| m.lock())
|
self.0.as_ref().map(|m| m.lock())
|
||||||
}
|
}
|
||||||
|
|
||||||
// **< Slot RENDER >**********************************************************************
|
// **< Embed RENDER >***************************************************************************
|
||||||
|
|
||||||
/// Renderiza el componente con el contexto proporcionado.
|
/// Renderiza el componente con el contexto proporcionado.
|
||||||
pub fn render(&self, cx: &mut Context) -> Markup {
|
pub fn render(&self, cx: &mut Context) -> Markup {
|
||||||
|
|
@ -243,11 +242,12 @@ pub enum ChildOp {
|
||||||
///
|
///
|
||||||
/// - [`Child`]: representa un componente hijo encapsulado dentro de la lista. Almacena cualquier
|
/// - [`Child`]: representa un componente hijo encapsulado dentro de la lista. Almacena cualquier
|
||||||
/// componente sin necesidad de conocer su tipo concreto.
|
/// componente sin necesidad de conocer su tipo concreto.
|
||||||
/// - [`Slot<C>`]: contenedor tipado para un *único* componente de tipo `C`. Preferible a `Children`
|
/// - [`Embed<C>`]: contenedor tipado para un *único* componente de tipo `C`. Preferible a
|
||||||
/// cuando el padre solo necesita un componente y quiere acceso directo a los métodos de `C`.
|
/// `Children` cuando el padre solo necesita un componente y quiere acceso directo a los métodos
|
||||||
|
/// de `C`.
|
||||||
/// - [`ChildOp`]: operaciones disponibles sobre la lista. Cuando se necesita algo más que añadir al
|
/// - [`ChildOp`]: operaciones disponibles sobre la lista. Cuando se necesita algo más que añadir al
|
||||||
/// final, se construye la variante adecuada y se pasa a [`with_child`](Self::with_child).
|
/// final, se construye la variante adecuada y se pasa a [`with_child`](Self::with_child).
|
||||||
/// - [`ComponentGuard`]: devuelto por [`Slot::get`] para garantizar acceso exclusivo al componente
|
/// - [`ComponentGuard`]: devuelto por [`Embed::get`] para garantizar acceso exclusivo al componente
|
||||||
/// tipado. Mientras está activo bloquea cualquier otro acceso por lo que conviene liberarlo
|
/// tipado. Mientras está activo bloquea cualquier otro acceso por lo que conviene liberarlo
|
||||||
/// cuanto antes.
|
/// cuanto antes.
|
||||||
///
|
///
|
||||||
|
|
|
||||||
|
|
@ -264,70 +264,70 @@ async fn children_render_concatenates_all_outputs_in_order() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// **< Slot >****************************************************************************************
|
// **< Embed >**************************************************************************************
|
||||||
|
|
||||||
#[pagetop::test]
|
#[pagetop::test]
|
||||||
async fn slot_default_is_empty() {
|
async fn embed_default_is_empty() {
|
||||||
let slot: Slot<TestComp> = Slot::default();
|
let embed: Embed<TestComp> = Embed::default();
|
||||||
assert!(slot.id().is_none());
|
assert!(embed.id().is_none());
|
||||||
assert!(slot.render(&mut Context::default()).is_empty());
|
assert!(embed.render(&mut Context::default()).is_empty());
|
||||||
assert!(slot.get().is_none());
|
assert!(embed.get().is_none());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pagetop::test]
|
#[pagetop::test]
|
||||||
async fn slot_with_stores_component() {
|
async fn embed_with_stores_component() {
|
||||||
let slot = Slot::with(TestComp::text("contenido"));
|
let embed = Embed::with(TestComp::text("contenido"));
|
||||||
assert!(slot.get().is_some());
|
assert!(embed.get().is_some());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
slot.render(&mut Context::default()).into_string(),
|
embed.render(&mut Context::default()).into_string(),
|
||||||
"contenido"
|
"contenido"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pagetop::test]
|
#[pagetop::test]
|
||||||
async fn slot_id_returns_component_id() {
|
async fn embed_id_returns_component_id() {
|
||||||
let slot = Slot::with(TestComp::tagged("slot-id", "texto"));
|
let embed = Embed::with(TestComp::tagged("embed-id", "texto"));
|
||||||
assert_eq!(slot.id(), Some("slot-id".to_string()));
|
assert_eq!(embed.id(), Some("embed-id".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pagetop::test]
|
#[pagetop::test]
|
||||||
async fn slot_get_is_some_when_component_present() {
|
async fn embed_get_is_some_when_component_present() {
|
||||||
let slot = Slot::with(TestComp::tagged("abc", "hola"));
|
let embed = Embed::with(TestComp::tagged("abc", "hola"));
|
||||||
// `get()` devuelve Some; la lectura del id verifica que accede al componente correctamente.
|
// `get()` devuelve Some; la lectura del id verifica que accede al componente correctamente.
|
||||||
assert!(slot.get().is_some());
|
assert!(embed.get().is_some());
|
||||||
assert_eq!(slot.id(), Some("abc".to_string()));
|
assert_eq!(embed.id(), Some("abc".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pagetop::test]
|
#[pagetop::test]
|
||||||
async fn slot_get_allows_mutating_component() {
|
async fn embed_get_allows_mutating_component() {
|
||||||
let slot = Slot::with(TestComp::tagged("orig", "texto"));
|
let embed = Embed::with(TestComp::tagged("orig", "texto"));
|
||||||
// El `;` final convierte el `if let` en sentencia y libera el guard antes que `slot`.
|
// El `;` final convierte el `if let` en sentencia y libera el guard antes que `embed`.
|
||||||
if let Some(mut comp) = slot.get() {
|
if let Some(mut comp) = embed.get() {
|
||||||
comp.id.alter_id("modificado");
|
comp.id.alter_id("modificado");
|
||||||
};
|
};
|
||||||
assert_eq!(slot.id(), Some("modificado".to_string()));
|
assert_eq!(embed.id(), Some("modificado".to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pagetop::test]
|
#[pagetop::test]
|
||||||
async fn slot_with_component_replaces_content() {
|
async fn embed_with_component_replaces_content() {
|
||||||
let slot =
|
let embed =
|
||||||
Slot::with(TestComp::text("primero")).with_component(Some(TestComp::text("segundo")));
|
Embed::with(TestComp::text("primero")).with_component(Some(TestComp::text("segundo")));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
slot.render(&mut Context::default()).into_string(),
|
embed.render(&mut Context::default()).into_string(),
|
||||||
"segundo"
|
"segundo"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pagetop::test]
|
#[pagetop::test]
|
||||||
async fn slot_with_component_none_empties_slot() {
|
async fn embed_with_component_none_empties_embed() {
|
||||||
let slot = Slot::with(TestComp::text("algo")).with_component(None);
|
let embed = Embed::with(TestComp::text("algo")).with_component(None);
|
||||||
assert!(slot.get().is_none());
|
assert!(embed.get().is_none());
|
||||||
assert!(slot.render(&mut Context::default()).is_empty());
|
assert!(embed.render(&mut Context::default()).is_empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pagetop::test]
|
#[pagetop::test]
|
||||||
async fn slot_clone_is_deep() {
|
async fn embed_clone_is_deep() {
|
||||||
let original = Slot::with(TestComp::tagged("orig", "texto"));
|
let original = Embed::with(TestComp::tagged("orig", "texto"));
|
||||||
let clone = original.clone();
|
let clone = original.clone();
|
||||||
// Mutar el clon no debe afectar al original.
|
// Mutar el clon no debe afectar al original.
|
||||||
if let Some(mut comp) = clone.get() {
|
if let Some(mut comp) = clone.get() {
|
||||||
|
|
@ -338,11 +338,11 @@ async fn slot_clone_is_deep() {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pagetop::test]
|
#[pagetop::test]
|
||||||
async fn slot_converts_into_child() {
|
async fn embed_converts_into_child() {
|
||||||
let slot = Slot::with(TestComp::text("desde slot"));
|
let embed = Embed::with(TestComp::text("desde embed"));
|
||||||
let child = Child::from(slot);
|
let child = Child::from(embed);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
child.render(&mut Context::default()).into_string(),
|
child.render(&mut Context::default()).into_string(),
|
||||||
"desde slot"
|
"desde embed"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue