Feat: accept closures directly in handler

This commit is contained in:
Jonathan Kelley committed 2021-03-02 01:24:53 -05:00
1 parent 07f671c8e1
commit f225030506
2 files changed
+58 -24

No files matched your search

+24 -6
View File
@@ -58,7 +58,8 @@ impl Parse for RsxRender {
// cannot accept multiple elements // cannot accept multiple elements
// can only accept one root per component // can only accept one root per component
// fragments can be used as // fragments can be used as
// _ { content } // todo
// enable fragements by autocoerrcing into list
let el: Element = input.parse()?; let el: Element = input.parse()?;
Ok(Self { el }) Ok(Self { el })
} }
@@ -286,11 +287,22 @@ impl Parse for Attr {
let ty = if name_str.starts_with("on") { let ty = if name_str.starts_with("on") {
// remove the "on" bit // remove the "on" bit
name = Ident::new(&name_str.trim_start_matches("on"), name.span()); name = Ident::new(&name_str.trim_start_matches("on"), name.span());
let content;
syn::braced!(content in s); if s.peek(token::Brace) {
// AttrType::Value(content.parse()?) let content;
AttrType::Event(content.parse()?) syn::braced!(content in s);
// AttrType::Event(content.parse()?)
// 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 { } else {
let lit_str = if name_str == "style" && s.peek(token::Brace) { let lit_str = if name_str == "style" && s.peek(token::Brace) {
// special-case to deal with literal styles. // special-case to deal with literal styles.
@@ -340,6 +352,11 @@ impl ToTokens for ToToksCtx<&Attr> {
.on(#name, #event) .on(#name, #event)
}); });
} }
AttrType::Tok(exp) => {
tokens.append_all(quote! {
.on(#name, #exp)
});
}
} }
} }
} }
@@ -347,6 +364,7 @@ impl ToTokens for ToToksCtx<&Attr> {
enum AttrType { enum AttrType {
Value(MaybeExpr<LitStr>), Value(MaybeExpr<LitStr>),
Event(ExprClosure), Event(ExprClosure),
Tok(Expr),
// todo Bool(MaybeExpr<LitBool>) // todo Bool(MaybeExpr<LitBool>)
} }
+34 -18
View File
@@ -1,8 +1,12 @@
use bumpalo::Bump; use bumpalo::Bump;
use dioxus::prelude::*; use dioxus::{events::EventTrigger, prelude::*};
use dioxus_core as dioxus; use dioxus_core as dioxus;
use dioxus_web::WebsysRenderer; 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() { fn main() {
wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); wasm_logger::init(wasm_logger::Config::new(log::Level::Debug));
console_error_panic_hook::set_once(); console_error_panic_hook::set_once();
@@ -12,26 +16,38 @@ fn main() {
static Example: FC<()> = |ctx, props| { static Example: FC<()> = |ctx, props| {
let (name, set_name) = use_state(&ctx, || "...?"); let (name, set_name) = use_state(&ctx, || "...?");
ctx.render(rsx! { let handler = move |_| set_name("jill");
div { class: "py-12 px-4 text-center w-full max-w-2xl mx-auto"
span { "Dioxus Example: Jack and Jill",
class: "text-sm font-semibold"
}
h2 { "Hello, {name}",
class: "text-5xl mt-2 mb-6 leading-tight font-semibold font-heading"
}
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!" ctx.render(rsx! {
class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow" div {
onclick: {move |_| set_name("jill")} class: "py-12 px-4 text-center w-full max-w-2xl mx-auto"
onclick: {move |_| set_name("jill")} span {
class: "text-sm font-semibold"
"Dioxus Example: Jack and Jill"
}
h2 {
class: "text-5xl mt-2 mb-6 leading-tight font-semibold font-heading"
"Hello, {name}"
}
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")}