add dyn_bindings builder method to component

This commit is contained in:
Upbolt 2024-04-16 10:05:37 -07:00
parent e29d31e686
commit cdd5e0f682
2 changed files with 68 additions and 1 deletions

View file

@ -365,6 +365,33 @@ impl ToTokens for Model {
})
.collect::<TokenStream>();
let dyn_binding_props = props
.iter()
.filter(
|Prop {
prop_opts: PropOpt { attrs, .. },
..
}| *attrs,
)
.filter_map(
|Prop {
name,
prop_opts: PropOpt { attrs, .. },
..
}| {
let ident = &name.ident;
if *attrs {
Some(quote! {
::leptos::leptos_dom::html::Binding::Attribute { name, value } => self.#ident.push((name, value)),
})
} else {
None
}
},
)
.collect::<TokenStream>();
let body = quote! {
#destructure_props
#tracing_span_expr
@ -504,6 +531,21 @@ impl ToTokens for Model {
}
}
impl #impl_generics #props_name #generics #where_clause {
fn dyn_bindings<B: Into<::leptos::leptos_dom::html::Binding>>(mut self, bindings: impl std::iter::IntoIterator<Item = B>) -> Self {
for binding in bindings.into_iter() {
let binding: ::leptos::leptos_dom::html::Binding = binding.into();
match binding {
#dyn_binding_props
_ => {}
}
}
self
}
}
#into_view
#docs

View file

@ -27,6 +27,30 @@ pub(crate) fn component_to_tokens(
}
});
let spread_bindings = node.attributes().iter().filter_map(|node| {
use rstml::node::NodeBlock;
use syn::{Expr, ExprRange, RangeLimits, Stmt};
if let NodeAttribute::Block(NodeBlock::ValidBlock(block)) = node {
match block.stmts.first()? {
Stmt::Expr(
Expr::Range(ExprRange {
start: None,
limits: RangeLimits::HalfOpen(_),
end: Some(end),
..
}),
_,
) => Some(
quote! { .dyn_bindings(#[allow(unused_brace)] {#end}) },
),
_ => None,
}
} else {
None
}
});
let props = attrs
.clone()
.filter(|attr| {
@ -222,7 +246,8 @@ pub(crate) fn component_to_tokens(
#[allow(clippy::let_unit_value, clippy::unit_arg)]
let props = props
#build
#dyn_attrs;
#dyn_attrs
#(#spread_bindings)*;
#[allow(unreachable_code)]
::leptos::component_view(