wip: move some examples around

This commit is contained in:
Jonathan Kelley 2021-07-07 16:19:10 -04:00
parent cca7c5fc3a
commit 98a09339fd
70 changed files with 111 additions and 117 deletions

View File

@ -60,3 +60,4 @@ wasm
7ns 7ns
attr attr
derefed derefed
Tokio

View File

@ -12,7 +12,7 @@ Your component today might look something like this:
```rust ```rust
fn Comp(cx: Context<()>) -> VNode { fn Comp(cx: Context<()>) -> VNode {
let (title, set_title) = use_state(&cx, || "Title".to_string()); let (title, set_title) = use_state(cx, || "Title".to_string());
cx.render(rsx!{ cx.render(rsx!{
input { input {
value: title, value: title,
@ -26,7 +26,7 @@ This component is fairly straightforward - the input updates its own value on ev
```rust ```rust
fn Comp(cx: Context<()>) -> VNode { fn Comp(cx: Context<()>) -> VNode {
let (title, set_title) = use_state(&cx, || "Title".to_string()); let (title, set_title) = use_state(cx, || "Title".to_string());
cx.render(rsx!{ cx.render(rsx!{
div { div {
input { input {

View File

@ -16,7 +16,7 @@ fn main() {
} }
static App: FC<()> = |cx| { static App: FC<()> = |cx| {
let (state, set_state) = use_state_classic(&cx, || 0); let (state, set_state) = use_state_classic(cx, || 0);
cx.render(rsx! { cx.render(rsx! {
div { div {
section { class: "py-12 px-4 text-center" section { class: "py-12 px-4 text-center"

View File

@ -28,9 +28,9 @@ enum Operator {
} }
static App: FC<()> = |cx| { static App: FC<()> = |cx| {
let (cur_val, set_cur_val) = use_state_classic(&cx, || 0.0_f64); let (cur_val, set_cur_val) = use_state_classic(cx, || 0.0_f64);
let (operator, set_operator) = use_state_classic(&cx, || None as Option<Operator>); let (operator, set_operator) = use_state_classic(cx, || None as Option<Operator>);
let (display_value, set_display_value) = use_state_classic(&cx, || "0".to_string()); let (display_value, set_display_value) = use_state_classic(cx, || "0".to_string());
let clear_display = display_value.eq("0"); let clear_display = display_value.eq("0");
let clear_text = if clear_display { "C" } else { "AC" }; let clear_text = if clear_display { "C" } else { "AC" };

View File

@ -12,7 +12,7 @@ fn main() {
} }
fn CustomA(cx: Context<()>) -> VNode { fn CustomA(cx: Context<()>) -> VNode {
let (val, set_val) = use_state_classic(&cx, || "abcdef".to_string() as String); let (val, set_val) = use_state_classic(cx, || "abcdef".to_string() as String);
cx.render(rsx! { cx.render(rsx! {
div { div {

View File

@ -10,7 +10,7 @@ fn main() {
} }
fn App(cx: Context<()>) -> VNode { fn App(cx: Context<()>) -> VNode {
let cansee = use_state(&cx, || false); let cansee = use_state(cx, || false);
rsx! { in cx, rsx! { in cx,
div { div {
"Shadow of the child:" "Shadow of the child:"

View File

@ -28,8 +28,8 @@ type RowList = im_rc::HashMap<usize, Rc<str>, FxBuildHasher>;
// type RowList = im_rc::HashMap<usize, Rc<str>, nohash_hasher::BuildNoHashHasher<usize>>; // type RowList = im_rc::HashMap<usize, Rc<str>, nohash_hasher::BuildNoHashHasher<usize>>;
static App: FC<()> = |cx| { static App: FC<()> = |cx| {
let (items, set_items) = use_state_classic(&cx, || RowList::default()); let (items, set_items) = use_state_classic(cx, || RowList::default());
let (selection, set_selection) = use_state_classic(&cx, || None as Option<usize>); let (selection, set_selection) = use_state_classic(cx, || None as Option<usize>);
let create_rendered_rows = move |from, num| move |_| set_items(create_row_list(from, num)); let create_rendered_rows = move |from, num| move |_| set_items(create_row_list(from, num));

View File

@ -15,7 +15,7 @@ fn main() {
// this is a component // this is a component
static Example: FC<()> = |cx| { static Example: FC<()> = |cx| {
let (event, set_event) = use_state_classic(&cx, || None); let (event, set_event) = use_state_classic(cx, || None);
let handler = move |evt| { let handler = move |evt| {
set_event(Some(evt)); set_event(Some(evt));

View File

@ -13,7 +13,7 @@ fn main() {
} }
static App: FC<()> = |cx| { static App: FC<()> = |cx| {
let (val, set_val) = use_state_classic(&cx, || "asd".to_string()); let (val, set_val) = use_state_classic(cx, || "asd".to_string());
cx.render(rsx! { cx.render(rsx! {
div { class: "max-w-lg max-w-xs bg-blue-800 shadow-2xl rounded-lg mx-auto text-center py-12 mt-4 rounded-xl" div { class: "max-w-lg max-w-xs bg-blue-800 shadow-2xl rounded-lg mx-auto text-center py-12 mt-4 rounded-xl"
@ -51,7 +51,7 @@ static Example: FC<()> = |cx| {
}; };
static UserInput: FC<()> = |cx| { static UserInput: FC<()> = |cx| {
let (val, set_val) = use_state_classic(&cx, || "asd".to_string()); let (val, set_val) = use_state_classic(cx, || "asd".to_string());
rsx! { in cx, rsx! { in cx,
div { class: "mb-4" div { class: "mb-4"

View File

@ -10,7 +10,7 @@ fn main() {
} }
static Example: FC<()> = |cx| { static Example: FC<()> = |cx| {
let (name, set_name) = use_state_classic(&cx, || "...?"); let (name, set_name) = use_state_classic(cx, || "...?");
log::debug!("Running component...."); log::debug!("Running component....");

View File

@ -10,7 +10,7 @@ fn main() {
} }
static Example: FC<()> = |cx| { static Example: FC<()> = |cx| {
let (name, set_name) = use_state_classic(&cx, || "...?"); let (name, set_name) = use_state_classic(cx, || "...?");
cx.render(rsx! { cx.render(rsx! {
section { class: "py-12 px-4 text-center" section { class: "py-12 px-4 text-center"
div { class: "w-full max-w-2xl mx-auto" div { class: "w-full max-w-2xl mx-auto"

View File

@ -15,7 +15,7 @@ fn main() {
} }
static App: FC<()> = |cx| { static App: FC<()> = |cx| {
let (contents, set_contents) = use_state_classic(&cx, || "asd"); let (contents, set_contents) = use_state_classic(cx, || "asd");
cx.render(rsx! { cx.render(rsx! {
div { div {

View File

@ -14,7 +14,7 @@ fn main() {
} }
static App: FC<()> = |cx| { static App: FC<()> = |cx| {
let (contents, set_contents) = use_state_classic(&cx, || "asd"); let (contents, set_contents) = use_state_classic(cx, || "asd");
cx.render(rsx! { cx.render(rsx! {
div { class: "flex items-center justify-center flex-col" div { class: "flex items-center justify-center flex-col"

View File

@ -27,9 +27,9 @@ pub struct TodoItem {
} }
static App: FC<()> = |cx| { static App: FC<()> = |cx| {
let (draft, set_draft) = use_state_classic(&cx, || "".to_string()); let (draft, set_draft) = use_state_classic(cx, || "".to_string());
let (filter, set_filter) = use_state_classic(&cx, || FilterState::All); let (filter, set_filter) = use_state_classic(cx, || FilterState::All);
let todos = use_state(&cx, || BTreeMap::<uuid::Uuid, TodoItem>::new()); let todos = use_state(cx, || BTreeMap::<uuid::Uuid, TodoItem>::new());
cx.render(rsx!( cx.render(rsx!(
div { div {
id: "app" id: "app"

View File

@ -28,7 +28,7 @@ struct ExampleProps {
} }
static Example: FC<ExampleProps> = |cx| { static Example: FC<ExampleProps> = |cx| {
let name = use_state(&cx, move || cx.initial_name); let name = use_state(cx, move || cx.initial_name);
cx.render(rsx! { cx.render(rsx! {
div { div {

View File

@ -26,9 +26,9 @@ pub struct TodoItem {
} }
pub fn App(cx: Context<()>) -> VNode { pub fn App(cx: Context<()>) -> VNode {
let (draft, set_draft) = use_state_classic(&cx, || "".to_string()); let (draft, set_draft) = use_state_classic(cx, || "".to_string());
let (todos, set_todos) = use_state_classic(&cx, || HashMap::<uuid::Uuid, Rc<TodoItem>>::new()); let (todos, set_todos) = use_state_classic(cx, || HashMap::<uuid::Uuid, Rc<TodoItem>>::new());
let (filter, set_filter) = use_state_classic(&cx, || FilterState::All); let (filter, set_filter) = use_state_classic(cx, || FilterState::All);
let filtered_todos = todos.iter().filter(move |(id, item)| match filter { let filtered_todos = todos.iter().filter(move |(id, item)| match filter {
FilterState::All => true, FilterState::All => true,
@ -100,7 +100,7 @@ pub struct TodoEntryProps {
} }
pub fn TodoEntry(cx: Context<TodoEntryProps>) -> VNode { pub fn TodoEntry(cx: Context<TodoEntryProps>) -> VNode {
let (is_editing, set_is_editing) = use_state_classic(&cx, || false); let (is_editing, set_is_editing) = use_state_classic(cx, || false);
let contents = ""; let contents = "";
let todo = TodoItem { let todo = TodoItem {
checked: false, checked: false,

View File

@ -8,7 +8,7 @@ pub struct TodoEntryProps {
} }
pub fn TodoEntry(cx: Context, props: &TodoEntryProps) -> VNode { pub fn TodoEntry(cx: Context, props: &TodoEntryProps) -> VNode {
let (is_editing, set_is_editing) = use_state(&cx, || false); let (is_editing, set_is_editing) = use_state(cx, || false);
let todo = use_atom_family(&cx, &TODOS, cx.id); let todo = use_atom_family(&cx, &TODOS, cx.id);
cx.render(rsx! ( cx.render(rsx! (

View File

@ -7,8 +7,8 @@ use crate::{
use dioxus_core::prelude::*; use dioxus_core::prelude::*;
pub fn TodoList(cx: Context<()>) -> VNode { pub fn TodoList(cx: Context<()>) -> VNode {
let (draft, set_draft) = use_state(&cx, || "".to_string()); let (draft, set_draft) = use_state(cx, || "".to_string());
let (todos, _) = use_state(&cx, || Vec::<TodoItem>::new()); let (todos, _) = use_state(cx, || Vec::<TodoItem>::new());
let filter = use_atom(&cx, &FILTER); let filter = use_atom(&cx, &FILTER);
cx.render(rsx! { cx.render(rsx! {

View File

@ -54,9 +54,9 @@ pub fn App(cx: Context<()>) -> VNode {
} }
pub fn TodoList(cx: Context<()>) -> VNode { pub fn TodoList(cx: Context<()>) -> VNode {
let (draft, set_draft) = use_state_classic(&cx, || "".to_string()); let (draft, set_draft) = use_state_classic(cx, || "".to_string());
let (todos, set_todos) = use_state_classic(&cx, || HashMap::<uuid::Uuid, Rc<TodoItem>>::new()); let (todos, set_todos) = use_state_classic(cx, || HashMap::<uuid::Uuid, Rc<TodoItem>>::new());
let (filter, set_filter) = use_state_classic(&cx, || FilterState::All); let (filter, set_filter) = use_state_classic(cx, || FilterState::All);
cx.render(rsx! { cx.render(rsx! {
div { div {
@ -103,7 +103,7 @@ pub struct TodoEntryProps {
} }
pub fn TodoEntry(cx: Context<TodoEntryProps>) -> VNode { pub fn TodoEntry(cx: Context<TodoEntryProps>) -> VNode {
let (is_editing, set_is_editing) = use_state_classic(&cx, || false); let (is_editing, set_is_editing) = use_state_classic(cx, || false);
let contents = ""; let contents = "";
let todo = TodoItem { let todo = TodoItem {
checked: false, checked: false,

View File

@ -74,7 +74,7 @@ impl TodoManager {
} }
pub fn TodoList(cx: Context<()>) -> VNode { pub fn TodoList(cx: Context<()>) -> VNode {
let draft = use_state(&cx, || "".to_string()); let draft = use_state(cx, || "".to_string());
let todos = use_read(&cx, &TODO_LIST); let todos = use_read(&cx, &TODO_LIST);
let filter = use_read(&cx, &FILTER); let filter = use_read(&cx, &FILTER);
@ -118,7 +118,7 @@ pub struct TodoEntryProps {
} }
pub fn TodoEntry(cx: Context, props: &TodoEntryProps) -> VNode { pub fn TodoEntry(cx: Context, props: &TodoEntryProps) -> VNode {
let (is_editing, set_is_editing) = use_state_classic(&cx, || false); let (is_editing, set_is_editing) = use_state_classic(cx, || false);
let todo = use_read(&cx, &TODO_LIST).get(&cx.id).unwrap(); let todo = use_read(&cx, &TODO_LIST).get(&cx.id).unwrap();
cx.render(rsx! ( cx.render(rsx! (

View File

@ -19,9 +19,9 @@ enum Operator {
} }
static App: FC<()> = |cx| { static App: FC<()> = |cx| {
let cur_val = use_state(&cx, || 0.0_f64); let cur_val = use_state(cx, || 0.0_f64);
let operator = use_state(&cx, || None as Option<Operator>); let operator = use_state(cx, || None as Option<Operator>);
let display_value = use_state(&cx, || "".to_string()); let display_value = use_state(cx, || "".to_string());
let clear_display = display_value.eq("0"); let clear_display = display_value.eq("0");
let clear_text = if clear_display { "C" } else { "AC" }; let clear_text = if clear_display { "C" } else { "AC" };

View File

@ -2,7 +2,7 @@ use dioxus::prelude::*;
fn main() {} fn main() {}
static Example: FC<()> = |cx| { static Example: FC<()> = |cx| {
let (g, set_g) = use_state_classic(&cx, || 0); let (g, set_g) = use_state_classic(cx, || 0);
let v = (0..10).map(move |f| { let v = (0..10).map(move |f| {
rsx!(li { rsx!(li {
onclick: move |_| set_g(10) onclick: move |_| set_g(10)

View File

@ -23,7 +23,7 @@ fn main() {
} }
static App: FC<()> = |cx| { static App: FC<()> = |cx| {
let calc = use_model(&cx, || Calculator::new()); let calc = use_model(cx, || Calculator::new());
let clear_display = calc.display_value.eq("0"); let clear_display = calc.display_value.eq("0");
let clear_text = if clear_display { "C" } else { "AC" }; let clear_text = if clear_display { "C" } else { "AC" };

View File

@ -3,13 +3,12 @@
//! The example from the README.md //! The example from the README.md
use dioxus::prelude::*; use dioxus::prelude::*;
fn main() { fn main() {
dioxus::web::launch(Example) dioxus::web::launch(Example)
} }
fn Example(cx: Context<()>) -> VNode { fn Example(cx: Context<()>) -> VNode {
let name = use_state(&cx, || "..?"); let name = use_state(cx, || "..?");
cx.render(rsx! { cx.render(rsx! {
h1 { "Hello, {name}" } h1 { "Hello, {name}" }
@ -17,21 +16,3 @@ fn Example(cx: Context<()>) -> VNode {
button { "?", onclick: move |_| name.set("Dioxus 🎉")} button { "?", onclick: move |_| name.set("Dioxus 🎉")}
}) })
} }
static Example2: FC<()> = |cx| {
let (g, set_g) = use_state_classic(&cx, || 0);
let v = (0..10).map(|f| {
dioxus::prelude::LazyNodes::new(move |__cx: &NodeFactory| {
__cx.element(dioxus_elements::li)
.listeners([dioxus::events::on::onclick(__cx, move |_| set_g(10))])
.finish()
})
});
cx.render(dioxus::prelude::LazyNodes::new(
move |__cx: &NodeFactory| {
__cx.element(dioxus_elements::div)
.children([__cx.fragment_from_iter(v)])
.finish()
},
))
};

View File

@ -8,7 +8,7 @@ fn main() {}
use dioxus::prelude::*; use dioxus::prelude::*;
pub static ExampleReducer: FC<()> = |cx| { pub static ExampleReducer: FC<()> = |cx| {
let (state, reduce) = use_reducer(&cx, PlayerState::new, PlayerState::reduce); let (state, reduce) = use_reducer(cx, PlayerState::new, PlayerState::reduce);
let is_playing = state.is_playing(); let is_playing = state.is_playing();

View File

@ -85,7 +85,7 @@ static AntipatternNestedFragments: FC<()> = |cx| {
/// recognize from the function signature, but Dioxus will not update the "live" version of state. Calling `set_state` /// recognize from the function signature, but Dioxus will not update the "live" version of state. Calling `set_state`
/// merely places a new value in the queue and schedules the component for a future update. /// merely places a new value in the queue and schedules the component for a future update.
static AntipaternRelyingOnSetState: FC<()> = |cx| { static AntipaternRelyingOnSetState: FC<()> = |cx| {
let (state, set_state) = use_state_classic(&cx, || "Hello world"); let (state, set_state) = use_state_classic(cx, || "Hello world");
set_state("New state"); set_state("New state");
// This will return false! `state` will *still* be "Hello world" // This will return false! `state` will *still* be "Hello world"
assert!(state == &"New state"); assert!(state == &"New state");
@ -126,7 +126,7 @@ static AntipatternMisusedHooks: FC<MisuedHooksProps> = |cx| {
if cx.should_render_state { if cx.should_render_state {
// do not place a hook in the conditional! // do not place a hook in the conditional!
// prefer to move it out of the conditional // prefer to move it out of the conditional
let (state, set_state) = use_state_classic(&cx, || "hello world"); let (state, set_state) = use_state_classic(cx, || "hello world");
rsx!(in cx, div { "{state}" }) rsx!(in cx, div { "{state}" })
} else { } else {
rsx!(in cx, div { "Not rendering state" }) rsx!(in cx, div { "Not rendering state" })

View File

@ -7,9 +7,6 @@ use dioxus::prelude::*;
fn main() {} fn main() {}
static Example: FC<()> = |cx| { static Example: FC<()> = |cx| {
cx.render(rsx! { //
div { cx.render(rsx! {})
}
})
}; };

View File

@ -2,7 +2,7 @@ use dioxus::prelude::*;
fn main() {} fn main() {}
static Example: FC<()> = |cx| { static Example: FC<()> = |cx| {
let (g, set_g) = use_state_classic(&cx, || 0); let (g, set_g) = use_state_classic(cx, || 0);
let v = (0..10).map(|f| { let v = (0..10).map(|f| {
rsx! { rsx! {
li { li {

View File

@ -11,7 +11,7 @@ fn main() {}
/// We can use `set_name` in multiple closures; the closures automatically *copy* the reference to set_name. /// We can use `set_name` in multiple closures; the closures automatically *copy* the reference to set_name.
static ButtonList: FC<()> = |cx| { static ButtonList: FC<()> = |cx| {
let (name, set_name) = use_state_classic(&cx, || "...?"); let (name, set_name) = use_state_classic(cx, || "...?");
let names = ["jack", "jill", "john", "jane"] let names = ["jack", "jill", "john", "jane"]
.iter() .iter()

View File

@ -47,7 +47,7 @@ fn main() {
const NONE_ELEMENT: Option<()> = None; const NONE_ELEMENT: Option<()> = None;
use baller::Baller; use baller::Baller;
use dioxus_core::prelude::*; use dioxus::prelude::*;
static Example: FC<()> = |cx| { static Example: FC<()> = |cx| {
let formatting = "formatting!"; let formatting = "formatting!";

View File

@ -16,7 +16,7 @@ fn main() {
} }
static App: FC<()> = |cx| { static App: FC<()> = |cx| {
let (count, set_count) = use_state_classic(&cx, || 0); let (count, set_count) = use_state_classic(cx, || 0);
cx.render(rsx! { cx.render(rsx! {
div { div {

View File

@ -17,4 +17,4 @@
- [] Implement controlled inputs for select and textarea - [] Implement controlled inputs for select and textarea
- [] ...somehow... noderefs.... - [] ...somehow... noderefs....
use_state(&cx, ) use_state(cx, )

View File

@ -39,7 +39,7 @@ impl Parse for HtmlRender {
return input.parse::<LitStr>()?.parse::<HtmlRender>(); return input.parse::<LitStr>()?.parse::<HtmlRender>();
} }
// let cx: Ident = s.parse()?; // let __cx: Ident = s.parse()?;
// s.parse::<Token![,]>()?; // s.parse::<Token![,]>()?;
// if elements are in an array, return a bumpalo::collections::Vec rather than a Node. // if elements are in an array, return a bumpalo::collections::Vec rather than a Node.
let kind = if input.peek(token::Bracket) { let kind = if input.peek(token::Bracket) {
@ -64,8 +64,8 @@ impl ToTokens for HtmlRender {
// create a lazy tree that accepts a bump allocator // create a lazy tree that accepts a bump allocator
let final_tokens = quote! { let final_tokens = quote! {
dioxus::prelude::LazyNodes::new(move |cx| { dioxus::prelude::LazyNodes::new(move |__cx| {
let bump = &cx.bump(); let bump = __cx.bump();
#new_toks #new_toks
}) })
@ -152,16 +152,18 @@ struct Element {
impl ToTokens for ToToksCtx<&Element> { impl ToTokens for ToToksCtx<&Element> {
fn to_tokens(&self, tokens: &mut TokenStream2) { fn to_tokens(&self, tokens: &mut TokenStream2) {
// let cx = self.cx; // let __cx = self.__cx;
let name = &self.inner.name.to_string(); let name = &self.inner.name;
// let name = &self.inner.name.to_string();
tokens.append_all(quote! { tokens.append_all(quote! {
dioxus::builder::ElementBuilder::new(cx, #name) __cx.element(dioxus_elements::#name)
// dioxus::builder::ElementBuilder::new( #name)
}); });
for attr in self.inner.attrs.iter() { for attr in self.inner.attrs.iter() {
self.recurse(attr).to_tokens(tokens); self.recurse(attr).to_tokens(tokens);
} }
if is_valid_svg_tag(name) { if is_valid_svg_tag(&name.to_string()) {
tokens.append_all(quote! { tokens.append_all(quote! {
.namespace(Some("http://www.w3.org/2000/svg")) .namespace(Some("http://www.w3.org/2000/svg"))
}); });

View File

@ -18,7 +18,6 @@ use syn::{
pub enum AmbiguousElement { pub enum AmbiguousElement {
Element(Element), Element(Element),
Component(Component), Component(Component),
Fragment(Fragment),
} }
impl Parse for AmbiguousElement { impl Parse for AmbiguousElement {
@ -76,7 +75,6 @@ impl ToTokens for AmbiguousElement {
match self { match self {
AmbiguousElement::Element(el) => el.to_tokens(tokens), AmbiguousElement::Element(el) => el.to_tokens(tokens),
AmbiguousElement::Component(comp) => comp.to_tokens(tokens), AmbiguousElement::Component(comp) => comp.to_tokens(tokens),
AmbiguousElement::Fragment(frag) => frag.to_tokens(tokens),
} }
} }
} }

View File

@ -133,14 +133,17 @@ impl ToTokens for Component {
let childs = &self.children; let childs = &self.children;
let children = quote! { let children = quote! {
ChildrenList::new(__cx) [ #( #childs ),* ]
#( .add_child(#childs) )*
.finish()
}; };
// ChildrenList::new(__cx)
// #( .add_child(#childs) )*
// .finish()
// ChildrenList::new(__cx)
// #( .add_child(#childs) )*
// .finish()
tokens.append_all(quote! { tokens.append_all(quote! {
dioxus::builder::virtual_child( __cx.virtual_child(
__cx,
#name, #name,
#builder, #builder,
#key_token, #key_token,

View File

@ -86,13 +86,13 @@ impl ToTokens for RsxRender {
match &self.custom_context { match &self.custom_context {
// The `in cx` pattern allows directly rendering // The `in cx` pattern allows directly rendering
Some(ident) => out_tokens.append_all(quote! { Some(ident) => out_tokens.append_all(quote! {
#ident.render(dioxus::prelude::LazyNodes::new(move |__cx: &NodeFactory|{ #ident.render(dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{
#inner #inner
})) }))
}), }),
// Otherwise we just build the LazyNode wrapper // Otherwise we just build the LazyNode wrapper
None => out_tokens.append_all(quote! { None => out_tokens.append_all(quote! {
dioxus::prelude::LazyNodes::new(move |__cx: &NodeFactory|{ dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory|{
#inner #inner
}) })
}), }),

View File

@ -150,7 +150,7 @@ pub mod on {
$( $(
$(#[$method_attr])* $(#[$method_attr])*
pub fn $name<'a>( pub fn $name<'a>(
c: &'_ NodeFactory<'a>, c: NodeFactory<'a>,
callback: impl Fn($wrapper) + 'a, callback: impl Fn($wrapper) + 'a,
) -> Listener<'a> { ) -> Listener<'a> {
let bump = &c.bump(); let bump = &c.bump();

View File

@ -23,7 +23,7 @@ use std::{
/// Usage: /// Usage:
/// ```ignore /// ```ignore
/// static Example: FC<()> = |cx| { /// static Example: FC<()> = |cx| {
/// let (counter, set_counter) = use_state(&cx, || 0); /// let (counter, set_counter) = use_state(cx, || 0);
/// let increment = |_| set_couter(counter + 1); /// let increment = |_| set_couter(counter + 1);
/// let decrement = |_| set_couter(counter + 1); /// let decrement = |_| set_couter(counter + 1);
/// ///
@ -145,7 +145,7 @@ impl<'a, T: 'static + Display> std::fmt::Display for UseState<T> {
/// Usage: /// Usage:
/// ```ignore /// ```ignore
/// static Example: FC<()> = |cx| { /// static Example: FC<()> = |cx| {
/// let (counter, set_counter) = use_state(&cx, || 0); /// let (counter, set_counter) = use_state(cx, || 0);
/// let increment = |_| set_couter(counter + 1); /// let increment = |_| set_couter(counter + 1);
/// let decrement = |_| set_couter(counter + 1); /// let decrement = |_| set_couter(counter + 1);
/// ///

View File

@ -620,23 +620,17 @@ where
} }
} }
// impl IntoVNode<'_> for () { impl IntoVNode<'_> for () {
// fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> { fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
// todo!(); cx.fragment_from_iter(None as Option<VNode>)
// VNode::Suspended { }
// real: Cell::new(RealDomNode::empty()), }
// }
// }
// }
// impl IntoVNode<'_> for Option<()> { impl IntoVNode<'_> for Option<()> {
// fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> { fn into_vnode<'a>(self, cx: NodeFactory<'a>) -> VNode<'a> {
// todo!(); cx.fragment_from_iter(None as Option<VNode>)
// VNode::Suspended { }
// real: Cell::new(RealDomNode::empty()), }
// }
// }
// }
/// Construct a text VNode. /// Construct a text VNode.
/// ///
@ -717,8 +711,6 @@ pub fn virtual_child<'a, T: Properties + 'a>(
VNode::Component( VNode::Component(
cx.bump() cx.bump()
.alloc(crate::nodes::VComponent::new(&cx, f, props, key, children)), .alloc(crate::nodes::VComponent::new(&cx, f, props, key, children)),
// cx.bump()
// .alloc(crate::nodes::VComponent::new(f, props, key)),
) )
} }
@ -786,6 +778,26 @@ impl<'a> NodeFactory<'a> {
})) }))
} }
pub fn virtual_child<T: Properties + 'a, C>(
&self,
f: FC<T>,
props: T,
key: Option<&'a str>, // key: NodeKey<'a>,
children: C,
) -> VNode<'a>
where
C: 'a + AsRef<[VNode<'a>]>,
{
let children: &'a C = self.bump().alloc(children);
VNode::Component(self.bump().alloc(crate::nodes::VComponent::new(
self,
f,
props,
key,
children.as_ref(),
)))
}
pub fn fragment_from_iter( pub fn fragment_from_iter(
self, self,
node_iter: impl IntoIterator<Item = impl IntoVNode<'a>>, node_iter: impl IntoIterator<Item = impl IntoVNode<'a>>,

View File

@ -25,7 +25,7 @@ fn main() {
} }
static App: FC<()> = |cx| { static App: FC<()> = |cx| {
let (url, set_url) = use_state(&cx, || ""); let (url, set_url) = use_state(cx, || "");
let body = match *url { let body = match *url {
"community" => rsx!(in cx, Community {}), "community" => rsx!(in cx, Community {}),

View File

@ -34,7 +34,7 @@ enum LightState {
Red, Red,
} }
static HelloMessage: FC<()> = |cx| { static HelloMessage: FC<()> = |cx| {
let (color, set_color) = use_state(&cx, || LightState::Green); let (color, set_color) = use_state(cx, || LightState::Green);
let title = match color { let title = match color {
Green => "Green means go", Green => "Green means go",

View File

@ -20,7 +20,7 @@ This is moderately efficient because the fields of the map are moved, but the da
However, if you used similar approach with Dioxus: However, if you used similar approach with Dioxus:
```rust ```rust
let (map, set_map) = use_state(&cx, || HashMap::new()); let (map, set_map) = use_state(cx, || HashMap::new());
set_map({ set_map({
let mut newmap = map.clone(); let mut newmap = map.clone();
newmap.set(key, value); newmap.set(key, value);

View File

@ -29,7 +29,7 @@ mod client {
static APP: FC<()> = |cx| { static APP: FC<()> = |cx| {
todo!() todo!()
// let (selected_stream, set_stream) = use_state(&cx, || SelectedStream::Football); // let (selected_stream, set_stream) = use_state(cx, || SelectedStream::Football);
// let opts = SelectedStream::iter().map(|name| rsx! { option { "{name}", value: "{name}" } }); // let opts = SelectedStream::iter().map(|name| rsx! { option { "{name}", value: "{name}" } });

View File

@ -29,7 +29,7 @@ mod client {
static APP: FC<()> = |cx| { static APP: FC<()> = |cx| {
todo!() todo!()
// let (selected_stream, set_stream) = use_state(&cx, || SelectedStream::Football); // let (selected_stream, set_stream) = use_state(cx, || SelectedStream::Football);
// let opts = SelectedStream::iter().map(|name| rsx! { option { "{name}", value: "{name}" } }); // let opts = SelectedStream::iter().map(|name| rsx! { option { "{name}", value: "{name}" } });

View File

@ -9,7 +9,7 @@ Dioxus-webview is an attempt at making a simpler "Tauri" where creating desktop
#[async_std::main] #[async_std::main]
async fn main() { async fn main() {
dioxus_webview::new(|cx| { dioxus_webview::new(|cx| {
let (count, set_count) = use_state(&cx, || 0); let (count, set_count) = use_state(cx, || 0);
cx.render(html! { cx.render(html! {
<div> <div>
<h1> "Dioxus Desktop Demo" </h1> <h1> "Dioxus Desktop Demo" </h1>
@ -44,4 +44,4 @@ By bridging the native process, desktop apps can access full multithreading powe
Dioxus-desktop is a pure liveview application where all of the state and event handlers are proxied through the liveview and into the native process. For pure server-based liveview, this would normally be too slow (in both render performance and latency), but because the VDom is local, desktop apps are just as fast as Electron. Dioxus-desktop is a pure liveview application where all of the state and event handlers are proxied through the liveview and into the native process. For pure server-based liveview, this would normally be too slow (in both render performance and latency), but because the VDom is local, desktop apps are just as fast as Electron.
Dioxus-desktop leverages dioxus-liveview under the hood, but with convenience wrappers around setting up the VDom bridge, proxying events, and serving the initial WebSys-Renderer. The backend is served by Tide, so an async runtime _is_ needed - we recommend async-std in tokio mode. Dioxus-desktop leverages dioxus-liveview under the hood, but with convenience wrappers around setting up the VDom bridge, proxying events, and serving the initial WebSys-Renderer. The backend is served by Tide, so an async runtime _is_ needed - we recommend async-std in Tokio mode.

View File

@ -94,7 +94,7 @@
//! //!
//! ``` //! ```
//! static Example: FC<()> = |cx| { //! static Example: FC<()> = |cx| {
//! let (val, set_val) = use_state(&cx, || 0); //! let (val, set_val) = use_state(cx, || 0);
//! cx.render(rsx!( //! cx.render(rsx!(
//! button { onclick: move |_| set_val(val + 1) } //! button { onclick: move |_| set_val(val + 1) }
//! )) //! ))