diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
index c4870ee..16c414f 100644
--- a/.github/workflows/rust.yml
+++ b/.github/workflows/rust.yml
@@ -5,7 +5,7 @@ on:
branches:
- main
paths:
- - sdk/**
+ - packages/**
- examples/**
pull_request:
@@ -13,7 +13,7 @@ on:
branches:
- main
paths:
- - sdk/**
+ - packages/**
- examples/**
env:
@@ -42,5 +42,5 @@ jobs:
- run: rustup target add wasm32-unknown-unknown
- run: rustup component add clippy
- uses: actions/checkout@v3
- - run: cargo clippy --package dioxus-sdk --target wasm32-unknown-unknown --tests --features wasm-testing -- -D warnings
- - run: cargo clippy --package dioxus-sdk --tests --features desktop-testing -- -D warnings
+ - run: cargo clippy --workspace --all-targets --exclude *-example --target wasm32-unknown-unknown --tests --all-features -- -D warnings
+ - run: cargo clippy --workspace --all-targets --tests --all-features -- -D warnings
diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml
index 052e890..0ca5b72 100644
--- a/.github/workflows/testing.yml
+++ b/.github/workflows/testing.yml
@@ -6,7 +6,7 @@ on:
branches:
- main
paths:
- - sdk/**
+ - packages/**
- examples/**
pull_request:
@@ -14,7 +14,7 @@ on:
branches:
- main
paths:
- - sdk/**
+ - packages/**
- examples/**
env:
@@ -29,7 +29,7 @@ jobs:
- uses: actions/checkout@v3
- run: rustup target add wasm32-unknown-unknown
- uses: Swatinem/rust-cache@v2
- - run: cargo build --package dioxus-sdk --verbose --target wasm32-unknown-unknown --no-default-features --features wasm-testing
+ - run: cargo build --all-targets --workspace --exclude *-example --verbose --target wasm32-unknown-unknown --all-features
# need to run tests here
desktop:
@@ -39,5 +39,6 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: Swatinem/rust-cache@v2
- - run: cargo build --package dioxus-sdk --verbose --no-default-features --features desktop-testing
- - run: cargo test --package dioxus-sdk --verbose --no-default-features --features desktop-testing
+ - run: cargo build --all-targets --workspace --verbose --all-features
+ - run: cargo test --all-targets --workspace --verbose --all-features
+ - run: cargo test --workspace --verbose --all-features --doc
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 1b32f8e..872127f 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -1,4 +1,6 @@
{
"rust-analyzer.cargo.features": "all",
"rust-analyzer.check.features": "all",
+ "rust-analyzer.check.allTargets": true,
+ //"rust-analyzer.cargo.target": "wasm32-unknown-unknown",
}
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index d88cbaf..a8fab64 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,9 +1,55 @@
[workspace]
-resolver = "2"
-members = ["sdk", "examples/*"]
+resolver = "3"
+members = ["packages/*", "examples/*"]
+
+package.authors = [
+ "Dioxus Labs",
+ "Jonathan Kelley",
+ "DogeDark",
+ "marc2332",
+ "ealmloff",
+]
+package.edition = "2024"
+package.license = "MIT OR Apache-2.0"
+package.homepage = "https://dioxuslabs.com"
+package.repository = "https://github.com/DioxusLabs/sdk/"
[workspace.dependencies]
-dioxus-sdk = { path = "./sdk" }
-dioxus = { version = "0.6.0" }
-dioxus-desktop = { version = "0.6.0" }
-dioxus-signals = { version = "0.6.0" }
+# Workspace
+dioxus-sdk = { path = "packages/sdk" }
+dioxus-time = { path = "packages/time" }
+dioxus-storage = { path = "packages/storage" }
+dioxus-geolocation = { path = "packages/geolocation" }
+dioxus-notification = { path = "packages/notification" }
+dioxus-sync = { path = "packages/sync" }
+dioxus-util = { path = "packages/util" }
+dioxus-window = { path = "packages/window" }
+
+# Dioxus
+dioxus = "0.6.0"
+dioxus-signals = "0.6.0"
+dioxus-desktop = "0.6.0"
+dioxus-config-macro = "0.6.0"
+
+# Deps
+cfg-if = "1.0.0"
+tokio = "1.43.0"
+futures = "0.3.31"
+futures-util = "0.3.31"
+
+serde = "1.0.163"
+wasm-bindgen = "0.2.100"
+web-sys = "0.3.77"
+js-sys = "0.3.77"
+
+[profile]
+
+[profile.wasm-dev]
+inherits = "dev"
+opt-level = 1
+
+[profile.server-dev]
+inherits = "dev"
+
+[profile.android-dev]
+inherits = "dev"
diff --git a/README.md b/README.md
index dd0d3c3..18bd506 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
🧰 Dioxus Development Kit 🚀
-
A platform agnostic library for supercharging your productivity with Dioxus.
+
Cross-platform crates for supercharging your productivity with Dioxus.
@@ -23,23 +23,27 @@
-----
-
This library is still under development. Expect breaking changes!
+
These crates are still under development. Expect breaking changes!
-`dioxus-sdk` is a development kit for Dioxus that provides abstractions for your Dioxus app. Abstractions included are notifications, clipboard, geolocation and storage with more to come!
+`dioxus-sdk` is a development kit for Dioxus that provides cross-platform APIs for your Dioxus app. SDK is organized into many different crates accessible through the `dioxus-sdk` crate with the corresponding feature flags.
-**Features**
-- [x] Geolocation - (Web, Windows)
-- [x] Storage - (Web, Desktop)
-- [x] Clipboard - (Desktop)
-- [x] Notifications - (Desktop)
-- [x] Color Scheme - (Web)
-- [x] Utility Hooks
- - [x] use_channel
- - [x] use_window_size
- - [x] use_interval
- - [x] use_debounce
- - [ ] use_timeout
+## Features
+- `dioxus-storage`
+- `dioxus-geolocation` - Web & Windows
+- `dioxus-notifications` - Desktop
+- `dioxus-window`
+ - [x] Theme - (Web, Windows, Mac)
+ - [x] Window Size
+- `dioxus-time`
+ - [x] Sleep
+ - [x] Intervals
+ - [x] Debounce
+ - [x] Timeouts
+- `dioxus-sync`
+ - [x] Channels
+- `dioxus-util`
+ - [x] `use_root_scroll`
- [ ] Camera
- [ ] WiFi
- [ ] Bluetooth
@@ -47,11 +51,14 @@
Geolocation example:
```rust
-use dioxus_sdk::geolocation::{
+// dioxus-geolocation= { version = "*" }
+use dioxus::prelude::*;
+use dioxus_geolocation::{
init_geolocator, use_geolocation, PowerMode
};
-fn app() -> Element {
+#[component]
+fn App() -> Element {
let geolocator = init_geolocator(PowerMode::High).unwrap();
let coords = use_geolocation();
@@ -69,22 +76,25 @@ fn app() -> Element {
}
```
-## Platform Support
-### Clipboard
-
-On linux you need the x11 library to use the clipboard abstraction:
-```
-sudo apt-get install xorg-dev
-```
-
## Usage
You can add `dioxus-sdk` to your application by adding it to your dependencies.
```toml
[dependencies]
-dioxus-sdk = { version = "0.6", features = [] }
+dioxus-sdk = { version = "0.7", features = [] }
```
+### Dioxus Compatibility
+This table represents the compatibility between this crate and Dioxus versions.
+The crate version supports a Dioxus version up until the next crate version in the table.
+
+E.g. if crate version `0.1` supported Dioxus `0.6` and crate version `0.4` supported Dioxus `0.7`, crate versions `0.1`, `0.2`, and `0.3` would support Dioxus `0.6`.
+
+| Crate Version | Dioxus Version |
+| ------------- | -------------- |
+| 0.7 | 0.6 |
+| 0.5 | 0.5 |
+
## License
This project is dual licensed under the [MIT](./LICENSE-MIT) and [Apache 2.0](./LICENSE-APACHE) licenses.
-Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in `dioxus-sdk` by you, shall be licensed as MIT or Apache 2.0, without any additional terms or conditions.
+Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in `dioxus-sdk` or any of it's crates, by you, shall be licensed as MIT or Apache 2.0, without any additional terms or conditions.
diff --git a/examples/README.md b/examples/README.md
deleted file mode 100644
index 6ac7d1c..0000000
--- a/examples/README.md
+++ /dev/null
@@ -1,16 +0,0 @@
-# Examples
-
-### [`system_theme`](./system_theme/)
-Learn how to use `use_system_theme`.
-
-### [`geolocation`](./geolocation/)
-Learn how to use the `geolocation` abstraction.
-
-### [`channel`](./channel/)
-Learn how to use the `channel` abstraction.
-
-### [`storage`](./storage/)
-Learn how to use the `storage` abstraction.
-
-### [`clipboard`](./clipboard/)
-Learn how to use the `clipboard` abstraction.
diff --git a/examples/channel/Cargo.toml b/examples/channel/Cargo.toml
index 6a9b7bf..c0b4e79 100644
--- a/examples/channel/Cargo.toml
+++ b/examples/channel/Cargo.toml
@@ -1,15 +1,13 @@
[package]
-name = "channel"
+name = "channel-example"
version = "0.1.0"
edition = "2021"
[dependencies]
-dioxus-sdk = { workspace = true, features = ["channel"] }
-dioxus = { workspace = true, features = ["web"] }
+dioxus = { workspace = true }
+dioxus-sync = { workspace = true }
-
-log = "0.4.6"
-
-# WebAssembly Debug
-wasm-logger = "0.2.0"
-console_error_panic_hook = "0.1.7"
+[features]
+default = ["desktop"]
+web = ["dioxus/web"]
+desktop = ["dioxus/desktop"]
\ No newline at end of file
diff --git a/examples/channel/Dioxus.toml b/examples/channel/Dioxus.toml
deleted file mode 100644
index 84136b0..0000000
--- a/examples/channel/Dioxus.toml
+++ /dev/null
@@ -1,42 +0,0 @@
-[application]
-
-# App (Project) Name
-name = "channel"
-
-# Dioxus App Default Platform
-# desktop, web, mobile, ssr
-default_platform = "web"
-
-# `build` & `serve` dist path
-out_dir = "dist"
-
-# resource (public) file folder
-asset_dir = "public"
-
-[web.app]
-
-# HTML title tag content
-title = "dioxus | ⛺"
-
-[web.watcher]
-
-# when watcher trigger, regenerate the `index.html`
-reload_html = true
-
-# which files or dirs will be watcher monitoring
-watch_path = ["src", "public"]
-
-# include `assets` in web platform
-[web.resource]
-
-# CSS style file
-style = []
-
-# Javascript code file
-script = []
-
-[web.resource.dev]
-
-# Javascript code file
-# serve: [dev-server] only
-script = []
diff --git a/examples/channel/README.md b/examples/channel/README.md
index c427972..4b44b2c 100644
--- a/examples/channel/README.md
+++ b/examples/channel/README.md
@@ -1,7 +1,7 @@
# use_channel
-Learn how to use `use_channel`.
+Learn how to use `use_channel` from `dioxus-sync`.
Run:
-```dioxus serve```
\ No newline at end of file
+```dx serve```
\ No newline at end of file
diff --git a/examples/channel/public/favicon.ico b/examples/channel/public/favicon.ico
deleted file mode 100644
index eed0c09..0000000
Binary files a/examples/channel/public/favicon.ico and /dev/null differ
diff --git a/examples/channel/src/main.rs b/examples/channel/src/main.rs
index 9be318d..1d5f2fd 100644
--- a/examples/channel/src/main.rs
+++ b/examples/channel/src/main.rs
@@ -1,21 +1,18 @@
-use dioxus::prelude::*;
-use dioxus_sdk::utils::channel::{use_channel, use_listen_channel};
+use dioxus::{logger::tracing::info, prelude::*};
+use dioxus_sync::channel::{use_channel, use_listen_channel};
fn main() {
- // init debug tool for WebAssembly
- wasm_logger::init(wasm_logger::Config::default());
- console_error_panic_hook::set_once();
-
- launch(app);
+ launch(App);
}
-fn app() -> Element {
+#[component]
+fn App() -> Element {
let channel = use_channel::
(5);
use_listen_channel(&channel, |message| async {
match message {
- Ok(value) => log::info!("Incoming message: {value}"),
- Err(err) => log::info!("Error: {err:?}"),
+ Ok(value) => info!("Incoming message: {value}"),
+ Err(err) => info!("Error: {err:?}"),
}
});
diff --git a/examples/clipboard/Cargo.toml b/examples/clipboard/Cargo.toml
deleted file mode 100644
index 91530c1..0000000
--- a/examples/clipboard/Cargo.toml
+++ /dev/null
@@ -1,8 +0,0 @@
-[package]
-name = "clipboard"
-version = "0.1.0"
-edition = "2021"
-
-[dependencies]
-dioxus-sdk = { workspace = true, features = ["clipboard"] }
-dioxus = { workspace = true, features = ["desktop"] }
diff --git a/examples/clipboard/src/main.rs b/examples/clipboard/src/main.rs
deleted file mode 100644
index 5e06527..0000000
--- a/examples/clipboard/src/main.rs
+++ /dev/null
@@ -1,43 +0,0 @@
-use dioxus::prelude::*;
-use dioxus_sdk::clipboard::use_clipboard;
-
-fn main() {
- launch(app);
-}
-
-fn app() -> Element {
- let mut clipboard = use_clipboard();
- let mut text = use_signal(String::new);
-
- let oninput = move |e: FormEvent| {
- text.set(e.data.value());
- };
-
- let oncopy = move |_| match clipboard.set(text.read().clone()) {
- Ok(_) => println!("Copied to clipboard: {}", text.read()),
- Err(err) => println!("Error on copy: {err:?}"),
- };
-
- let onpaste = move |_| match clipboard.get() {
- Ok(contents) => {
- println!("Pasted from clipboard: {contents}");
- text.set(contents);
- }
- Err(err) => println!("Error on paste: {err:?}"),
- };
-
- rsx!(
- input {
- oninput: oninput,
- value: "{text}"
- }
- button {
- onclick: oncopy,
- "Copy"
- }
- button {
- onclick: onpaste,
- "Paste"
- }
- )
-}
diff --git a/examples/geolocation/Cargo.toml b/examples/geolocation/Cargo.toml
index 53c9f69..ad06396 100644
--- a/examples/geolocation/Cargo.toml
+++ b/examples/geolocation/Cargo.toml
@@ -1,10 +1,14 @@
[package]
-name = "geolocation"
+name = "geolocation-example"
version = "0.1.0"
edition = "2021"
[dependencies]
-dioxus-sdk = { workspace = true, features = ["geolocation"] }
-# You can change from 'desktop' to 'web' as well
-dioxus = { workspace = true, features = ["desktop"] }
+dioxus = { workspace = true }
+dioxus-geolocation = { workspace = true }
+
+[features]
+default = ["desktop"]
+web = ["dioxus/web"]
+desktop = ["dioxus/desktop"]
diff --git a/examples/geolocation/Dioxus.toml b/examples/geolocation/Dioxus.toml
deleted file mode 100644
index 749b197..0000000
--- a/examples/geolocation/Dioxus.toml
+++ /dev/null
@@ -1,42 +0,0 @@
-[application]
-
-# App (Project) Name
-name = "geolocation"
-
-# Dioxus App Default Platform
-# desktop, web, mobile, ssr
-default_platform = "web"
-
-# `build` & `serve` dist path
-out_dir = "dist"
-
-# resource (public) file folder
-asset_dir = "public"
-
-[web.app]
-
-# HTML title tag content
-title = "dioxus | ⛺"
-
-[web.watcher]
-
-# when watcher trigger, regenerate the `index.html`
-reload_html = true
-
-# which files or dirs will be watcher monitoring
-watch_path = ["src", "public"]
-
-# include `assets` in web platform
-[web.resource]
-
-# CSS style file
-style = []
-
-# Javascript code file
-script = []
-
-[web.resource.dev]
-
-# Javascript code file
-# serve: [dev-server] only
-script = []
diff --git a/examples/geolocation/LICENSE b/examples/geolocation/LICENSE
deleted file mode 100644
index bcdd828..0000000
--- a/examples/geolocation/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2022 Dioxus
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/examples/geolocation/index.html b/examples/geolocation/index.html
deleted file mode 100644
index f57330c..0000000
--- a/examples/geolocation/index.html
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/examples/geolocation/public/favicon.ico b/examples/geolocation/public/favicon.ico
deleted file mode 100644
index eed0c09..0000000
Binary files a/examples/geolocation/public/favicon.ico and /dev/null differ
diff --git a/examples/geolocation/src/main.rs b/examples/geolocation/src/main.rs
index 8547f2f..be27cc1 100644
--- a/examples/geolocation/src/main.rs
+++ b/examples/geolocation/src/main.rs
@@ -1,11 +1,12 @@
use dioxus::prelude::*;
-use dioxus_sdk::geolocation::{init_geolocator, use_geolocation, PowerMode};
+use dioxus_geolocation::{init_geolocator, use_geolocation, PowerMode};
fn main() {
- launch(app);
+ launch(App);
}
-fn app() -> Element {
+#[component]
+fn App() -> Element {
let geolocator = init_geolocator(PowerMode::High);
let initial_coords = use_resource(move || async move {
geolocator
diff --git a/examples/scroll/Cargo.toml b/examples/scroll/Cargo.toml
index 6d1af22..79d4819 100644
--- a/examples/scroll/Cargo.toml
+++ b/examples/scroll/Cargo.toml
@@ -1,11 +1,13 @@
[package]
-name = "use_scroll"
+name = "use-scroll-example"
version = "0.1.0"
edition = "2021"
[dependencies]
-dioxus-sdk = { workspace = true, features = ["scroll"] }
-dioxus = { workspace = true }
+dioxus-util.workspace = true
+dioxus.workspace = true
[features]
+default = ["desktop"]
web = ["dioxus/web"]
+desktop = ["dioxus/desktop"]
\ No newline at end of file
diff --git a/examples/scroll/README.md b/examples/scroll/README.md
index f68a3f3..4d9bfa6 100644
--- a/examples/scroll/README.md
+++ b/examples/scroll/README.md
@@ -6,4 +6,9 @@ Learn how to use `use_root_scroll`.
### Run
**Web**
-```dioxus serve --platform web```
\ No newline at end of file
+
+```dx serve --platform web```
+
+**Desktop**
+
+```dx serve --platform desktop```
\ No newline at end of file
diff --git a/examples/scroll/public/favicon.ico b/examples/scroll/public/favicon.ico
deleted file mode 100644
index eed0c09..0000000
Binary files a/examples/scroll/public/favicon.ico and /dev/null differ
diff --git a/examples/scroll/src/main.rs b/examples/scroll/src/main.rs
index 46c1ba9..3e6b58e 100644
--- a/examples/scroll/src/main.rs
+++ b/examples/scroll/src/main.rs
@@ -2,7 +2,7 @@ use dioxus::{
logger::tracing::{info, Level},
prelude::*,
};
-use dioxus_sdk::utils::scroll::use_root_scroll;
+use dioxus_util::scroll::use_root_scroll;
fn main() {
dioxus::logger::init(Level::TRACE).unwrap();
diff --git a/examples/storage/Cargo.toml b/examples/storage/Cargo.toml
index ddd257d..83e8ea6 100644
--- a/examples/storage/Cargo.toml
+++ b/examples/storage/Cargo.toml
@@ -1,13 +1,14 @@
[package]
-name = "storage-desktop"
+name = "storage-example"
version = "0.1.0"
edition = "2021"
[dependencies]
-dioxus-sdk = { workspace = true, features = ["storage"] }
dioxus = { workspace = true, features = ["router"] }
+dioxus-storage = { workspace = true }
[features]
+default = ["desktop"]
web = ["dioxus/web"]
desktop = ["dioxus/desktop"]
fullstack = ["dioxus/fullstack"]
diff --git a/examples/storage/src/main.rs b/examples/storage/src/main.rs
index 45d9dbe..de1af7a 100644
--- a/examples/storage/src/main.rs
+++ b/examples/storage/src/main.rs
@@ -1,12 +1,13 @@
use dioxus::prelude::*;
-use dioxus_sdk::storage::*;
+use dioxus_storage::*;
fn main() {
- dioxus_sdk::storage::set_dir!();
- launch(app);
+ dioxus_storage::set_dir!();
+ launch(App);
}
-fn app() -> Element {
+#[component]
+fn App() -> Element {
rsx! {
Router:: {}
}
@@ -32,7 +33,7 @@ fn Footer() -> Element {
div {
button {
onclick: move |_| {
- let dom = VirtualDom::new(app);
+ let dom = VirtualDom::new(App);
window.new_window(dom, Default::default());
},
"New Window"
diff --git a/examples/system_theme/README.md b/examples/system_theme/README.md
deleted file mode 100644
index f22f9e4..0000000
--- a/examples/system_theme/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# color_scheme
-
-Learn how to use `use_preferred_color_scheme`.
-
-Run:
-
-```dioxus serve```
\ No newline at end of file
diff --git a/examples/system_theme/public/favicon.ico b/examples/system_theme/public/favicon.ico
deleted file mode 100644
index eed0c09..0000000
Binary files a/examples/system_theme/public/favicon.ico and /dev/null differ
diff --git a/examples/system_theme/Cargo.toml b/examples/theme/Cargo.toml
similarity index 64%
rename from examples/system_theme/Cargo.toml
rename to examples/theme/Cargo.toml
index 4fbb6c7..d61a79d 100644
--- a/examples/system_theme/Cargo.toml
+++ b/examples/theme/Cargo.toml
@@ -1,12 +1,13 @@
[package]
-name = "color_scheme"
+name = "theme-example"
version = "0.1.0"
edition = "2021"
[dependencies]
-dioxus-sdk = { workspace = true, features = ["system_theme"] }
dioxus = { workspace = true }
+dioxus-window = { workspace = true }
[features]
+default = ["desktop"]
web = ["dioxus/web"]
desktop = ["dioxus/desktop"]
\ No newline at end of file
diff --git a/examples/theme/README.md b/examples/theme/README.md
new file mode 100644
index 0000000..68c5386
--- /dev/null
+++ b/examples/theme/README.md
@@ -0,0 +1,7 @@
+# color_scheme
+
+Learn how to use the `use_system_theme` hook.
+
+Run:
+
+```dx serve```
\ No newline at end of file
diff --git a/examples/system_theme/src/main.rs b/examples/theme/src/main.rs
similarity index 95%
rename from examples/system_theme/src/main.rs
rename to examples/theme/src/main.rs
index d86b75a..cc7f856 100644
--- a/examples/system_theme/src/main.rs
+++ b/examples/theme/src/main.rs
@@ -1,5 +1,5 @@
use dioxus::prelude::*;
-use dioxus_sdk::theme::use_system_theme;
+use dioxus_window::theme::use_system_theme;
fn main() {
launch(App);
diff --git a/examples/timing/Cargo.toml b/examples/timing/Cargo.toml
index edf3d64..fa3f98e 100644
--- a/examples/timing/Cargo.toml
+++ b/examples/timing/Cargo.toml
@@ -1,13 +1,14 @@
[package]
-name = "timing"
+name = "timing-example"
version = "0.1.0"
edition = "2021"
[dependencies]
-dioxus-sdk = { workspace = true, features = ["timing"] }
dioxus = { workspace = true }
-dioxus-logger = "0.5.1"
+dioxus-time = { workspace = true }
+gloo-timers = { version = "0.3", features = ["futures"] }
[features]
+default = ["desktop"]
web = ["dioxus/web"]
desktop = ["dioxus/desktop"]
diff --git a/examples/timing/Dioxus.toml b/examples/timing/Dioxus.toml
deleted file mode 100644
index 5a45f78..0000000
--- a/examples/timing/Dioxus.toml
+++ /dev/null
@@ -1,42 +0,0 @@
-[application]
-
-# App (Project) Name
-name = "interval"
-
-# Dioxus App Default Platform
-# desktop, web, mobile, ssr
-default_platform = "web"
-
-# `build` & `serve` dist path
-out_dir = "dist"
-
-# resource (public) file folder
-asset_dir = "public"
-
-[web.app]
-
-# HTML title tag content
-title = "dioxus | ⛺"
-
-[web.watcher]
-
-# when watcher trigger, regenerate the `index.html`
-reload_html = true
-
-# which files or dirs will be watcher monitoring
-watch_path = ["src", "public"]
-
-# include `assets` in web platform
-[web.resource]
-
-# CSS style file
-style = []
-
-# Javascript code file
-script = []
-
-[web.resource.dev]
-
-# Javascript code file
-# serve: [dev-server] only
-script = []
diff --git a/examples/timing/README.md b/examples/timing/README.md
index 0d2fe46..67bd269 100644
--- a/examples/timing/README.md
+++ b/examples/timing/README.md
@@ -1,7 +1,7 @@
-# use_interval
+# dioxus-time example
-Learn how to use `use_interval`.
+Learn how to use the `use_interval` and `use_debounce` hooks in `dioxus-time`.
Run:
-```dioxus serve```
\ No newline at end of file
+```dx serve```
\ No newline at end of file
diff --git a/examples/timing/public/favicon.ico b/examples/timing/public/favicon.ico
deleted file mode 100644
index eed0c09..0000000
Binary files a/examples/timing/public/favicon.ico and /dev/null differ
diff --git a/examples/timing/src/main.rs b/examples/timing/src/main.rs
index 2b680fa..303e0a0 100644
--- a/examples/timing/src/main.rs
+++ b/examples/timing/src/main.rs
@@ -1,27 +1,32 @@
-use dioxus::prelude::*;
-use dioxus_logger::tracing::{info, Level};
-use dioxus_sdk::utils::timing::{use_debounce, use_interval};
+use dioxus::{logger::tracing::info, prelude::*};
+use dioxus_time::{use_debounce, use_interval, use_timeout};
use std::time::Duration;
fn main() {
- dioxus_logger::init(Level::INFO).expect("logger failed to init");
- launch(app);
+ launch(App);
}
-fn app() -> Element {
+#[component]
+fn App() -> Element {
let mut count = use_signal(|| 0);
// using `use_interval`, we increment the count by 1 every second.
- use_interval(Duration::from_secs(1), move || {
+ use_interval(Duration::from_secs(1), move |()| {
count += 1;
});
// using `use_debounce`, we reset the counter after 2 seconds since the last button click.
- let mut debounce = use_debounce(Duration::from_millis(2000), move |text| {
+ let mut debounce = use_debounce(Duration::from_secs(2), move |text| {
info!("{text}");
count.set(0);
});
+ // using `use_timeout`, we increase a the counter 2 seconds after every trigger.
+ let mut timeout_count = use_signal(|| 0);
+ let timeout = use_timeout(Duration::from_secs(2), move |()| {
+ timeout_count += 1;
+ });
+
rsx! {
p { "{count}" },
button {
@@ -31,5 +36,9 @@ fn app() -> Element {
},
"Reset the counter! (2 second debounce)"
}
+ button {
+ onclick: move |_| { timeout.action(()); },
+ "Trigger Timeout: {timeout_count}",
+ }
}
}
diff --git a/examples/window_size/Cargo.toml b/examples/window_size/Cargo.toml
index fb13980..4ba3a3e 100644
--- a/examples/window_size/Cargo.toml
+++ b/examples/window_size/Cargo.toml
@@ -1,12 +1,13 @@
[package]
-name = "use_window_size"
+name = "window-size-example"
version = "0.1.0"
edition = "2021"
[dependencies]
-dioxus-sdk = { workspace = true, features = ["window_size"] }
dioxus = { workspace = true }
+dioxus-window = { workspace = true }
[features]
+default = ["desktop"]
web = ["dioxus/web"]
desktop = ["dioxus/desktop"]
diff --git a/examples/window_size/README.md b/examples/window_size/README.md
index 71a1159..203284b 100644
--- a/examples/window_size/README.md
+++ b/examples/window_size/README.md
@@ -6,7 +6,7 @@ Learn how to use `use_window_size`.
### Run
**Desktop**
-```dioxus serve --platform desktop```
+```dx serve --platform desktop```
**Web**
-```dioxus serve --platform web```
\ No newline at end of file
+```dx serve --platform web```
\ No newline at end of file
diff --git a/examples/window_size/public/favicon.ico b/examples/window_size/public/favicon.ico
deleted file mode 100644
index eed0c09..0000000
Binary files a/examples/window_size/public/favicon.ico and /dev/null differ
diff --git a/examples/window_size/src/main.rs b/examples/window_size/src/main.rs
index 76602e8..16854cb 100644
--- a/examples/window_size/src/main.rs
+++ b/examples/window_size/src/main.rs
@@ -1,5 +1,5 @@
use dioxus::prelude::*;
-use dioxus_sdk::utils::window::{get_window_size, use_window_size};
+use dioxus_window::size::{get_window_size, use_window_size};
fn main() {
launch(App);
@@ -7,8 +7,10 @@ fn main() {
#[component]
fn App() -> Element {
- let initial_size = use_signal(get_window_size);
+ let initial_size = use_signal(|| get_window_size().unwrap());
+
let window_size = use_window_size();
+ let window_size = window_size().unwrap();
rsx!(
div {
@@ -19,8 +21,8 @@ fn App() -> Element {
p { "Height: {initial_size().height}" }
h3 { "Current Size" }
- p { "Width: {window_size().width}" }
- p { "Height: {window_size().height}" }
+ p { "Width: {window_size.width}" }
+ p { "Height: {window_size.height}" }
}
)
}
diff --git a/packages/geolocation/Cargo.toml b/packages/geolocation/Cargo.toml
new file mode 100644
index 0000000..b93b4b0
--- /dev/null
+++ b/packages/geolocation/Cargo.toml
@@ -0,0 +1,36 @@
+[package]
+name = "dioxus-geolocation"
+version = "0.1.0-alpha.1"
+
+description = "Geolocation utilities and hooks for Dioxus."
+readme = "./README.md"
+keywords = ["gui", "dioxus", "hooks"]
+categories = ["gui", "wasm"]
+
+edition.workspace = true
+authors.workspace = true
+license.workspace = true
+homepage.workspace = true
+repository.workspace = true
+
+[dependencies]
+dioxus = { workspace = true }
+cfg-if = { workspace = true }
+futures = { workspace = true }
+futures-util = { workspace = true }
+
+[target.'cfg(target_family = "wasm")'.dependencies]
+wasm-bindgen = { workspace = true }
+js-sys = { workspace = true }
+web-sys = { workspace = true, features = [
+ "Window",
+ "Navigator",
+ "Geolocation",
+ "PositionOptions",
+] }
+
+[target.'cfg(windows)'.dependencies]
+windows = { version = "0.48.0", features = [
+ "Foundation",
+ "Devices_Geolocation",
+] }
diff --git a/packages/geolocation/README.md b/packages/geolocation/README.md
new file mode 100644
index 0000000..34c3d0a
--- /dev/null
+++ b/packages/geolocation/README.md
@@ -0,0 +1,53 @@
+# Dioxus Geolocation
+Geolocation utilities and hooks for Dioxus.
+
+### Supports
+- [x] Web
+- [x] Windows
+- [ ] Mac
+- [ ] Linux
+- [ ] Android
+- [ ] iOs
+
+## Usage
+Add `dioxus-geolocation` to your `Cargo.toml`:
+```toml
+[dependencies]
+dioxus-geolocation = "0.1"
+```
+
+Example:
+```rs
+use dioxus::prelude::*;
+use dioxus_geolocation::{
+ init_geolocator, use_geolocation, PowerMode
+};
+
+#[component]
+fn App() -> Element {
+ let geolocator = init_geolocator(PowerMode::High).unwrap();
+ let coords = use_geolocation();
+
+ match coords {
+ Ok(coords) => {
+ rsx!( p { "Latitude: {coords.latitude} | Longitude: {coords.longitude}" } )
+ }
+ Err(Error::NotInitialized) => {
+ rsx!( p { "Initializing..." } )
+ }
+ Err(e) => {
+ rsx!( p { "An error occurred {e}" } )
+ }
+ }
+}
+```
+
+### Dioxus Compatibility
+This table represents the compatibility between this crate and Dioxus versions.
+The crate version supports a Dioxus version up until the next crate version in the table.
+
+E.g. if crate version `0.1` supported Dioxus `0.6` and crate version `0.4` supported Dioxus `0.7`, crate versions `0.1`, `0.2`, and `0.3` would support Dioxus `0.6`.
+
+| Crate Version | Dioxus Version |
+| ------------- | -------------- |
+| 0.1 | 0.6 |
\ No newline at end of file
diff --git a/sdk/src/geolocation/core.rs b/packages/geolocation/src/core.rs
similarity index 100%
rename from sdk/src/geolocation/core.rs
rename to packages/geolocation/src/core.rs
diff --git a/sdk/src/geolocation/mod.rs b/packages/geolocation/src/lib.rs
similarity index 100%
rename from sdk/src/geolocation/mod.rs
rename to packages/geolocation/src/lib.rs
diff --git a/sdk/src/geolocation/platform/mod.rs b/packages/geolocation/src/platform/mod.rs
similarity index 100%
rename from sdk/src/geolocation/platform/mod.rs
rename to packages/geolocation/src/platform/mod.rs
diff --git a/sdk/src/geolocation/platform/wasm.rs b/packages/geolocation/src/platform/wasm.rs
similarity index 97%
rename from sdk/src/geolocation/platform/wasm.rs
rename to packages/geolocation/src/platform/wasm.rs
index ba2c233..e282ef9 100644
--- a/sdk/src/geolocation/platform/wasm.rs
+++ b/packages/geolocation/src/platform/wasm.rs
@@ -1,10 +1,10 @@
use futures::channel::mpsc;
use futures_util::StreamExt;
use std::sync::Arc;
-use wasm_bindgen::{prelude::Closure, JsCast, JsValue};
+use wasm_bindgen::{JsCast, JsValue, prelude::Closure};
use web_sys::PositionOptions;
-use crate::geolocation::{Error, Event, Geocoordinates, PowerMode};
+use crate::{Error, Event, Geocoordinates, PowerMode};
/// Represents the HAL's geolocator.
pub struct Geolocator {
diff --git a/sdk/src/geolocation/platform/windows.rs b/packages/geolocation/src/platform/windows.rs
similarity index 98%
rename from sdk/src/geolocation/platform/windows.rs
rename to packages/geolocation/src/platform/windows.rs
index a218635..830d2e4 100644
--- a/sdk/src/geolocation/platform/windows.rs
+++ b/packages/geolocation/src/platform/windows.rs
@@ -8,7 +8,7 @@ use windows::{
Foundation::TypedEventHandler,
};
-use crate::geolocation::core::{Error, Event, Geocoordinates, PowerMode, Status};
+use crate::core::{Error, Event, Geocoordinates, PowerMode, Status};
/// Represents the HAL's geolocator.
pub struct Geolocator {
diff --git a/sdk/src/geolocation/use_geolocation.rs b/packages/geolocation/src/use_geolocation.rs
similarity index 93%
rename from sdk/src/geolocation/use_geolocation.rs
rename to packages/geolocation/src/use_geolocation.rs
index 7d48c4e..33f0ab9 100644
--- a/sdk/src/geolocation/use_geolocation.rs
+++ b/packages/geolocation/src/use_geolocation.rs
@@ -3,8 +3,8 @@
use super::core::{Error, Event, Geocoordinates, Geolocator, PowerMode, Status};
use dioxus::{
prelude::{
- provide_context, try_consume_context, use_coroutine, use_hook, use_signal, ReadOnlySignal,
- Signal, UnboundedReceiver,
+ ReadOnlySignal, Signal, UnboundedReceiver, provide_context, try_consume_context,
+ use_coroutine, use_hook, use_signal,
},
signals::{Readable, Writable},
};
diff --git a/packages/notification/Cargo.toml b/packages/notification/Cargo.toml
new file mode 100644
index 0000000..74753b3
--- /dev/null
+++ b/packages/notification/Cargo.toml
@@ -0,0 +1,20 @@
+[package]
+name = "dioxus-notification"
+version = "0.1.0-alpha.1"
+
+description = "Send notifications from your Dioxus apps."
+readme = "./README.md"
+keywords = ["gui", "dioxus", "hooks"]
+categories = ["gui", "wasm"]
+
+edition.workspace = true
+authors.workspace = true
+license.workspace = true
+homepage.workspace = true
+repository.workspace = true
+
+[dependencies]
+cfg-if.workspace = true
+
+[target.'cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))'.dependencies]
+notify-rust = "4.11.5"
diff --git a/packages/notification/README.md b/packages/notification/README.md
new file mode 100644
index 0000000..f07f120
--- /dev/null
+++ b/packages/notification/README.md
@@ -0,0 +1,40 @@
+# Dioxus Notification
+Send notifications from your Dioxus apps.
+
+### Supports
+- [x] Windows
+- [x] Mac
+- [x] Linux
+- [ ] Android
+- [ ] iOs
+
+## Usage
+Add `dioxus-notification` to your `Cargo.toml`:
+```toml
+[dependencies]
+dioxus-notification = "0.1"
+```
+
+Example:
+```rs
+use dioxus_notification::Notification;
+
+Notification::new()
+ .app_name("dioxus test".to_string())
+ .summary("hi, this is dioxus test".to_string())
+ .body("lorem ipsum".to_string())
+ .show()
+ .unwrap();
+```
+
+
+
+### Dioxus Compatibility
+This table represents the compatibility between this crate and Dioxus versions.
+The crate version supports a Dioxus version up until the next crate version in the table.
+
+E.g. if crate version `0.1` supported Dioxus `0.6` and crate version `0.4` supported Dioxus `0.7`, crate versions `0.1`, `0.2`, and `0.3` would support Dioxus `0.6`.
+
+| Crate Version | Dioxus Version |
+| ------------- | -------------- |
+| 0.1 | 0.6 |
\ No newline at end of file
diff --git a/packages/notification/src/lib.rs b/packages/notification/src/lib.rs
new file mode 100644
index 0000000..84d9156
--- /dev/null
+++ b/packages/notification/src/lib.rs
@@ -0,0 +1,164 @@
+//! Send desktop notifications.
+//!
+//! This crate only supports desktop targets (Windows, MacOS, & Linux).
+#![deny(missing_docs)]
+
+use std::{
+ error::Error,
+ fmt::{self, Display},
+ path::{Path, PathBuf},
+};
+
+/// Provides a builder API and contains relevant notification info.
+///
+/// # Examples
+///
+/// ```
+/// use dioxus_notification::Notification;
+///
+/// Notification::new()
+/// .app_name("dioxus test".to_string())
+/// .summary("hi, this is dioxus test".to_string())
+/// .body("lorem ipsum??".to_string())
+/// .show()
+/// .unwrap();
+///
+/// ```
+#[derive(Debug, Clone, Default)]
+pub struct Notification {
+ app_name: String,
+ summary: String,
+ body: String,
+ icon_path: PathBuf,
+ timeout: NotificationTimeout,
+}
+
+/// Represents the notification's timeout.
+#[derive(Debug, PartialEq, Clone, Default)]
+pub enum NotificationTimeout {
+ /// Default depends on the target OS.
+ #[default]
+ Default,
+ /// A notification that has to be manually acknowledged.
+ Never,
+ /// A notification that times out after a duration.
+ Duration(std::time::Duration),
+}
+
+cfg_if::cfg_if! {
+ if #[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))] {
+ use notify_rust::Timeout;
+ impl From for Timeout {
+ fn from(value: NotificationTimeout) -> Self {
+ match value {
+ NotificationTimeout::Default => Timeout::Default,
+ NotificationTimeout::Never => Timeout::Never,
+ NotificationTimeout::Duration(dur) => Timeout::Milliseconds(dur.as_millis().try_into().unwrap()),
+ }
+ }
+ }
+ }
+}
+
+impl Notification {
+ /// Creates a new notification with empty/default values.
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ /// Show the final notification.
+ pub fn show(&self) -> Result<(), NotificationError> {
+ self.show_inner()
+ }
+
+ // Unsupported fallback.
+ #[cfg(not(any(target_os = "windows", target_os = "macos", target_os = "linux")))]
+ fn show_inner(&self) -> Result<(), NotificationError> {
+ Err(NotificationError::Unsupported)
+ }
+
+ // notify_rust implementation supporting windows, mac, and linux.
+ #[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
+ fn show_inner(&self) -> Result<(), NotificationError> {
+ let icon_path =
+ self.icon_path
+ .as_os_str()
+ .to_str()
+ .ok_or(NotificationError::FailedToShow(
+ "failed to convert icon path into str".into(),
+ ))?;
+
+ notify_rust::Notification::new()
+ .appname(&self.app_name)
+ .summary(&self.summary)
+ .body(&self.body)
+ .icon(icon_path)
+ .timeout(self.timeout.clone())
+ .show()
+ .map_err(|e| NotificationError::FailedToShow(e.into()))?;
+
+ Ok(())
+ }
+
+ /// Set the application's name for the notification.
+ pub fn app_name(&mut self, value: impl ToString) -> &mut Self {
+ self.app_name = value.to_string();
+ self
+ }
+
+ /// Set the summary content of the notification.
+ pub fn summary(&mut self, value: impl ToString) -> &mut Self {
+ self.summary = value.to_string();
+ self
+ }
+
+ /// Set the body content of the notification.
+ pub fn body(&mut self, value: impl ToString) -> &mut Self {
+ self.body = value.to_string();
+ self
+ }
+
+ /// Set full path to image.
+ ///
+ /// Not supported on MacOS.
+ pub fn icon_path(&mut self, value: impl AsRef) -> &mut Self {
+ self.icon_path = value.as_ref().to_path_buf();
+ self
+ }
+
+ /// Set a timeout for when the notification should hide.
+ pub fn timeout(&mut self, value: NotificationTimeout) -> &mut Self {
+ self.timeout = value;
+ self
+ }
+}
+
+#[test]
+#[cfg(any(target_os = "windows", target_os = "macos", target_os = "linux"))]
+fn test_notification() {
+ Notification::new()
+ .app_name("dioxus test".to_string())
+ .summary("hi, this is dioxus test".to_string())
+ .body("lorem ipsum??".to_string())
+ .show()
+ .unwrap();
+}
+
+/// Represents errors when utilizing the notification abstraction.
+#[derive(Debug)]
+pub enum NotificationError {
+ /// Notification is unsupported on this platform.
+ Unsupported,
+ /// Failure to show a notification.
+ FailedToShow(Box),
+}
+
+impl Error for NotificationError {}
+impl Display for NotificationError {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Self::Unsupported => write!(f, "notification is not supported on this platform"),
+ Self::FailedToShow(err) => write!(f, "failed to show notification: {err}"),
+ }
+ }
+}
diff --git a/packages/sdk/Cargo.toml b/packages/sdk/Cargo.toml
new file mode 100644
index 0000000..d583a11
--- /dev/null
+++ b/packages/sdk/Cargo.toml
@@ -0,0 +1,35 @@
+[package]
+name = "dioxus-sdk"
+version = "0.7.0-alpha.1"
+
+description = "A platform agnostic library for supercharging your productivity with Dioxus."
+readme = "../../README.md"
+keywords = ["gui", "dioxus", "hooks"]
+categories = ["gui", "wasm"]
+
+edition.workspace = true
+authors.workspace = true
+license.workspace = true
+homepage.workspace = true
+repository.workspace = true
+
+[dependencies]
+dioxus-geolocation = { workspace = true, optional = true }
+dioxus-notification = { workspace = true, optional = true }
+dioxus-storage = { workspace = true, optional = true }
+dioxus-sync = { workspace = true, optional = true }
+dioxus-time = { workspace = true, optional = true }
+dioxus-util = { workspace = true, optional = true }
+dioxus-window = { workspace = true, optional = true }
+
+[features]
+geolocation = ["dep:dioxus-geolocation"]
+notification = ["dep:dioxus-notification"]
+storage = ["dep:dioxus-storage"]
+sync = ["dep:dioxus-sync"]
+time = ["dep:dioxus-time"]
+util = ["dep:dioxus-util"]
+window = ["dep:dioxus-window"]
+
+[package.metadata.docs.rs]
+all-features = true
\ No newline at end of file
diff --git a/packages/sdk/src/lib.rs b/packages/sdk/src/lib.rs
new file mode 100644
index 0000000..7b35479
--- /dev/null
+++ b/packages/sdk/src/lib.rs
@@ -0,0 +1,51 @@
+//! # Dioxus SDK
+//! The Dioxus SDK is a group of platform agnostic crates for common apis and functionality.
+//!
+//! This crate, `dioxus-sdk`, acts as an entrypoint to explore the variety of crates in the SDK ecosystem.
+//! Individual crates from the SDK ecosystem can be used directly from `crates.io` or you can enable the
+//! corresponding feature for a crate here.
+//!
+//! SDK is growing, and not all functionality supports every platform. Platform support will be documented in
+//! each crate, and in the majority of cases a runtime `Err(Unsupported)` will be returned if you target an unsupported platform.
+//!
+//! ## Available Crates
+//! Below is a table of the crates in our ecosystem, a short description, and their corresponding feature flag.
+//!
+//! | Crate | Description | Feature |
+//! | ------------------------- | ------------------------------------- | ----------------- |
+//! | [`dioxus-geolocation`] | Access user location services. | `geolocation` |
+//! | [`dioxus-storage`] | Store local and persistent data. | `storage` |
+//! | [`dioxus-time`] | Common timing utilities. | `time` |
+//! | [`dioxus-window`] | Common window utilities. | `window` |
+//! | [`dioxus-notification`] | Send notifications. | `notification` |
+//! | [`dioxus-sync`] | Synchronization primities for Dioxus. | `sync` |
+//! | [`dioxus-util`] | Misc utilities for Dioxus. | `util` |
+//!
+//! [`dioxus-geolocation`]: https://crates.io/crates/dioxus-geolocation
+//! [`dioxus-storage`]: https://crates.io/crates/dioxus-storage
+//! [`dioxus-time`]: https://crates.io/crates/dioxus-time
+//! [`dioxus-window`]: https://crates.io/crates/dioxus-window
+//! [`dioxus-notification`]: https://crates.io/crates/dioxus-notification
+//! [`dioxus-sync`]: https://crates.io/crates/dioxus-sync
+//! [`dioxus-util`]: https://crates.io/crates/dioxus-util
+
+#[cfg(feature = "geolocation")]
+pub use dioxus_geolocation as geolocation;
+
+#[cfg(feature = "notification")]
+pub use dioxus_notification as notification;
+
+#[cfg(feature = "storage")]
+pub use dioxus_storage as storage;
+
+#[cfg(feature = "sync")]
+pub use dioxus_sync as sync;
+
+#[cfg(feature = "time")]
+pub use dioxus_time as time;
+
+#[cfg(feature = "util")]
+pub use dioxus_util as util;
+
+#[cfg(feature = "window")]
+pub use dioxus_window as window;
diff --git a/packages/storage/Cargo.toml b/packages/storage/Cargo.toml
new file mode 100644
index 0000000..bc35209
--- /dev/null
+++ b/packages/storage/Cargo.toml
@@ -0,0 +1,34 @@
+[package]
+name = "dioxus-storage"
+version = "0.1.0-alpha.1"
+
+description = "Local and persistent storage utilities for Dioxus."
+readme = "./README.md"
+keywords = ["gui", "dioxus", "hooks"]
+categories = ["gui", "wasm"]
+
+edition.workspace = true
+authors.workspace = true
+license.workspace = true
+homepage.workspace = true
+repository.workspace = true
+
+[dependencies]
+dioxus = { workspace = true }
+tokio = { workspace = true, features = ["sync"] }
+futures-util = { workspace = true }
+cfg-if = { workspace = true }
+
+rustc-hash = "1.1.0"
+ciborium = "0.2.2"
+once_cell = "1.17.0"
+dioxus-signals = { workspace = true, features = ["serialize"] }
+serde.workspace = true
+yazi = "0.1.4"
+
+[target.'cfg(not(target_family = "wasm"))'.dependencies]
+directories = "4.0.1"
+
+[target.'cfg(target_family = "wasm")'.dependencies]
+web-sys = { workspace = true, features = ["Window", "Storage", "StorageEvent"] }
+wasm-bindgen = { workspace = true }
diff --git a/packages/storage/README.md b/packages/storage/README.md
new file mode 100644
index 0000000..57201ee
--- /dev/null
+++ b/packages/storage/README.md
@@ -0,0 +1,47 @@
+# Dioxus Storage
+Local and persistent storage utilities for Dioxus.
+
+### Features:
+- [x] Local Storage
+- [x] Persistent Storage
+
+## Usage
+Add `dioxus-storage` to your `Cargo.toml`:
+```toml
+[dependencies]
+dioxus-storage = "0.1"
+```
+
+Example:
+```rs
+use dioxus_storage::use_persistent;
+use dioxus::prelude::*;
+
+#[component]
+fn App() -> Element {
+ let mut num = use_persistent("count", || 0);
+ rsx! {
+ div {
+ button {
+ onclick: move |_| {
+ *num.write() += 1;
+ },
+ "Increment"
+ }
+ div {
+ "{*num.read()}"
+ }
+ }
+ }
+}
+```
+
+### Dioxus Compatibility
+This table represents the compatibility between this crate and Dioxus versions.
+The crate version supports a Dioxus version up until the next crate version in the table.
+
+E.g. if crate version `0.1` supported Dioxus `0.6` and crate version `0.4` supported Dioxus `0.7`, crate versions `0.1`, `0.2`, and `0.3` would support Dioxus `0.6`.
+
+| Crate Version | Dioxus Version |
+| ------------- | -------------- |
+| 0.1 | 0.6 |
\ No newline at end of file
diff --git a/sdk/src/storage/client_storage/fs.rs b/packages/storage/src/client_storage/fs.rs
similarity index 93%
rename from sdk/src/storage/client_storage/fs.rs
rename to packages/storage/src/client_storage/fs.rs
index 9d2dde5..f7fd110 100644
--- a/sdk/src/storage/client_storage/fs.rs
+++ b/packages/storage/src/client_storage/fs.rs
@@ -1,12 +1,13 @@
-use crate::storage::{StorageChannelPayload, StorageSubscription};
-use serde::de::DeserializeOwned;
+use crate::{StorageChannelPayload, StorageSubscription};
+use dioxus::logger::tracing::trace;
use serde::Serialize;
+use serde::de::DeserializeOwned;
use std::collections::HashMap;
use std::io::Write;
use std::sync::{OnceLock, RwLock};
-use tokio::sync::watch::{channel, Receiver};
+use tokio::sync::watch::{Receiver, channel};
-use crate::storage::{serde_to_string, try_serde_from_string, StorageBacking, StorageSubscriber};
+use crate::{StorageBacking, StorageSubscriber, serde_to_string, try_serde_from_string};
#[doc(hidden)]
/// Sets the directory where the storage files are located.
@@ -107,7 +108,7 @@ impl StorageSubscriber for LocalStorage {
}
fn unsubscribe(key: &::Key) {
- tracing::trace!("Unsubscribing from \"{}\"", key);
+ trace!("Unsubscribing from \"{}\"", key);
// Fail silently if unsubscribe is called but the subscriptions map isn't initialized yet.
if let Some(subscriptions) = SUBSCRIPTIONS.get() {
@@ -115,7 +116,7 @@ impl StorageSubscriber for LocalStorage {
// If the subscription exists, remove it from the subscriptions map.
if read_binding.contains_key(key) {
- tracing::trace!("Found entry for \"{}\"", key);
+ trace!("Found entry for \"{}\"", key);
drop(read_binding);
subscriptions.write().unwrap().remove(key);
}
diff --git a/sdk/src/storage/client_storage/memory.rs b/packages/storage/src/client_storage/memory.rs
similarity index 98%
rename from sdk/src/storage/client_storage/memory.rs
rename to packages/storage/src/client_storage/memory.rs
index 195007f..d0433ba 100644
--- a/sdk/src/storage/client_storage/memory.rs
+++ b/packages/storage/src/client_storage/memory.rs
@@ -5,7 +5,7 @@ use std::ops::{Deref, DerefMut};
use std::rc::Rc;
use std::sync::Arc;
-use crate::storage::StorageBacking;
+use crate::StorageBacking;
#[derive(Clone)]
pub struct SessionStorage;
diff --git a/sdk/src/storage/client_storage/mod.rs b/packages/storage/src/client_storage/mod.rs
similarity index 78%
rename from sdk/src/storage/client_storage/mod.rs
rename to packages/storage/src/client_storage/mod.rs
index 32f18e0..3706c9d 100644
--- a/sdk/src/storage/client_storage/mod.rs
+++ b/packages/storage/src/client_storage/mod.rs
@@ -2,7 +2,7 @@
/// Set the directory where the storage files are located on non-wasm targets.
///
/// ```rust
-/// use dioxus_sdk::set_dir;
+/// use dioxus_storage::set_dir;
///
/// fn main(){
/// // set the directory to the default location
@@ -10,7 +10,7 @@
/// }
/// ```
/// ```rust
-/// use dioxus_sdk::set_dir;
+/// use dioxus_storage::set_dir;
///
/// fn main(){
/// // set the directory to a custom location
@@ -21,14 +21,13 @@
macro_rules! set_dir {
() => {
#[cfg(not(target_family = "wasm"))]
- $crate::storage::set_dir_name(env!("CARGO_PKG_NAME"))
+ $crate::set_dir_name(env!("CARGO_PKG_NAME"))
};
($path: literal) => {
#[cfg(not(target_family = "wasm"))]
- $crate::storage::set_directory(std::path::PathBuf::from($path))
+ $crate::set_directory(std::path::PathBuf::from($path))
};
}
-pub use set_dir;
cfg_if::cfg_if! {
if #[cfg(target_family = "wasm")] {
diff --git a/sdk/src/storage/client_storage/web.rs b/packages/storage/src/client_storage/web.rs
similarity index 87%
rename from sdk/src/storage/client_storage/web.rs
rename to packages/storage/src/client_storage/web.rs
index b42fec7..b0b224b 100644
--- a/sdk/src/storage/client_storage/web.rs
+++ b/packages/storage/src/client_storage/web.rs
@@ -3,16 +3,17 @@ use std::{
sync::{Arc, RwLock},
};
+use dioxus::logger::tracing::{error, trace};
use once_cell::sync::Lazy;
-use serde::{de::DeserializeOwned, Serialize};
-use tokio::sync::watch::{channel, Receiver};
-use wasm_bindgen::prelude::Closure;
+use serde::{Serialize, de::DeserializeOwned};
+use tokio::sync::watch::{Receiver, channel};
use wasm_bindgen::JsCast;
-use web_sys::{window, Storage};
+use wasm_bindgen::prelude::Closure;
+use web_sys::{Storage, window};
-use crate::storage::{
- serde_to_string, try_serde_from_string, StorageBacking, StorageChannelPayload,
- StorageSubscriber, StorageSubscription,
+use crate::{
+ StorageBacking, StorageChannelPayload, StorageSubscriber, StorageSubscription, serde_to_string,
+ try_serde_from_string,
};
#[derive(Clone)]
@@ -65,20 +66,20 @@ impl StorageSubscriber for LocalStorage {
static SUBSCRIPTIONS: Lazy>>> = Lazy::new(|| {
// Create a closure that will be called when a storage event occurs.
let closure = Closure::wrap(Box::new(move |e: web_sys::StorageEvent| {
- tracing::trace!("Storage event: {:?}", e);
+ trace!("Storage event: {:?}", e);
let key: String = e.key().unwrap();
let read_binding = SUBSCRIPTIONS.read().unwrap();
if let Some(subscription) = read_binding.get(&key) {
if subscription.tx.is_closed() {
- tracing::trace!("Channel is closed, removing subscription for \"{}\"", key);
+ trace!("Channel is closed, removing subscription for \"{}\"", key);
drop(read_binding);
SUBSCRIPTIONS.write().unwrap().remove(&key);
return;
}
// Call the getter for the given entry and send the value to said entry's channel.
match subscription.get_and_send() {
- Ok(_) => tracing::trace!("Sent storage event"),
- Err(err) => tracing::error!("Error sending storage event: {:?}", err.to_string()),
+ Ok(_) => trace!("Sent storage event"),
+ Err(err) => error!("Error sending storage event: {:?}", err.to_string()),
}
}
}) as Box);
diff --git a/sdk/src/storage/mod.rs b/packages/storage/src/lib.rs
similarity index 97%
rename from sdk/src/storage/mod.rs
rename to packages/storage/src/lib.rs
index f2bb1ea..89881f0 100644
--- a/sdk/src/storage/mod.rs
+++ b/packages/storage/src/lib.rs
@@ -4,10 +4,11 @@
//!
//! ## Usage
//! ```rust
-//! use dioxus_sdk::storage::use_persistent;
+//! use dioxus_storage::use_persistent;
//! use dioxus::prelude::*;
//!
-//! fn app() -> Element {
+//! #[component]
+//! fn App() -> Element {
//! let mut num = use_persistent("count", || 0);
//! rsx! {
//! div {
@@ -29,6 +30,7 @@ mod client_storage;
mod persistence;
pub use client_storage::{LocalStorage, SessionStorage};
+use dioxus::logger::tracing::trace;
use futures_util::stream::StreamExt;
pub use persistence::{
new_persistent, new_singleton_persistent, use_persistent, use_singleton_persistent,
@@ -37,7 +39,7 @@ use std::cell::RefCell;
use std::rc::Rc;
use dioxus::prelude::*;
-use serde::{de::DeserializeOwned, Serialize};
+use serde::{Serialize, de::DeserializeOwned};
use std::any::Any;
use std::fmt::{Debug, Display};
use std::ops::{Deref, DerefMut};
@@ -45,7 +47,6 @@ use std::sync::Arc;
use tokio::sync::watch::error::SendError;
use tokio::sync::watch::{Receiver, Sender};
-pub use client_storage::set_dir;
#[cfg(not(target_family = "wasm"))]
pub use client_storage::{set_dir_name, set_directory};
@@ -56,7 +57,7 @@ pub use client_storage::{set_dir_name, set_directory};
/// ## Usage
///
/// ```rust
-/// use dioxus_sdk::storage::{use_storage, StorageBacking};
+/// use dioxus_storage::{use_storage, StorageBacking};
/// use dioxus::prelude::*;
/// use dioxus_signals::Signal;
///
@@ -86,6 +87,7 @@ enum StorageMode {
impl StorageMode {
// Get the active mode
+ #[allow(unreachable_code)]
const fn current() -> Self {
server_only! {
return StorageMode::Server;
@@ -106,7 +108,7 @@ impl StorageMode {
/// ## Usage
///
/// ```rust
-/// use dioxus_sdk::storage::{new_storage, StorageBacking};
+/// use dioxus_storage::{new_storage, StorageBacking};
/// use dioxus::prelude::*;
/// use dioxus_signals::Signal;
///
@@ -282,7 +284,7 @@ pub trait StorageEntryTrait:
let (rc, mut reactive_context) = ReactiveContext::new();
rc.run_in(|| {
if old.borrow().as_ref() != Some(&*data.read()) {
- tracing::trace!("Saving to storage");
+ trace!("Saving to storage");
entry_clone.save();
old.replace(Some(data()));
}
@@ -586,10 +588,7 @@ pub(crate) fn try_serde_from_string(value: &str) -> Option<
}
match yazi::decompress(&bytes, yazi::Format::Zlib) {
- Ok((decompressed, _)) => match ciborium::from_reader(std::io::Cursor::new(decompressed)) {
- Ok(v) => Some(v),
- Err(_) => None,
- },
+ Ok((decompressed, _)) => ciborium::from_reader(std::io::Cursor::new(decompressed)).ok(),
Err(_) => None,
}
}
diff --git a/sdk/src/storage/persistence.rs b/packages/storage/src/persistence.rs
similarity index 96%
rename from sdk/src/storage/persistence.rs
rename to packages/storage/src/persistence.rs
index db21872..64ee5f2 100644
--- a/sdk/src/storage/persistence.rs
+++ b/packages/storage/src/persistence.rs
@@ -1,9 +1,9 @@
-use crate::storage::SessionStorage;
-use crate::storage::{new_storage_entry, use_hydrate_storage};
+use crate::SessionStorage;
+use crate::{new_storage_entry, use_hydrate_storage};
use dioxus::prelude::*;
use dioxus_signals::Signal;
-use serde::de::DeserializeOwned;
use serde::Serialize;
+use serde::de::DeserializeOwned;
use super::StorageEntryTrait;
diff --git a/packages/sync/Cargo.toml b/packages/sync/Cargo.toml
new file mode 100644
index 0000000..abbbc55
--- /dev/null
+++ b/packages/sync/Cargo.toml
@@ -0,0 +1,23 @@
+[package]
+name = "dioxus-sync"
+version = "0.1.0-alpha.1"
+
+description = "Synchronization primitives for your Dioxus app."
+readme = "./README.md"
+keywords = ["gui", "dioxus", "hooks"]
+categories = ["gui", "wasm"]
+
+edition.workspace = true
+authors.workspace = true
+license.workspace = true
+homepage.workspace = true
+repository.workspace = true
+
+[dependencies]
+dioxus = { workspace = true }
+
+uuid = { version = "1.3.2", features = ["v4"] }
+async-broadcast = "0.5.1"
+
+[target.'cfg(target_family = "wasm")'.dependencies]
+uuid = { version = "1.3.2", features = ["v4", "js"] }
diff --git a/packages/sync/README.md b/packages/sync/README.md
new file mode 100644
index 0000000..1c27954
--- /dev/null
+++ b/packages/sync/README.md
@@ -0,0 +1,22 @@
+# Dioxus Sync
+Synchronization primitives for your Dioxus app.
+
+### Features:
+- [x] `channel`
+
+## Usage
+Add `dioxus-sync` to your `Cargo.toml`:
+```toml
+[dependencies]
+dioxus-sync = "0.1"
+```
+
+### Dioxus Compatibility
+This table represents the compatibility between this crate and Dioxus versions.
+The crate version supports a Dioxus version up until the next crate version in the table.
+
+E.g. if crate version `0.1` supported Dioxus `0.6` and crate version `0.4` supported Dioxus `0.7`, crate versions `0.1`, `0.2`, and `0.3` would support Dioxus `0.6`.
+
+| Crate Version | Dioxus Version |
+| ------------- | -------------- |
+| 0.1 | 0.6 |
\ No newline at end of file
diff --git a/packages/sync/src/channel/mod.rs b/packages/sync/src/channel/mod.rs
new file mode 100644
index 0000000..86ffc3e
--- /dev/null
+++ b/packages/sync/src/channel/mod.rs
@@ -0,0 +1,5 @@
+mod use_channel;
+mod use_listen_channel;
+
+pub use use_channel::{UseChannel, use_channel};
+pub use use_listen_channel::{UseListenChannelError, use_listen_channel};
diff --git a/sdk/src/utils/channel/use_channel.rs b/packages/sync/src/channel/use_channel.rs
similarity index 94%
rename from sdk/src/utils/channel/use_channel.rs
rename to packages/sync/src/channel/use_channel.rs
index 6b8677b..dc3210f 100644
--- a/sdk/src/utils/channel/use_channel.rs
+++ b/packages/sync/src/channel/use_channel.rs
@@ -1,4 +1,4 @@
-use async_broadcast::{broadcast, InactiveReceiver, Receiver, SendError, Sender, TrySendError};
+use async_broadcast::{InactiveReceiver, Receiver, SendError, Sender, TrySendError, broadcast};
use dioxus::prelude::*;
use uuid::Uuid;
diff --git a/sdk/src/utils/channel/use_listen_channel.rs b/packages/sync/src/channel/use_listen_channel.rs
similarity index 100%
rename from sdk/src/utils/channel/use_listen_channel.rs
rename to packages/sync/src/channel/use_listen_channel.rs
diff --git a/packages/sync/src/lib.rs b/packages/sync/src/lib.rs
new file mode 100644
index 0000000..ff02972
--- /dev/null
+++ b/packages/sync/src/lib.rs
@@ -0,0 +1 @@
+pub mod channel;
diff --git a/packages/time/Cargo.toml b/packages/time/Cargo.toml
new file mode 100644
index 0000000..6008097
--- /dev/null
+++ b/packages/time/Cargo.toml
@@ -0,0 +1,24 @@
+[package]
+name = "dioxus-time"
+version = "0.1.0-alpha.1"
+
+description = "Timing utilities and hooks for Dioxus."
+readme = "./README.md"
+keywords = ["gui", "dioxus", "hooks"]
+categories = ["gui", "wasm"]
+
+edition.workspace = true
+authors.workspace = true
+license.workspace = true
+homepage.workspace = true
+repository.workspace = true
+
+[dependencies]
+dioxus = { workspace = true }
+futures = { workspace = true }
+
+[target.'cfg(not(target_family = "wasm"))'.dependencies]
+tokio = { workspace = true, features = ["time"]}
+
+[target.'cfg(target_family = "wasm")'.dependencies]
+gloo-timers = { version = "0.3.0", features = ["futures"] }
\ No newline at end of file
diff --git a/packages/time/README.md b/packages/time/README.md
new file mode 100644
index 0000000..23e71c9
--- /dev/null
+++ b/packages/time/README.md
@@ -0,0 +1,61 @@
+# Dioxus Time
+Timing utilities and hooks for Dioxus.
+
+### Features:
+- [x] Intervals
+- [x] Debounces
+- [ ] Timeouts
+
+## Usage
+Add `dioxus-time` to your `Cargo.toml`:
+```toml
+[dependencies]
+dioxus-time = "0.1"
+```
+
+Example:
+```rs
+use dioxus::{logger::tracing::info, prelude::*};
+use dioxus_time::{use_debounce, use_interval};
+use std::time::Duration;
+
+fn main() {
+ launch(App);
+}
+
+#[component]
+fn App() -> Element {
+ let mut count = use_signal(|| 0);
+
+ // Increment count every second.
+ use_interval(Duration::from_secs(1), move || count += 1);
+
+ // Reset count after 2 seconds of the latest action call.
+ let mut debounce = use_debounce(Duration::from_millis(2000), move |text| {
+ info!("{text}");
+ count.set(0);
+ });
+
+ rsx! {
+ p { "{count}" },
+ button {
+ // Trigger the debounce.
+ onclick: move |_| debounce.action("button was clicked"),
+ "Reset the counter! (2 second debounce)"
+ }
+ }
+}
+
+```
+
+
+
+### Dioxus Compatibility
+This table represents the compatibility between this crate and Dioxus versions.
+The crate version supports a Dioxus version up until the next crate version in the table.
+
+E.g. if crate version `0.1` supported Dioxus `0.6` and crate version `0.4` supported Dioxus `0.7`, crate versions `0.1`, `0.2`, and `0.3` would support Dioxus `0.6`.
+
+| Crate Version | Dioxus Version |
+| ------------- | -------------- |
+| 0.1 | 0.6 |
\ No newline at end of file
diff --git a/packages/time/src/debounce.rs b/packages/time/src/debounce.rs
new file mode 100644
index 0000000..1e2ed66
--- /dev/null
+++ b/packages/time/src/debounce.rs
@@ -0,0 +1,128 @@
+use crate::{TimeoutHandle, UseTimeout, use_timeout};
+use dioxus::{
+ dioxus_core::SpawnIfAsync,
+ hooks::use_signal,
+ signals::{Signal, Writable},
+};
+use std::time::Duration;
+
+/// The interface for calling a debounce.
+///
+/// See [`use_debounce`] for more information.
+#[derive(Clone, Copy, PartialEq)]
+pub struct UseDebounce {
+ current_handle: Signal