diff --git a/examples/basic.rs b/examples/basic.rs deleted file mode 100644 index 12958072a..000000000 --- a/examples/basic.rs +++ /dev/null @@ -1,14 +0,0 @@ -use dioxus::prelude::*; - -fn main() { - let g = dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory| { - use dioxus_elements::{GlobalAttributes, SvgAttributes}; - __cx.element( - dioxus_elements::button, - [dioxus::events::on::onclick(__cx, move |_| {})], - [], - [], - None, - ) - }); -} diff --git a/examples/calculator.rs b/examples/calculator.rs index 3b86d1a31..7108b368b 100644 --- a/examples/calculator.rs +++ b/examples/calculator.rs @@ -12,7 +12,7 @@ fn main() { const APP: FC<()> = |cx, _| { let cur_val = use_state(cx, || 0.0_f64); - let operator = use_state(cx, || None); + let operator = use_state(cx, || None as Option<&'static str>); let display_value = use_state(cx, || String::from("")); let clear_display = display_value == "0"; @@ -25,11 +25,12 @@ const APP: FC<()> = |cx, _| { let perform_operation = move || { if let Some(op) = operator.as_ref() { let rhs = display_value.parse::().unwrap(); - let new_val = match op { - Operator::Add => *cur_val + rhs, - Operator::Sub => *cur_val - rhs, - Operator::Mul => *cur_val * rhs, - Operator::Div => *cur_val / rhs, + let new_val = match *op { + "+" => *cur_val + rhs, + "-" => *cur_val - rhs, + "*" => *cur_val * rhs, + "/" => *cur_val / rhs, + _ => unreachable!(), }; cur_val.set(new_val); display_value.set(new_val.to_string()); @@ -56,10 +57,10 @@ const APP: FC<()> = |cx, _| { }; let keydownhandler = move |evt: KeyboardEvent| match evt.key_code() { - KeyCode::Add => operator.set(Some(Operator::Add)), - KeyCode::Subtract => operator.set(Some(Operator::Sub)), - KeyCode::Divide => operator.set(Some(Operator::Div)), - KeyCode::Multiply => operator.set(Some(Operator::Mul)), + KeyCode::Add => operator.set(Some("+")), + KeyCode::Subtract => operator.set(Some("-")), + KeyCode::Divide => operator.set(Some("/")), + KeyCode::Multiply => operator.set(Some("*")), KeyCode::Num0 => input_digit(0), KeyCode::Num1 => input_digit(1), KeyCode::Num2 => input_digit(2), @@ -99,23 +100,16 @@ const APP: FC<()> = |cx, _| { })} } div { class: "operator-keys" - CalculatorKey { name: "key-divide", onclick: move |_| operator.set(Some(Operator::Div)) "÷" } - CalculatorKey { name: "key-multiply", onclick: move |_| operator.set(Some(Operator::Mul)) "×" } - CalculatorKey { name: "key-subtract", onclick: move |_| operator.set(Some(Operator::Sub)) "−" } - CalculatorKey { name: "key-add", onclick: move |_| operator.set(Some(Operator::Add)) "+" } + CalculatorKey { name: "key-divide", onclick: move |_| operator.set(Some("/")) "÷" } + CalculatorKey { name: "key-multiply", onclick: move |_| operator.set(Some("*")) "×" } + CalculatorKey { name: "key-subtract", onclick: move |_| operator.set(Some("-")) "−" } + CalculatorKey { name: "key-add", onclick: move |_| operator.set(Some("+")) "+" } CalculatorKey { name: "key-equals", onclick: move |_| perform_operation() "=" } } } }) }; -enum Operator { - Add, - Sub, - Mul, - Div, -} - #[derive(Props)] struct CalculatorKeyProps<'a> { name: &'static str, diff --git a/examples/crm.rs b/examples/crm.rs index 9426ff410..5155221c3 100644 --- a/examples/crm.rs +++ b/examples/crm.rs @@ -6,7 +6,6 @@ use dioxus::prelude::*; fn main() { dioxus::web::launch(App, |c| c); } - enum Scene { ClientsList, NewClientForm, @@ -28,50 +27,78 @@ static App: FC<()> = |cx, _| { let lastname = use_state(cx, || String::new()); let description = use_state(cx, || String::new()); - match *scene { + let scene = match *scene { Scene::ClientsList => { rsx!(cx, div { class: "crm" - h1 { "List of clients" } - div { class: "clients" {clients.read().iter().map(|client| rsx!( - div { class: "client" style: "margin-bottom: 50px" - p { "First Name: {client.first_name}" } - p { "Last Name: {client.last_name}" } - p {"Description: {client.description}"} - }))} + h2 { "List of clients" margin_bottom: "10px" } + div { class: "clients" margin_left: "10px" + {clients.read().iter().map(|client| rsx!( + div { class: "client" style: "margin-bottom: 50px" + p { "First Name: {client.first_name}" } + p { "Last Name: {client.last_name}" } + p {"Description: {client.description}"} + }) + )} } - button { onclick: move |_| scene.set(Scene::NewClientForm), "Add New" } - button { onclick: move |_| scene.set(Scene::Settings), "Settings" } + button { class: "pure-button pure-button-primary" onclick: move |_| scene.set(Scene::NewClientForm), "Add New" } + button { class: "pure-button" onclick: move |_| scene.set(Scene::Settings), "Settings" } }) } Scene::NewClientForm => { - rsx!(cx, div { class: "crm" - h1 {"Add new client"} - div { class: "names" - input { class: "new-client firstname" placeholder: "First name" - onchange: move |e| firstname.set(e.value()) - } - input { class: "new-client lastname" placeholder: "Last name" - onchange: move |e| lastname.set(e.value()) - } - textarea { class: "new-client description" placeholder: "Description" - onchange: move |e| description.set(e.value()) - } - } - button { disabled: "false", onclick: move |_| clients.write().push(Client { + let add_new = move |_| { + clients.write().push(Client { description: (*description).clone(), first_name: (*firstname).clone(), last_name: (*lastname).clone(), - - }), "Add New" } - button { onclick: move |_| scene.set(Scene::ClientsList), "Go Back" } + }); + description.set(String::new()); + firstname.set(String::new()); + lastname.set(String::new()); + }; + rsx!(cx, div { class: "crm" + h2 {"Add new client" margin_bottom: "10px" } + form { class: "pure-form" + input { class: "new-client firstname" placeholder: "First name" value: "{firstname}" + oninput: move |e| firstname.set(e.value()) + } + input { class: "new-client lastname" placeholder: "Last name" value: "{lastname}" + oninput: move |e| lastname.set(e.value()) + } + textarea { class: "new-client description" placeholder: "Description" value: "{description}" + oninput: move |e| description.set(e.value()) + } + } + button { class: "pure-button pure-button-primary", onclick: {add_new}, "Add New" } + button { class: "pure-button", onclick: move |_| scene.set(Scene::ClientsList), "Go Back" } }) } Scene::Settings => { rsx!(cx, div { - h1 {"Settings"} - button { onclick: move |_| clients.write().clear() "Remove all clients" } - button { onclick: move |_| scene.set(Scene::ClientsList), "Go Back" } + h2 {"Settings" margin_bottom: "10px" } + button { + background: "rgb(202, 60, 60)" + class: "pure-button pure-button-primary" + onclick: move |_| clients.write().clear(), + "Remove all clients" + } + button { + class: "pure-button pure-button-primary" + onclick: move |_| scene.set(Scene::ClientsList), + "Go Back" + } }) } - } + }; + + rsx!(cx, body { + link { + rel: "stylesheet" + href: "https://unpkg.com/purecss@2.0.6/build/pure-min.css" + integrity: "sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5" + crossorigin: "anonymous" + } + margin_left: "35%" + h1 {"Dioxus CRM Example"} + {scene} + }) }; diff --git a/examples/file_explorer.rs b/examples/file_explorer.rs index bc0c289d4..da543e5c3 100644 --- a/examples/file_explorer.rs +++ b/examples/file_explorer.rs @@ -7,7 +7,6 @@ use dioxus::desktop::wry::application::dpi::LogicalSize; use dioxus::prelude::*; -use std::fs::{self, DirEntry}; fn main() { env_logger::init(); @@ -73,7 +72,7 @@ impl Files { fn reload_path_list(&mut self) { let cur_path = self.path_stack.last().unwrap(); - let paths = match fs::read_dir(cur_path) { + let paths = match std::fs::read_dir(cur_path) { Ok(e) => e, Err(err) => { let err = format!("An error occured: {:?}", err); diff --git a/examples/manually.rs b/examples/manually.rs index 9dd760bf7..584b91756 100644 --- a/examples/manually.rs +++ b/examples/manually.rs @@ -6,7 +6,6 @@ fn main() { // .. should result in an "invalid node tree" let edits = vec![ CreateElement { tag: "div", id: 0 }, - // CreatePlaceholder { id: 1 }, CreateElement { tag: "h1", id: 2 }, CreateTextNode { text: "hello world", @@ -15,7 +14,6 @@ fn main() { AppendChildren { many: 1 }, AppendChildren { many: 1 }, AppendChildren { many: 1 }, - // ReplaceWith { many: 1 }, ]; dioxus_desktop::WebviewRenderer::run_with_edits(App, (), |c| c, Some(edits)).expect("failed"); diff --git a/examples/model.rs b/examples/model.rs index ee137ab1a..f7012fa32 100644 --- a/examples/model.rs +++ b/examples/model.rs @@ -33,40 +33,38 @@ fn main() { } static App: FC<()> = |cx, props| { - let state = use_state(cx, || Calculator::new()); + let state = use_ref(cx, || Calculator::new()); - let clear_display = state.display_value.eq("0"); + let clear_display = state.read().display_value.eq("0"); let clear_text = if clear_display { "C" } else { "AC" }; - let formatted = state.formatted_display(); + let formatted = state.read().formatted_display(); - cx.render(rsx! { - div { id: "wrapper" - div { class: "app", style { "{STYLE}" } - div { class: "calculator", onkeypress: move |evt| state.modify().handle_keydown(evt), - div { class: "calculator-display", "{formatted}"} - div { class: "calculator-keypad" - div { class: "input-keys" - div { class: "function-keys" - CalculatorKey { name: "key-clear", onclick: move |_| state.modify().clear_display(), "{clear_text}" } - CalculatorKey { name: "key-sign", onclick: move |_| state.modify().toggle_sign(), "±"} - CalculatorKey { name: "key-percent", onclick: move |_| state.modify().toggle_percent(), "%"} - } - div { class: "digit-keys" - CalculatorKey { name: "key-0", onclick: move |_| state.modify().input_digit(0), "0" } - CalculatorKey { name: "key-dot", onclick: move |_| state.modify().input_dot(), "●" } - {(1..10).map(move |k| rsx!{ - CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| state.modify().input_digit(k), "{k}" } - })} - } + rsx!(cx, div { id: "wrapper" + div { class: "app", style { "{STYLE}" } + div { class: "calculator", onkeypress: move |evt| state.write().handle_keydown(evt), + div { class: "calculator-display", "{formatted}"} + div { class: "calculator-keypad" + div { class: "input-keys" + div { class: "function-keys" + CalculatorKey { name: "key-clear", onclick: move |_| state.write().clear_display(), "{clear_text}" } + CalculatorKey { name: "key-sign", onclick: move |_| state.write().toggle_sign(), "±"} + CalculatorKey { name: "key-percent", onclick: move |_| state.write().toggle_percent(), "%"} } - div { class: "operator-keys" - CalculatorKey { name:"key-divide", onclick: move |_| state.modify().set_operator(Operator::Div), "÷" } - CalculatorKey { name:"key-multiply", onclick: move |_| state.modify().set_operator(Operator::Mul), "×" } - CalculatorKey { name:"key-subtract", onclick: move |_| state.modify().set_operator(Operator::Sub), "−" } - CalculatorKey { name:"key-add", onclick: move |_| state.modify().set_operator(Operator::Add), "+" } - CalculatorKey { name:"key-equals", onclick: move |_| state.modify().perform_operation(), "=" } + div { class: "digit-keys" + CalculatorKey { name: "key-0", onclick: move |_| state.write().input_digit(0), "0" } + CalculatorKey { name: "key-dot", onclick: move |_| state.write().input_dot(), "●" } + {(1..10).map(move |k| rsx!{ + CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| state.write().input_digit(k), "{k}" } + })} } } + div { class: "operator-keys" + CalculatorKey { name:"key-divide", onclick: move |_| state.write().set_operator(Operator::Div), "÷" } + CalculatorKey { name:"key-multiply", onclick: move |_| state.write().set_operator(Operator::Mul), "×" } + CalculatorKey { name:"key-subtract", onclick: move |_| state.write().set_operator(Operator::Sub), "−" } + CalculatorKey { name:"key-add", onclick: move |_| state.write().set_operator(Operator::Add), "+" } + CalculatorKey { name:"key-equals", onclick: move |_| state.write().perform_operation(), "=" } + } } } } @@ -89,7 +87,6 @@ fn CalculatorKey<'a, 'r>(cx: Context<'a>, props: &'a CalculatorKeyProps) -> DomT }) } -#[derive(Clone)] struct Calculator { display_value: String, operator: Option, diff --git a/examples/reducer.rs b/examples/reducer.rs index 52e3e9a92..a23bd2659 100644 --- a/examples/reducer.rs +++ b/examples/reducer.rs @@ -11,23 +11,21 @@ fn main() { dioxus::desktop::launch(App, |c| c); } -pub static App: FC<()> = |cx, props| { +pub static App: FC<()> = |cx, _| { let state = use_state(cx, PlayerState::new); let is_playing = state.is_playing(); - cx.render(rsx! { - div { - h1 {"Select an option"} - h3 {"The radio is... {is_playing}!"} - button { - "Pause" - onclick: move |_| state.modify().reduce(PlayerAction::Pause) - } - button { - "Play" - onclick: move |_| state.modify().reduce(PlayerAction::Play) - } + rsx!(cx, div { + h1 {"Select an option"} + h3 {"The radio is... {is_playing}!"} + button { + "Pause" + onclick: move |_| state.modify().reduce(PlayerAction::Pause) + } + button { + "Play" + onclick: move |_| state.modify().reduce(PlayerAction::Play) } }) }; diff --git a/examples/slideshow.rs b/examples/slideshow.rs deleted file mode 100644 index 80154b4ac..000000000 --- a/examples/slideshow.rs +++ /dev/null @@ -1,112 +0,0 @@ -//! Example: Webview Renderer -//! ------------------------- -//! -//! This example shows how to use the dioxus_desktop crate to build a basic desktop application. -//! -//! Under the hood, the dioxus_desktop crate bridges a native Dioxus VirtualDom with a custom prebuit application running -//! in the webview runtime. Custom handlers are provided for the webview instance to consume patches and emit user events -//! into the native VDom instance. -//! -//! Currently, NodeRefs won't work properly, but all other event functionality will. - -use dioxus::prelude::*; - -fn main() { - dioxus::desktop::launch(App, |c| c); -} - -static App: FC<()> = |cx, props| { - let slides = use_state(cx, SlideController::new); - - let slide = match slides.slide_id { - 0 => cx.render(rsx!(Title {})), - 1 => cx.render(rsx!(Slide1 {})), - 2 => cx.render(rsx!(Slide2 {})), - 3 => cx.render(rsx!(Slide3 {})), - _ => cx.render(rsx!(End {})), - }; - - cx.render(rsx! { - div { - style: { - background_color: "red" - } - div { - div { h1 {"my awesome slideshow"} } - div { - button {"<-", onclick: move |_| slides.modify().go_forward()} - h3 { "{slides.slide_id}" } - button {"->" onclick: move |_| slides.modify().go_backward()} - } - } - {slide} - } - }) -}; - -#[derive(Clone)] -struct SlideController { - slide_id: isize, -} -impl SlideController { - fn new() -> Self { - Self { slide_id: 0 } - } - fn can_go_forward(&self) -> bool { - false - } - fn can_go_backward(&self) -> bool { - true - } - fn go_forward(&mut self) { - if self.can_go_forward() { - self.slide_id += 1; - } - } - fn go_backward(&mut self) { - if self.can_go_backward() { - self.slide_id -= 1; - } - } -} - -const Title: FC<()> = |cx, props| { - cx.render(rsx! { - div { - h1 { "Title" } - p {} - } - }) -}; -const Slide1: FC<()> = |cx, props| { - cx.render(rsx! { - div { - h1 { "Slide1" } - p {} - } - }) -}; -const Slide2: FC<()> = |cx, props| { - cx.render(rsx! { - div { - h1 { "Slide2" } - p {} - } - }) -}; -const Slide3: FC<()> = |cx, props| { - cx.render(rsx! { - div { - h1 { "Slide3" } - p {} - } - }) -}; -const End: FC<()> = |cx, props| { - cx.render(rsx! { - div { - h1 { "End" } - p {} - } - }) -}; diff --git a/examples/testbed.rs b/examples/testbed.rs deleted file mode 100644 index 63d76659c..000000000 --- a/examples/testbed.rs +++ /dev/null @@ -1,67 +0,0 @@ -use std::cell::Cell; - -use dioxus::prelude::*; -use dioxus_core::{ - nodes::{VElement, VText}, - ElementId, -}; - -fn main() { - env_logger::init(); - dioxus::desktop::launch(Example, |c| c); -} - -const STYLE: &str = r#" -body {background-color: powderblue;} -h1 {color: blue;} -p {color: red;} -"#; - -const Example: FC<()> = |cx, props| { - cx.render(rsx! { - Fragment { - Fragment { - Fragment { - "h1" - div { - - } - } - "h2" - } - "h3" - } - "h4" - div { "h5" } - button { } - Child {} - }) -}; - -const Child: FC<()> = |cx, props| { - cx.render(rsx!( - h1 {"1" } - h1 {"2" } - h1 {"3" } - h1 {"4" } - )) -}; - -// this is a bad case that hurts our subtree memoization :( -const AbTest: FC<()> = |cx, props| { - if 1 == 2 { - cx.render(rsx!( - h1 {"1"} - h1 {"2"} - h1 {"3"} - h1 {"4"} - )) - } else { - cx.render(rsx!( - h1 {"1"} - h1 {"2"} - h2 {"basd"} - h1 {"4"} - )) - } -}; diff --git a/examples/todomvc.rs b/examples/todomvc.rs index d5d961ba0..c094d889a 100644 --- a/examples/todomvc.rs +++ b/examples/todomvc.rs @@ -48,62 +48,60 @@ const App: FC<()> = |cx, props| { _ => "items", }; - cx.render(rsx! { - div { id: "app" - style {"{STYLE}"} - div { - header { class: "header" - h1 {"todos"} - input { - class: "new-todo" - placeholder: "What needs to be done?" - value: "{draft}" - oninput: move |evt| draft.set(evt.value()) + rsx!(cx, div { id: "app" + style {"{STYLE}"} + div { + header { class: "header" + h1 {"todos"} + input { + class: "new-todo" + placeholder: "What needs to be done?" + value: "{draft}" + oninput: move |evt| draft.set(evt.value()) + } + } + {todolist} + {(!todos.is_empty()).then(|| rsx!( + footer { + span { strong {"{items_left}"} span {"{item_text} left"} } + ul { class: "filters" + li { class: "All", a { href: "", onclick: move |_| filter.set(FilterState::All), "All" }} + li { class: "Active", a { href: "active", onclick: move |_| filter.set(FilterState::Active), "Active" }} + li { class: "Completed", a { href: "completed", onclick: move |_| filter.set(FilterState::Completed), "Completed" }} } } - {todolist} - {(!todos.is_empty()).then(|| rsx!( - footer { - span { strong {"{items_left}"} span {"{item_text} left"} } - ul { class: "filters" - li { class: "All", a { href: "", onclick: move |_| filter.set(FilterState::All), "All" }} - li { class: "Active", a { href: "active", onclick: move |_| filter.set(FilterState::Active), "Active" }} - li { class: "Completed", a { href: "completed", onclick: move |_| filter.set(FilterState::Completed), "Completed" }} - } - } - ))} - } - footer { class: "info" - p {"Double-click to edit a todo"} - p { "Created by ", a { "jkelleyrtp", href: "http://github.com/jkelleyrtp/" }} - p { "Part of ", a { "TodoMVC", href: "http://todomvc.com" }} - } + ))} + } + footer { class: "info" + p {"Double-click to edit a todo"} + p { "Created by ", a { "jkelleyrtp", href: "http://github.com/jkelleyrtp/" }} + p { "Part of ", a { "TodoMVC", href: "http://todomvc.com" }} } }) }; #[derive(PartialEq, Props)] pub struct TodoEntryProps { - todo: std::rc::Rc, + todo: Rc, } -pub fn TodoEntry<'a>(cx: Context<'a>, TodoEntryProps { todo }: &'a TodoEntryProps) -> DomTree<'a> { +pub fn TodoEntry<'a>(cx: Context<'a>, props: &TodoEntryProps) -> DomTree<'a> { let is_editing = use_state(cx, || false); - let contents = ""; + let contents = use_state(cx, || String::from("")); + let todo = &props.todo; - cx.render(rsx! ( - li { - "{todo.id}" - input { - class: "toggle" - r#type: "checkbox" - "{todo.checked}" - } - {is_editing.then(|| rsx!{ - input { - value: "{contents}" - } - })} + rsx!(cx, li { + "{todo.id}" + input { + class: "toggle" + r#type: "checkbox" + "{todo.checked}" } - )) + {is_editing.then(|| rsx!{ + input { + value: "{contents}" + oninput: move |evt| contents.set(evt.value()) + } + })} + }) } diff --git a/examples/webview.rs b/examples/webview.rs deleted file mode 100644 index ee74970dc..000000000 --- a/examples/webview.rs +++ /dev/null @@ -1,48 +0,0 @@ -//! Example: Webview Renderer -//! ------------------------- -//! -//! This example shows how to use the dioxus_desktop crate to build a basic desktop application. -//! -//! Under the hood, the dioxus_desktop crate bridges a native Dioxus VirtualDom with a custom prebuit application running -//! in the webview runtime. Custom handlers are provided for the webview instance to consume patches and emit user events -//! into the native VDom instance. -//! -//! Currently, NodeRefs won't work properly, but all other event functionality will. -#![allow(non_upper_case_globals, non_snake_case)] - -use dioxus::{events::on::MouseEvent, prelude::*}; - -fn main() -> anyhow::Result<()> { - env_logger::init(); - dioxus::desktop::launch(App, |c| c) -} - -static App: FC<()> = |cx, props| { - let state = use_state(cx, || String::from("hello")); - let clear_text = state == "hello"; - - dbg!("rednering parent"); - cx.render(rsx! { - div { - h1 {"{state}"} - CalculatorKey { name: "key-clear", onclick: move |_| state.modify().push_str("hello"), "{clear_text}" } - CalculatorKey { name: "key-sign", onclick: move |_| { state.modify().pop(); }, "±"} - } - }) -}; - -#[derive(Props)] -struct CalculatorKeyProps<'a> { - name: &'static str, - onclick: &'a dyn Fn(MouseEvent), -} - -fn CalculatorKey<'a>(cx: Context<'a>, props: &'a CalculatorKeyProps) -> DomTree<'a> { - cx.render(rsx! { - button { - class: "calculator-key {props.name}" - onclick: {props.onclick} - {cx.children()} - } - }) -}