diff --git a/examples/_examples/anim.rs b/examples/_examples/anim.rs deleted file mode 100644 index a441f5827..000000000 --- a/examples/_examples/anim.rs +++ /dev/null @@ -1,49 +0,0 @@ -fn main() { - // render the - let transition = move |cx, (width, height)| {}; - - cx.render(rsx! { - div { - Transition { - start: (0, 5), - stop: (10, 10), - render: transition - } - - Transition { - start: (0, 5), - stop: (10, 10), - render: move |cx, (width, height)| { - // - cx.render(rsx!{ - div { - style { - width: width, - width: height - } - } - }) - } - } - } - }) -} - -// Animations with signals -fn signal_based(cx: ()) { - const InitPos: (i32, i32) = (0, 0); - const EndPos: (i32, i32) = (100, 200); - - let spring = use_spring(cx, move |spring| spring.from(InitPos).to(EndPos)); - - cx.render(rsx! { - div { - style: [ - width: spring.0, - height: spring.1 - ] - button { onclick: move |_| spring.set(InitPos), "Reset" } - button { onclick: move |_| spring.set(EndPos), "Animate" } - } - }) -} diff --git a/examples/_examples/basic.rs b/examples/_examples/basic.rs deleted file mode 100644 index d1f943ec5..000000000 --- a/examples/_examples/basic.rs +++ /dev/null @@ -1,57 +0,0 @@ -//! Basic example that renders a simple VNode to the browser. - -use dioxus::events::on::MouseEvent; -use dioxus_core as dioxus; -use dioxus_core::prelude::*; -use dioxus_html as dioxus_elements; -use dioxus_web::*; - -fn main() { - // Setup logging - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - - // Run the app - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -static App: FC<()> = |cx, props| { - let (state, set_state) = use_state_classic(cx, || 0); - cx.render(rsx! { - div { - section { class: "py-12 px-4 text-center" - div { class: "w-full max-w-2xl mx-auto" - span { class: "text-sm font-semibold" - "count: {state}" - } - div { - C1 { - onclick: move |_| set_state(state + 1) - "incr" - } - C1 { - onclick: move |_| set_state(state - 1) - "decr" - } - } - } - } - } - }) -}; - -#[derive(Props)] -struct IncrementerProps<'a> { - onclick: &'a dyn Fn(MouseEvent), -} - -fn C1<'a, 'b>(cx: Context<'a, IncrementerProps<'b>>) -> DomTree<'a> { - cx.render(rsx! { - button { - class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow" - onclick: {cx.onclick} - "becr" - {cx.children()} - } - }) -} diff --git a/examples/_examples/calculator.rs b/examples/_examples/calculator.rs deleted file mode 100644 index fee49b504..000000000 --- a/examples/_examples/calculator.rs +++ /dev/null @@ -1,188 +0,0 @@ -//! Example: Calculator -//! ------------------ -//! -//! This example showcases a basic iOS-style calculator app using classic react-style `use_state` hooks. A counterpart of -//! this example is in `model.rs` which shows the same calculator app implemented using the `model` paradigm. We've found -//! that the most natural Rust code is more "model-y" than "React-y", but opt to keep this example to show the different -//! flavors of programming you can use in Dioxus. - -use dioxus::events::on::*; -use dioxus::prelude::*; -use dioxus_core as dioxus; -use dioxus_html as dioxus_elements; -use dioxus_web::WebsysRenderer; - -const STYLE: &str = include_str!("../../../examples/assets/calculator.css"); - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -enum Operator { - Add, - Sub, - Mul, - Div, -} - -static App: FC<()> = |cx, props| { - let (cur_val, set_cur_val) = use_state_classic(cx, || 0.0_f64); - let (operator, set_operator) = use_state_classic(cx, || None as Option); - let (display_value, set_display_value) = use_state_classic(cx, || "0".to_string()); - - let clear_display = display_value.eq("0"); - let clear_text = if clear_display { "C" } else { "AC" }; - - let input_digit = move |num: u8| { - let mut new = if operator.is_some() { - String::new() - } else if display_value == "0" { - String::new() - } else { - display_value.clone() - }; - if operator.is_some() { - let val = display_value.parse::().unwrap(); - set_cur_val(val); - } - - new.push_str(num.to_string().as_str()); - set_display_value(new); - }; - - let input_dot = move || { - let mut new = display_value.clone(); - new.push_str("."); - set_display_value(new); - }; - - 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, - }; - set_cur_val(new_val); - set_display_value(new_val.to_string()); - set_operator(None); - } - }; - - let toggle_sign = move |_| { - if display_value.starts_with("-") { - set_display_value(display_value.trim_start_matches("-").to_string()) - } else { - set_display_value(format!("-{}", *display_value)) - } - }; - let toggle_percent = move |_| todo!(); - - let clear_key = move |_| { - set_display_value("0".to_string()); - if !clear_display { - set_operator(None); - set_cur_val(0.0); - } - }; - - let keydownhandler = move |evt: KeyboardEvent| match evt.key_code() { - KeyCode::Backspace => { - let mut new = display_value.clone(); - if !new.as_str().eq("0") { - new.pop(); - } - set_display_value(new); - } - KeyCode::_0 => input_digit(0), - KeyCode::_1 => input_digit(1), - KeyCode::_2 => input_digit(2), - KeyCode::_3 => input_digit(3), - KeyCode::_4 => input_digit(4), - KeyCode::_5 => input_digit(5), - KeyCode::_6 => input_digit(6), - KeyCode::_7 => input_digit(7), - KeyCode::_8 => input_digit(8), - KeyCode::_9 => input_digit(9), - KeyCode::Add => set_operator(Some(Operator::Add)), - KeyCode::Subtract => set_operator(Some(Operator::Sub)), - KeyCode::Divide => set_operator(Some(Operator::Div)), - KeyCode::Multiply => set_operator(Some(Operator::Mul)), - _ => {} - }; - - cx.render(rsx! { - div { - id: "wrapper" - div { class: "app" onkeydown: {keydownhandler} - style { "{STYLE}" } - div { class: "calculator", - CalculatorDisplay { val: &display_value} - div { class: "calculator-keypad" - div { class: "input-keys" - div { class: "function-keys" - CalculatorKey { name: "key-clear", onclick: {clear_key} "{clear_text}" } - CalculatorKey { name: "key-sign", onclick: {toggle_sign}, "±"} - CalculatorKey { name: "key-percent", onclick: {toggle_percent} "%"} - } - div { class: "digit-keys" - CalculatorKey { name: "key-0", onclick: move |_| input_digit(0), "0" } - CalculatorKey { name: "key-dot", onclick: move |_| input_dot(), "●" } - {(1..10).map(move |k| rsx!{ - CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| input_digit(k), "{k}" } - })} - } - } - div { class: "operator-keys" - CalculatorKey { name: "key-divide", onclick: move |_| set_operator(Some(Operator::Div)) "÷" } - CalculatorKey { name: "key-multiply", onclick: move |_| set_operator(Some(Operator::Mul)) "×" } - CalculatorKey { name: "key-subtract", onclick: move |_| set_operator(Some(Operator::Sub)) "−" } - CalculatorKey { name: "key-add", onclick: move |_| set_operator(Some(Operator::Add)) "+" } - CalculatorKey { name: "key-equals", onclick: move |_| perform_operation() "=" } - } - } - } - } - } - }) -}; - -#[derive(Props)] -struct CalculatorKeyProps<'a> { - /// Name! - name: &'static str, - - /// Click! - onclick: &'a dyn Fn(MouseEvent), -} - -fn CalculatorKey<'a, 'r>(cx: Context<'a, CalculatorKeyProps<'r>>) -> DomTree<'a> { - cx.render(rsx! { - button { - class: "calculator-key {cx.name}" - onclick: {cx.onclick} - {cx.children()} - } - }) -} - -#[derive(Props, PartialEq)] -struct CalculatorDisplayProps<'a> { - val: &'a str, -} - -fn CalculatorDisplay<'a>(cx: Context<'a, CalculatorDisplayProps>) -> DomTree<'a> { - use separator::Separatable; - // Todo, add float support to the num-format crate - let formatted = cx.val.parse::().unwrap().separated_string(); - // TODO: make it autoscaling with css - cx.render(rsx! { - div { class: "calculator-display" - div { class: "auto-scaling-text", "{formatted}" } - } - }) -} diff --git a/examples/_examples/calculator_.rs b/examples/_examples/calculator_.rs deleted file mode 100644 index 107794164..000000000 --- a/examples/_examples/calculator_.rs +++ /dev/null @@ -1,181 +0,0 @@ -use dioxus::events::on::*; -use dioxus::prelude::*; -use dioxus_core as dioxus; - -const STYLE: &str = include_str!("../../../examples/assets/calculator.css"); - -fn main() { - dioxus_desktop::launch( - |builder| { - builder - .title("Test Dioxus App") - .size(340, 560) - .resizable(false) - .debug(true) - }, - (), - App, - ) - .expect("Webview finished"); -} - -static App: FC<()> = |cx, props| { - let state = use_model(&cx, || Calculator::new()); - - let clear_display = state.display_value.eq("0"); - let clear_text = if clear_display { "C" } else { "AC" }; - let formatted = state.formatted_display(); - - cx.render(rsx! { - div { id: "wrapper" - div { class: "app", style { "{STYLE}" } - div { class: "calculator", onkeypress: move |evt| state.get_mut().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.get_mut().clear_display(), "{clear_text}" } - CalculatorKey { name: "key-sign", onclick: move |_| state.get_mut().toggle_sign(), "±"} - CalculatorKey { name: "key-percent", onclick: move |_| state.get_mut().toggle_percent(), "%"} - } - div { class: "digit-keys" - CalculatorKey { name: "key-0", onclick: move |_| state.get_mut().input_digit(0), "0" } - CalculatorKey { name: "key-dot", onclick: move |_| state.get_mut().input_dot(), "●" } - {(1..10).map(move |k| rsx!{ - CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| state.get_mut().input_digit(k), "{k}" } - })} - } - } - div { class: "operator-keys" - CalculatorKey { name:"key-divide", onclick: move |_| state.get_mut().set_operator(Operator::Div), "÷" } - CalculatorKey { name:"key-multiply", onclick: move |_| state.get_mut().set_operator(Operator::Mul), "×" } - CalculatorKey { name:"key-subtract", onclick: move |_| state.get_mut().set_operator(Operator::Sub), "−" } - CalculatorKey { name:"key-add", onclick: move |_| state.get_mut().set_operator(Operator::Add), "+" } - CalculatorKey { name:"key-equals", onclick: move |_| state.get_mut().perform_operation(), "=" } - } - } - } - } - } - }) -}; - -#[derive(Props)] -struct CalculatorKeyProps<'a> { - name: &'static str, - onclick: &'a dyn Fn(MouseEvent), -} - -fn CalculatorKey<'a, 'r>(cx: Context<'a, CalculatorKeyProps<'r>>) -> DomTree<'a> { - cx.render(rsx! { - button { - class: "calculator-key {cx.name}" - onclick: {cx.onclick} - {cx.children()} - } - }) -} - -#[derive(Clone)] -struct Calculator { - display_value: String, - operator: Option, - waiting_for_operand: bool, - cur_val: f64, -} -#[derive(Clone)] -enum Operator { - Add, - Sub, - Mul, - Div, -} - -impl Calculator { - fn new() -> Self { - Calculator { - display_value: "0".to_string(), - operator: None, - waiting_for_operand: false, - cur_val: 0.0, - } - } - fn formatted_display(&self) -> String { - // use separator::Separatable; - self.display_value.clone() - // .parse::() - // .unwrap() - // .separated_string() - } - fn clear_display(&mut self) { - self.display_value = "0".to_string(); - } - fn input_digit(&mut self, digit: u8) { - let content = digit.to_string(); - if self.waiting_for_operand || self.display_value == "0" { - self.waiting_for_operand = false; - self.display_value = content; - } else { - self.display_value.push_str(content.as_str()); - } - } - fn input_dot(&mut self) { - if self.display_value.find(".").is_none() { - self.display_value.push_str("."); - } - } - fn perform_operation(&mut self) { - if let Some(op) = &self.operator { - let rhs = self.display_value.parse::().unwrap(); - let new_val = match op { - Operator::Add => self.cur_val + rhs, - Operator::Sub => self.cur_val - rhs, - Operator::Mul => self.cur_val * rhs, - Operator::Div => self.cur_val / rhs, - }; - self.cur_val = new_val; - self.display_value = new_val.to_string(); - self.operator = None; - } - } - fn toggle_sign(&mut self) { - if self.display_value.starts_with("-") { - self.display_value = self.display_value.trim_start_matches("-").to_string(); - } else { - self.display_value = format!("-{}", self.display_value); - } - } - fn toggle_percent(&mut self) { - self.display_value = (self.display_value.parse::().unwrap() / 100.0).to_string(); - } - fn backspace(&mut self) { - if !self.display_value.as_str().eq("0") { - self.display_value.pop(); - } - } - fn set_operator(&mut self, operator: Operator) { - self.operator = Some(operator); - self.cur_val = self.display_value.parse::().unwrap(); - self.waiting_for_operand = true; - } - fn handle_keydown(&mut self, evt: KeyboardEvent) { - match evt.key_code() { - KeyCode::Backspace => self.backspace(), - KeyCode::_0 => self.input_digit(0), - KeyCode::_1 => self.input_digit(1), - KeyCode::_2 => self.input_digit(2), - KeyCode::_3 => self.input_digit(3), - KeyCode::_4 => self.input_digit(4), - KeyCode::_5 => self.input_digit(5), - KeyCode::_6 => self.input_digit(6), - KeyCode::_7 => self.input_digit(7), - KeyCode::_8 => self.input_digit(8), - KeyCode::_9 => self.input_digit(9), - KeyCode::Add => self.operator = Some(Operator::Add), - KeyCode::Subtract => self.operator = Some(Operator::Sub), - KeyCode::Divide => self.operator = Some(Operator::Div), - KeyCode::Multiply => self.operator = Some(Operator::Mul), - _ => {} - } - } -} diff --git a/examples/_examples/children.rs b/examples/_examples/children.rs deleted file mode 100644 index c30d1fd80..000000000 --- a/examples/_examples/children.rs +++ /dev/null @@ -1,37 +0,0 @@ -//! Basic example that renders a simple VNode to the browser. - -use dioxus_core::prelude::*; -use dioxus_html as dioxus_elements; -use dioxus_web::*; - -fn main() { - // Setup logging - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - - // Run the app - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -static App: FC<()> = |cx, props| { - cx.render(rsx! { - Calcier { - h2 {"abc 1"} - h2 {"abc 2"} - h2 {"abc 3"} - h2 {"abc 4"} - h2 {"abc 5"} - } - }) -}; - -static Calcier: FC<()> = |cx, props| { - cx.render(rsx! { - div { - h1 { - "abc 0" - } - {cx.children()} - } - }) -}; diff --git a/examples/_examples/context.rs b/examples/_examples/context.rs deleted file mode 100644 index 0658aa711..000000000 --- a/examples/_examples/context.rs +++ /dev/null @@ -1,65 +0,0 @@ -//! Example: Context API -//! -------------------- -//! This example demonstrates how to use the raw context api for sharing state throughout the VirtualDOM Tree. -//! A custom context must be its own unique type - otherwise use_context will fail. A context may be c -//! -//! -//! -//! -//! -//! -//! -//! - -use dioxus_core::prelude::*; -use dioxus_core as dioxus; -use dioxus_web::WebsysRenderer; -use dioxus_html as dioxus_elements; - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Trace)); - console_error_panic_hook::set_once(); - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example)); -} - -#[derive(Debug)] -struct CustomContext([&'static str; 3]); - -pub static Example: FC<()> = |cx, props|{ - cx.use_create_context(|| CustomContext(["Jack", "Jill", "Bob"])); - - cx.render(rsx! { - div { - class: "py-12 px-4 text-center w-full max-w-2xl mx-auto" - span { - class: "text-sm font-semibold" - "Dioxus Example: Jack and Jill" - } - h2 { - class: "text-5xl mt-2 mb-6 leading-tight font-semibold font-heading" - "Hello" - } - - CustomButton { id: 0 } - CustomButton { id: 1 } - CustomButton { id: 2 } - } - }) -}; - -#[derive(Props, PartialEq)] -struct ButtonProps { - id: u8, -} - -fn CustomButton(cx: Context) -> DomTree { - let names = cx.use_context::(); - let name = names.0[cx.id as usize]; - - cx.render(rsx!{ - button { - class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow" - "{name}" - } - }) -} diff --git a/examples/_examples/deep.rs b/examples/_examples/deep.rs deleted file mode 100644 index cfc1388fd..000000000 --- a/examples/_examples/deep.rs +++ /dev/null @@ -1,75 +0,0 @@ -use std::rc::Rc; - -use dioxus::prelude::*; -use dioxus_core as dioxus; -use dioxus_html as dioxus_elements; - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - - wasm_bindgen_futures::spawn_local(dioxus_web::WebsysRenderer::start(CustomA)) -} - -fn CustomA(cx: Context<()>) -> DomTree { - let (val, set_val) = use_state_classic(cx, || "abcdef".to_string() as String); - - cx.render(rsx! { - div { - class: "m-8" - "CustomA {val}" - button { - "Upper" - onclick: move |_| set_val(val.to_ascii_uppercase()) - } - button { - "Lower" - onclick: move |_| set_val(val.to_ascii_lowercase()) - } - components::CustomB { - val: val.clone() - } - } - }) -} - -mod components { - use std::rc::Rc; - - use super::*; - - #[derive(Debug, Props, PartialEq)] - pub struct PropsB { - val: String, - } - - pub fn CustomB(cx: Context) -> DomTree { - let (first, last) = cx.val.split_at(3); - cx.render(rsx! { - div { - class: "m-8" - "CustomB {cx.val}" - CustomC { - val: first.to_string() - } - CustomC { - val: last.to_string() - } - } - }) - } - - #[derive(Debug, Props, PartialEq)] - struct PropsC { - val: String, - } - - fn CustomC(cx: Context) -> DomTree { - cx.render(rsx! { - div { - class: "m-8" - "CustomC {cx.val}" - } - }) - } -} diff --git a/examples/_examples/demo.rs b/examples/_examples/demo.rs deleted file mode 100644 index bcd898055..000000000 --- a/examples/_examples/demo.rs +++ /dev/null @@ -1,71 +0,0 @@ -//! An example where the dioxus vdom is running in a native thread, interacting with webview -//! Content is passed from the native thread into the webview -use dioxus_core as dioxus; -use dioxus_core::prelude::*; -fn main() { - dioxus_desktop::launch( - |builder| { - builder - .title("Test Dioxus App") - .size(320, 480) - .resizable(false) - .debug(true) - }, - (), - Example, - ) - .expect("Webview finished"); -} - -// pub static Example: FC<()> = |cx, props|{ -// cx.render(html! { -//
-// - -// -// - -// -//
-// }) -// }; -pub static Example: FC<()> = |cx, props| { - cx.render(rsx! { - div { - class: "flex items-center justify-center flex-col" - div { - class: "flex items-center justify-center" - div { - class: "flex flex-col bg-white rounded p-4 w-full max-w-xs" - div { class: "font-bold text-xl", "Example desktop app" } - div { class: "text-sm text-gray-500", "This is running natively" } - div { - class: "flex flex-row items-center justify-center mt-6" - div { class: "font-medium text-6xl", "100%" } - } - div { - class: "flex flex-row justify-between mt-6" - a { - href: "https://www.dioxuslabs.com" - class: "underline" - "Made with dioxus" - } - } - ul { - {(0..10).map(|f| rsx!(li { - key: "{f}" - "{f}" - }))} - } - } - } - } - }) -}; diff --git a/examples/_examples/demo2.rs b/examples/_examples/demo2.rs deleted file mode 100644 index f328e4d9d..000000000 --- a/examples/_examples/demo2.rs +++ /dev/null @@ -1 +0,0 @@ -fn main() {} diff --git a/examples/_examples/demoday.rs b/examples/_examples/demoday.rs deleted file mode 100644 index ee54d06d3..000000000 --- a/examples/_examples/demoday.rs +++ /dev/null @@ -1,89 +0,0 @@ -use dioxus_core as dioxus; -use dioxus_html as dioxus_elements; -use dioxus_html::*; -use dioxus_web::{dioxus::prelude::*, WebsysRenderer}; - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)) -} - -fn App(cx: Context<()>) -> DomTree { - cx.render(rsx! { - div { class: "dark:bg-gray-800 bg-white relative h-screen" - NavBar {} - {(0..10).map(|f| rsx!(Landing { key: "{f}" }))} - } - }) -} - -fn NavBar(cx: Context<()>) -> DomTree { - cx.render(rsx!{ - header { class: "h-24 sm:h-32 flex items-center z-30 w-full" - div { class: "container mx-auto px-6 flex items-center justify-between" - div { class: "uppercase text-gray-800 dark:text-white font-black text-3xl" - svg { focusable:"false" width:"100" height:"100" viewBox: "0 0 512 309" - path { fill: "#000" - d: "M120.81 80.561h96.568v7.676h-87.716v57.767h82.486v7.675h-82.486v63.423h88.722v7.675H120.81V80.561zm105.22 0h10.26l45.467 63.423L328.23 80.56L391.441 0l-103.85 150.65l53.515 74.127h-10.663l-48.686-67.462l-48.888 67.462h-10.461l53.917-74.128l-50.296-70.088zm118.898 7.676V80.56h110.048v7.676h-50.699v136.54h-8.852V88.237h-50.497zM0 80.56h11.065l152.58 228.323l-63.053-84.107L9.254 91.468l-.402 133.31H0V80.56zm454.084 134.224c-1.809 0-3.165-1.4-3.165-3.212c0-1.81 1.356-3.212 3.165-3.212c1.83 0 3.165 1.401 3.165 3.212c0 1.811-1.335 3.212-3.165 3.212zm8.698-8.45h4.737c.064 2.565 1.937 4.29 4.693 4.29c3.079 0 4.823-1.854 4.823-5.325v-21.99h4.823v22.011c0 6.252-3.617 9.853-9.603 9.853c-5.62 0-9.473-3.493-9.473-8.84zm25.384-.28h4.78c.409 2.953 3.294 4.828 7.45 4.828c3.875 0 6.717-2.005 6.717-4.764c0-2.371-1.809-3.794-5.921-4.764l-4.005-.97c-5.62-1.316-8.181-4.032-8.181-8.602c0-5.54 4.521-9.227 11.303-9.227c6.308 0 10.916 3.686 11.196 8.925h-4.694c-.452-2.867-2.95-4.657-6.567-4.657c-3.81 0-6.35 1.833-6.35 4.635c0 2.22 1.635 3.493 5.683 4.441l3.423.841c6.373 1.488 9 4.075 9 8.753c0 5.95-4.607 9.68-11.97 9.68c-6.89 0-11.52-3.558-11.864-9.12z" - } - } - } - div { class:"flex items-center" - nav { class: "font-sen text-gray-800 dark:text-white uppercase text-lg lg:flex items-center hidden" - a { href: "#", class:"py-2 px-6 flex text-indigo-500 border-b-2 border-indigo-500" - "Home" - } - a { href: "#", class: "py-2 px-6 flex hover:text-indigo-500" - "Watch" - } - a { href: "#", class: "py-2 px-6 flex hover:text-indigo-500" - "Product" - } - a { href: "#", class: "py-2 px-6 flex hover:text-indigo-500" - "Contact" - } - a { href: "#", class: "py-2 px-6 flex hover:text-indigo-500" - "Career" - } - } - button { class: "lg:hidden flex flex-col ml-4" - span { class: "w-6 h-1 bg-gray-800 dark:bg-white mb-1" } - span { class: "w-6 h-1 bg-gray-800 dark:bg-white mb-1" } - span { class: "w-6 h-1 bg-gray-800 dark:bg-white mb-1" } - } - } - } - } - }) -} - -fn Landing(cx: Context<()>) -> DomTree { - cx.render(rsx!{ - div { class: "bg-white dark:bg-gray-800 flex relative z-20 items-center" - div { class: "container mx-auto px-6 flex flex-col justify-between items-center relative py-8" - div { class: "flex flex-col" - h1 { class: "font-light w-full uppercase text-center text-4xl sm:text-5xl dark:text-white text-gray-800" - "The Dioxus Framework for Production" - } - h2{ class: "font-light max-w-2xl mx-auto w-full text-xl dark:text-white text-gray-500 text-center py-8" - "Next.js gives you the best developer experience with all the features you need for production: \n - hybrid static & server rendering, TypeScript support, smart bundling, route pre-fetching, and \n - more. No config needed." - } - div { class: "flex items-center justify-center mt-4" - a { href: "#" class: "uppercase py-2 px-4 bg-gray-800 border-2 border-transparent text-white text-md mr-4 hover:bg-gray-900" - "Get started" - } - a{ href: "#" class: "uppercase py-2 px-4 bg-transparent border-2 border-gray-800 text-gray-800 dark:text-white hover:bg-gray-800 hover:text-white text-md" - "Documentation" - } - } - } - div { class: "block w-full mx-auto mt-6 md:mt-0 relative" - img { src: "/images/object/12.svg" class: "max-w-xs md:max-w-2xl m-auto" } - } - } - } - }) -} diff --git a/examples/_examples/derive.rs b/examples/_examples/derive.rs deleted file mode 100644 index 02259a111..000000000 --- a/examples/_examples/derive.rs +++ /dev/null @@ -1,46 +0,0 @@ -use dioxus::{events::on::MouseEvent, prelude::*}; -use dioxus_core as dioxus; -use dioxus_html as dioxus_elements; -use dioxus_web::WebsysRenderer; - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -fn App(cx: Context<()>) -> DomTree { - let cansee = use_state(cx, || false); - rsx! { in cx, - div { - "Shadow of the child:" - button { onclick: move |_| cansee.set(!**cansee) - "Gaze into the void" - } - {cansee.then(|| rsx!{ Child {} })} - } - } -} - -fn Child(cx: Context<()>) -> DomTree { - rsx! { in cx, - section { class: "py-6 bg-coolGray-100 text-coolGray-900" - div { class: "container mx-auto flex flex-col items-center justify-center p-4 space-y-8 md:p-10 md:px-24 xl:px-48" - h1 { class: "text-5xl font-bold leading-none text-center", - "Sign up now" - } - p { class: "text-xl font-medium text-center", - "At a assumenda quas cum earum ut itaque commodi saepe rem aspernatur quam natus quis nihil quod, hic explicabo doloribus magnam neque, exercitationem eius sunt!" - } - div { class: "flex flex-col space-y-4 sm:space-y-0 sm:flex-row sm:space-x-8" - button { class: "px-8 py-3 text-lg font-semibold rounded bg-violet-600 text-coolGray-50", - "Get started" - } - button { class: "px-8 py-3 text-lg font-normal border rounded bg-coolGray-800 text-coolGray-50 border-coolGray-700", - "Learn more" - } - } - } - } - } -} diff --git a/examples/_examples/events.rs b/examples/_examples/events.rs deleted file mode 100644 index 438fddcc6..000000000 --- a/examples/_examples/events.rs +++ /dev/null @@ -1,21 +0,0 @@ -use dioxus_core as dioxus; -use dioxus_core::events::on::*; -use dioxus_core::prelude::*; - -fn main() {} - -fn autocomplete() { - // let handler = move |evt| { - // let r = evt.alt_key(); - // if evt.alt_key() {} - // }; - - // let g = rsx! { - // button { - // button { - // onclick: {handler} - // } - // } - - // }; -} diff --git a/examples/_examples/fragment.rs b/examples/_examples/fragment.rs deleted file mode 100644 index 958fa102c..000000000 --- a/examples/_examples/fragment.rs +++ /dev/null @@ -1,26 +0,0 @@ -//! Basic example that renders a simple VNode to the browser. - -use dioxus_core::prelude::*; -use dioxus_html as dioxus_elements; -use dioxus_web::*; - -fn main() { - // Setup logging - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - - // Run the app - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -static App: FC<()> = |cx, props| { - cx.render(rsx! { - h2 { "abc 1" } - div { - "hello world!" - } - Fragment { - h2 { "abc 2"} - } - }) -}; diff --git a/examples/_examples/hello.rs b/examples/_examples/hello.rs deleted file mode 100644 index 72b89a3f4..000000000 --- a/examples/_examples/hello.rs +++ /dev/null @@ -1,33 +0,0 @@ -use dioxus_core as dioxus; -use dioxus_core::prelude::*; -use dioxus_html as dioxus_elements; -use dioxus_web::WebsysRenderer; - -fn main() { - // wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - // console_error_panic_hook::set_once(); - - // log::info!("hello world"); - dioxus_web::intern_cache(); - - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example)); -} - -pub static Example: FC<()> = |cx, props| { - let nodes = (0..500).map(|f| rsx! (li {"div"})); - cx.render(rsx! { - div { - span { - class: "px-2 py-1 flex w-36 mt-4 items-center text-xs rounded-md font-semibold text-yellow-500 bg-yellow-100" - "DUE DATE : 189 JUN" - } - p { - "these" - "are" - "text" - "nodes" - } - {nodes} - } - }) -}; diff --git a/examples/_examples/helloworld.rs b/examples/_examples/helloworld.rs deleted file mode 100644 index 5a0ae6010..000000000 --- a/examples/_examples/helloworld.rs +++ /dev/null @@ -1,13 +0,0 @@ -use dioxus_core as dioxus; -use dioxus_html as dioxus_elements; -use dioxus_web::prelude::*; - -fn main() { - wasm_bindgen_futures::spawn_local(dioxus_web::WebsysRenderer::start(App)) -} - -fn App(cx: Context<()>) -> DomTree { - cx.render(rsx! { - div { "Hello, world!" } - }) -} diff --git a/examples/_examples/hifive.rs b/examples/_examples/hifive.rs deleted file mode 100644 index 972eff4ff..000000000 --- a/examples/_examples/hifive.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! An example where the dioxus vdom is running in a native thread, interacting with webview -//! Content is passed from the native thread into the webview -use dioxus_core as dioxus; -use dioxus_core::prelude::*; -fn main() { - dioxus_desktop::launch( - |builder| { - builder - .title("Test Dioxus App") - .size(320, 480) - .resizable(false) - .debug(true) - }, - (), - App, - ) - .expect("Webview finished"); -} - -static App: FC<()> = |cx, props| { - let hifives = use_model(&cx, || 0); - cx.render(rsx! { - div { - h1 { "Hi-fives collected: {hifives}" } - button { "Hi five me!", onclick: move |_| *hifives.get_mut() += 1 } - } - }) -}; diff --git a/examples/_examples/htmlexample.html b/examples/_examples/htmlexample.html deleted file mode 100644 index e081b23e7..000000000 --- a/examples/_examples/htmlexample.html +++ /dev/null @@ -1,59 +0,0 @@ -
-

- "Messages" -

-
    -
  • - - profil - -
    - - {title} - - - "Hey John ! Do you read the NextJS doc ?" - -
    -
  • -
  • - - profil - -
    - - "Marie Lou" - - - "No I think the dog is better..." - -
    -
  • -
  • - - profil - -
    - - "Ivan Buck" - - - "Seriously ? haha Bob is not a children !" - -
    -
  • -
  • - - profil - -
    - - "Marina Farga" - - - "Do you need that deisgn ?" - -
    -
  • -
-
diff --git a/examples/_examples/infer.rs b/examples/_examples/infer.rs deleted file mode 100644 index 8d61a3345..000000000 --- a/examples/_examples/infer.rs +++ /dev/null @@ -1,59 +0,0 @@ -use dioxus_core as dioxus; -use dioxus_core::{events::on::MouseEvent, prelude::*}; -use dioxus_web::WebsysRenderer; -use dioxus_html as dioxus_elements; - - -fn main() { - // Setup logging - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - - log::info!("hello world"); - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example)); -} - -// this is a component -pub static Example: FC<()> = |cx, props|{ - let (event, set_event) = use_state_classic(cx, || None); - - let handler = move |evt| { - set_event(Some(evt)); - }; - - log::info!("hello world"); - - cx.render(rsx! { - div { - - class: "py-12 px-4 w-full max-w-2xl mx-auto bg-red-100" - span { - class: "text-sm font-semibold" - "Dioxus Example: Synthetic Events" - } - button { - class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow" - "press me" - } - pre { - onmousemove: {handler} - id: "json" - "Hello world" - } - Example2 { name: "Blah".into() } - } - }) -}; - -#[derive(Debug, PartialEq, Props)] -struct ExampleProps { - name: String, -} - -pub static Example2: FC = |cx, props|{ - cx.render(rsx! { - div { - h1 {"hello {cx.name}"} - } - }) -}; diff --git a/examples/_examples/input.rs b/examples/_examples/input.rs deleted file mode 100644 index 66a0fab7a..000000000 --- a/examples/_examples/input.rs +++ /dev/null @@ -1,67 +0,0 @@ -use dioxus_core as dioxus; -use dioxus_core::prelude::*; -use dioxus_web::WebsysRenderer; -use dioxus_html as dioxus_elements; - - -fn main() { - // wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - - log::info!("hello world"); - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -static App: FC<()> = |cx, props|{ - let (val, set_val) = use_state_classic(cx, || "asd".to_string()); - - cx.render(rsx! { - div { class: "max-w-lg max-w-xs bg-blue-800 shadow-2xl rounded-lg mx-auto text-center py-12 mt-4 rounded-xl" - div { class: "container py-5 max-w-md mx-auto" - h1 { class: "text-gray-200 text-center font-extrabold -mt-3 text-3xl", - "Text Input Example" - } - div { class: "mb-4" - input { - placeholder: "Username" - class: "shadow appearance-none rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" - id: "username" - r#type: "text" - value: "{val}" - oninput: move |evet| set_val(evet.value()) - } - p { "Val is: {val}" } - } - } - } - }) -}; - -pub static Example: FC<()> = |cx, props|{ - cx.render(rsx! { - div { class: "max-w-lg max-w-xs bg-blue-800 shadow-2xl rounded-lg mx-auto text-center py-12 mt-4 rounded-xl" - div { class: "container py-5 max-w-md mx-auto" - h1 { class: "text-gray-200 text-center font-extrabold -mt-3 text-3xl", - "Text Input Example" - } - UserInput {} - } - } - }) -}; - -static UserInput: FC<()> = |cx, props|{ - let (val, set_val) = use_state_classic(cx, || "asd".to_string()); - - rsx! { in cx, - div { class: "mb-4" - input { class: "shadow appearance-none rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline" - placeholder: "Username" - id: "username" - r#type: "text" - oninput: move |evet| set_val(evet.value()) - } - p { "Val is: {val}" } - } - } -}; diff --git a/examples/_examples/jackjill.rs b/examples/_examples/jackjill.rs deleted file mode 100644 index cb4e95c78..000000000 --- a/examples/_examples/jackjill.rs +++ /dev/null @@ -1,49 +0,0 @@ -use dioxus::prelude::*; -use dioxus_core as dioxus; -use dioxus_web::WebsysRenderer; - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example)) -} - -pub static Example: FC<()> = |cx, props| { - let (name, set_name) = use_state_classic(cx, || "...?"); - - log::debug!("Running component...."); - - cx.render(html! { -
-
-
- // Tagline - - "Dioxus Example: Jack and Jill" - - - // Header -

- "Hello, {name}" -

- - // Control buttons -
- - - -
-
-
-
- }) -}; diff --git a/examples/_examples/jackjillrsx.rs b/examples/_examples/jackjillrsx.rs deleted file mode 100644 index fcf7c790f..000000000 --- a/examples/_examples/jackjillrsx.rs +++ /dev/null @@ -1,38 +0,0 @@ -use dioxus::prelude::*; -use dioxus_core as dioxus; -use dioxus_html as dioxus_elements; -use dioxus_web::WebsysRenderer; - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example)) -} - -pub static Example: FC<()> = |cx, props| { - let (name, set_name) = use_state_classic(cx, || "...?"); - cx.render(rsx! { - section { class: "py-12 px-4 text-center" - div { class: "w-full max-w-2xl mx-auto" - span { class: "text-sm font-semibold" - "Dioxus Example: Jack and Jill" - } - h2 { class: "text-5xl mt-2 mb-6 leading-tight font-semibold font-heading" - "Hello, {name}" - } - div { - button { - class:"inline-block py-4 px-8 m-2 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow" - onclick: move |_| set_name("jack") - "Jack!" - } - button { - class:"inline-block py-4 px-8 m-2 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow" - onclick: move |_| set_name("jill") - "Jill!" - } - } - } - } - }) -}; diff --git a/examples/_examples/landingpage.rs b/examples/_examples/landingpage.rs deleted file mode 100644 index 2cd24f7c7..000000000 --- a/examples/_examples/landingpage.rs +++ /dev/null @@ -1,45 +0,0 @@ -//! Basic example that renders a simple VNode to the browser. - -use std::rc::Rc; - -use dioxus_core::prelude::*; -use dioxus_html as dioxus_elements; -use dioxus_web::*; - -fn main() { - // Setup logging - // wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - // Run the app - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -static App: FC<()> = |cx, props| { - let (contents, set_contents) = use_state_classic(cx, || "asd"); - - cx.render(rsx! { - div { - class: "flex items-center justify-center flex-col" - div { - class: "flex items-center justify-center" - div { - class: "flex flex-col bg-white rounded p-4 w-full max-w-xs" - div { class: "font-bold text-xl", "Example cloud app" } - div { class: "text-sm text-gray-500", "This is running in the cloud!!" } - div { - class: "flex flex-row items-center justify-center mt-6" - div { class: "font-medium text-6xl", "100%" } - } - div { - class: "flex flex-row justify-between mt-6" - a { - href: "https://www.dioxuslabs.com" - class: "underline" - "Made with dioxus" - } - } - } - } - } - }) -}; diff --git a/examples/_examples/landingpage2.rs b/examples/_examples/landingpage2.rs deleted file mode 100644 index 53ba2acdd..000000000 --- a/examples/_examples/landingpage2.rs +++ /dev/null @@ -1,37 +0,0 @@ -//! Basic example that renders a simple VNode to the browser. - -use dioxus_core::prelude::*; -use dioxus_html as dioxus_elements; -use dioxus_web::*; - -fn main() { - // Setup logging and panic handling - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - - // Run the app - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -static App: FC<()> = |cx, props| { - let (contents, set_contents) = use_state_classic(cx, || "asd"); - - cx.render(rsx! { - div { class: "flex items-center justify-center flex-col" - div { class: "flex items-center justify-center" - div { class: "flex flex-col bg-white rounded p-4 w-full max-w-xs" - div { class: "font-bold text-xl", "Example Web app" } - div { class: "text-sm text-gray-500", "This is running in your browser!" } - div { class: "flex flex-row items-center justify-center mt-6" - div { class: "font-medium text-6xl", "100%" } - } - div { class: "flex flex-row justify-between mt-6" - a { href: "https://www.dioxuslabs.com", class: "underline" - "Made with dioxus" - } - } - } - } - } - }) -}; diff --git a/examples/_examples/list.rs b/examples/_examples/list.rs deleted file mode 100644 index 4232194b5..000000000 --- a/examples/_examples/list.rs +++ /dev/null @@ -1,174 +0,0 @@ -use dioxus_core as dioxus; -use dioxus_core::prelude::*; -use dioxus_html as dioxus_elements; -use dioxus_web::WebsysRenderer; -use std::collections::BTreeMap; - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -static APP_STYLE: &'static str = include_str!("./todomvc/style.css"); - -#[derive(PartialEq, Clone, Copy)] -pub enum FilterState { - All, - Active, - Completed, -} - -#[derive(Debug, PartialEq, Clone)] -pub struct TodoItem { - pub id: uuid::Uuid, - pub checked: bool, - pub contents: String, -} - -static App: FC<()> = |cx, props| { - let (draft, set_draft) = use_state_classic(cx, || "".to_string()); - let (filter, set_filter) = use_state_classic(cx, || FilterState::All); - let todos = use_state(cx, || BTreeMap::::new()); - cx.render(rsx!( - div { - id: "app" - div { - header { - class: "header" - h1 {"todos"} - button { - "press me" - onclick: move |evt| { - let contents = draft.clone(); - todos.modify(|f| { - let id = uuid::Uuid::new_v4(); - f.insert(id.clone(), TodoItem { - id, - checked: false, - contents - }); - }) - } - } - input { - class: "new-todo" - placeholder: "What needs to be done?" - oninput: move |evt| set_draft(evt.value()) - } - } - - { // list - todos - .iter() - .filter(|(id, item)| match filter { - FilterState::All => true, - FilterState::Active => !item.checked, - FilterState::Completed => item.checked, - }) - .map(|(id, todo)| { - rsx!{ - li { - key: "{id}" - "{todo.contents}" - input { - class: "toggle" - r#type: "checkbox" - "{todo.checked}" - } - } - } - }) - } - - // filter toggle (show only if the list isn't empty) - {(!todos.is_empty()).then(|| - rsx!{ - footer { - span { - strong {"10"} - span {"0 items left"} - } - ul { - class: "filters" - {[ - ("All", "", FilterState::All), - ("Active", "active", FilterState::Active), - ("Completed", "completed", FilterState::Completed), - ] - .iter() - .map(|(name, path, filter)| { - rsx!( - li { - class: "{name}" - a { - href: "{path}" - onclick: move |_| set_filter(filter.clone()) - "{name}" - } - } - ) - }) - }} - } - } - )} - } - - - 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" } - } - } - } - )) -}; - -pub fn FilterToggles(cx: Context<()>) -> DomTree { - // let reducer = recoil::use_callback(&cx, || ()); - // let items_left = recoil::use_atom_family(&cx, &TODOS, uuid::Uuid::new_v4()); - - let toggles = [ - ("All", "", FilterState::All), - ("Active", "active", FilterState::Active), - ("Completed", "completed", FilterState::Completed), - ] - .iter() - .map(|(name, path, _filter)| { - rsx!( - li { - class: "{name}" - a { - href: "{path}" - // onclick: move |_| reducer.set_filter(&filter) - "{name}" - } - } - ) - }); - - // todo - let item_text = ""; - let items_left = ""; - - cx.render(rsx! { - footer { - span { - strong {"{items_left}"} - span {"{item_text} left"} - } - ul { - class: "filters" - {toggles} - } - } - }) -} diff --git a/examples/_examples/listy.rs b/examples/_examples/listy.rs deleted file mode 100644 index 4515e4db2..000000000 --- a/examples/_examples/listy.rs +++ /dev/null @@ -1,29 +0,0 @@ -use dioxus_core as dioxus; -use dioxus_core::prelude::*; -use dioxus_html as dioxus_elements; -use dioxus_web::WebsysRenderer; - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - - log::info!("hello world"); - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(JonsFavoriteCustomApp)); -} - -fn JonsFavoriteCustomApp(cx: Context<()>) -> DomTree { - let items = (0..20).map(|f| { - rsx! { - li {"{f}"} - } - }); - - cx.render(rsx! { - div { - "list" - ul { - {items} - } - } - }) -} diff --git a/examples/_examples/many.rs b/examples/_examples/many.rs deleted file mode 100644 index cd2027b59..000000000 --- a/examples/_examples/many.rs +++ /dev/null @@ -1,23 +0,0 @@ -use dioxus_core as dioxus; -use dioxus_core::prelude::*; -use dioxus_html as dioxus_elements; -use dioxus_web::WebsysRenderer; - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - - log::info!("hello world"); - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example)); -} - -pub static Example: FC<()> = |cx, props| { - cx.render(rsx! { - div { - span { - class: "px-2 py-1 flex w-36 mt-4 items-center text-xs rounded-md font-semibold text-yellow-500 bg-yellow-100" - "DUE DATE : 18 JUN" - } - } - }) -}; diff --git a/examples/_examples/model.rs b/examples/_examples/model.rs deleted file mode 100644 index 41906ce92..000000000 --- a/examples/_examples/model.rs +++ /dev/null @@ -1,193 +0,0 @@ -//! Example: Calculator -//! ------------------- -//! -//! Some components benefit through the use of "Models". Models are a single block of encapsulated state that allow mutative -//! methods to be performed on them. Dioxus exposes the ability to use the model pattern through the "use_model" hook. -//! -//! Models are commonly used in the "Model-View-Component" approach for building UI state. -//! -//! `use_model` is basically just a fancy wrapper around set_state, but saves a "working copy" of the new state behind a -//! RefCell. To modify the working copy, you need to call "get_mut" which returns the RefMut. This makes it easy to write -//! fully encapsulated apps that retain a certain feel of native Rusty-ness. A calculator app is a good example of when this -//! is useful. -//! -//! Do note that "get_mut" returns a `RefMut` (a lock over a RefCell). If two `RefMut`s are held at the same time (ie in a loop) -//! the RefCell will panic and crash. You can use `try_get_mut` or `.modify` to avoid this problem, or just not hold two -//! RefMuts at the same time. - -use dioxus::events::on::*; -use dioxus::prelude::*; -use dioxus_core as dioxus; -use dioxus_html as dioxus_elements; -use dioxus_web::WebsysRenderer; - -const STYLE: &str = include_str!("../../../examples/assets/calculator.css"); - -fn main() { - // Setup logging - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - // Run the app - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -static App: FC<()> = |cx, props| { - let state = use_model(&cx, || Calculator::new()); - - let clear_display = state.display_value.eq("0"); - let clear_text = if clear_display { "C" } else { "AC" }; - let formatted = state.formatted_display(); - - cx.render(rsx! { - div { id: "wrapper" - div { class: "app", style { "{STYLE}" } - div { class: "calculator", onkeypress: move |evt| state.get_mut().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.get_mut().clear_display(), "{clear_text}" } - CalculatorKey { name: "key-sign", onclick: move |_| state.get_mut().toggle_sign(), "±"} - CalculatorKey { name: "key-percent", onclick: move |_| state.get_mut().toggle_percent(), "%"} - } - div { class: "digit-keys" - CalculatorKey { name: "key-0", onclick: move |_| state.get_mut().input_digit(0), "0" } - CalculatorKey { name: "key-dot", onclick: move |_| state.get_mut().input_dot(), "●" } - {(1..10).map(move |k| rsx!{ - CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| state.get_mut().input_digit(k), "{k}" } - })} - } - } - div { class: "operator-keys" - CalculatorKey { name:"key-divide", onclick: move |_| state.get_mut().set_operator(Operator::Div), "÷" } - CalculatorKey { name:"key-multiply", onclick: move |_| state.get_mut().set_operator(Operator::Mul), "×" } - CalculatorKey { name:"key-subtract", onclick: move |_| state.get_mut().set_operator(Operator::Sub), "−" } - CalculatorKey { name:"key-add", onclick: move |_| state.get_mut().set_operator(Operator::Add), "+" } - CalculatorKey { name:"key-equals", onclick: move |_| state.get_mut().perform_operation(), "=" } - } - } - } - } - } - }) -}; - -#[derive(Props)] -struct CalculatorKeyProps<'a> { - name: &'static str, - onclick: &'a dyn Fn(MouseEvent), -} - -fn CalculatorKey<'a, 'r>(cx: Context<'a, CalculatorKeyProps<'r>>) -> DomTree<'a> { - cx.render(rsx! { - button { - class: "calculator-key {cx.name}" - onclick: {cx.onclick} - {cx.children()} - } - }) -} - -#[derive(Clone)] -struct Calculator { - display_value: String, - operator: Option, - waiting_for_operand: bool, - cur_val: f64, -} -#[derive(Clone)] -enum Operator { - Add, - Sub, - Mul, - Div, -} - -impl Calculator { - fn new() -> Self { - Calculator { - display_value: "0".to_string(), - operator: None, - waiting_for_operand: false, - cur_val: 0.0, - } - } - fn formatted_display(&self) -> String { - use separator::Separatable; - self.display_value - .parse::() - .unwrap() - .separated_string() - } - fn clear_display(&mut self) { - self.display_value = "0".to_string(); - } - fn input_digit(&mut self, digit: u8) { - let content = digit.to_string(); - if self.waiting_for_operand || self.display_value == "0" { - self.waiting_for_operand = false; - self.display_value = content; - } else { - self.display_value.push_str(content.as_str()); - } - } - fn input_dot(&mut self) { - if self.display_value.find(".").is_none() { - self.display_value.push_str("."); - } - } - fn perform_operation(&mut self) { - if let Some(op) = &self.operator { - let rhs = self.display_value.parse::().unwrap(); - let new_val = match op { - Operator::Add => self.cur_val + rhs, - Operator::Sub => self.cur_val - rhs, - Operator::Mul => self.cur_val * rhs, - Operator::Div => self.cur_val / rhs, - }; - self.cur_val = new_val; - self.display_value = new_val.to_string(); - self.operator = None; - } - } - fn toggle_sign(&mut self) { - if self.display_value.starts_with("-") { - self.display_value = self.display_value.trim_start_matches("-").to_string(); - } else { - self.display_value = format!("-{}", self.display_value); - } - } - fn toggle_percent(&mut self) { - self.display_value = (self.display_value.parse::().unwrap() / 100.0).to_string(); - } - fn backspace(&mut self) { - if !self.display_value.as_str().eq("0") { - self.display_value.pop(); - } - } - fn set_operator(&mut self, operator: Operator) { - self.operator = Some(operator); - self.cur_val = self.display_value.parse::().unwrap(); - self.waiting_for_operand = true; - } - fn handle_keydown(&mut self, evt: KeyboardEvent) { - match evt.key_code() { - KeyCode::Backspace => self.backspace(), - KeyCode::_0 => self.input_digit(0), - KeyCode::_1 => self.input_digit(1), - KeyCode::_2 => self.input_digit(2), - KeyCode::_3 => self.input_digit(3), - KeyCode::_4 => self.input_digit(4), - KeyCode::_5 => self.input_digit(5), - KeyCode::_6 => self.input_digit(6), - KeyCode::_7 => self.input_digit(7), - KeyCode::_8 => self.input_digit(8), - KeyCode::_9 => self.input_digit(9), - KeyCode::Add => self.operator = Some(Operator::Add), - KeyCode::Subtract => self.operator = Some(Operator::Sub), - KeyCode::Divide => self.operator = Some(Operator::Div), - KeyCode::Multiply => self.operator = Some(Operator::Mul), - _ => {} - } - } -} diff --git a/examples/_examples/props.rs b/examples/_examples/props.rs deleted file mode 100644 index 09c4ecc08..000000000 --- a/examples/_examples/props.rs +++ /dev/null @@ -1,13 +0,0 @@ -use dioxus_core as dioxus; -use dioxus_core::prelude::*; - -#[derive(Props)] -struct MyProps<'a> { - blah: u128, - b: &'a (), -} - -fn main() { - // let p = unsafe { MyProps {}.memoize(&MyProps {}) }; - // dbg!(p); -} diff --git a/examples/_examples/query.rs b/examples/_examples/query.rs deleted file mode 100644 index 40cca683a..000000000 --- a/examples/_examples/query.rs +++ /dev/null @@ -1,20 +0,0 @@ -// use dioxus_core::prelude::*; -// use dioxus_web::WebsysRenderer; - -// fn main() { -// wasm_bindgen_futures::spawn_local(WebsysRenderer::start(Example)); -// } - -// fn Example(cx: Context, props: ()) -> DomTree { -// let user_data = use_sql_query(&cx, USER_DATA_QUERY); - -// cx.render(rsx! { -// h1 { "Hello, {username}"} -// button { -// "Delete user" -// onclick: move |_| user_data.delete() -// } -// }) -// } - -fn main() {} diff --git a/examples/_examples/rsxt.rs b/examples/_examples/rsxt.rs deleted file mode 100644 index f800b7e58..000000000 --- a/examples/_examples/rsxt.rs +++ /dev/null @@ -1,86 +0,0 @@ -#![allow(non_snake_case)] -use std::rc::Rc; - -use dioxus::{events::on::MouseEvent, prelude::*}; -use dioxus_core as dioxus; -use dioxus_web::WebsysRenderer; -use dioxus_html as dioxus_elements; - - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Trace)); - console_error_panic_hook::set_once(); - - wasm_bindgen_futures::spawn_local(async { - let props = ExampleProps { - initial_name: "..?", - }; - WebsysRenderer::new_with_props(Example, props) - .run() - .await - .unwrap() - }); -} - -#[derive(PartialEq, Props)] -struct ExampleProps { - initial_name: &'static str, -} - -pub static Example: FC = |cx, props|{ - let name = use_state(cx, move || cx.initial_name); - - cx.render(rsx! { - div { - class: "py-12 px-4 text-center w-full max-w-2xl mx-auto" - span { - class: "text-sm font-semibold" - "Dioxus Example: Jack and Jill" - } - h2 { - class: "text-5xl mt-2 mb-6 leading-tight font-semibold font-heading" - "Hello, {name}" - } - - CustomButton { name: "Jack!", handler: move |_| name.set("Jack") } - CustomButton { name: "Jill!", handler: move |_| name.set("Jill") } - CustomButton { name: "Bob!", handler: move |_| name.set("Bob")} - Placeholder {val: name} - Placeholder {val: name} - } - }) -}; - -#[derive(Props)] -struct ButtonProps<'src, F: Fn(MouseEvent)> { - name: &'src str, - handler: F, -} - -fn CustomButton<'a, F: Fn(MouseEvent)>(cx: Context<'a, ButtonProps<'a, F>>) -> DomTree { - cx.render(rsx!{ - button { - class: "inline-block py-4 px-8 mr-6 leading-none text-white bg-indigo-600 hover:bg-indigo-900 font-semibold rounded shadow" - onmouseover: {&cx.handler} - "{cx.name}" - } - }) -} - -impl PartialEq for ButtonProps<'_, F> { - fn eq(&self, other: &Self) -> bool { - false - } -} - -#[derive(Props, PartialEq)] -struct PlaceholderProps { - val: &'static str, -} -fn Placeholder(cx: Context) -> DomTree { - cx.render(rsx! { - div { - "child: {cx.val}" - } - }) -} diff --git a/examples/_examples/todomvc-nodeps.rs b/examples/_examples/todomvc-nodeps.rs deleted file mode 100644 index d50a23a63..000000000 --- a/examples/_examples/todomvc-nodeps.rs +++ /dev/null @@ -1,126 +0,0 @@ -use std::{collections::HashMap, rc::Rc}; - -use dioxus_core as dioxus; -use dioxus_core::prelude::*; -use dioxus_html as dioxus_elements; -use dioxus_web::WebsysRenderer; - -static APP_STYLE: &'static str = include_str!("./todomvc/style.css"); - -fn main() { - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -#[derive(PartialEq)] -pub enum FilterState { - All, - Active, - Completed, -} - -#[derive(Debug, PartialEq, Clone)] -pub struct TodoItem { - pub id: uuid::Uuid, - pub checked: bool, - pub contents: String, -} - -pub fn App(cx: Context<()>) -> DomTree { - let (draft, set_draft) = use_state_classic(cx, || "".to_string()); - let (todos, set_todos) = use_state_classic(cx, || HashMap::>::new()); - let (filter, set_filter) = use_state_classic(cx, || FilterState::All); - - let filtered_todos = todos.iter().filter(move |(id, item)| match filter { - FilterState::All => true, - FilterState::Active => !item.checked, - FilterState::Completed => item.checked, - }); - let items_left = filtered_todos.clone().count(); - let item_text = match items_left { - 1 => "item", - _ => "items", - }; - - cx.render(rsx! { - div { id: "app" - div { - header { class: "header" - h1 {"todos"} - input { - class: "new-todo" - placeholder: "What needs to be done?" - value: "{draft}" - oninput: move |evt| set_draft(evt.value()) - } - } - - {filtered_todos.map(|(id, item)| { - rsx!(TodoEntry { - key: "{id}", - item: item.clone() - }) - })} - - // filter toggle (show only if the list isn't empty) - {(!todos.is_empty()).then(|| rsx!( - footer { - span { - strong {"{items_left}"} - span {"{item_text} left"} - } - ul { - class: "filters" - li { class: "All", a { href: "", onclick: move |_| set_filter(FilterState::All), "All" }} - li { class: "Active", a { href: "active", onclick: move |_| set_filter(FilterState::Active), "Active" }} - li { class: "Completed", a { href: "completed", onclick: move |_| set_filter(FilterState::Completed), "Completed" }} - } - } - ))} - } - // footer - 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 { - item: Rc, -} - -pub fn TodoEntry(cx: Context) -> DomTree { - let (is_editing, set_is_editing) = use_state_classic(cx, || false); - let contents = ""; - let todo = TodoItem { - checked: false, - contents: "asd".to_string(), - id: uuid::Uuid::new_v4(), - }; - - cx.render(rsx! ( - li { - "{todo.id}" - input { - class: "toggle" - r#type: "checkbox" - "{todo.checked}" - } - {is_editing.then(|| rsx!{ - input { - value: "{contents}" - } - })} - } - )) -} diff --git a/examples/_examples/todomvc/filtertoggles.rs b/examples/_examples/todomvc/filtertoggles.rs deleted file mode 100644 index b55366552..000000000 --- a/examples/_examples/todomvc/filtertoggles.rs +++ /dev/null @@ -1,42 +0,0 @@ -use crate::recoil; -use crate::state::{FilterState, TODOS}; -use dioxus_core::prelude::*; - -pub fn FilterToggles(cx: Context<()>) -> DomTree { - let reducer = recoil::use_callback(&cx, || ()); - let items_left = recoil::use_atom_family(&cx, &TODOS, uuid::Uuid::new_v4()); - - let toggles = [ - ("All", "", FilterState::All), - ("Active", "active", FilterState::Active), - ("Completed", "completed", FilterState::Completed), - ] - .iter() - .map(|(name, path, filter)| { - rsx!(li { - class: "{name}" - a { - "{name}" - href: "{path}" - onclick: move |_| reducer.set_filter(&filter) - } - }) - }); - - // todo - let item_text = ""; - let items_left = ""; - - cx.render(rsx! { - footer { - span { - strong {"{items_left}"} - span {"{item_text} left"} - } - ul { - class: "filters" - {toggles} - } - } - }) -} diff --git a/examples/_examples/todomvc/main.rs b/examples/_examples/todomvc/main.rs deleted file mode 100644 index 56bd3789d..000000000 --- a/examples/_examples/todomvc/main.rs +++ /dev/null @@ -1,39 +0,0 @@ -use dioxus_core as dioxus; -use dioxus_html as dioxus_elements; -use dioxus_web::{prelude::*, WebsysRenderer}; - -// mod filtertoggles; -// mod recoil; -// mod state; -// mod todoitem; -// mod todolist; - -static APP_STYLE: &'static str = include_str!("./style.css"); - -fn main() { - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|cx, props| { - cx.render(rsx! { - div { - id: "app" - // style { "{APP_STYLE}" } - - // list - // todolist::TodoList {} - - // footer - 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" } - } - } - } - }) - })) -} diff --git a/examples/_examples/todomvc/recoil.rs b/examples/_examples/todomvc/recoil.rs deleted file mode 100644 index e2fe67754..000000000 --- a/examples/_examples/todomvc/recoil.rs +++ /dev/null @@ -1,102 +0,0 @@ -use dioxus_core::context::Context; - -pub struct RecoilContext { - _inner: T, -} - -impl RecoilContext { - /// Get the value of an atom. Returns a reference to the underlying data. - - pub fn get(&self) {} - - /// Replace an existing value with a new value - /// - /// This does not replace the value instantly, and all calls to "get" within the current scope will return - pub fn set(&self) {} - - // Modify lets you modify the value in place. However, because there's no previous value around to compare - // the new one with, we are unable to memoize the change. As such, all downsteam users of this Atom will - // be updated, causing all subsrcibed components to re-render. - // - // This is fine for most values, but might not be performant when dealing with collections. For collections, - // use the "Family" variants as these will stay memoized for inserts, removals, and modifications. - // - // Note - like "set" this won't propogate instantly. Once all "gets" are dropped, only then will we run the - pub fn modify(&self) {} -} - -pub fn use_callback<'a, G>(c: &Context<'a>, f: impl Fn() -> G) -> &'a RecoilContext { - todo!() -} - -pub fn use_atom(c: &Context, t: &'static Atom) -> O { - todo!() -} -pub fn use_batom(c: &Context, t: impl Readable) -> O { - todo!() -} - -pub trait Readable {} -impl Readable for &'static Atom {} -impl Readable for &'static AtomFamily {} - -pub fn use_atom_family<'a, K: PartialEq, V: PartialEq>( - c: &Context<'a>, - t: &'static AtomFamily, - g: K, -) -> &'a V { - todo!() -} - -pub use atoms::{atom, Atom}; -pub use atoms::{atom_family, AtomFamily}; -mod atoms { - - use super::*; - pub struct AtomBuilder { - pub key: String, - pub manual_init: Option T>>, - _never: std::marker::PhantomData, - } - - impl AtomBuilder { - pub fn new() -> Self { - Self { - key: uuid::Uuid::new_v4().to_string(), - manual_init: None, - _never: std::marker::PhantomData {}, - } - } - - pub fn init T + 'static>(&mut self, f: A) { - self.manual_init = Some(Box::new(f)); - } - - pub fn set_key(&mut self, _key: &'static str) {} - } - - pub struct atom(pub fn(&mut AtomBuilder) -> T); - pub type Atom = atom; - - pub struct AtomFamilyBuilder { - _never: std::marker::PhantomData<(K, V)>, - } - - pub struct atom_family(pub fn(&mut AtomFamilyBuilder)); - pub type AtomFamily = atom_family; -} - -pub use selectors::selector; -mod selectors { - pub struct SelectorBuilder { - _p: std::marker::PhantomData, - } - impl SelectorBuilder { - pub fn getter(self, f: impl Fn(()) -> O) -> SelectorBuilder { - todo!() - // std::rc::Rc::pin(value) - // todo!() - } - } - pub struct selector(pub fn(SelectorBuilder) -> SelectorBuilder); -} diff --git a/examples/_examples/todomvc/state.rs b/examples/_examples/todomvc/state.rs deleted file mode 100644 index d1066c32b..000000000 --- a/examples/_examples/todomvc/state.rs +++ /dev/null @@ -1,43 +0,0 @@ -use crate::recoil::*; - -pub static TODOS: AtomFamily = atom_family(|_| {}); -pub static FILTER: Atom = atom(|_| FilterState::All); -pub static SHOW_ALL_TODOS: selector = selector(|g| g.getter(|f| false)); - -#[derive(PartialEq)] -pub enum FilterState { - All, - Active, - Completed, -} - -#[derive(Debug, PartialEq, Clone)] -pub struct TodoItem { - pub id: uuid::Uuid, - pub checked: bool, - pub contents: String, -} - -impl RecoilContext<()> { - pub fn add_todo(&self, contents: String) {} - - pub fn remove_todo(&self, id: &uuid::Uuid) { - // TODOS.with().remove(id) - } - - pub fn select_all_todos(&self) {} - - pub fn toggle_todo(&self, id: &uuid::Uuid) {} - - pub fn clear_completed(&self) { - // let (set, get) = (self.set, self.get); - - // TOODS - // .get(&cx) - // .iter() - // .filter(|(k, v)| v.checked) - // .map(|(k, v)| TODOS.remove(&cx, k)); - } - - pub fn set_filter(&self, filter: &FilterState) {} -} diff --git a/examples/_examples/todomvc/style.css b/examples/_examples/todomvc/style.css deleted file mode 100644 index d8be205ad..000000000 --- a/examples/_examples/todomvc/style.css +++ /dev/null @@ -1,376 +0,0 @@ -html, -body { - margin: 0; - padding: 0; -} - -button { - margin: 0; - padding: 0; - border: 0; - background: none; - font-size: 100%; - vertical-align: baseline; - font-family: inherit; - font-weight: inherit; - color: inherit; - -webkit-appearance: none; - appearance: none; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -body { - font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; - line-height: 1.4em; - background: #f5f5f5; - color: #4d4d4d; - min-width: 230px; - max-width: 550px; - margin: 0 auto; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - font-weight: 300; -} - -:focus { - outline: 0; -} - -.hidden { - display: none; -} - -.todoapp { - background: #fff; - margin: 130px 0 40px 0; - position: relative; - box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), - 0 25px 50px 0 rgba(0, 0, 0, 0.1); -} - -.todoapp input::-webkit-input-placeholder { - font-style: italic; - font-weight: 300; - color: #e6e6e6; -} - -.todoapp input::-moz-placeholder { - font-style: italic; - font-weight: 300; - color: #e6e6e6; -} - -.todoapp input::input-placeholder { - font-style: italic; - font-weight: 300; - color: #e6e6e6; -} - -.todoapp h1 { - position: absolute; - top: -155px; - width: 100%; - font-size: 100px; - font-weight: 100; - text-align: center; - color: rgba(175, 47, 47, 0.15); - -webkit-text-rendering: optimizeLegibility; - -moz-text-rendering: optimizeLegibility; - text-rendering: optimizeLegibility; -} - -.new-todo, -.edit { - position: relative; - margin: 0; - width: 100%; - font-size: 24px; - font-family: inherit; - font-weight: inherit; - line-height: 1.4em; - border: 0; - color: inherit; - padding: 6px; - border: 1px solid #999; - box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); - box-sizing: border-box; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -.new-todo { - padding: 16px 16px 16px 60px; - border: none; - background: rgba(0, 0, 0, 0.003); - box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03); -} - -.main { - position: relative; - z-index: 2; - border-top: 1px solid #e6e6e6; -} - -.toggle-all { - text-align: center; - border: none; /* Mobile Safari */ - opacity: 0; - position: absolute; -} - -.toggle-all + label { - width: 60px; - height: 34px; - font-size: 0; - position: absolute; - top: -52px; - left: -13px; - -webkit-transform: rotate(90deg); - transform: rotate(90deg); -} - -.toggle-all + label:before { - content: '❯'; - font-size: 22px; - color: #e6e6e6; - padding: 10px 27px 10px 27px; -} - -.toggle-all:checked + label:before { - color: #737373; -} - -.todo-list { - margin: 0; - padding: 0; - list-style: none; -} - -.todo-list li { - position: relative; - font-size: 24px; - border-bottom: 1px solid #ededed; -} - -.todo-list li:last-child { - border-bottom: none; -} - -.todo-list li.editing { - border-bottom: none; - padding: 0; -} - -.todo-list li.editing .edit { - display: block; - width: 506px; - padding: 12px 16px; - margin: 0 0 0 43px; -} - -.todo-list li.editing .view { - display: none; -} - -.todo-list li .toggle { - text-align: center; - width: 40px; - /* auto, since non-WebKit browsers doesn't support input styling */ - height: auto; - position: absolute; - top: 0; - bottom: 0; - margin: auto 0; - border: none; /* Mobile Safari */ - -webkit-appearance: none; - appearance: none; -} - -.todo-list li .toggle { - opacity: 0; -} - -.todo-list li .toggle + label { - /* - Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433 - IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/ - */ - background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E'); - background-repeat: no-repeat; - background-position: center left; -} - -.todo-list li .toggle:checked + label { - background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E'); -} - -.todo-list li label { - word-break: break-all; - padding: 15px 15px 15px 60px; - display: block; - line-height: 1.2; - transition: color 0.4s; -} - -.todo-list li.completed label { - color: #d9d9d9; - text-decoration: line-through; -} - -.todo-list li .destroy { - display: none; - position: absolute; - top: 0; - right: 10px; - bottom: 0; - width: 40px; - height: 40px; - margin: auto 0; - font-size: 30px; - color: #cc9a9a; - margin-bottom: 11px; - transition: color 0.2s ease-out; -} - -.todo-list li .destroy:hover { - color: #af5b5e; -} - -.todo-list li .destroy:after { - content: '×'; -} - -.todo-list li:hover .destroy { - display: block; -} - -.todo-list li .edit { - display: none; -} - -.todo-list li.editing:last-child { - margin-bottom: -1px; -} - -.footer { - color: #777; - padding: 10px 15px; - height: 20px; - text-align: center; - border-top: 1px solid #e6e6e6; -} - -.footer:before { - content: ''; - position: absolute; - right: 0; - bottom: 0; - left: 0; - height: 50px; - overflow: hidden; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), - 0 8px 0 -3px #f6f6f6, - 0 9px 1px -3px rgba(0, 0, 0, 0.2), - 0 16px 0 -6px #f6f6f6, - 0 17px 2px -6px rgba(0, 0, 0, 0.2); -} - -.todo-count { - float: left; - text-align: left; -} - -.todo-count strong { - font-weight: 300; -} - -.filters { - margin: 0; - padding: 0; - list-style: none; - position: absolute; - right: 0; - left: 0; -} - -.filters li { - display: inline; -} - -.filters li a { - color: inherit; - margin: 3px; - padding: 3px 7px; - text-decoration: none; - border: 1px solid transparent; - border-radius: 3px; -} - -.filters li a:hover { - border-color: rgba(175, 47, 47, 0.1); -} - -.filters li a.selected { - border-color: rgba(175, 47, 47, 0.2); -} - -.clear-completed, -html .clear-completed:active { - float: right; - position: relative; - line-height: 20px; - text-decoration: none; - cursor: pointer; -} - -.clear-completed:hover { - text-decoration: underline; -} - -.info { - margin: 65px auto 0; - color: #bfbfbf; - font-size: 10px; - text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); - text-align: center; -} - -.info p { - line-height: 1; -} - -.info a { - color: inherit; - text-decoration: none; - font-weight: 400; -} - -.info a:hover { - text-decoration: underline; -} - -/* - Hack to remove background from Mobile Safari. - Can't use it globally since it destroys checkboxes in Firefox -*/ -@media screen and (-webkit-min-device-pixel-ratio:0) { - .toggle-all, - .todo-list li .toggle { - background: none; - } - - .todo-list li .toggle { - height: 40px; - } -} - -@media (max-width: 430px) { - .footer { - height: 50px; - } - - .filters { - bottom: 10px; - } -} diff --git a/examples/_examples/todomvc/todoitem.rs b/examples/_examples/todomvc/todoitem.rs deleted file mode 100644 index 431b68445..000000000 --- a/examples/_examples/todomvc/todoitem.rs +++ /dev/null @@ -1,29 +0,0 @@ -use super::state::TODOS; -use crate::recoil::use_atom_family; -use dioxus_core::prelude::*; - -#[derive(PartialEq, Props)] -pub struct TodoEntryProps { - id: uuid::Uuid, -} - -pub fn TodoEntry(cx: Context, props: &TodoEntryProps) -> DomTree { - let (is_editing, set_is_editing) = use_state(cx, || false); - let todo = use_atom_family(&cx, &TODOS, cx.id); - - cx.render(rsx! ( - li { - "{todo.id}" - input { - class: "toggle" - type: "checkbox" - "{todo.checked}" - } - {is_editing.then(|| rsx!( - input { - value: "{todo.contents}" - } - ))} - } - )) -} diff --git a/examples/_examples/todomvc/todolist.rs b/examples/_examples/todomvc/todolist.rs deleted file mode 100644 index cf4c48fac..000000000 --- a/examples/_examples/todomvc/todolist.rs +++ /dev/null @@ -1,49 +0,0 @@ -use crate::{ - filtertoggles, - recoil::use_atom, - state::{FilterState, TodoItem, FILTER, TODOS}, - todoitem::TodoEntry, -}; -use dioxus_core::prelude::*; - -pub fn TodoList(cx: Context<()>) -> DomTree { - let (draft, set_draft) = use_state(cx, || "".to_string()); - let (todos, _) = use_state(cx, || Vec::::new()); - let filter = use_atom(&cx, &FILTER); - - cx.render(rsx! { - div { - header { - class: "header" - h1 {"todos"} - input { - class: "new-todo" - placeholder: "What needs to be done?" - value: "{draft}" - oninput: move |evt| set_draft(evt.value) - } - } - - { // list - todos - .iter() - .filter(|item| match filter { - FilterState::All => true, - FilterState::Active => !item.checked, - FilterState::Completed => item.checked, - }) - .map(|item| { - rsx!(TodoEntry { - key: "{order}", - id: item.id, - }) - }) - } - - // filter toggle (show only if the list isn't empty) - {(!todos.is_empty()).then(|| - rsx!( filtertoggles::FilterToggles {}) - )} - } - }) -} diff --git a/examples/_examples/todomvc_simple.rs b/examples/_examples/todomvc_simple.rs deleted file mode 100644 index 2ba4495b0..000000000 --- a/examples/_examples/todomvc_simple.rs +++ /dev/null @@ -1,167 +0,0 @@ -use std::{collections::HashMap, rc::Rc}; - -use dioxus_core as dioxus; -use dioxus_core::prelude::*; -use dioxus_html as dioxus_elements; -use dioxus_web::WebsysRenderer; - -static APP_STYLE: &'static str = include_str!("./todomvc/style.css"); - -fn main() { - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(App)); -} - -#[derive(PartialEq)] -pub enum FilterState { - All, - Active, - Completed, -} - -#[derive(Debug, PartialEq, Clone)] -pub struct TodoItem { - pub id: uuid::Uuid, - pub checked: bool, - pub contents: String, -} - -// ======================= -// Components -// ======================= -pub fn App(cx: Context<()>) -> DomTree { - cx.render(rsx! { - div { - id: "app" - - // list - TodoList {} - - // footer - 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" } - } - } - } - }) -} - -pub fn TodoList(cx: Context<()>) -> DomTree { - let (draft, set_draft) = use_state_classic(cx, || "".to_string()); - let (todos, set_todos) = use_state_classic(cx, || HashMap::>::new()); - let (filter, set_filter) = use_state_classic(cx, || FilterState::All); - - cx.render(rsx! { - div { - header { - class: "header" - h1 {"todos"} - input { - class: "new-todo" - placeholder: "What needs to be done?" - value: "{draft}" - oninput: move |evt| set_draft(evt.value()) - } - } - - { // list - todos - .iter() - .filter(|(id, item)| match filter { - FilterState::All => true, - FilterState::Active => !item.checked, - FilterState::Completed => item.checked, - }) - .map(|(id, item)| { - // TodoEntry!(); - todo!() - // rsx!(TodoEntry { - // key: "{order}", - // item: item.clone() - // }) - }) - } - - // filter toggle (show only if the list isn't empty) - {(!todos.is_empty()).then(|| - rsx!( FilterToggles {}) - )} - } - }) -} - -#[derive(PartialEq, Props)] -pub struct TodoEntryProps { - item: Rc, -} - -pub fn TodoEntry(cx: Context) -> DomTree { - let (is_editing, set_is_editing) = use_state_classic(cx, || false); - let contents = ""; - let todo = TodoItem { - checked: false, - contents: "asd".to_string(), - id: uuid::Uuid::new_v4(), - }; - - cx.render(rsx! ( - li { - "{todo.id}" - input { - class: "toggle" - r#type: "checkbox" - "{todo.checked}" - } - {is_editing.then(|| rsx!{ - input { - value: "{contents}" - } - })} - } - )) -} - -pub fn FilterToggles(cx: Context<()>) -> DomTree { - let toggles = [ - ("All", "", FilterState::All), - ("Active", "active", FilterState::Active), - ("Completed", "completed", FilterState::Completed), - ] - .iter() - .map(|(name, path, filter)| { - rsx!( - li { - class: "{name}" - a { - href: "{path}" - // onclick: move |_| reducer.set_filter(&filter) - "{name}" - } - } - ) - }); - - // todo - let item_text = ""; - let items_left = ""; - - cx.render(rsx! { - footer { - span { - strong {"{items_left}"} - span {"{item_text} left"} - } - ul { - class: "filters" - {toggles} - } - } - }) -} diff --git a/examples/_examples/todomvcsingle.rs b/examples/_examples/todomvcsingle.rs deleted file mode 100644 index 94108974d..000000000 --- a/examples/_examples/todomvcsingle.rs +++ /dev/null @@ -1,200 +0,0 @@ -//! Example: TODOVMC - One file -//! --------------------------- -//! This example shows how to build a one-file TODO MVC app with Dioxus and Recoil. -//! This project is confined to a single file to showcase the suggested patterns -//! for building a small but mighty UI with Dioxus without worrying about project structure. -//! -//! If you want an example on recommended project structure, check out the TodoMVC folder -//! -//! Here, we show to use Dioxus' Recoil state management solution to simplify app logic -#![allow(non_snake_case)] -use dioxus_core as dioxus; -use dioxus_web::dioxus::prelude::*; - -use std::collections::HashMap; -use uuid::Uuid; - -#[derive(PartialEq, Clone, Copy)] -pub enum FilterState { - All, - Active, - Completed, -} - -#[derive(Debug, PartialEq, Clone)] -pub struct TodoItem { - pub id: Uuid, - pub checked: bool, - pub contents: String, -} - -// Declare our global app state -const TODO_LIST: AtomHashMap = |_| {}; -const FILTER: Atom = |_| FilterState::All; -const TODOS_LEFT: Selector = |api| api.get(&TODO_LIST).len(); - -// Implement a simple abstraction over sets/gets of multiple atoms -struct TodoManager(RecoilApi); -impl TodoManager { - fn add_todo(&self, contents: String) { - let item = TodoItem { - checked: false, - contents, - id: Uuid::new_v4(), - }; - self.0.modify(&TODO_LIST, move |list| { - list.insert(item.id, item); - }); - } - fn remove_todo(&self, id: &Uuid) { - self.0.modify(&TODO_LIST, move |list| { - list.remove(id); - }) - } - fn select_all_todos(&self) { - self.0.modify(&TODO_LIST, move |list| { - for item in list.values_mut() { - item.checked = true; - } - }) - } - fn toggle_todo(&self, id: &Uuid) { - self.0.modify(&TODO_LIST, move |list| { - list.get_mut(id).map(|item| item.checked = !item.checked) - }); - } - fn clear_completed(&self) { - self.0.modify(&TODO_LIST, move |list| { - *list = list.drain().filter(|(_, item)| !item.checked).collect(); - }) - } - fn set_filter(&self, filter: &FilterState) { - self.0.modify(&FILTER, move |f| *f = *filter); - } -} - -pub fn TodoList(cx: Context<()>) -> DomTree { - let draft = use_state(cx, || "".to_string()); - let todos = use_read(&cx, &TODO_LIST); - let filter = use_read(&cx, &FILTER); - - let todolist = todos - .values() - .filter(|item| match filter { - FilterState::All => true, - FilterState::Active => !item.checked, - FilterState::Completed => item.checked, - }) - .map(|item| { - rsx!(TodoEntry { - key: "{order}", - id: item.id, - }) - }); - - rsx! { in cx, - 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} - - // rsx! accepts optionals, so we suggest the `then` method in place of ternary - {(!todos.is_empty()).then(|| rsx!( FilterToggles {}) )} - } - } -} - -#[derive(PartialEq, Props)] -pub struct TodoEntryProps { - id: Uuid, -} - -pub fn TodoEntry(cx: Context, props: &TodoEntryProps) -> DomTree { - let (is_editing, set_is_editing) = use_state_classic(cx, || false); - let todo = use_read(&cx, &TODO_LIST).get(&cx.id).unwrap(); - - cx.render(rsx! ( - li { - "{todo.id}" - input { - class: "toggle" - type: "checkbox" - "{todo.checked}" - } - {is_editing.then(|| rsx!( - input { - value: "{todo.contents}" - } - ))} - } - )) -} - -pub fn FilterToggles(cx: Context<()>) -> DomTree { - let reducer = TodoManager(use_recoil_api(cx)); - let items_left = use_read(cx, &TODOS_LEFT); - - let item_text = match items_left { - 1 => "item", - _ => "items", - }; - - let toggles = rsx! { - ul { - class: "filters" - li { class: "All", a { href: "", onclick: move |_| reducer.set_filter(&FilterState::All), "All" }} - li { class: "Active", a { href: "active", onclick: move |_| reducer.set_filter(&FilterState::Active), "Active" }} - li { class: "Completed", a { href: "completed", onclick: move |_| reducer.set_filter(&FilterState::Completed), "Completed" }} - } - }; - - rsx! { in cx, - footer { - span { - strong {"{items_left}"} - span { "{item_text} left" } - } - {toggles} - } - } -} - -pub fn Footer(cx: Context<()>) -> DomTree { - rsx! { in cx, - 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" } - } - } - } -} - -const APP_STYLE: &'static str = include_str!("./todomvc/style.css"); - -fn App(cx: Context<()>) -> DomTree { - use_init_recoil_root(cx, |_| {}); - rsx! { in cx, - div { id: "app" - TodoList {} - Footer {} - } - } -} - -fn main() { - wasm_bindgen_futures::spawn_local(dioxus_web::WebsysRenderer::start(App)); -} diff --git a/examples/_examples/weather.rs b/examples/_examples/weather.rs deleted file mode 100644 index 9a2d0b4fc..000000000 --- a/examples/_examples/weather.rs +++ /dev/null @@ -1,47 +0,0 @@ -//! basic example that renders a simple VNode to the page :) -//! -//! -//! -use dioxus_core::prelude::*; -use dioxus_web::*; - -fn main() { - wasm_logger::init(wasm_logger::Config::new(log::Level::Debug)); - console_error_panic_hook::set_once(); - - wasm_bindgen_futures::spawn_local(WebsysRenderer::start(|cx, props| { - cx.render(html! { -
-
-
-
- // Title -
- "Jon's awesome site!!" -
- - // Subtext / description -
- "He worked so hard on it :)" -
- -
- // Main number -
- "1337" -
-
- - // Try another - -
-
-
-
- }) - })); -}