Merge branch 'master' into add-file-data-drag-event
This commit is contained in:
commit
847801908f
575 files changed
+12880
-17751
No files matched your search
@@ -3,12 +3,13 @@ name = "dioxus-pwa-example"
|
||||
version = "0.1.0"
|
||||
authors = ["Antonio Curavalea <one.kyonblack@gmail.com>"]
|
||||
edition = "2021"
|
||||
publish = false
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
dioxus = { path = "../../packages/dioxus", version = "^0.3.0"}
|
||||
dioxus-web = { path = "../../packages/web", version = "^0.3.0"}
|
||||
dioxus = { path = "../../packages/dioxus", version = "*" }
|
||||
dioxus-web = { path = "../../packages/web", version = "*" }
|
||||
|
||||
log = "0.4.6"
|
||||
|
||||
|
||||
@@ -7,12 +7,13 @@ It is also very much usable as a template for your projects, if you're aiming to
|
||||
|
||||
## Try the example
|
||||
|
||||
Make sure you have Dioxus CLI installed (if you're unsure, run `cargo install dioxus-cli`).
|
||||
Make sure you have Dioxus CLI installed (if you're unsure, run `cargo install dioxus-cli --locked`).
|
||||
|
||||
You can run `dx serve` in this directory to start the web server locally, or run
|
||||
`dx build --release` to build the project so you can deploy it on a separate web-server.
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
├── Cargo.toml
|
||||
├── Dioxus.toml
|
||||
@@ -33,12 +34,12 @@ You can run `dx serve` in this directory to start the web server locally, or run
|
||||
|
||||
If you're just getting started with PWAs, here are some useful resources:
|
||||
|
||||
* [PWABuilder docs](https://docs.pwabuilder.com/#/)
|
||||
* [MDN article on PWAs](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps)
|
||||
- [PWABuilder docs](https://docs.pwabuilder.com/#/)
|
||||
- [MDN article on PWAs](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps)
|
||||
|
||||
For service worker scripting (in JavaScript):
|
||||
|
||||
* [Service worker guide from PWABuilder](https://docs.pwabuilder.com/#/home/sw-intro)
|
||||
* [Service worker examples, also from PWABuilder](https://github.com/pwa-builder/pwabuilder-serviceworkers)
|
||||
- [Service worker guide from PWABuilder](https://docs.pwabuilder.com/#/home/sw-intro)
|
||||
- [Service worker examples, also from PWABuilder](https://github.com/pwa-builder/pwabuilder-serviceworkers)
|
||||
|
||||
If you want to stay as close to 100% Rust as possible, you can try using [wasi-worker](https://github.com/dunnock/wasi-worker) to replace the JS service worker file. The JSON manifest will still be required though.
|
||||
+1
-7
@@ -1,17 +1,11 @@
|
||||
//! Example: README.md showcase
|
||||
//!
|
||||
//! The example from the README.md.
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_signals::{use_init_signal_rt, use_signal};
|
||||
use dioxus_signals::use_signal;
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch(app);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
use_init_signal_rt(cx);
|
||||
|
||||
let mut count = use_signal(cx, || 0);
|
||||
|
||||
use_future!(cx, || async move {
|
||||
|
||||
+9
-9
@@ -1,5 +1,4 @@
|
||||
//! Tiny CRM: A port of the Yew CRM example to Dioxus.
|
||||
#![allow(non_snake_case)]
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_router::prelude::*;
|
||||
|
||||
@@ -27,6 +26,7 @@ pub struct Client {
|
||||
|
||||
type ClientContext = Vec<Client>;
|
||||
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
use_shared_state_provider::<ClientContext>(cx, Default::default);
|
||||
|
||||
@@ -46,11 +46,11 @@ fn App(cx: Scope) -> Element {
|
||||
|
||||
h1 { "Dioxus CRM Example" }
|
||||
|
||||
Router {}
|
||||
Router::<Route> {}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn ClientList(cx: Scope) -> Element {
|
||||
let clients = use_shared_state::<ClientContext>(cx).unwrap();
|
||||
|
||||
@@ -58,12 +58,12 @@ fn ClientList(cx: Scope) -> Element {
|
||||
h2 { "List of Clients" }
|
||||
|
||||
Link {
|
||||
target: Route::ClientAdd {},
|
||||
to: Route::ClientAdd {},
|
||||
class: "pure-button pure-button-primary",
|
||||
"Add Client"
|
||||
}
|
||||
Link {
|
||||
target: Route::Settings {},
|
||||
to: Route::Settings {},
|
||||
class: "pure-button",
|
||||
"Settings"
|
||||
}
|
||||
@@ -80,7 +80,7 @@ fn ClientList(cx: Scope) -> Element {
|
||||
})
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn ClientAdd(cx: Scope) -> Element {
|
||||
let clients = use_shared_state::<ClientContext>(cx).unwrap();
|
||||
let first_name = use_state(cx, String::new);
|
||||
@@ -161,7 +161,7 @@ fn ClientAdd(cx: Scope) -> Element {
|
||||
"Save"
|
||||
}
|
||||
Link {
|
||||
target: Route::ClientList {},
|
||||
to: Route::ClientList {},
|
||||
class: "pure-button pure-button-primary red",
|
||||
"Cancel"
|
||||
}
|
||||
@@ -173,7 +173,7 @@ fn ClientAdd(cx: Scope) -> Element {
|
||||
})
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Settings(cx: Scope) -> Element {
|
||||
let clients = use_shared_state::<ClientContext>(cx).unwrap();
|
||||
|
||||
@@ -190,7 +190,7 @@ fn Settings(cx: Scope) -> Element {
|
||||
}
|
||||
|
||||
Link {
|
||||
target: Route::ClientList {},
|
||||
to: Route::ClientList {},
|
||||
class: "pure-button",
|
||||
"Go back"
|
||||
}
|
||||
|
||||
+6
-5
@@ -2,7 +2,7 @@ use dioxus::prelude::*;
|
||||
use std::collections::HashMap;
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch(|cx| render!(app_root {}));
|
||||
dioxus_desktop::launch(|cx| render!(AppRoot {}));
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, serde::Deserialize)]
|
||||
@@ -10,7 +10,8 @@ struct ListBreeds {
|
||||
message: HashMap<String, Vec<String>>,
|
||||
}
|
||||
|
||||
fn app_root(cx: Scope<'_>) -> Element {
|
||||
#[component]
|
||||
fn AppRoot(cx: Scope<'_>) -> Element {
|
||||
let breed = use_state(cx, || "deerhound".to_string());
|
||||
|
||||
let breeds = use_future!(cx, || async move {
|
||||
@@ -36,7 +37,7 @@ fn app_root(cx: Scope<'_>) -> Element {
|
||||
}
|
||||
}
|
||||
}
|
||||
div { flex: "50%", breed_pic { breed: breed.to_string() } }
|
||||
div { flex: "50%", BreedPic { breed: breed.to_string() } }
|
||||
}
|
||||
}
|
||||
}),
|
||||
@@ -49,8 +50,8 @@ struct DogApi {
|
||||
message: String,
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
fn breed_pic(cx: Scope, breed: String) -> Element {
|
||||
#[component]
|
||||
fn BreedPic(cx: Scope, breed: String) -> Element {
|
||||
let fut = use_future!(cx, |breed| async move {
|
||||
reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random"))
|
||||
.await
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch(app);
|
||||
dioxus_desktop::launch(App);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
let val = use_state(cx, || "0.0001");
|
||||
|
||||
let num = match val.parse::<f32>() {
|
||||
@@ -19,13 +20,13 @@ fn app(cx: Scope) -> Element {
|
||||
"Set an invalid number"
|
||||
}
|
||||
(0..5).map(|i| rsx! {
|
||||
demo_c { x: i }
|
||||
DemoC { x: i }
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
fn demo_c(cx: Scope, x: i32) -> Element {
|
||||
#[component]
|
||||
fn DemoC(cx: Scope, x: i32) -> Element {
|
||||
cx.render(rsx! {
|
||||
h1 {
|
||||
"asdasdasdasd {x}"
|
||||
|
||||
+28
-23
@@ -5,29 +5,34 @@ fn main() {
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
let eval = dioxus_desktop::use_eval(cx);
|
||||
let script = use_state(cx, String::new);
|
||||
let output = use_state(cx, String::new);
|
||||
let eval_provider = use_eval(cx);
|
||||
|
||||
cx.render(rsx! {
|
||||
div {
|
||||
p { "Output: {output}" }
|
||||
input {
|
||||
placeholder: "Enter an expression",
|
||||
value: "{script}",
|
||||
oninput: move |e| script.set(e.value.clone()),
|
||||
}
|
||||
button {
|
||||
onclick: move |_| {
|
||||
to_owned![script, eval, output];
|
||||
cx.spawn(async move {
|
||||
if let Ok(res) = eval(script.to_string()).await {
|
||||
output.set(res.to_string());
|
||||
}
|
||||
});
|
||||
},
|
||||
"Execute"
|
||||
}
|
||||
let future = use_future(cx, (), |_| {
|
||||
to_owned![eval_provider];
|
||||
async move {
|
||||
let eval = eval_provider(
|
||||
r#"
|
||||
dioxus.send("Hi from JS!");
|
||||
let msg = await dioxus.recv();
|
||||
console.log(msg);
|
||||
return "hello world";
|
||||
"#,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
eval.send("Hi from Rust!".into()).unwrap();
|
||||
let res = eval.recv().await.unwrap();
|
||||
println!("{:?}", eval.await);
|
||||
res
|
||||
}
|
||||
})
|
||||
});
|
||||
|
||||
match future.value() {
|
||||
Some(v) => cx.render(rsx!(
|
||||
p { "{v}" }
|
||||
)),
|
||||
_ => cx.render(rsx!(
|
||||
p { "hello" }
|
||||
)),
|
||||
}
|
||||
}
|
||||
+14
-15
@@ -1,5 +1,3 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_desktop::{tao::dpi::LogicalSize, Config, WindowBuilder};
|
||||
use dioxus_router::prelude::*;
|
||||
@@ -13,12 +11,13 @@ fn main() {
|
||||
.with_resizable(false),
|
||||
);
|
||||
|
||||
dioxus_desktop::launch_cfg(app, cfg)
|
||||
dioxus_desktop::launch_cfg(App, cfg)
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
render! {
|
||||
Router {}
|
||||
Router::<Route> {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,11 +35,11 @@ enum Route {
|
||||
Settings {},
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Footer(cx: Scope) -> Element {
|
||||
render! {
|
||||
div {
|
||||
Outlet { }
|
||||
Outlet::<Route> { }
|
||||
|
||||
p {
|
||||
"----"
|
||||
@@ -48,32 +47,32 @@ fn Footer(cx: Scope) -> Element {
|
||||
|
||||
nav {
|
||||
ul {
|
||||
li { Link { target: Route::Home {}, "Home" } }
|
||||
li { Link { target: Route::Games {}, "Games" } }
|
||||
li { Link { target: Route::Play {}, "Play" } }
|
||||
li { Link { target: Route::Settings {}, "Settings" } }
|
||||
li { Link { to: Route::Home {}, "Home" } }
|
||||
li { Link { to: Route::Games {}, "Games" } }
|
||||
li { Link { to: Route::Play {}, "Play" } }
|
||||
li { Link { to: Route::Settings {}, "Settings" } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Home(cx: Scope) -> Element {
|
||||
render!("Home")
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Games(cx: Scope) -> Element {
|
||||
render!("Games")
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Play(cx: Scope) -> Element {
|
||||
render!("Play")
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Settings(cx: Scope) -> Element {
|
||||
render!("Settings")
|
||||
}
|
||||
@@ -13,7 +13,8 @@ use dioxus::prelude::*;
|
||||
use dioxus_desktop::Config;
|
||||
|
||||
fn main() {
|
||||
let vdom = VirtualDom::new(app);
|
||||
let mut vdom = VirtualDom::new(app);
|
||||
let _ = vdom.rebuild();
|
||||
let content = dioxus_ssr::pre_render(&vdom);
|
||||
|
||||
dioxus_desktop::launch_cfg(app, Config::new().with_prerendered(content));
|
||||
|
||||
+11
-9
@@ -1,33 +1,35 @@
|
||||
//! Run with `cargo-expand` to see what each one expands to
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
//! Run with `cargo-expand` to see what each one expands to.
|
||||
//! This file is named `inlineprops.rs`, because there used to be a `#[inline_props]` macro to
|
||||
//! do this. However, it's now deprecated (and will likely be removed in a future major version),
|
||||
//! so please use `#[component]` instead!
|
||||
use dioxus::prelude::*;
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Thing1<T>(cx: Scope, _a: T) -> Element {
|
||||
cx.render(rsx! { "" })
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Thing2(cx: Scope, _a: u32) -> Element<'a> {
|
||||
cx.render(rsx! { "" })
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Thing3<'a, T>(cx: Scope<'a>, _a: &'a T) -> Element<'a> {
|
||||
cx.render(rsx! { "" })
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Thing4<'a>(cx: Scope<'a>, _a: &'a u32) -> Element<'a> {
|
||||
cx.render(rsx! { "" })
|
||||
}
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch(app);
|
||||
dioxus_desktop::launch(App);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
let state = use_state(cx, || 1);
|
||||
|
||||
cx.render(rsx! {
|
||||
|
||||
+10
-11
@@ -1,13 +1,12 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_router::prelude::*;
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch(app);
|
||||
dioxus_desktop::launch(App);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
cx.render(rsx! (
|
||||
div {
|
||||
p {
|
||||
@@ -23,7 +22,7 @@ fn app(cx: Scope) -> Element {
|
||||
}
|
||||
}
|
||||
div {
|
||||
Router {}
|
||||
Router::<Route> {}
|
||||
}
|
||||
))
|
||||
}
|
||||
@@ -38,24 +37,24 @@ enum Route {
|
||||
Settings {},
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Header(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Your app here" }
|
||||
ul {
|
||||
li { Link { target: Route::Home {}, "home" } }
|
||||
li { Link { target: Route::Settings {}, "settings" } }
|
||||
li { Link { to: Route::Home {}, "home" } }
|
||||
li { Link { to: Route::Settings {}, "settings" } }
|
||||
}
|
||||
Outlet {}
|
||||
Outlet::<Route> {}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Home(cx: Scope) -> Element {
|
||||
render!(h1 { "Home" })
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Settings(cx: Scope) -> Element {
|
||||
render!(h1 { "Settings" })
|
||||
}
|
||||
@@ -35,7 +35,6 @@ fn app(cx: Scope) -> Element {
|
||||
h1 { "Login" }
|
||||
form {
|
||||
onsubmit: onsubmit,
|
||||
prevent_default: "onsubmit", // Prevent the default behavior of <form> to post
|
||||
input { r#type: "text", id: "username", name: "username" }
|
||||
label { "Username" }
|
||||
br {}
|
||||
|
||||
@@ -72,7 +72,7 @@ fn app(cx: Scope) -> Element {
|
||||
onclick: move|_| {
|
||||
println!("Clicked!");
|
||||
items.push(items.len());
|
||||
cx.needs_update_any(ScopeId(0));
|
||||
cx.needs_update_any(ScopeId::ROOT);
|
||||
println!("Requested update");
|
||||
},
|
||||
"Add item"
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "query_segments_demo"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
dioxus = { path = "../../packages/dioxus", version = "*" }
|
||||
dioxus-router = { path = "../../packages/router", version = "*" }
|
||||
dioxus-web = { path = "../../packages/web", version = "*" }
|
||||
form_urlencoded = "1.2.0"
|
||||
@@ -0,0 +1,74 @@
|
||||
#![allow(unused)]
|
||||
//! Example: Url query segments usage
|
||||
//! ------------------------------------
|
||||
//!
|
||||
//! This example shows how to access and use multiple query segments present in an url on the web.
|
||||
//!
|
||||
//! Run `dx serve` and navigate to `http://localhost:8080/blog?name=John&surname=Doe`
|
||||
use std::fmt::Display;
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_router::prelude::*;
|
||||
|
||||
// ANCHOR: route
|
||||
#[derive(Routable, Clone)]
|
||||
#[rustfmt::skip]
|
||||
enum Route {
|
||||
// segments that start with ?: are query segments
|
||||
#[route("/blog?:query_params")]
|
||||
BlogPost {
|
||||
// You must include query segments in child variants
|
||||
query_params: BlogQuerySegments,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
struct BlogQuerySegments {
|
||||
name: String,
|
||||
surname: String,
|
||||
}
|
||||
|
||||
/// The display impl needs to display the query in a way that can be parsed:
|
||||
impl Display for BlogQuerySegments {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "name={}&surname={}", self.name, self.surname)
|
||||
}
|
||||
}
|
||||
|
||||
/// The query segment is anything that implements https://docs.rs/dioxus-router/latest/dioxus_router/routable/trait.FromQuery.html. You can implement that trait for a struct if you want to parse multiple query parameters.
|
||||
impl FromQuery for BlogQuerySegments {
|
||||
fn from_query(query: &str) -> Self {
|
||||
let mut name = None;
|
||||
let mut surname = None;
|
||||
let pairs = form_urlencoded::parse(query.as_bytes());
|
||||
pairs.for_each(|(key, value)| {
|
||||
if key == "name" {
|
||||
name = Some(value.clone().into());
|
||||
}
|
||||
if key == "surname" {
|
||||
surname = Some(value.clone().into());
|
||||
}
|
||||
});
|
||||
Self {
|
||||
name: name.unwrap(),
|
||||
surname: surname.unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn BlogPost(cx: Scope, query_params: BlogQuerySegments) -> Element {
|
||||
render! {
|
||||
div{"This is your blogpost with a query segment:"}
|
||||
div{format!("{:?}", query_params)}
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
render! { Router::<Route>{} }
|
||||
}
|
||||
|
||||
fn main() {
|
||||
dioxus_web::launch(App);
|
||||
}
|
||||
+14
-15
@@ -1,5 +1,3 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_router::prelude::*;
|
||||
|
||||
@@ -37,54 +35,55 @@ enum Route {
|
||||
}
|
||||
// ANCHOR_END: router
|
||||
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
render! {
|
||||
Router {}
|
||||
Router::<Route> {}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn NavBar(cx: Scope) -> Element {
|
||||
render! {
|
||||
nav {
|
||||
ul {
|
||||
li { Link { target: Route::Home {}, "Home" } }
|
||||
li { Link { target: Route::BlogList {}, "Blog" } }
|
||||
li { Link { to: Route::Home {}, "Home" } }
|
||||
li { Link { to: Route::BlogList {}, "Blog" } }
|
||||
}
|
||||
}
|
||||
Outlet {}
|
||||
Outlet::<Route> {}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Home(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Welcome to the Dioxus Blog!" }
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Blog(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Blog" }
|
||||
Outlet {}
|
||||
Outlet::<Route> {}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn BlogList(cx: Scope) -> Element {
|
||||
render! {
|
||||
h2 { "Choose a post" }
|
||||
ul {
|
||||
li {
|
||||
Link {
|
||||
target: Route::BlogPost { name: "Blog post 1".into() },
|
||||
to: Route::BlogPost { name: "Blog post 1".into() },
|
||||
"Read the first blog post"
|
||||
}
|
||||
}
|
||||
li {
|
||||
Link {
|
||||
target: Route::BlogPost { name: "Blog post 2".into() },
|
||||
to: Route::BlogPost { name: "Blog post 2".into() },
|
||||
"Read the second blog post"
|
||||
}
|
||||
}
|
||||
@@ -92,14 +91,14 @@ fn BlogList(cx: Scope) -> Element {
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn BlogPost(cx: Scope, name: String) -> Element {
|
||||
render! {
|
||||
h2 { "Blog Post: {name}"}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn PageNotFound(cx: Scope, route: Vec<String>) -> Element {
|
||||
render! {
|
||||
h1 { "Page not found" }
|
||||
|
||||
+17
-10
@@ -1,4 +1,3 @@
|
||||
#![allow(non_snake_case)]
|
||||
//! A tour of the rsx! macro
|
||||
//! ------------------------
|
||||
//!
|
||||
@@ -40,7 +39,7 @@
|
||||
//! - Allow top-level fragments
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch(app);
|
||||
dioxus_desktop::launch(App);
|
||||
}
|
||||
|
||||
use core::{fmt, str::FromStr};
|
||||
@@ -49,7 +48,8 @@ use std::fmt::Display;
|
||||
use baller::Baller;
|
||||
use dioxus::prelude::*;
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
let formatting = "formatting!";
|
||||
let formatting_tuple = ("a", "b");
|
||||
let lazy_fmt = format_args!("lazily formatted text");
|
||||
@@ -217,12 +217,16 @@ fn format_dollars(dollars: u32, cents: u32) -> String {
|
||||
format!("${dollars}.{cents:02}")
|
||||
}
|
||||
|
||||
fn helper<'a>(cx: &'a ScopeState, text: &str) -> Element<'a> {
|
||||
fn helper<'a>(cx: &'a ScopeState, text: &'a str) -> Element<'a> {
|
||||
cx.render(rsx! {
|
||||
p { "{text}" }
|
||||
})
|
||||
}
|
||||
|
||||
// no_case_check disables PascalCase checking if you *really* want a snake_case component.
|
||||
// This will likely be deprecated/removed in a future update that will introduce a more polished linting system,
|
||||
// something like Clippy.
|
||||
#[component(no_case_check)]
|
||||
fn lowercase_helper(cx: Scope) -> Element {
|
||||
cx.render(rsx! {
|
||||
"asd"
|
||||
@@ -234,12 +238,16 @@ mod baller {
|
||||
#[derive(Props, PartialEq, Eq)]
|
||||
pub struct BallerProps {}
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[component]
|
||||
/// This component totally balls
|
||||
pub fn Baller(_: Scope<BallerProps>) -> Element {
|
||||
pub fn Baller(_cx: Scope<BallerProps>) -> Element {
|
||||
todo!()
|
||||
}
|
||||
|
||||
// no_case_check disables PascalCase checking if you *really* want a snake_case component.
|
||||
// This will likely be deprecated/removed in a future update that will introduce a more polished linting system,
|
||||
// something like Clippy.
|
||||
#[component(no_case_check)]
|
||||
pub fn lowercase_component(cx: Scope) -> Element {
|
||||
cx.render(rsx! { "look ma, no uppercase" })
|
||||
}
|
||||
@@ -253,7 +261,7 @@ pub struct TallerProps<'a> {
|
||||
}
|
||||
|
||||
/// Documention for this component is visible within the rsx macro
|
||||
#[allow(non_snake_case)]
|
||||
#[component]
|
||||
pub fn Taller<'a>(cx: Scope<'a, TallerProps<'a>>) -> Element {
|
||||
cx.render(rsx! {
|
||||
&cx.props.children
|
||||
@@ -275,15 +283,14 @@ where
|
||||
todo!()
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn WithInline<'a>(cx: Scope<'a>, text: &'a str) -> Element {
|
||||
cx.render(rsx! {
|
||||
p { "{text}" }
|
||||
})
|
||||
}
|
||||
|
||||
// generic component with inline_props too
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Label<T>(cx: Scope, text: T) -> Element
|
||||
where
|
||||
T: Display,
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
use dioxus::prelude::*;
|
||||
@@ -27,6 +25,7 @@ impl CoolData {
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
#[rustfmt::skip]
|
||||
pub fn App(cx: Scope) -> Element {
|
||||
use_shared_state_provider(cx, || CoolData::new(HashMap::from([
|
||||
@@ -50,7 +49,7 @@ pub fn App(cx: Scope) -> Element {
|
||||
)
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn DataEditor(cx: Scope, id: usize) -> Element {
|
||||
let cool_data = use_shared_state::<CoolData>(cx).unwrap().read();
|
||||
|
||||
@@ -61,7 +60,7 @@ fn DataEditor(cx: Scope, id: usize) -> Element {
|
||||
})
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn DataView(cx: Scope, id: usize) -> Element {
|
||||
let cool_data = use_shared_state::<CoolData>(cx).unwrap();
|
||||
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@ fn app(cx: Scope) -> Element {
|
||||
button { onclick: move |_| count += 1, "Up high!" }
|
||||
button { onclick: move |_| count -= 1, "Down low!" }
|
||||
|
||||
if count() > 5 {
|
||||
if count.value() > 5 {
|
||||
rsx!{ h2 { "High five!" } }
|
||||
}
|
||||
})
|
||||
|
||||
+16
-15
@@ -9,12 +9,13 @@ fn main() {
|
||||
.with_module_level("dioxus", log::LevelFilter::Trace)
|
||||
.init()
|
||||
.unwrap();
|
||||
dioxus_desktop::launch(app);
|
||||
dioxus_desktop::launch(App);
|
||||
}
|
||||
|
||||
fn app(cx: Scope) -> Element {
|
||||
#[component]
|
||||
fn App(cx: Scope) -> Element {
|
||||
render! {
|
||||
Router {}
|
||||
Router::<Route> {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,46 +37,46 @@ enum Route {
|
||||
Oranges {},
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn NavBar(cx: Scope) -> Element {
|
||||
render! {
|
||||
h1 { "Your app here" }
|
||||
ul {
|
||||
li { Link { target: Route::Home {}, "home" } }
|
||||
li { Link { target: Route::BlogList {}, "blog" } }
|
||||
li { Link { target: Route::BlogPost { post: "tim".into() }, "tims' blog" } }
|
||||
li { Link { target: Route::BlogPost { post: "bill".into() }, "bills' blog" } }
|
||||
li { Link { target: Route::BlogPost { post: "james".into() }, "james amazing' blog" } }
|
||||
li { Link { to: Route::Home {}, "home" } }
|
||||
li { Link { to: Route::BlogList {}, "blog" } }
|
||||
li { Link { to: Route::BlogPost { post: "tim".into() }, "tims' blog" } }
|
||||
li { Link { to: Route::BlogPost { post: "bill".into() }, "bills' blog" } }
|
||||
li { Link { to: Route::BlogPost { post: "james".into() }, "james amazing' blog" } }
|
||||
}
|
||||
Outlet {}
|
||||
Outlet::<Route> {}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Home(cx: Scope) -> Element {
|
||||
log::debug!("rendering home {:?}", cx.scope_id());
|
||||
render! { h1 { "Home" } }
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn BlogList(cx: Scope) -> Element {
|
||||
log::debug!("rendering blog list {:?}", cx.scope_id());
|
||||
render! { div { "Blog List" } }
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn BlogPost(cx: Scope, post: String) -> Element {
|
||||
log::debug!("rendering blog post {}", post);
|
||||
|
||||
render! {
|
||||
div {
|
||||
h3 { "blog post: {post}" }
|
||||
Link { target: Route::BlogList {}, "back to blog list" }
|
||||
Link { to: Route::BlogList {}, "back to blog list" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline_props]
|
||||
#[component]
|
||||
fn Oranges(cx: Scope) -> Element {
|
||||
render!("Oranges are not apples!")
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
#![allow(non_snake_case)]
|
||||
use dioxus::prelude::*;
|
||||
use dioxus_router::prelude::*;
|
||||
|
||||
#[derive(Routable, Clone, PartialEq)]
|
||||
enum Route {
|
||||
#[layout(Nav)]
|
||||
#[route("/")]
|
||||
Homepage {},
|
||||
|
||||
#[route("/blog/:id")]
|
||||
Blog { id: String },
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Homepage(cx: Scope) -> Element {
|
||||
render! { h1 { "Welcome home" } }
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Blog(cx: Scope, id: String) -> Element {
|
||||
render! {
|
||||
h1 { "How to make: " }
|
||||
p { "{id}" }
|
||||
}
|
||||
}
|
||||
|
||||
#[component]
|
||||
fn Nav(cx: Scope) -> Element {
|
||||
render! {
|
||||
nav {
|
||||
li { Link { to: Route::Homepage { }, "Go home" } }
|
||||
li { Link { to: Route::Blog { id: "Brownies".to_string() }, "Learn Brownies" } }
|
||||
li { Link { to: Route::Blog { id: "Cookies".to_string() }, "Learn Cookies" } }
|
||||
}
|
||||
div { Outlet::<Route> {} }
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
dioxus_desktop::launch(|cx| render!(Router::<Route> {}));
|
||||
}
|
||||
@@ -10,7 +10,7 @@
|
||||
//! will cause it to fetch a random dog image from the Dog API. Since the data
|
||||
//! is not ready immediately, we render some loading text.
|
||||
//!
|
||||
//! We can achieve the majoirty of suspense functionality by composing "suspenseful"
|
||||
//! We can achieve the majority of suspense functionality by composing "suspenseful"
|
||||
//! primitives in our own custom components.
|
||||
|
||||
use dioxus::prelude::*;
|
||||
|
||||
@@ -30,7 +30,7 @@ watch_path = ["src", "public"]
|
||||
[web.resource]
|
||||
|
||||
# CSS style file
|
||||
style = ["tailwind.css"]
|
||||
style = ["/tailwind.css"]
|
||||
|
||||
# Javascript code file
|
||||
script = []
|
||||
|
||||
@@ -81,7 +81,7 @@ watch_path = ["src", "public"]
|
||||
[web.resource]
|
||||
|
||||
# CSS style file
|
||||
style = ["tailwind.css"]
|
||||
style = ["/tailwind.css"]
|
||||
|
||||
# Javascript code file
|
||||
script = []
|
||||
|
||||
Reference in new issue
Block a user