docs: remove old examples

This commit is contained in:
Jonathan Kelley 2021-10-14 14:53:06 -04:00
parent ef2daf62a3
commit 2b7dd45aa2
41 changed files with 0 additions and 3092 deletions

View file

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

View file

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

View file

@ -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<Operator>);
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::<f64>().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::<f64>().unwrap();
let new_val = match op {
Operator::Add => *cur_val + rhs,
Operator::Sub => *cur_val - rhs,
Operator::Mul => *cur_val * rhs,
Operator::Div => *cur_val / rhs,
};
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::<f64>().unwrap().separated_string();
// TODO: make it autoscaling with css
cx.render(rsx! {
div { class: "calculator-display"
div { class: "auto-scaling-text", "{formatted}" }
}
})
}

View file

@ -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<Operator>,
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::<f64>()
// .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::<f64>().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::<f64>().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::<f64>().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),
_ => {}
}
}
}

View file

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

View file

@ -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<ButtonProps>) -> DomTree {
let names = cx.use_context::<CustomContext>();
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}"
}
})
}

View file

@ -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<PropsB>) -> 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<PropsC>) -> DomTree {
cx.render(rsx! {
div {
class: "m-8"
"CustomC {cx.val}"
}
})
}
}

View file

@ -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! {
// <div>
// <svg class="octicon octicon-star v-align-text-bottom"
// viewBox="0 0 14 16" version="1.1"
// width="14" height="16"
// xmlns="http://www.w3.org/2000/svg"
// >
// <path
// d="M14 6l-4.9-.64L7 1 4.9 5.36 0 6l3.6 3.26L2.67 14"
// xmlns="http://www.w3.org/2000/svg"
// >
// </path>
// </svg>
// </div>
// })
// };
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}"
}))}
}
}
}
}
})
};

View file

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

View file

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

View file

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

View file

@ -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}
// }
// }
// };
}

View file

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

View file

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

View file

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

View file

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

View file

@ -1,59 +0,0 @@
<div class="shadow-lg rounded-2xl p-4 bg-white dark:bg-gray-700 w-full">
<p class="font-bold text-md text-black dark:text-white">
"Messages"
</p>
<ul>
<li class="flex items-center my-6 space-x-2">
<a href="#" class="block relative">
<img alt="profil" src="/images/person/1.jpg" class="mx-auto object-cover rounded-full h-10 w-10 " />
</a>
<div class="flex flex-col">
<span class="text-sm text-gray-900 font-semibold dark:text-white ml-2">
{title}
</span>
<span class="text-sm text-gray-400 dark:text-gray-300 ml-2">
"Hey John ! Do you read the NextJS doc ?"
</span>
</div>
</li>
<li class="flex items-center my-6 space-x-2">
<a href="#" class="block relative">
<img alt="profil" src="/images/person/5.jpg" class="mx-auto object-cover rounded-full h-10 w-10 " />
</a>
<div class="flex flex-col">
<span class="text-sm text-gray-900 font-semibold dark:text-white ml-2">
"Marie Lou"
</span>
<span class="text-sm text-gray-400 dark:text-gray-300 ml-2">
"No I think the dog is better..."
</span>
</div>
</li>
<li class="flex items-center my-6 space-x-2">
<a href="#" class="block relative">
<img alt="profil" src="/images/person/6.jpg" class="mx-auto object-cover rounded-full h-10 w-10 " />
</a>
<div class="flex flex-col">
<span class="text-sm text-gray-900 font-semibold dark:text-white ml-2">
"Ivan Buck"
</span>
<span class="text-sm text-gray-400 dark:text-gray-300 ml-2">
"Seriously ? haha Bob is not a children !"
</span>
</div>
</li>
<li class="flex items-center my-6 space-x-2">
<a href="#" class="block relative">
<img alt="profil" src="/images/person/7.jpg" class="mx-auto object-cover rounded-full h-10 w-10 " />
</a>
<div class="flex flex-col">
<span class="text-sm text-gray-900 font-semibold dark:text-white ml-2">
"Marina Farga"
</span>
<span class="text-sm text-gray-400 dark:text-gray-300 ml-2">
"Do you need that deisgn ?"
</span>
</div>
</li>
</ul>
</div>

View file

@ -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<ExampleProps> = |cx, props|{
cx.render(rsx! {
div {
h1 {"hello {cx.name}"}
}
})
};

View file

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

View file

@ -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! {
<div>
<section class="py-12 px-4 text-center">
<div class="w-full max-w-2xl mx-auto">
// Tagline
<span class="text-sm font-semibold">
"Dioxus Example: Jack and Jill"
</span>
// Header
<h2 class="text-5xl mt-2 mb-6 leading-tight font-semibold font-heading">
"Hello, {name}"
</h2>
// Control buttons
<div>
<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={move |_| set_name("jack")}>
"Jack!"
</button>
<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={move |_| set_name("jill")}>
"Jill!"
</button>
</div>
</div>
</section>
</div>
})
};

