浏览代码

wip: almost there

Jonathan Kelley 3 年之前
父节点
当前提交
047c810507
共有 11 个文件被更改,包括 152 次插入382 次删除
  1. 0 14
      examples/basic.rs
  2. 15 21
      examples/calculator.rs
  3. 57 30
      examples/crm.rs
  4. 1 2
      examples/file_explorer.rs
  5. 0 2
      examples/manually.rs
  6. 26 29
      examples/model.rs
  7. 11 13
      examples/reducer.rs
  8. 0 112
      examples/slideshow.rs
  9. 0 67
      examples/testbed.rs
  10. 42 44
      examples/todomvc.rs
  11. 0 48
      examples/webview.rs

+ 0 - 14
examples/basic.rs

@@ -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,
-        )
-    });
-}

+ 15 - 21
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::<f64>().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,

+ 57 - 30
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 => {
+            let add_new = move |_| {
+                clients.write().push(Client {
+                    description: (*description).clone(),
+                    first_name: (*firstname).clone(),
+                    last_name: (*lastname).clone(),
+                });
+                description.set(String::new());
+                firstname.set(String::new());
+                lastname.set(String::new());
+            };
             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())
+                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"
-                        onchange: move |e| lastname.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"
-                        onchange: move |e| description.set(e.value())
+                    textarea { class: "new-client description" placeholder: "Description" value: "{description}"
+                        oninput: move |e| description.set(e.value())
                     }
                 }
-                button { disabled: "false", onclick: 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" }
+                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}
+    })
 };

+ 1 - 2
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);

+ 0 - 2
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");

+ 26 - 29
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<Operator>,

+ 11 - 13
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)
         }
     })
 };

+ 0 - 112
examples/slideshow.rs

@@ -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 {}
-        }
-    })
-};

+ 0 - 67
examples/testbed.rs

@@ -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"}
-        ))
-    }
-};

+ 42 - 44
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" }}
-                        }
-                    }
-                ))}
-            }
-            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" }}
             }
+            {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" }}
         }
     })
 };
 
 #[derive(PartialEq, Props)]
 pub struct TodoEntryProps {
-    todo: std::rc::Rc<TodoItem>,
+    todo: Rc<TodoItem>,
 }
 
-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}"
+    rsx!(cx, li {
+        "{todo.id}"
+        input {
+            class: "toggle"
+            r#type: "checkbox"
+            "{todo.checked}"
+        }
+       {is_editing.then(|| rsx!{
             input {
-                class: "toggle"
-                r#type: "checkbox"
-                "{todo.checked}"
+                value: "{contents}"
+                oninput: move |evt| contents.set(evt.value())
             }
-           {is_editing.then(|| rsx!{
-                input {
-                    value: "{contents}"
-                }
-            })}
-        }
-    ))
+        })}
+    })
 }

+ 0 - 48
examples/webview.rs

@@ -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()}
-        }
-    })
-}