Parcourir la source

wip: move examples around

Jonathan Kelley il y a 3 ans
Parent
commit
1e6e5e6
86 fichiers modifiés avec 160 ajouts et 216 suppressions
  1. 1 1
      .vscode/settings.json
  2. 0 1
      Cargo.toml
  3. 3 2
      examples/calculator.rs
  4. 0 0
      examples/core/alternative.rs
  5. 0 0
      examples/core/async.rs
  6. 0 0
      examples/core/borrowed.rs
  7. 0 0
      examples/core/contextapi.rs
  8. 0 0
      examples/core/expand.rs
  9. 0 0
      examples/core/fragment_from_iter.rs
  10. 0 0
      examples/core/html.rs
  11. 0 0
      examples/core/jsframework.rs
  12. 0 0
      examples/core/syntax.rs
  13. 0 0
      examples/core/syntax2.rs
  14. 0 0
      examples/core/tasks.rs
  15. 0 0
      examples/core/vdom_usage.rs
  16. 0 0
      examples/core_reference/README.md
  17. 0 0
      examples/core_reference/antipatterns.rs
  18. 0 0
      examples/core_reference/basics.rs
  19. 0 0
      examples/core_reference/children.rs
  20. 0 0
      examples/core_reference/conditional_rendering.rs
  21. 0 0
      examples/core_reference/controlled_inputs.rs
  22. 0 0
      examples/core_reference/custom_elements.rs
  23. 0 0
      examples/core_reference/empty.rs
  24. 0 0
      examples/core_reference/errorhandling.rs
  25. 0 0
      examples/core_reference/fragments.rs
  26. 0 0
      examples/core_reference/global_css.rs
  27. 0 0
      examples/core_reference/inline_styles.rs
  28. 0 0
      examples/core_reference/iterators.rs
  29. 0 0
      examples/core_reference/listener.rs
  30. 0 0
      examples/core_reference/memo.rs
  31. 0 0
      examples/core_reference/noderefs.rs
  32. 0 0
      examples/core_reference/signals.rs
  33. 0 0
      examples/core_reference/spreadpattern.rs
  34. 0 0
      examples/core_reference/statemanagement.rs
  35. 0 0
      examples/core_reference/suspense.rs
  36. 0 0
      examples/core_reference/task.rs
  37. 0 0
      examples/core_reference/testing.rs
  38. 0 0
      examples/core_reference/tostring.rs
  39. 11 9
      examples/coroutine.rs
  40. 5 5
      examples/crm.rs
  41. 0 0
      examples/desktop/core.rs
  42. 0 0
      examples/desktop/crm.rs
  43. 0 0
      examples/desktop/demo.rs
  44. 0 0
      examples/desktop/kitchensink.rs
  45. 0 0
      examples/desktop/tauri.rs
  46. 0 0
      examples/desktop/todomvc.css
  47. 10 6
      examples/desktop/todomvc.rs
  48. 2 2
      examples/framework_benchmark.rs
  49. 3 2
      examples/pattern_model.rs
  50. 3 5
      examples/router.rs
  51. 9 6
      examples/rsx_usage.rs
  52. 0 0
      examples/ssr/basic.rs
  53. 0 0
      examples/ssr/hydration.rs
  54. 0 0
      examples/ssr/template.html
  55. 0 0
      examples/ssr/tide.rs
  56. 5 5
      examples/ssr/tofile.rs
  57. 2 2
      examples/tailwind.rs
  58. 5 5
      examples/todomvc.rs
  59. 1 1
      examples/weather_app.rs
  60. 0 0
      examples/web/async_web.rs
  61. 0 0
      examples/web/basic.rs
  62. 0 0
      examples/web/blah.rs
  63. 0 0
      examples/web/btns.rs
  64. 0 0
      examples/web/crm2.rs
  65. 0 0
      examples/web/demo.rs
  66. 0 1
      examples/webview_web.rs
  67. 1 0
      packages/core/benches/jsframework.rs
  68. 30 9
      packages/core/src/component.rs
  69. 5 3
      packages/core/src/lazynodes.rs
  70. 3 3
      packages/core/src/lib.rs
  71. 4 1
      packages/core/src/nodes.rs
  72. 1 20
      packages/core/tests/create_dom.rs
  73. 0 3
      packages/desktop/Cargo.toml
  74. 7 3
      packages/desktop/src/desktop_context.rs
  75. 2 0
      packages/desktop/src/index.html
  76. 41 6
      packages/desktop/src/lib.rs
  77. 0 52
      packages/hooks/examples/lifecycle.rs
  78. 0 1
      packages/hooks/examples/reducer.rs
  79. 1 1
      packages/hooks/src/use_shared_state.rs
  80. 1 1
      packages/hooks/src/usestate.rs
  81. 0 28
      packages/router/examples/blog.rs
  82. 4 10
      packages/ssr/src/lib.rs
  83. 0 3
      packages/web/.vscode/settings.json
  84. 0 8
      packages/webview-client/Cargo.toml
  85. 0 8
      packages/webview-client/README.md
  86. 0 3
      packages/webview-client/src/main.rs

+ 1 - 1
.vscode/settings.json