View file

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

View file

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

View file

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

View file

@ -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::<uuid::Uuid, TodoItem>::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}
}
}
})
}

View file

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

View file

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

View file

@ -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<Operator>,
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::<f64>()
.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::<f64>().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::<f64>().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::<f64>().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),
_ => {}
}
}
}

View file

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

View file

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

View file

@ -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<ExampleProps> = |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<F: Fn(MouseEvent)> PartialEq for ButtonProps<'_, F> {
fn eq(&self, other: &Self) -> bool {
false
}
}
#[derive(Props, PartialEq)]
struct PlaceholderProps {
val: &'static str,
}
fn Placeholder(cx: Context<PlaceholderProps>) -> DomTree {
cx.render(rsx! {
div {
"child: {cx.val}"
}
})
}

View file

@ -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::<uuid::Uuid, Rc<TodoItem>>::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<TodoItem>,
}
pub fn TodoEntry(cx: Context<TodoEntryProps>) -> 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}"
}
})}
}
))
}

View file

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

View file

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

View file

@ -1,102 +0,0 @@
use dioxus_core::context::Context;
pub struct RecoilContext<T: 'static> {
_inner: T,
}
impl<T: 'static> RecoilContext<T> {
/// 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<G> {
todo!()
}
pub fn use_atom<T: PartialEq, O>(c: &Context, t: &'static Atom<T>) -> O {
todo!()
}
pub fn use_batom<T: PartialEq, O>(c: &Context, t: impl Readable) -> O {
todo!()
}
pub trait Readable {}
impl<T: PartialEq> Readable for &'static Atom<T> {}
impl<K: PartialEq, V: PartialEq> Readable for &'static AtomFamily<K, V> {}
pub fn use_atom_family<'a, K: PartialEq, V: PartialEq>(
c: &Context<'a>,
t: &'static AtomFamily<K, V>,
g: K,
) -> &'a V {
todo!()
}
pub use atoms::{atom, Atom};
pub use atoms::{atom_family, AtomFamily};
mod atoms {
use super::*;
pub struct AtomBuilder<T: PartialEq> {
pub key: String,
pub manual_init: Option<Box<dyn Fn() -> T>>,
_never: std::marker::PhantomData<T>,
}
impl<T: PartialEq> AtomBuilder<T> {
pub fn new() -> Self {
Self {
key: uuid::Uuid::new_v4().to_string(),
manual_init: None,
_never: std::marker::PhantomData {},
}
}
pub fn init<A: Fn() -> 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<T: PartialEq>(pub fn(&mut AtomBuilder<T>) -> T);
pub type Atom<T: PartialEq> = atom<T>;
pub struct AtomFamilyBuilder<K, V> {
_never: std::marker::PhantomData<(K, V)>,
}
pub struct atom_family<K: PartialEq, V: PartialEq>(pub fn(&mut AtomFamilyBuilder<K, V>));
pub type AtomFamily<K: PartialEq, V: PartialEq> = atom_family<K, V>;
}
pub use selectors::selector;
mod selectors {
pub struct SelectorBuilder<Out, const Built: bool> {
_p: std::marker::PhantomData<Out>,
}
impl<O> SelectorBuilder<O, false> {
pub fn getter(self, f: impl Fn(()) -> O) -> SelectorBuilder<O, true> {
todo!()
// std::rc::Rc::pin(value)
// todo!()
}
}
pub struct selector<O>(pub fn(SelectorBuilder<O, false>) -> SelectorBuilder<O, true>);
}

View file

@ -1,43 +0,0 @@
use crate::recoil::*;
pub static TODOS: AtomFamily<uuid::Uuid, TodoItem> = atom_family(|_| {});
pub static FILTER: Atom<FilterState> = atom(|_| FilterState::All);
pub static SHOW_ALL_TODOS: selector<bool> = 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) {}
}

View file

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

View file

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

View file

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

View file

@ -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::<uuid::Uuid, Rc<TodoItem>>::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<TodoItem>,
}
pub fn TodoEntry(cx: Context<TodoEntryProps>) -> 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}
}
}
})
}

View file

@ -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<Uuid, TodoItem> = |_| {};
const FILTER: Atom<FilterState> = |_| FilterState::All;
const TODOS_LEFT: Selector<usize> = |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));
}

View file

@ -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! {
<div>
<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">
// Title
<div class="font-bold text-xl">
"Jon's awesome site!!"
</div>
// Subtext / description
<div class="text-sm text-gray-500">
"He worked so hard on it :)"
</div>
<div class="flex flex-row items-center justify-center mt-6">
// Main number
<div class="font-medium text-6xl">
"1337"
</div>
</div>
// Try another
<div class="flex flex-row justify-between mt-6">
// <a href=format!("http://localhost:8080/fib/{}", other_fib_to_try) class="underline">
"Legit made my own React"
// </a>
</div>
</div>
</div>
</div>
</div>
})
}));
}