From 04d16b41dc9bc06ca0320a9fec27744318e48355 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Fri, 24 Sep 2021 02:37:51 -0400 Subject: [PATCH] polish: exampels --- examples/file_explorer.rs | 36 +++++----- examples/framework_benchmark.rs | 73 ++++++++------------- examples/hydration.rs | 1 + examples/manual_edits.rs | 40 +++++++++++ examples/manually.rs | 22 ------- examples/{model.rs => pattern_model.rs} | 0 examples/{reducer.rs => pattern_reducer.rs} | 0 packages/core/src/events.rs | 6 +- 8 files changed, 90 insertions(+), 88 deletions(-) create mode 100644 examples/manual_edits.rs delete mode 100644 examples/manually.rs rename examples/{model.rs => pattern_model.rs} (100%) rename examples/{reducer.rs => pattern_reducer.rs} (100%) diff --git a/examples/file_explorer.rs b/examples/file_explorer.rs index da543e5c3..e6fadc989 100644 --- a/examples/file_explorer.rs +++ b/examples/file_explorer.rs @@ -5,52 +5,50 @@ //! //! This example is interesting because it's mixing filesystem operations and GUI, which is typically hard for UI to do. -use dioxus::desktop::wry::application::dpi::LogicalSize; use dioxus::prelude::*; fn main() { env_logger::init(); dioxus::desktop::launch(App, |c| { c.with_window(|w| { - w.with_resizable(false) - .with_inner_size(LogicalSize::new(800.0, 400.0)) + w.with_resizable(false).with_inner_size( + dioxus::desktop::wry::application::dpi::LogicalSize::new(800.0, 400.0), + ) }) }) .unwrap(); } static App: FC<()> = |cx, props| { - let files = use_state(cx, || Files::new()); + let file_manager = use_ref(cx, || Files::new()); + let files = file_manager.read(); let file_list = files.path_names.iter().enumerate().map(|(dir_id, path)| { rsx! ( - li { a {"{path}", onclick: move |_| files.modify().enter_dir(dir_id), href: "#"} } + li { a {"{path}", onclick: move |_| file_manager.write().enter_dir(dir_id), href: "#"} } ) }); let err_disp = files.err.as_ref().map(|err| { - rsx! { + rsx! ( div { code {"{err}"} - button {"x", onclick: move |_| files.modify().clear_err() } + button {"x", onclick: move |_| file_manager.write().clear_err() } } - } + ) }); - let cur = files.current(); - cx.render(rsx! { - div { - h1 {"Files: "} - h3 {"Cur dir: {cur}"} - button { "go up", onclick: move |_| files.modify().go_up() } - ol { {file_list} } - {err_disp} - } + let current_dir = files.current(); + + rsx!(cx, div { + h1 {"Files: "} + h3 {"Cur dir: {current_dir}"} + button { "go up", onclick: move |_| file_manager.write().go_up() } + ol { {file_list} } + {err_disp} }) }; -// right now, this gets cloned every time. It might be a bit better to use im_rc's collections instead -#[derive(Clone)] struct Files { path_stack: Vec, path_names: Vec, diff --git a/examples/framework_benchmark.rs b/examples/framework_benchmark.rs index 8927198a9..25a772cf0 100644 --- a/examples/framework_benchmark.rs +++ b/examples/framework_benchmark.rs @@ -1,25 +1,15 @@ -//! JS Framework Benchmark -//! ---------------------- -//! -//! This example is used in the JS framework benchmarking tool to compare Dioxus' performance with other frontend frameworks. -//! -//! -//! - -use dioxus::{events::on::MouseEvent, prelude::*}; -use dioxus_html as dioxus_elements; -use fxhash::{FxBuildHasher, FxHasher32}; +use dioxus::{events::MouseEvent, prelude::*}; +use fxhash::FxBuildHasher; use std::rc::Rc; fn main() { - log::debug!("starting!"); - dioxus::desktop::launch(App, |c| c); + dioxus::desktop::launch(App, |c| c).unwrap(); } // We use a special immutable hashmap to make hashmap operations efficient type RowList = im_rc::HashMap, FxBuildHasher>; -static App: FC<()> = |cx, props| { +static App: FC<()> = |cx, _props| { let items = use_state(cx, || RowList::default()); let create_rendered_rows = move |from, num| move |_| items.set(create_row_list(from, num)); @@ -63,12 +53,12 @@ static App: FC<()> = |cx, props| { div { class: "col-md-6", h1 { "Dioxus" } } div { class: "col-md-6" div { class: "row" - ActionButton { name: "Create 1,000 rows", id: "run", action: create_rendered_rows(0, 1_000) } - ActionButton { name: "Create 10,000 rows", id: "runlots", action: create_rendered_rows(0, 10_000) } - ActionButton { name: "Append 1,000 rows", id: "add", action: append_1_000_rows } - ActionButton { name: "Update every 10th row", id: "update", action: update_every_10th_row, } - ActionButton { name: "Clear", id: "clear", action: clear_rows } - ActionButton { name: "Swap rows", id: "swaprows", action: swap_rows } + ActionButton { name: "Create 1,000 rows", id: "run", onclick: {create_rendered_rows(0, 1_000)} } + ActionButton { name: "Create 10,000 rows", id: "runlots", onclick: {create_rendered_rows(0, 10_000)} } + ActionButton { name: "Append 1,000 rows", id: "add", onclick: {append_1_000_rows} } + ActionButton { name: "Update every 10th row", id: "update", onclick: {update_every_10th_row} } + ActionButton { name: "Clear", id: "clear", onclick: {clear_rows} } + ActionButton { name: "Swap rows", id: "swaprows", onclick: {swap_rows} } } } } @@ -83,24 +73,17 @@ static App: FC<()> = |cx, props| { }) }; -#[derive(Clone)] -struct RowController {} - #[derive(Props)] -struct ActionButtonProps { +struct ActionButtonProps<'a> { name: &'static str, id: &'static str, - action: F, + onclick: &'a dyn Fn(MouseEvent), } -fn ActionButton<'a, F>(cx: Context<'a>, props: &'a ActionButtonProps) -> DomTree<'a> -where - F: Fn(MouseEvent), -{ - cx.render(rsx! { - div { class: "col-sm-6 smallpad" - button { class:"btn btn-primary btn-block", r#type: "button", id: "{props.id}", onclick: {&props.action}, - "{props.name}" - } + +fn ActionButton<'a>(cx: Context<'a>, props: &'a ActionButtonProps) -> DomTree<'a> { + rsx!(cx, div { class: "col-sm-6 smallpad" + button { class:"btn btn-primary btn-block", r#type: "button", id: "{props.id}", onclick: {props.onclick}, + "{props.name}" } }) } @@ -111,19 +94,17 @@ struct RowProps { label: Rc, } fn Row<'a>(cx: Context<'a>, props: &'a RowProps) -> DomTree<'a> { - cx.render(rsx! { - tr { - td { class:"col-md-1", "{props.row_id}" } - td { class:"col-md-1", onclick: move |_| { /* run onselect */ } - a { class: "lbl", "{props.label}" } - } - td { class: "col-md-1" - a { class: "remove", onclick: move |_| {/* remove */} - span { class: "glyphicon glyphicon-remove remove" aria_hidden: "true" } - } - } - td { class: "col-md-6" } + rsx!(cx, tr { + td { class:"col-md-1", "{props.row_id}" } + td { class:"col-md-1", onclick: move |_| { /* run onselect */ } + a { class: "lbl", "{props.label}" } } + td { class: "col-md-1" + a { class: "remove", onclick: move |_| {/* remove */} + span { class: "glyphicon glyphicon-remove remove" aria_hidden: "true" } + } + } + td { class: "col-md-6" } }) } diff --git a/examples/hydration.rs b/examples/hydration.rs index a661ae842..55fd02226 100644 --- a/examples/hydration.rs +++ b/examples/hydration.rs @@ -21,6 +21,7 @@ fn main() { static App: FC<()> = |cx, props| { let mut val = use_state(cx, || 0); + cx.render(rsx! { div { h1 {"hello world. Count: {val}"} diff --git a/examples/manual_edits.rs b/examples/manual_edits.rs new file mode 100644 index 000000000..57150c9a2 --- /dev/null +++ b/examples/manual_edits.rs @@ -0,0 +1,40 @@ +/* +Example: Manual Edits + +It's possible to manually provide a stream of DomEdits to a Dioxus Renderer. All renderers are designed to accept a stream +of DomEdits that abstract over a stack machine. This allows the VirtualDOM to exist entirely separately from the RealDOM, +though features like NodeRefs and NativeEvents might not work properly everywhere. +*/ + +use dioxus::core::*; +use dioxus::prelude::*; + +fn main() { + use DomEdit::*; + + let edits = vec![ + // create a container and push it onto the stack + CreateElement { tag: "div", id: 0 }, + // create an element and push it onto the stack + CreateElement { tag: "h1", id: 2 }, + // create a text node and push it onto the stack + CreateTextNode { + text: "hello world", + id: 3, + }, + // append the text node to the h1 element + AppendChildren { many: 1 }, + // append the h1 element to the container + AppendChildren { many: 1 }, + // append the container to the default render element ("dioxusroot" if used with default config) + AppendChildren { many: 1 }, + ]; + + dioxus_desktop::WebviewRenderer::run_with_edits(APP, (), |c| c, Some(edits)).expect("failed"); +} + +const APP: FC<()> = |cx, _props| { + rsx!(cx, div { + "some app" + }) +}; diff --git a/examples/manually.rs b/examples/manually.rs deleted file mode 100644 index 584b91756..000000000 --- a/examples/manually.rs +++ /dev/null @@ -1,22 +0,0 @@ -use dioxus_core::*; - -fn main() { - use DomEdit::*; - - // .. should result in an "invalid node tree" - let edits = vec![ - CreateElement { tag: "div", id: 0 }, - CreateElement { tag: "h1", id: 2 }, - CreateTextNode { - text: "hello world", - id: 3, - }, - AppendChildren { many: 1 }, - AppendChildren { many: 1 }, - AppendChildren { many: 1 }, - ]; - - dioxus_desktop::WebviewRenderer::run_with_edits(App, (), |c| c, Some(edits)).expect("failed"); -} - -const App: FC<()> = |cx, props| todo!(); diff --git a/examples/model.rs b/examples/pattern_model.rs similarity index 100% rename from examples/model.rs rename to examples/pattern_model.rs diff --git a/examples/reducer.rs b/examples/pattern_reducer.rs similarity index 100% rename from examples/reducer.rs rename to examples/pattern_reducer.rs diff --git a/packages/core/src/events.rs b/packages/core/src/events.rs index e11127e43..7b01a26a9 100644 --- a/packages/core/src/events.rs +++ b/packages/core/src/events.rs @@ -188,7 +188,11 @@ pub(crate) fn event_meta(event: &UserEvent) -> (bool, EventPriority) { } } -pub use on::KeyCode; +pub use on::{ + AnimationEvent, ClipboardEvent, CompositionEvent, FocusEvent, FormEvent, GenericEvent, KeyCode, + KeyboardEvent, MediaEvent, MouseEvent, PointerEvent, SelectionEvent, ToggleEvent, TouchEvent, + TransitionEvent, WheelEvent, +}; pub mod on { //! This module defines the synthetic events that all Dioxus apps enable. No matter the platform, every dioxus renderer