@@ -1,3 +1,3 @@
 {
-  // "rust-analyzer.cargo.allFeatures": true
+  "rust-analyzer.cargo.allFeatures": true
 }

+ 0 - 1
Cargo.toml

@@ -79,7 +79,6 @@ members = [
     "packages/ssr",
     "packages/desktop",
     "packages/mobile",
-    "packages/webview-client",
 ]
 
 

+ 3 - 2
examples/calculator.rs

@@ -114,12 +114,13 @@ const APP: FC<()> = |(cx, _)| {
 struct CalculatorKeyProps<'a> {
     name: &'static str,
     onclick: &'a dyn Fn(MouseEvent),
+    children: ScopeChildren<'a>,
 }
 
-fn CalculatorKey<'a>((cx, props): Scope<'a, CalculatorKeyProps>) -> Element<'a> {
+fn CalculatorKey<'a>((cx, props): Scope<'a, CalculatorKeyProps<'a>>) -> Element {
     rsx!(cx, button {
         class: "calculator-key {props.name}"
         onclick: {props.onclick}
-        {cx.children()}
+        {&props.children}
     })
 }

+ 0 - 0
packages/core/examples/alternative.rs → examples/core/alternative.rs


+ 0 - 0
packages/core/examples/async.rs → examples/core/async.rs


+ 0 - 0
packages/core/examples/borrowed.rs → examples/core/borrowed.rs


+ 0 - 0
packages/core/examples/contextapi.rs → examples/core/contextapi.rs


+ 0 - 0
packages/core/examples/expand.rs → examples/core/expand.rs


+ 0 - 0
packages/core/examples/fragment_from_iter.rs → examples/core/fragment_from_iter.rs


+ 0 - 0
packages/core/examples/html.rs → examples/core/html.rs


+ 0 - 0
packages/core/examples/jsframework.rs → examples/core/jsframework.rs


+ 0 - 0
packages/core/examples/syntax.rs → examples/core/syntax.rs


+ 0 - 0
packages/core/examples/syntax2.rs → examples/core/syntax2.rs


+ 0 - 0
packages/core/examples/tasks.rs → examples/core/tasks.rs


+ 0 - 0
packages/core/examples/vdom_usage.rs → examples/core/vdom_usage.rs


+ 0 - 0
reference/README.md → examples/core_reference/README.md


+ 0 - 0
reference/antipatterns.rs → examples/core_reference/antipatterns.rs


+ 0 - 0
reference/basics.rs → examples/core_reference/basics.rs


+ 0 - 0
reference/children.rs → examples/core_reference/children.rs


+ 0 - 0
reference/conditional_rendering.rs → examples/core_reference/conditional_rendering.rs


+ 0 - 0
reference/controlled_inputs.rs → examples/core_reference/controlled_inputs.rs


+ 0 - 0
reference/custom_elements.rs → examples/core_reference/custom_elements.rs


+ 0 - 0
reference/empty.rs → examples/core_reference/empty.rs


+ 0 - 0
reference/errorhandling.rs → examples/core_reference/errorhandling.rs


+ 0 - 0
reference/fragments.rs → examples/core_reference/fragments.rs


+ 0 - 0
reference/global_css.rs → examples/core_reference/global_css.rs


+ 0 - 0
reference/inline_styles.rs → examples/core_reference/inline_styles.rs


+ 0 - 0
reference/iterators.rs → examples/core_reference/iterators.rs


+ 0 - 0
reference/listener.rs → examples/core_reference/listener.rs


+ 0 - 0
reference/memo.rs → examples/core_reference/memo.rs


+ 0 - 0
reference/noderefs.rs → examples/core_reference/noderefs.rs


+ 0 - 0
reference/signals.rs → examples/core_reference/signals.rs


+ 0 - 0
reference/spreadpattern.rs → examples/core_reference/spreadpattern.rs


+ 0 - 0
reference/statemanagement.rs → examples/core_reference/statemanagement.rs


+ 0 - 0
reference/suspense.rs → examples/core_reference/suspense.rs


+ 0 - 0
reference/task.rs → examples/core_reference/task.rs


+ 0 - 0
reference/testing.rs → examples/core_reference/testing.rs


+ 0 - 0
reference/tostring.rs → examples/core_reference/tostring.rs


+ 11 - 9
examples/coroutine.rs

