wip: almost there
This commit is contained in:
1 parent
f07e345eb2
commit
047c810507
11 files changed
+155
-385
No files matched your search
@@ -1,14 +0,0 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let g = dioxus::prelude::LazyNodes::new(move |__cx: NodeFactory| {
|
||||
use dioxus_elements::{GlobalAttributes, SvgAttributes};
|
||||
__cx.element(
|
||||
dioxus_elements::button,
|
||||
[dioxus::events::on::onclick(__cx, move |_| {})],
|
||||
[],
|
||||
[],
|
||||
None,
|
||||
)
|
||||
});
|
||||
}
|
||||
+15
-21
@@ -12,7 +12,7 @@ fn main() {
|
||||
|
||||
const APP: FC<()> = |cx, _| {
|
||||
let cur_val = use_state(cx, || 0.0_f64);
|
||||
let operator = use_state(cx, || None);
|
||||
let operator = use_state(cx, || None as Option<&'static str>);
|
||||
let display_value = use_state(cx, || String::from(""));
|
||||
|
||||
let clear_display = display_value == "0";
|
||||
@@ -25,11 +25,12 @@ const APP: FC<()> = |cx, _| {
|
||||
let perform_operation = move || {
|
||||
if let Some(op) = operator.as_ref() {
|
||||
let rhs = display_value.parse::<f64>().unwrap();
|
||||
let new_val = match op {
|
||||
Operator::Add => *cur_val + rhs,
|
||||
Operator::Sub => *cur_val - rhs,
|
||||
Operator::Mul => *cur_val * rhs,
|
||||
Operator::Div => *cur_val / rhs,
|
||||
let new_val = match *op {
|
||||
"+" => *cur_val + rhs,
|
||||
"-" => *cur_val - rhs,
|
||||
"*" => *cur_val * rhs,
|
||||
"/" => *cur_val / rhs,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
cur_val.set(new_val);
|
||||
display_value.set(new_val.to_string());
|
||||
@@ -56,10 +57,10 @@ const APP: FC<()> = |cx, _| {
|
||||
};
|
||||
|
||||
let keydownhandler = move |evt: KeyboardEvent| match evt.key_code() {
|
||||
KeyCode::Add => operator.set(Some(Operator::Add)),
|
||||
KeyCode::Subtract => operator.set(Some(Operator::Sub)),
|
||||
KeyCode::Divide => operator.set(Some(Operator::Div)),
|
||||
KeyCode::Multiply => operator.set(Some(Operator::Mul)),
|
||||
KeyCode::Add => operator.set(Some("+")),
|
||||
KeyCode::Subtract => operator.set(Some("-")),
|
||||
KeyCode::Divide => operator.set(Some("/")),
|
||||
KeyCode::Multiply => operator.set(Some("*")),
|
||||
KeyCode::Num0 => input_digit(0),
|
||||
KeyCode::Num1 => input_digit(1),
|
||||
KeyCode::Num2 => input_digit(2),
|
||||
@@ -99,23 +100,16 @@ const APP: FC<()> = |cx, _| {
|
||||
})}
|
||||
}
|
||||
div { class: "operator-keys"
|
||||
CalculatorKey { name: "key-divide", onclick: move |_| operator.set(Some(Operator::Div)) "÷" }
|
||||
CalculatorKey { name: "key-multiply", onclick: move |_| operator.set(Some(Operator::Mul)) "×" }
|
||||
CalculatorKey { name: "key-subtract", onclick: move |_| operator.set(Some(Operator::Sub)) "−" }
|
||||
CalculatorKey { name: "key-add", onclick: move |_| operator.set(Some(Operator::Add)) "+" }
|
||||
CalculatorKey { name: "key-divide", onclick: move |_| operator.set(Some("/")) "÷" }
|
||||
CalculatorKey { name: "key-multiply", onclick: move |_| operator.set(Some("*")) "×" }
|
||||
CalculatorKey { name: "key-subtract", onclick: move |_| operator.set(Some("-")) "−" }
|
||||
CalculatorKey { name: "key-add", onclick: move |_| operator.set(Some("+")) "+" }
|
||||
CalculatorKey { name: "key-equals", onclick: move |_| perform_operation() "=" }
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
enum Operator {
|
||||
Add,
|
||||
Sub,
|
||||
Mul,
|
||||
Div,
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
struct CalculatorKeyProps<'a> {
|
||||
name: &'static str,
|
||||
|
||||
+59
-32
@@ -6,7 +6,6 @@ use dioxus::prelude::*;
|
||||
fn main() {
|
||||
dioxus::web::launch(App, |c| c);
|
||||
}
|
||||
|
||||
enum Scene {
|
||||
ClientsList,
|
||||
NewClientForm,
|
||||
@@ -28,50 +27,78 @@ static App: FC<()> = |cx, _| {
|
||||
let lastname = use_state(cx, || String::new());
|
||||
let description = use_state(cx, || String::new());
|
||||
|
||||
match *scene {
|
||||
let scene = match *scene {
|
||||
Scene::ClientsList => {
|
||||
rsx!(cx, div { class: "crm"
|
||||
h1 { "List of clients" }
|
||||
div { class: "clients" {clients.read().iter().map(|client| rsx!(
|
||||
div { class: "client" style: "margin-bottom: 50px"
|
||||
p { "First Name: {client.first_name}" }
|
||||
p { "Last Name: {client.last_name}" }
|
||||
p {"Description: {client.description}"}
|
||||
}))}
|
||||
h2 { "List of clients" margin_bottom: "10px" }
|
||||
div { class: "clients" margin_left: "10px"
|
||||
{clients.read().iter().map(|client| rsx!(
|
||||
div { class: "client" style: "margin-bottom: 50px"
|
||||
p { "First Name: {client.first_name}" }
|
||||
p { "Last Name: {client.last_name}" }
|
||||
p {"Description: {client.description}"}
|
||||
})
|
||||
)}
|
||||
}
|
||||
button { onclick: move |_| scene.set(Scene::NewClientForm), "Add New" }
|
||||
button { onclick: move |_| scene.set(Scene::Settings), "Settings" }
|
||||
button { class: "pure-button pure-button-primary" onclick: move |_| scene.set(Scene::NewClientForm), "Add New" }
|
||||
button { class: "pure-button" onclick: move |_| scene.set(Scene::Settings), "Settings" }
|
||||
})
|
||||
}
|
||||
Scene::NewClientForm => {
|
||||
rsx!(cx, div { class: "crm"
|
||||
h1 {"Add new client"}
|
||||
div { class: "names"
|
||||
input { class: "new-client firstname" placeholder: "First name"
|
||||
onchange: move |e| firstname.set(e.value())
|
||||
}
|
||||
input { class: "new-client lastname" placeholder: "Last name"
|
||||
onchange: move |e| lastname.set(e.value())
|
||||
}
|
||||
textarea { class: "new-client description" placeholder: "Description"
|
||||
onchange: move |e| description.set(e.value())
|
||||
}
|
||||
}
|
||||
button { disabled: "false", onclick: move |_| clients.write().push(Client {
|
||||
let add_new = move |_| {
|
||||
clients.write().push(Client {
|
||||
description: (*description).clone(),
|
||||
first_name: (*firstname).clone(),
|
||||
last_name: (*lastname).clone(),
|
||||
|
||||
}), "Add New" }
|
||||
button { onclick: move |_| scene.set(Scene::ClientsList), "Go Back" }
|
||||
});
|
||||
description.set(String::new());
|
||||
firstname.set(String::new());
|
||||
lastname.set(String::new());
|
||||
};
|
||||
rsx!(cx, div { class: "crm"
|
||||
h2 {"Add new client" margin_bottom: "10px" }
|
||||
form { class: "pure-form"
|
||||
input { class: "new-client firstname" placeholder: "First name" value: "{firstname}"
|
||||
oninput: move |e| firstname.set(e.value())
|
||||
}
|
||||
input { class: "new-client lastname" placeholder: "Last name" value: "{lastname}"
|
||||
oninput: move |e| lastname.set(e.value())
|
||||
}
|
||||
textarea { class: "new-client description" placeholder: "Description" value: "{description}"
|
||||
oninput: move |e| description.set(e.value())
|
||||
}
|
||||
}
|
||||
button { class: "pure-button pure-button-primary", onclick: {add_new}, "Add New" }
|
||||
button { class: "pure-button", onclick: move |_| scene.set(Scene::ClientsList), "Go Back" }
|
||||
})
|
||||
}
|
||||
Scene::Settings => {
|
||||
rsx!(cx, div {
|
||||
h1 {"Settings"}
|
||||
button { onclick: move |_| clients.write().clear() "Remove all clients" }
|
||||
button { onclick: move |_| scene.set(Scene::ClientsList), "Go Back" }
|
||||
h2 {"Settings" margin_bottom: "10px" }
|
||||
button {
|
||||
background: "rgb(202, 60, 60)"
|
||||
class: "pure-button pure-button-primary"
|
||||
onclick: move |_| clients.write().clear(),
|
||||
"Remove all clients"
|
||||
}
|
||||
button {
|
||||
class: "pure-button pure-button-primary"
|
||||
onclick: move |_| scene.set(Scene::ClientsList),
|
||||
"Go Back"
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
rsx!(cx, body {
|
||||
link {
|
||||
rel: "stylesheet"
|
||||
href: "https://unpkg.com/purecss@2.0.6/build/pure-min.css"
|
||||
integrity: "sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5"
|
||||
crossorigin: "anonymous"
|
||||
}
|
||||
margin_left: "35%"
|
||||
h1 {"Dioxus CRM Example"}
|
||||
{scene}
|
||||
})
|
||||
};
|
||||
@@ -7,7 +7,6 @@
|
||||
|
||||
use dioxus::desktop::wry::application::dpi::LogicalSize;
|
||||
use dioxus::prelude::*;
|
||||
use std::fs::{self, DirEntry};
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
@@ -73,7 +72,7 @@ impl Files {
|
||||
|
||||
fn reload_path_list(&mut self) {
|
||||
let cur_path = self.path_stack.last().unwrap();
|
||||
let paths = match fs::read_dir(cur_path) {
|
||||
let paths = match std::fs::read_dir(cur_path) {
|
||||
Ok(e) => e,
|
||||
Err(err) => {
|
||||
let err = format!("An error occured: {:?}", err);
|
||||
|
||||
@@ -6,7 +6,6 @@ fn main() {
|
||||
// .. should result in an "invalid node tree"
|
||||
let edits = vec![
|
||||
CreateElement { tag: "div", id: 0 },
|
||||
// CreatePlaceholder { id: 1 },
|
||||
CreateElement { tag: "h1", id: 2 },
|
||||
CreateTextNode {
|
||||
text: "hello world",
|
||||
@@ -15,7 +14,6 @@ fn main() {
|
||||
AppendChildren { many: 1 },
|
||||
AppendChildren { many: 1 },
|
||||
AppendChildren { many: 1 },
|
||||
// ReplaceWith { many: 1 },
|
||||
];
|
||||
|
||||
dioxus_desktop::WebviewRenderer::run_with_edits(App, (), |c| c, Some(edits)).expect("failed");
|
||||
|
||||
+26
-29
@@ -33,40 +33,38 @@ fn main() {
|
||||
}
|
||||
|
||||
static App: FC<()> = |cx, props| {
|
||||
let state = use_state(cx, || Calculator::new());
|
||||
let state = use_ref(cx, || Calculator::new());
|
||||
|
||||
let clear_display = state.display_value.eq("0");
|
||||
let clear_display = state.read().display_value.eq("0");
|
||||
let clear_text = if clear_display { "C" } else { "AC" };
|
||||
let formatted = state.formatted_display();
|
||||
let formatted = state.read().formatted_display();
|
||||
|
||||
cx.render(rsx! {
|
||||
div { id: "wrapper"
|
||||
div { class: "app", style { "{STYLE}" }
|
||||
div { class: "calculator", onkeypress: move |evt| state.modify().handle_keydown(evt),
|
||||
div { class: "calculator-display", "{formatted}"}
|
||||
div { class: "calculator-keypad"
|
||||
div { class: "input-keys"
|
||||
div { class: "function-keys"
|
||||
CalculatorKey { name: "key-clear", onclick: move |_| state.modify().clear_display(), "{clear_text}" }
|
||||
CalculatorKey { name: "key-sign", onclick: move |_| state.modify().toggle_sign(), "±"}
|
||||
CalculatorKey { name: "key-percent", onclick: move |_| state.modify().toggle_percent(), "%"}
|
||||
}
|
||||
div { class: "digit-keys"
|
||||
CalculatorKey { name: "key-0", onclick: move |_| state.modify().input_digit(0), "0" }
|
||||
CalculatorKey { name: "key-dot", onclick: move |_| state.modify().input_dot(), "●" }
|
||||
{(1..10).map(move |k| rsx!{
|
||||
CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| state.modify().input_digit(k), "{k}" }
|
||||
})}
|
||||
}
|
||||
rsx!(cx, div { id: "wrapper"
|
||||
div { class: "app", style { "{STYLE}" }
|
||||
div { class: "calculator", onkeypress: move |evt| state.write().handle_keydown(evt),
|
||||
div { class: "calculator-display", "{formatted}"}
|
||||
div { class: "calculator-keypad"
|
||||
div { class: "input-keys"
|
||||
div { class: "function-keys"
|
||||
CalculatorKey { name: "key-clear", onclick: move |_| state.write().clear_display(), "{clear_text}" }
|
||||
CalculatorKey { name: "key-sign", onclick: move |_| state.write().toggle_sign(), "±"}
|
||||
CalculatorKey { name: "key-percent", onclick: move |_| state.write().toggle_percent(), "%"}
|
||||
}
|
||||
div { class: "operator-keys"
|
||||
CalculatorKey { name:"key-divide", onclick: move |_| state.modify().set_operator(Operator::Div), "÷" }
|
||||
CalculatorKey { name:"key-multiply", onclick: move |_| state.modify().set_operator(Operator::Mul), "×" }
|
||||
CalculatorKey { name:"key-subtract", onclick: move |_| state.modify().set_operator(Operator::Sub), "−" }
|
||||
CalculatorKey { name:"key-add", onclick: move |_| state.modify().set_operator(Operator::Add), "+" }
|
||||
CalculatorKey { name:"key-equals", onclick: move |_| state.modify().perform_operation(), "=" }
|
||||
div { class: "digit-keys"
|
||||
CalculatorKey { name: "key-0", onclick: move |_| state.write().input_digit(0), "0" }
|
||||
CalculatorKey { name: "key-dot", onclick: move |_| state.write().input_dot(), "●" }
|
||||
{(1..10).map(move |k| rsx!{
|
||||
CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| state.write().input_digit(k), "{k}" }
|
||||
})}
|
||||
}
|
||||
}
|
||||
div { class: "operator-keys"
|
||||
CalculatorKey { name:"key-divide", onclick: move |_| state.write().set_operator(Operator::Div), "÷" }
|
||||
CalculatorKey { name:"key-multiply", onclick: move |_| state.write().set_operator(Operator::Mul), "×" }
|
||||
CalculatorKey { name:"key-subtract", onclick: move |_| state.write().set_operator(Operator::Sub), "−" }
|
||||
CalculatorKey { name:"key-add", onclick: move |_| state.write().set_operator(Operator::Add), "+" }
|
||||
CalculatorKey { name:"key-equals", onclick: move |_| state.write().perform_operation(), "=" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -89,7 +87,6 @@ fn CalculatorKey<'a, 'r>(cx: Context<'a>, props: &'a CalculatorKeyProps) -> DomT
|
||||
})
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct Calculator {
|
||||
display_value: String,
|
||||
operator: Option<Operator>,
|
||||
|
||||
+11
-13
@@ -11,23 +11,21 @@ fn main() {
|
||||
dioxus::desktop::launch(App, |c| c);
|
||||
}
|
||||
|
||||
pub static App: FC<()> = |cx, props| {
|
||||
pub static App: FC<()> = |cx, _| {
|
||||
let state = use_state(cx, PlayerState::new);
|
||||
|
||||
let is_playing = state.is_playing();
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 {"Select an option"}
|
||||
h3 {"The radio is... {is_playing}!"}
|
||||
button {
|
||||
"Pause"
|
||||
onclick: move |_| state.modify().reduce(PlayerAction::Pause)
|
||||
}
|
||||
button {
|
||||
"Play"
|
||||
onclick: move |_| state.modify().reduce(PlayerAction::Play)
|
||||
}
|
||||
rsx!(cx, div {
|
||||
h1 {"Select an option"}
|
||||
h3 {"The radio is... {is_playing}!"}
|
||||
button {
|
||||
"Pause"
|
||||
onclick: move |_| state.modify().reduce(PlayerAction::Pause)
|
||||
}
|
||||
button {
|
||||
"Play"
|
||||
onclick: move |_| state.modify().reduce(PlayerAction::Play)
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
//! Example: Webview Renderer
|
||||
//! -------------------------
|
||||
//!
|
||||
//! This example shows how to use the dioxus_desktop crate to build a basic desktop application.
|
||||
//!
|
||||
//! Under the hood, the dioxus_desktop crate bridges a native Dioxus VirtualDom with a custom prebuit application running
|
||||
//! in the webview runtime. Custom handlers are provided for the webview instance to consume patches and emit user events
|
||||
//! into the native VDom instance.
|
||||
//!
|
||||
//! Currently, NodeRefs won't work properly, but all other event functionality will.
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus::desktop::launch(App, |c| c);
|
||||
}
|
||||
|
||||
static App: FC<()> = |cx, props| {
|
||||
let slides = use_state(cx, SlideController::new);
|
||||
|
||||
let slide = match slides.slide_id {
|
||||
0 => cx.render(rsx!(Title {})),
|
||||
1 => cx.render(rsx!(Slide1 {})),
|
||||
2 => cx.render(rsx!(Slide2 {})),
|
||||
3 => cx.render(rsx!(Slide3 {})),
|
||||
_ => cx.render(rsx!(End {})),
|
||||
};
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
style: {
|
||||
background_color: "red"
|
||||
}
|
||||
div {
|
||||
div { h1 {"my awesome slideshow"} }
|
||||
div {
|
||||
button {"<-", onclick: move |_| slides.modify().go_forward()}
|
||||
h3 { "{slides.slide_id}" }
|
||||
button {"->" onclick: move |_| slides.modify().go_backward()}
|
||||
}
|
||||
}
|
||||
{slide}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
struct SlideController {
|
||||
slide_id: isize,
|
||||
}
|
||||
impl SlideController {
|
||||
fn new() -> Self {
|
||||
Self { slide_id: 0 }
|
||||
}
|
||||
fn can_go_forward(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn can_go_backward(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn go_forward(&mut self) {
|
||||
if self.can_go_forward() {
|
||||
self.slide_id += 1;
|
||||
}
|
||||
}
|
||||
fn go_backward(&mut self) {
|
||||
if self.can_go_backward() {
|
||||
self.slide_id -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Title: FC<()> = |cx, props| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 { "Title" }
|
||||
p {}
|
||||
}
|
||||
})
|
||||
};
|
||||
const Slide1: FC<()> = |cx, props| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 { "Slide1" }
|
||||
p {}
|
||||
}
|
||||
})
|
||||
};
|
||||
const Slide2: FC<()> = |cx, props| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 { "Slide2" }
|
||||
p {}
|
||||
}
|
||||
})
|
||||
};
|
||||
const Slide3: FC<()> = |cx, props| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 { "Slide3" }
|
||||
p {}
|
||||
}
|
||||
})
|
||||
};
|
||||
const End: FC<()> = |cx, props| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 { "End" }
|
||||
p {}
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -1,67 +0,0 @@
|
||||
use std::cell::Cell;
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_core::{
|
||||
nodes::{VElement, VText},
|
||||
ElementId,
|
||||
};
|
||||
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
dioxus::desktop::launch(Example, |c| c);
|
||||
}
|
||||
|
||||
const STYLE: &str = r#"
|
||||
body {background-color: powderblue;}
|
||||
h1 {color: blue;}
|
||||
p {color: red;}
|
||||
"#;
|
||||
|
||||
const Example: FC<()> = |cx, props| {
|
||||
cx.render(rsx! {
|
||||
Fragment {
|
||||
Fragment {
|
||||
Fragment {
|
||||
"h1"
|
||||
div {
|
||||
|
||||
}
|
||||
}
|
||||
"h2"
|
||||
}
|
||||
"h3"
|
||||
}
|
||||
"h4"
|
||||
div { "h5" }
|
||||
button { }
|
||||
Child {}
|
||||
})
|
||||
};
|
||||
|
||||
const Child: FC<()> = |cx, props| {
|
||||
cx.render(rsx!(
|
||||
h1 {"1" }
|
||||
h1 {"2" }
|
||||
h1 {"3" }
|
||||
h1 {"4" }
|
||||
))
|
||||
};
|
||||
|
||||
// this is a bad case that hurts our subtree memoization :(
|
||||
const AbTest: FC<()> = |cx, props| {
|
||||
if 1 == 2 {
|
||||
cx.render(rsx!(
|
||||
h1 {"1"}
|
||||
h1 {"2"}
|
||||
h1 {"3"}
|
||||
h1 {"4"}
|
||||
))
|
||||
} else {
|
||||
cx.render(rsx!(
|
||||
h1 {"1"}
|
||||
h1 {"2"}
|
||||
h2 {"basd"}
|
||||
h1 {"4"}
|
||||
))
|
||||
}
|
||||
};
|
||||
+43
-45
@@ -48,62 +48,60 @@ const App: FC<()> = |cx, props| {
|
||||
_ => "items",
|
||||
};
|
||||
|
||||
cx.render(rsx! {
|
||||
div { id: "app"
|
||||
style {"{STYLE}"}
|
||||
div {
|
||||
header { class: "header"
|
||||
h1 {"todos"}
|
||||
input {
|
||||
class: "new-todo"
|
||||
placeholder: "What needs to be done?"
|
||||
value: "{draft}"
|
||||
oninput: move |evt| draft.set(evt.value())
|
||||
rsx!(cx, div { id: "app"
|
||||
style {"{STYLE}"}
|
||||
div {
|
||||
header { class: "header"
|
||||
h1 {"todos"}
|
||||
input {
|
||||
class: "new-todo"
|
||||
placeholder: "What needs to be done?"
|
||||
value: "{draft}"
|
||||
oninput: move |evt| draft.set(evt.value())
|
||||
}
|
||||
}
|
||||
{todolist}
|
||||
{(!todos.is_empty()).then(|| rsx!(
|
||||
footer {
|
||||
span { strong {"{items_left}"} span {"{item_text} left"} }
|
||||
ul { class: "filters"
|
||||
li { class: "All", a { href: "", onclick: move |_| filter.set(FilterState::All), "All" }}
|
||||
li { class: "Active", a { href: "active", onclick: move |_| filter.set(FilterState::Active), "Active" }}
|
||||
li { class: "Completed", a { href: "completed", onclick: move |_| filter.set(FilterState::Completed), "Completed" }}
|
||||
}
|
||||
}
|
||||
{todolist}
|
||||
{(!todos.is_empty()).then(|| rsx!(
|
||||
footer {
|
||||
span { strong {"{items_left}"} span {"{item_text} left"} }
|
||||
ul { class: "filters"
|
||||
li { class: "All", a { href: "", onclick: move |_| filter.set(FilterState::All), "All" }}
|
||||
li { class: "Active", a { href: "active", onclick: move |_| filter.set(FilterState::Active), "Active" }}
|
||||
li { class: "Completed", a { href: "completed", onclick: move |_| filter.set(FilterState::Completed), "Completed" }}
|
||||
}
|
||||
}
|
||||
))}
|
||||
}
|
||||
footer { class: "info"
|
||||
p {"Double-click to edit a todo"}
|
||||
p { "Created by ", a { "jkelleyrtp", href: "http://github.com/jkelleyrtp/" }}
|
||||
p { "Part of ", a { "TodoMVC", href: "http://todomvc.com" }}
|
||||
}
|
||||
))}
|
||||
}
|
||||
footer { class: "info"
|
||||
p {"Double-click to edit a todo"}
|
||||
p { "Created by ", a { "jkelleyrtp", href: "http://github.com/jkelleyrtp/" }}
|
||||
p { "Part of ", a { "TodoMVC", href: "http://todomvc.com" }}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
#[derive(PartialEq, Props)]
|
||||
pub struct TodoEntryProps {
|
||||
todo: std::rc::Rc<TodoItem>,
|
||||
todo: Rc<TodoItem>,
|
||||
}
|
||||
|
||||
pub fn TodoEntry<'a>(cx: Context<'a>, TodoEntryProps { todo }: &'a TodoEntryProps) -> DomTree<'a> {
|
||||
pub fn TodoEntry<'a>(cx: Context<'a>, props: &TodoEntryProps) -> DomTree<'a> {
|
||||
let is_editing = use_state(cx, || false);
|
||||
let contents = "";
|
||||
let contents = use_state(cx, || String::from(""));
|
||||
let todo = &props.todo;
|
||||
|
||||
cx.render(rsx! (
|
||||
li {
|
||||
"{todo.id}"
|
||||
input {
|
||||
class: "toggle"
|
||||
r#type: "checkbox"
|
||||
"{todo.checked}"
|
||||
}
|
||||
{is_editing.then(|| rsx!{
|
||||
input {
|
||||
value: "{contents}"
|
||||
}
|
||||
})}
|
||||
rsx!(cx, li {
|
||||
"{todo.id}"
|
||||
input {
|
||||
class: "toggle"
|
||||
r#type: "checkbox"
|
||||
"{todo.checked}"
|
||||
}
|
||||
))
|
||||
{is_editing.then(|| rsx!{
|
||||
input {
|
||||
value: "{contents}"
|
||||
oninput: move |evt| contents.set(evt.value())
|
||||
}
|
||||
})}
|
||||
})
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
//! Example: Webview Renderer
|
||||
//! -------------------------
|
||||
//!
|
||||
//! This example shows how to use the dioxus_desktop crate to build a basic desktop application.
|
||||
//!
|
||||
//! Under the hood, the dioxus_desktop crate bridges a native Dioxus VirtualDom with a custom prebuit application running
|
||||
//! in the webview runtime. Custom handlers are provided for the webview instance to consume patches and emit user events
|
||||
//! into the native VDom instance.
|
||||
//!
|
||||
//! Currently, NodeRefs won't work properly, but all other event functionality will.
|
||||
#![allow(non_upper_case_globals, non_snake_case)]
|
||||
|
||||
use dioxus::{events::on::MouseEvent, prelude::*};
|
||||
|
||||
fn main() -> anyhow::Result<()> {
|
||||
env_logger::init();
|
||||
dioxus::desktop::launch(App, |c| c)
|
||||
}
|
||||
|
||||
static App: FC<()> = |cx, props| {
|
||||
let state = use_state(cx, || String::from("hello"));
|
||||
let clear_text = state == "hello";
|
||||
|
||||
dbg!("rednering parent");
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 {"{state}"}
|
||||
CalculatorKey { name: "key-clear", onclick: move |_| state.modify().push_str("hello"), "{clear_text}" }
|
||||
CalculatorKey { name: "key-sign", onclick: move |_| { state.modify().pop(); }, "±"}
|
||||
}
|
||||
})
|
||||
};
|
||||
|
||||
#[derive(Props)]
|
||||
struct CalculatorKeyProps<'a> {
|
||||
name: &'static str,
|
||||
onclick: &'a dyn Fn(MouseEvent),
|
||||
}
|
||||
|
||||
fn CalculatorKey<'a>(cx: Context<'a>, props: &'a CalculatorKeyProps) -> DomTree<'a> {
|
||||
cx.render(rsx! {
|
||||
button {
|
||||
class: "calculator-key {props.name}"
|
||||
onclick: {props.onclick}
|
||||
{cx.children()}
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user