Renderers are now packages, not features. (#387)
* feat: use synchronous router design * feat: function to get router out of dom * chore: restructure workspace to use renderers as packages, not features
This commit is contained in:
parent
c97ca7dff6
commit
d9546d9504
|
@ -40,4 +40,4 @@ jobs:
|
||||||
- uses: actions-rs/cargo@v1
|
- uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: test
|
command: test
|
||||||
args: --features "desktop, ssr, router"
|
args: --all --tests
|
||||||
|
|
|
@ -43,6 +43,7 @@ jobs:
|
||||||
- uses: actions-rs/cargo@v1
|
- uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
command: check
|
command: check
|
||||||
|
args: --all --examples --tests
|
||||||
|
|
||||||
test:
|
test:
|
||||||
if: github.event.pull_request.draft == false
|
if: github.event.pull_request.draft == false
|
||||||
|
|
|
@ -71,6 +71,6 @@ jobs:
|
||||||
rustc -Vv
|
rustc -Vv
|
||||||
cargo -V
|
cargo -V
|
||||||
set RUST_BACKTRACE=1
|
set RUST_BACKTRACE=1
|
||||||
cargo build --features "desktop, ssr, router"
|
cargo build --all --tests --examples
|
||||||
cargo test --features "desktop, ssr, router"
|
cargo test --all --tests
|
||||||
shell: cmd
|
shell: cmd
|
||||||
|
|
93
Cargo.toml
93
Cargo.toml
|
@ -1,61 +1,10 @@
|
||||||
[package]
|
|
||||||
name = "dioxus"
|
|
||||||
version = "0.2.4"
|
|
||||||
authors = ["Jonathan Kelley"]
|
|
||||||
edition = "2021"
|
|
||||||
description = "Core functionality for Dioxus - a concurrent renderer-agnostic Virtual DOM for interactive user experiences"
|
|
||||||
license = "MIT OR Apache-2.0"
|
|
||||||
repository = "https://github.com/DioxusLabs/dioxus/"
|
|
||||||
homepage = "https://dioxuslabs.com"
|
|
||||||
documentation = "https://dioxuslabs.com"
|
|
||||||
keywords = ["dom", "ui", "gui", "react", "wasm"]
|
|
||||||
rust-version = "1.60.0"
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
dioxus-core = { path = "./packages/core", version = "^0.2.1" }
|
|
||||||
dioxus-html = { path = "./packages/html", version = "^0.2.1", optional = true }
|
|
||||||
dioxus-core-macro = { path = "./packages/core-macro", version = "^0.2.1", optional = true }
|
|
||||||
dioxus-hooks = { path = "./packages/hooks", version = "^0.2.1", optional = true }
|
|
||||||
fermi = { path = "./packages/fermi", version = "^0.2.1", optional = true }
|
|
||||||
|
|
||||||
dioxus-web = { path = "./packages/web", version = "^0.2.1", optional = true }
|
|
||||||
dioxus-desktop = { path = "./packages/desktop", version = "^0.2.3", optional = true }
|
|
||||||
dioxus-ssr = { path = "./packages/ssr", version = "^0.2.1", optional = true }
|
|
||||||
|
|
||||||
dioxus-router = { path = "./packages/router", version = "^0.2.3", optional = true }
|
|
||||||
dioxus-interpreter-js = { path = "./packages/interpreter", version = "^0.2.1", optional = true }
|
|
||||||
dioxus-tui = { path = "./packages/tui", version = "^0.2.2", optional = true }
|
|
||||||
|
|
||||||
dioxus-rsx = { path = "./packages/rsx", optional = true }
|
|
||||||
dioxus-rsx-interpreter = { path = "./packages/rsx_interpreter", optional = true }
|
|
||||||
dioxus-liveview = { path = "./packages/liveview", version = "^0.1.0", optional = true }
|
|
||||||
|
|
||||||
dioxus-native-core = { path = "./packages/native-core", version = "^0.2.0", optional = true }
|
|
||||||
dioxus-native-core-macro = { path = "./packages/native-core-macro", version = "^0.2.0", optional = true }
|
|
||||||
|
|
||||||
# dioxus-mobile = { path = "./packages/mobile", version = "^0.2.0", optional = true }
|
|
||||||
# dioxus-rsx = { path = "./packages/rsx", optional = true }
|
|
||||||
# macro = ["dioxus-core-macro", "dioxus-rsx"]
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["macro", "hooks", "html"]
|
|
||||||
|
|
||||||
macro = ["dioxus-core-macro", "dioxus-rsx"]
|
|
||||||
hooks = ["dioxus-hooks"]
|
|
||||||
html = ["dioxus-html"]
|
|
||||||
ssr = ["dioxus-ssr"]
|
|
||||||
web = ["dioxus-web", "dioxus-router?/web"]
|
|
||||||
desktop = ["dioxus-desktop"]
|
|
||||||
router = ["dioxus-router"]
|
|
||||||
tui = ["dioxus-tui"]
|
|
||||||
liveview = ["dioxus-liveview"]
|
|
||||||
hot-reload = ["dioxus-core-macro/hot-reload", "dioxus-rsx-interpreter", "dioxus-desktop?/hot-reload", "dioxus-web?/hot-reload", "dioxus-router?/hot-reload"]
|
|
||||||
native-core = ["dioxus-native-core", "dioxus-native-core-macro"]
|
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
|
"packages/dioxus",
|
||||||
"packages/core",
|
"packages/core",
|
||||||
"packages/core-macro",
|
"packages/core-macro",
|
||||||
|
"packages/router",
|
||||||
"packages/html",
|
"packages/html",
|
||||||
"packages/hooks",
|
"packages/hooks",
|
||||||
"packages/web",
|
"packages/web",
|
||||||
|
@ -71,11 +20,32 @@ members = [
|
||||||
"packages/rsx_interpreter",
|
"packages/rsx_interpreter",
|
||||||
"packages/native-core",
|
"packages/native-core",
|
||||||
"packages/native-core-macro",
|
"packages/native-core-macro",
|
||||||
"packages/rsx-prelude",
|
|
||||||
"docs/guide",
|
"docs/guide",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
# This is a "virtual package"
|
||||||
|
# It is not meant to be published, but is used so "cargo run --example XYZ" works properly
|
||||||
|
[package]
|
||||||
|
name = "dioxus-examples"
|
||||||
|
version = "0.0.0"
|
||||||
|
authors = ["Jonathan Kelley"]
|
||||||
|
edition = "2021"
|
||||||
|
description = "Top level crate for the Dioxus repository"
|
||||||
|
license = "MIT OR Apache-2.0"
|
||||||
|
repository = "https://github.com/DioxusLabs/dioxus/"
|
||||||
|
homepage = "https://dioxuslabs.com"
|
||||||
|
documentation = "https://dioxuslabs.com"
|
||||||
|
keywords = ["dom", "ui", "gui", "react", "wasm"]
|
||||||
|
rust-version = "1.60.0"
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
dioxus = { path = "./packages/dioxus" }
|
||||||
|
dioxus-desktop = { path = "./packages/desktop" }
|
||||||
|
dioxus-ssr = { path = "./packages/ssr" }
|
||||||
|
dioxus-router = { path = "./packages/router" }
|
||||||
|
fermi = { path = "./packages/fermi" }
|
||||||
futures-util = "0.3.21"
|
futures-util = "0.3.21"
|
||||||
log = "0.4.14"
|
log = "0.4.14"
|
||||||
num-format = "0.4.0"
|
num-format = "0.4.0"
|
||||||
|
@ -87,21 +57,6 @@ serde_json = "1.0.79"
|
||||||
rand = { version = "0.8.4", features = ["small_rng"] }
|
rand = { version = "0.8.4", features = ["small_rng"] }
|
||||||
tokio = { version = "1.16.1", features = ["full"] }
|
tokio = { version = "1.16.1", features = ["full"] }
|
||||||
reqwest = { version = "0.11.9", features = ["json"] }
|
reqwest = { version = "0.11.9", features = ["json"] }
|
||||||
dioxus = { path = ".", features = ["desktop", "ssr", "router", "fermi", "tui", "hot-reload"] }
|
|
||||||
fern = { version = "0.6.0", features = ["colored"] }
|
fern = { version = "0.6.0", features = ["colored"] }
|
||||||
criterion = "0.3.5"
|
|
||||||
thiserror = "1.0.30"
|
thiserror = "1.0.30"
|
||||||
env_logger = "0.9.0"
|
env_logger = "0.9.0"
|
||||||
|
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "create"
|
|
||||||
harness = false
|
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "jsframework"
|
|
||||||
harness = false
|
|
||||||
|
|
||||||
[[bench]]
|
|
||||||
name = "tui_update"
|
|
||||||
harness = false
|
|
||||||
|
|
|
@ -6,7 +6,16 @@ description = "Dioxus guide, including testable examples"
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
dioxus = { path = "../..", features = ["desktop", "web", "ssr", "router", "fermi", "tui"] }
|
dioxus = { path = "../../packages/dioxus" }
|
||||||
|
dioxus-desktop = { path = "../../packages/desktop" }
|
||||||
|
dioxus-web = { path = "../../packages/web" }
|
||||||
|
dioxus-ssr = { path = "../../packages/ssr" }
|
||||||
|
dioxus-router = { path = "../../packages/router" }
|
||||||
|
dioxus-tui = { path = "../../packages/tui" }
|
||||||
|
fermi = { path = "../../packages/fermi" }
|
||||||
|
|
||||||
|
|
||||||
|
# dioxus = { path = "../../packages/dioxus", features = ["desktop", "web", "ssr", "router", "fermi", "tui"] }
|
||||||
serde = { version = "1.0.138", features=["derive"] }
|
serde = { version = "1.0.138", features=["derive"] }
|
||||||
reqwest = { version = "0.11.11", features = ["json"] }
|
reqwest = { version = "0.11.11", features = ["json"] }
|
||||||
tokio = { version = "1.19.2" , features=[]}
|
tokio = { version = "1.19.2" , features=[]}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: App
|
// ANCHOR: App
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: App
|
// ANCHOR: App
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: App
|
// ANCHOR: App
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn App(cx: Scope) -> Element {
|
pub fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use dioxus::events::MouseEvent;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: component
|
// ANCHOR: component
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::tui::launch(App);
|
dioxus_tui::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -3,16 +3,16 @@
|
||||||
|
|
||||||
use dioxus::events::{KeyCode, KeyboardEvent};
|
use dioxus::events::{KeyCode, KeyboardEvent};
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus::tui::TuiContext;
|
use dioxus_tui::TuiContext;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::tui::launch_cfg(
|
dioxus_tui::launch_cfg(
|
||||||
App,
|
App,
|
||||||
dioxus::tui::Config::new()
|
dioxus_tui::Config::new()
|
||||||
.without_ctrl_c_quit()
|
.without_ctrl_c_quit()
|
||||||
// Some older terminals only support 16 colors or ANSI colors
|
// Some older terminals only support 16 colors or ANSI colors
|
||||||
// If your terminal is one of these, change this to BaseColors or ANSI
|
// If your terminal is one of these, change this to BaseColors or ANSI
|
||||||
.with_rendering_mode(dioxus::tui::RenderingMode::Rgb),
|
.with_rendering_mode(dioxus_tui::RenderingMode::Rgb),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::web::launch(App);
|
dioxus_web::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -4,7 +4,7 @@ use dioxus::prelude::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: component
|
// ANCHOR: component
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: component
|
// ANCHOR: component
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: component
|
// ANCHOR: component
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: component
|
// ANCHOR: component
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: component
|
// ANCHOR: component
|
||||||
|
|
|
@ -5,7 +5,7 @@ use dioxus::events::FormEvent;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(MemeEditor);
|
dioxus_desktop::launch(MemeEditor);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: meme_editor
|
// ANCHOR: meme_editor
|
||||||
|
|
|
@ -5,7 +5,7 @@ use dioxus::events::FormEvent;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ANCHOR: DarkMode_struct
|
// ANCHOR: DarkMode_struct
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Clone)]
|
#[derive(PartialEq, Clone)]
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn App(cx: Scope) -> Element {
|
pub fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug)]
|
#[derive(serde::Deserialize, Debug)]
|
||||||
|
|
|
@ -33,7 +33,7 @@ let name = "jane";
|
||||||
let pending = false;
|
let pending = false;
|
||||||
let count = 10;
|
let count = 10;
|
||||||
|
|
||||||
dioxus::ssr::render_lazy(html! {
|
dioxus_ssr::render_lazy(html! {
|
||||||
<div>
|
<div>
|
||||||
<p> "Hello, {name}!" </p>
|
<p> "Hello, {name}!" </p>
|
||||||
<p> "Status: {pending}!" </p>
|
<p> "Status: {pending}!" </p>
|
||||||
|
@ -51,7 +51,7 @@ When helpful, the Dioxus VSCode extension provides a way of converting a selecti
|
||||||
It's also a bit easier on the eyes than HTML.
|
It's also a bit easier on the eyes than HTML.
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
dioxus::ssr::render_lazy(rsx! {
|
dioxus_ssr::render_lazy(rsx! {
|
||||||
div {
|
div {
|
||||||
p {"Hello, {name}!"}
|
p {"Hello, {name}!"}
|
||||||
p {"Status: {pending}!"}
|
p {"Status: {pending}!"}
|
||||||
|
|
|
@ -159,7 +159,7 @@ force_render(ScopeId(0));
|
||||||
|
|
||||||
In our guides, we frequently use the phrase "re-render" to describe updates to our app. You'll often hear this paired with "preventing unnecessary re-renders." But what exactly does this mean?
|
In our guides, we frequently use the phrase "re-render" to describe updates to our app. You'll often hear this paired with "preventing unnecessary re-renders." But what exactly does this mean?
|
||||||
|
|
||||||
When we call `dioxus::desktop::launch`, Dioxus will create a new `Scope` object and call the component we gave it. Our `rsx!` calls will create new nodes which we return back to the VirtualDom. Dioxus will then look through these nodes for child components, call their functions, and so on until every component has been "rendered." We consider these nodes "rendered" because they were created because of our explicit actions.
|
When we call `dioxus_desktop::launch`, Dioxus will create a new `Scope` object and call the component we gave it. Our `rsx!` calls will create new nodes which we return back to the VirtualDom. Dioxus will then look through these nodes for child components, call their functions, and so on until every component has been "rendered." We consider these nodes "rendered" because they were created because of our explicit actions.
|
||||||
|
|
||||||
The tree of UI that dioxus creates will roughly look like the tree of components presented earlier:
|
The tree of UI that dioxus creates will roughly look like the tree of components presented earlier:
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ Instead of passing a closure, you can also pass a string to event handlers – t
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -16,7 +16,7 @@ For the simplest of apps, all of your state can enter the app from the root prop
|
||||||
```rust
|
```rust
|
||||||
let all_content = get_all_content().await;
|
let all_content = get_all_content().await;
|
||||||
|
|
||||||
let output = dioxus::ssr::render_lazy(rsx!{
|
let output = dioxus_ssr::render_lazy(rsx!{
|
||||||
div {
|
div {
|
||||||
RenderContent { content: all_content }
|
RenderContent { content: all_content }
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ cargo install --git https://github.com/BrainiumLLC/cargo-mobile
|
||||||
And then initialize your app for the right platform. Use the `winit` template for now. Right now, there's no "Dioxus" template in cargo-mobile.
|
And then initialize your app for the right platform. Use the `winit` template for now. Right now, there's no "Dioxus" template in cargo-mobile.
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
cargo mobile init
|
cargo mobile init
|
||||||
```
|
```
|
||||||
|
|
||||||
We're going to completely clear out the `dependencies` it generates for us, swapping out `winit` with `dioxus-mobile`.
|
We're going to completely clear out the `dependencies` it generates for us, swapping out `winit` with `dioxus-mobile`.
|
||||||
|
@ -61,7 +61,7 @@ Edit your `lib.rs`:
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::mobile::launch(app);
|
dioxus_mobile::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -21,10 +21,10 @@ If you just want to render `rsx!` or a VirtualDom to HTML, check out the API doc
|
||||||
// We can render VirtualDoms
|
// We can render VirtualDoms
|
||||||
let mut vdom = VirtualDom::new(app);
|
let mut vdom = VirtualDom::new(app);
|
||||||
let _ = vdom.rebuild();
|
let _ = vdom.rebuild();
|
||||||
println!("{}", dioxus::ssr::render_vdom(&vdom));
|
println!("{}", dioxus_ssr::render_vdom(&vdom));
|
||||||
|
|
||||||
// Or we can render rsx! calls directly
|
// Or we can render rsx! calls directly
|
||||||
println!( "{}", dioxus::ssr::render_lazy(rsx! { h1 { "Hello, world!" } } );
|
println!( "{}", dioxus_ssr::render_lazy(rsx! { h1 { "Hello, world!" } } );
|
||||||
```
|
```
|
||||||
|
|
||||||
However, for this guide, we're going to show how to use Dioxus SSR with `Axum`.
|
However, for this guide, we're going to show how to use Dioxus SSR with `Axum`.
|
||||||
|
@ -84,7 +84,7 @@ And then add our endpoint. We can either render `rsx!` directly:
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
async fn app_endpoint() -> Html<String> {
|
async fn app_endpoint() -> Html<String> {
|
||||||
Html(dioxus::ssr::render_lazy(rsx! {
|
Html(dioxus_ssr::render_lazy(rsx! {
|
||||||
h1 { "hello world!" }
|
h1 { "hello world!" }
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
@ -100,7 +100,7 @@ async fn app_endpoint() -> Html<String> {
|
||||||
let mut app = VirtualDom::new(app);
|
let mut app = VirtualDom::new(app);
|
||||||
let _ = app.rebuild();
|
let _ = app.rebuild();
|
||||||
|
|
||||||
Html(dioxus::ssr::render_vdom(&app))
|
Html(dioxus_ssr::render_vdom(&app))
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
# Interactivity
|
# Interactivity
|
||||||
|
|
||||||
So far, we've learned how to describe the structure and properties of our user interfaces. However, most interfaces need to be interactive in order to be useful. In this chapter, we describe how to make a Dioxus app that responds to the user.
|
So far, we've learned how to describe the structure and properties of our user interfaces. However, most interfaces need to be interactive in order to be useful. In this chapter, we describe how to make a Dioxus app that responds to the user.
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
After many months of work, we're very excited to release the first version of Dioxus!
|
After many months of work, we're very excited to release the first version of Dioxus!
|
||||||
|
|
||||||
Dioxus is a new library for building interactive user interfaces (GUI) with Rust. It is built around a Virtual DOM, making it portable for the web, desktop, server, mobile, and more.
|
Dioxus is a new library for building interactive user interfaces (GUI) with Rust. It is built around a Virtual DOM, making it portable for the web, desktop, server, mobile, and more.
|
||||||
|
|
||||||
Dioxus has the following design goals:
|
Dioxus has the following design goals:
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ To give you an idea of what Dioxus looks like, here's a simple counter app:
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app)
|
dioxus_desktop::launch(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
@ -187,7 +187,7 @@ We can add our counter from above.
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app)
|
dioxus_desktop::launch(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
@ -239,7 +239,7 @@ LazyNodes::new(|f| {
|
||||||
|
|
||||||
The `rsx!` macro generates idiomatic Rust code that uses the factory API — no different than what you'd write by hand yourself.
|
The `rsx!` macro generates idiomatic Rust code that uses the factory API — no different than what you'd write by hand yourself.
|
||||||
|
|
||||||
To make it easier to work with RSX, we've built a small [VSCode extension](https://github.com/DioxusLabs/studio) with useful utilities. This extension provides a command that converts a selected block of HTML into RSX so you can easily reuse existing web templates.
|
To make it easier to work with RSX, we've built a small [VSCode extension](https://github.com/DioxusLabs/studio) with useful utilities. This extension provides a command that converts a selected block of HTML into RSX so you can easily reuse existing web templates.
|
||||||
|
|
||||||
## Dioxus prioritizes developer experience
|
## Dioxus prioritizes developer experience
|
||||||
|
|
||||||
|
@ -299,7 +299,7 @@ There's *way* more to this story, but hopefully we've convinced you that Dioxus'
|
||||||
|
|
||||||
## Dioxus is perfected for the IDE
|
## Dioxus is perfected for the IDE
|
||||||
|
|
||||||
Note: all IDE-related features have only been tested with [Rust-Analyzer](https://github.com/rust-analyzer/rust-analyzer).
|
Note: all IDE-related features have only been tested with [Rust-Analyzer](https://github.com/rust-analyzer/rust-analyzer).
|
||||||
|
|
||||||
Dioxus code operates pleasantly with your IDE. For starters, most elements are documented through the Rustdoc system. A quick summary of the MDN docs is always under your finger tips:
|
Dioxus code operates pleasantly with your IDE. For starters, most elements are documented through the Rustdoc system. A quick summary of the MDN docs is always under your finger tips:
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ Dioxus is humbly built off the work done by [Dodrio](https://github.com/fitzgen/
|
||||||
|
|
||||||
Dioxus is *substantially* more performant than many of the other Rust DOM-based UI libraries (Yew/Percy) and is *significantly* more performant than React - roughly competitive with InfernoJS. While not as performant as libraries like SolidJS/Sycamore, Dioxus imposes roughly a ~3% overhead over DOM patching, so it's *plenty* fast.
|
Dioxus is *substantially* more performant than many of the other Rust DOM-based UI libraries (Yew/Percy) and is *significantly* more performant than React - roughly competitive with InfernoJS. While not as performant as libraries like SolidJS/Sycamore, Dioxus imposes roughly a ~3% overhead over DOM patching, so it's *plenty* fast.
|
||||||
|
|
||||||
## Works on Desktop and Mobile
|
## Works on Desktop and Mobile
|
||||||
We’ve mentioned before that Dioxus works practically anywhere that Rust does. When running natively as a desktop or mobile app, your Dioxus code will run on its own thread, not inside of a web runtime. This means you can access hardware, file system, and platform APIs directly without needing to go through a shim layer. In our examples, we feature a [file explorer app](https://github.com/DioxusLabs/example-projects/tree/master/file-explorer) and [WiFi scanner app](https://github.com/DioxusLabs/example-projects/tree/master/wifi-scanner) where platform access occurs inside an asynchronous multithreaded coroutine. This solves the problem faced by React Native and other cross-platform toolkits where JavaScript apps incur a massive performance penalty with substantial maintenance overhead associated with platform API shims.
|
We’ve mentioned before that Dioxus works practically anywhere that Rust does. When running natively as a desktop or mobile app, your Dioxus code will run on its own thread, not inside of a web runtime. This means you can access hardware, file system, and platform APIs directly without needing to go through a shim layer. In our examples, we feature a [file explorer app](https://github.com/DioxusLabs/example-projects/tree/master/file-explorer) and [WiFi scanner app](https://github.com/DioxusLabs/example-projects/tree/master/wifi-scanner) where platform access occurs inside an asynchronous multithreaded coroutine. This solves the problem faced by React Native and other cross-platform toolkits where JavaScript apps incur a massive performance penalty with substantial maintenance overhead associated with platform API shims.
|
||||||
|
|
||||||
A desktop app:
|
A desktop app:
|
||||||
|
@ -401,7 +401,7 @@ Stay tuned for our next article, which will go over some of the optimization tec
|
||||||
|
|
||||||
## Community
|
## Community
|
||||||
|
|
||||||
The future is bright for Rust frontends! If you'd like to get involved, we have a [Discord server](https://discord.gg/XgGxMSkvUM), [a subreddit](http://reddit.com/r/dioxus), and [GitHub discussion pages](https://github.com/DioxusLabs/dioxus/discussions).
|
The future is bright for Rust frontends! If you'd like to get involved, we have a [Discord server](https://discord.gg/XgGxMSkvUM), [a subreddit](http://reddit.com/r/dioxus), and [GitHub discussion pages](https://github.com/DioxusLabs/dioxus/discussions).
|
||||||
|
|
||||||
Let us know what you build!
|
Let us know what you build!
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// Launch Dioxus web app
|
// Launch Dioxus web app
|
||||||
dioxus::web::launch(app);
|
dioxus_web::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Our root component.
|
// Our root component.
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use dioxus::{events::*, prelude::*};
|
use dioxus::{events::*, prelude::*};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -19,7 +19,7 @@ and is proven to be safe with MIRI.
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -4,12 +4,12 @@ This calculator version uses React-style state management. All state is held as
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use dioxus::events::*;
|
use dioxus::events::*;
|
||||||
|
use dioxus::html::input_data::keyboard_types::Key;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_html::input_data::keyboard_types::Key;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
use dioxus::desktop::tao::dpi::LogicalSize;
|
use dioxus_desktop::tao::dpi::LogicalSize;
|
||||||
dioxus::desktop::launch_cfg(app, |cfg| {
|
dioxus_desktop::launch_cfg(app, |cfg| {
|
||||||
cfg.with_window(|w| {
|
cfg.with_window(|w| {
|
||||||
w.with_title("Calculator Demo")
|
w.with_title("Calculator Demo")
|
||||||
.with_resizable(false)
|
.with_resizable(false)
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
# Reference Guide
|
|
||||||
|
|
||||||
This folder holds a bunch of useful reference code. However, none of the code is meant to be executed (nothing special will happen).
|
|
||||||
|
|
||||||
|
|
||||||
| Reference: | What it does |
|
|
||||||
| --------------------------------------------------- | ------------------------------------------------------ |
|
|
||||||
| [Basics](./basics.rs) | How to render a simple app |
|
|
||||||
| [Empty](./empty.rs) | Components can return None |
|
|
||||||
| [Children](./children.rs) | Components can have children |
|
|
||||||
| [Suspense](./suspense.rs) | Suspense can be achieved with use_suspense |
|
|
||||||
| [Conditional Rendering](./conditional_rendering.rs) | Elements can be hidden conditionally |
|
|
||||||
| [Controlled Inputs](./controlled_inputs.rs) | Inputs are "controlled" similar to React |
|
|
||||||
| [Fragments](./fragments.rs) | Components can return multiple elements without a root |
|
|
||||||
| [Inline Styles](./inline_styles.rs) | Styles can be inlined as element attributes |
|
|
||||||
| [Spread Pattern for Props](./spreadpattern.rs) | Props can be spread into component calls |
|
|
||||||
| [Iterators](./iterators.rs) | Lists of elements can be made from iterators |
|
|
||||||
| [Listener](./listener.rs) | State can be updated from event listeners |
|
|
||||||
| [Memo](./memo.rs) | Memoization is controlled via PartialEq |
|
|
||||||
| [Custom Elements](./custom_elements.rs) | Define custom elements |
|
|
||||||
| [Anti-patterns](./antipatterns.rs) | What not to do! |
|
|
|
@ -1,44 +0,0 @@
|
||||||
//! Example: Web Components & Custom Elements
|
|
||||||
//! -----------------------------------------
|
|
||||||
//!
|
|
||||||
//! Web components are a flavor of html elements that can be user-defined.
|
|
||||||
//! See: https://www.webcomponents.org for more information.
|
|
||||||
//!
|
|
||||||
//! Users who use webcomponents typically don't use Dioxus. However, if you would like to use webcomponents in Dioxus,
|
|
||||||
//! you can easily create a new custom element with compile-time correct wrappers around the webcomponent.
|
|
||||||
//!
|
|
||||||
//! We don't support building new webcomponents with Dioxus, however. :(
|
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
pub fn Example(cx: Scope) -> Element {
|
|
||||||
cx.render(rsx! {
|
|
||||||
div {
|
|
||||||
custom_element {
|
|
||||||
custom_attr: "custom data on custom elements"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
mod dioxus_elements {
|
|
||||||
use std::fmt::Arguments;
|
|
||||||
|
|
||||||
use dioxus::prelude::DioxusElement;
|
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
pub struct custom_element;
|
|
||||||
impl DioxusElement for custom_element {
|
|
||||||
const TAG_NAME: &'static str = "custom_element";
|
|
||||||
const NAME_SPACE: Option<&'static str> = None;
|
|
||||||
}
|
|
||||||
impl custom_element {
|
|
||||||
pub fn custom_attr<'a>(&self, f: NodeFactory<'a>, val: Arguments) -> Attribute<'a> {
|
|
||||||
f.attr("custom_asttr", val, None, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Re-export the normal html namespace
|
|
||||||
pub use dioxus::prelude::dioxus_elements::*;
|
|
||||||
use dioxus_core::{nodes::Attribute, NodeFactory};
|
|
||||||
}
|
|
|
@ -1,89 +0,0 @@
|
||||||
//! Example: Error Handling
|
|
||||||
//! ------------------------
|
|
||||||
//!
|
|
||||||
//! Error handling in Dioxus comes in a few flavors. Because Dioxus is a Rust project, Options and Results are obviously
|
|
||||||
//! the go-to way of wrapping possibly-errored data. However, if a component fails when "unwrapping," everything will crash,
|
|
||||||
//! the page will deadlock, and your users will be sad.
|
|
||||||
//!
|
|
||||||
//! So, obviously, you need to handle your errors.
|
|
||||||
//!
|
|
||||||
//! Fortunately, it's easy to avoid panics, even during quick prototyping.
|
|
||||||
//!
|
|
||||||
//! Here are a few strategies:
|
|
||||||
//! - Leverage the ability to return "None" and propagate None directly
|
|
||||||
//! - Instead of propagating "None" manually, use the "?" syntax sugar
|
|
||||||
//! - Convert Results into Options with .ok()
|
|
||||||
//! - Manually display a separate screen by matching on Options/Results
|
|
||||||
//!
|
|
||||||
//! There *are* plans to add helpful screens for when apps completely panic in Wasm. However, you should really try to
|
|
||||||
//! avoid panicking.
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
fn main() {}
|
|
||||||
|
|
||||||
/// This is one way to go about error handling (just toss things away with unwrap).
|
|
||||||
/// However, if you get it wrong, the whole app will crash.
|
|
||||||
/// This is pretty flimsy.
|
|
||||||
pub fn App(cx: Scope) -> Element {
|
|
||||||
let data = get_data().unwrap();
|
|
||||||
cx.render(rsx!( div { "{data}" } ))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is a pretty verbose way of error handling
|
|
||||||
/// However, it's still pretty good since we don't panic, just fail to render anything
|
|
||||||
pub fn App1(cx: Scope) -> Element {
|
|
||||||
let data = match get_data() {
|
|
||||||
Some(data) => data,
|
|
||||||
None => return None,
|
|
||||||
};
|
|
||||||
cx.render(rsx!( div { "{data}" } ))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is an even better form of error handling.
|
|
||||||
/// However, it _does_ make the component go blank, which might not be desirable.
|
|
||||||
///
|
|
||||||
/// This type of error handling is good when you have "selectors" that produce Some/None based on some state that's
|
|
||||||
/// already controlled higher in the tree. i.e. displaying a "Username" in a component that should only be shown if
|
|
||||||
/// a user is logged in.
|
|
||||||
///
|
|
||||||
/// Dioxus will throw an error in the console if the None-path is ever taken.
|
|
||||||
pub fn App2(cx: Scope) -> Element {
|
|
||||||
let data = get_data()?;
|
|
||||||
cx.render(rsx!( div { "{data}" } ))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is top-tier error handling since it displays a failure state.
|
|
||||||
///
|
|
||||||
/// However, the error is lacking in context.
|
|
||||||
pub fn App3(cx: Scope) -> Element {
|
|
||||||
match get_data() {
|
|
||||||
Some(data) => cx.render(rsx!( div { "{data}" } )),
|
|
||||||
None => cx.render(rsx!( div { "Failed to load data :(" } )),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// For errors that return results, it's possible to short-circuit the match-based error handling with `.ok()` which converts
|
|
||||||
/// a Result<T, V> into an Option<T> and lets you abort rendering by early-returning `None`
|
|
||||||
pub fn App4(cx: Scope) -> Element {
|
|
||||||
let data = get_data_err().ok()?;
|
|
||||||
cx.render(rsx!( div { "{data}" } ))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// This is great error handling since it displays a failure state... with context!
|
|
||||||
///
|
|
||||||
/// Hopefully you'll never need to display a screen like this. It's rather bad taste
|
|
||||||
pub fn App5(cx: Scope) -> Element {
|
|
||||||
match get_data_err() {
|
|
||||||
Ok(data) => cx.render(rsx!( div { "{data}" } )),
|
|
||||||
Err(c) => cx.render(rsx!( div { "Failed to load data: {c}" } )),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// this fetching function produces "nothing"
|
|
||||||
fn get_data() -> Option<String> {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
|
|
||||||
// this fetching function produces "nothing"
|
|
||||||
fn get_data_err() -> Result<String, &'static str> {
|
|
||||||
Result::Err("Failed!")
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
//! Examples: CSS
|
|
||||||
//! -------------
|
|
||||||
//!
|
|
||||||
//! Originally taken from:
|
|
||||||
//! - https://www.w3schools.com/html/tryit.asp?filename=tryhtml_css_internal
|
|
||||||
//!
|
|
||||||
//! Include global styles in your app!
|
|
||||||
//!
|
|
||||||
//! You can simply drop in a "style" tag and set the inner contents to your stylesheet.
|
|
||||||
//! It's slightly more manual than React, but is less magical.
|
|
||||||
//!
|
|
||||||
//! A coming update with the assets system will make it possible to include global css from child components.
|
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
const STYLE: &str = r#"
|
|
||||||
body {background-color: powderblue;}
|
|
||||||
h1 {color: blue;}
|
|
||||||
p {color: red;}
|
|
||||||
"#;
|
|
||||||
|
|
||||||
pub fn Example(cx: Scope) -> Element {
|
|
||||||
cx.render(rsx! {
|
|
||||||
head { style { "{STYLE}" } }
|
|
||||||
body {
|
|
||||||
h1 {"This is a heading"}
|
|
||||||
p {"This is a paragraph"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,29 +0,0 @@
|
||||||
//! Example: Inline Styles
|
|
||||||
//! ----------------------
|
|
||||||
//!
|
|
||||||
//! This example shows how to use inline styles in Dioxus components.
|
|
||||||
//!
|
|
||||||
//! Inline styles function very similarly to regular attributes, just grouped together in "style".
|
|
||||||
//!
|
|
||||||
//! Inline styles in Dioxus are more performant than React since we're able to cache attributes and compare by pointers.
|
|
||||||
//! However, it's still not as performant as cascaded styles. Use with care.
|
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
pub fn Example(cx: Scope) -> Element {
|
|
||||||
cx.render(rsx! {
|
|
||||||
head {
|
|
||||||
background_color: "powderblue"
|
|
||||||
}
|
|
||||||
body {
|
|
||||||
h1 {
|
|
||||||
color: "blue",
|
|
||||||
"This is a heading"
|
|
||||||
}
|
|
||||||
p {
|
|
||||||
color: "red",
|
|
||||||
"This is a paragraph"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,84 +0,0 @@
|
||||||
//! Example: Memoization
|
|
||||||
//! --------------------
|
|
||||||
//!
|
|
||||||
//! This example showcases how memoization works in Dioxus.
|
|
||||||
//!
|
|
||||||
//! Memoization is the process in which Dioxus skips diffing child components if their props don't change.
|
|
||||||
//! In React, components are never memoized unless wrapped in `memo` or configured with `shouldComponentUpdate`.
|
|
||||||
//!
|
|
||||||
//! Due to the safety guarantees of Rust, we can automatically memoize components in some circumstances. Whenever a
|
|
||||||
//! component's properties are valid for the `'static` lifetime, Dioxus will automatically compare the props before
|
|
||||||
//! diffing the component. If the props don't change (according to PartialEq), the component will not be re-rendered.
|
|
||||||
//!
|
|
||||||
//! However, if the props use some generics or borrow from their parent, then Dioxus can't safely supress updates,
|
|
||||||
//! and is forced to render the child. If you think that this behavior is wrong for your usecase, you can implement
|
|
||||||
//! the memo method yourself, but beware, doing so is UNSAFE and may cause issues if you do it wrong.
|
|
||||||
//!
|
|
||||||
//! If you want to gain that little bit extra performance, consider using global state management, signals, or
|
|
||||||
//! memoized collections like im-rc which are designed for this use case.
|
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
// By default, components with no props are always memoized.
|
|
||||||
// A props of () is considered empty.
|
|
||||||
pub fn Example(cx: Scope) -> Element {
|
|
||||||
cx.render(rsx! {
|
|
||||||
div { "100% memoized!" }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// These props do not borrow any content, and therefore can be safely memoized.
|
|
||||||
// However, the parent *must* create a new string on every render.
|
|
||||||
// Notice how these props implement PartialEq - this is required for 'static props
|
|
||||||
#[derive(PartialEq, Props)]
|
|
||||||
pub struct MyProps1 {
|
|
||||||
name: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn Example1(cx: Scope<MyProps1>) -> Element {
|
|
||||||
cx.render(rsx! {
|
|
||||||
div { "100% memoized! {cx.props.name}" }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// These props do not borrow any content, and therefore can be safely memoized.
|
|
||||||
// In contrast with the `String` example, these props use `Rc<str>` which operates similar to strings in JavaScript.
|
|
||||||
// These strings cannot be modified, but may be cheaply shared in many places without issue.
|
|
||||||
#[derive(PartialEq, Props)]
|
|
||||||
pub struct MyProps2 {
|
|
||||||
name: std::rc::Rc<str>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn Example2(cx: Scope<MyProps2>) -> Element {
|
|
||||||
cx.render(rsx! {
|
|
||||||
div { "100% memoized! {cx.props.name}" }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// These props *do* borrow any content, and therefore cannot be safely memoized!.
|
|
||||||
#[derive(PartialEq, Props)]
|
|
||||||
pub struct MyProps3<'a> {
|
|
||||||
name: &'a str,
|
|
||||||
}
|
|
||||||
// We need to manually specify a lifetime that ensures props and scope (the component's state) share the same lifetime.
|
|
||||||
// Using the `pub fn Example(cx: Scope): Component` pattern _will_ specify a lifetime, but that lifetime will be static which might
|
|
||||||
// not exactly be what you want
|
|
||||||
fn Example3(cx: Scope<'a, MyProps3<'a>>) -> DomTree {
|
|
||||||
cx.render(rsx! {
|
|
||||||
div { "Not memoized! {cx.props.name}" }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// These props *do* borrow any content, and therefore cannot be safely memoized!.
|
|
||||||
// However, they cannot be compared, so we don't need the PartialEq flag.
|
|
||||||
#[derive(Props)]
|
|
||||||
pub struct MyProps4<'a> {
|
|
||||||
onhandle: &'a dyn Fn(),
|
|
||||||
}
|
|
||||||
|
|
||||||
// We need to manually specify a lifetime that ensures props and scope (the component's state) share the same lifetime.
|
|
||||||
fn Example4<'a>(cx: Scope<'a, MyProps4<'a>>) -> DomTree {
|
|
||||||
cx.render(rsx! {
|
|
||||||
div { "Not memoized!", onclick: move |_| (props.onhandle)() }
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
//! Example: Spread pattern for Components
|
|
||||||
//! --------------------------------------
|
|
||||||
//!
|
|
||||||
//! Dioxus supports the "spread" pattern for manually building a component's properties. This is useful when props
|
|
||||||
//! are passed down from a parent, or it's more ergonomic to construct props from outside the rsx! macro.
|
|
||||||
//!
|
|
||||||
//! To use the spread pattern, simply pass ".." followed by a Rust expression. This pattern also supports overriding
|
|
||||||
//! values, using the manual props as the base and then modifying fields specified with non-spread attributes.
|
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
pub fn Example(cx: Scope) -> Element {
|
|
||||||
let props = MyProps {
|
|
||||||
count: 0,
|
|
||||||
live: true,
|
|
||||||
name: "Dioxus",
|
|
||||||
};
|
|
||||||
cx.render(rsx! {
|
|
||||||
Example1 { ..props, count: 10, div {"child"} }
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Props)]
|
|
||||||
pub struct MyProps<'a> {
|
|
||||||
count: u32,
|
|
||||||
live: bool,
|
|
||||||
name: &'static str,
|
|
||||||
children: Element<'a>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn Example1<'a>(cx: Scope<'a, MyProps<'a>>) -> Element {
|
|
||||||
let MyProps { count, live, name } = cx.props;
|
|
||||||
cx.render(rsx! {
|
|
||||||
div {
|
|
||||||
h1 { "Hello, {name}"}
|
|
||||||
h3 {"Are we alive? {live}"}
|
|
||||||
p {"Count is {count}"}
|
|
||||||
&cx.props.children
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,38 +0,0 @@
|
||||||
//! Example: Suspense
|
|
||||||
//! -----------------
|
|
||||||
//! This example demonstrates how the use_suspense hook can be used to load and render asynchronous data. Suspense enables
|
|
||||||
//! components to wait on futures to complete before rendering the result into VNodes. These VNodes are immediately
|
|
||||||
//! available in a suspended" fashion and will automatically propagate to the UI when the future completes.
|
|
||||||
//!
|
|
||||||
//! Currently, suspense futures are non-restartable. In the future, we'll provide more granular control of how to start,
|
|
||||||
//! stop, and reset these futures.
|
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
#[derive(serde::Deserialize)]
|
|
||||||
struct DogApi {
|
|
||||||
message: String,
|
|
||||||
}
|
|
||||||
const ENDPOINT: &str = "https://dog.ceo/api/breeds/image/random";
|
|
||||||
|
|
||||||
pub fn Example(cx: Scope) -> Element {
|
|
||||||
let doggo = use_suspense(
|
|
||||||
cx,
|
|
||||||
|| surf::get(ENDPOINT).recv_json::<DogApi>(),
|
|
||||||
|cx, res| match res {
|
|
||||||
Ok(res) => rsx!(
|
|
||||||
cx,
|
|
||||||
img {
|
|
||||||
src: "{res.message}"
|
|
||||||
}
|
|
||||||
),
|
|
||||||
Err(_) => rsx!(cx, div { "No doggos for you :(" }),
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
cx.render(rsx!(
|
|
||||||
div {
|
|
||||||
h1 {"Waiting for a doggo..."}
|
|
||||||
{doggo}
|
|
||||||
}
|
|
||||||
))
|
|
||||||
}
|
|
|
@ -1,61 +0,0 @@
|
||||||
//! Example: Tasks
|
|
||||||
//! --------------
|
|
||||||
//!
|
|
||||||
//! Built around the same system that powers suspense, Dioxus also allows users to write arbitrary tasks that can modify
|
|
||||||
//! state asynchronously. `use_task` takes a future and returns a task handle and an option that holds the tasks's return
|
|
||||||
//! value. When the task completes, the component will re-render with the result freshly available.
|
|
||||||
//!
|
|
||||||
//! Tasks don't necessarily need to complete, however. It would be completely reasonable to wire up a websocket receiver
|
|
||||||
//! in a task and have it work infinitely while the app is running. If the socket throws an error, the task could complete
|
|
||||||
//! and the UI could present a helpful error message.
|
|
||||||
//!
|
|
||||||
//! Tasks also return the `TaskHandle` type which lets other component logic start, stop, and restart the task at any time.
|
|
||||||
//! Tasks are very much like an async-flavoroued coroutine, making them incredibly powerful.
|
|
||||||
//!
|
|
||||||
//! Tasks must be valid for the 'static lifetime, so any state management neeeds to be cloned into the closure. `use_state`
|
|
||||||
//! has a method called `for_async` which generates an AsyncUseState wrapper. This has a very similar API to the regualr
|
|
||||||
//! `use_state` but is `static.
|
|
||||||
//!
|
|
||||||
//! Remeber `use_task` is a hook! Don't call it out of order or in loops. You might aaccidentally swap the task handles
|
|
||||||
//! and break things in subtle ways.
|
|
||||||
//!
|
|
||||||
//! Whenever a component is scheduled for deletion, the task is dropped. Make sure that whatever primitives used in the
|
|
||||||
//! task have a valid drop implementation and won't leave resources tied up.
|
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
pub static Example: Component = |cx| {
|
|
||||||
let count = use_state(&cx, || 0);
|
|
||||||
let mut direction = use_state(&cx, || 1);
|
|
||||||
|
|
||||||
// Tasks are 'static, so we need to copy relevant items in
|
|
||||||
let (async_count, dir) = (count.for_async(), *direction);
|
|
||||||
|
|
||||||
let (task, result) = use_task(cx, move || async move {
|
|
||||||
loop {
|
|
||||||
gloo_timers::future::TimeoutFuture::new(250).await;
|
|
||||||
*async_count.get_mut() += dir;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
cx.render(rsx! {
|
|
||||||
div {
|
|
||||||
h1 {"count is {count}"}
|
|
||||||
button {
|
|
||||||
onclick: move |_| task.stop(),
|
|
||||||
"Stop counting"
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
onclick: move |_| task.resume(),
|
|
||||||
"Start counting"
|
|
||||||
}
|
|
||||||
button {
|
|
||||||
onclick: move |_| {
|
|
||||||
direction *= -1;
|
|
||||||
task.restart();
|
|
||||||
}
|
|
||||||
"Switch counting direcion"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
};
|
|
|
@ -2,9 +2,10 @@
|
||||||
Tiny CRM: A port of the Yew CRM example to Dioxus.
|
Tiny CRM: A port of the Yew CRM example to Dioxus.
|
||||||
*/
|
*/
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_router::{Link, Route, Router};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default)]
|
#[derive(Clone, Debug, Default)]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -10,7 +10,7 @@ fn main() {
|
||||||
let mut dom = VirtualDom::new(app);
|
let mut dom = VirtualDom::new(app);
|
||||||
let _ = dom.rebuild();
|
let _ = dom.rebuild();
|
||||||
|
|
||||||
let output = dioxus::ssr::render_vdom(&dom);
|
let output = dioxus_ssr::render_vdom(&dom);
|
||||||
|
|
||||||
println!("{}", output);
|
println!("{}", output);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,11 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch_cfg(app, |c| {
|
dioxus_desktop::launch_cfg(app, |c| {
|
||||||
c.with_custom_head("<style>body { background-color: red; }</style>".into())
|
c.with_custom_head("<style>body { background-color: red; }</style>".into())
|
||||||
});
|
});
|
||||||
|
|
||||||
dioxus::desktop::launch_cfg(app, |c| {
|
dioxus_desktop::launch_cfg(app, |c| {
|
||||||
c.with_custom_index(
|
c.with_custom_index(
|
||||||
r#"
|
r#"
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -2,12 +2,11 @@
|
||||||
|
|
||||||
//! Render a bunch of doggos!
|
//! Render a bunch of doggos!
|
||||||
|
|
||||||
|
use dioxus::prelude::*;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, serde::Deserialize)]
|
#[derive(Debug, Clone, PartialEq, serde::Deserialize)]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
let script = use_state(&cx, String::new);
|
let script = use_state(&cx, String::new);
|
||||||
let eval = use_eval(&cx);
|
let eval = dioxus_desktop::use_eval(&cx);
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
|
@ -17,7 +17,6 @@ fn app(cx: Scope) -> Element {
|
||||||
}
|
}
|
||||||
button {
|
button {
|
||||||
onclick: move |_| eval(script),
|
onclick: move |_| eval(script),
|
||||||
|
|
||||||
"Execute"
|
"Execute"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
use fermi::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app)
|
dioxus_desktop::launch(app)
|
||||||
}
|
}
|
||||||
|
|
||||||
static NAME: Atom<String> = |_| "world".to_string();
|
static NAME: Atom<String> = |_| "world".to_string();
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch_cfg(app, |c| c.with_window(|w| w.with_resizable(true)));
|
dioxus_desktop::launch_cfg(app, |c| c.with_window(|w| w.with_resizable(true)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch_with_props(app, (), |c| {
|
dioxus_desktop::launch_with_props(app, (), |c| {
|
||||||
c.with_file_drop_handler(|_w, e| {
|
c.with_file_drop_handler(|_w, e| {
|
||||||
println!("{:?}", e);
|
println!("{:?}", e);
|
||||||
true
|
true
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
use dioxus::desktop::tao::dpi::LogicalSize;
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_desktop::tao::dpi::LogicalSize;
|
||||||
|
use dioxus_router::{Link, Route, Router};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
env_logger::init();
|
env_logger::init();
|
||||||
|
|
||||||
dioxus::desktop::launch_cfg(app, |c| {
|
dioxus_desktop::launch_cfg(app, |c| {
|
||||||
c.with_window(|c| {
|
c.with_window(|c| {
|
||||||
c.with_title("Spinsense Client")
|
c.with_title("Spinsense Client")
|
||||||
.with_inner_size(LogicalSize::new(600, 1000))
|
.with_inner_size(LogicalSize::new(600, 1000))
|
||||||
|
|
|
@ -6,24 +6,22 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
Router {
|
div {
|
||||||
div {
|
h1 { "Form" }
|
||||||
h1 { "Form" }
|
form {
|
||||||
form {
|
onsubmit: move |ev| println!("Submitted {:?}", ev.values),
|
||||||
onsubmit: move |ev| println!("Submitted {:?}", ev.values),
|
oninput: move |ev| println!("Input {:?}", ev.values),
|
||||||
oninput: move |ev| println!("Input {:?}", ev.values),
|
input { r#type: "text", name: "username" }
|
||||||
input { r#type: "text", name: "username" }
|
input { r#type: "text", name: "full-name" }
|
||||||
input { r#type: "text", name: "full-name" }
|
input { r#type: "password", name: "password" }
|
||||||
input { r#type: "password", name: "password" }
|
input { r#type: "radio", name: "color", value: "red" }
|
||||||
input { r#type: "radio", name: "color", value: "red" }
|
input { r#type: "radio", name: "color", value: "blue" }
|
||||||
input { r#type: "radio", name: "color", value: "blue" }
|
button { r#type: "submit", value: "Submit", "Submit the form" }
|
||||||
button { r#type: "submit", value: "Submit", "Submit the form" }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -4,7 +4,7 @@ use dioxus::prelude::*;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -10,13 +10,12 @@
|
||||||
//! proof-of-concept for the hydration feature, but you'll probably only want to use hydration for the web.
|
//! proof-of-concept for the hydration feature, but you'll probably only want to use hydration for the web.
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus::ssr;
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let vdom = VirtualDom::new(app);
|
let vdom = VirtualDom::new(app);
|
||||||
let content = ssr::render_vdom_cfg(&vdom, |f| f.pre_render(true));
|
let content = dioxus_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));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -24,7 +24,7 @@ fn Thing4<'a>(cx: Scope<'a>, _a: &'a u32) -> Element<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dioxus::{events::FormEvent, prelude::*};
|
use dioxus::{events::FormEvent, prelude::*};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
const FIELDS: &[(&str, &str)] = &[
|
const FIELDS: &[(&str, &str)] = &[
|
||||||
|
|
|
@ -1,25 +1,21 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_router::{Link, Route, Router};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
cx.render(rsx! (
|
cx.render(rsx! (
|
||||||
div {
|
div {
|
||||||
p {
|
p {
|
||||||
a {
|
a { href: "http://dioxuslabs.com/", "Default link - links outside of your app" }
|
||||||
href: "http://dioxuslabs.com/",
|
|
||||||
"Default link - links outside of your app"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
a {
|
a {
|
||||||
href: "http://dioxuslabs.com/",
|
href: "http://dioxuslabs.com/",
|
||||||
prevent_default: "onclick",
|
prevent_default: "onclick",
|
||||||
onclick: |_| {
|
onclick: |_| println!("Hello Dioxus"),
|
||||||
println!("Hello Dioxus");
|
|
||||||
},
|
|
||||||
"Custom event link - links inside of your app",
|
"Custom event link - links inside of your app",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +24,6 @@ fn app(cx: Scope) -> Element {
|
||||||
Router {
|
Router {
|
||||||
Route { to: "/", h1 { "Home" } },
|
Route { to: "/", h1 { "Home" } },
|
||||||
Route { to: "/settings", h1 { "settings" } },
|
Route { to: "/settings", h1 { "settings" } },
|
||||||
|
|
||||||
p { "----"}
|
p { "----"}
|
||||||
ul {
|
ul {
|
||||||
Link { to: "/", li { "Router link to home" } },
|
Link { to: "/", li { "Router link to home" } },
|
||||||
|
|
|
@ -5,7 +5,7 @@ use dioxus::events::*;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -17,13 +17,13 @@
|
||||||
//! the RefCell will panic and crash. You can use `try_get_mut` or `.modify` to avoid this problem, or just not hold two
|
//! the RefCell will panic and crash. You can use `try_get_mut` or `.modify` to avoid this problem, or just not hold two
|
||||||
//! RefMuts at the same time.
|
//! RefMuts at the same time.
|
||||||
|
|
||||||
use dioxus::desktop::wry::application::dpi::LogicalSize;
|
|
||||||
use dioxus::events::*;
|
use dioxus::events::*;
|
||||||
|
use dioxus::html::input_data::keyboard_types::Key;
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_html::input_data::keyboard_types::Key;
|
use dioxus_desktop::wry::application::dpi::LogicalSize;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch_cfg(app, |cfg| {
|
dioxus_desktop::launch_cfg(app, |cfg| {
|
||||||
cfg.with_window(|w| {
|
cfg.with_window(|w| {
|
||||||
w.with_title("Calculator Demo")
|
w.with_title("Calculator Demo")
|
||||||
.with_resizable(false)
|
.with_resizable(false)
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
#![allow(non_snake_case)]
|
#![allow(non_snake_case)]
|
||||||
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus::router::{Link, Route, Router};
|
use dioxus_router::{Link, Route, Router};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
@ -30,7 +30,7 @@ fn app(cx: Scope) -> Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn BlogPost(cx: Scope) -> Element {
|
fn BlogPost(cx: Scope) -> Element {
|
||||||
let post = dioxus::router::use_route(&cx).last_segment()?;
|
let post = dioxus_router::use_route(&cx).last_segment()?;
|
||||||
|
|
||||||
cx.render(rsx! {
|
cx.render(rsx! {
|
||||||
div {
|
div {
|
||||||
|
@ -46,9 +46,9 @@ struct Query {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn User(cx: Scope) -> Element {
|
fn User(cx: Scope) -> Element {
|
||||||
let post = dioxus::router::use_route(&cx).last_segment()?;
|
let post = dioxus_router::use_route(&cx).last_segment()?;
|
||||||
|
|
||||||
let query = dioxus::router::use_route(&cx)
|
let query = dioxus_router::use_route(&cx)
|
||||||
.query::<Query>()
|
.query::<Query>()
|
||||||
.unwrap_or(Query { bold: false });
|
.unwrap_or(Query { bold: false });
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ fn main() {
|
||||||
let mut vdom = VirtualDom::new(example);
|
let mut vdom = VirtualDom::new(example);
|
||||||
vdom.rebuild();
|
vdom.rebuild();
|
||||||
|
|
||||||
let out = dioxus::ssr::render_vdom_cfg(&vdom, |c| c.newline(true).indent(true));
|
let out = dioxus_ssr::render_vdom_cfg(&vdom, |c| c.newline(true).indent(true));
|
||||||
println!("{}", out);
|
println!("{}", out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,7 @@
|
||||||
//! - Allow top-level fragments
|
//! - Allow top-level fragments
|
||||||
//!
|
//!
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// When trying to return "nothing" to Dioxus, you'll need to specify the type parameter or Rust will be sad.
|
/// When trying to return "nothing" to Dioxus, you'll need to specify the type parameter or Rust will be sad.
|
||||||
|
|
|
@ -10,12 +10,12 @@ fn main() {
|
||||||
// We can render VirtualDoms
|
// We can render VirtualDoms
|
||||||
let mut vdom = VirtualDom::new(app);
|
let mut vdom = VirtualDom::new(app);
|
||||||
let _ = vdom.rebuild();
|
let _ = vdom.rebuild();
|
||||||
println!("{}", dioxus::ssr::render_vdom(&vdom));
|
println!("{}", dioxus_ssr::render_vdom(&vdom));
|
||||||
|
|
||||||
// Or we can render rsx! calls themselves
|
// Or we can render rsx! calls themselves
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}",
|
||||||
dioxus::ssr::render_lazy(rsx! {
|
dioxus_ssr::render_lazy(rsx! {
|
||||||
div {
|
div {
|
||||||
h1 { "Hello, world!" }
|
h1 { "Hello, world!" }
|
||||||
}
|
}
|
||||||
|
@ -25,14 +25,14 @@ fn main() {
|
||||||
// We can configure the SSR rendering to add ids for rehydration
|
// We can configure the SSR rendering to add ids for rehydration
|
||||||
println!(
|
println!(
|
||||||
"{}",
|
"{}",
|
||||||
dioxus::ssr::render_vdom_cfg(&vdom, |c| c.pre_render(true))
|
dioxus_ssr::render_vdom_cfg(&vdom, |c| c.pre_render(true))
|
||||||
);
|
);
|
||||||
|
|
||||||
// We can even render as a writer
|
// We can even render as a writer
|
||||||
let mut file = String::new();
|
let mut file = String::new();
|
||||||
let _ = file.write_fmt(format_args!(
|
let _ = file.write_fmt(format_args!(
|
||||||
"{}",
|
"{}",
|
||||||
dioxus::ssr::TextRenderer::from_vdom(&vdom, Default::default())
|
dioxus_ssr::TextRenderer::from_vdom(&vdom, Default::default())
|
||||||
));
|
));
|
||||||
println!("{}", file);
|
println!("{}", file);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
use dioxus::desktop::tao::dpi::LogicalSize;
|
use dioxus_desktop::tao::dpi::LogicalSize;
|
||||||
dioxus::desktop::launch_cfg(app, |cfg| {
|
dioxus_desktop::launch_cfg(app, |cfg| {
|
||||||
cfg.with_window(|w| {
|
cfg.with_window(|w| {
|
||||||
w.with_title("Doggo Fetcher")
|
w.with_title("Doggo Fetcher")
|
||||||
.with_inner_size(LogicalSize::new(600.0, 800.0))
|
.with_inner_size(LogicalSize::new(600.0, 800.0))
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use dioxus::{events::MouseEvent, prelude::*};
|
use dioxus::{events::MouseEvent, prelude::*};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -71,5 +71,5 @@ fn app(cx: Scope) -> Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch_cfg(app, |c| {
|
dioxus_desktop::launch_cfg(app, |c| {
|
||||||
c.with_custom_head("<script src=\"https://cdn.tailwindcss.com\"></script>".to_string())
|
c.with_custom_head("<script src=\"https://cdn.tailwindcss.com\"></script>".to_string())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use dioxus::prelude::*;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use dioxus::prelude::*;
|
||||||
use dioxus_elements::input_data::keyboard_types::Key;
|
use dioxus_elements::input_data::keyboard_types::Key;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch_cfg(app, |cfg| {
|
dioxus_desktop::launch_cfg(app, |cfg| {
|
||||||
cfg.with_window(|w| w.with_title("BorderLess Demo").with_decorations(false))
|
cfg.with_window(|w| w.with_title("BorderLess Demo").with_decorations(false))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
let window = dioxus::desktop::use_window(&cx);
|
let window = dioxus_desktop::use_window(&cx);
|
||||||
|
|
||||||
// if you want to make window fullscreen, you need close the resizable.
|
// if you want to make window fullscreen, you need close the resizable.
|
||||||
// window.set_fullscreen(true);
|
// window.set_fullscreen(true);
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
use dioxus::desktop::use_window;
|
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
use dioxus_desktop::use_window;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
# Parity with React
|
|
||||||
|
|
||||||
Parity has moved to the homepage
|
|
||||||
|
|
||||||
## Required services:
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Gloo is covering a lot of these. We want to build hooks around these and provide examples on how to use them.
|
|
||||||
https://github.com/rustwasm/gloo
|
|
||||||
|
|
||||||
For example, resize observer would function like this:
|
|
||||||
|
|
||||||
```rust
|
|
||||||
pub static Example: Component = |cx| {
|
|
||||||
let observer = use_resize_observer();
|
|
||||||
|
|
||||||
cx.render(rsx!(
|
|
||||||
div { ref: observer.node_ref
|
|
||||||
"Size, x: {observer.x} y: {observer.y}"
|
|
||||||
}
|
|
||||||
))
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
However, resize observing is _not_ cross-platform, so this hook (internally) needs to abstract over the rendering platform.
|
|
||||||
|
|
||||||
For other services, we shell out to gloo. If the gloo service doesn't exist, then we need to contribute to the project to make sure it exists.
|
|
||||||
|
|
||||||
| Service | Hook examples | Current Projects |
|
|
||||||
| ---------------------------- | ------------- | ---------------- |
|
|
||||||
| Fetch | 👀 | Reqwest/surf |
|
|
||||||
| Local storage (cache) | 👀 | Gloo |
|
|
||||||
| Persistent storage (IndexDB) | 👀 | 👀 |
|
|
||||||
| WebSocket | 👀 | Gloo |
|
|
||||||
| 3D Renderer / WebGL | 👀 | Gloo |
|
|
||||||
| Web Worker | 👀 | 👀 |
|
|
||||||
| Router | 👀 | 👀 |
|
|
||||||
| Notifications | 👀 | 👀 |
|
|
||||||
| WebRTC Client | 👀 | 👀 |
|
|
||||||
| Service Workers | 👀 | 👀 |
|
|
||||||
| Resize Observer | 👀 | 👀 |
|
|
||||||
| Canvas | 👀 | 👀 |
|
|
||||||
| Clipboard | 👀 | 👀 |
|
|
||||||
| Fullscreen | 👀 | 👀 |
|
|
||||||
| History API | 👀 | 👀 |
|
|
|
@ -44,7 +44,7 @@ To launch an app, we use the `launch` method for the specific renderer we want t
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(app);
|
dioxus_desktop::launch(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn app(cx: Scope) -> Element {
|
fn app(cx: Scope) -> Element {
|
||||||
|
@ -276,7 +276,7 @@ Using components, templates, and hooks, we can build a simple app.
|
||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
dioxus::desktop::launch(App);
|
dioxus_desktop::launch(App);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn App(cx: Scope) -> Element {
|
fn App(cx: Scope) -> Element {
|
||||||
|
|
|
@ -1,90 +0,0 @@
|
||||||
# Road map
|
|
||||||
|
|
||||||
This release map gives a sense of the release cadence and features per update going forward into the future. PRs are required to be squashed before merging. For each point release, we save a branch on master (0.1, 0.2, 0.3, master). Eventually, we'll remove these in favor of higher point releases when dioxus is stabilized. Any live PRs will be merged into the dev branch.
|
|
||||||
|
|
||||||
Until 0.3, Dioxus will be in stealth mode. The goal is to launch with a bountiful feature set and a cohesive API before OSS tears it apart :).
|
|
||||||
|
|
||||||
## v0.1: Bare Necessities
|
|
||||||
|
|
||||||
> Enable ergonomic and performant webapps
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Dioxus Core
|
|
||||||
|
|
||||||
- Lifecycles for components
|
|
||||||
- Internal event system
|
|
||||||
- Diffing
|
|
||||||
- Patching
|
|
||||||
|
|
||||||
Html macro
|
|
||||||
|
|
||||||
- special formatting
|
|
||||||
- closure handlers
|
|
||||||
- child handlers
|
|
||||||
- iterator handlers
|
|
||||||
|
|
||||||
Dioxus web
|
|
||||||
|
|
||||||
- a
|
|
||||||
|
|
||||||
Dioxus CLI
|
|
||||||
|
|
||||||
- Develop
|
|
||||||
- Bundle
|
|
||||||
- Test
|
|
||||||
|
|
||||||
Server-side-rendering
|
|
||||||
|
|
||||||
- Write nodes to string
|
|
||||||
- Integration with tide, Actix, warp
|
|
||||||
|
|
||||||
Dioxus WebView (desktop)
|
|
||||||
|
|
||||||
- One-file setup for desktop apps
|
|
||||||
- Integration with the web browser for rapid development
|
|
||||||
|
|
||||||
## v0.2: Bread and butter
|
|
||||||
|
|
||||||
> Complex apps? CHECK
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
State management
|
|
||||||
|
|
||||||
- Dioxus-Reducer as the blessed redux alternative
|
|
||||||
- Includes thunks and reducers (async dispatches)
|
|
||||||
- Dioxus-DataFlow as the blessed recoil alternative
|
|
||||||
- The hip, new approach for granular state
|
|
||||||
|
|
||||||
Dioxus CLI
|
|
||||||
|
|
||||||
- Visual tool?
|
|
||||||
- Asset bundling service
|
|
||||||
|
|
||||||
Dioxus DevTools integration with the web
|
|
||||||
|
|
||||||
- Basic support for pure liveview/webview
|
|
||||||
|
|
||||||
## v0.3: Superpowers
|
|
||||||
|
|
||||||
> Enable LiveView for fullstack development
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
Dioxus LiveView
|
|
||||||
|
|
||||||
- Custom server built on Actix (or something fast)
|
|
||||||
- Ergonomic builders
|
|
||||||
- Concurrent system built into dioxus core
|
|
||||||
|
|
||||||
Dioxus iOS
|
|
||||||
|
|
||||||
- Initial support via webview
|
|
||||||
- Look into native support based on how Flutter/SwiftUI works
|
|
||||||
|
|
||||||
Dioxus Android
|
|
||||||
|
|
||||||
## v0.4: Community
|
|
||||||
|
|
||||||
> Foster the incoming community
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue