Procházet zdrojové kódy

Feat: accept closures directly in handler

Jonathan Kelley před 4 roky
rodič
revize
f225030506
2 změnil soubory, kde provedl 54 přidání a 20 odebrání
  1. 24 6
      packages/core-macro/src/rsxt.rs
  2. 30 14
      packages/web/examples/rsxt.rs

+ 24 - 6
packages/core-macro/src/rsxt.rs

@@ -58,7 +58,8 @@ impl Parse for RsxRender {
         // cannot accept multiple elements
         // can only accept one root per component
         // fragments can be used as
-        // _ { content }
+        // todo
+        // enable fragements by autocoerrcing into list
         let el: Element = input.parse()?;
         Ok(Self { el })
     }
@@ -286,11 +287,22 @@ impl Parse for Attr {
         let ty = if name_str.starts_with("on") {
             // remove the "on" bit
             name = Ident::new(&name_str.trim_start_matches("on"), name.span());
-            let content;
-            syn::braced!(content in s);
-            // AttrType::Value(content.parse()?)
-            AttrType::Event(content.parse()?)
-        // AttrType::Event(content.parse()?)
+
+            if s.peek(token::Brace) {
+                let content;
+                syn::braced!(content in s);
+
+                // Try to parse directly as a closure
+                let fork = content.fork();
+                if let Ok(event) = fork.parse::<ExprClosure>() {
+                    content.advance_to(&fork);
+                    AttrType::Event(event)
+                } else {
+                    AttrType::Tok(content.parse()?)
+                }
+            } else {
+                AttrType::Event(s.parse()?)
+            }
         } else {
             let lit_str = if name_str == "style" && s.peek(token::Brace) {
                 // special-case to deal with literal styles.
@@ -340,6 +352,11 @@ impl ToTokens for ToToksCtx<&Attr> {
                     .on(#name, #event)
                 });
             }
+            AttrType::Tok(exp) => {
+                tokens.append_all(quote! {
+                    .on(#name, #exp)
+                });
+            }
         }
     }
 }
@@ -347,6 +364,7 @@ impl ToTokens for ToToksCtx<&Attr> {
 enum AttrType {
     Value(MaybeExpr<LitStr>),
     Event(ExprClosure),
+    Tok(Expr),
     // todo Bool(MaybeExpr<LitBool>)
 }
 

+ 30 - 14
packages/web/examples/rsxt.rs

@@ -1,8 +1,12 @@
 use bumpalo::Bump;
-use dioxus::prelude::*;
+use dioxus::{events::EventTrigger, prelude::*};
 use dioxus_core as dioxus;
 use dioxus_web::WebsysRenderer;
 
+// creates a proxy address that gets transpiled at compile time
+// all asset ids are shuttled through the renderer
+// static IMG: ImgAsset = dioxus_asset!("");
+
 fn main() {
     wasm_logger::init(wasm_logger::Config::new(log::Level::Debug));
     console_error_panic_hook::set_once();
@@ -12,26 +16,38 @@ fn main() {
 static Example: FC<()> = |ctx, props| {
     let (name, set_name) = use_state(&ctx, || "...?");
 
+    let handler = move |_| set_name("jill");
+
     ctx.render(rsx! {
-        div { class: "py-12 px-4 text-center w-full max-w-2xl mx-auto"
-            span { "Dioxus Example: Jack and Jill",
+        div { 
+            class: "py-12 px-4 text-center w-full max-w-2xl mx-auto"
+            span { 
                 class: "text-sm font-semibold"
+                "Dioxus Example: Jack and Jill"
             }
-            h2 { "Hello, {name}", 
+            h2 { 
                 class: "text-5xl mt-2 mb-6 leading-tight font-semibold font-heading"   
+                "Hello, {name}"
             }
-            div {
-                button { "Jack!"
-                    class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
-                    onclick: {move |_| set_name("jack")}
-                }
-                
-                button { "Jill!"
-                    class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
-                    onclick: {move |_| set_name("jill")}
-                    onclick: {move |_| set_name("jill")}
+            button {  
+                class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
+                onmouseover: move |_| set_name("jack") 
+                "Jack!"
+            }
+            button {  
+                class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow"
+                onfocus: {handler}
+                onmouseover: move |_| {
+                    set_name("jill");
                 }
+                "Jill!"
             }
         }
     })
 };
+
+
+
+
+
+// onclick: {move |_| set_name("jill")}