diff --git a/packages/core-macro/src/rsxt.rs b/packages/core-macro/src/rsxt.rs index 839bd990b..524acc4ee 100644 --- a/packages/core-macro/src/rsxt.rs +++ b/packages/core-macro/src/rsxt.rs @@ -132,7 +132,7 @@ impl Parse for Node { struct Component { name: Ident, - body: Vec, + body: Vec, // attrs: Vec, children: MaybeExpr>, } @@ -147,13 +147,19 @@ impl ToTokens for ToToksCtx<&Component> { // self.recurse(attr).to_tokens(&mut toks); // } - let body = &self.inner.body; - // panic!("tokens are {:#?}", toks); + let mut builder = quote! { + fc_to_builder(#name) + }; - // tokens.append_all(quote! { - // dioxus::builder::virtual_child(ctx, #name{ #body, ___p: PhantomData{} }) - // // dioxus::builder::ElementBuilder::new(ctx, #name) - // }); + for field in &self.inner.body { + builder.append_all(quote! {#field}); + } + + builder.append_all(quote! { + .build() + }); + + // panic!("tokens are {:#?}", toks); // no children right now @@ -179,6 +185,9 @@ impl ToTokens for ToToksCtx<&Component> { // tokens.append_all(quote! { // .finish() // }); + let toks = tokens.append_all(quote! { + dioxus::builder::virtual_child(ctx, #name, #builder) + }); } } @@ -199,18 +208,21 @@ impl Parse for Component { let content: ParseBuffer; syn::braced!(content in s); - let mut body: Vec = Vec::new(); - let mut attrs = Vec::new(); + let mut body: Vec = Vec::new(); let mut children: Vec = Vec::new(); - parse_element_content(content, &mut attrs, &mut children); + // parse_element_content(content, &mut attrs, &mut children); - // 'parsing: loop { - // // [1] Break if empty - // if content.is_empty() { - // break 'parsing; - // } - // } + 'parsing: loop { + // [1] Break if empty + if content.is_empty() { + break 'parsing; + } + + if let Ok(field) = content.parse::() { + body.push(field); + } + } // let body = content.parse()?; @@ -231,20 +243,36 @@ impl Parse for Component { } // the struct's fields info -pub struct Field { +pub struct ComponentField { name: Ident, - content: Ident, + content: Expr, } -impl Parse for Field { +impl Parse for ComponentField { fn parse(input: ParseStream) -> Result { - todo!() + let mut name = Ident::parse_any(input)?; + let name_str = name.to_string(); + input.parse::()?; + let content = input.parse()?; + + // consume comma if it exists + // we don't actually care if there *are* commas between attrs + if input.peek(Token![,]) { + let _ = input.parse::(); + } + + Ok(Self { name, content }) } } -impl ToTokens for ToToksCtx<&Field> { +impl ToTokens for &ComponentField { + // impl ToTokens for ToToksCtx<&ComponentField> { fn to_tokens(&self, tokens: &mut TokenStream2) { - todo!() + let name = &self.name; + let content = &self.content; + tokens.append_all(quote! { + .#name(#content) + }) } } diff --git a/packages/core/examples/borrowed.rs b/packages/core/examples/borrowed.rs index 5054111a5..e203364a6 100644 --- a/packages/core/examples/borrowed.rs +++ b/packages/core/examples/borrowed.rs @@ -9,7 +9,7 @@ fn main() {} use std::fmt::Debug; -use dioxus_core::{component::Properties, prelude::*}; +use dioxus_core::prelude::*; struct Props { items: Vec, @@ -32,11 +32,12 @@ fn app(ctx: Context, props: &Props) -> DomTree { // root = root.child(builder::virtual_child( c, - ChildProps { - item: child, - item_handler: setter, - }, - child_item, + ChildItem, + // create the props with nothing but the fc + fc_to_builder(ChildItem) + .item(child) + .item_handler(setter) + .build(), )); } root.finish() @@ -64,7 +65,9 @@ struct ChildProps<'a> { impl PartialEq for ChildProps<'_> { fn eq(&self, other: &Self) -> bool { - todo!() + // assume the dyn fn is never stable - + // wrap with use_callback if it's an issue for you + false } } @@ -75,7 +78,7 @@ impl<'a> Properties for ChildProps<'a> { } } -fn child_item(ctx: Context, props: &ChildProps) -> DomTree { +fn ChildItem(ctx: Context, props: &ChildProps) -> DomTree { todo!() // ctx.render(rsx! { // div { diff --git a/packages/core/examples/fc.rs b/packages/core/examples/fc.rs index f3305cfd9..ed77d7558 100644 --- a/packages/core/examples/fc.rs +++ b/packages/core/examples/fc.rs @@ -1,41 +1,37 @@ +use dioxus_core::component::fc_to_builder; use dioxus_core::prelude::*; - use dioxus_core_macro::fc; use std::marker::PhantomData; -// #[derive(PartialEq)] -// pub struct Example<'a> { -// b: &'a str, -// ___p: std::marker::PhantomData<&'a ()>, -// } -// impl<'a> FC for Example<'a> { -// fn render(ctx: Context<'_>, props: &Example<'a>) -> DomTree { -// let Example { b, .. } = props; -// { -// ctx.render(rsx! { -// div { "abcd {b}" } -// }) -// } -// } -// } - -// always try to fill in with Default - -// #[fc] -fn Example(ctx: Context, a: &str, b: &str, c: &str) -> DomTree { +static BLAH: FC<()> = |ctx, props| { + let g = "asd".to_string(); ctx.render(rsx! { div { SomeComponent { - a: "123" + some_field: g + abc123: 10, } } }) +}; + +#[derive(PartialEq, Props)] +pub struct ExampleProps { + some_field: String, } -// #[fc] -fn SomeComponent(ctx: Context, a: &str, b: &str) -> DomTree { - todo!() -} +static SomeComponent: FC = |ctx, props| { + ctx.render(rsx! { + div { } + }) +}; fn main() {} + +impl Properties for ExampleProps { + type Builder = ExamplePropsBuilder<((),)>; + fn builder() -> Self::Builder { + ExampleProps::builder() + } +} diff --git a/packages/core/src/component.rs b/packages/core/src/component.rs index 13698a37f..45c6cf6a2 100644 --- a/packages/core/src/component.rs +++ b/packages/core/src/component.rs @@ -15,7 +15,7 @@ pub trait Properties: PartialEq { pub struct EmptyBuilder; impl EmptyBuilder { - pub fn build() -> () { + pub fn build(self) -> () { () } } diff --git a/packages/core/src/lib.rs b/packages/core/src/lib.rs index 972097218..92ea4ec7e 100644 --- a/packages/core/src/lib.rs +++ b/packages/core/src/lib.rs @@ -130,7 +130,7 @@ pub(crate) mod innerlude { /// Re-export common types for ease of development use. /// Essential when working with the html! macro pub mod prelude { - // pub use crate::component::Properties; + pub use crate::component::{fc_to_builder, Properties}; pub use crate::context::Context; use crate::nodes; pub use crate::virtual_dom::VirtualDom; diff --git a/packages/core/src/nodebuilder.rs b/packages/core/src/nodebuilder.rs index 7a5c88697..ee2aa2868 100644 --- a/packages/core/src/nodebuilder.rs +++ b/packages/core/src/nodebuilder.rs @@ -528,9 +528,10 @@ pub fn attr<'a>(name: &'static str, value: &'a str) -> Attribute<'a> { // _props: T pub fn virtual_child<'a, 'b, T: crate::innerlude::Properties>( ctx: &'b NodeCtx<'a>, - p: T, f: FC, + p: T, ) -> VNode<'a> { + // crate::nodes::VComponent todo!() // VNode::Component() }