awesome: arbitrary expressions excepted without braces
This commit is contained in:
1 parent
14961023f9
commit
4c85bcfdc8
40 files changed
+825
-767
No files matched your search
+8
-16
@@ -42,14 +42,6 @@ These examples are not necessarily meant to be run, but rather serve as a refere
|
||||
| [Complete rsx reference](./rsx_usage.rs) | A complete reference for all rsx! usage | ✅ |
|
||||
| [Event Listeners](./listener.rs) | Attach closures to events on elements | ✅ |
|
||||
|
||||
These web-specific examples must be run with `dioxus-cli` using `dioxus develop --example XYZ`
|
||||
|
||||
| Example | What it does |
|
||||
| ------- | ------------ |
|
||||
| asd | this does |
|
||||
| asd | this does |
|
||||
|
||||
|
||||
|
||||
## Show me some examples!
|
||||
|
||||
@@ -75,9 +67,9 @@ fn Toggle(cx: Scope<ToggleProps>) -> Element {
|
||||
let mut toggled = use_state(&cx, || false);
|
||||
cx.render(rsx!{
|
||||
div {
|
||||
{&cx.props.children}
|
||||
&cx.props.children
|
||||
button { onclick: move |_| toggled.set(true),
|
||||
{toggled.and_then(|| "On").or_else(|| "Off")}
|
||||
toggled.and_then(|| "On").or_else(|| "Off")
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -112,8 +104,8 @@ fn App(cx: Scope) -> Element {
|
||||
|
||||
if should_show {
|
||||
cx.render(rsx!(
|
||||
{title}
|
||||
ul { {list} }
|
||||
title,
|
||||
ul { list }
|
||||
))
|
||||
} else {
|
||||
None
|
||||
@@ -169,10 +161,10 @@ enum Route {
|
||||
fn App(cx: Scope) -> Element {
|
||||
let route = use_router(cx, Route::parse);
|
||||
cx.render(rsx!(div {
|
||||
{match route {
|
||||
match route {
|
||||
Route::Home => rsx!( Home {} ),
|
||||
Route::Post(id) => rsx!( Post { id: id })
|
||||
}}
|
||||
}
|
||||
}))
|
||||
}
|
||||
```
|
||||
@@ -187,8 +179,8 @@ fn App(cx: Scope) -> Element {
|
||||
|
||||
cx.render(rsx!{
|
||||
div {
|
||||
"One doggo coming right up:"
|
||||
{doggo}
|
||||
"One doggo coming right up:",
|
||||
doggo
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+4
-6
@@ -26,20 +26,18 @@ fn app(cx: Scope) -> Element {
|
||||
|
||||
rsx!(cx, div {
|
||||
h1 {"count is {count}"}
|
||||
button {
|
||||
button { onclick: move |_| task.stop(),
|
||||
"Stop counting"
|
||||
onclick: move |_| task.stop()
|
||||
}
|
||||
button {
|
||||
button { onclick: move |_| task.resume(),
|
||||
"Start counting"
|
||||
onclick: move |_| task.resume()
|
||||
}
|
||||
button {
|
||||
"Switch counting direcion"
|
||||
onclick: move |_| {
|
||||
*direction.modify() *= -1;
|
||||
task.restart();
|
||||
}
|
||||
},
|
||||
"Switch counting direcion"
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -21,7 +21,7 @@ fn main() {
|
||||
}
|
||||
|
||||
fn App(cx: Scope) -> Element {
|
||||
let text: &mut Vec<String> = cx.use_hook(|_| vec![String::from("abc=def")], |f| f);
|
||||
let text = cx.use_hook(|_| vec![String::from("abc=def")], |f| f);
|
||||
|
||||
let first = text.get_mut(0).unwrap();
|
||||
|
||||
|
||||
+53
-26
@@ -24,7 +24,9 @@ fn app(cx: Scope) -> Element {
|
||||
let input_digit = move |num: u8| display_value.modify().push_str(num.to_string().as_str());
|
||||
|
||||
cx.render(rsx!(
|
||||
div { class: "calculator",
|
||||
style { [include_str!("./assets/calculator.css")] }
|
||||
div {
|
||||
class: "calculator",
|
||||
onkeydown: move |evt| match evt.key_code {
|
||||
KeyCode::Add => operator.set(Some("+")),
|
||||
KeyCode::Subtract => operator.set(Some("-")),
|
||||
@@ -46,12 +48,11 @@ fn app(cx: Scope) -> Element {
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
div { class: "calculator-display", {[cur_val.separated_string()]} }
|
||||
div { class: "input-keys"
|
||||
div { class: "function-keys"
|
||||
},
|
||||
div { class: "calculator-display", [cur_val.separated_string()] }
|
||||
div { class: "input-keys",
|
||||
div { class: "function-keys",
|
||||
CalculatorKey {
|
||||
{[if display_value == "0" { "C" } else { "AC" }]}
|
||||
name: "key-clear",
|
||||
onclick: move |_| {
|
||||
display_value.set("0".to_string());
|
||||
@@ -59,10 +60,10 @@ fn app(cx: Scope) -> Element {
|
||||
operator.set(None);
|
||||
cur_val.set(0.0);
|
||||
}
|
||||
}
|
||||
},
|
||||
[if display_value == "0" { "C" } else { "AC" }]
|
||||
}
|
||||
CalculatorKey {
|
||||
"±"
|
||||
name: "key-sign",
|
||||
onclick: move |_| {
|
||||
if display_value.starts_with("-") {
|
||||
@@ -71,28 +72,53 @@ fn app(cx: Scope) -> Element {
|
||||
display_value.set(format!("-{}", *display_value))
|
||||
}
|
||||
},
|
||||
"±"
|
||||
}
|
||||
CalculatorKey {
|
||||
"%"
|
||||
onclick: {toggle_percent}
|
||||
onclick: toggle_percent,
|
||||
name: "key-percent",
|
||||
"%"
|
||||
}
|
||||
}
|
||||
div { class: "digit-keys"
|
||||
CalculatorKey { name: "key-0", onclick: move |_| input_digit(0), "0" }
|
||||
CalculatorKey { name: "key-dot", onclick: move |_| display_value.modify().push_str("."), "●" }
|
||||
|
||||
{(1..9).map(|k| rsx!{
|
||||
CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| input_digit(k), "{k}" }
|
||||
})}
|
||||
div { class: "digit-keys",
|
||||
CalculatorKey { name: "key-0", onclick: move |_| input_digit(0),
|
||||
"0"
|
||||
}
|
||||
CalculatorKey { name: "key-dot", onclick: move |_| display_value.modify().push_str("."),
|
||||
"●"
|
||||
}
|
||||
(1..9).map(|k| rsx!{
|
||||
CalculatorKey {
|
||||
key: "{k}",
|
||||
name: "key-{k}",
|
||||
onclick: move |_| input_digit(k),
|
||||
"{k}"
|
||||
}
|
||||
}),
|
||||
}
|
||||
div { class: "operator-keys"
|
||||
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("+")) "+" }
|
||||
|
||||
div { class: "operator-keys",
|
||||
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 |_| {
|
||||
if let Some(op) = operator.as_ref() {
|
||||
@@ -109,6 +135,7 @@ fn app(cx: Scope) -> Element {
|
||||
operator.set(None);
|
||||
}
|
||||
},
|
||||
"="
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -125,9 +152,9 @@ fn CalculatorKey<'a>(
|
||||
) -> Element {
|
||||
cx.render(rsx! {
|
||||
button {
|
||||
class: "calculator-key {name}"
|
||||
onclick: {onclick}
|
||||
{children}
|
||||
class: "calculator-key {name}",
|
||||
onclick: onclick,
|
||||
children
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -20,11 +20,11 @@ pub static Example: Component = |cx| {
|
||||
li { onclick: move |_| example_data.set(f)
|
||||
"ID: {f}"
|
||||
ul {
|
||||
{(0..10).map(|k| rsx!{
|
||||
(0..10).map(|k| rsx!{
|
||||
li {
|
||||
"Sub iterator: {f}.{k}"
|
||||
}
|
||||
})}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+95
-82
@@ -4,7 +4,7 @@ Tiny CRM: A port of the Yew CRM example to Dioxus.
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus::web::launch(App);
|
||||
dioxus::desktop::launch(app);
|
||||
}
|
||||
enum Scene {
|
||||
ClientsList,
|
||||
@@ -19,88 +19,101 @@ pub struct Client {
|
||||
pub description: String,
|
||||
}
|
||||
|
||||
static App: Component = |cx| {
|
||||
let mut clients = use_ref(&cx, || vec![] as Vec<Client>);
|
||||
let mut scene = use_state(&cx, || Scene::ClientsList);
|
||||
fn app(cx: Scope) -> Element {
|
||||
let clients = use_ref(&cx, || vec![] as Vec<Client>);
|
||||
|
||||
let mut firstname = use_state(&cx, || String::new());
|
||||
let mut lastname = use_state(&cx, || String::new());
|
||||
let mut description = use_state(&cx, || String::new());
|
||||
|
||||
let scene = match *scene {
|
||||
Scene::ClientsList => {
|
||||
rsx!(cx, div { class: "crm"
|
||||
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 { 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 => {
|
||||
let add_new = move |_| {
|
||||
clients.write().push(Client {
|
||||
description: (*description).clone(),
|
||||
first_name: (*firstname).clone(),
|
||||
last_name: (*lastname).clone(),
|
||||
});
|
||||
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.clone())
|
||||
}
|
||||
input { class: "new-client lastname" placeholder: "Last name" value: "{lastname}"
|
||||
oninput: move |e| lastname.set(e.value.clone())
|
||||
}
|
||||
textarea { class: "new-client description" placeholder: "Description" value: "{description}"
|
||||
oninput: move |e| description.set(e.value.clone())
|
||||
}
|
||||
}
|
||||
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 {
|
||||
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"
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
let scene = use_state(&cx, || Scene::ClientsList);
|
||||
let firstname = use_state(&cx, String::new);
|
||||
let lastname = use_state(&cx, String::new);
|
||||
let description = use_state(&cx, String::new);
|
||||
|
||||
cx.render(rsx!(
|
||||
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}
|
||||
}
|
||||
body { margin_left: "35%",
|
||||
link {
|
||||
rel: "stylesheet",
|
||||
href: "https://unpkg.com/purecss@2.0.6/build/pure-min.css",
|
||||
integrity: "sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5",
|
||||
crossorigin: "anonymous",
|
||||
}
|
||||
|
||||
h1 {"Dioxus CRM Example"}
|
||||
|
||||
match *scene {
|
||||
Scene::ClientsList => rsx!(
|
||||
div { class: "crm",
|
||||
h2 { margin_bottom: "10px", "List of clients" }
|
||||
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 { 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!(
|
||||
div { class: "crm",
|
||||
h2 { margin_bottom: "10px", "Add new client" }
|
||||
form { class: "pure-form",
|
||||
input {
|
||||
class: "new-client firstname",
|
||||
placeholder: "First name",
|
||||
value: "{firstname}",
|
||||
oninput: move |e| firstname.set(e.value.clone())
|
||||
}
|
||||
input {
|
||||
class: "new-client lastname",
|
||||
placeholder: "Last name",
|
||||
value: "{lastname}",
|
||||
oninput: move |e| lastname.set(e.value.clone())
|
||||
}
|
||||
textarea {
|
||||
class: "new-client description",
|
||||
placeholder: "Description",
|
||||
value: "{description}",
|
||||
oninput: move |e| description.set(e.value.clone())
|
||||
}
|
||||
}
|
||||
button {
|
||||
class: "pure-button pure-button-primary",
|
||||
onclick: move |_| {
|
||||
clients.write().push(Client {
|
||||
description: (*description).clone(),
|
||||
first_name: (*firstname).clone(),
|
||||
last_name: (*lastname).clone(),
|
||||
});
|
||||
description.set(String::new());
|
||||
firstname.set(String::new());
|
||||
lastname.set(String::new());
|
||||
},
|
||||
"Add New"
|
||||
}
|
||||
button { class: "pure-button", onclick: move |_| scene.set(Scene::ClientsList),
|
||||
"Go Back"
|
||||
}
|
||||
}
|
||||
),
|
||||
Scene::Settings => rsx!(
|
||||
div {
|
||||
h2 { margin_bottom: "10px", "Settings" }
|
||||
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"
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
))
|
||||
};
|
||||
}
|
||||
@@ -13,6 +13,6 @@ static App: Component = |cx| {
|
||||
div {
|
||||
"hello world!"
|
||||
}
|
||||
{(0..10).map(|f| rsx!( div {"abc {f}"}))}
|
||||
(0..10).map(|f| rsx!( div {"abc {f}"}))
|
||||
))
|
||||
};
|
||||
@@ -1,8 +0,0 @@
|
||||
use dioxus_core as dioxus;
|
||||
use dioxus_core::prelude::*;
|
||||
use dioxus_core_macro::*;
|
||||
use dioxus_hooks::*;
|
||||
|
||||
use dioxus_html as dioxus_elements;
|
||||
|
||||
fn main() {}
|
||||
@@ -1 +0,0 @@
|
||||
fn main() {}
|
||||
@@ -98,24 +98,24 @@ pub static App: Component = |cx| {
|
||||
}
|
||||
}
|
||||
}
|
||||
ul { class: "todo-list"
|
||||
{filtered_todos.iter().map(|id| rsx!(TodoEntry { key: "{id}", id: *id }))}
|
||||
ul { class: "todo-list",
|
||||
filtered_todos.iter().map(|id| rsx!(TodoEntry { key: "{id}", id: *id }))
|
||||
}
|
||||
{(!todos.read().is_empty()).then(|| rsx!(
|
||||
footer { class: "footer"
|
||||
(!todos.read().is_empty()).then(|| rsx!(
|
||||
footer { class: "footer",
|
||||
span { class: "todo-count" strong {"{items_left} "} span {"{item_text} left"} }
|
||||
ul { class: "filters"
|
||||
li { class: "All", a { onclick: move |_| filter.set(FilterState::All), "All" }}
|
||||
li { class: "Active", a { onclick: move |_| filter.set(FilterState::Active), "Active" }}
|
||||
li { class: "Completed", a { onclick: move |_| filter.set(FilterState::Completed), "Completed" }}
|
||||
}
|
||||
{(show_clear_completed).then(|| rsx!(
|
||||
(show_clear_completed).then(|| rsx!(
|
||||
button { class: "clear-completed", onclick: move |_| clear_completed(),
|
||||
"Clear completed"
|
||||
}
|
||||
))}
|
||||
))
|
||||
}
|
||||
))}
|
||||
))
|
||||
}
|
||||
}
|
||||
footer { class: "info"
|
||||
|
||||
+30
-43
@@ -4,50 +4,45 @@
|
||||
//! This is a fun little desktop application that lets you explore the file system.
|
||||
//!
|
||||
//! This example is interesting because it's mixing filesystem operations and GUI, which is typically hard for UI to do.
|
||||
//!
|
||||
//! It also uses `use_ref` to maintain a model, rather than `use_state`. That way,
|
||||
//! we dont need to clutter our code with `read` commands.
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus::desktop::launch_cfg(App, |c| {
|
||||
dioxus::desktop::launch_cfg(app, |c| {
|
||||
c.with_window(|w| {
|
||||
w.with_resizable(true).with_inner_size(
|
||||
dioxus::desktop::wry::application::dpi::LogicalSize::new(400.0, 800.0),
|
||||
)
|
||||
w.with_resizable(true)
|
||||
.with_inner_size(dioxus::desktop::tao::dpi::LogicalSize::new(400.0, 800.0))
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
static App: Component = |cx| {
|
||||
let file_manager = use_ref(&cx, Files::new);
|
||||
let files = file_manager.read();
|
||||
|
||||
let file_list = files.path_names.iter().enumerate().map(|(dir_id, path)| {
|
||||
rsx! (
|
||||
li { a {"{path}", onclick: move |_| file_manager.write().enter_dir(dir_id), href: "#"} }
|
||||
)
|
||||
});
|
||||
|
||||
let err_disp = files.err.as_ref().map(|err| {
|
||||
rsx! (
|
||||
div {
|
||||
code {"{err}"}
|
||||
button {"x", onclick: move |_| file_manager.write().clear_err() }
|
||||
}
|
||||
)
|
||||
});
|
||||
|
||||
let current_dir = files.current();
|
||||
fn app(cx: Scope) -> Element {
|
||||
let files = use_ref(&cx, Files::new);
|
||||
|
||||
cx.render(rsx!(
|
||||
div {
|
||||
h1 {"Files: "}
|
||||
h3 {"Cur dir: {current_dir}"}
|
||||
button { "go up", onclick: move |_| file_manager.write().go_up() }
|
||||
ol { {file_list} }
|
||||
{err_disp}
|
||||
h1 { "Files: " }
|
||||
h3 { "Cur dir: " [files.read().current()] }
|
||||
button { onclick: move |_| files.write().go_up(), "go up" }
|
||||
ol {
|
||||
files.read().path_names.iter().enumerate().map(|(dir_id, path)| rsx!(
|
||||
li { key: "{path}",
|
||||
a { href: "#", onclick: move |_| files.write().enter_dir(dir_id),
|
||||
"{path}",
|
||||
}
|
||||
}
|
||||
))
|
||||
}
|
||||
files.read().err.as_ref().map(|err| rsx!(
|
||||
div {
|
||||
code { "{err}" }
|
||||
button { onclick: move |_| files.write().clear_err(), "x" }
|
||||
}
|
||||
))
|
||||
))
|
||||
};
|
||||
}
|
||||
|
||||
struct Files {
|
||||
path_stack: Vec<String>,
|
||||
@@ -69,29 +64,21 @@ impl Files {
|
||||
}
|
||||
|
||||
fn reload_path_list(&mut self) {
|
||||
let cur_path = self.path_stack.last().unwrap();
|
||||
log::info!("Reloading path list for {:?}", cur_path);
|
||||
let paths = match std::fs::read_dir(cur_path) {
|
||||
let paths = match std::fs::read_dir(self.path_stack.last().unwrap()) {
|
||||
Ok(e) => e,
|
||||
Err(err) => {
|
||||
let err = format!("An error occured: {:?}", err);
|
||||
self.err = Some(err);
|
||||
self.err = Some(format!("An error occured: {:?}", err));
|
||||
self.path_stack.pop();
|
||||
return;
|
||||
}
|
||||
};
|
||||
let collected = paths.collect::<Vec<_>>();
|
||||
log::info!("Path list reloaded {:#?}", collected);
|
||||
|
||||
// clear the current state
|
||||
self.clear_err();
|
||||
self.path_names.clear();
|
||||
|
||||
for path in collected {
|
||||
self.path_names
|
||||
.push(path.unwrap().path().display().to_string());
|
||||
}
|
||||
log::info!("path namees are {:#?}", self.path_names);
|
||||
self.path_names
|
||||
.extend(paths.map(|path| path.unwrap().path().display().to_string()));
|
||||
}
|
||||
|
||||
fn go_up(&mut self) {
|
||||
|
||||
@@ -2,8 +2,8 @@ use dioxus::prelude::*;
|
||||
use rand::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus::web::launch(App);
|
||||
// dioxus::desktop::launch(App);
|
||||
// dioxus::web::launch(App);
|
||||
dioxus::desktop::launch(App);
|
||||
}
|
||||
|
||||
#[derive(Clone, PartialEq)]
|
||||
@@ -31,16 +31,16 @@ impl Label {
|
||||
}
|
||||
|
||||
static App: Component = |cx| {
|
||||
let mut items = use_ref(&cx, || vec![]);
|
||||
let mut selected = use_state(&cx, || None);
|
||||
let items = use_ref(&cx, || vec![]);
|
||||
let selected = use_state(&cx, || None);
|
||||
|
||||
cx.render(rsx! {
|
||||
div { class: "container"
|
||||
div { class: "jumbotron"
|
||||
div { class: "row"
|
||||
div { class: "container",
|
||||
div { class: "jumbotron",
|
||||
div { class: "row",
|
||||
div { class: "col-md-6", h1 { "Dioxus" } }
|
||||
div { class: "col-md-6"
|
||||
div { class: "row"
|
||||
div { class: "col-md-6",
|
||||
div { class: "row",
|
||||
ActionButton { name: "Create 1,000 rows", id: "run",
|
||||
onclick: move || items.set(Label::new_list(1_000)),
|
||||
}
|
||||
@@ -67,15 +67,15 @@ static App: Component = |cx| {
|
||||
tbody {
|
||||
{items.read().iter().enumerate().map(|(id, item)| {
|
||||
let is_in_danger = if (*selected).map(|s| s == id).unwrap_or(false) {"danger"} else {""};
|
||||
rsx!(tr { class: "{is_in_danger}"
|
||||
rsx!(tr { class: "{is_in_danger}",
|
||||
td { class:"col-md-1" }
|
||||
td { class:"col-md-1", "{item.key}" }
|
||||
td { class:"col-md-1", onclick: move |_| selected.set(Some(id)),
|
||||
a { class: "lbl", {item.labels} }
|
||||
a { class: "lbl", item.labels }
|
||||
}
|
||||
td { class: "col-md-1"
|
||||
td { class: "col-md-1",
|
||||
a { class: "remove", onclick: move |_| { items.write().remove(id); },
|
||||
span { class: "glyphicon glyphicon-remove remove" aria_hidden: "true" }
|
||||
span { class: "glyphicon glyphicon-remove remove", aria_hidden: "true" }
|
||||
}
|
||||
}
|
||||
td { class: "col-md-6" }
|
||||
@@ -83,7 +83,7 @@ static App: Component = |cx| {
|
||||
})}
|
||||
}
|
||||
}
|
||||
// span { class: "preloadicon glyphicon glyphicon-remove" aria_hidden: "true" }
|
||||
span { class: "preloadicon glyphicon glyphicon-remove", aria_hidden: "true" }
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -96,7 +96,7 @@ struct ActionButtonProps<'a> {
|
||||
}
|
||||
|
||||
fn ActionButton<'a>(cx: Scope<'a, ActionButtonProps<'a>>) -> Element {
|
||||
rsx!(cx, div { class: "col-sm-6 smallpad"
|
||||
rsx!(cx, div { class: "col-sm-6 smallpad",
|
||||
button { class:"btn btn-primary btn-block", r#type: "button", id: "{cx.props.id}", onclick: move |_| (cx.props.onclick)(),
|
||||
"{cx.props.name}"
|
||||
}
|
||||
|
||||
@@ -16,18 +16,18 @@ fn main() {
|
||||
let vdom = VirtualDom::new(App);
|
||||
let content = ssr::render_vdom_cfg(&vdom, |f| f.pre_render(true));
|
||||
|
||||
dioxus::desktop::launch_cfg(App, |c| c.with_prerendered(content));
|
||||
// dioxus::desktop::launch_cfg(App, |c| c.with_prerendered(content));
|
||||
}
|
||||
|
||||
static App: Component = |cx| {
|
||||
let mut val = use_state(&cx, || 0);
|
||||
let val = use_state(&cx, || 0);
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 {"hello world. Count: {val}"}
|
||||
h1 { "hello world. Count: {val}" }
|
||||
button {
|
||||
onclick: move |_| *val.modify() += 1,
|
||||
"click to increment"
|
||||
onclick: move |_| val += 1
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
+20
-20
@@ -24,42 +24,42 @@ use dioxus::prelude::*;
|
||||
const STYLE: &str = include_str!("./assets/calculator.css");
|
||||
fn main() {
|
||||
env_logger::init();
|
||||
dioxus::desktop::launch_cfg(App, |cfg| {
|
||||
cfg.with_window(|w| {
|
||||
w.with_title("Calculator Demo")
|
||||
.with_resizable(false)
|
||||
.with_inner_size(LogicalSize::new(320.0, 530.0))
|
||||
})
|
||||
});
|
||||
// dioxus::desktop::launch_cfg(App, |cfg| {
|
||||
// cfg.with_window(|w| {
|
||||
// w.with_title("Calculator Demo")
|
||||
// .with_resizable(false)
|
||||
// .with_inner_size(LogicalSize::new(320.0, 530.0))
|
||||
// })
|
||||
// });
|
||||
}
|
||||
|
||||
static App: Component = |cx| {
|
||||
fn app(cx: Scope) -> Element {
|
||||
let state = use_ref(&cx, || Calculator::new());
|
||||
|
||||
let clear_display = state.read().display_value.eq("0");
|
||||
let clear_text = if clear_display { "C" } else { "AC" };
|
||||
let formatted = state.read().formatted_display();
|
||||
|
||||
rsx!(cx, div { id: "wrapper"
|
||||
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"
|
||||
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: "digit-keys"
|
||||
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!{
|
||||
(1..10).map(move |k| rsx!{
|
||||
CalculatorKey { key: "{k}", name: "key-{k}", onclick: move |_| state.write().input_digit(k), "{k}" }
|
||||
})}
|
||||
})
|
||||
}
|
||||
}
|
||||
div { class: "operator-keys"
|
||||
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), "−" }
|
||||
@@ -70,7 +70,7 @@ static App: Component = |cx| {
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Props)]
|
||||
struct CalculatorKeyProps<'a> {
|
||||
@@ -82,9 +82,9 @@ struct CalculatorKeyProps<'a> {
|
||||
fn CalculatorKey<'a>(cx: Scope<'a, CalculatorKeyProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
button {
|
||||
class: "calculator-key {cx.props.name}"
|
||||
onclick: move |e| (cx.props.onclick)(e)
|
||||
{&cx.props.children}
|
||||
class: "calculator-key {cx.props.name}",
|
||||
onclick: move |e| (cx.props.onclick)(e),
|
||||
&cx.props.children
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
+11
-13
@@ -14,20 +14,18 @@ fn main() {
|
||||
pub static App: Component = |cx| {
|
||||
let state = use_state(&cx, PlayerState::new);
|
||||
|
||||
let is_playing = state.is_playing();
|
||||
|
||||
rsx!(cx, div {
|
||||
h1 {"Select an option"}
|
||||
h3 {"The radio is... {is_playing}!"}
|
||||
button {
|
||||
"Pause"
|
||||
onclick: move |_| state.modify().reduce(PlayerAction::Pause)
|
||||
cx.render(rsx!(
|
||||
div {
|
||||
h1 {"Select an option"}
|
||||
h3 { "The radio is... " [state.is_playing()], "!" }
|
||||
button { onclick: move |_| state.modify().reduce(PlayerAction::Pause),
|
||||
"Pause"
|
||||
}
|
||||
button { onclick: move |_| state.modify().reduce(PlayerAction::Play),
|
||||
"Play"
|
||||
}
|
||||
}
|
||||
button {
|
||||
"Play"
|
||||
onclick: move |_| state.modify().reduce(PlayerAction::Play)
|
||||
}
|
||||
})
|
||||
))
|
||||
};
|
||||
|
||||
enum PlayerAction {
|
||||
|
||||
+3
-3
@@ -9,13 +9,13 @@ fn main() {
|
||||
}
|
||||
|
||||
static App: Component = |cx| {
|
||||
let count = use_state(&cx, || 0);
|
||||
let mut count = use_state(&cx, || 0);
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 { "High-Five counter: {count}" }
|
||||
button { onclick: move |_| *count.modify() += 1, "Up high!" }
|
||||
button { onclick: move |_| *count.modify() -= 1, "Down low!" }
|
||||
button { onclick: move |_| count += 1, "Up high!" }
|
||||
button { onclick: move |_| count -= 1, "Down low!" }
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -0,0 +1,61 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
let mut vdom = VirtualDom::new(example);
|
||||
vdom.rebuild();
|
||||
|
||||
let out = dioxus::ssr::render_vdom_cfg(&vdom, |c| c.newline(true).indent(true));
|
||||
println!("{}", out);
|
||||
}
|
||||
|
||||
fn example(cx: Scope) -> Element {
|
||||
let items = use_state(&cx, || {
|
||||
vec![Thing {
|
||||
a: "asd".to_string(),
|
||||
b: 10,
|
||||
}]
|
||||
});
|
||||
|
||||
let things = use_ref(&cx, || {
|
||||
vec![Thing {
|
||||
a: "asd".to_string(),
|
||||
b: 10,
|
||||
}]
|
||||
});
|
||||
let things_list = things.read();
|
||||
|
||||
let mything = use_ref(&cx, || Some(String::from("asd")));
|
||||
let mything_read = mything.read();
|
||||
|
||||
cx.render(rsx!(
|
||||
div {
|
||||
div {
|
||||
id: "asd",
|
||||
"your neighborhood spiderman"
|
||||
|
||||
items.iter().cycle().take(5).map(|f| rsx!{
|
||||
div {
|
||||
"{f.a}"
|
||||
}
|
||||
})
|
||||
|
||||
things_list.iter().map(|f| rsx!{
|
||||
div {
|
||||
"{f.a}"
|
||||
}
|
||||
})
|
||||
|
||||
mything_read.as_ref().map(|f| rsx!{
|
||||
div {
|
||||
"{f}"
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
))
|
||||
}
|
||||
|
||||
struct Thing {
|
||||
a: String,
|
||||
b: u32,
|
||||
}
|
||||
+54
-29
@@ -60,6 +60,7 @@ pub static EXAMPLE: Component = |cx| {
|
||||
h1 {"Some text"}
|
||||
h1 {"Some text with {formatting}"}
|
||||
h1 {"Formatting basic expressions {formatting_tuple.0} and {formatting_tuple.1}"}
|
||||
h1 {"Formatting without interpolation " [formatting_tuple.0] "and" [formatting_tuple.1] }
|
||||
h2 {
|
||||
"Multiple"
|
||||
"Text"
|
||||
@@ -72,7 +73,7 @@ pub static EXAMPLE: Component = |cx| {
|
||||
h3 {"elements"}
|
||||
}
|
||||
div {
|
||||
class: "my special div"
|
||||
class: "my special div",
|
||||
h1 {"Headers and attributes!"}
|
||||
}
|
||||
div {
|
||||
@@ -88,42 +89,51 @@ pub static EXAMPLE: Component = |cx| {
|
||||
}
|
||||
|
||||
// Expressions can be used in element position too:
|
||||
{rsx!(p { "More templating!" })}
|
||||
// {html!(<p>"Even HTML templating!!"</p>)}
|
||||
rsx!(p { "More templating!" }),
|
||||
|
||||
// Iterators
|
||||
{(0..10).map(|i| rsx!(li { "{i}" }))}
|
||||
{{
|
||||
(0..10).map(|i| rsx!(li { "{i}" })),
|
||||
|
||||
// Iterators within expressions
|
||||
{
|
||||
let data = std::collections::HashMap::<&'static str, &'static str>::new();
|
||||
// Iterators *should* have keys when you can provide them.
|
||||
// Keys make your app run faster. Make sure your keys are stable, unique, and predictable.
|
||||
// Using an "ID" associated with your data is a good idea.
|
||||
data.into_iter().map(|(k, v)| rsx!(li { key: "{k}" "{v}" }))
|
||||
}}
|
||||
data.into_iter().map(|(k, v)| rsx!(li { key: "{k}", "{v}" }))
|
||||
}
|
||||
|
||||
// Matching
|
||||
{match true {
|
||||
match true {
|
||||
true => rsx!( h1 {"Top text"}),
|
||||
false => rsx!( h1 {"Bottom text"})
|
||||
}}
|
||||
}
|
||||
|
||||
// Conditional rendering
|
||||
// Dioxus conditional rendering is based around None/Some. We have no special syntax for conditionals.
|
||||
// You can convert a bool condition to rsx! with .then and .or
|
||||
{true.then(|| rsx!(div {}))}
|
||||
true.then(|| rsx!(div {})),
|
||||
|
||||
// True conditions need to be rendered (same reasons as matching)
|
||||
{if true {
|
||||
rsx!(cx, h1 {"Top text"})
|
||||
// Alternatively, you can use the "if" syntax - but both branches must be resolve to Element
|
||||
if false {
|
||||
rsx!(h1 {"Top text"})
|
||||
} else {
|
||||
rsx!(cx, h1 {"Bottom text"})
|
||||
}}
|
||||
rsx!(h1 {"Bottom text"})
|
||||
}
|
||||
|
||||
// returning "None" is a bit noisy... but rare in practice
|
||||
{None as Option<()>}
|
||||
// Using optionals for diverging branches
|
||||
if true {
|
||||
Some(rsx!(h1 {"Top text"}))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
|
||||
|
||||
// returning "None" without a diverging branch is a bit noisy... but rare in practice
|
||||
None as Option<()>,
|
||||
|
||||
// Use the Dioxus type-alias for less noise
|
||||
{NONE_ELEMENT}
|
||||
NONE_ELEMENT,
|
||||
|
||||
// can also just use empty fragments
|
||||
Fragment {}
|
||||
@@ -137,9 +147,8 @@ pub static EXAMPLE: Component = |cx| {
|
||||
Fragment {
|
||||
"D"
|
||||
Fragment {
|
||||
"heavily nested fragments is an antipattern"
|
||||
"they cause Dioxus to do unnecessary work"
|
||||
"don't use them carelessly if you can help it"
|
||||
"E"
|
||||
"F"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,22 +167,29 @@ pub static EXAMPLE: Component = |cx| {
|
||||
Taller { a: "asd" }
|
||||
|
||||
// Can pass in props directly as an expression
|
||||
{{
|
||||
{
|
||||
let props = TallerProps {a: "hello", children: Default::default()};
|
||||
rsx!(Taller { ..props })
|
||||
}}
|
||||
}
|
||||
|
||||
// Spreading can also be overridden manually
|
||||
Taller {
|
||||
..TallerProps { a: "ballin!", children: Default::default() }
|
||||
..TallerProps { a: "ballin!", children: Default::default() },
|
||||
a: "not ballin!"
|
||||
}
|
||||
|
||||
// Can take children too!
|
||||
Taller { a: "asd", div {"hello world!"} }
|
||||
|
||||
// Components can be used with the `call` syntax
|
||||
// This component's props are defined *inline* with the `inline_props` macro
|
||||
with_inline(
|
||||
text: "using functionc all syntax"
|
||||
)
|
||||
|
||||
// helper functions
|
||||
{helper(&cx, "hello world!")}
|
||||
// Single values must be wrapped in braces or `Some` to satisfy `IntoIterator`
|
||||
[helper(&cx, "hello world!")]
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -187,6 +203,7 @@ mod baller {
|
||||
#[derive(Props, PartialEq)]
|
||||
pub struct BallerProps {}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
/// This component totally balls
|
||||
pub fn Baller(_: Scope<BallerProps>) -> Element {
|
||||
todo!()
|
||||
@@ -195,12 +212,20 @@ mod baller {
|
||||
|
||||
#[derive(Props)]
|
||||
pub struct TallerProps<'a> {
|
||||
/// Fields are documented and accessible in rsx!
|
||||
a: &'static str,
|
||||
children: Element<'a>,
|
||||
}
|
||||
|
||||
/// This component is taller than most :)
|
||||
pub fn Taller<'a>(_: Scope<'a, TallerProps<'a>>) -> Element {
|
||||
let b = true;
|
||||
todo!()
|
||||
/// Documention for this component is visible within the rsx macro
|
||||
#[allow(non_snake_case)]
|
||||
pub fn Taller<'a>(cx: Scope<'a, TallerProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
&cx.props.children
|
||||
})
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
fn with_inline<'a>(cx: Scope<'a>, text: &'a str) -> Element {
|
||||
rsx!(cx, p { "{text}" })
|
||||
}
|
||||
+38
-38
@@ -16,9 +16,9 @@ const STYLE: &str = "body {overflow:hidden;}";
|
||||
|
||||
pub static App: Component = |cx| {
|
||||
cx.render(rsx!(
|
||||
div { class: "overflow-hidden"
|
||||
div { class: "overflow-hidden",
|
||||
style { "{STYLE}" }
|
||||
link { href:"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel:"stylesheet" }
|
||||
link { href:"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css", rel:"stylesheet" }
|
||||
Header {}
|
||||
Entry {}
|
||||
Hero {}
|
||||
@@ -33,20 +33,20 @@ pub static App: Component = |cx| {
|
||||
pub static Header: Component = |cx| {
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
header { class: "text-gray-400 bg-gray-900 body-font"
|
||||
div { class: "container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center"
|
||||
a { class: "flex title-font font-medium items-center text-white mb-4 md:mb-0"
|
||||
header { class: "text-gray-400 bg-gray-900 body-font",
|
||||
div { class: "container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center",
|
||||
a { class: "flex title-font font-medium items-center text-white mb-4 md:mb-0",
|
||||
StacksIcon {}
|
||||
span { class: "ml-3 text-xl" "Hello Dioxus!"}
|
||||
span { class: "ml-3 text-xl", "Hello Dioxus!"}
|
||||
}
|
||||
nav { class: "md:ml-auto flex flex-wrap items-center text-base justify-center"
|
||||
a { class: "mr-5 hover:text-white" "First Link"}
|
||||
a { class: "mr-5 hover:text-white" "Second Link"}
|
||||
a { class: "mr-5 hover:text-white" "Third Link"}
|
||||
a { class: "mr-5 hover:text-white" "Fourth Link"}
|
||||
nav { class: "md:ml-auto flex flex-wrap items-center text-base justify-center",
|
||||
a { class: "mr-5 hover:text-white", "First Link"}
|
||||
a { class: "mr-5 hover:text-white", "Second Link"}
|
||||
a { class: "mr-5 hover:text-white", "Third Link"}
|
||||
a { class: "mr-5 hover:text-white", "Fourth Link"}
|
||||
}
|
||||
button {
|
||||
class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0"
|
||||
class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0",
|
||||
"Button"
|
||||
RightArrowIcon {}
|
||||
}
|
||||
@@ -59,34 +59,34 @@ pub static Header: Component = |cx| {
|
||||
pub static Hero: Component = |cx| {
|
||||
//
|
||||
cx.render(rsx! {
|
||||
section{ class: "text-gray-400 bg-gray-900 body-font"
|
||||
div { class: "container mx-auto flex px-5 py-24 md:flex-row flex-col items-center"
|
||||
div { class: "lg:flex-grow md:w-1/2 lg:pr-24 md:pr-16 flex flex-col md:items-start md:text-left mb-16 md:mb-0 items-center text-center"
|
||||
h1 { class: "title-font sm:text-4xl text-3xl mb-4 font-medium text-white"
|
||||
section{ class: "text-gray-400 bg-gray-900 body-font",
|
||||
div { class: "container mx-auto flex px-5 py-24 md:flex-row flex-col items-center",
|
||||
div { class: "lg:flex-grow md:w-1/2 lg:pr-24 md:pr-16 flex flex-col md:items-start md:text-left mb-16 md:mb-0 items-center text-center",
|
||||
h1 { class: "title-font sm:text-4xl text-3xl mb-4 font-medium text-white",
|
||||
br { class: "hidden lg:inline-block" }
|
||||
"Dioxus Sneak Peek"
|
||||
}
|
||||
p {
|
||||
class: "mb-8 leading-relaxed"
|
||||
class: "mb-8 leading-relaxed",
|
||||
|
||||
"Dioxus is a new UI framework that makes it easy and simple to write cross-platform apps using web
|
||||
technologies! It is functional, fast, and portable. Dioxus can run on the web, on the desktop, and
|
||||
on mobile and embedded platforms."
|
||||
|
||||
}
|
||||
div { class: "flex justify-center"
|
||||
div { class: "flex justify-center",
|
||||
button {
|
||||
class: "inline-flex text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg"
|
||||
class: "inline-flex text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg",
|
||||
"Learn more"
|
||||
}
|
||||
button {
|
||||
class: "ml-4 inline-flex text-gray-400 bg-gray-800 border-0 py-2 px-6 focus:outline-none hover:bg-gray-700 hover:text-white rounded text-lg"
|
||||
class: "ml-4 inline-flex text-gray-400 bg-gray-800 border-0 py-2 px-6 focus:outline-none hover:bg-gray-700 hover:text-white rounded text-lg",
|
||||
"Build an app"
|
||||
}
|
||||
}
|
||||
}
|
||||
div { class: "lg:max-w-lg lg:w-full md:w-1/2 w-5/6"
|
||||
img { class: "object-cover object-center rounded" alt: "hero" src: "https://i.imgur.com/oK6BLtw.png"
|
||||
div { class: "lg:max-w-lg lg:w-full md:w-1/2 w-5/6",
|
||||
img { class: "object-cover object-center rounded", alt: "hero", src: "https://i.imgur.com/oK6BLtw.png",
|
||||
referrerpolicy:"no-referrer"
|
||||
}
|
||||
}
|
||||
@@ -97,8 +97,8 @@ pub static Hero: Component = |cx| {
|
||||
pub static Entry: Component = |cx| {
|
||||
//
|
||||
cx.render(rsx! {
|
||||
section{ class: "text-gray-400 bg-gray-900 body-font"
|
||||
div { class: "container mx-auto flex px-5 py-24 md:flex-row flex-col items-center"
|
||||
section{ class: "text-gray-400 bg-gray-900 body-font",
|
||||
div { class: "container mx-auto flex px-5 py-24 md:flex-row flex-col items-center",
|
||||
textarea {
|
||||
|
||||
}
|
||||
@@ -111,13 +111,13 @@ pub static StacksIcon: Component = |cx| {
|
||||
cx.render(rsx!(
|
||||
svg {
|
||||
// xmlns: "http://www.w3.org/2000/svg"
|
||||
fill: "none"
|
||||
stroke: "currentColor"
|
||||
stroke_linecap: "round"
|
||||
stroke_linejoin: "round"
|
||||
stroke_width: "2"
|
||||
class: "w-10 h-10 text-white p-2 bg-indigo-500 rounded-full"
|
||||
view_box: "0 0 24 24"
|
||||
fill: "none",
|
||||
stroke: "currentColor",
|
||||
stroke_linecap: "round",
|
||||
stroke_linejoin: "round",
|
||||
stroke_width: "2",
|
||||
class: "w-10 h-10 text-white p-2 bg-indigo-500 rounded-full",
|
||||
view_box: "0 0 24 24",
|
||||
path { d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"}
|
||||
}
|
||||
))
|
||||
@@ -125,13 +125,13 @@ pub static StacksIcon: Component = |cx| {
|
||||
pub static RightArrowIcon: Component = |cx| {
|
||||
cx.render(rsx!(
|
||||
svg {
|
||||
fill: "none"
|
||||
stroke: "currentColor"
|
||||
stroke_linecap: "round"
|
||||
stroke_linejoin: "round"
|
||||
stroke_width: "2"
|
||||
class: "w-4 h-4 ml-1"
|
||||
view_box: "0 0 24 24"
|
||||
fill: "none",
|
||||
stroke: "currentColor",
|
||||
stroke_linecap: "round",
|
||||
stroke_linejoin: "round",
|
||||
stroke_width: "2",
|
||||
class: "w-4 h-4 ml-1",
|
||||
view_box: "0 0 24 24",
|
||||
path { d: "M5 12h14M12 5l7 7-7 7"}
|
||||
}
|
||||
))
|
||||
|
||||
+3
-2
@@ -15,8 +15,9 @@ fn app(cx: Scope) -> Element {
|
||||
use_future(&cx, || {
|
||||
for_async![count];
|
||||
async move {
|
||||
while let _ = tokio::time::sleep(Duration::from_millis(1000)).await {
|
||||
*count.modify() += 1;
|
||||
loop {
|
||||
tokio::time::sleep(Duration::from_millis(1000)).await;
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
+21
-18
@@ -29,7 +29,7 @@ const App: Component = |cx| {
|
||||
|
||||
let todolist = todos
|
||||
.iter()
|
||||
.filter(|(id, item)| match *filter {
|
||||
.filter(|(_id, item)| match *filter {
|
||||
FilterState::All => true,
|
||||
FilterState::Active => !item.checked,
|
||||
FilterState::Completed => item.checked,
|
||||
@@ -48,34 +48,37 @@ const App: Component = |cx| {
|
||||
_ => "items",
|
||||
};
|
||||
|
||||
rsx!(cx, div { id: "app"
|
||||
rsx!(cx, div { id: "app",
|
||||
style {"{STYLE}"}
|
||||
div {
|
||||
header { class: "header"
|
||||
header { class: "header",
|
||||
h1 {"todos"}
|
||||
input {
|
||||
class: "new-todo"
|
||||
placeholder: "What needs to be done?"
|
||||
value: "{draft}"
|
||||
oninput: move |evt| draft.set(evt.value.clone())
|
||||
class: "new-todo",
|
||||
placeholder: "What needs to be done?",
|
||||
value: "{draft}",
|
||||
oninput: move |evt| draft.set(evt.value.clone()),
|
||||
}
|
||||
}
|
||||
{todolist}
|
||||
{(!todos.is_empty()).then(|| rsx!(
|
||||
todolist,
|
||||
(!todos.is_empty()).then(|| rsx!(
|
||||
footer {
|
||||
span { strong {"{items_left}"} span {"{item_text} left"} }
|
||||
ul { class: "filters"
|
||||
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"
|
||||
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" }}
|
||||
p { "Created by ", a { href: "http://github.com/jkelleyrtp/", "jkelleyrtp" }}
|
||||
p { "Part of ", a { href: "http://todomvc.com", "TodoMVC" }}
|
||||
}
|
||||
})
|
||||
};
|
||||
@@ -93,13 +96,13 @@ pub fn TodoEntry(cx: Scope<TodoEntryProps>) -> Element {
|
||||
rsx!(cx, li {
|
||||
"{todo.id}"
|
||||
input {
|
||||
class: "toggle"
|
||||
r#type: "checkbox"
|
||||
class: "toggle",
|
||||
r#type: "checkbox",
|
||||
"{todo.checked}"
|
||||
}
|
||||
{is_editing.then(|| rsx!{
|
||||
input {
|
||||
value: "{contents}"
|
||||
value: "{contents}",
|
||||
oninput: move |evt| contents.set(evt.value.clone())
|
||||
}
|
||||
})}
|
||||
|
||||
+9
-18
@@ -13,28 +13,19 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
#[cfg(target_arch = "wasm32")]
|
||||
intern_strings();
|
||||
|
||||
dioxus::web::launch(App);
|
||||
dioxus::desktop::launch(App);
|
||||
}
|
||||
|
||||
static App: Component = |cx| {
|
||||
let mut rng = SmallRng::from_entropy();
|
||||
let rows = (0..1_000).map(|f| {
|
||||
let label = Label::new(&mut rng);
|
||||
rsx! {
|
||||
Row {
|
||||
row_id: f,
|
||||
label: label
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
cx.render(rsx! {
|
||||
table {
|
||||
tbody {
|
||||
{rows}
|
||||
(0..1_000).map(|f| {
|
||||
let label = Label::new(&mut rng);
|
||||
rsx! (Row { row_id: f, label: label })
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -50,12 +41,12 @@ fn Row(cx: Scope<RowProps>) -> Element {
|
||||
cx.render(rsx! {
|
||||
tr {
|
||||
td { class:"col-md-1", "{cx.props.row_id}" }
|
||||
td { class:"col-md-1", onclick: move |_| { /* run onselect */ }
|
||||
td { class:"col-md-1", onclick: move |_| { /* run onselect */ },
|
||||
a { class: "lbl", "{adj}" "{col}" "{noun}" }
|
||||
}
|
||||
td { class: "col-md-1"
|
||||
a { class: "remove", onclick: move |_| {/* remove */}
|
||||
span { class: "glyphicon glyphicon-remove remove" aria_hidden: "true" }
|
||||
td { class: "col-md-1",
|
||||
a { class: "remove", onclick: move |_| {/* remove */},
|
||||
span { class: "glyphicon glyphicon-remove remove", aria_hidden: "true" }
|
||||
}
|
||||
}
|
||||
td { class: "col-md-6" }
|
||||
|
||||
@@ -16,13 +16,13 @@ fn main() {
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
let count = use_state(&cx, || 0);
|
||||
let mut count = use_state(&cx, || 0);
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
h1 { "Hifive counter: {count}" }
|
||||
button { onclick: move |_| *count.modify() += 1, "Up high!" }
|
||||
button { onclick: move |_| *count.modify() -= 1, "Down low!" }
|
||||
button { onclick: move |_| count += 1, "Up high!" }
|
||||
button { onclick: move |_| count -= 1, "Down low!" }
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus::desktop::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
let contents = use_state(&cx, || String::from("<script>alert(123)</script>"));
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
"hello world!"
|
||||
|
||||
h1 {
|
||||
"{contents}"
|
||||
}
|
||||
h3 {
|
||||
[contents.as_str()]
|
||||
}
|
||||
|
||||
input {
|
||||
value: "{contents}",
|
||||
oninput: move |e| {
|
||||
contents.set(e.value.clone());
|
||||
eprintln!("asd");
|
||||
},
|
||||
"type": "text",
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user