✨ Implementa temas hijo y macro render_component!
Añade `Theme::parent()` para declarar jerarquías de herencia entre temas. Sustituye la acción `PrepareRender<C>` por el método `Theme::prepare_component()` y la macro `render_component!`.
This commit is contained in:
parent
0684472df2
commit
9f8640d6bf
14 changed files with 161 additions and 139 deletions
|
|
@ -5,6 +5,3 @@ pub use before_render_component::*;
|
|||
|
||||
mod after_render_component;
|
||||
pub use after_render_component::*;
|
||||
|
||||
mod prepare_render;
|
||||
pub use prepare_render::*;
|
||||
|
|
|
|||
|
|
@ -1,65 +0,0 @@
|
|||
use crate::prelude::*;
|
||||
|
||||
/// Tipo de función para alterar el renderizado de un componente.
|
||||
///
|
||||
/// Permite a un [tema](crate::base::action::theme) sobreescribir el renderizado predeterminado de
|
||||
/// los componentes.
|
||||
///
|
||||
/// Recibe una referencia al componente `component` y una referencia mutable al contexto `cx`.
|
||||
pub type FnPrepareRender<C> = fn(component: &C, cx: &mut Context) -> Result<Markup, ComponentError>;
|
||||
|
||||
/// Ejecuta [`FnPrepareRender`] para preparar el renderizado de un componente.
|
||||
///
|
||||
/// Permite a un tema hacer una implementación nueva del renderizado de un componente.
|
||||
pub struct PrepareRender<C: Component> {
|
||||
f: FnPrepareRender<C>,
|
||||
theme_type_id: Option<UniqueId>,
|
||||
referer_type_id: Option<UniqueId>,
|
||||
}
|
||||
|
||||
/// Filtro para despachar [`FnPrepareRender`] que modifica el renderizado de un componente `C`.
|
||||
impl<C: Component> ActionDispatcher for PrepareRender<C> {
|
||||
/// Devuelve el identificador de tipo ([`UniqueId`]) del tema.
|
||||
fn theme_type_id(&self) -> Option<UniqueId> {
|
||||
self.theme_type_id
|
||||
}
|
||||
|
||||
/// Devuelve el identificador de tipo ([`UniqueId`]) del componente `C`.
|
||||
fn referer_type_id(&self) -> Option<UniqueId> {
|
||||
self.referer_type_id
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: Component> PrepareRender<C> {
|
||||
/// Permite [registrar](Extension::actions) una nueva acción [`FnPrepareRender`] para un tema
|
||||
/// dado.
|
||||
pub fn new(theme: ThemeRef, f: FnPrepareRender<C>) -> Self {
|
||||
PrepareRender {
|
||||
f,
|
||||
theme_type_id: Some(theme.type_id()),
|
||||
referer_type_id: Some(UniqueId::of::<C>()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Despacha las acciones. Se detiene en cuanto una renderiza o produce un error.
|
||||
#[inline]
|
||||
pub(crate) fn dispatch(component: &C, cx: &mut Context) -> Result<Markup, ComponentError> {
|
||||
let mut render_result: Result<Markup, ComponentError> = Ok(html! {});
|
||||
dispatch_actions_until(
|
||||
&ActionKey::new(
|
||||
UniqueId::of::<Self>(),
|
||||
Some(cx.theme().type_id()),
|
||||
Some(UniqueId::of::<C>()),
|
||||
None,
|
||||
),
|
||||
|action: &Self| match &render_result {
|
||||
Ok(markup) if markup.is_empty() => {
|
||||
render_result = (action.f)(component, cx);
|
||||
std::ops::ControlFlow::Continue(())
|
||||
}
|
||||
_ => std::ops::ControlFlow::Break(()),
|
||||
},
|
||||
);
|
||||
render_result
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue