From f225030506967415a21f4af0372477cb5224ee7c Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Tue, 2 Mar 2021 01:24:53 -0500 Subject: [PATCH] Feat: accept closures directly in handler --- packages/core-macro/src/rsxt.rs | 30 +++++++++++++++++----- packages/web/examples/rsxt.rs | 44 ++++++++++++++++++++++----------- 2 files changed, 54 insertions(+), 20 deletions(-) diff --git a/packages/core-macro/src/rsxt.rs b/packages/core-macro/src/rsxt.rs index a8edd99a1..cad534d58 100644 --- a/packages/core-macro/src/rsxt.rs +++ b/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::() { + 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), Event(ExprClosure), + Tok(Expr), // todo Bool(MaybeExpr) } diff --git a/packages/web/examples/rsxt.rs b/packages/web/examples/rsxt.rs index 2ec4e52bf..e5fa19edc 100644 --- a/packages/web/examples/rsxt.rs +++ b/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")}