Feat: accept closures directly in handler
This commit is contained in:
1 parent
07f671c8e1
commit
f225030506
2 files changed
+54
-20
No files matched your search
@@ -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>)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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, || "...?");
|
||||||
|
|
||||||
|
let handler = move |_| set_name("jill");
|
||||||
|
|
||||||
ctx.render(rsx! {
|
ctx.render(rsx! {
|
||||||
div { class: "py-12 px-4 text-center w-full max-w-2xl mx-auto"
|
div {
|
||||||
span { "Dioxus Example: Jack and Jill",
|
class: "py-12 px-4 text-center w-full max-w-2xl mx-auto"
|
||||||
|
span {
|
||||||
class: "text-sm font-semibold"
|
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"
|
class: "text-5xl mt-2 mb-6 leading-tight font-semibold font-heading"
|
||||||
|
"Hello, {name}"
|
||||||
}
|
}
|
||||||
div {
|
button {
|
||||||
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"
|
||||||
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")
|
||||||
onclick: {move |_| set_name("jack")}
|
"Jack!"
|
||||||
}
|
}
|
||||||
|
button {
|
||||||
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"
|
||||||
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}
|
||||||
onclick: {move |_| set_name("jill")}
|
onmouseover: move |_| {
|
||||||
onclick: {move |_| set_name("jill")}
|
set_name("jill");
|
||||||
}
|
}
|
||||||
|
"Jill!"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// onclick: {move |_| set_name("jill")}
|
||||||
Reference in new issue
Block a user