1
0
Эх сурвалжийг харах

feat: add an unhygenic render macro (#556)

* feat: add an unhygenic render macro

* chore: use render instead of rsx!(cx,
Jon Kelley 2 жил өмнө
parent
commit
28fba42e7e

+ 1 - 1
docs/guide/src/en/__unused/advanced-guides/11-arena-memo.md

@@ -32,7 +32,7 @@ static TestComponent: Component = |cx|{
 
 #[inline_props]
 fn test_component(cx: Scope, name: String) -> Element {
-    rsx!(cx, "Hello, {name}")
+    render!("Hello, {name}")
 }
 ```
 

+ 1 - 1
docs/guide/src/en/__unused/advanced-guides/12-signals.md

@@ -98,7 +98,7 @@ Sometimes you want a signal to propagate across your app, either through far-awa
 const TITLE: Atom<String> = || "".to_string();
 const Provider: Component = |cx|{
     let title = use_signal(&cx, &TITLE);
-    rsx!(cx, input { value: title })
+    render!(input { value: title })
 };
 ```
 

+ 12 - 12
docs/reference/src/guide/rsx_in_depth.md

@@ -53,14 +53,14 @@ Commas are entirely optional, but might be useful to delineate between elements
 
 The `render` function provides an **extremely efficient** allocator for VNodes and text, so try not to use the `format!` macro in your components. Rust's default `ToString` methods pass through the global allocator, but all text in components is allocated inside a manually-managed Bump arena. To push you in the right direction, all text-based attributes take `std::fmt::Arguments` directly, so you'll want to reach for `format_args!` when the built-in `f-string` interpolation just doesn't cut it.
 
-### Ignoring `cx.render` with `rsx!(cx, ...)`
+### Ignoring `cx.render` with `render!(...)`
 
 Sometimes, writing `cx.render` is a hassle. The `rsx! macro will accept any token followed by a comma as the target to call "render" on:
 
 ```rust
 cx.render(rsx!( div {} ))
 // becomes
-rsx!(cx, div {})
+render!(div {})
 ```
 
 ### Conditional Rendering
@@ -70,9 +70,9 @@ Sometimes, you might not want to render an element given a condition. The rsx! m
 ```rust
 rsx!({
     if enabled {
-        rsx!(cx, div {"enabled"})
+        render!(div {"enabled"})
     } else {
-        rsx!(cx, li {"disabled"})
+        render!(li {"disabled"})
     }
 })
 ```
@@ -96,8 +96,8 @@ match case {
 
 // the nodes must be rendered first
 match case {
-    true => rsx!(cx, div {}),
-    false => rsx!(cx, div {})
+    true => render!(div {}),
+    false => render!(div {})
 }
 ```
 
@@ -121,10 +121,10 @@ Sometimes, it makes sense to render VNodes into a list:
 let mut items = vec![];
 
 for _ in 0..5 {
-    items.push(rsx!(cx, li {} ))
+    items.push(render!(li {} ))
 }
 
-rsx!(cx, {items} )
+render!({items} )
 ```
 
 #### Lists and Keys
@@ -137,7 +137,7 @@ In these cases, it is vitally important to specify a "key" alongside the element
 
 ```rust
 fn render_list(cx: Scope, items: HashMap<String, Todo>) -> DomTree {
-    rsx!(cx, ul {
+    render!(ul {
         {items.iter().map(|key, item| {
             li {
                 key: key,
@@ -209,9 +209,9 @@ cx.render(rsx!{
             // rsx! is lazy, and the underlying closures cannot have the same type
             // Rendering produces the VNode type
             {match rand::gen_range::<i32>(1..3) {
-                1 => rsx!(cx, h1 { "big" })
-                2 => rsx!(cx, h2 { "medium" })
-                _ => rsx!(cx, h3 { "small" })
+                1 => render!(h1 { "big" })
+                2 => render!(h2 { "medium" })
+                _ => render!(h3 { "small" })
             }}
 
             // Optionals

+ 12 - 12
docs/reference/src/guide/rsx_in_depth_pt-br.md

@@ -53,14 +53,14 @@ As vírgulas são totalmente opcionais, mas podem ser úteis para delinear entre
 
 A função `render` fornece um alocador **extremamente eficiente** para `VNodes` e `text`, então tente não usar a macro `format!` em seus componentes. Os métodos `ToString` padrão do Rust passam pelo alocador global, mas todo o texto nos componentes é alocado dentro de uma ""arena Bump"" gerenciada manualmente. Para levá-lo na direção certa, todos os atributos baseados em texto recebem `std::fmt::Arguments` diretamente, então você vai querer usar `format_args!` quando a interpolação interna `f-string` simplesmente não funcionar.
 
-### Ignorando `cx.render` com `rsx!(cx, ...)`
+### Ignorando `cx.render` com `render!(...)`
 
 Às vezes, escrever `cx.render` é um aborrecimento. O `rsx!` macro aceitará qualquer token seguido por uma vírgula como destino para chamar "render" em:
 
 ```rust
 cx.render(rsx!( div {} ))
 // becomes
-rsx!(cx, div {})
+render!(div {})
 ```
 
 ### Renderização Condicional
@@ -70,9 +70,9 @@ rsx!(cx, div {})
 ```rust
 rsx!({
     if enabled {
-        rsx!(cx, div {"enabled"})
+        render!(div {"enabled"})
     } else {
-        rsx!(cx, li {"disabled"})
+        render!(li {"disabled"})
     }
 })
 ```
@@ -96,8 +96,8 @@ match case {
 
 // the nodes must be rendered first
 match case {
-    true => rsx!(cx, div {}),
-    false => rsx!(cx, div {})
+    true => render!(div {}),
+    false => render!(div {})
 }
 ```
 
@@ -121,10 +121,10 @@ cx.render(rsx!{
 let mut items = vec![];
 
 for _ in 0..5 {
-    items.push(rsx!(cx, li {} ))
+    items.push(render!(li {} ))
 }
 
-rsx!(cx, {items} )
+render!({items} )
 ```
 
 #### Listas e chaves
@@ -137,7 +137,7 @@ Nesses casos, é de vital importância especificar uma "chave" ao lado do elemen
 
 ```rust
 fn render_list(cx: Scope, items: HashMap<String, Todo>) -> DomTree {
-    rsx!(cx, ul {
+    render!(ul {
         {items.iter().map(|key, item| {
             li {
                 key: key,
@@ -209,9 +209,9 @@ cx.render(rsx!{
             // rsx! is lazy, and the underlying closures cannot have the same type
             // Rendering produces the VNode type
             {match rand::gen_range::<i32>(1..3) {
-                1 => rsx!(cx, h1 { "big" })
-                2 => rsx!(cx, h2 { "medium" })
-                _ => rsx!(cx, h3 { "small" })
+                1 => render!(h1 { "big" })
+                2 => render!(h2 { "medium" })
+                _ => render!(h3 { "small" })
             }}
 
             // Optionals

+ 40 - 38
examples/file_explorer.rs

@@ -21,46 +21,48 @@ fn main() {
 fn app(cx: Scope) -> Element {
     let files = use_ref(&cx, Files::new);
 
-    rsx!(cx, div {
-        link { href:"https://fonts.googleapis.com/icon?family=Material+Icons", rel:"stylesheet", }
-        style { include_str!("./assets/fileexplorer.css") }
-        header {
-            i { class: "material-icons icon-menu", "menu" }
-            h1 { "Files: ", files.read().current() }
-            span { }
-            i { class: "material-icons", onclick: move |_| files.write().go_up(), "logout" }
-        }
-        main {
-            files.read().path_names.iter().enumerate().map(|(dir_id, path)| {
-                let path_end = path.split('/').last().unwrap_or(path.as_str());
-                let icon_type = if path_end.contains('.') {
-                    "description"
-                } else {
-                    "folder"
-                };
-                rsx! (
-                    div {
-                        class: "folder",
-                        key: "{path}",
-                        i { class: "material-icons",
-                            onclick: move |_| files.write().enter_dir(dir_id),
-                            "{icon_type}"
-                            p { class: "cooltip", "0 folders / 0 files" }
+    render! {
+        div {
+            link { href:"https://fonts.googleapis.com/icon?family=Material+Icons", rel:"stylesheet", }
+            style { include_str!("./assets/fileexplorer.css") }
+            header {
+                i { class: "material-icons icon-menu", "menu" }
+                h1 { "Files: ", files.read().current() }
+                span { }
+                i { class: "material-icons", onclick: move |_| files.write().go_up(), "logout" }
+            }
+            main {
+                files.read().path_names.iter().enumerate().map(|(dir_id, path)| {
+                    let path_end = path.split('/').last().unwrap_or(path.as_str());
+                    let icon_type = if path_end.contains('.') {
+                        "description"
+                    } else {
+                        "folder"
+                    };
+                    rsx! (
+                        div {
+                            class: "folder",
+                            key: "{path}",
+                            i { class: "material-icons",
+                                onclick: move |_| files.write().enter_dir(dir_id),
+                                "{icon_type}"
+                                p { class: "cooltip", "0 folders / 0 files" }
+                            }
+                            h1 { "{path_end}" }
+                        }
+                    )
+                }),
+                files.read().err.as_ref().map(|err| {
+                    rsx! (
+                        div {
+                            code { "{err}" }
+                            button { onclick: move |_| files.write().clear_err(), "x" }
                         }
-                        h1 { "{path_end}" }
-                    }
-                )
-            }),
-            files.read().err.as_ref().map(|err| {
-                rsx! (
-                    div {
-                        code { "{err}" }
-                        button { onclick: move |_| files.write().clear_err(), "x" }
-                    }
-                )
-            })
+                    )
+                })
+            }
         }
-    })
+    }
 }
 
 struct Files {

+ 4 - 4
examples/svg.rs

@@ -9,7 +9,7 @@ fn main() {
 fn app(cx: Scope) -> Element {
     let val = use_state(&cx, || 5);
 
-    cx.render(rsx! {
+    render! {
         div {
             user_select: "none",
             webkit_user_select: "none",
@@ -31,7 +31,7 @@ fn app(cx: Scope) -> Element {
                 }
             }
         }
-    })
+    }
 }
 
 #[derive(Props)]
@@ -78,7 +78,7 @@ pub fn Die<'a>(cx: Scope<'a, DieProps<'a>>) -> Element {
             })
         });
 
-    rsx!(cx,
+    render! {
       svg {
         onclick: move |e| cx.props.onclick.call(e),
         prevent_default: "onclick",
@@ -97,5 +97,5 @@ pub fn Die<'a>(cx: Scope<'a, DieProps<'a>>) -> Element {
 
         dots
       }
-    )
+    }
 }

+ 2 - 2
notes/README.md

@@ -101,7 +101,7 @@ fn example(cx: Scope) -> Element {
     // both of these are equivalent
     cx.render(rsx!("hello world"))
 
-    rsx!(cx, "hello world!")
+    render!("hello world!")
 }
 ```
 
@@ -235,7 +235,7 @@ use hooks to define state and modify it from within listeners.
 fn app(cx: Scope) -> Element {
     let name = use_state(&cx, || "world");
 
-    rsx!(cx, "hello {name}!")
+    render!("hello {name}!")
 }
 ```
 

+ 20 - 0
packages/core-macro/src/lib.rs

@@ -72,6 +72,26 @@ pub fn rsx(s: TokenStream) -> TokenStream {
     }
 }
 
+/// The render! macro makes it easy for developers to write jsx-style markup in their components.
+///
+/// The render macro automatically renders rsx - making it unhygenic.
+///
+/// ## Complete Reference Guide:
+/// ```ignore
+#[doc = include_str!("../../../examples/rsx_usage.rs")]
+/// ```
+#[proc_macro]
+pub fn render(s: TokenStream) -> TokenStream {
+    match syn::parse::<rsx::CallBody>(s) {
+        Err(err) => err.to_compile_error().into(),
+        Ok(body) => quote::quote! {
+            cx.render(#body)
+        }
+        .into_token_stream()
+        .into(),
+    }
+}
+
 /// Derive props for a component within the component definition.
 ///
 /// This macro provides a simple transformation from `Scope<{}>` to `Scope<P>`,

+ 1 - 1
packages/core/README.md

@@ -7,7 +7,7 @@ To build new apps with Dioxus or to extend the ecosystem with new hooks or compo
 
 ```rust, ignore
 fn app(cx: Scope) -> Element {
-    rsx!(cx, div { "hello world" })
+    render!(div { "hello world" })
 }
 
 fn main() {

+ 1 - 1
packages/core/src/events.rs

@@ -32,7 +32,7 @@ impl BubbleState {
 /// # Example
 /// ```rust, ignore
 /// fn App(cx: Scope) -> Element {
-///     rsx!(cx, div {
+///     render!(div {
 ///         onclick: move |_| println!("Clicked!")
 ///     })
 /// }

+ 5 - 5
packages/core/src/scopes.rs

@@ -528,7 +528,7 @@ impl ScopeState {
     ///
     /// ```rust, ignore
     /// fn App(cx: Scope) -> Element {
-    ///     rsx!(cx, div { "Subtree {id}"})
+    ///     render!(div { "Subtree {id}"})
     /// };
     /// ```
     ///
@@ -659,12 +659,12 @@ impl ScopeState {
     ///
     /// static App: Component = |cx| {
     ///     cx.use_hook(|| cx.provide_context(SharedState("world")));
-    ///     rsx!(cx, Child {})
+    ///     render!(Child {})
     /// }
     ///
     /// static Child: Component = |cx| {
     ///     let state = cx.consume_state::<SharedState>();
-    ///     rsx!(cx, div { "hello {state.0}" })
+    ///     render!(div { "hello {state.0}" })
     /// }
     /// ```
     pub fn provide_context<T: 'static + Clone>(&self, value: T) -> T {
@@ -685,12 +685,12 @@ impl ScopeState {
     ///
     /// static App: Component = |cx| {
     ///     cx.use_hook(|| cx.provide_root_context(SharedState("world")));
-    ///     rsx!(cx, Child {})
+    ///     render!(Child {})
     /// }
     ///
     /// static Child: Component = |cx| {
     ///     let state = cx.consume_state::<SharedState>();
-    ///     rsx!(cx, div { "hello {state.0}" })
+    ///     render!(div { "hello {state.0}" })
     /// }
     /// ```
     pub fn provide_root_context<T: 'static + Clone>(&self, value: T) -> T {

+ 4 - 4
packages/core/src/virtual_dom.rs

@@ -597,7 +597,7 @@ impl VirtualDom {
     ///
     /// ```rust, ignore
     /// fn Base(cx: Scope) -> Element {
-    ///     rsx!(cx, div {})
+    ///     render!(div {})
     /// }
     ///
     /// let dom = VirtualDom::new(Base);
@@ -617,7 +617,7 @@ impl VirtualDom {
     ///
     /// ```rust, ignore
     /// fn Base(cx: Scope) -> Element {
-    ///     rsx!(cx, div {})
+    ///     render!(div {})
     /// }
     ///
     /// let dom = VirtualDom::new(Base);
@@ -639,7 +639,7 @@ impl VirtualDom {
     ///
     /// ```rust, ignore
     /// fn Base(cx: Scope) -> Element {
-    ///     rsx!(cx, div {})
+    ///     render!(div {})
     /// }
     ///
     /// let dom = VirtualDom::new(Base);
@@ -662,7 +662,7 @@ impl VirtualDom {
     ///
     /// ```rust, ignore
     /// fn Base(cx: Scope) -> Element {
-    ///     rsx!(cx, div {})
+    ///     render!(div {})
     /// }
     ///
     /// let dom = VirtualDom::new(Base);

+ 1 - 1
packages/dioxus/benches/jsframework.rs

@@ -23,7 +23,7 @@ fn create_rows(c: &mut Criterion) {
     static App: Component = |cx| {
         let mut rng = SmallRng::from_entropy();
 
-        rsx!(cx, table {
+        render!(table {
             tbody {
                 (0..10_000_usize).map(|f| {
                     let label = Label::new(&mut rng);

+ 1 - 1
packages/dioxus/src/lib.rs

@@ -26,7 +26,7 @@ pub mod prelude {
     pub use dioxus_core::prelude::*;
 
     #[cfg(feature = "macro")]
-    pub use dioxus_core_macro::{format_args_f, inline_props, rsx, Props};
+    pub use dioxus_core_macro::{format_args_f, inline_props, render, rsx, Props};
 
     #[cfg(feature = "html")]
     pub use dioxus_html as dioxus_elements;

+ 1 - 1
packages/dioxus/tests/diffing.rs

@@ -9,7 +9,7 @@
 use dioxus::prelude::*;
 
 fn new_dom() -> VirtualDom {
-    VirtualDom::new(|cx| rsx!(cx, "hi"))
+    VirtualDom::new(|cx| render!("hi"))
 }
 
 use dioxus_core::DomEdit::*;

+ 1 - 1
packages/dioxus/tests/earlyabort.rs

@@ -28,7 +28,7 @@ fn test_early_abort() {
             return None;
         }
 
-        rsx!(cx, div { "Hello, world!" })
+        render!(div { "Hello, world!" })
     };
 
     let mut dom = new_dom(app, ());

+ 16 - 17
packages/dioxus/tests/miri_stress.rs

@@ -54,7 +54,7 @@ fn test_memory_leak() {
     }
 
     fn BorrowedChild<'a>(cx: Scope<'a, BorrowedProps<'a>>) -> Element {
-        rsx!(cx, div {
+        render!(div {
             "goodbye {cx.props.na}"
             Child {}
             Child {}
@@ -62,7 +62,7 @@ fn test_memory_leak() {
     }
 
     fn Child(cx: Scope) -> Element {
-        rsx!(cx, div { "goodbye world" })
+        render!(div { "goodbye world" })
     }
 
     let mut dom = new_dom(app, ());
@@ -101,7 +101,7 @@ fn memo_works_properly() {
     }
 
     fn Child(cx: Scope<ChildProps>) -> Element {
-        rsx!(cx, div { "goodbye world" })
+        render!(div { "goodbye world" })
     }
 
     let mut dom = new_dom(app, ());
@@ -133,7 +133,7 @@ fn free_works_on_root_props() {
     }
 
     fn Child(cx: Scope<ChildProps>) -> Element {
-        rsx!(cx, "child {cx.props.a}")
+        render!("child {cx.props.a}")
     }
 
     struct Custom {
@@ -165,7 +165,7 @@ fn free_works_on_borrowed() {
 
     fn Child<'a>(cx: Scope<'a, ChildProps<'a>>) -> Element {
         dbg!("rendering child");
-        rsx!(cx, "child {cx.props.a}, {cx.props.b}")
+        render!("child {cx.props.a}, {cx.props.b}")
     }
 
     impl Drop for ChildProps<'_> {
@@ -193,7 +193,7 @@ fn free_works_on_root_hooks() {
 
     fn app(cx: Scope) -> Element {
         let name = cx.use_hook(|| Droppable(String::from("asd")));
-        rsx!(cx, div { "{name.0}" })
+        render!(div { "{name.0}" })
     }
 
     let mut dom = new_dom(app, ());
@@ -208,9 +208,9 @@ fn old_props_arent_stale() {
         *cnt += 1;
 
         if *cnt == 1 {
-            rsx!(cx, div { Child { a: "abcdef".to_string() } })
+            render!(div { Child { a: "abcdef".to_string() } })
         } else {
-            rsx!(cx, div { Child { a: "abcdef".to_string() } })
+            render!(div { Child { a: "abcdef".to_string() } })
         }
     }
 
@@ -220,7 +220,7 @@ fn old_props_arent_stale() {
     }
     fn Child(cx: Scope<ChildProps>) -> Element {
         dbg!("rendering child", &cx.props.a);
-        rsx!(cx, div { "child {cx.props.a}" })
+        render!(div { "child {cx.props.a}" })
     }
 
     let mut dom = new_dom(app, ());
@@ -250,7 +250,7 @@ fn old_props_arent_stale() {
 #[test]
 fn basic() {
     fn app(cx: Scope) -> Element {
-        rsx!(cx, div {
+        render!(div {
             Child { a: "abcdef".to_string() }
         })
     }
@@ -262,7 +262,7 @@ fn basic() {
 
     fn Child(cx: Scope<ChildProps>) -> Element {
         dbg!("rendering child", &cx.props.a);
-        rsx!(cx, div { "child {cx.props.a}" })
+        render!(div { "child {cx.props.a}" })
     }
 
     let mut dom = new_dom(app, ());
@@ -290,7 +290,7 @@ fn leak_thru_children() {
 
     #[inline_props]
     fn Child(cx: Scope, name: String) -> Element {
-        rsx!(cx, div { "child {name}" })
+        render!(div { "child {name}" })
     }
 
     let mut dom = new_dom(app, ());
@@ -315,8 +315,7 @@ fn test_pass_thru() {
     }
 
     fn NavMenu(cx: Scope) -> Element {
-        rsx!(cx,
-            NavBrand {}
+        render!(            NavBrand {}
             div {
                 NavStart {}
                 NavEnd {}
@@ -325,15 +324,15 @@ fn test_pass_thru() {
     }
 
     fn NavBrand(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     fn NavStart(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     fn NavEnd(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     #[inline_props]

+ 1 - 1
packages/dioxus/tests/passthru.rs

@@ -10,7 +10,7 @@
 use dioxus::prelude::*;
 
 fn new_dom() -> VirtualDom {
-    VirtualDom::new(|cx| rsx!(cx, "hi"))
+    VirtualDom::new(|cx| render!("hi"))
 }
 
 use dioxus_core::DomEdit::*;

+ 1 - 1
packages/dioxus/tests/vdom_rebuild.rs

@@ -15,7 +15,7 @@ use dioxus_core::DomEdit::*;
 
 #[test]
 fn app_runs() {
-    static App: Component = |cx| rsx!(cx, div{"hello"} );
+    static App: Component = |cx| render!(div{"hello"} );
 
     let mut vdom = VirtualDom::new(App);
     let edits = vdom.rebuild();

+ 1 - 1
packages/native-core-macro/tests/called_minimally_on_build.rs

@@ -67,7 +67,7 @@ macro_rules! test_state{
         fn state_reduce_initally_called_minimally() {
             #[allow(non_snake_case)]
             fn Base(cx: Scope) -> Element {
-                rsx!(cx, div {
+                render!(div {
                     div{
                         div{
                             p{}

+ 2 - 2
packages/native-core-macro/tests/change_nodes.rs

@@ -13,7 +13,7 @@ struct Empty {}
 fn remove_node() {
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     let vdom = VirtualDom::new(Base);
@@ -87,7 +87,7 @@ fn remove_node() {
 fn add_node() {
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     let vdom = VirtualDom::new(Base);

+ 2 - 2
packages/native-core-macro/tests/initial_build.rs

@@ -16,7 +16,7 @@ fn initial_build_simple() {
 
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     let vdom = VirtualDom::new(Base);
@@ -47,7 +47,7 @@ fn initial_build_simple() {
 fn initial_build_with_children() {
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     let vdom = VirtualDom::new(Base);

+ 4 - 4
packages/native-core-macro/tests/peristant_iterator.rs

@@ -15,7 +15,7 @@ struct Empty {}
 fn traverse() {
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
     let vdom = VirtualDom::new(Base);
     let mutations = vdom.create_vnodes(rsx! {
@@ -108,7 +108,7 @@ fn traverse() {
 fn persist_removes() {
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
     let vdom = VirtualDom::new(Base);
     let (build, update) = vdom.diff_lazynodes(
@@ -196,7 +196,7 @@ fn persist_removes() {
 fn persist_instertions_before() {
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
     let vdom = VirtualDom::new(Base);
     let (build, update) = vdom.diff_lazynodes(
@@ -262,7 +262,7 @@ fn persist_instertions_before() {
 fn persist_instertions_after() {
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
     let vdom = VirtualDom::new(Base);
     let (build, update) = vdom.diff_lazynodes(

+ 4 - 4
packages/native-core-macro/tests/update_state.rs

@@ -163,7 +163,7 @@ struct StateTester {
 fn state_initial() {
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {
+        render!(div {
             p{}
             h1{}
         })
@@ -240,7 +240,7 @@ fn state_initial() {
 fn state_reduce_parent_called_minimally_on_update() {
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {
+        render!(div {
             width: "100%",
             div{
                 div{
@@ -307,7 +307,7 @@ fn state_reduce_parent_called_minimally_on_update() {
 fn state_reduce_child_called_minimally_on_update() {
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {
+        render!(div {
             div{
                 div{
                     p{
@@ -435,7 +435,7 @@ impl NodeDepState<()> for CDepCallCounter {
 fn dependancies_order_independant() {
     #[allow(non_snake_case)]
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {
+        render!(div {
             width: "100%",
             p{
                 "hello"

+ 9 - 32
packages/rsx/src/lib.rs

@@ -30,25 +30,15 @@ use proc_macro2::TokenStream as TokenStream2;
 use quote::{quote, ToTokens, TokenStreamExt};
 use syn::{
     parse::{Parse, ParseStream},
-    Ident, Result, Token,
+    Result, Token,
 };
 
 pub struct CallBody {
-    pub custom_context: Option<Ident>,
     pub roots: Vec<BodyNode>,
 }
 
 impl Parse for CallBody {
     fn parse(input: ParseStream) -> Result<Self> {
-        let custom_context = if input.peek(Ident) && input.peek2(Token![,]) {
-            let name = input.parse::<Ident>()?;
-            input.parse::<Token![,]>()?;
-
-            Some(name)
-        } else {
-            None
-        };
-
         let mut roots = Vec::new();
 
         while !input.is_empty() {
@@ -61,10 +51,7 @@ impl Parse for CallBody {
             roots.push(node);
         }
 
-        Ok(Self {
-            custom_context,
-            roots,
-        })
+        Ok(Self { roots })
     }
 }
 
@@ -79,22 +66,12 @@ impl ToTokens for CallBody {
             quote! { __cx.fragment_root([ #(#childs),* ]) }
         };
 
-        match &self.custom_context {
-            // The `in cx` pattern allows directly rendering
-            Some(ident) => out_tokens.append_all(quote! {
-                #ident.render(LazyNodes::new(move |__cx: NodeFactory| -> VNode {
-                    use dioxus_elements::{GlobalAttributes, SvgAttributes};
-                    #inner
-                }))
-            }),
-
-            // Otherwise we just build the LazyNode wrapper
-            None => out_tokens.append_all(quote! {
-                LazyNodes::new(move |__cx: NodeFactory| -> VNode {
-                    use dioxus_elements::{GlobalAttributes, SvgAttributes};
-                    #inner
-                })
-            }),
-        };
+        // Otherwise we just build the LazyNode wrapper
+        out_tokens.append_all(quote! {
+            LazyNodes::new(move |__cx: NodeFactory| -> VNode {
+                use dioxus_elements::{GlobalAttributes, SvgAttributes};
+                #inner
+            })
+        })
     }
 }

+ 1 - 4
packages/rsx_interpreter/src/captuered_context.rs

@@ -30,10 +30,7 @@ impl CapturedContextBuilder {
     }
 
     pub fn from_call_body(body: CallBody) -> Result<Self> {
-        let mut new = Self {
-            custom_context: body.custom_context,
-            ..Default::default()
-        };
+        let mut new = Self::default();
         for node in body.roots {
             new.extend(Self::find_captured(node)?);
         }

+ 8 - 8
packages/rsx_interpreter/tests/render.rs

@@ -4,7 +4,7 @@ use dioxus::prelude::*;
 #[allow(non_snake_case)]
 fn render_basic() {
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     let dom = VirtualDom::new(Base);
@@ -44,7 +44,7 @@ fn render_basic() {
 #[allow(non_snake_case)]
 fn render_nested() {
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     let dom = VirtualDom::new(Base);
@@ -96,7 +96,7 @@ fn render_nested() {
 #[allow(non_snake_case)]
 fn render_custom_attribute() {
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     let dom = VirtualDom::new(Base);
@@ -144,11 +144,11 @@ fn render_custom_attribute() {
 #[allow(non_snake_case)]
 fn render_component() {
     fn Comp(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     let dom = VirtualDom::new(Base);
@@ -200,7 +200,7 @@ fn render_component() {
 #[allow(non_snake_case)]
 fn render_iterator() {
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     let dom = VirtualDom::new(Base);
@@ -254,7 +254,7 @@ fn render_iterator() {
 #[allow(non_snake_case)]
 fn render_captured_variable() {
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     let dom = VirtualDom::new(Base);
@@ -309,7 +309,7 @@ fn render_captured_variable() {
 #[allow(non_snake_case)]
 fn render_listener() {
     fn Base(cx: Scope) -> Element {
-        rsx!(cx, div {})
+        render!(div {})
     }
 
     let dom = VirtualDom::new(Base);

+ 2 - 2
packages/web/src/lib.rs

@@ -89,7 +89,7 @@ mod util;
 /// }
 ///
 /// static App: Component = |cx| {
-///     rsx!(cx, div {"hello world"})
+///     render!(div {"hello world"})
 /// }
 /// ```
 pub fn launch(root_component: Component) {
@@ -140,7 +140,7 @@ pub fn launch_cfg(root: Component, config: Config) {
 /// }
 ///
 /// static App: Component<RootProps> = |cx| {
-///     rsx!(cx, div {"hello {cx.props.name}"})
+///     render!(div {"hello {cx.props.name}"})
 /// }
 /// ```
 pub fn launch_with_props<T>(root_component: Component<T>, root_properties: T, config: Config)