feat: components pass thru children
This commit is contained in:
1 parent
b6c0bce89c
commit
c6a6c3d0f8
17 files changed
+581
-298
No files matched your search
@@ -1,9 +1,12 @@
|
||||
use std::{cell::Cell, fmt::Arguments};
|
||||
|
||||
use bumpalo::Bump;
|
||||
|
||||
use crate::{
|
||||
any_props::{AnyProps, VComponentProps},
|
||||
arena::ElementId,
|
||||
innerlude::{DynamicNode, DynamicNodeKind},
|
||||
LazyNodes, ScopeState, VNode,
|
||||
Attribute, AttributeValue, Element, LazyNodes, Properties, Scope, ScopeState, VNode,
|
||||
};
|
||||
|
||||
impl ScopeState {
|
||||
@@ -50,6 +53,56 @@ impl ScopeState {
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new [`Attribute`]
|
||||
pub fn attr<'a>(
|
||||
&'a self,
|
||||
name: &'static str,
|
||||
val: impl IntoAttributeValue<'a>,
|
||||
namespace: Option<&'static str>,
|
||||
is_volatile: bool,
|
||||
) -> Attribute<'a> {
|
||||
Attribute {
|
||||
name,
|
||||
namespace,
|
||||
mounted_element: Cell::new(ElementId(0)),
|
||||
path: &[0],
|
||||
value: val.into_value(self.bump()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a new [`VNode::Component`]
|
||||
pub fn component<'a, P>(
|
||||
&'a self,
|
||||
component: fn(Scope<'a, P>) -> Element,
|
||||
props: P,
|
||||
fn_name: &'static str,
|
||||
) -> DynamicNode<'a>
|
||||
where
|
||||
P: Properties + 'a,
|
||||
{
|
||||
let props = self.bump().alloc(props);
|
||||
let detached = unsafe { std::mem::transmute(component) };
|
||||
let vcomp = VComponentProps::new(detached, P::memoize, props);
|
||||
let as_dyn = self.bump().alloc(vcomp) as &mut dyn AnyProps;
|
||||
let detached_dyn: *mut dyn AnyProps = unsafe { std::mem::transmute(as_dyn) };
|
||||
|
||||
// todo: clean up borrowed props
|
||||
// if !P::IS_STATIC {
|
||||
// let vcomp = &*vcomp;
|
||||
// let vcomp = unsafe { std::mem::transmute(vcomp) };
|
||||
// self.scope.items.borrow_mut().borrowed_props.push(vcomp);
|
||||
// }
|
||||
|
||||
DynamicNode {
|
||||
path: &[],
|
||||
kind: DynamicNodeKind::Component {
|
||||
name: fn_name,
|
||||
can_memoize: P::IS_STATIC,
|
||||
props: detached_dyn,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub trait IntoVnode<'a, A = ()> {
|
||||
@@ -61,3 +114,56 @@ impl<'a, 'b> IntoVnode<'a> for LazyNodes<'a, 'b> {
|
||||
self.call(cx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> IntoVnode<'a> for VNode<'a> {
|
||||
fn into_dynamic_node(self, cx: &'a ScopeState) -> VNode<'a> {
|
||||
self
|
||||
}
|
||||
}
|
||||
impl<'a, 'b> IntoVnode<'a> for &'a VNode<'a> {
|
||||
fn into_dynamic_node(self, cx: &'a ScopeState) -> VNode<'a> {
|
||||
VNode {
|
||||
node_id: self.node_id.clone(),
|
||||
parent: self.parent,
|
||||
template: self.template,
|
||||
root_ids: self.root_ids,
|
||||
dynamic_nodes: self.dynamic_nodes,
|
||||
dynamic_attrs: self.dynamic_attrs,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A value that can be converted into an attribute value
|
||||
pub trait IntoAttributeValue<'a> {
|
||||
/// Convert into an attribute value
|
||||
fn into_value(self, bump: &'a Bump) -> AttributeValue<'a>;
|
||||
}
|
||||
|
||||
impl<'a> IntoAttributeValue<'a> for &'a str {
|
||||
fn into_value(self, _: &'a Bump) -> AttributeValue<'a> {
|
||||
AttributeValue::Text(self)
|
||||
}
|
||||
}
|
||||
impl<'a> IntoAttributeValue<'a> for f32 {
|
||||
fn into_value(self, _: &'a Bump) -> AttributeValue<'a> {
|
||||
AttributeValue::Float(self)
|
||||
}
|
||||
}
|
||||
impl<'a> IntoAttributeValue<'a> for i32 {
|
||||
fn into_value(self, _: &'a Bump) -> AttributeValue<'a> {
|
||||
AttributeValue::Int(self)
|
||||
}
|
||||
}
|
||||
impl<'a> IntoAttributeValue<'a> for bool {
|
||||
fn into_value(self, _: &'a Bump) -> AttributeValue<'a> {
|
||||
AttributeValue::Bool(self)
|
||||
}
|
||||
}
|
||||
impl<'a> IntoAttributeValue<'a> for Arguments<'_> {
|
||||
fn into_value(self, bump: &'a Bump) -> AttributeValue<'a> {
|
||||
use bumpalo::core_alloc::fmt::Write;
|
||||
let mut str_buf = bumpalo::collections::String::new_in(bump);
|
||||
str_buf.write_fmt(self).unwrap();
|
||||
AttributeValue::Text(str_buf.into_bump_str())
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user