@@ -46,7 +46,8 @@ static App: FC<()> = |(cx, props)| {
     });
 
     cx.render(rsx! {
-        div { style: { width: "400px", height: "400px", position: "relative", background: "yellow" }
+        div {
+            width: "400px", height: "400px", position: "relative", background: "yellow"
             button { "reset", onclick: move |_| {} }
             Horsey { pos: *p1, "horsey 1" }
             Horsey { pos: *p2, "horsey 2" }
@@ -54,18 +55,19 @@ static App: FC<()> = |(cx, props)| {
     })
 };
 
-#[derive(PartialEq, Props)]
-struct HorseyProps {
+#[derive(Props)]
+struct HorseyProps<'a> {
     pos: i32,
+    children: ScopeChildren<'a>,
 }
 
-static Horsey: FC<HorseyProps> = |(cx, props)| {
+fn Horsey<'a>((cx, props): Scope<'a, HorseyProps<'a>>) -> Element {
     cx.render(rsx! {
-    div {
-        button { "pause" }
         div {
-            {cx.children()}
+            button { "pause" }
+            div {
+                {&props.children}
+            }
         }
-      }
     })
-};
+}

+ 5 - 5
examples/crm.rs

@@ -20,12 +20,12 @@ pub struct Client {
 }
 
 static App: FC<()> = |(cx, _)| {
-    let clients = use_ref(cx, || vec![] as Vec<Client>);
-    let scene = use_state(cx, || Scene::ClientsList);
+    let mut clients = use_ref(cx, || vec![] as Vec<Client>);
+    let mut scene = use_state(cx, || Scene::ClientsList);
 
-    let firstname = use_state(cx, || String::new());
-    let lastname = use_state(cx, || String::new());
-    let description = use_state(cx, || String::new());
+    let mut firstname = use_state(cx, || String::new());
+    let mut lastname = use_state(cx, || String::new());
+    let mut description = use_state(cx, || String::new());
 
     let scene = match *scene {
         Scene::ClientsList => {

+ 0 - 0
packages/desktop/examples/core.rs → examples/desktop/core.rs


+ 0 - 0
packages/desktop/examples/crm.rs → examples/desktop/crm.rs


+ 0 - 0
packages/desktop/examples/demo.rs → examples/desktop/demo.rs


+ 0 - 0
packages/desktop/examples/kitchensink.rs → examples/desktop/kitchensink.rs


+ 0 - 0
packages/desktop/examples/tauri.rs → examples/desktop/tauri.rs


+ 0 - 0
packages/desktop/examples/todomvc.css → examples/desktop/todomvc.css


+ 10 - 6
packages/desktop/examples/todomvc.rs → examples/desktop/todomvc.rs

@@ -34,11 +34,11 @@ pub type Todos = HashMap<u32, TodoItem>;
 
 pub static App: FC<()> = |(cx, _)| {
     // Share our TodoList to the todos themselves
-    use_provide_state(cx, || Todos::new());
+    use_provide_state(cx, Todos::new);
 
     // Save state for the draft, filter
-    let mut draft = use_state(cx, || "".to_string());
-    let mut filter = use_state(cx, || FilterState::All);
+    let draft = use_state(cx, || "".to_string());
+    let filter = use_state(cx, || FilterState::All);
     let mut todo_id = use_state(cx, || 0);
 
     // Consume the todos
@@ -95,7 +95,7 @@ pub static App: FC<()> = |(cx, _)| {
                         placeholder: "What needs to be done?"
                         value: "{draft}"
                         autofocus: "true"
-                        oninput: move |evt| draft.set(evt.value.clone())
+                        oninput: move |evt| draft.set(evt.value)
                         onkeydown: move |evt| {
                             if evt.key == "Enter" {
                                 submit_todo();
@@ -150,7 +150,9 @@ pub fn TodoEntry((cx, props): Scope<TodoEntryProps>) -> Element {
             div { class: "view"
                 input { class: "toggle" r#type: "checkbox" id: "cbg-{todo.id}" checked: "{todo.checked}"
                     onchange: move |evt| {
-                        todos.write().get_mut(&props.id).map(|todo| todo.checked = evt.value.parse().unwrap());
+                        if let Some(todo) = todos.write().get_mut(&props.id) { 
+                            todo.checked = evt.value.parse().unwrap()
+                        }
                     }
                 }
 
@@ -161,7 +163,9 @@ pub fn TodoEntry((cx, props): Scope<TodoEntryProps>) -> Element {
                {is_editing.then(|| rsx!{
                     input { value: "{todo.contents}"
                         oninput: move |evt| {
-                            todos.write().get_mut(&props.id).map(|todo| todo.contents = evt.value.clone());
+                            if let Some(todo) = todos.write().get_mut(&props.id) { 
+                                todo.contents = evt.value
+                            }
                         },
                     }
                 })}

+ 2 - 2
examples/framework_benchmark.rs

@@ -10,11 +10,11 @@ fn main() {
 type RowList = im_rc::HashMap<usize, Rc<str>, FxBuildHasher>;
 
 static App: FC<()> = |(cx, _props)| {
-    let items = use_state(cx, || RowList::default());
+    let mut items = use_state(cx, || RowList::default());
 
     let create_rendered_rows = move |from, num| move |_| items.set(create_row_list(from, num));
 
-    let append_1_000_rows =
+    let mut append_1_000_rows =
         move |_| items.set(create_row_list(items.len(), 1000).union((*items).clone()));
 
     let update_every_10th_row = move |_| {

+ 3 - 2
examples/pattern_model.rs

@@ -74,14 +74,15 @@ static App: FC<()> = |(cx, props)| {
 struct CalculatorKeyProps<'a> {
     name: &'static str,
     onclick: &'a dyn Fn(MouseEvent),
+    children: ScopeChildren<'a>,
 }
 
-fn CalculatorKey<'a>((cx, props): Scope<'a, CalculatorKeyProps>) -> Element<'a> {
+fn CalculatorKey<'a>((cx, props): Scope<'a, CalculatorKeyProps<'a>>) -> Element<'a> {
     cx.render(rsx! {
         button {
             class: "calculator-key {props.name}"
             onclick: {props.onclick}
-            {cx.children()}
+            {&props.children}
         }
     })
 }

+ 3 - 5
packages/router/examples/v2.rs → examples/router.rs

@@ -1,9 +1,5 @@
 use dioxus::prelude::*;
-use dioxus_router::{use_router, Link, Routable};
-
-fn main() {
-    dbg!(App as *const fn());
-}
+use dioxus::router::Router;
 
 #[derive(PartialEq, Debug, Clone)]
 pub enum Route {
@@ -86,3 +82,5 @@ impl Routable for Route {
         todo!()
     }
 }
+
+fn main() {}

+ 9 - 6
examples/rsx_usage.rs

@@ -162,13 +162,13 @@ pub static Example: FC<()> = |(cx, props)| {
 
             // Can pass in props directly as an expression
             {{
-                let props = TallerProps {a: "hello"};
+                let props = TallerProps {a: "hello", children: Default::default()};
                 rsx!(Taller { ..props })
             }}
 
             // Spreading can also be overridden manually
             Taller {
-                ..TallerProps { a: "ballin!" }
+                ..TallerProps { a: "ballin!", children: Default::default() }
                 a: "not ballin!"
             }
 
@@ -180,7 +180,7 @@ pub static Example: FC<()> = |(cx, props)| {
 
 mod baller {
     use super::*;
-    #[derive(PartialEq, Props)]
+    #[derive(Props, PartialEq)]
     pub struct BallerProps {}
 
     /// This component totally balls
@@ -189,13 +189,16 @@ mod baller {
     }
 }
 
-#[derive(Debug, PartialEq, Props)]
-pub struct TallerProps {
+#[derive(Props)]
+pub struct TallerProps<'a> {
     a: &'static str,
+
+    #[builder(default)]
+    children: ScopeChildren<'a>,
 }
 
 /// This component is taller than most :)
-pub fn Taller(_: Scope<TallerProps>) -> Element {
+pub fn Taller<'a>(_: Scope<'a, TallerProps<'a>>) -> Element {
     let b = true;
     todo!()
 }

+ 0 - 0
packages/ssr/examples/basic.rs → examples/ssr/basic.rs


+ 0 - 0
packages/ssr/examples/hydration.rs → examples/ssr/hydration.rs


+ 0 - 0
packages/ssr/examples/template.html → examples/ssr/template.html


+ 0 - 0
packages/ssr/examples/tide.rs → examples/ssr/tide.rs


+ 5 - 5
packages/ssr/examples/tofile.rs → examples/ssr/tofile.rs

@@ -119,14 +119,14 @@ pub static Entry: FC<()> = |(cx, props)| {
 pub static StacksIcon: FC<()> = |(cx, props)| {
     cx.render(rsx!(
         svg {
-            // xmlns: "http://www.w3.org/2000/svg"
+            xmlns: "http://www.w3.org/2000/svg"
             fill: "none"
             stroke: "currentColor"
             stroke_linecap: "round"
             stroke_linejoin: "round"
             stroke_width: "2"
-            // class: "w-10 h-10 text-white p-2 bg-indigo-500 rounded-full"
-            viewBox: "0 0 24 24"
+            class: "w-10 h-10 text-white p-2 bg-indigo-500 rounded-full"
+            view_box: "0 0 24 24"
             path { d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"}
         }
     ))
@@ -139,8 +139,8 @@ pub static RightArrowIcon: FC<()> = |(cx, props)| {
             stroke_linecap: "round"
             stroke_linejoin: "round"
             stroke_width: "2"
-            // class: "w-4 h-4 ml-1"
-            viewBox: "0 0 24 24"
+            class: "w-4 h-4 ml-1"
+            view_box: "0 0 24 24"
             path { d: "M5 12h14M12 5l7 7-7 7"}
         }
     ))

+ 2 - 2
examples/tailwind.rs

@@ -117,7 +117,7 @@ pub static StacksIcon: FC<()> = |(cx, props)| {
             stroke_linejoin: "round"
             stroke_width: "2"
             class: "w-10 h-10 text-white p-2 bg-indigo-500 rounded-full"
-            viewBox: "0 0 24 24"
+            view_box: "0 0 24 24"
             path { d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"}
         }
     ))
@@ -131,7 +131,7 @@ pub static RightArrowIcon: FC<()> = |(cx, props)| {
             stroke_linejoin: "round"
             stroke_width: "2"
             class: "w-4 h-4 ml-1"
-            viewBox: "0 0 24 24"
+            view_box: "0 0 24 24"
             path { d: "M5 12h14M12 5l7 7-7 7"}
         }
     ))

+ 5 - 5
examples/todomvc.rs

@@ -23,9 +23,9 @@ pub struct TodoItem {
 
 const STYLE: &str = include_str!("./assets/todomvc.css");
 const App: FC<()> = |(cx, props)| {
-    let draft = use_state(cx, || "".to_string());
-    let todos = use_state(cx, || HashMap::<u32, Rc<TodoItem>>::new());
-    let filter = use_state(cx, || FilterState::All);
+    let mut draft = use_state(cx, || "".to_string());
+    let mut todos = use_state(cx, || HashMap::<u32, Rc<TodoItem>>::new());
+    let mut filter = use_state(cx, || FilterState::All);
 
     let todolist = todos
         .iter()
@@ -86,8 +86,8 @@ pub struct TodoEntryProps {
 }
 
 pub fn TodoEntry((cx, props): Scope<TodoEntryProps>) -> Element {
-    let is_editing = use_state(cx, || false);
-    let contents = use_state(cx, || String::from(""));
+    let mut is_editing = use_state(cx, || false);
+    let mut contents = use_state(cx, || String::from(""));
     let todo = &props.todo;
 
     rsx!(cx, li {

+ 1 - 1
examples/weather_app.rs

@@ -26,7 +26,7 @@ static App: FC<()> = |(cx, props)| {
         },
         |cx, props| {
             //
-            rsx!(cx, WeatherDisplay {})
+            rsx!(WeatherDisplay {})
         },
     );
 

+ 0 - 0
packages/web/examples/async_web.rs → examples/web/async_web.rs


+ 0 - 0
packages/web/examples/basic.rs → examples/web/basic.rs


+ 0 - 0
packages/web/examples/blah.rs → examples/web/blah.rs


+ 0 - 0
packages/web/examples/btns.rs → examples/web/btns.rs


+ 0 - 0
packages/web/examples/crm2.rs → examples/web/crm2.rs


+ 0 - 0
packages/web/examples/demo.rs → examples/web/demo.rs


+ 0 - 1
examples/webview_web.rs

@@ -22,7 +22,6 @@ static App: FC<()> = |(cx, props)| {
     cx.render(rsx! {
         div {
             h1 { "Hifive counter: {count}" }
-            {cx.children()}
             button { onclick: move |_| count += 1, "Up high!" }
             button { onclick: move |_| count -= 1, "Down low!" }
         }

+ 1 - 0
packages/core/benches/jsframework.rs

@@ -19,6 +19,7 @@ use dioxus_core_macro::*;
 use dioxus_html as dioxus_elements;
 use rand::prelude::*;
 
+fn main() {}
 criterion_group!(mbenches, create_rows);
 criterion_main!(mbenches);
 

+ 30 - 9
packages/core/src/component.rs

@@ -5,7 +5,10 @@
 //! if the type supports PartialEq. The Properties trait is used by the rsx! and html! macros to generate the type-safe builder
 //! that ensures compile-time required and optional fields on cx.
 
-use crate::innerlude::{Context, Element, VNode};
+use crate::{
+    innerlude::{Context, Element, VAnchor, VFragment, VNode},
+    LazyNodes, ScopeChildren,
+};
 /// A component is a wrapper around a Context and some Props that share a lifetime
 ///
 ///
@@ -41,23 +44,39 @@ use crate::innerlude::{Context, Element, VNode};
 pub type Scope<'a, T> = (Context<'a>, &'a T);
 
 pub struct FragmentProps<'a> {
-    childen: &'a VNode<'a>,
+    children: ScopeChildren<'a>,
 }
-pub struct FragmentPropsBuilder<'a> {
-    childen: Option<&'a VNode<'a>>,
+
+pub struct FragmentBuilder<'a, const BUILT: bool> {
+    children: Option<ScopeChildren<'a>>,
+}
+impl<'a> FragmentBuilder<'a, false> {
+    pub fn children(mut self, children: ScopeChildren<'a>) -> FragmentBuilder<'a, true> {
+        FragmentBuilder {
+            children: Some(children),
+        }
+    }
+}
+
+impl<'a, const A: bool> FragmentBuilder<'a, A> {
+    pub fn build(self) -> FragmentProps<'a> {
+        FragmentProps {
+            children: self.children.unwrap_or_default(),
+        }
+    }
 }
 
 impl<'a> Properties for FragmentProps<'a> {
-    type Builder = FragmentPropsBuilder<'a>;
+    type Builder = FragmentBuilder<'a, false>;
 
     const IS_STATIC: bool = false;
 
     fn builder() -> Self::Builder {
-        todo!()
+        FragmentBuilder { children: None }
     }
 
     unsafe fn memoize(&self, other: &Self) -> bool {
-        todo!()
+        false
     }
 }
 
@@ -83,8 +102,10 @@ impl<'a> Properties for FragmentProps<'a> {
 /// You want to use this free-function when your fragment needs a key and simply returning multiple nodes from rsx! won't cut it.
 ///
 #[allow(non_upper_case_globals, non_snake_case)]
-pub fn Fragment<'a>((_, props): Scope<'a, FragmentProps<'a>>) -> Element<'a> {
-    Some(props.childen.decouple())
+pub fn Fragment<'a>((cx, props): Scope<'a, FragmentProps<'a>>) -> Element<'a> {
+    cx.render(Some(LazyNodes::new(|f| {
+        f.fragment_from_iter(&props.children)
+    })))
 }
 
 /// Every "Props" used for a component must implement the `Properties` trait. This trait gives some hints to Dioxus

+ 5 - 3
packages/core/src/lazynodes.rs

@@ -11,7 +11,7 @@
 //! The logic for this was borrowed from https://docs.rs/stack_dst/0.6.1/stack_dst/. Unfortunately, this crate does not
 //! support non-static closures, so we've implemented the core logic of `ValueA` in this module.
 
-use crate::innerlude::{NodeFactory, VNode};
+use crate::prelude::{NodeFactory, VNode};
 use std::mem;
 
 /// A concrete type provider for closures that build VNode structures.
@@ -27,7 +27,7 @@ pub struct LazyNodes<'a, 'b> {
     inner: StackNodeStorage<'a, 'b>,
 }
 
-type StackHeapSize = [usize; 12];
+type StackHeapSize = [usize; 0];
 
 enum StackNodeStorage<'a, 'b> {
     Stack(LazyStack),
@@ -77,7 +77,7 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
                 }
             } else {
                 log::debug!("lazy nodes fits on stack!");
-                let mut buf: StackHeapSize = [0; 12];
+                let mut buf: StackHeapSize = StackHeapSize::default();
 
                 assert!(info.len() + round_to_words(size) <= buf.as_ref().len());
 
@@ -97,6 +97,8 @@ impl<'a, 'b> LazyNodes<'a, 'b> {
                     *dataptr.add(i) = *src_ptr.add(i);
                 }
 
+                std::mem::forget(val);
+
                 Self {
                     inner: StackNodeStorage::Stack(LazyStack { _align: [], buf }),
                 }

+ 3 - 3
packages/core/src/lib.rs

@@ -65,9 +65,9 @@ pub(crate) mod innerlude {
 }
 
 pub use crate::innerlude::{
-    Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, MountType, Mutations,
-    NodeFactory, Properties, SchedulerMsg, ScopeChildren, ScopeId, SuspendedContext, TaskHandle,
-    TestDom, ThreadsafeVirtualDom, UserEvent, VNode, VirtualDom, FC,
+    Context, DioxusElement, DomEdit, Element, ElementId, EventPriority, LazyNodes, MountType,
+    Mutations, NodeFactory, Properties, SchedulerMsg, ScopeChildren, ScopeId, SuspendedContext,
+    TaskHandle, TestDom, ThreadsafeVirtualDom, UserEvent, VNode, VirtualDom, FC,
 };
 
 pub mod prelude {

+ 4 - 1
packages/core/src/nodes.rs

@@ -765,6 +765,9 @@ impl<'a> ScopeChildren<'a> {
     pub fn new(root: VNode<'a>) -> Self {
         Self { root: Some(root) }
     }
+    pub fn new_option(root: Option<VNode<'a>>) -> Self {
+        Self { root }
+    }
 }
 
 impl IntoIterator for &ScopeChildren<'_> {
@@ -773,7 +776,7 @@ impl IntoIterator for &ScopeChildren<'_> {
     type IntoIter = std::iter::Once<Self>;
 
     fn into_iter(self) -> Self::IntoIter {
-        todo!()
+        std::iter::once(self)
     }
 }
 

+ 1 - 20
packages/core/tests/create_dom.rs

@@ -303,27 +303,8 @@ fn anchors() {
 #[test]
 fn suspended() {
     static App: FC<()> = |(cx, props)| {
-        let val = use_suspense(
-            cx,
-            || async {
-                //
-            },
-            |cx, p| todo!(),
-            // |cx, p| rsx! { "hi "},
-        );
-
-        // let prom = use_task(fetch());
+        let val = use_suspense(cx, || async {}, |cx, p| todo!());
 
-        // Value {
-        //     a: value.await,
-        //     b: value.await,
-        //     f: a.await
-        //     div {
-        //         div {
-        //             hidden: should_hide.await,
-        //         }
-        //     }
-        // }
         cx.render(rsx! { {val} })
     };
 

+ 0 - 3
packages/desktop/Cargo.toml

@@ -34,6 +34,3 @@ tokio_runtime = ["tokio"]
 dioxus-html = { path = "../html" }
 dioxus-hooks = { path = "../hooks" }
 simple_logger = "1.13.0"
-
-
-[build-dependencies]

+ 7 - 3
packages/desktop/src/desktop_context.rs

@@ -1,6 +1,7 @@
 use std::cell::RefCell;
 
 use dioxus::prelude::Scope;
+use dioxus::ScopeChildren;
 use dioxus_core as dioxus;
 use dioxus_core::{Context, Element, LazyNodes, NodeFactory, Properties};
 use dioxus_core_macro::Props;
@@ -42,6 +43,8 @@ pub struct WebviewWindowProps<'a> {
 
     /// focuse me
     onfocused: &'a dyn FnMut(()),
+
+    children: ScopeChildren<'a>,
 }
 
 /// A handle to a
@@ -70,9 +73,10 @@ pub fn WebviewWindow<'a>((cx, props): Scope<'a, WebviewWindowProps>) -> Element<
     );
 
     // render the children directly
-    cx.render(LazyNodes::new(move |f: NodeFactory| {
-        f.fragment_from_iter(cx.children())
-    }))
+    todo!()
+    // cx.render(LazyNodes::new(move |f: NodeFactory| {
+    //     f.fragment_from_iter(cx.children())
+    // }))
 }
 
 pub struct WindowHandle {}

+ 2 - 0
packages/desktop/src/index.html

@@ -13,6 +13,8 @@
             position: fixed;
         }
     </style> -->
+    <link rel="stylesheet" href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css">
+    <script src="https://cdn.plot.ly/plotly-1.52.3.min.js"></script>
 </head>
 
 

+ 41 - 6
packages/desktop/src/lib.rs

@@ -20,9 +20,9 @@ use serde::{Deserialize, Serialize};
 pub use wry;
 
 use wry::application::accelerator::{Accelerator, SysMods};
-use wry::application::event::{Event, StartCause, WindowEvent};
+use wry::application::event::{ElementState, Event, StartCause, WindowEvent};
 use wry::application::event_loop::{self, ControlFlow, EventLoop};
-use wry::application::keyboard::KeyCode;
+use wry::application::keyboard::{Key, KeyCode, ModifiersState};
 use wry::application::menu::{MenuBar, MenuItem, MenuItemAttributes};
 use wry::application::window::Fullscreen;
 use wry::webview::{WebView, WebViewBuilder};
@@ -94,6 +94,11 @@ pub fn run<T: 'static + Send + Sync>(
 
     let props_shared = Cell::new(Some(props));
 
+    // create local modifier state
+    let mut modifiers = ModifiersState::default();
+
+    let quit_hotkey = Accelerator::new(SysMods::Cmd, KeyCode::KeyQ);
+
     event_loop.run(move |event, event_loop, control_flow| {
         *control_flow = ControlFlow::Wait;
 
@@ -112,10 +117,8 @@ pub fn run<T: 'static + Send + Sync>(
                 first_menu.add_native_item(MenuItem::HideOthers);
                 first_menu.add_native_item(MenuItem::ShowAll);
 
-                let quit_item = first_menu.add_item(
-                    MenuItemAttributes::new("Quit")
-                        .with_accelerators(&Accelerator::new(SysMods::Cmd, KeyCode::KeyQ)),
-                );
+                first_menu.add_native_item(MenuItem::Quit);
+                first_menu.add_native_item(MenuItem::CloseWindow);
 
                 // create second menu
                 let mut second_menu = MenuBar::new();
@@ -129,6 +132,7 @@ pub fn run<T: 'static + Send + Sync>(
                 menu_bar_menu.add_submenu("Second menu", true, second_menu);
 
                 let window = WindowBuilder::new()
+                    .with_maximized(true)
                     .with_menu(menu_bar_menu)
                     .with_title("Dioxus App")
                     .build(event_loop)
@@ -197,6 +201,37 @@ pub fn run<T: 'static + Send + Sync>(
                 event, window_id, ..
             } => match event {
                 WindowEvent::CloseRequested => *control_flow = ControlFlow::Exit,
+                WindowEvent::Destroyed { .. } => {
+                    webviews.remove(&window_id);
+                    if webviews.is_empty() {
+                        *control_flow = ControlFlow::Exit;
+                    }
+                }
+                // catch only pressed event
+                WindowEvent::KeyboardInput { event, .. } => {
+                    log::debug!("keybowrd input");
+                    if quit_hotkey.matches(&modifiers, &event.physical_key) {
+                        log::debug!("quitting");
+
+                        webviews.remove(&window_id);
+                        if webviews.is_empty() {
+                            *control_flow = ControlFlow::Exit;
+                        }
+                    }
+
+                    // println!(
+                    //     "KeyEvent:  `Shift` + `1` | logical_key: {:?}",
+                    //     &event.logical_key
+                    // );
+                    // we can match manually without `Accelerator`
+
+                    // else if event.key_without_modifiers() == Key::Character("1")
+                    //     && modifiers.is_empty()
+                    // {
+                    //     println!("KeyEvent: `1`");
+                    // }
+                }
+
                 WindowEvent::Resized(_) | WindowEvent::Moved(_) => {
                     if let Some(view) = webviews.get_mut(&window_id) {
                         let _ = view.resize();

+ 0 - 52
packages/hooks/examples/lifecycle.rs

@@ -1,52 +0,0 @@
-fn main() {}
-
-// struct CompState {
-//     tasks: Vec<()>,
-// }
-// enum Actions {
-//     Add,
-//     MoveUp,
-//     MoveDown,
-//     Remvoe,
-// }
-
-// static Component: FC<()> = |(cx, props)|{
-//     let (tasks, dispatch) = use_reducer(
-//         cx,
-//         || CompState { tasks: Vec::new() },
-//         |state, action: Actions| match action {
-//             Actions::Add => state,
-//             Actions::MoveUp => state,
-//             Actions::MoveDown => state,
-//             Actions::Remvoe => state,
-//         },
-//     );
-
-//     let tasklist = { (0..10).map(|f| html! { <li></li> }) }.collect::<Vec<_>>();
-
-//     html! {
-//         <div>
-//             <div>
-//                 <h1>"Tasks: "</h1>
-//                 <ul>
-//                     {tasklist}
-//                 </ul>
-//             </div>
-//             <div>
-//                 <button onclick=|_| dispatch(Action::Add)>{"Add"}</button>
-//                 <button onclick=|_| dispatch(Action::MoveUp)>{"MoveUp"}</button>
-//                 <button onclick=|_| dispatch(Action::MoveDown)>{"MoveDown"}</button>
-//                 <button onclick=|_| dispatch(Action::Remvoe)>{"Remvoe"}</button>
-//             </div>
-//         </div>
-//     }
-// };
-
-// fn use_reducer<Props, State, Action>(
-//     cx: &mut Context<Props>,
-//     init: fn() -> State,
-//     reducer: fn(State, Action) -> State,
-// ) -> (State, impl Fn(Action)) {
-//     let ii = init();
-//     (ii, |_| {})
-// }

+ 0 - 1
packages/hooks/examples/reducer.rs

@@ -1 +0,0 @@
-fn main() {}

+ 1 - 1
packages/hooks/src/use_shared_state.rs

@@ -126,7 +126,7 @@ impl<'a, T: 'static> UseSharedState<'a, T> {
     ///
     ///
     /// TODO: We prevent unncessary notifications only in the hook, but we should figure out some more global lock
-    pub fn write(&mut self) -> RefMut<'_, T> {
+    pub fn write(&self) -> RefMut<'_, T> {
         self.cx.needs_update();
         self.notify_consumers();
         self.value.borrow_mut()

+ 1 - 1
packages/hooks/src/usestate.rs

@@ -102,7 +102,7 @@ impl<'a, T: 'static> UseState<'a, T> {
         }
     }
 
-    pub fn set(&mut self, new_val: T) {
+    pub fn set(&self, new_val: T) {
         *self.inner.wip.borrow_mut() = Some(new_val);
         self.needs_update();
     }

+ 0 - 28
packages/router/examples/blog.rs

@@ -1,28 +0,0 @@
-use dioxus::prelude::*;
-
-fn main() {}
-
-enum Routes {
-    Home,
-    Blog,
-}
-
-static App: FC<()> = |(cx, props)| {
-    let route = use_router::<Routes>(cx);
-
-    let content = match route {
-        Routes::Home => rsx!(Home {}),
-        Routes::Blog => rsx!(Blog {}),
-    };
-
-    cx.render(rsx! {
-        {content}
-    })
-};
-
-fn use_router<P>(cx: Context) -> &P {
-    todo!()
-}
-
-static Home: FC<()> = |(cx, props)| todo!();
-static Blog: FC<()> = |(cx, props)| todo!();

+ 4 - 10
packages/ssr/src/lib.rs

@@ -31,10 +31,7 @@ impl SsrRenderer {
         }
     }
 
-    pub fn render_lazy<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>>(
-        &'a mut self,
-        f: LazyNodes<'a, F>,
-    ) -> String {
+    pub fn render_lazy<'a>(&'a mut self, f: Option<LazyNodes<'a, '_>>) -> String {
         let bump = &mut self.inner as *mut _;
         let s = self.render_inner(f);
         // reuse the bump's memory
@@ -42,10 +39,7 @@ impl SsrRenderer {
         s
     }
 
-    fn render_inner<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>>(
-        &'a self,
-        f: LazyNodes<'a, F>,
-    ) -> String {
+    fn render_inner<'a>(&'a self, f: Option<LazyNodes<'a, '_>>) -> String {
         let factory = NodeFactory::new(&self.inner);
         let root = f.into_vnode(factory);
         format!(
@@ -59,7 +53,7 @@ impl SsrRenderer {
     }
 }
 
-pub fn render_lazy<'a, F: FnOnce(NodeFactory<'a>) -> VNode<'a>>(f: LazyNodes<'a, F>) -> String {
+pub fn render_lazy<'a>(f: Option<LazyNodes<'a, '_>>) -> String {
     let bump = bumpalo::Bump::new();
     let borrowed = &bump;
 
@@ -398,7 +392,7 @@ mod tests {
     fn styles() {
         static STLYE_APP: FC<()> = |(cx, _)| {
             cx.render(rsx! {
-                div { style: { color: "blue", font_size: "46px" } }
+                div { color: "blue", font_size: "46px"  }
             })
         };
 

+ 0 - 3
packages/web/.vscode/settings.json

@@ -1,3 +0,0 @@
-{
-    "rust-analyzer.inlayHints.enable": false
-}

+ 0 - 8
packages/webview-client/Cargo.toml

@@ -1,8 +0,0 @@
-[package]
-name = "dioxus-webview-client"
-version = "0.0.0"
-edition = "2018"
-
-# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
-
-[dependencies]

+ 0 - 8
packages/webview-client/README.md

@@ -1,8 +0,0 @@
-# the client part of the vdom
-
-
-this crate is designed to be the "receiving end" of the dioxus virtualdom, using wasm_bindgen to expose an API for the receiving end.
-
-
-
-

+ 0 - 3
packages/webview-client/src/main.rs

@@ -1,3 +0,0 @@
-fn main() {
-    println!("Hello, world!");
-}