add component support
This commit is contained in:
1 parent
07da854455
commit
a0c7e4d78a
8 files changed
+62
-14
No files matched your search
+18
-1
@@ -21,7 +21,24 @@ fn app(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
h1 {
|
||||
width: format!("{}px", count),
|
||||
"High-Five counter: {count}"
|
||||
"High-Five counter: {count}",
|
||||
Comp{
|
||||
color: "#083289"
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Props)]
|
||||
struct CompProps {
|
||||
color: &'static str,
|
||||
}
|
||||
|
||||
fn Comp(cx: Scope<CompProps>) -> Element {
|
||||
cx.render(rsx! {
|
||||
h1 {
|
||||
color: cx.props.color,
|
||||
"Hello, from a component!"
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -202,11 +202,11 @@ pub fn rsx(s: TokenStream) -> TokenStream {
|
||||
#rsx_text.to_string(),
|
||||
);
|
||||
});
|
||||
LazyNodes::new(move |factory|{
|
||||
LazyNodes::new(move |__cx|{
|
||||
let read = rsx_text_index.read();
|
||||
if let Some(text) = read.get(&line_num){
|
||||
interpert_rsx(
|
||||
factory,
|
||||
__cx,
|
||||
&text,
|
||||
#captured
|
||||
)
|
||||
|
||||
@@ -22,6 +22,7 @@ use syn::{
|
||||
token, Expr, Ident, LitStr, Result, Token,
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct Component {
|
||||
pub name: syn::Path,
|
||||
pub body: Vec<ComponentField>,
|
||||
@@ -149,11 +150,13 @@ impl ToTokens for Component {
|
||||
}
|
||||
|
||||
// the struct's fields info
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct ComponentField {
|
||||
pub name: Ident,
|
||||
pub content: ContentField,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum ContentField {
|
||||
ManExpr(Expr),
|
||||
Formatted(LitStr),
|
||||
|
||||
@@ -10,6 +10,7 @@ use syn::{
|
||||
// =======================================
|
||||
// Parse the VNode::Element type
|
||||
// =======================================
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct Element {
|
||||
pub name: Ident,
|
||||
pub key: Option<LitStr>,
|
||||
@@ -189,6 +190,7 @@ impl ToTokens for Element {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum ElementAttr {
|
||||
/// attribute: "valuee {}"
|
||||
AttrText {
|
||||
@@ -225,6 +227,7 @@ pub enum ElementAttr {
|
||||
Meta(String),
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub struct ElementAttrNamed {
|
||||
pub el_name: Ident,
|
||||
pub attr: ElementAttr,
|
||||
|
||||
@@ -15,6 +15,7 @@ Parse
|
||||
-> "text {with_args}"
|
||||
-> (0..10).map(|f| rsx!("asd")), // <--- notice the comma - must be a complete expr
|
||||
*/
|
||||
#[derive(PartialEq, Eq)]
|
||||
pub enum BodyNode {
|
||||
Element(Element),
|
||||
Component(Component),
|
||||
|
||||
@@ -83,6 +83,13 @@ impl ToTokens for CapturedContextBuilder {
|
||||
iterators,
|
||||
captured_expressions,
|
||||
} = self;
|
||||
let compontents_str = components
|
||||
.iter()
|
||||
.map(|comp| comp.to_token_stream().to_string());
|
||||
let components = components.iter().map(|comp| comp);
|
||||
let iterators_str = iterators
|
||||
.iter()
|
||||
.map(|expr| expr.to_token_stream().to_string());
|
||||
let captured: Vec<_> = attributes
|
||||
.iter()
|
||||
.map(|(_, fmt)| fmt.named_args.iter())
|
||||
@@ -99,8 +106,8 @@ impl ToTokens for CapturedContextBuilder {
|
||||
captured: IfmtArgs{
|
||||
named_args: vec![#((#captured_names, #captured_expr.to_string())),*]
|
||||
},
|
||||
components: vec![#(#components),*],
|
||||
iterators: vec![#(#iterators),*],
|
||||
components: vec![#((#compontents_str, #components)),*],
|
||||
iterators: vec![#((#iterators_str, #iterators)),*],
|
||||
expressions: vec![#((#captured_attr_expressions_text, #captured_expressions.to_string())),*],
|
||||
}
|
||||
})
|
||||
@@ -113,9 +120,9 @@ pub struct CapturedContext<'a> {
|
||||
// // map of the attribute name and element path to the formated value
|
||||
// pub captured_attribute_values: IfmtArgs,
|
||||
// the only thing we can update in component is the children
|
||||
pub components: Vec<VNode<'a>>,
|
||||
pub components: Vec<(&'static str, VNode<'a>)>,
|
||||
// we can't reasonably interpert iterators, so they are staticly inserted
|
||||
pub iterators: Vec<VNode<'a>>,
|
||||
pub iterators: Vec<(&'static str, VNode<'a>)>,
|
||||
// map expression to the value resulting from the expression
|
||||
pub expressions: Vec<(&'static str, String)>,
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use dioxus_core::{Attribute, NodeFactory, VNode};
|
||||
use dioxus_rsx::{BodyNode, CallBody, ElementAttr};
|
||||
use dioxus_rsx::{BodyNode, CallBody, Component, ElementAttr};
|
||||
use quote::ToTokens;
|
||||
use std::str::FromStr;
|
||||
use syn::{parse_str, Expr};
|
||||
use syn::{parse2, parse_str, Expr};
|
||||
|
||||
use crate::attributes::attrbute_to_static_str;
|
||||
use crate::captuered_context::{CapturedContext, IfmtArgs};
|
||||
@@ -83,17 +84,21 @@ impl FromStr for InterperedIfmt {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build<'a>(rsx: CallBody, ctx: CapturedContext, factory: &NodeFactory<'a>) -> VNode<'a> {
|
||||
pub fn build<'a>(
|
||||
rsx: CallBody,
|
||||
mut ctx: CapturedContext<'a>,
|
||||
factory: &NodeFactory<'a>,
|
||||
) -> VNode<'a> {
|
||||
let children_built = factory.bump().alloc(Vec::new());
|
||||
for (i, child) in rsx.roots.into_iter().enumerate() {
|
||||
children_built.push(build_node(child, &ctx, factory, i.to_string().as_str()));
|
||||
children_built.push(build_node(child, &mut ctx, factory, i.to_string().as_str()));
|
||||
}
|
||||
factory.fragment_from_iter(children_built.iter())
|
||||
}
|
||||
|
||||
fn build_node<'a>(
|
||||
node: BodyNode,
|
||||
ctx: &CapturedContext,
|
||||
ctx: &mut CapturedContext<'a>,
|
||||
factory: &NodeFactory<'a>,
|
||||
key: &str,
|
||||
) -> Option<VNode<'a>> {
|
||||
@@ -190,7 +195,19 @@ fn build_node<'a>(
|
||||
None
|
||||
}
|
||||
}
|
||||
BodyNode::Component(_) => todo!(),
|
||||
BodyNode::Component(comp) => {
|
||||
let expr: Expr = parse2(comp.to_token_stream()).unwrap();
|
||||
if let Some(idx) = ctx
|
||||
.components
|
||||
.iter()
|
||||
.position(|(code, _)| parse_str::<Expr>(*code).unwrap() == expr)
|
||||
{
|
||||
let (_, vnode) = ctx.components.remove(idx);
|
||||
Some(vnode)
|
||||
} else {
|
||||
panic!("could not resolve component {:?}", comp.name);
|
||||
}
|
||||
}
|
||||
BodyNode::RawExpr(_) => todo!(),
|
||||
BodyNode::Meta(_) => todo!(),
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ pub fn with_hot_reload(cx: Scope<Component>) -> Element {
|
||||
pub fn interpert_rsx<'a, 'b>(
|
||||
factory: dioxus_core::NodeFactory<'a>,
|
||||
text: &str,
|
||||
context: captuered_context::CapturedContext,
|
||||
context: captuered_context::CapturedContext<'a>,
|
||||
) -> VNode<'a> {
|
||||
build(parse_str(text).unwrap(), context, &factory)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user