diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 00000000..2e89c5d1 --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,49 @@ +name: check examples + +on: + push: + branches: + - main + paths: + - /** + - preview/**/*.rs + - preview/**/Cargo.toml + - primitives/**/*.rs + - primitives/**/Cargo.toml + - .github/** + - Cargo.toml + + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: + - main + paths: + - /** + - preview/**/*.rs + - preview/**/Cargo.toml + - primitives/**/*.rs + - primitives/**/Cargo.toml + - .github/** + - Cargo.toml + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + check: + runs-on: ubuntu-latest + steps: + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev + version: 1.0 + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@stable + - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + cache-on-failure: "false" + cache-directories: "target/dx" + - name: Check + run: cargo check --workspace --all-features diff --git a/.github/workflows/gh-pages.yml b/.github/workflows/gh-pages.yml new file mode 100644 index 00000000..e70f0a11 --- /dev/null +++ b/.github/workflows/gh-pages.yml @@ -0,0 +1,48 @@ +name: github pages + +on: + push: + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + build-deploy: + runs-on: ubuntu-latest + env: + CARGO_INCREMENTAL: 1 + steps: + - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev + version: 1.0 + - name: Install Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + targets: x86_64-unknown-linux-gnu,wasm32-unknown-unknown + - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + cache-on-failure: "false" + - uses: cargo-bins/cargo-binstall@main + - name: Install CLI + run: cargo install dioxus-cli --git https://github.com/ealmloff/dioxus --branch fix-bundle + - name: Build + run: cd preview && dx build --platform web --release + - name: Copy output + run: cp -r target/dx/preview/release/web/public docs + - name: Add gh pages 404 + run: cp docs/index.html docs/404.html + - name: Deploy 🚀 + uses: JamesIves/github-pages-deploy-action@v4.2.3 + with: + branch: gh-pages # The branch the action should deploy to. + folder: docs # The folder the action should deploy. + target-folder: . + clean: true + single-commit: true diff --git a/.github/workflows/preview.yml b/.github/workflows/preview.yml new file mode 100644 index 00000000..f5dc6269 --- /dev/null +++ b/.github/workflows/preview.yml @@ -0,0 +1,54 @@ +name: Deploy PR previews + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + branches: + - main + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + +jobs: + deploy-preview: + runs-on: ubuntu-latest + env: + CARGO_INCREMENTAL: 1 + steps: + - uses: actions/checkout@v4 + - uses: awalsh128/cache-apt-pkgs-action@latest + with: + packages: libwebkit2gtk-4.1-dev libgtk-3-dev libayatana-appindicator3-dev libxdo-dev + version: 1.0 + - name: Install Rust + uses: dtolnay/rust-toolchain@master + with: + toolchain: stable + targets: x86_64-unknown-linux-gnu,wasm32-unknown-unknown + - uses: Swatinem/rust-cache@v2 + with: + cache-all-crates: "true" + cache-on-failure: "false" + - uses: cargo-bins/cargo-binstall@main + - name: Install CLI + run: cargo install dioxus-cli --git https://github.com/ealmloff/dioxus --branch fix-bundle + - name: Set base path + run: | + echo "[application] + name = \"Dioxus Preview\" + version = \"0.1.0\" + + [web.app] + base_path = \"components/pr-preview/pr-${{ github.event.pull_request.number }}/\"" > preview/Dioxus.toml + - name: Build + run: cd preview && dx build --platform web --release + - name: Copy output + run: cp -r target/dx/preview/release/web/public docs + - name: Add gh pages 404 + run: cp docs/index.html docs/404.html + - name: Deploy preview + uses: rossjrw/pr-preview-action@v1 + with: + preview-branch: gh-pages # The branch the action should deploy to. + source-dir: docs # The folder the action should deploy. diff --git a/Cargo.lock b/Cargo.lock index a3411a95..a08f2776 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -26,16 +26,38 @@ dependencies = [ "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "ashpd" -version = "0.8.1" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd884d7c72877a94102c3715f3b1cd09ff4fac28221add3e57cfbe25c236d093" +checksum = "6cbdf310d77fd3aaee6ea2093db7011dc2d35d2eb3481e5607f1f8d942ed99df" dependencies = [ "enumflags2", "futures-channel", "futures-util", - "rand 0.8.5", + "rand 0.9.1", + "raw-window-handle 0.6.2", "serde", "serde_repr", "tokio", @@ -43,6 +65,12 @@ dependencies = [ "zbus", ] +[[package]] +name = "askama_escape" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" + [[package]] name = "async-broadcast" version = "0.7.2" @@ -55,67 +83,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "async-channel" -version = "2.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" -dependencies = [ - "concurrent-queue", - "event-listener-strategy", - "futures-core", - "pin-project-lite", -] - -[[package]] -name = "async-io" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" -dependencies = [ - "async-lock", - "cfg-if", - "concurrent-queue", - "futures-io", - "futures-lite", - "parking", - "polling", - "rustix 0.38.44", - "slab", - "tracing", - "windows-sys 0.59.0", -] - -[[package]] -name = "async-lock" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" -dependencies = [ - "event-listener", - "event-listener-strategy", - "pin-project-lite", -] - -[[package]] -name = "async-process" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" -dependencies = [ - "async-channel", - "async-io", - "async-lock", - "async-signal", - "async-task", - "blocking", - "cfg-if", - "event-listener", - "futures-lite", - "rustix 0.38.44", - "tracing", -] - [[package]] name = "async-recursion" version = "1.1.1" @@ -124,33 +91,9 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", -] - -[[package]] -name = "async-signal" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" -dependencies = [ - "async-io", - "async-lock", - "atomic-waker", - "cfg-if", - "futures-core", - "futures-io", - "rustix 0.38.44", - "signal-hook-registry", - "slab", - "windows-sys 0.59.0", + "syn 2.0.101", ] -[[package]] -name = "async-task" -version = "4.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" - [[package]] name = "async-trait" version = "0.1.88" @@ -159,7 +102,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -197,11 +140,69 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" +[[package]] +name = "axum" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" +dependencies = [ + "axum-core", + "base64", + "bytes", + "form_urlencoded", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa 1.0.15", + "matchit", + "memchr", + "mime", + "multer", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sha1", + "sync_wrapper", + "tokio", + "tokio-tungstenite", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "backtrace" -version = "0.3.74" +version = "0.3.75" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" dependencies = [ "addr2line", "cfg-if", @@ -212,12 +213,27 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "base16" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d27c3610c36aee21ce8ac510e6224498de4228ad772a171ed65643a24693a5a8" + [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -226,9 +242,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.9.0" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" dependencies = [ "serde", ] @@ -250,33 +266,11 @@ dependencies = [ [[package]] name = "block2" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c132eebf10f5cad5289222520a4a058514204aed6d791f1cf4fe8088b82d15f" -dependencies = [ - "objc2 0.5.2", -] - -[[package]] -name = "block2" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d59b4c170e16f0405a2e95aff44432a0d41aa97675f3d52623effe95792a037" -dependencies = [ - "objc2 0.6.0", -] - -[[package]] -name = "blocking" -version = "1.6.1" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +checksum = "340d2f0bdb2a43c1d3cd40513185b2bd7def0aa1052f956455114bc98f82dcf2" dependencies = [ - "async-channel", - "async-task", - "futures-io", - "futures-lite", - "piper", + "objc2", ] [[package]] @@ -303,7 +297,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cairo-sys-rs", "glib", "libc", @@ -324,9 +318,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.16" +version = "1.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951" dependencies = [ "shlex", ] @@ -364,6 +358,26 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chrono" +version = "0.4.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "wasm-bindgen", + "windows-link", +] + [[package]] name = "ciborium" version = "0.2.2" @@ -393,61 +407,30 @@ dependencies = [ [[package]] name = "cocoa" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" -dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa-foundation 0.1.2", - "core-foundation 0.9.4", - "core-graphics 0.23.2", - "foreign-types", - "libc", - "objc", -] - -[[package]] -name = "cocoa" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f79398230a6e2c08f5c9760610eb6924b52aa9e7950a619602baba59dcbbdbb2" -dependencies = [ - "bitflags 2.9.0", - "block", - "cocoa-foundation 0.2.0", - "core-foundation 0.10.0", - "core-graphics 0.24.0", - "foreign-types", - "libc", - "objc", -] - -[[package]] -name = "cocoa-foundation" -version = "0.1.2" +version = "0.26.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +checksum = "ad36507aeb7e16159dfe68db81ccc27571c3ccd4b76fb2fb72fc59e7a4b1b64c" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.1", "block", - "core-foundation 0.9.4", - "core-graphics-types 0.1.3", + "cocoa-foundation", + "core-foundation 0.10.1", + "core-graphics", + "foreign-types 0.5.0", "libc", "objc", ] [[package]] name = "cocoa-foundation" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e14045fb83be07b5acf1c0884b2180461635b433455fa35d1cd6f17f1450679d" +checksum = "81411967c50ee9a1fc11365f8c585f863a22a9697c89239c452292c40ba79b0d" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "block", - "core-foundation 0.10.0", - "core-graphics-types 0.2.0", - "libc", + "core-foundation 0.10.1", + "core-graphics-types", "objc", ] @@ -482,9 +465,9 @@ dependencies = [ [[package]] name = "const-serialize" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08259976d62c715c4826cb4a3d64a3a9e5c5f68f964ff6087319857f569f93a6" +checksum = "6eda1adcfaaec418a6dedb03d704916570255f19312e381e72a57b417f79b371" dependencies = [ "const-serialize-macro", "serde", @@ -492,15 +475,21 @@ dependencies = [ [[package]] name = "const-serialize-macro" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04382d0d9df7434af6b1b49ea1a026ef39df1b0738b1cc373368cf175354f6eb" +checksum = "8669fc49d73fecc7eec84aac1a80ec0ff30877c5a8083e250d27bf905d1c3ff2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] +[[package]] +name = "const-str" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e991226a70654b49d34de5ed064885f0bef0348a8e70018b8ff1ac80aa984a2" + [[package]] name = "const_format" version = "0.2.34" @@ -529,9 +518,9 @@ checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" [[package]] name = "convert_case" -version = "0.6.0" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec182b0ca2f35d8fc196cf3404988fd8b8c739a4d270ff118a398feb0cbec1ca" +checksum = "baaaa0ecca5b51987b9423ccdc971514dd8b0bb7b4060b983d3664dad3f1f89f" dependencies = [ "unicode-segmentation", ] @@ -548,9 +537,9 @@ dependencies = [ [[package]] name = "core-foundation" -version = "0.10.0" +version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63" +checksum = "b2a6cd9ae233e7f62ba4e9353e81a88df7fc8a5987b8d445b4d90c879bd156f6" dependencies = [ "core-foundation-sys", "libc", @@ -562,40 +551,16 @@ version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" -[[package]] -name = "core-graphics" -version = "0.23.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c07782be35f9e1140080c6b96f0d44b739e2278479f64e02fdab4e32dfd8b081" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", - "core-graphics-types 0.1.3", - "foreign-types", - "libc", -] - [[package]] name = "core-graphics" version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa95a34622365fa5bbf40b20b75dba8dfa8c94c734aea8ac9a5ca38af14316f1" dependencies = [ - "bitflags 2.9.0", - "core-foundation 0.10.0", - "core-graphics-types 0.2.0", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45390e6114f68f718cc7a830514a96f903cccd70d02a8f6d9f643ac4ba45afaf" -dependencies = [ - "bitflags 1.3.2", - "core-foundation 0.9.4", + "bitflags 2.9.1", + "core-foundation 0.10.1", + "core-graphics-types", + "foreign-types 0.5.0", "libc", ] @@ -605,8 +570,8 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3d44a101f213f6c4cdc1853d4b78aef6db6bdfa3468798cc1d9912f4735013eb" dependencies = [ - "bitflags 2.9.0", - "core-foundation 0.10.0", + "bitflags 2.9.1", + "core-foundation 0.10.1", "libc", ] @@ -630,9 +595,9 @@ dependencies = [ [[package]] name = "crossbeam-channel" -version = "0.5.14" +version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" dependencies = [ "crossbeam-utils", ] @@ -683,14 +648,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "darling" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ "darling_core", "darling_macro", @@ -698,35 +663,36 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "darling_macro" -version = "0.20.10" +version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ "darling_core", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "dashmap" -version = "5.5.3" +version = "6.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +checksum = "5041cc499144891f3790297212f32a74fb938e5136a14943f338ef9e0ae276cf" dependencies = [ "cfg-if", + "crossbeam-utils", "hashbrown 0.14.5", "lock_api", "once_cell", @@ -735,32 +701,30 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" [[package]] -name = "derivative" -version = "2.2.0" +name = "deranged" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e" dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", + "powerfmt", ] [[package]] name = "derive_more" -version = "0.99.19" +version = "0.99.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3da29a38df43d6f156149c9b43ded5e018ddff2a855cf2cfd62e8cd7d079c69f" +checksum = "6edb4b64a43d977b8e99788fe3a04d483834fba1215a7e02caa415b626497f7f" dependencies = [ "convert_case 0.4.0", "proc-macro2", "quote", "rustc_version", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -775,12 +739,13 @@ dependencies = [ [[package]] name = "dioxus" -version = "0.6.3" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a247114500f1a78e87022defa8173de847accfada8e8809dfae23a118a580c" +checksum = "f4dbcead80ff5ec0f1fa480303f7700bc5b20293bc450db2acd011dfcb59f941" dependencies = [ "dioxus-cli-config", "dioxus-config-macro", + "dioxus-config-macros", "dioxus-core", "dioxus-core-macro", "dioxus-desktop", @@ -790,37 +755,67 @@ dependencies = [ "dioxus-history", "dioxus-hooks", "dioxus-html", + "dioxus-liveview", "dioxus-logger", + "dioxus-router", + "dioxus-server", "dioxus-signals", + "dioxus-ssr", "dioxus-web", + "dioxus_server_macro", "manganis", + "serde", + "subsecond", "warnings", ] +[[package]] +name = "dioxus-asset-resolver" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7047fa23aa7b39e43bd6c84b29f17a63e64752b96bc34645eb2e282e392298c1" +dependencies = [ + "dioxus-cli-config", + "http", + "infer", + "jni", + "ndk", + "ndk-context", + "ndk-sys", + "thiserror 2.0.12", + "urlencoding", +] + [[package]] name = "dioxus-cli-config" -version = "0.6.3" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdd16948f1ffdb068dd9a64812158073a4250e2af4e98ea31fdac0312e6bce86" +checksum = "f55b81114bea9c5b0198bf6b120aaaee445bba432ed984865cc73e433ac5dbe6" dependencies = [ "wasm-bindgen", ] [[package]] name = "dioxus-config-macro" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75cbf582fbb1c32d34a1042ea675469065574109c95154468710a4d73ee98b49" +checksum = "7edac8734d75062f614724172937d942cee0e454db63419330ea5b6cfe3efddc" dependencies = [ "proc-macro2", "quote", ] +[[package]] +name = "dioxus-config-macros" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6cdd2080174d6e119cef3c7758c91814b7a1312e1520f6af44f1aefd36d39a0" + [[package]] name = "dioxus-core" -version = "0.6.3" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c03f451a119e47433c16e2d8eb5b15bf7d6e6734eb1a4c47574e6711dadff8d" +checksum = "5f4895f7411b9fca3bf8a1aef82bdd14d72e06028d8e2147a79ae08a9256e3d6" dependencies = [ "const_format", "dioxus-core-types", @@ -828,47 +823,49 @@ dependencies = [ "futures-util", "generational-box", "longest-increasing-subsequence", - "rustc-hash", + "rustc-hash 2.1.1", "rustversion", "serde", "slab", "slotmap", + "subsecond", "tracing", "warnings", ] [[package]] name = "dioxus-core-macro" -version = "0.6.3" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "105c954caaaedf8cd10f3d1ba576b01e18aa8d33ad435182125eefe488cf0064" +checksum = "83866113d4d67fbb7fb8f3799a479e5ba4305bf56b741236a7da4c99cb56d8f6" dependencies = [ - "convert_case 0.6.0", + "convert_case 0.8.0", "dioxus-rsx", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "dioxus-core-types" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91a82fccfa48574eb7aa183e297769540904694844598433a9eb55896ad9f93b" +checksum = "d52a645c20de7d1071fa0b3cdeb3d6e491069c0905f41a71116e571143aa4e80" dependencies = [ "once_cell", ] [[package]] name = "dioxus-desktop" -version = "0.6.3" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b0cca3e7a10a4a3df37ea52c4cc7a53e5c9233489e03ee3f2829471fc3099a" +checksum = "5dd1a2dc2b7e6975e3e49fb98dc7adc1200ec42a117b2ca36a9dd4e16a4c6db0" dependencies = [ "async-trait", "base64", - "cocoa 0.25.0", - "core-foundation 0.9.4", + "cocoa", + "core-foundation 0.10.1", + "dioxus-asset-resolver", "dioxus-cli-config", "dioxus-core", "dioxus-devtools", @@ -886,7 +883,8 @@ dependencies = [ "infer", "jni", "lazy-js-bundle", - "muda 0.11.5", + "libc", + "muda", "ndk", "ndk-context", "ndk-sys", @@ -894,13 +892,13 @@ dependencies = [ "objc_id", "once_cell", "rfd", - "rustc-hash", + "rustc-hash 2.1.1", "serde", "serde_json", "signal-hook", "slab", "tao", - "thiserror 1.0.69", + "thiserror 2.0.12", "tokio", "tracing", "tray-icon", @@ -911,15 +909,18 @@ dependencies = [ [[package]] name = "dioxus-devtools" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712a7300f1e8181218187b03502044157eef04e0a25b518117c5ef9ae1096880" +checksum = "5783e5a5660664bdc9edeb7985a3b84816f8791e5b911f6ff92caee620c567d1" dependencies = [ + "dioxus-cli-config", "dioxus-core", "dioxus-devtools-types", "dioxus-signals", "serde", "serde_json", + "subsecond", + "thiserror 2.0.12", "tracing", "tungstenite", "warnings", @@ -927,19 +928,20 @@ dependencies = [ [[package]] name = "dioxus-devtools-types" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f62434973c0c9c5a3bc42e9cd5e7070401c2062a437fb5528f318c3e42ebf4ff" +checksum = "6a8c5b9f97622f27eeb24928cd143fc6a9e37e893fe1cc82bb98dc127325e544" dependencies = [ "dioxus-core", "serde", + "subsecond-types", ] [[package]] name = "dioxus-document" -version = "0.6.3" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "802a2014d1662b6615eec0a275745822ee4fc66aacd9d0f2fb33d6c8da79b8f2" +checksum = "367a6887a3ed89701fb6697e6ca8a29581d2148065554839f284bad8442364f3" dependencies = [ "dioxus-core", "dioxus-core-macro", @@ -956,17 +958,20 @@ dependencies = [ [[package]] name = "dioxus-fullstack" -version = "0.6.3" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe99b48a1348eec385b5c4bd3e80fd863b0d3b47257d34e2ddc58754dec5d128" +checksum = "9c511dcd3c82be304ec70777c5f6787aea905ed9cb2dabe233807c0f21db46e6" dependencies = [ "base64", "bytes", "ciborium", - "dioxus-desktop", "dioxus-devtools", + "dioxus-fullstack-hooks", + "dioxus-fullstack-protocol", "dioxus-history", + "dioxus-interpreter-js", "dioxus-lib", + "dioxus-server", "dioxus-web", "dioxus_server_macro", "futures-channel", @@ -979,11 +984,38 @@ dependencies = [ "web-sys", ] +[[package]] +name = "dioxus-fullstack-hooks" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe59ae103f6f486bd5fbeef22ae136df745fa54f5e8216a56158e04c7542af8" +dependencies = [ + "dioxus-core", + "dioxus-fullstack-protocol", + "dioxus-hooks", + "dioxus-signals", + "futures-channel", + "serde", +] + +[[package]] +name = "dioxus-fullstack-protocol" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a140fba9b42c2de2d6ee4f29254a6b1a7eba8992eb7875a76611a69c70b6ecb" +dependencies = [ + "base64", + "ciborium", + "dioxus-core", + "serde", + "tracing", +] + [[package]] name = "dioxus-history" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ae4e22616c698f35b60727313134955d885de2d32e83689258e586ebc9b7909" +checksum = "9cf1d72ade61051fee3d8f15a6a077c9b2dc41cab76904fd2186270ade617e07" dependencies = [ "dioxus-core", "tracing", @@ -991,9 +1023,9 @@ dependencies = [ [[package]] name = "dioxus-hooks" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "948e2b3f20d9d4b2c300aaa60281b1755f3298684448920b27106da5841896d0" +checksum = "c5f2ebd42681bf2f42509f12c1d82e3eb4857f5c8e299a5e447416a10e9fb83d" dependencies = [ "dioxus-core", "dioxus-signals", @@ -1008,9 +1040,9 @@ dependencies = [ [[package]] name = "dioxus-html" -version = "0.6.3" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c9a40e6fee20ce7990095492dedb6a753eebe05e67d28271a249de74dc796d" +checksum = "a5976b6b7d8205865a00a7887c8ee0d4f74efff57badea0a3098de3b649b9044" dependencies = [ "async-trait", "dioxus-core", @@ -1033,28 +1065,28 @@ dependencies = [ [[package]] name = "dioxus-html-internal-macro" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43ba87b53688a2c9f619ecdf4b3b955bc1f08bd0570a80a0d626c405f6d14a76" +checksum = "7c56a1c2b214e7315cbe0f2941cddbda99a97d407ce445c4201e036c870c683b" dependencies = [ - "convert_case 0.6.0", + "convert_case 0.8.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "dioxus-interpreter-js" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "330707b10ca75cb0eb05f9e5f8d80217cd0d7e62116a8277ae363c1a09b57a22" +checksum = "5085b5948bf9c1ee30fd08858b2b4c2a0f3a450225fe22539485d1f97469b811" dependencies = [ "dioxus-core", "dioxus-core-types", "dioxus-html", "js-sys", "lazy-js-bundle", - "rustc-hash", + "rustc-hash 2.1.1", "serde", "sledgehammer_bindgen", "sledgehammer_utils", @@ -1063,11 +1095,26 @@ dependencies = [ "web-sys", ] +[[package]] +name = "dioxus-isrg" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84c8328881804c5faffeaea01756c60d4a6b04c8b970ad62f3611e1e26f22b43" +dependencies = [ + "chrono", + "http", + "lru", + "rustc-hash 2.1.1", + "thiserror 2.0.12", + "tracing", + "walkdir", +] + [[package]] name = "dioxus-lib" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5405b71aa9b8b0c3e0d22728f12f34217ca5277792bd315878cc6ecab7301b72" +checksum = "3a5cb1203142faacfd2c7765f8fdbabc9046273503091e3589c90e48e2e17259" dependencies = [ "dioxus-config-macro", "dioxus-core", @@ -1081,11 +1128,39 @@ dependencies = [ "warnings", ] +[[package]] +name = "dioxus-liveview" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca3b1e00ef7b96aa59f2c3426ba6c6d5e828cdcc896da6a691e0002e41ad820" +dependencies = [ + "axum", + "dioxus-cli-config", + "dioxus-core", + "dioxus-devtools", + "dioxus-document", + "dioxus-history", + "dioxus-html", + "dioxus-interpreter-js", + "futures-channel", + "futures-util", + "generational-box", + "rustc-hash 2.1.1", + "serde", + "serde_json", + "slab", + "thiserror 2.0.12", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", +] + [[package]] name = "dioxus-logger" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545961e752f6c8bf59c274951b3c8b18a106db6ad2f9e2035b29e1f2a3e899b1" +checksum = "748d500d52fd611a83c583f26a154fd21c090ced10dbdf34adcddd27f54a2ae8" dependencies = [ "console_error_panic_hook", "dioxus-cli-config", @@ -1098,28 +1173,108 @@ dependencies = [ name = "dioxus-primitives" version = "0.0.1" dependencies = [ + "dioxus", "dioxus-lib", "dioxus-time", "tracing", ] +[[package]] +name = "dioxus-router" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34b08165221e24d4333342bd985fe6effa5a0a40b2556ca24fb3a889b7f9d52e" +dependencies = [ + "dioxus-cli-config", + "dioxus-fullstack-hooks", + "dioxus-history", + "dioxus-lib", + "dioxus-router-macro", + "rustversion", + "tracing", + "url", + "urlencoding", +] + +[[package]] +name = "dioxus-router-macro" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4933c281d8c3dda7968a3ef2de1f9a759625076886ad56b9f6218bc55e1515b8" +dependencies = [ + "base16", + "digest", + "proc-macro2", + "quote", + "sha2", + "slab", + "syn 2.0.101", +] + [[package]] name = "dioxus-rsx" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb588e05800b5a7eb90b2f40fca5bbd7626e823fb5e1ba21e011de649b45aa1" +checksum = "ddfa94afa200720fbb4f11781af3f8dd2cafbb5b42cf908e9521886612468a8b" dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.100", + "syn 2.0.101", +] + +[[package]] +name = "dioxus-server" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734e553d7bcf1217d9a8e0c4570a0226c3bd7517a76d13dcc571aa55031dddb3" +dependencies = [ + "async-trait", + "axum", + "base64", + "bytes", + "ciborium", + "dashmap", + "dioxus-cli-config", + "dioxus-devtools", + "dioxus-fullstack-hooks", + "dioxus-fullstack-protocol", + "dioxus-history", + "dioxus-interpreter-js", + "dioxus-isrg", + "dioxus-lib", + "dioxus-router", + "dioxus-ssr", + "enumset", + "futures-channel", + "futures-util", + "generational-box", + "http", + "hyper", + "hyper-util", + "inventory", + "once_cell", + "parking_lot", + "pin-project", + "serde", + "server_fn", + "subsecond", + "thiserror 2.0.12", + "tokio", + "tokio-util", + "tower", + "tower-http", + "tower-layer", + "tracing", + "tracing-futures", + "web-sys", ] [[package]] name = "dioxus-signals" -version = "0.6.3" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10e032dbb3a2c0386ec8b8ee59bc20b5aeb67038147c855801237b45b13d72ac" +checksum = "6b525f9e4655da0660494fb9067693b32354a1a83c145dfbfda0214411250ad2" dependencies = [ "dioxus-core", "futures-channel", @@ -1127,16 +1282,27 @@ dependencies = [ "generational-box", "once_cell", "parking_lot", - "rustc-hash", + "rustc-hash 2.1.1", "tracing", "warnings", ] +[[package]] +name = "dioxus-ssr" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1c35657fa80d3179bbd8fd0827844fcfd94c0a8076b527c593db4009320e57" +dependencies = [ + "askama_escape", + "dioxus-core", + "dioxus-core-types", + "rustc-hash 2.1.1", +] + [[package]] name = "dioxus-time" version = "0.1.0-alpha.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdbdc95015314059d9683d5c93913156ddabc3d834dd7e76d34c3bb666daabf1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#37be79f01b6b30abe19cd91863b01fb73c5ab471" dependencies = [ "dioxus", "futures", @@ -1146,17 +1312,17 @@ dependencies = [ [[package]] name = "dioxus-web" -version = "0.6.3" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e7c12475c3d360058b8afe1b68eb6dfc9cbb7dcd760aed37c5f85c561c83ed1" +checksum = "7f2ac1b068c4eea7f9cca8ee501fd6fc4043afd16992bfe338c50d1e6ca7c0c5" dependencies = [ "async-trait", - "ciborium", "dioxus-cli-config", "dioxus-core", "dioxus-core-types", "dioxus-devtools", "dioxus-document", + "dioxus-fullstack-protocol", "dioxus-history", "dioxus-html", "dioxus-interpreter-js", @@ -1164,9 +1330,10 @@ dependencies = [ "futures-channel", "futures-util", "generational-box", + "gloo-timers", "js-sys", "lazy-js-bundle", - "rustc-hash", + "rustc-hash 2.1.1", "serde", "serde-wasm-bindgen", "serde_json", @@ -1178,14 +1345,14 @@ dependencies = [ [[package]] name = "dioxus_server_macro" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "371a5b21989a06b53c5092e977b3f75d0e60a65a4c15a2aa1d07014c3b2dda97" +checksum = "af71b5741d256bb9b70d9125f94b36579fc5d221a45500e90f1bd7c8027db4e1" dependencies = [ "proc-macro2", "quote", "server_fn_macro", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1215,6 +1382,28 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" +[[package]] +name = "dispatch2" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a0d569e003ff27784e0e14e4a594048698e0c0f0b66cabcb51511be55a7caa0" +dependencies = [ + "bitflags 2.9.1", + "block2", + "libc", + "objc2", +] + +[[package]] +name = "dispatch2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" +dependencies = [ + "bitflags 2.9.1", + "objc2", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -1223,7 +1412,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1240,20 +1429,20 @@ dependencies = [ [[package]] name = "dlopen2_derive" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2b99bf03862d7f545ebc28ddd33a665b50865f4dfd84031a393823879bd4c54" +checksum = "788160fb30de9cdd857af31c6a2675904b16ece8fc2737b2c7127ba368c9d0f4" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "dpi" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f25c0e292a7ca6d6498557ff1df68f32c99850012b6ea401cf8daf771f22ff53" +checksum = "d8b14ccef22fc6f5a8f4d7d768562a182c04ce9a3b3157b91390b52ddfdf1a76" [[package]] name = "dtoa" @@ -1276,6 +1465,15 @@ version = "1.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + [[package]] name = "endi" version = "1.1.0" @@ -1300,28 +1498,28 @@ checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "enumset" -version = "1.1.5" +version = "1.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d07a4b049558765cef5f0c1a273c3fc57084d768b44d2f98127aef4cceb17293" +checksum = "11a6b7c3d347de0a9f7bfd2f853be43fe32fa6fac30c70f6d6d67a1e936b87ee" dependencies = [ "enumset_derive", ] [[package]] name = "enumset_derive" -version = "0.10.0" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59c3b24c345d8c314966bdc1832f6c2635bfcce8e7cf363bd115987bba2ee242" +checksum = "6da3ea9e1d1a3b1593e15781f930120e72aa7501610b2f82e5b6739c72e8eac5" dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1332,9 +1530,9 @@ checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.10" +version = "0.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18" dependencies = [ "libc", "windows-sys 0.59.0", @@ -1363,9 +1561,9 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.5.3" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" dependencies = [ "event-listener", "pin-project-lite", @@ -1398,9 +1596,9 @@ dependencies = [ [[package]] name = "flate2" -version = "1.1.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" dependencies = [ "crc32fast", "miniz_oxide", @@ -1412,6 +1610,21 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared 0.1.1", +] + [[package]] name = "foreign-types" version = "0.5.0" @@ -1419,7 +1632,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" dependencies = [ "foreign-types-macros", - "foreign-types-shared", + "foreign-types-shared 0.3.1", ] [[package]] @@ -1430,9 +1643,15 @@ checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + [[package]] name = "foreign-types-shared" version = "0.3.1" @@ -1527,7 +1746,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1670,9 +1889,9 @@ dependencies = [ [[package]] name = "generational-box" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a673cf4fb0ea6a91aa86c08695756dfe875277a912cdbf33db9a9f62d47ed82b" +checksum = "325ed4c07e447d6f6cbe39d0dc8a5e345f4d76e7ea62d75c2ccd0e263ad5099b" dependencies = [ "parking_lot", "tracing", @@ -1688,6 +1907,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "getopts" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14dbbfd5c71d70241ecf9e6f13737f7b5ce823821063188d7e46c41d371eebd5" +dependencies = [ + "unicode-width", +] + [[package]] name = "getrandom" version = "0.1.16" @@ -1701,9 +1929,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.15" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" dependencies = [ "cfg-if", "libc", @@ -1712,9 +1940,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" dependencies = [ "cfg-if", "libc", @@ -1766,7 +1994,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "futures-channel", "futures-core", "futures-executor", @@ -1790,11 +2018,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bb0228f477c0900c880fd78c8759b95c7636dbd7842707f49e132378aa2acdc" dependencies = [ "heck 0.4.1", - "proc-macro-crate 2.0.2", + "proc-macro-crate 2.0.0", "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -1809,18 +2037,17 @@ dependencies = [ [[package]] name = "global-hotkey" -version = "0.5.5" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b436093d1598b05e3b7fddc097b2bad32763f53a1beb25ab6f9718c6a60acd09" +checksum = "41fbb3a4e56c901ee66c190fdb3fa08344e6d09593cc6c61f8eb9add7144b271" dependencies = [ - "bitflags 2.9.0", - "cocoa 0.25.0", "crossbeam-channel", "keyboard-types", - "objc", + "objc2", + "objc2-app-kit", "once_cell", - "thiserror 1.0.69", - "windows-sys 0.52.0", + "thiserror 2.0.12", + "windows-sys 0.59.0", "x11-dl", ] @@ -1930,14 +2157,33 @@ dependencies = [ "proc-macro-error", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", +] + +[[package]] +name = "h2" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap 2.9.0", + "slab", + "tokio", + "tokio-util", + "tracing", ] [[package]] name = "half" -version = "2.5.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" dependencies = [ "cfg-if", "crunchy", @@ -1957,9 +2203,14 @@ checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "hashbrown" -version = "0.15.2" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" +checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] [[package]] name = "heck" @@ -1973,12 +2224,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" - [[package]] name = "hex" version = "0.4.3" @@ -2042,12 +2287,24 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-range-header" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" + [[package]] name = "httparse" version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + [[package]] name = "hyper" version = "1.6.0" @@ -2057,9 +2314,11 @@ dependencies = [ "bytes", "futures-channel", "futures-util", + "h2", "http", "http-body", "httparse", + "httpdate", "itoa 1.0.15", "pin-project-lite", "smallvec", @@ -2067,18 +2326,39 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + [[package]] name = "hyper-util" -version = "0.1.10" +version = "0.1.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" +checksum = "b1c293b6b3d21eca78250dc7dbebd6b9210ec5530e038cbfe0661b5c47ab06e8" dependencies = [ + "base64", "bytes", "futures-channel", + "futures-core", "futures-util", "http", "http-body", "hyper", + "ipnet", + "libc", + "percent-encoding", "pin-project-lite", "socket2", "tokio", @@ -2087,55 +2367,60 @@ dependencies = [ ] [[package]] -name = "icu_collections" -version = "1.5.0" +name = "iana-time-zone" +version = "0.1.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8" dependencies = [ - "displaydoc", - "yoke", - "zerofrom", - "zerovec", + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core 0.61.2", ] [[package]] -name = "icu_locid" -version = "1.5.0" +name = "iana-time-zone-haiku" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" dependencies = [ - "displaydoc", - "litemap", - "tinystr", - "writeable", - "zerovec", + "cc", ] [[package]] -name = "icu_locid_transform" -version = "1.5.0" +name = "icu_collections" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" dependencies = [ "displaydoc", - "icu_locid", - "icu_locid_transform_data", - "icu_provider", - "tinystr", + "potential_utf", + "yoke", + "zerofrom", "zerovec", ] [[package]] -name = "icu_locid_transform_data" -version = "1.5.0" +name = "icu_locale_core" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] [[package]] name = "icu_normalizer" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" dependencies = [ "displaydoc", "icu_collections", @@ -2143,67 +2428,54 @@ dependencies = [ "icu_properties", "icu_provider", "smallvec", - "utf16_iter", - "utf8_iter", - "write16", "zerovec", ] [[package]] name = "icu_normalizer_data" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" [[package]] name = "icu_properties" -version = "1.5.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" dependencies = [ "displaydoc", "icu_collections", - "icu_locid_transform", + "icu_locale_core", "icu_properties_data", "icu_provider", - "tinystr", + "potential_utf", + "zerotrie", "zerovec", ] [[package]] name = "icu_properties_data" -version = "1.5.0" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" [[package]] name = "icu_provider" -version = "1.5.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" dependencies = [ "displaydoc", - "icu_locid", - "icu_provider_macros", + "icu_locale_core", "stable_deref_trait", "tinystr", "writeable", "yoke", "zerofrom", + "zerotrie", "zerovec", ] -[[package]] -name = "icu_provider_macros" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", -] - [[package]] name = "ident_case" version = "1.0.1" @@ -2223,9 +2495,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" dependencies = [ "icu_normalizer", "icu_properties", @@ -2243,30 +2515,30 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.8.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", - "hashbrown 0.15.2", + "hashbrown 0.15.3", ] [[package]] name = "infer" -version = "0.11.0" +version = "0.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a6c16b11a665b26aeeb9b1d7f954cdeb034be38dd00adab4f2ae921a8fee804" +checksum = "a588916bfdfd92e71cacef98a63d9b1f0d74d6599980d11894290e7ddefffcf7" dependencies = [ "cfb", ] [[package]] -name = "instant" -version = "0.1.13" +name = "inventory" +version = "0.3.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +checksum = "ab08d7cd2c5897f2c949e5383ea7c7db03fb19130ffcfbf7eda795137ae3cb83" dependencies = [ - "cfg-if", + "rustversion", ] [[package]] @@ -2275,6 +2547,16 @@ version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + [[package]] name = "itoa" version = "0.4.8" @@ -2348,7 +2630,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "serde", "unicode-segmentation", ] @@ -2368,9 +2650,9 @@ dependencies = [ [[package]] name = "lazy-js-bundle" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e49596223b9d9d4947a14a25c142a6e7d8ab3f27eb3ade269d238bb8b5c267e2" +checksum = "3cbef75ea0d48cf0f979b0cf8c1a14d9a62f5e43020b9b2cfde8f16ea793c861" [[package]] name = "lazy_static" @@ -2398,15 +2680,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6e9ec52138abedcc58dc17a7c6c0c00a2bdb4f3427c7f63fa97fd0d859155caf" dependencies = [ "gtk-sys", - "libloading", + "libloading 0.7.4", "once_cell", ] [[package]] name = "libc" -version = "0.2.171" +version = "0.2.172" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" +checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa" [[package]] name = "libloading" @@ -2418,13 +2700,23 @@ dependencies = [ "winapi", ] +[[package]] +name = "libloading" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667" +dependencies = [ + "cfg-if", + "windows-targets 0.53.0", +] + [[package]] name = "libredox" version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "libc", ] @@ -2447,6 +2739,12 @@ dependencies = [ "x11", ] +[[package]] +name = "linked-hash-map" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" + [[package]] name = "linux-raw-sys" version = "0.4.15" @@ -2455,21 +2753,21 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] name = "linux-raw-sys" -version = "0.9.3" +version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" +checksum = "cd945864f07fe9f5371a27ad7b52a172b4b499999f1d97574c9fa68373937e12" [[package]] name = "litemap" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" [[package]] name = "lock_api" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" +checksum = "96936507f153605bddfcda068dd804796c84324ed2510809e5b2a624c81da765" dependencies = [ "autocfg", "scopeguard", @@ -2477,9 +2775,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "longest-increasing-subsequence" @@ -2487,12 +2785,32 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" +[[package]] +name = "lru" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" +dependencies = [ + "hashbrown 0.15.3", +] + [[package]] name = "mac" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c41e0c4fef86961ac6d6f8a82609f55f31b05e4fce149ac5710e439df7619ba4" +[[package]] +name = "macro-string" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b27834086c65ec3f9387b096d66e99f221cf081c2b738042aa252bcd41204e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + [[package]] name = "malloc_buf" version = "0.0.6" @@ -2504,9 +2822,9 @@ dependencies = [ [[package]] name = "manganis" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "317af44b15e7605b85f04525449a3bb631753040156c9b318e6cba8a3ea4ef73" +checksum = "7370cf5b0609ba96b318564493bec5c8df5c07726a5d5cbf100dfef90c855978" dependencies = [ "const-serialize", "manganis-core", @@ -2515,9 +2833,9 @@ dependencies = [ [[package]] name = "manganis-core" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c38bee65cc725b2bba23b5dbb290f57c8be8fadbe2043fb7e2ce73022ea06519" +checksum = "b5e065f874f74ac406b6987c567a4f26471d35490a65d5567d8385cb7b56a423" dependencies = [ "const-serialize", "dioxus-cli-config", @@ -2527,15 +2845,16 @@ dependencies = [ [[package]] name = "manganis-macro" -version = "0.6.2" +version = "0.7.0-alpha.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9f4f71310913c40174d9f0cfcbcb127dad0329ecdb3945678a120db22d3d065" +checksum = "f11f005857d685e4740eaf3e2bfcc048548489e2ce9b4f891d10db9d1e5421d4" dependencies = [ "dunce", + "macro-string", "manganis-core", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -2552,18 +2871,51 @@ dependencies = [ "tendril", ] +[[package]] +name = "matchers" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" +dependencies = [ + "regex-automata 0.1.10", +] + [[package]] name = "matches" version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + [[package]] name = "memchr" version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "memfd" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2cffa4ad52c6f791f4f8b15f0c05f9824b2ced1160e88cc393d64fff9a8ac64" +dependencies = [ + "rustix 0.38.44", +] + +[[package]] +name = "memmap2" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f" +dependencies = [ + "libc", +] + [[package]] name = "memoffset" version = "0.9.1" @@ -2591,9 +2943,9 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.8.5" +version = "0.8.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" dependencies = [ "adler2", "simd-adler32", @@ -2601,51 +2953,68 @@ dependencies = [ [[package]] name = "mio" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] name = "muda" -version = "0.11.5" +version = "0.16.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c47e7625990fc1af2226ea4f34fb2412b03c12639fcb91868581eb3a6893453" +checksum = "4de14a9b5d569ca68d7c891d613b390cf5ab4f851c77aaa2f9e435555d3d9492" dependencies = [ - "cocoa 0.25.0", "crossbeam-channel", + "dpi", "gtk", "keyboard-types", "libxdo", - "objc", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", "once_cell", "png", - "thiserror 1.0.69", - "windows-sys 0.52.0", + "thiserror 2.0.12", + "windows-sys 0.59.0", ] [[package]] -name = "muda" -version = "0.15.3" +name = "multer" +version = "3.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdae9c00e61cc0579bcac625e8ad22104c60548a025bfc972dc83868a28e1484" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" dependencies = [ - "crossbeam-channel", - "dpi", - "gtk", - "keyboard-types", - "libxdo", - "objc2 0.5.2", - "objc2-app-kit 0.2.2", - "objc2-foundation 0.2.2", - "once_cell", - "png", - "thiserror 1.0.69", - "windows-sys 0.59.0", + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "memchr", + "mime", + "spin", + "version_check", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", ] [[package]] @@ -2654,7 +3023,7 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3f42e7bbe13d351b6bead8286a43aac9534b82bd3cc43e47037f012ebfd62d4" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "jni-sys", "log", "ndk-sys", @@ -2686,12 +3055,13 @@ checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" [[package]] name = "nix" -version = "0.27.1" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "cfg-if", + "cfg_aliases", "libc", "memoffset", ] @@ -2702,6 +3072,12 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72ef4a56884ca558e5ddb05a1d1e7e1bfd9a68d9ed024c21704cc98872dae1bb" +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-traits" version = "0.2.19" @@ -2726,10 +3102,10 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ - "proc-macro-crate 2.0.2", + "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -2739,117 +3115,51 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ "malloc_buf", - "objc_exception", -] - -[[package]] -name = "objc-foundation" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" -dependencies = [ - "block", - "objc", - "objc_id", ] -[[package]] -name = "objc-sys" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb91bdd390c7ce1a8607f35f3ca7151b65afc0ff5ff3b34fa350f7d7c7e4310" - [[package]] name = "objc2" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46a785d4eeff09c14c487497c162e92766fbb3e4059a71840cecc03d9a50b804" -dependencies = [ - "objc-sys", - "objc2-encode", -] - -[[package]] -name = "objc2" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3531f65190d9cff863b77a99857e74c314dd16bf56c538c4b57c7cbc3f3a6e59" +checksum = "88c6597e14493ab2e44ce58f2fdecf095a51f12ca57bec060a11c57332520551" dependencies = [ "objc2-encode", ] [[package]] name = "objc2-app-kit" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4e89ad9e3d7d297152b17d39ed92cd50ca8063a89a9fa569046d41568891eff" -dependencies = [ - "bitflags 2.9.0", - "block2 0.5.1", - "libc", - "objc2 0.5.2", - "objc2-core-data", - "objc2-core-image", - "objc2-foundation 0.2.2", - "objc2-quartz-core", -] - -[[package]] -name = "objc2-app-kit" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5906f93257178e2f7ae069efb89fbd6ee94f0592740b5f8a1512ca498814d0fb" +checksum = "e6f29f568bec459b0ddff777cec4fe3fd8666d82d5a40ebd0ff7e66134f89bcc" dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.0", + "bitflags 2.9.1", + "block2", + "objc2", "objc2-core-foundation", - "objc2-foundation 0.3.0", -] - -[[package]] -name = "objc2-core-data" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617fbf49e071c178c0b24c080767db52958f716d9eabdf0890523aeae54773ef" -dependencies = [ - "bitflags 2.9.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", + "objc2-foundation", ] [[package]] name = "objc2-core-foundation" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "daeaf60f25471d26948a1c2f840e3f7d86f4109e3af4e8e4b5cd70c39690d925" +checksum = "1c10c2894a6fed806ade6027bcd50662746363a9589d3ec9d9bef30a4e4bc166" dependencies = [ - "bitflags 2.9.0", - "objc2 0.6.0", + "bitflags 2.9.1", + "dispatch2 0.3.0", + "objc2", ] [[package]] name = "objc2-core-graphics" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dca602628b65356b6513290a21a6405b4d4027b8b250f0b98dddbb28b7de02" +checksum = "989c6c68c13021b5c2d6b71456ebb0f9dc78d752e86a98da7c716f4f9470f5a4" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "objc2-core-foundation", ] -[[package]] -name = "objc2-core-image" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55260963a527c99f1819c4f8e3b47fe04f9650694ef348ffd2227e8196d34c80" -dependencies = [ - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", -] - [[package]] name = "objc2-encode" version = "4.1.0" @@ -2858,85 +3168,105 @@ checksum = "ef25abbcd74fb2609453eb695bd2f860d389e457f67dc17cafc8b8cbc89d0c33" [[package]] name = "objc2-foundation" -version = "0.2.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8" +checksum = "900831247d2fe1a09a683278e5384cfb8c80c79fe6b166f9d14bfdde0ea1b03c" dependencies = [ - "bitflags 2.9.0", - "block2 0.5.1", - "libc", - "objc2 0.5.2", + "bitflags 2.9.1", + "block2", + "objc2", + "objc2-core-foundation", ] [[package]] -name = "objc2-foundation" -version = "0.3.0" +name = "objc_id" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a21c6c9014b82c39515db5b396f91645182611c97d24637cf56ac01e5f8d998" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" dependencies = [ - "bitflags 2.9.0", - "block2 0.6.0", - "objc2 0.6.0", - "objc2-core-foundation", + "objc", ] [[package]] -name = "objc2-metal" -version = "0.2.2" +name = "object" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ - "bitflags 2.9.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", + "memchr", ] [[package]] -name = "objc2-quartz-core" -version = "0.2.2" +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "onig" +version = "6.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a" +checksum = "336b9c63443aceef14bea841b899035ae3abe89b7c486aaf4c5bd8aafedac3f0" dependencies = [ - "bitflags 2.9.0", - "block2 0.5.1", - "objc2 0.5.2", - "objc2-foundation 0.2.2", - "objc2-metal", + "bitflags 2.9.1", + "libc", + "once_cell", + "onig_sys", ] [[package]] -name = "objc_exception" -version = "0.1.2" +name = "onig_sys" +version = "69.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +checksum = "c7f86c6eef3d6df15f23bcfb6af487cbd2fed4e5581d58d5bf1f5f8b7f6727dc" dependencies = [ "cc", + "pkg-config", ] [[package]] -name = "objc_id" -version = "0.1.1" +name = "openssl" +version = "0.10.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" dependencies = [ - "objc", + "bitflags 2.9.1", + "cfg-if", + "foreign-types 0.3.2", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", ] [[package]] -name = "object" -version = "0.36.7" +name = "openssl-macros" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ - "memchr", + "proc-macro2", + "quote", + "syn 2.0.101", ] [[package]] -name = "once_cell" -version = "1.21.1" +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.109" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] [[package]] name = "option-ext" @@ -2987,9 +3317,9 @@ checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[package]] name = "parking_lot" -version = "0.12.3" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" +checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13" dependencies = [ "lock_api", "parking_lot_core", @@ -2997,9 +3327,9 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.10" +version = "0.9.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" +checksum = "bc838d2a56b5b1a6c25f55575dfc605fabb63bb2365f6c2353ef9159aa69e4a5" dependencies = [ "cfg-if", "libc", @@ -3142,7 +3472,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3157,23 +3487,25 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "piper" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" -dependencies = [ - "atomic-waker", - "fastrand", - "futures-io", -] - [[package]] name = "pkg-config" version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "plist" +version = "1.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac26e981c03a6e53e0aee43c113e3202f5581d5360dae7bd2c70e800dd0451d" +dependencies = [ + "base64", + "indexmap 2.9.0", + "quick-xml", + "serde", + "time", +] + [[package]] name = "png" version = "0.17.16" @@ -3188,25 +3520,25 @@ dependencies = [ ] [[package]] -name = "polling" -version = "3.7.4" +name = "pollster" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3" + +[[package]] +name = "potential_utf" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" +checksum = "e5a7c30837279ca13e7c867e9e40053bc68740f988cb07f7ca6df43cc734b585" dependencies = [ - "cfg-if", - "concurrent-queue", - "hermit-abi", - "pin-project-lite", - "rustix 0.38.44", - "tracing", - "windows-sys 0.59.0", + "zerovec", ] [[package]] -name = "pollster" -version = "0.3.0" +name = "powerfmt" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22686f4785f02a4fcc856d3b3bb19bf6c8160d103f7a99cc258bddd0251dc7f2" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" @@ -3229,6 +3561,9 @@ version = "0.1.0" dependencies = [ "dioxus", "dioxus-primitives", + "pulldown-cmark", + "syntect", + "tracing", ] [[package]] @@ -3243,12 +3578,20 @@ dependencies = [ [[package]] name = "proc-macro-crate" -version = "2.0.2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b00f26d3400549137f92511a46ac1cd8ce37cb5598a96d382381458b992a5d24" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edce586971a4dfaa28950c6f18ed55e0406c1ab88bbce2c6f6293a7aaba73d35" +dependencies = [ + "toml_edit 0.22.26", ] [[package]] @@ -3283,9 +3626,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.94" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" dependencies = [ "unicode-ident", ] @@ -3298,10 +3641,38 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "version_check", ] +[[package]] +name = "pulldown-cmark" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e8bbe1a966bd2f362681a44f6edce3c2310ac21e4d5067a6e7ec396297a6ea0" +dependencies = [ + "bitflags 2.9.1", + "getopts", + "memchr", + "pulldown-cmark-escape", + "unicase", +] + +[[package]] +name = "pulldown-cmark-escape" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "007d8adb5ddab6f8e3f491ac63566a7d5002cc7ed73901f72057943fa71ae1ae" + +[[package]] +name = "quick-xml" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.40" @@ -3342,6 +3713,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + [[package]] name = "rand_chacha" version = "0.2.2" @@ -3362,6 +3743,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + [[package]] name = "rand_core" version = "0.5.1" @@ -3377,7 +3768,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", ] [[package]] @@ -3412,11 +3812,11 @@ checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" [[package]] name = "redox_syscall" -version = "0.5.10" +version = "0.5.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", ] [[package]] @@ -3425,7 +3825,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" dependencies = [ - "getrandom 0.2.15", + "getrandom 0.2.16", "libredox", "thiserror 2.0.12", ] @@ -3438,8 +3838,17 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata", - "regex-syntax", + "regex-automata 0.4.9", + "regex-syntax 0.8.5", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax 0.6.29", ] [[package]] @@ -3450,9 +3859,15 @@ checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", - "regex-syntax", + "regex-syntax 0.8.5", ] +[[package]] +name = "regex-syntax" +version = "0.6.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" + [[package]] name = "regex-syntax" version = "0.8.5" @@ -3461,9 +3876,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.12.15" +version = "0.12.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +checksum = "e98ff6b0dbbe4d5a37318f433d4fc82babd21631f194d370409ceb2e40b2f0b5" dependencies = [ "base64", "bytes", @@ -3473,52 +3888,57 @@ dependencies = [ "http-body", "http-body-util", "hyper", + "hyper-tls", "hyper-util", "ipnet", "js-sys", "log", "mime", "mime_guess", + "native-tls", "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", "tokio", + "tokio-native-tls", "tokio-util", "tower", + "tower-http", "tower-service", "url", "wasm-bindgen", "wasm-bindgen-futures", "wasm-streams", "web-sys", - "windows-registry", ] [[package]] name = "rfd" -version = "0.14.1" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25a73a7337fc24366edfca76ec521f51877b114e42dab584008209cca6719251" +checksum = "80c844748fdc82aae252ee4594a89b6e7ebef1063de7951545564cbc4e57075d" dependencies = [ "ashpd", - "block", - "dispatch", + "block2", + "dispatch2 0.2.0", "js-sys", "log", - "objc", - "objc-foundation", - "objc_id", + "objc2", + "objc2-app-kit", + "objc2-core-foundation", + "objc2-foundation", "pollster", "raw-window-handle 0.6.2", "urlencoding", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] @@ -3533,6 +3953,12 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + [[package]] name = "rustc_version" version = "0.4.1" @@ -3548,7 +3974,7 @@ version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "errno", "libc", "linux-raw-sys 0.4.15", @@ -3557,22 +3983,31 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.3" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ - "bitflags 2.9.0", + "bitflags 2.9.1", "errno", "libc", - "linux-raw-sys 0.9.3", + "linux-raw-sys 0.9.4", "windows-sys 0.59.0", ] +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + [[package]] name = "rustversion" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" [[package]] name = "ryu" @@ -3589,12 +4024,44 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + [[package]] name = "scopeguard" version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.9.1", + "core-foundation 0.9.4", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "selectors" version = "0.22.0" @@ -3641,9 +4108,9 @@ dependencies = [ [[package]] name = "serde-wasm-bindgen" -version = "0.5.0" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" dependencies = [ "js-sys", "serde", @@ -3658,7 +4125,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3673,15 +4140,25 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_path_to_error" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a" +dependencies = [ + "itoa 1.0.15", + "serde", +] + [[package]] name = "serde_qs" -version = "0.12.0" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0431a35568651e363364210c91983c1da5eb29404d9f0928b67d4ebcfa7d330c" +checksum = "8b417bedc008acbdf6d6b4bc482d29859924114bbe2650b7921fb68a261d0aa6" dependencies = [ "percent-encoding", "serde", - "thiserror 1.0.69", + "thiserror 2.0.12", ] [[package]] @@ -3692,7 +4169,7 @@ checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3718,25 +4195,39 @@ dependencies = [ [[package]] name = "server_fn" -version = "0.6.15" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fae7a3038a32e5a34ba32c6c45eb4852f8affaf8b794ebfcd4b1099e2d62ebe" +checksum = "09b0f92b9d3a62c73f238ac21f7a09f15bad335a9d1651514d9da80d2eaf8d4c" dependencies = [ + "axum", + "base64", "bytes", + "const-str", "const_format", "dashmap", "futures", "gloo-net", "http", + "http-body-util", + "hyper", + "inventory", "js-sys", "once_cell", + "pin-project-lite", "reqwest", + "rustc_version", + "rustversion", "send_wrapper", "serde", "serde_json", "serde_qs", "server_fn_macro_default", - "thiserror 1.0.69", + "thiserror 2.0.12", + "throw_error", + "tokio", + "tokio-tungstenite", + "tower", + "tower-layer", "url", "wasm-bindgen", "wasm-bindgen-futures", @@ -3747,26 +4238,27 @@ dependencies = [ [[package]] name = "server_fn_macro" -version = "0.6.15" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faaaf648c6967aef78177c0610478abb5a3455811f401f3c62d10ae9bd3901a1" +checksum = "341dd1087afe9f3e546c5979a4f0b6d55ac072e1201313f86e7fe364223835ac" dependencies = [ "const_format", - "convert_case 0.6.0", + "convert_case 0.8.0", "proc-macro2", "quote", - "syn 2.0.100", + "rustc_version", + "syn 2.0.101", "xxhash-rust", ] [[package]] name = "server_fn_macro_default" -version = "0.6.15" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2aa8119b558a17992e0ac1fd07f080099564f24532858811ce04f742542440" +checksum = "bc5ab934f581482a66da82f2b57b15390ad67c9ab85bd9a6c54bb65060fb1380" dependencies = [ "server_fn_macro", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3792,9 +4284,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.8" +version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", "cpufeatures", @@ -3818,9 +4310,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook" -version = "0.3.17" +version = "0.3.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" dependencies = [ "libc", "signal-hook-registry", @@ -3828,9 +4320,9 @@ dependencies = [ [[package]] name = "signal-hook-registry" -version = "1.4.2" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410" dependencies = [ "libc", ] @@ -3874,12 +4366,12 @@ dependencies = [ [[package]] name = "sledgehammer_bindgen_macro" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33a1b4f13e2bbf2f5b29d09dfebc9de69229ffee245aed80e3b70f9b5fd28c06" +checksum = "f62f06db0370222f7f498ef478fce9f8df5828848d1d3517e3331936d7074f55" dependencies = [ "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -3888,7 +4380,7 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "debdd4b83524961983cea3c55383b3910fd2f24fd13a188f5b091d2d504a61ae" dependencies = [ - "rustc-hash", + "rustc-hash 1.1.0", ] [[package]] @@ -3903,15 +4395,15 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.14.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" [[package]] name = "socket2" -version = "0.5.8" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" dependencies = [ "libc", "windows-sys 0.52.0", @@ -3943,6 +4435,12 @@ dependencies = [ "system-deps", ] +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + [[package]] name = "stable_deref_trait" version = "1.2.0" @@ -3957,9 +4455,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "string_cache" -version = "0.8.8" +version = "0.8.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "938d512196766101d333398efde81bc1f37b00cb42c2f8350e5df639f040bbbe" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" dependencies = [ "new_debug_unreachable", "parking_lot", @@ -3980,6 +4478,34 @@ dependencies = [ "quote", ] +[[package]] +name = "subsecond" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1038bac163d3b5f3c08a0af5e8444fb8fbe8263d8e2cc478ed166dd044cfd6a8" +dependencies = [ + "js-sys", + "libc", + "libloading 0.8.8", + "memfd", + "memmap2", + "serde", + "subsecond-types", + "thiserror 2.0.12", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "subsecond-types" +version = "0.7.0-alpha.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b3f036208ecba80c3a9c69647a64786206385d322e66a225445f860ac096370" +dependencies = [ + "serde", +] + [[package]] name = "syn" version = "1.0.109" @@ -3993,9 +4519,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.100" +version = "2.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf" dependencies = [ "proc-macro2", "quote", @@ -4013,13 +4539,35 @@ dependencies = [ [[package]] name = "synstructure" -version = "0.13.1" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", +] + +[[package]] +name = "syntect" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1" +dependencies = [ + "bincode", + "bitflags 1.3.2", + "flate2", + "fnv", + "once_cell", + "onig", + "plist", + "regex-syntax 0.8.5", + "serde", + "serde_derive", + "serde_json", + "thiserror 1.0.69", + "walkdir", + "yaml-rust", ] [[package]] @@ -4037,14 +4585,13 @@ dependencies = [ [[package]] name = "tao" -version = "0.30.8" +version = "0.33.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6682a07cf5bab0b8a2bd20d0a542917ab928b5edb75ebd4eda6b05cbaab872da" +checksum = "1e59c1f38e657351a2e822eadf40d6a2ad4627b9c25557bc1180ec1b3295ef82" dependencies = [ - "bitflags 2.9.0", - "cocoa 0.26.0", - "core-foundation 0.10.0", - "core-graphics 0.24.0", + "bitflags 2.9.1", + "core-foundation 0.10.1", + "core-graphics", "crossbeam-channel", "dispatch", "dlopen2", @@ -4052,7 +4599,6 @@ dependencies = [ "gdkwayland-sys", "gdkx11-sys", "gtk", - "instant", "jni", "lazy_static", "libc", @@ -4060,7 +4606,9 @@ dependencies = [ "ndk", "ndk-context", "ndk-sys", - "objc", + "objc2", + "objc2-app-kit", + "objc2-foundation", "once_cell", "parking_lot", "raw-window-handle 0.5.2", @@ -4069,8 +4617,8 @@ dependencies = [ "tao-macros", "unicode-segmentation", "url", - "windows", - "windows-core", + "windows 0.61.1", + "windows-core 0.61.2", "windows-version", "x11-dl", ] @@ -4083,7 +4631,7 @@ checksum = "f4e16beb8b2ac17db28eab8bca40e62dbfbb34c0fcdc6d9826b11b7b5d047dfd" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4094,14 +4642,14 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" [[package]] name = "tempfile" -version = "3.19.0" +version = "3.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600" +checksum = "e8a64e3985349f2441a1a9ef0b853f869006c3855f2cda6862a94d26ebb9d6a1" dependencies = [ "fastrand", - "getrandom 0.3.2", + "getrandom 0.3.3", "once_cell", - "rustix 1.0.3", + "rustix 1.0.7", "windows-sys 0.59.0", ] @@ -4148,7 +4696,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4159,7 +4707,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4172,11 +4720,51 @@ dependencies = [ "once_cell", ] +[[package]] +name = "throw_error" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41e42a6afdde94f3e656fae18f837cb9bbe500a5ac5de325b09f3ec05b9c28e3" +dependencies = [ + "pin-project-lite", +] + +[[package]] +name = "time" +version = "0.3.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" +dependencies = [ + "deranged", + "itoa 1.0.15", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" + +[[package]] +name = "time-macros" +version = "0.2.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tinystr" -version = "0.7.6" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" dependencies = [ "displaydoc", "zerovec", @@ -4184,9 +4772,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.44.1" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ "backtrace", "bytes", @@ -4201,46 +4789,81 @@ dependencies = [ ] [[package]] -name = "tokio-macros" -version = "2.5.0" +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +checksum = "7a9daff607c6d2bf6c16fd681ccb7eecc83e4e2cdc1ca067ffaadfca5de7f084" dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.100", + "futures-util", + "log", + "tokio", + "tungstenite", ] [[package]] name = "tokio-util" -version = "0.7.14" +version = "0.7.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b9590b93e6fcc1739458317cccd391ad3955e2bde8913edf6f95f9e65a8f034" +checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df" dependencies = [ "bytes", "futures-core", "futures-sink", + "futures-util", + "hashbrown 0.15.3", "pin-project-lite", "tokio", ] [[package]] name = "toml" -version = "0.8.2" +version = "0.8.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.22.26", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3" dependencies = [ "serde", ] @@ -4251,22 +4874,33 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.8.0", + "indexmap 2.9.0", "toml_datetime", - "winnow", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.20.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" dependencies = [ - "indexmap 2.8.0", + "indexmap 2.9.0", + "toml_datetime", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e" +dependencies = [ + "indexmap 2.9.0", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.7.10", ] [[package]] @@ -4282,6 +4916,34 @@ dependencies = [ "tokio", "tower-layer", "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e" +dependencies = [ + "bitflags 2.9.1", + "bytes", + "futures-util", + "http", + "http-body", + "http-body-util", + "http-range-header", + "httpdate", + "iri-string", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower", + "tower-layer", + "tower-service", + "tracing", ] [[package]] @@ -4302,6 +4964,7 @@ version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ + "log", "pin-project-lite", "tracing-attributes", "tracing-core", @@ -4315,7 +4978,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4327,14 +4990,28 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + [[package]] name = "tracing-subscriber" version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ + "matchers", + "once_cell", + "regex", "sharded-slab", "thread_local", + "tracing", "tracing-core", ] @@ -4351,19 +5028,19 @@ dependencies = [ [[package]] name = "tray-icon" -version = "0.19.3" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadd75f5002e2513eaa19b2365f533090cc3e93abd38788452d9ea85cff7b48a" +checksum = "9f7eee98ec5c90daf179d55c20a49d8c0d043054ce7c26336c09a24d31f14fa0" dependencies = [ "crossbeam-channel", "dirs", "libappindicator", - "muda 0.15.3", - "objc2 0.6.0", - "objc2-app-kit 0.3.0", + "muda", + "objc2", + "objc2-app-kit", "objc2-core-foundation", "objc2-core-graphics", - "objc2-foundation 0.3.0", + "objc2-foundation", "once_cell", "png", "thiserror 2.0.12", @@ -4378,19 +5055,18 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "tungstenite" -version = "0.23.0" +version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e2ce1e47ed2994fd43b04c8f618008d4cabdd5ee34027cf14f9d918edd9c8" +checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" dependencies = [ - "byteorder", "bytes", "data-encoding", "http", "httparse", "log", - "rand 0.8.5", + "rand 0.9.1", "sha1", - "thiserror 1.0.69", + "thiserror 2.0.12", "utf-8", ] @@ -4429,6 +5105,12 @@ version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + [[package]] name = "unicode-xid" version = "0.2.6" @@ -4459,12 +5141,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf16_iter" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -4473,9 +5149,19 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "uuid" -version = "1.16.0" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "vcpkg" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version-compare" @@ -4527,7 +5213,7 @@ checksum = "59195a1db0e95b920366d949ba5e0d3fc0e70b67c09be15ce5abb790106b0571" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4573,7 +5259,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "wasm-bindgen-shared", ] @@ -4608,7 +5294,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -4647,17 +5333,17 @@ dependencies = [ [[package]] name = "webbrowser" -version = "0.8.15" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db67ae75a9405634f5882791678772c94ff5f16a66535aae186e26aa0841fc8b" +checksum = "d5df295f8451142f1856b1bd86a606dfe9587d439bc036e319c827700dbd555e" dependencies = [ - "core-foundation 0.9.4", + "core-foundation 0.10.1", "home", "jni", "log", "ndk-context", - "objc", - "raw-window-handle 0.5.2", + "objc2", + "objc2-foundation", "url", "web-sys", ] @@ -4714,10 +5400,10 @@ checksum = "6f61ff3d9d0ee4efcb461b14eb3acfda2702d10dc329f339303fc3e57215ae2c" dependencies = [ "webview2-com-macros", "webview2-com-sys", - "windows", - "windows-core", - "windows-implement", - "windows-interface", + "windows 0.58.0", + "windows-core 0.58.0", + "windows-implement 0.58.0", + "windows-interface 0.58.0", ] [[package]] @@ -4728,7 +5414,7 @@ checksum = "1d228f15bba3b9d56dde8bddbee66fa24545bd17b48d5128ccf4a8742b18e431" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -4738,8 +5424,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a3a3e2eeb58f82361c93f9777014668eb3d07e7d174ee4c819575a9208011886" dependencies = [ "thiserror 1.0.69", - "windows", - "windows-core", + "windows 0.58.0", + "windows-core 0.58.0", ] [[package]] @@ -4779,23 +5465,69 @@ version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" dependencies = [ - "windows-core", + "windows-core 0.58.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5ee8f3d025738cb02bad7868bbb5f8a6327501e870bf51f1b455b0a2454a419" +dependencies = [ + "windows-collections", + "windows-core 0.61.2", + "windows-future", + "windows-link", + "windows-numerics", +] + +[[package]] +name = "windows-collections" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3beeceb5e5cfd9eb1d76b381630e82c4241ccd0d27f1a39ed41b2760b255c5e8" +dependencies = [ + "windows-core 0.61.2", +] + [[package]] name = "windows-core" version = "0.58.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" dependencies = [ - "windows-implement", - "windows-interface", + "windows-implement 0.58.0", + "windows-interface 0.58.0", "windows-result 0.2.0", "windows-strings 0.1.0", "windows-targets 0.52.6", ] +[[package]] +name = "windows-core" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0fdd3ddb90610c7638aa2b3a3ab2904fb9e5cdbecc643ddb3647212781c4ae3" +dependencies = [ + "windows-implement 0.60.0", + "windows-interface 0.59.1", + "windows-link", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-future" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc6a41e98427b19fe4b73c550f060b59fa592d7d686537eebf9385621bfbad8e" +dependencies = [ + "windows-core 0.61.2", + "windows-link", + "windows-threading", +] + [[package]] name = "windows-implement" version = "0.58.0" @@ -4804,7 +5536,18 @@ checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", +] + +[[package]] +name = "windows-implement" +version = "0.60.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", ] [[package]] @@ -4815,7 +5558,18 @@ checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", +] + +[[package]] +name = "windows-interface" +version = "0.59.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.101", ] [[package]] @@ -4825,14 +5579,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38" [[package]] -name = "windows-registry" -version = "0.4.0" +name = "windows-numerics" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +checksum = "9150af68066c4c5c07ddc0ce30421554771e528bde427614c61038bc2c92c2b1" dependencies = [ - "windows-result 0.3.2", - "windows-strings 0.3.1", - "windows-targets 0.53.0", + "windows-core 0.61.2", + "windows-link", ] [[package]] @@ -4846,9 +5599,9 @@ dependencies = [ [[package]] name = "windows-result" -version = "0.3.2" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" dependencies = [ "windows-link", ] @@ -4865,9 +5618,9 @@ dependencies = [ [[package]] name = "windows-strings" -version = "0.3.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87fa48cc5d406560701792be122a10132491cff9d0aeb23583cc2dcafc847319" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" dependencies = [ "windows-link", ] @@ -4881,15 +5634,6 @@ dependencies = [ "windows-targets 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.5", -] - [[package]] name = "windows-sys" version = "0.52.0" @@ -4923,21 +5667,6 @@ dependencies = [ "windows_x86_64_msvc 0.42.2", ] -[[package]] -name = "windows-targets" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" -dependencies = [ - "windows_aarch64_gnullvm 0.48.5", - "windows_aarch64_msvc 0.48.5", - "windows_i686_gnu 0.48.5", - "windows_i686_msvc 0.48.5", - "windows_x86_64_gnu 0.48.5", - "windows_x86_64_gnullvm 0.48.5", - "windows_x86_64_msvc 0.48.5", -] - [[package]] name = "windows-targets" version = "0.52.6" @@ -4970,6 +5699,15 @@ dependencies = [ "windows_x86_64_msvc 0.53.0", ] +[[package]] +name = "windows-threading" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66463ad2e0ea3bbf808b7f1d371311c80e115c0b71d60efc142cafbcfb057a6" +dependencies = [ + "windows-link", +] + [[package]] name = "windows-version" version = "0.1.4" @@ -4985,12 +5723,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.52.6" @@ -5009,12 +5741,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" - [[package]] name = "windows_aarch64_msvc" version = "0.52.6" @@ -5033,12 +5759,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" -[[package]] -name = "windows_i686_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" - [[package]] name = "windows_i686_gnu" version = "0.52.6" @@ -5069,12 +5789,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" -[[package]] -name = "windows_i686_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" - [[package]] name = "windows_i686_msvc" version = "0.52.6" @@ -5093,12 +5807,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" - [[package]] name = "windows_x86_64_gnu" version = "0.52.6" @@ -5117,12 +5825,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" - [[package]] name = "windows_x86_64_gnullvm" version = "0.52.6" @@ -5141,12 +5843,6 @@ version = "0.42.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" - [[package]] name = "windows_x86_64_msvc" version = "0.52.6" @@ -5169,25 +5865,28 @@ dependencies = [ ] [[package]] -name = "wit-bindgen-rt" -version = "0.39.0" +name = "winnow" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" dependencies = [ - "bitflags 2.9.0", + "memchr", ] [[package]] -name = "write16" -version = "1.0.0" +name = "wit-bindgen-rt" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.1", +] [[package]] name = "writeable" -version = "0.5.5" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" [[package]] name = "wry" @@ -5197,8 +5896,8 @@ checksum = "ac0099a336829fbf54c26b5f620c68980ebbe37196772aeaf6118df4931b5cb0" dependencies = [ "base64", "block", - "cocoa 0.26.0", - "core-graphics 0.24.0", + "cocoa", + "core-graphics", "crossbeam-channel", "dpi", "dunce", @@ -5223,8 +5922,8 @@ dependencies = [ "webkit2gtk", "webkit2gtk-sys", "webview2-com", - "windows", - "windows-core", + "windows 0.58.0", + "windows-core 0.58.0", "windows-version", "x11-dl", ] @@ -5250,27 +5949,26 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "xdg-home" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec1cdab258fb55c0da61328dc52c8764709b249011b2cad0454c72f0bf10a1f6" -dependencies = [ - "libc", - "windows-sys 0.59.0", -] - [[package]] name = "xxhash-rust" version = "0.8.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "yoke" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" dependencies = [ "serde", "stable_deref_trait", @@ -5280,45 +5978,39 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.7.5" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "synstructure", ] [[package]] name = "zbus" -version = "4.0.1" +version = "5.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b8e3d6ae3342792a6cc2340e4394334c7402f3d793b390d2c5494a4032b3030" +checksum = "d3a7c7cee313d044fca3f48fa782cb750c79e4ca76ba7bc7718cd4024cdf6f68" dependencies = [ "async-broadcast", - "async-process", "async-recursion", "async-trait", - "derivative", "enumflags2", "event-listener", "futures-core", - "futures-sink", - "futures-util", + "futures-lite", "hex", "nix", "ordered-stream", - "rand 0.8.5", "serde", "serde_repr", - "sha1", - "static_assertions", "tokio", "tracing", "uds_windows", - "windows-sys 0.52.0", - "xdg-home", + "windows-sys 0.59.0", + "winnow 0.7.10", "zbus_macros", "zbus_names", "zvariant", @@ -5326,47 +6018,49 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "4.0.1" +version = "5.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7a3e850ff1e7217a3b7a07eba90d37fe9bb9e89a310f718afcde5885ca9b6d7" +checksum = "a17e7e5eec1550f747e71a058df81a9a83813ba0f6a95f39c4e218bdc7ba366a" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "regex", - "syn 1.0.109", + "syn 2.0.101", + "zbus_names", + "zvariant", "zvariant_utils", ] [[package]] name = "zbus_names" -version = "3.0.0" +version = "4.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b9b1fef7d021261cc16cba64c351d291b715febe0fa10dc3a443ac5a5022e6c" +checksum = "7be68e64bf6ce8db94f63e72f0c7eb9a60d733f7e0499e628dfab0f84d6bcb97" dependencies = [ "serde", "static_assertions", + "winnow 0.7.10", "zvariant", ] [[package]] name = "zerocopy" -version = "0.8.23" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6" +checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.23" +version = "0.8.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154" +checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] @@ -5386,15 +6080,32 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", "synstructure", ] +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + [[package]] name = "zerovec" -version = "0.10.4" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +checksum = "4a05eb080e015ba39cc9e23bbe5e7fb04d5fb040350f99f34e338d5fdd294428" dependencies = [ "yoke", "zerofrom", @@ -5403,49 +6114,88 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.10.3" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.100", + "syn 2.0.101", ] [[package]] name = "zvariant" -version = "4.0.0" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e09e8be97d44eeab994d752f341e67b3b0d80512a8b315a0671d47232ef1b65" +checksum = "9d30786f75e393ee63a21de4f9074d4c038d52c5b1bb4471f955db249f9dffb1" dependencies = [ "endi", "enumflags2", "serde", - "static_assertions", "url", + "winnow 0.7.10", "zvariant_derive", + "zvariant_utils", ] [[package]] name = "zvariant_derive" -version = "4.0.0" +version = "5.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72a5857e2856435331636a9fbb415b09243df4521a267c5bedcd5289b4d5799e" +checksum = "75fda702cd42d735ccd48117b1630432219c0e9616bf6cb0f8350844ee4d9580" dependencies = [ - "proc-macro-crate 1.3.1", + "proc-macro-crate 3.3.0", "proc-macro2", "quote", - "syn 1.0.109", + "syn 2.0.101", "zvariant_utils", ] [[package]] name = "zvariant_utils" -version = "1.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00bedb16a193cc12451873fee2a1bc6550225acece0e36f333e68326c73c8172" +checksum = "e16edfee43e5d7b553b77872d99bc36afdda75c223ca7ad5e3fbecd82ca5fc34" dependencies = [ "proc-macro2", "quote", - "syn 1.0.109", + "serde", + "static_assertions", + "syn 2.0.101", + "winnow 0.7.10", ] + +[[patch.unused]] +name = "dioxus-geolocation" +version = "0.1.0-alpha.1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#37be79f01b6b30abe19cd91863b01fb73c5ab471" + +[[patch.unused]] +name = "dioxus-notification" +version = "0.1.0-alpha.1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#37be79f01b6b30abe19cd91863b01fb73c5ab471" + +[[patch.unused]] +name = "dioxus-sdk" +version = "0.7.0-alpha.1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#37be79f01b6b30abe19cd91863b01fb73c5ab471" + +[[patch.unused]] +name = "dioxus-sync" +version = "0.1.0-alpha.1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#37be79f01b6b30abe19cd91863b01fb73c5ab471" + +[[patch.unused]] +name = "dioxus-util" +version = "0.1.0-alpha.1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#37be79f01b6b30abe19cd91863b01fb73c5ab471" + +[[patch.unused]] +name = "dioxus-window" +version = "0.1.0-alpha.1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#37be79f01b6b30abe19cd91863b01fb73c5ab471" + +[[patch.unused]] +name = "dioxus_storage" +version = "0.1.0-alpha.1" +source = "git+https://github.com/ealmloff/dioxus-std?branch=0.7#37be79f01b6b30abe19cd91863b01fb73c5ab471" diff --git a/Cargo.toml b/Cargo.toml index b42aa982..740b334e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,10 +5,20 @@ members = ["primitives", "preview"] [workspace.dependencies] dioxus-primitives = { path = "primitives" } -dioxus = "0.6" -dioxus-lib = "0.6" +dioxus = "0.7.0-alpha.0" +dioxus-lib = "0.7.0-alpha.0" tracing = { version = "0.1", features = ["std"] } +[patch.crates-io] +dioxus-geolocation = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-notification = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-sdk = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus_storage = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-sync = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-time = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-util = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } +dioxus-window = { git = "https://github.com/ealmloff/dioxus-std", branch = "0.7" } + [profile] [profile.wasm-dev] diff --git a/preview/Cargo.toml b/preview/Cargo.toml index e5f4a976..d8bb9ddc 100644 --- a/preview/Cargo.toml +++ b/preview/Cargo.toml @@ -4,10 +4,16 @@ version = "0.1.0" edition = "2024" [dependencies] -dioxus.workspace = true +dioxus = { workspace = true, features = ["router"] } dioxus-primitives.workspace = true +tracing.workspace = true + +[build-dependencies] +syntect = "5.0" +pulldown-cmark = "0.13.0" [features] -default = ["desktop"] web = ["dioxus/web"] desktop = ["dioxus/desktop"] +fullstack = ["dioxus/fullstack"] +server = ["dioxus/server"] diff --git a/preview/Dioxus.toml b/preview/Dioxus.toml new file mode 100644 index 00000000..0028540a --- /dev/null +++ b/preview/Dioxus.toml @@ -0,0 +1,6 @@ +[application] +name = "Dioxus Preview" +version = "0.1.0" + +[web.app] +base_path = "components" diff --git a/preview/assets/dioxus-logo.png b/preview/assets/dioxus-logo.png new file mode 100644 index 00000000..4ad62768 Binary files /dev/null and b/preview/assets/dioxus-logo.png differ diff --git a/preview/assets/dioxus_color.svg b/preview/assets/dioxus_color.svg new file mode 100644 index 00000000..387e008e --- /dev/null +++ b/preview/assets/dioxus_color.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + + + + + + + diff --git a/preview/assets/hero.css b/preview/assets/hero.css index 2b71cdf1..45d17cc2 100644 --- a/preview/assets/hero.css +++ b/preview/assets/hero.css @@ -1,12 +1,14 @@ #hero { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; padding: 50px; margin: 0; - background: rgb(11,104,195); - background: linear-gradient(90deg, rgba(11,104,195,1) 0%, rgba(5,22,154,1) 100%); } #hero>h1, #hero>h2 { - color: #ffffff; + color: var(--text-color); font-family: Arial, Helvetica, sans-serif; font-size: 1.5rem; font-weight: 500; @@ -26,4 +28,27 @@ #hero-separator { margin-bottom: 50px; height: 2px; -} \ No newline at end of file +} + +#hero-search-container { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + max-width: 800px; + margin: auto; +} + +#hero-search-input { + width: 100%; + margin: 20px 0; + padding: 10px; + color: var(--text-color); + border: 1px solid var(--border-color); + border-radius: 4px; + background-color: var(--brighter-background-color); + box-sizing: border-box; + margin: 2em auto; + padding: 10px 20px; +} diff --git a/preview/assets/hover-card.css b/preview/assets/hover-card.css deleted file mode 100644 index 528aeb1b..00000000 --- a/preview/assets/hover-card.css +++ /dev/null @@ -1,218 +0,0 @@ -/* Hover Card Styles */ -.hover-card { - position: relative; - display: inline-block; -} - -.hover-card-trigger { - display: inline-block; - cursor: pointer; -} - -.hover-card-content { - position: absolute; - z-index: 1000; - min-width: 200px; - padding: 12px 16px; - border-radius: 6px; - background-color: white; - color: #333; - font-size: 14px; - line-height: 1.5; - box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); - border: 1px solid #eaeaea; - animation: hoverCardFadeIn 0.2s ease-in-out; -} - -/* Positioning based on side */ -.hover-card-content[data-side="top"] { - position: absolute; - bottom: 100%; - margin-bottom: 10px; - left: 50%; - transform: translateX(-50%); -} - -.hover-card-content[data-side="right"] { - position: absolute; - left: 100%; - top: 50%; - transform: translateY(-50%); - margin-left: 10px; -} - -.hover-card-content[data-side="bottom"] { - position: absolute; - top: 100%; - margin-top: 10px; - left: 50%; - transform: translateX(-50%); -} - -.hover-card-content[data-side="left"] { - position: absolute; - right: 100%; - top: 50%; - transform: translateY(-50%); - margin-right: 10px; -} - -/* Alignment styles for top and bottom */ -.hover-card-content[data-side="top"][data-align="start"], -.hover-card-content[data-side="bottom"][data-align="start"] { - left: 0; - transform: none; -} - -.hover-card-content[data-side="top"][data-align="center"], -.hover-card-content[data-side="bottom"][data-align="center"] { - left: 50%; - transform: translateX(-50%); -} - -.hover-card-content[data-side="top"][data-align="end"], -.hover-card-content[data-side="bottom"][data-align="end"] { - left: auto; - right: 0; - transform: none; -} - -/* Alignment styles for left and right */ -.hover-card-content[data-side="left"][data-align="start"], -.hover-card-content[data-side="right"][data-align="start"] { - top: 0; - transform: none; -} - -.hover-card-content[data-side="left"][data-align="center"], -.hover-card-content[data-side="right"][data-align="center"] { - top: 50%; - transform: translateY(-50%); -} - -.hover-card-content[data-side="left"][data-align="end"], -.hover-card-content[data-side="right"][data-align="end"] { - top: auto; - bottom: 0; - transform: none; -} - -/* Animation */ -@keyframes hoverCardFadeIn { - from { - opacity: 0; - transform: scale(0.95); - } - - to { - opacity: 1; - transform: scale(1); - } -} - -/* State styles */ -.hover-card[data-disabled="true"] .hover-card-trigger { - cursor: default; -} - -.hover-card-content[data-state="closed"] { - display: none; -} - -/* Example specific styles */ -.user-card { - display: flex; - flex-direction: column; - gap: 8px; -} - -.user-card-header { - display: flex; - align-items: center; - gap: 12px; -} - -.user-card-avatar { - width: 48px; - height: 48px; - border-radius: 50%; - object-fit: cover; -} - -.user-card-name { - margin: 0; - font-size: 16px; - font-weight: 600; -} - -.user-card-username { - margin: 0; - font-size: 14px; - color: #666; -} - -.user-card-bio { - margin: 8px 0; - font-size: 14px; - color: #333; -} - -.user-card-stats { - display: flex; - gap: 16px; - margin-top: 8px; -} - -.user-card-stat { - display: flex; - flex-direction: column; -} - -.user-card-stat-value { - font-weight: 600; - font-size: 14px; -} - -.user-card-stat-label { - font-size: 12px; - color: #666; -} - -.product-card { - display: flex; - flex-direction: column; - gap: 8px; -} - -.product-card-image { - width: 100%; - height: 120px; - object-fit: cover; - border-radius: 4px; -} - -.product-card-title { - margin: 0; - font-size: 16px; - font-weight: 600; -} - -.product-card-price { - font-size: 14px; - font-weight: 600; - color: #0070f3; -} - -.product-card-description { - margin: 8px 0; - font-size: 14px; - color: #333; -} - -.product-card-rating { - display: flex; - align-items: center; - gap: 4px; - font-size: 14px; - color: #f5a623; -} diff --git a/preview/assets/main.css b/preview/assets/main.css index dd62b809..d71f2587 100644 --- a/preview/assets/main.css +++ b/preview/assets/main.css @@ -1,5 +1,260 @@ +/* Theme style variables */ +:root { + --highlight-color-main: #dd7230; + --highlight-color-secondary: #eb5160; + --highlight-color-tertiary: #2b7fff; +} + +@media (prefers-color-scheme: light) { + :root { + --background-color: #fff; + --brighter-background-color: #fbfbfb; + --dim-background-color: oklch(0.967 0.003 264.542); + --hover-background-color: #dadada; + --focused-background-color: #d7d7d7; + --contrast-background-color: #0d0d0d; + --text-color: #000; + --dim-text-color: rgb(43, 43, 43); + --border-color: #000; + --dim-border-color: rgb(43, 43, 43); + --muted-text-color: #b0b0b0; + --focused-border-color: #2b7fff; + --success-background-color: #ecfdf5; + --success-text-color: #10b981; + --warning-background-color: #fffbeb; + --warning-text-color: #f59e0b; + --error-background-color: #fef2f2; + --error-text-color: #ef4444; + --info-background-color: #e0f2fe; + --info-text-color: #0284c7; + } +} + +@media (prefers-color-scheme: dark) { + :root { + --background-color: #000; + --brighter-background-color: #0e0e0e; + --dim-background-color: #141313; + --hover-background-color: #292929; + --focused-background-color: #2c2b2b; + --contrast-background-color: #e6e6e6; + --text-color: #fff; + --dim-text-color: rgb(220, 220, 220); + --border-color: #fff; + --dim-border-color: rgb(43, 43, 43); + --muted-text-color: #b0b0b0; + --focused-border-color: #2b7fff; + --success-background-color: #02271c; + --success-text-color: #b6fae3; + --warning-background-color: #342203; + --warning-text-color: #feeac7; + --error-background-color: #360e0e; + --error-text-color: #e0baba; + --info-background-color: #0c1f2b; + --info-text-color: #b3d7e6; + } +} + +@media (prefers-color-scheme: light) { + .code-block-dark { + display: none; + } +} + +@media (prefers-color-scheme: dark) { + .code-block-light { + display: none; + } +} + body { margin: 0; padding: 0; + color: var(--text-color); + background-color: var(--background-color); +} + +.navbar { + display: flex; + align-items: center; + justify-content: space-between; + position: sticky; + padding: 1rem; + top: 0; + z-index: 1000; + background-color: var(--brighter-background-color); + border-bottom: 1px solid var(--border-color); +} + +.navbar-link { + color: var(--text-color); + text-decoration: none; + font-size: 1.2em; + font-weight: bold; + padding: 0.5em 1em; +} + +.navbar-link:hover { + color: var(--dim-text-color); +} + +.navbar-links { + display: flex; + gap: 1rem; +} + +.navbar-brand { + display: flex; + text-decoration: none; + align-items: center; + font-size: 1.5em; + font-weight: bold; + color: var(--text-color); +} + +/* Code block styles */ +.code-block { + font-family: "Courier New", Courier, monospace; + border-radius: 4px; + overflow: scroll; + width: 100%; + height: 100%; + max-height: 80vh; + box-sizing: border-box; +} + +.code-block[data-collapsed="true"] { + height: 10em; + backdrop-filter: blur(1px); + mask: linear-gradient( + to bottom, + rgba(0, 0, 0, 1) 12.5%, + rgba(0, 0, 0, 1) 25%, + rgba(0, 0, 0, 1) 37.5%, + rgba(0, 0, 0, 0) 100% + ); + overflow: hidden; + user-select: none; + -webkit-user-select: none; +} + +.copy-button { + display: flex; + align-items: center; + justify-content: center; + position: absolute; + top: 0.5em; + right: 0.5em; + background: none; + color: var(--text-color); + border: none; + border-radius: 4px; + cursor: pointer; +} + +.copy-button:hover { + color: var(--highlight-color-tertiary); +} + +.copy-button[data-copied="true"] { + color: var(--success-text-color); +} + +/* Demo frame styles */ +.component-title { + font-size: 1.5em; + margin: 0.5em 0; + text-transform: capitalize; +} + +.component-preview { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100vw; +} + +.component-preview-separator { + width: 100%; + height: 1px; + background-color: var(--dim-border-color); +} + +.component-preview-contents { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background-color: var(--dim-background-color); + border: 1px solid var(--dim-border-color); + border-radius: 8px; + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); + box-sizing: border-box; + margin: 20px 0; + width: 75vw; } +.component-preview-frame { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + min-height: 25vh; + max-height: 100%; + border-top-right-radius: 0.5em; + border-top-left-radius: 0.5em; + background-color: var(--dim-background-color); + padding: 20px; + box-sizing: border-box; +} + +/* component info styles */ +.component-title { + font-size: 2em; + width: 100%; + text-align: center; + margin-bottom: 20px; + margin-top: 20px; + text-transform: capitalize; +} + +.component-description { + font-size: 1em; + margin: 5vw; +} + +.component-code { + width: 100%; +} + +/* Masonry styles */ +.masonry-with-columns { + display: flex; + flex-wrap: wrap; + padding: 0 0 0 1rem; +} +.masonry-with-columns .masonry-preview-frame { + display: flex; + flex-direction: column; + align-items: center; + min-height: 10rem; + max-width: calc(100vw - 2rem); + margin: 0 1rem 1rem 0; + padding: 3rem; + flex: 1 0 auto; + border-radius: 0.5rem; + background-color: var(--dim-background-color); + border: 1px solid var(--dim-border-color); + box-sizing: border-box; +} + +.masonry-with-columns .masonry-component-frame { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + height: 100%; + width: 100%; +} diff --git a/preview/assets/prism.css b/preview/assets/prism.css new file mode 100644 index 00000000..ea89f186 --- /dev/null +++ b/preview/assets/prism.css @@ -0,0 +1,3 @@ +/* PrismJS 1.30.0 +https://prismjs.com/download#themes=prism-twilight&languages=rust */ +code[class*=language-],pre[class*=language-]{color:#fff;background:0 0;font-family:Consolas,Monaco,'Andale Mono','Ubuntu Mono',monospace;font-size:1em;text-align:left;text-shadow:0 -.1em .2em #000;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}:not(pre)>code[class*=language-],pre[class*=language-]{background:#141414}pre[class*=language-]{border-radius:.5em;border:.3em solid #545454;box-shadow:1px 1px .5em #000 inset;margin:.5em 0;overflow:auto;padding:1em}pre[class*=language-]::-moz-selection{background:#27292a}pre[class*=language-]::selection{background:#27292a}code[class*=language-] ::-moz-selection,code[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection{text-shadow:none;background:hsla(0,0%,93%,.15)}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:hsla(0,0%,93%,.15)}:not(pre)>code[class*=language-]{border-radius:.3em;border:.13em solid #545454;box-shadow:1px 1px .3em -.1em #000 inset;padding:.15em .2em .05em;white-space:normal}.token.cdata,.token.comment,.token.doctype,.token.prolog{color:#777}.token.punctuation{opacity:.7}.token.namespace{opacity:.7}.token.boolean,.token.deleted,.token.number,.token.tag{color:#ce6849}.token.builtin,.token.constant,.token.keyword,.token.property,.token.selector,.token.symbol{color:#f9ed99}.language-css .token.string,.style .token.string,.token.attr-name,.token.attr-value,.token.char,.token.entity,.token.inserted,.token.operator,.token.string,.token.url,.token.variable{color:#909e6a}.token.atrule{color:#7385a5}.token.important,.token.regex{color:#e8c062}.token.bold,.token.important{font-weight:700}.token.italic{font-style:italic}.token.entity{cursor:help}.language-markup .token.attr-name,.language-markup .token.punctuation,.language-markup .token.tag{color:#ac885c}.token{position:relative;z-index:1}.line-highlight.line-highlight{background:hsla(0,0%,33%,.25);background:linear-gradient(to right,hsla(0,0%,33%,.1) 70%,hsla(0,0%,33%,0));border-bottom:1px dashed #545454;border-top:1px dashed #545454;margin-top:.75em;z-index:0}.line-highlight.line-highlight:before,.line-highlight.line-highlight[data-end]:after{background-color:#8693a6;color:#f4f1ef} diff --git a/preview/assets/prism.js b/preview/assets/prism.js new file mode 100644 index 00000000..df1b6010 --- /dev/null +++ b/preview/assets/prism.js @@ -0,0 +1,4 @@ +/* PrismJS 1.30.0 +https://prismjs.com/download#themes=prism-twilight&languages=rust */ +var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(e){var n=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,r={},a={manual:e.Prism&&e.Prism.manual,disableWorkerMessageHandler:e.Prism&&e.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof i?new i(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/=g.reach);A+=w.value.length,w=w.next){var P=w.value;if(n.length>e.length)return;if(!(P instanceof i)){var E,S=1;if(y){if(!(E=l(b,A,e,m))||E.index>=e.length)break;var L=E.index,O=E.index+E[0].length,C=A;for(C+=w.value.length;L>=C;)C+=(w=w.next).value.length;if(A=C-=w.value.length,w.value instanceof i)continue;for(var j=w;j!==n.tail&&(Cg.reach&&(g.reach=W);var I=w.prev;if(_&&(I=u(n,I,_),A+=_.length),c(n,I,S),w=u(n,I,new i(f,p?a.tokenize(N,p):N,k,N)),M&&u(n,w,M),S>1){var T={cause:f+","+d,reach:W};o(e,n,t,w.prev,A,T),g&&T.reach>g.reach&&(g.reach=T.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function u(e,n,t){var r=n.next,a={value:t,prev:n,next:r};return n.next=a,r.prev=a,e.length++,a}function c(e,n,t){for(var r=n.next,a=0;a"+i.content+""},!e.document)return e.addEventListener?(a.disableWorkerMessageHandler||e.addEventListener("message",(function(n){var t=JSON.parse(n.data),r=t.language,i=t.code,l=t.immediateClose;e.postMessage(a.highlight(i,a.languages[r],r)),l&&e.close()}),!1),a):a;var g=a.util.currentScript();function f(){a.manual||a.highlightAll()}if(g&&(a.filename=g.src,g.hasAttribute("data-manual")&&(a.manual=!0)),!a.manual){var h=document.readyState;"loading"===h||"interactive"===h&&g&&g.defer?document.addEventListener("DOMContentLoaded",f):window.requestAnimationFrame?window.requestAnimationFrame(f):window.setTimeout(f,16)}return a}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism); +!function(e){for(var a="/\\*(?:[^*/]|\\*(?!/)|/(?!\\*)|)*\\*/",t=0;t<2;t++)a=a.replace(//g,(function(){return a}));a=a.replace(//g,(function(){return"[^\\s\\S]"})),e.languages.rust={comment:[{pattern:RegExp("(^|[^\\\\])"+a),lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/b?"(?:\\[\s\S]|[^\\"])*"|b?r(#*)"(?:[^"]|"(?!\1))*"\1/,greedy:!0},char:{pattern:/b?'(?:\\(?:x[0-7][\da-fA-F]|u\{(?:[\da-fA-F]_*){1,6}\}|.)|[^\\\r\n\t'])'/,greedy:!0},attribute:{pattern:/#!?\[(?:[^\[\]"]|"(?:\\[\s\S]|[^\\"])*")*\]/,greedy:!0,alias:"attr-name",inside:{string:null}},"closure-params":{pattern:/([=(,:]\s*|\bmove\s*)\|[^|]*\||\|[^|]*\|(?=\s*(?:\{|->))/,lookbehind:!0,greedy:!0,inside:{"closure-punctuation":{pattern:/^\||\|$/,alias:"punctuation"},rest:null}},"lifetime-annotation":{pattern:/'\w+/,alias:"symbol"},"fragment-specifier":{pattern:/(\$\w+:)[a-z]+/,lookbehind:!0,alias:"punctuation"},variable:/\$\w+/,"function-definition":{pattern:/(\bfn\s+)\w+/,lookbehind:!0,alias:"function"},"type-definition":{pattern:/(\b(?:enum|struct|trait|type|union)\s+)\w+/,lookbehind:!0,alias:"class-name"},"module-declaration":[{pattern:/(\b(?:crate|mod)\s+)[a-z][a-z_\d]*/,lookbehind:!0,alias:"namespace"},{pattern:/(\b(?:crate|self|super)\s*)::\s*[a-z][a-z_\d]*\b(?:\s*::(?:\s*[a-z][a-z_\d]*\s*::)*)?/,lookbehind:!0,alias:"namespace",inside:{punctuation:/::/}}],keyword:[/\b(?:Self|abstract|as|async|await|become|box|break|const|continue|crate|do|dyn|else|enum|extern|final|fn|for|if|impl|in|let|loop|macro|match|mod|move|mut|override|priv|pub|ref|return|self|static|struct|super|trait|try|type|typeof|union|unsafe|unsized|use|virtual|where|while|yield)\b/,/\b(?:bool|char|f(?:32|64)|[ui](?:8|16|32|64|128|size)|str)\b/],function:/\b[a-z_]\w*(?=\s*(?:::\s*<|\())/,macro:{pattern:/\b\w+!/,alias:"property"},constant:/\b[A-Z_][A-Z_\d]+\b/,"class-name":/\b[A-Z]\w*\b/,namespace:{pattern:/(?:\b[a-z][a-z_\d]*\s*::\s*)*\b[a-z][a-z_\d]*\s*::(?!\s*<)/,inside:{punctuation:/::/}},number:/\b(?:0x[\dA-Fa-f](?:_?[\dA-Fa-f])*|0o[0-7](?:_?[0-7])*|0b[01](?:_?[01])*|(?:(?:\d(?:_?\d)*)?\.)?\d(?:_?\d)*(?:[Ee][+-]?\d+)?)(?:_?(?:f32|f64|[iu](?:8|16|32|64|size)?))?\b/,boolean:/\b(?:false|true)\b/,punctuation:/->|\.\.=|\.{1,3}|::|[{}[\];(),:]/,operator:/[-+*\/%!^]=?|=[=>]?|&[&=]?|\|[|=]?|<>?=?|[@?]/},e.languages.rust["closure-params"].inside.rest=e.languages.rust,e.languages.rust.attribute.inside.string=e.languages.rust.string}(Prism); diff --git a/preview/assets/progress.css b/preview/assets/progress.css deleted file mode 100644 index 115409ce..00000000 --- a/preview/assets/progress.css +++ /dev/null @@ -1,33 +0,0 @@ -.progress { - position: relative; - overflow: hidden; - background: #e2e8f0; - border-radius: 9999px; - width: 300px; - height: 20px; - border: 2px solid #94a3b8; - box-sizing: border-box; -} - -.progress[data-state='indeterminate'] .progress-indicator { - width: 50%; - animation: indeterminate 1s infinite linear; -} - -.progress-indicator { - height: 100%; - background-color: #3b82f6; - transition: width 250ms ease; - width: var(--progress-value, 0%); - /* Use CSS variable for width */ -} - -@keyframes indeterminate { - 0% { - transform: translateX(-100%); - } - - 100% { - transform: translateX(200%); - } -} \ No newline at end of file diff --git a/preview/assets/tabs.css b/preview/assets/tabs.css deleted file mode 100644 index e8989422..00000000 --- a/preview/assets/tabs.css +++ /dev/null @@ -1,55 +0,0 @@ -.tabs { - width: 100%; - display: flex; - flex-direction: column; - gap: 20px; -} - -.tabs-list { - display: flex; - border-bottom: 1px solid #e2e8f0; - gap: 2px; -} - -.tabs-trigger { - all: unset; - padding: 8px 16px; - font-size: 14px; - color: #64748b; - cursor: pointer; - border-radius: 4px 4px 0 0; - transition: all 0.2s; -} - -.tabs-trigger:hover { - color: #0f172a; - background: #f8fafc; -} - -.tabs-trigger[data-state="active"] { - color: #0f172a; - background: #f1f5f9; - border-bottom: 2px solid #3b82f6; - margin-bottom: -1px; -} - -.tabs-trigger:focus-visible { - outline: 2px solid #3b82f6; - outline-offset: -2px; -} - -.tabs-trigger[data-disabled="true"] { - opacity: 0.5; - cursor: not-allowed; -} - -.tabs-content { - padding: 16px; - background: #f8fafc; - border-radius: 4px; - font-size: 14px; -} - -.tabs-content[data-state="inactive"] { - display: none; -} \ No newline at end of file diff --git a/preview/build.rs b/preview/build.rs new file mode 100644 index 00000000..eb4cdb1c --- /dev/null +++ b/preview/build.rs @@ -0,0 +1,71 @@ +use std::sync::OnceLock; +fn main() { + let out_dir = std::env::var("OUT_DIR").unwrap(); + let out_dir = std::path::PathBuf::from(out_dir); + println!("cargo:rerun-if-changed=src/components"); + for folder in std::fs::read_dir("src/components").unwrap().flatten() { + if !folder.file_type().unwrap().is_dir() { + continue; + } + let folder_name = folder.file_name(); + let folder_name = folder_name.to_string_lossy(); + let out_folder = out_dir.join(&*folder_name); + std::fs::create_dir_all(&out_folder).unwrap(); + for file in std::fs::read_dir(folder.path()).unwrap().flatten() { + if file.file_type().unwrap().is_dir() { + continue; + } + if file.path().extension() == Some(std::ffi::OsStr::new("md")) { + let markdown = process_markdown_to_html(&file.path()); + let out_file_path = out_folder.join(file.file_name()).with_extension("html"); + std::fs::write(out_file_path, markdown).unwrap(); + continue; + } + let file_name = file.file_name(); + let file_name = file_name.to_string_lossy(); + for theme in ["base16-ocean.dark", "base16-ocean.light"] { + let html = highlight_file_to(&file.path(), theme); + let out_file_path = out_folder.join(format!("{file_name}.{theme}.html")); + std::fs::write(out_file_path, html).unwrap(); + } + } + } +} +fn highlight_file_to(file_path: &std::path::Path, theme: &str) -> String { + use std::io::BufRead; + use syntect::easy::HighlightFile; + use syntect::highlighting::{Style, ThemeSet}; + use syntect::html::{IncludeBackground, styled_line_to_highlighted_html}; + use syntect::parsing::SyntaxSet; + static SYNTAX_SET: OnceLock = OnceLock::new(); + static THEME_SET: OnceLock = OnceLock::new(); + let ss = SYNTAX_SET.get_or_init(SyntaxSet::load_defaults_newlines); + let ts = THEME_SET.get_or_init(ThemeSet::load_defaults); + let mut all_html = String::new(); + let mut highlighter = HighlightFile::new(&file_path, &ss, &ts.themes[theme]).unwrap(); + let mut line = String::new(); + while highlighter.reader.read_line(&mut line).unwrap_or_default() > 0 { + { + let regions: Vec<(Style, &str)> = highlighter + .highlight_lines + .highlight_line(&line, &ss) + .unwrap(); + let html = + styled_line_to_highlighted_html(®ions[..], IncludeBackground::No).unwrap(); + all_html += &html; + } + line.clear(); + } + all_html +} +fn process_markdown_to_html(markdown_path: &std::path::Path) -> String { + use pulldown_cmark::{Options, Parser}; + let markdown_input = + std::fs::read_to_string(markdown_path).expect("Failed to read markdown file"); + let mut options = Options::empty(); + options.insert(Options::ENABLE_GFM); + let parser = Parser::new_ext(&markdown_input, options); + let mut html_output = String::new(); + pulldown_cmark::html::push_html(&mut html_output, parser); + html_output +} diff --git a/preview/src/components/accordion/docs.md b/preview/src/components/accordion/docs.md new file mode 100644 index 00000000..57ca506e --- /dev/null +++ b/preview/src/components/accordion/docs.md @@ -0,0 +1,18 @@ +The accordion component is used to display collapsible content panels for presenting information in a limited amount of space. It allows users to expand and collapse sections to view more or less content. + +## Component Structure + +```rust +// The accordion component must wrap all accordion items. +Accordion { + // Each accordion item contains both a trigger the expanded contents of the item. + AccordionItem { + // Each item must have an index starting from 0 to control where the item is placed. + index: 0, + // The trigger is used to expand or collapse the item. + AccordionTrigger {} + // The content that is shown when the item is expanded. + AccordionContent {} + } +} +``` \ No newline at end of file diff --git a/preview/src/components/accordion/mod.rs b/preview/src/components/accordion/mod.rs new file mode 100644 index 00000000..4a71f31a --- /dev/null +++ b/preview/src/components/accordion/mod.rs @@ -0,0 +1,36 @@ +use dioxus::prelude::*; +use dioxus_primitives::accordion::{ + Accordion, AccordionContent, AccordionItem, AccordionTrigger, +}; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/accordion/style.css"), + } + Accordion { + class: "accordion", + allow_multiple_open: false, + horizontal: false, + for i in 0..4 { + AccordionItem { + class: "accordion-item", + index: i, + on_change: move |open| { + tracing::info!("{open};"); + }, + on_trigger_click: move || { + tracing::info!("trigger"); + }, + AccordionTrigger { class: "accordion-trigger", "the quick brown fox" } + AccordionContent { class: "accordion-content", + div { class: "accordion-content-inner", + p { "lorem ipsum lorem ipsum" } + } + } + } + } + } + } +} diff --git a/preview/assets/accordion.css b/preview/src/components/accordion/style.css similarity index 75% rename from preview/assets/accordion.css rename to preview/src/components/accordion/style.css index 8c66de30..3ad21bcc 100644 --- a/preview/assets/accordion.css +++ b/preview/src/components/accordion/style.css @@ -1,14 +1,14 @@ .accordion { - width: 500px; - background-color: rgb(223, 223, 223); + background-color: var(--brighter-background-color); } .accordion-trigger { border: none; outline: none; - border-bottom: 1px solid rgb(102, 102, 102); + border-bottom: 1px solid var(--dim-border-color); width: 100%; - background-color: rgb(160, 160, 160); + color: var(--text-color); + background-color: var(--brighter-background-color); padding: 10px; text-align: left; font-weight: bold; diff --git a/preview/src/components/aspect_ratio/docs.md b/preview/src/components/aspect_ratio/docs.md new file mode 100644 index 00000000..c06540c9 --- /dev/null +++ b/preview/src/components/aspect_ratio/docs.md @@ -0,0 +1,12 @@ +The AspectRatio component is used to maintain a specific aspect ratio for its children. This is particularly useful for responsive designs where you want to ensure that an element retains its proportions regardless of the screen size. + +## Component Structure + +```rust +AspectRatio { + // The aspect ratio to maintain (width / height) + ratio: 4. / 3., + // The children of the AspectRatio component will be rendered within it. + {children} +} +``` diff --git a/preview/src/components/aspect_ratio/mod.rs b/preview/src/components/aspect_ratio/mod.rs new file mode 100644 index 00000000..bd53c77a --- /dev/null +++ b/preview/src/components/aspect_ratio/mod.rs @@ -0,0 +1,22 @@ +use dioxus::prelude::*; +use dioxus_primitives::aspect_ratio::AspectRatio; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/aspect_ratio/style.css"), + } + div { + class: "aspect-ratio-container", + width: "10em", + min_width: "30vw", + AspectRatio { ratio: 4.0 / 3.0, + img { + class: "aspect-ratio-image", + src: asset!("/assets/dioxus-logo.png", ImageAssetOptions::new().with_avif()), + } + } + } + } +} diff --git a/preview/assets/aspect-ratio.css b/preview/src/components/aspect_ratio/style.css similarity index 66% rename from preview/assets/aspect-ratio.css rename to preview/src/components/aspect_ratio/style.css index 18661bc7..006e1e76 100644 --- a/preview/assets/aspect-ratio.css +++ b/preview/src/components/aspect_ratio/style.css @@ -1,8 +1,10 @@ .aspect-ratio-container { - width: 300px; border-radius: 6px; overflow: hidden; box-shadow: 0 2px 10px #000000; + background-color: var(--dim-background-color); + padding: 1rem; + box-sizing: border-box; } .aspect-ratio-image { diff --git a/preview/src/components/avatar/docs.md b/preview/src/components/avatar/docs.md new file mode 100644 index 00000000..b9cd284f --- /dev/null +++ b/preview/src/components/avatar/docs.md @@ -0,0 +1,25 @@ +The Avatar component is used to display a user's profile picture or an icon representing the user. It handles the loading state of the image and can display a fallback icon if the image fails to load. + +## Component Structure + +```rust +// All avatar contents must be wrapped in the Avatar component. +Avatar { + on_state_change: |state: AvatarState| { + // This callback is triggered when the avatar's state changes. The state can be used to determine if the image is loading, loaded, or failed to load. + }, + // The avatar image component is used to display the user's profile picture. + AvatarImage { + // The source URL of the image to be displayed. + src: "", + // The alt text for the image, used for accessibility. + alt: "", + } + // The avatar fallback component is used to display an icon or text when the image fails to load. + AvatarFallback { + // The content to display when the image fails to load. + // This can be an icon or text representing the user. + {children} + } +} +``` diff --git a/preview/src/components/avatar/mod.rs b/preview/src/components/avatar/mod.rs new file mode 100644 index 00000000..b63b432f --- /dev/null +++ b/preview/src/components/avatar/mod.rs @@ -0,0 +1,72 @@ +use dioxus::prelude::*; +use dioxus_primitives::avatar::{Avatar, AvatarFallback, AvatarImage}; +#[component] +pub(super) fn Demo() -> Element { + let mut avatar_state = use_signal(|| "No state yet".to_string()); + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/avatar/style.css"), + } + div { class: "avatar-example-section", + div { class: "avatar-example", + div { class: "avatar-item", + p { class: "avatar-label", "Basic Usage" } + Avatar { + class: "avatar", + on_state_change: move |state| { + avatar_state.set(format!("Avatar 1: {:?}", state)); + }, + AvatarImage { + src: asset!("/assets/dioxus-logo.png", ImageAssetOptions::new().with_avif()), + alt: "User avatar", + } + AvatarFallback { class: "avatar-fallback", "UA" } + } + } + div { class: "avatar-item", + p { class: "avatar-label", "Error State" } + Avatar { + class: "avatar", + on_state_change: move |state| { + avatar_state.set(format!("Avatar 2: {:?}", state)); + }, + AvatarImage { + src: "https://invalid-url.example/image.jpg", + alt: "Invalid image", + } + AvatarFallback { class: "avatar-fallback", "JD" } + } + } + div { class: "avatar-item", + p { class: "avatar-label", "Emoji Fallback" } + Avatar { + class: "avatar", + on_state_change: move |state| { + avatar_state.set(format!("Avatar 3: {:?}", state)); + }, + AvatarImage { + src: "https://invalid-url.example/image.jpg", + alt: "Invalid image", + } + AvatarFallback { class: "avatar-fallback", "👤" } + } + } + div { class: "avatar-item", + p { class: "avatar-label", "Large Size" } + Avatar { + class: "avatar avatar-lg", + on_state_change: move |state| { + avatar_state.set(format!("Avatar 4: {:?}", state)); + }, + AvatarImage { + src: asset!("/assets/dioxus-logo.png", ImageAssetOptions::new().with_avif()), + alt: "Large avatar", + } + AvatarFallback { class: "avatar-fallback", "LG" } + } + } + } + } + } +} diff --git a/preview/assets/avatar.css b/preview/src/components/avatar/style.css similarity index 87% rename from preview/assets/avatar.css rename to preview/src/components/avatar/style.css index 7a1af84f..541d6aa4 100644 --- a/preview/assets/avatar.css +++ b/preview/src/components/avatar/style.css @@ -1,20 +1,10 @@ /* Avatar Example Layout */ -.avatar-example-section { - margin-bottom: 2rem; -} - -.avatar-example-section h4 { - margin-bottom: 1rem; - font-size: 1.2rem; - color: #334155; -} - .avatar-example { display: flex; flex-wrap: wrap; gap: 1.5rem; padding: 1rem; - background: #f8fafc; + background: var(--brighter-background-color); border-radius: 8px; } @@ -27,7 +17,7 @@ .avatar-label { font-size: 0.875rem; - color: #64748b; + color: var(--text-color); margin: 0; } @@ -37,8 +27,8 @@ height: 64px; border-radius: 50%; overflow: hidden; - background: #e2e8f0; - color: #64748b; + background: var(--brighter-background-color); + color: var(--text-color); font-weight: 500; display: inline-flex; align-items: center; @@ -123,5 +113,5 @@ background: #f0f0f0; border-radius: 4px; font-family: monospace; - color: #334155; + color: var(--dim-text-color); } \ No newline at end of file diff --git a/preview/src/components/calendar/docs.md b/preview/src/components/calendar/docs.md new file mode 100644 index 00000000..20a1043c --- /dev/null +++ b/preview/src/components/calendar/docs.md @@ -0,0 +1,27 @@ +The Calendar component is used to display a calendar interface, allowing users to select dates. It provides a grid layout of days for a specific month and year. + +## Component Structure + +```rust +Calendar { + // The currently selected date in the calendar (if any). + selected_date, + on_date_change: |date: Option| { + // This callback is triggered when a date is selected in the calendar. + // The date parameter contains the selected date. + }, + // The current view date of the calendar, which determines the month and year displayed. + view_date, + on_view_change: |date: CalendarDate| { + // This callback is triggered when the view date changes. + // The date parameter contains the new view date. + }, + // The calendar header should contain the navigation controls and the title for the calendar. + CalendarHeader { + // The calendar navigation handles switching between months and years within the calendar view. + CalendarNavigation {} + } + // The calendar grid displays the days of the month in a grid layout. + CalendarGrid {} +} +``` diff --git a/preview/src/components/calendar/mod.rs b/preview/src/components/calendar/mod.rs new file mode 100644 index 00000000..9a0984f2 --- /dev/null +++ b/preview/src/components/calendar/mod.rs @@ -0,0 +1,40 @@ +use dioxus::prelude::*; +use dioxus_primitives::calendar::{ + Calendar, CalendarDate, CalendarGrid, CalendarHeader, CalendarNavigation, +}; +#[component] +pub(super) fn Demo() -> Element { + let mut selected_date = use_signal(|| None::); + let mut view_date = use_signal(|| CalendarDate::new(2024, 5, 15)); + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/calendar/style.css"), + } + div { class: "calendar-example", style: "padding: 20px;", + div { class: "calendar", + Calendar { + selected_date: selected_date(), + on_date_change: move |date| { + tracing::info!("Selected date: {:?}", date); + selected_date.set(date); + }, + view_date: view_date(), + on_view_change: move |new_view: CalendarDate| { + tracing::info!("View changed to: {}-{}", new_view.year, new_view.month); + view_date.set(new_view); + }, + CalendarHeader { CalendarNavigation {} } + CalendarGrid {} + } + } + div { class: "selected-date", style: "margin-top: 20px;", + if let Some(date) = selected_date() { + p { style: "font-weight: bold;", "Selected date: {date}" } + } else { + p { "No date selected" } + } + } + } + } +} diff --git a/preview/assets/calendar.css b/preview/src/components/calendar/style.css similarity index 78% rename from preview/assets/calendar.css rename to preview/src/components/calendar/style.css index 501ddcd3..c3b2847f 100644 --- a/preview/assets/calendar.css +++ b/preview/src/components/calendar/style.css @@ -1,9 +1,9 @@ /* Calendar Container */ .calendar { - width: 300px; - border: 1px solid #ddd; + width: 100%; + border: 1px solid var(--dim-border-color); border-radius: 8px; - background-color: #fff; + background-color: var(--background-color); box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; } @@ -14,13 +14,13 @@ align-items: center; justify-content: space-between; padding: 12px; - border-bottom: 1px solid #eee; + border-bottom: 1px solid var(--dim-border-color); } .calendar-nav-title { font-weight: 600; font-size: 16px; - color: #333; + color: var(--text-color); } .calendar-nav-prev, @@ -28,7 +28,7 @@ background: none; border: none; font-size: 18px; - color: #666; + color: var(--dim-text-color); cursor: pointer; width: 30px; height: 30px; @@ -40,13 +40,13 @@ .calendar-nav-prev:hover, .calendar-nav-next:hover { - background-color: #f5f5f5; - color: #333; + background-color: var(--hover-background-color); + color: var(--text-color); } .calendar-nav-prev:focus, .calendar-nav-next:focus { - outline: 2px solid #0066cc; + outline: 2px solid var(--focused-border-color); outline-offset: 2px; } @@ -71,7 +71,7 @@ text-align: center; font-size: 12px; font-weight: 600; - color: #666; + color: var(--muted-text-color); padding: 4px; } @@ -103,30 +103,30 @@ background: none; border-radius: 4px; cursor: pointer; - color: #333; + color: var(--dim-text-color); } .calendar-grid-cell:hover:not([data-disabled="true"]) { - background-color: #f0f0f0; + background-color: var(--hover-background-color); } .calendar-grid-cell:focus { - outline: 2px solid #0066cc; + outline: 2px solid var(--focused-border-color); outline-offset: 2px; } .calendar-grid-cell[data-disabled="true"] { - color: #ccc; + color: var(--dim-text-color); cursor: not-allowed; } .calendar-grid-cell[data-selected="true"] { - background-color: #0066cc; - color: white; + background-color: var(--focused-border-color); + color: var(--text-color); } .calendar-grid-cell[data-today="true"]:not([data-selected="true"]) { - border: 2px solid #0066cc; + border: 2px solid var(--focused-border-color); font-weight: bold; } @@ -139,8 +139,8 @@ align-items: center; justify-content: center; font-size: 12px; - color: #999; - background-color: #f5f5f5; + color: var(--dim-text-color); + background-color: var(--background-color); border-radius: 4px; } diff --git a/preview/src/components/checkbox/docs.md b/preview/src/components/checkbox/docs.md new file mode 100644 index 00000000..22e59d1d --- /dev/null +++ b/preview/src/components/checkbox/docs.md @@ -0,0 +1,14 @@ +The Checkbox component is used to create an accessible checkbox input. + +## Component Structure + +```rust +// The checkbox component creates a checkbox button +Checkbox { + // The checkbox indicator is a child component which will only be visible when the checkbox is checked. + CheckboxIndicator { + // The content of the checkbox indicator, typically an icon or image. + {children} + } +} +``` diff --git a/preview/src/components/checkbox/mod.rs b/preview/src/components/checkbox/mod.rs new file mode 100644 index 00000000..a86b396f --- /dev/null +++ b/preview/src/components/checkbox/mod.rs @@ -0,0 +1,14 @@ +use dioxus::prelude::*; +use dioxus_primitives::checkbox::{Checkbox, CheckboxIndicator}; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/checkbox/style.css"), + } + Checkbox { id: "tos-check", name: "tos-check", + CheckboxIndicator { "✓" } + } + } +} diff --git a/preview/src/components/checkbox/style.css b/preview/src/components/checkbox/style.css new file mode 100644 index 00000000..d1cff520 --- /dev/null +++ b/preview/src/components/checkbox/style.css @@ -0,0 +1,23 @@ +#tos-check { + width: 25px; + height: 25px; + margin: 8px 16px; + color: var(--text-color); + background-color: var(--background-color); + border: 1px solid var(--dim-border-color); + border-radius: 4px; + cursor: pointer; + font-size: 14px; +} + +#tos-check:hover { + color: var(--text-color); + background-color: var(--hover-background-color); + transition: background-color 0.2s ease; +} + +#tos-check:focus { + color: var(--text-color); + background-color: var(--focused-background-color); + transition: background-color 0.2s ease; +} diff --git a/preview/src/components/context_menu/docs.md b/preview/src/components/context_menu/docs.md new file mode 100644 index 00000000..54210986 --- /dev/null +++ b/preview/src/components/context_menu/docs.md @@ -0,0 +1,28 @@ +The context menu component can be used to define a context menu that is displayed when the user right-clicks on an element. It can contain various menu items that the user can interact with. + +## Component Structure + +```rust +// The context menu component must wrap all context menu items. +ContextMenu { + // The context menu trigger is the element that will display the context menu when right-clicked. + ContextMenuTrigger { + // The content of the trigger + {children} + } + // The context menu content contains all the items that will be displayed in the context menu. + ContextMenuContent { + // Each context menu item represents an individual action in the context menu. Items are displayed in order based on the order of the index property. + ContextMenuItem { + // The index of the item, used to determine the order in which items are displayed. + index: 0, + // The value of the item which will be passed to the on_select callback when the item is selected. + value: "", + on_select: |value: String| { + // This callback is triggered when the item is selected. + // The value parameter contains the value of the selected item. + }, + } + } +} +``` \ No newline at end of file diff --git a/preview/src/components/context_menu/mod.rs b/preview/src/components/context_menu/mod.rs new file mode 100644 index 00000000..657c7669 --- /dev/null +++ b/preview/src/components/context_menu/mod.rs @@ -0,0 +1,55 @@ +use dioxus::prelude::*; +use dioxus_primitives::context_menu::{ + ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger, +}; +#[component] +pub(super) fn Demo() -> Element { + let mut selected_value = use_signal(String::new); + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/context_menu/style.css"), + } + div { class: "context-menu-example", + ContextMenu { + ContextMenuTrigger { class: "context-menu-trigger", "Right click here to open context menu" } + ContextMenuContent { class: "context-menu-content", + ContextMenuItem { + class: "context-menu-item", + value: "edit".to_string(), + index: 0usize, + on_select: move |value| { + selected_value.set(value); + }, + "Edit" + } + ContextMenuItem { + class: "context-menu-item", + value: "duplicate".to_string(), + index: 1usize, + on_select: move |value| { + selected_value.set(value); + }, + "Duplicate" + } + ContextMenuItem { + class: "context-menu-item", + value: "delete".to_string(), + index: 2usize, + on_select: move |value| { + selected_value.set(value); + }, + "Delete" + } + } + } + div { class: "selected-value", + if selected_value().is_empty() { + "No action selected" + } else { + "Selected action: {selected_value()}" + } + } + } + } +} diff --git a/preview/assets/context-menu.css b/preview/src/components/context_menu/style.css similarity index 71% rename from preview/assets/context-menu.css rename to preview/src/components/context_menu/style.css index 1b305162..db57e10e 100644 --- a/preview/assets/context-menu.css +++ b/preview/src/components/context_menu/style.css @@ -1,12 +1,11 @@ .context-menu-example { padding: 20px; - min-height: 200px; } .context-menu-trigger { padding: 20px; - background: #f5f5f5; - border: 1px solid #ddd; + background: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); border-radius: 4px; cursor: context-menu; user-select: none; @@ -14,11 +13,11 @@ .context-menu-content { min-width: 220px; - background: white; + background: var(--brighter-background-color); border-radius: 6px; padding: 5px; box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1); - border: 1px solid #ddd; + border: 1px solid var(--dim-border-color); animation: slideIn 0.1s ease-out; } @@ -33,17 +32,17 @@ user-select: none; outline: none; font-size: 14px; - color: #333; + color: var(--text-color); display: flex; align-items: center; } .context-menu-item:hover { - background: #f5f5f5; + background: var(--hover-background-color); } .context-menu-item:focus { - background: #eee; + background: var(--focused-background-color); } @keyframes slideIn { diff --git a/preview/src/components/dropdown_menu/docs.md b/preview/src/components/dropdown_menu/docs.md new file mode 100644 index 00000000..36564722 --- /dev/null +++ b/preview/src/components/dropdown_menu/docs.md @@ -0,0 +1,28 @@ +The DropdownMenu component is used to create a dropdown menu that can be triggered by a button click. It allows users to select an option from a list of items. + +## Component Structure + +```rust +// The dropdown menu component must wrap all dropdown items. +DropdownMenu { + // The dropdown menu trigger is the button that will display the dropdown menu when clicked. + DropdownMenuTrigger { + // The content of the trigger to display inside the button. + {children} + } + // The dropdown menu content contains all the items that will be displayed in the dropdown menu. + DropdownMenuContent { + // Each dropdown menu item represents an individual option in the dropdown menu. Items are displayed in order based on the order of the index property. + DropdownMenuItem { + // The index of the item, used to determine the order in which items are displayed. + index: 0, + // The value of the item which will be passed to the on_select callback when the item is selected. + value: "", + on_select: |value: String| { + // This callback is triggered when the item is selected. + // The value parameter contains the value of the selected item. + }, + } + } +} +``` \ No newline at end of file diff --git a/preview/src/components/dropdown_menu/mod.rs b/preview/src/components/dropdown_menu/mod.rs new file mode 100644 index 00000000..01831788 --- /dev/null +++ b/preview/src/components/dropdown_menu/mod.rs @@ -0,0 +1,45 @@ +use dioxus::prelude::*; +use dioxus_primitives::dropdown_menu::{ + DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger, +}; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/dropdown_menu/style.css"), + } + DropdownMenu { class: "dropdown-menu", default_open: false, + DropdownMenuTrigger { class: "dropdown-menu-trigger", "Open Menu" } + DropdownMenuContent { class: "dropdown-menu-content", + DropdownMenuItem { + class: "dropdown-menu-item", + value: "item1".to_string(), + index: 0usize, + on_select: move |value| { + tracing::info!("Selected: {}", value); + }, + "Item 1" + } + DropdownMenuItem { + class: "dropdown-menu-item", + value: "item2".to_string(), + index: 1usize, + on_select: move |value| { + tracing::info!("Selected: {}", value); + }, + "Item 2" + } + DropdownMenuItem { + class: "dropdown-menu-item", + value: "item3".to_string(), + index: 2usize, + on_select: move |value| { + tracing::info!("Selected: {}", value); + }, + "Item 3" + } + } + } + } +} diff --git a/preview/assets/dropdown-menu.css b/preview/src/components/dropdown_menu/style.css similarity index 73% rename from preview/assets/dropdown-menu.css rename to preview/src/components/dropdown_menu/style.css index 1b90671a..dd102d2b 100644 --- a/preview/assets/dropdown-menu.css +++ b/preview/src/components/dropdown_menu/style.css @@ -6,8 +6,9 @@ .dropdown-menu-trigger { padding: 8px 16px; - background-color: #f8f9fa; - border: 1px solid #dee2e6; + color: var(--text-color); + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); border-radius: 4px; cursor: pointer; font-size: 14px; @@ -15,7 +16,7 @@ } .dropdown-menu-trigger:hover { - background-color: #e9ecef; + background-color: var(--dim-background-color); } .dropdown-menu-trigger:focus { @@ -29,8 +30,8 @@ left: 0; margin-top: 4px; min-width: 200px; - background-color: white; - border: 1px solid #dee2e6; + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); border-radius: 4px; box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15); z-index: 1000; @@ -50,12 +51,12 @@ } .dropdown-menu-item:hover { - background-color: #f8f9fa; + background-color: var(--hover-background-color); } .dropdown-menu-item:focus { outline: none; - background-color: #e9ecef; + background-color: var(--focused-background-color); } /* State styles */ diff --git a/preview/src/components/form/docs.md b/preview/src/components/form/docs.md new file mode 100644 index 00000000..e69de29b diff --git a/preview/src/components/form/mod.rs b/preview/src/components/form/mod.rs new file mode 100644 index 00000000..cd780574 --- /dev/null +++ b/preview/src/components/form/mod.rs @@ -0,0 +1,20 @@ +use dioxus::prelude::*; +use dioxus_primitives::checkbox::{Checkbox, CheckboxIndicator}; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { rel: "stylesheet", href: asset!("/src/components/form/style.css") } + form { + class: "form-example", + onsubmit: move |e| { + tracing::info!("{:?}", e.values()); + }, + Checkbox { id: "tos-check", name: "tos-check", + CheckboxIndicator { "+" } + } + label { r#for: "tos-check", "I agree to the terms presented." } + br {} + button { r#type: "submit", "Submit" } + } + } +} diff --git a/preview/src/components/form/style.css b/preview/src/components/form/style.css new file mode 100644 index 00000000..efe8ad1a --- /dev/null +++ b/preview/src/components/form/style.css @@ -0,0 +1,21 @@ +#tos-check { + width: 50px; + height: 50px; + margin: 8px 16px; + color: var(--text-color); + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); + border-radius: 4px; + cursor: pointer; + font-size: 14px; +} + +.form-example button { + padding: 8px 16px; + color: var(--text-color); + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); + border-radius: 4px; + cursor: pointer; + font-size: 14px; +} diff --git a/preview/src/components/hover_card/docs.md b/preview/src/components/hover_card/docs.md new file mode 100644 index 00000000..8c3dc4ee --- /dev/null +++ b/preview/src/components/hover_card/docs.md @@ -0,0 +1,23 @@ +The HoverCard component can be used to display additional information when a user hovers over an element. It is useful for showing tooltips, additional details, or any other content that should be revealed on hover. + +## Component Structure + +```rust +// The HoverCard component wraps the trigger element and the content that will be displayed on hover. +HoverCard { + // The HoverCardTrigger contains the elements that will trigger the hover card to display when hovered. + HoverCardTrigger { + // The elements that will trigger the hover card when hovered over. + {children} + } + // The HoverCardContent contains the content that will be displayed when the user hovers over the trigger. + HoverCardContent { + // The side of the HoverCardTrigger where the content will be displayed. Can be one Top, Right, Bottom, or Left. + side: HoverCardSide::Bottom, + // The alignment of the HoverCardContent relative to the HoverCardTrigger. Can be one of Start, Center, or End. + align: HoverCardAlign::Start, + // The content of the hover card, which can include text, images, or any other elements. + {children} + } +} +``` \ No newline at end of file diff --git a/preview/src/components/hover_card/mod.rs b/preview/src/components/hover_card/mod.rs new file mode 100644 index 00000000..6cf9c4b9 --- /dev/null +++ b/preview/src/components/hover_card/mod.rs @@ -0,0 +1,89 @@ +use dioxus::prelude::*; +use dioxus_primitives::hover_card::{ + HoverCard, HoverCardAlign, HoverCardContent, HoverCardSide, HoverCardTrigger, +}; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/hover_card/style.css"), + } + div { + style: "padding: 50px; display: flex; flex-direction: row; flex-wrap: wrap; gap: 40px; justify-content: center; align-items: center;", + HoverCard { class: "hover-card", + HoverCardTrigger { class: "hover-card-trigger", + button { class: "user-trigger", "@johndoe" } + } + HoverCardContent { class: "hover-card-content", side: HoverCardSide::Bottom, + div { class: "user-card", + div { class: "user-card-header", + img { + class: "user-card-avatar", + src: "https://github.com/DioxusLabs.png", + alt: "User avatar", + } + div { + h4 { class: "user-card-name", "John Doe" } + p { class: "user-card-username", "@johndoe" } + } + } + p { class: "user-card-bio", + "Software developer passionate about Rust and web technologies. Building awesome UI components with Dioxus." + } + div { class: "user-card-stats", + div { class: "user-card-stat", + span { class: "user-card-stat-value", "142" } + span { class: "user-card-stat-label", "Posts" } + } + div { class: "user-card-stat", + span { class: "user-card-stat-value", "2.5k" } + span { class: "user-card-stat-label", "Followers" } + } + div { class: "user-card-stat", + span { class: "user-card-stat-value", "350" } + span { class: "user-card-stat-label", "Following" } + } + } + } + } + } + HoverCard { class: "hover-card", + HoverCardTrigger { class: "hover-card-trigger", + button { class: "product-trigger", "View Product" } + } + HoverCardContent { + class: "hover-card-content", + side: HoverCardSide::Right, + align: HoverCardAlign::Start, + div { class: "product-card", + img { + class: "product-card-image", + src: "https://images.unsplash.com/photo-1505740420928-5e560c06d30e", + alt: "Product image", + } + h4 { class: "product-card-title", "Wireless Headphones" } + p { class: "product-card-price", "$129.99" } + p { class: "product-card-description", + "High-quality wireless headphones with noise cancellation and 30-hour battery life." + } + div { class: "product-card-rating", "★★★★☆ (4.5)" } + } + } + } + HoverCard { class: "hover-card", + HoverCardTrigger { class: "hover-card-trigger", + a { href: "#", "Hover over this link" } + } + HoverCardContent { + class: "hover-card-content", + side: HoverCardSide::Top, + align: HoverCardAlign::Center, + div { style: "padding: 8px;", + p { style: "margin: 0;", "This link will take you to an external website." } + } + } + } + } + } +} diff --git a/preview/src/components/hover_card/style.css b/preview/src/components/hover_card/style.css new file mode 100644 index 00000000..2ec8f758 --- /dev/null +++ b/preview/src/components/hover_card/style.css @@ -0,0 +1,240 @@ +/* Hover Card Styles */ +.hover-card { + position: relative; + display: inline-block; +} + +.hover-card-trigger { + display: inline-block; + cursor: pointer; +} + +.hover-card-content { + position: absolute; + z-index: 1000; + min-width: 200px; + padding: 12px 16px; + border-radius: 6px; + background-color: var(--brighter-background-color); + color: var(--text-color); + font-size: 14px; + line-height: 1.5; + box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); + border: 1px solid #eaeaea; + animation: hoverCardFadeIn 0.2s ease-in-out; +} + +/* Positioning based on side */ +.hover-card-content[data-side="top"] { + position: absolute; + bottom: 100%; + margin-bottom: 10px; + left: 50%; + transform: translateX(-50%); +} + +.hover-card-content[data-side="right"] { + position: absolute; + left: 100%; + top: 50%; + transform: translateY(-50%); + margin-left: 10px; +} + +.hover-card-content[data-side="bottom"] { + position: absolute; + top: 100%; + margin-top: 10px; + left: 50%; + transform: translateX(-50%); +} + +.hover-card-content[data-side="left"] { + position: absolute; + right: 100%; + top: 50%; + transform: translateY(-50%); + margin-right: 10px; +} + +/* Alignment styles for top and bottom */ +.hover-card-content[data-side="top"][data-align="start"], +.hover-card-content[data-side="bottom"][data-align="start"] { + left: 0; + transform: none; +} + +.hover-card-content[data-side="top"][data-align="center"], +.hover-card-content[data-side="bottom"][data-align="center"] { + left: 50%; + transform: translateX(-50%); +} + +.hover-card-content[data-side="top"][data-align="end"], +.hover-card-content[data-side="bottom"][data-align="end"] { + left: auto; + right: 0; + transform: none; +} + +/* Alignment styles for left and right */ +.hover-card-content[data-side="left"][data-align="start"], +.hover-card-content[data-side="right"][data-align="start"] { + top: 0; + transform: none; +} + +.hover-card-content[data-side="left"][data-align="center"], +.hover-card-content[data-side="right"][data-align="center"] { + top: 50%; + transform: translateY(-50%); +} + +.hover-card-content[data-side="left"][data-align="end"], +.hover-card-content[data-side="right"][data-align="end"] { + top: auto; + bottom: 0; + transform: none; +} + +/* Animation */ +@keyframes hoverCardFadeIn { + from { + opacity: 0; + transform: scale(0.95); + } + + to { + opacity: 1; + transform: scale(1); + } +} + +/* State styles */ +.hover-card[data-disabled="true"] .hover-card-trigger { + cursor: default; +} + +.hover-card-content[data-state="closed"] { + display: none; +} + +/* Example specific styles */ +.user-card { + display: flex; + flex-direction: column; + gap: 8px; +} + +.user-card-header { + display: flex; + align-items: center; + gap: 12px; +} + +.user-card-avatar { + width: 48px; + height: 48px; + border-radius: 50%; + object-fit: cover; +} + +.user-card-name { + margin: 0; + font-size: 16px; + font-weight: 600; +} + +.user-card-username { + margin: 0; + font-size: 14px; + color: var(--dim-text-color); +} + +.user-card-bio { + margin: 8px 0; + font-size: 14px; + color: var(--text-color); +} + +.user-card-stats { + display: flex; + gap: 16px; + margin-top: 8px; +} + +.user-card-stat { + display: flex; + flex-direction: column; +} + +.user-card-stat-value { + font-weight: 600; + font-size: 14px; +} + +.user-card-stat-label { + font-size: 12px; + color: var(--dim-text-color); +} + +.user-trigger { + cursor: pointer; + padding: 8px 16px; + color: var(--text-color); + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); + border-radius: 4px; + cursor: pointer; + font-size: 14px; +} + +.product-card { + display: flex; + flex-direction: column; + gap: 8px; +} + +.product-card-image { + width: 100%; + height: 120px; + object-fit: cover; + border-radius: 4px; +} + +.product-card-title { + margin: 0; + font-size: 16px; + font-weight: 600; +} + +.product-card-price { + font-size: 14px; + font-weight: 600; + color: #0070f3; +} + +.product-card-description { + margin: 8px 0; + font-size: 14px; + color: var(--text-color); +} + +.product-card-rating { + display: flex; + align-items: center; + gap: 4px; + font-size: 14px; + color: #f5a623; +} + +.product-trigger { + cursor: pointer; + padding: 8px 16px; + color: var(--text-color); + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); + border-radius: 4px; + cursor: pointer; + font-size: 14px; +} diff --git a/preview/src/components/menubar/docs.md b/preview/src/components/menubar/docs.md new file mode 100644 index 00000000..95cca37e --- /dev/null +++ b/preview/src/components/menubar/docs.md @@ -0,0 +1,31 @@ +The Menubar component can be used to display a menu bar with collapsible menus. It is useful for creating a navigation bar or a menu system in your application. + +## Component Structure + +```rust +// The Menubar component wraps the entire menu bar and contains the individual menus in the order of their index. +Menubar { + // The MenubarMenu contains the individual menus that can be opened. + MenubarMenu { + // The index of the menu, used to determine the order in which menus are displayed. + index: 0, + // The menubar trigger is the element that will display the menu when activated. + MenubarTrigger { + // The content of the trigger button + {children} + } + // The menubar content contains all the items that will be displayed in the menu when it is opened. + MenubarContent { + // Each menubar item represents an individual items in the menu. + MenubarItem { + // The value of the item which will be passed to the on_select callback when the item is selected. + value: "", + on_select: |value: String| { + // This callback is triggered when the item is selected. + // The value parameter contains the value of the selected item. + }, + } + } + } +} +``` diff --git a/preview/src/components/menubar/mod.rs b/preview/src/components/menubar/mod.rs new file mode 100644 index 00000000..ccf86e17 --- /dev/null +++ b/preview/src/components/menubar/mod.rs @@ -0,0 +1,75 @@ +use dioxus::prelude::*; +use dioxus_primitives::menubar::{ + Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarTrigger, +}; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/menubar/style.css"), + } + div { class: "menubar-example", + Menubar { class: "menubar", + MenubarMenu { class: "menubar-menu", index: 0usize, + MenubarTrigger { class: "menubar-trigger", "File" } + MenubarContent { class: "menubar-content", + MenubarItem { + class: "menubar-item", + value: "new".to_string(), + on_select: move |value| { + tracing::info!("Selected: {value}"); + }, + "New" + } + MenubarItem { + class: "menubar-item", + value: "open".to_string(), + on_select: move |value| { + tracing::info!("Selected: {value}"); + }, + "Open" + } + MenubarItem { + class: "menubar-item", + value: "save".to_string(), + on_select: move |value| { + tracing::info!("Selected: {value}"); + }, + "Save" + } + } + } + MenubarMenu { class: "menubar-menu", index: 1usize, + MenubarTrigger { class: "menubar-trigger", "Edit" } + MenubarContent { class: "menubar-content", + MenubarItem { + class: "menubar-item", + value: "cut".to_string(), + on_select: move |value| { + tracing::info!("Selected: {value}"); + }, + "Cut" + } + MenubarItem { + class: "menubar-item", + value: "copy".to_string(), + on_select: move |value| { + tracing::info!("Selected: {value}"); + }, + "Copy" + } + MenubarItem { + class: "menubar-item", + value: "paste".to_string(), + on_select: move |value| { + tracing::info!("Selected: {value}"); + }, + "Paste" + } + } + } + } + } + } +} diff --git a/preview/assets/menubar.css b/preview/src/components/menubar/style.css similarity index 71% rename from preview/assets/menubar.css rename to preview/src/components/menubar/style.css index 7c7d151e..e45ee7c3 100644 --- a/preview/assets/menubar.css +++ b/preview/src/components/menubar/style.css @@ -2,9 +2,9 @@ display: flex; gap: 4px; padding: 4px; - border: 1px solid #ccc; + border: 1px solid var(--dim-border-color); border-radius: 4px; - background: white; + background: var(--background-color); } .menubar-menu { @@ -16,10 +16,11 @@ border: none; background: none; cursor: pointer; + color: var(--text-color); } .menubar-trigger:hover { - background: #f0f0f0; + background: var(--hover-background-color); border-radius: 4px; } @@ -29,8 +30,8 @@ top: 100%; left: 0; min-width: 200px; - background: white; - border: 1px solid #ccc; + background: var(--background-color); + border: 1px solid var(--dim-border-color); border-radius: 4px; padding: 4px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); @@ -48,7 +49,7 @@ } .menubar-item:hover { - background: #f0f0f0; + background: var(--hover-background-color); } [data-disabled="true"] { diff --git a/preview/src/components/mod.rs b/preview/src/components/mod.rs new file mode 100644 index 00000000..5229cb60 --- /dev/null +++ b/preview/src/components/mod.rs @@ -0,0 +1,39 @@ +use super::{ComponentDemoData, HighlightedCode}; +macro_rules! examples { + ($($name:ident),*) => { + $(mod $name;)* pub (crate) static DEMOS : & [ComponentDemoData] = & + [$(ComponentDemoData { name : stringify!($name), docs : + include_str!(concat!(env!("OUT_DIR"), "/", stringify!($name), "/docs.html")), + rs_highlighted : HighlightedCode { light : include_str!(concat!(env!("OUT_DIR"), + "/", stringify!($name), "/mod.rs.base16-ocean.light.html")), dark : + include_str!(concat!(env!("OUT_DIR"), "/", stringify!($name), + "/mod.rs.base16-ocean.dark.html")), }, css_highlighted : HighlightedCode { light + : include_str!(concat!(env!("OUT_DIR"), "/", stringify!($name), + "/style.css.base16-ocean.light.html")), dark : + include_str!(concat!(env!("OUT_DIR"), "/", stringify!($name), + "/style.css.base16-ocean.dark.html")), }, component : $name ::Demo, },)*]; + }; +} +examples!( + accordion, + aspect_ratio, + avatar, + calendar, + context_menu, + checkbox, + dropdown_menu, + hover_card, + menubar, + progress, + radio_group, + scroll_area, + select, + separator, + slider, + switch, + tabs, + toast, + toggle_group, + toolbar, + tooltip +); diff --git a/preview/src/components/progress/docs.md b/preview/src/components/progress/docs.md new file mode 100644 index 00000000..231df4b8 --- /dev/null +++ b/preview/src/components/progress/docs.md @@ -0,0 +1,14 @@ +The Progress component is used to display the progress of a task or operation. It can be used to indicate loading states, file uploads, or any other process that takes time to complete. + +## Component Structure + +```rust +Progress { + // The current progress value (0 to max + value: 0.5, + // The maximum value of the progress (default is 100.0) + max: 1.0, + // Elements that will be displayed inside the progress bar + {children} +} +``` \ No newline at end of file diff --git a/preview/src/components/progress/mod.rs b/preview/src/components/progress/mod.rs new file mode 100644 index 00000000..d00987f5 --- /dev/null +++ b/preview/src/components/progress/mod.rs @@ -0,0 +1,33 @@ +use dioxus::prelude::*; +use dioxus_primitives::progress::{Progress, ProgressIndicator}; +#[component] +pub(super) fn Demo() -> Element { + let mut progress = use_signal(|| 80.0); + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/progress/style.css"), + } + div { style: "display: flex; flex-direction: column; align-items: center; gap: 4px;", + Progress { class: "progress", value: progress(), + ProgressIndicator { class: "progress-indicator" } + } + button { + class: "progress-button", + onclick: move |_| progress.set(progress() + 10.0), + "Increment" + } + button { + class: "progress-button", + onclick: move |_| progress.set(progress() - 10.0), + "Decrement" + } + button { class: "progress-button", onclick: move |_| progress.set(0.0), "Reset" } + button { + class: "progress-button", + onclick: move |_| progress.set(100.0), + "Complete" + } + } + } +} diff --git a/preview/src/components/progress/style.css b/preview/src/components/progress/style.css new file mode 100644 index 00000000..35369f20 --- /dev/null +++ b/preview/src/components/progress/style.css @@ -0,0 +1,53 @@ +.progress { + position: relative; + overflow: hidden; + background: var(--brighter-background-color); + border-radius: 9999px; + width: 200px; + height: 20px; + border: 2px solid var(--dim-border-color); + box-sizing: border-box; +} + +.progress[data-state='indeterminate'] .progress-indicator { + width: 50%; + animation: indeterminate 1s infinite linear; +} + +.progress-indicator { + height: 100%; + background-color: var(--contrast-background-color); + transition: width 250ms ease; + width: var(--progress-value, 0%); + /* Use CSS variable for width */ +} + +@keyframes indeterminate { + 0% { + transform: translateX(-100%); + } + + 100% { + transform: translateX(200%); + } +} + +.progress-button { + padding: 8px 12px; + border-radius: 4px; + cursor: pointer; + user-select: none; + outline: none; + font-size: 14px; + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); + color: var(--text-color); +} + +.progress-button:hover { + background: var(--hover-background-color); +} + +.progress-button:focus { + background: var(--focused-background-color); +} diff --git a/preview/src/components/radio_group/docs.md b/preview/src/components/radio_group/docs.md new file mode 100644 index 00000000..cd9c6b5f --- /dev/null +++ b/preview/src/components/radio_group/docs.md @@ -0,0 +1,24 @@ +The RadioGroup component is used to create a group of radio buttons that allows the user to select one option from a set. + +## Component Structure + +```rust +// The RadioGroup component wraps all radio items in the group. +RadioGroup { + // The value property represents the currently selected radio button in the group. + value: "option1", + on_value_change: |value: String| { + // This callback is triggered when the selected radio button changes. + // The value parameter contains the value of the newly selected radio button. + }, + // The RadioItem component represents each individual radio button in the group. + RadioItem { + // The index of the radio item, used to determine the order in which items are displayed. + index: 0, + // The value of the radio button, which is used to identify the selected option and will be passed to the on_value_change callback when selected. + value: "option1", + // The contents of the radio item button + {children} + } +} +``` \ No newline at end of file diff --git a/preview/src/components/radio_group/mod.rs b/preview/src/components/radio_group/mod.rs new file mode 100644 index 00000000..0dd89237 --- /dev/null +++ b/preview/src/components/radio_group/mod.rs @@ -0,0 +1,38 @@ +use dioxus::prelude::*; +use dioxus_primitives::radio_group::{RadioGroup, RadioItem}; +#[component] +pub(super) fn Demo() -> Element { + let mut value = use_signal(|| String::from("option1")); + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/radio_group/style.css"), + } + RadioGroup { + class: "radio-group", + value, + on_value_change: move |new_value| { + value.set(new_value); + }, + RadioItem { + class: "radio-item", + value: "option1".to_string(), + index: 0usize, + "Option 1" + } + RadioItem { + class: "radio-item", + value: "option2".to_string(), + index: 1usize, + "Option 2" + } + RadioItem { + class: "radio-item", + value: "option3".to_string(), + index: 2usize, + "Option 3" + } + } + div { style: "margin-top: 1rem;", "Selected value: {value()}" } + } +} diff --git a/preview/assets/radio-group.css b/preview/src/components/radio_group/style.css similarity index 65% rename from preview/assets/radio-group.css rename to preview/src/components/radio_group/style.css index 66f861dc..4d1d05cd 100644 --- a/preview/assets/radio-group.css +++ b/preview/src/components/radio_group/style.css @@ -10,15 +10,16 @@ align-items: center; padding: 8px 16px; border-radius: 6px; - border: 1px solid #ccc; - background: none; + border: 1px solid var(--dim-border-color); + background: var(--brighter-background-color); cursor: pointer; font-size: 14px; transition: all 0.2s; + color: var(--text-color); } .radio-item:hover { - background: #f5f5f5; + background: var(--hover-background-color); } .radio-item:focus { @@ -27,8 +28,8 @@ } .radio-item[data-state="checked"] { - background: #e9ecef; - border-color: #adb5bd; + background: var(--focused-background-color); + border-color: var(--dim-border-color); } .radio-item[data-disabled="true"] { diff --git a/preview/src/components/scroll_area/docs.md b/preview/src/components/scroll_area/docs.md new file mode 100644 index 00000000..8f7c2c56 --- /dev/null +++ b/preview/src/components/scroll_area/docs.md @@ -0,0 +1,13 @@ +The ScrollArea component is used to create a scrollable container for its children. It can be used to enable scrolling for content that overflows the available space. + +## Component Structure + +```rust +// The ScrollArea component wraps all scrollable content. +ScrollArea { + // The direction in which the scroll area can scroll. Can be one of Horizontal, Vertical, or Both. + scroll_direction: ScrollDirection::Vertical, + // The content of the scrollable area + {children} +} +``` \ No newline at end of file diff --git a/preview/src/components/scroll_area/mod.rs b/preview/src/components/scroll_area/mod.rs new file mode 100644 index 00000000..52940662 --- /dev/null +++ b/preview/src/components/scroll_area/mod.rs @@ -0,0 +1,53 @@ +use dioxus::prelude::*; +use dioxus_primitives::scroll_area::{ScrollArea, ScrollDirection}; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/scroll_area/style.css"), + } + div { class: "scroll-area-demo", + div { class: "scroll-demo-section", + h3 { "Vertical Scroll" } + ScrollArea { + class: "demo-scroll-area", + direction: ScrollDirection::Vertical, + div { class: "scroll-content", + for i in 1..=20 { + p { "Scrollable content item {i}" } + } + } + } + } + div { class: "scroll-demo-section", + h3 { "Horizontal Scroll" } + ScrollArea { + class: "demo-scroll-area", + direction: ScrollDirection::Horizontal, + div { class: "scroll-content-horizontal", + for i in 1..=20 { + span { "Column {i} " } + } + } + } + } + div { class: "scroll-demo-section", + h3 { "Both Directions" } + ScrollArea { + class: "demo-scroll-area", + direction: ScrollDirection::Both, + div { class: "scroll-content-both", + for i in 1..=20 { + div { + for j in 1..=20 { + span { "Cell {i},{j} " } + } + } + } + } + } + } + } + } +} diff --git a/preview/assets/scroll-area.css b/preview/src/components/scroll_area/style.css similarity index 77% rename from preview/assets/scroll-area.css rename to preview/src/components/scroll_area/style.css index bf9f7930..e243f482 100644 --- a/preview/assets/scroll-area.css +++ b/preview/src/components/scroll_area/style.css @@ -1,25 +1,35 @@ .scroll-area-demo { - padding: 20px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + padding: 2em; + width: 35rem; + max-width: 100%; } .scroll-demo-section { + max-width: 30rem; + max-height: 30rem; margin-bottom: 30px; } .scroll-demo-section h3 { margin-bottom: 10px; - color: #333; + color: var(--text-color); } .demo-scroll-area { - border: 1px solid #ccc; + border: 1px solid var(--dim-border-color); border-radius: 4px; - background: #fff; + background: var(--background-color); } /* Vertical scroll example */ .demo-scroll-area[data-scroll-direction="vertical"] { - height: 200px; + height: 20rem; + width: auto; } .scroll-content { @@ -29,14 +39,14 @@ .scroll-content p { margin: 8px 0; padding: 8px; - background: #f5f5f5; + background: var(--brighter-background-color); border-radius: 4px; } /* Horizontal scroll example */ .demo-scroll-area[data-scroll-direction="horizontal"] { height: auto; - width: 100%; + width: 20rem; } .scroll-content-horizontal { @@ -48,14 +58,14 @@ display: inline-block; margin: 0 4px; padding: 8px 16px; - background: #f5f5f5; + background: var(--brighter-background-color); border-radius: 4px; } /* Both directions example */ .demo-scroll-area[data-scroll-direction="both"] { - height: 200px; - width: 100%; + height: 20rem; + width: 20rem; } .scroll-content-both { @@ -71,7 +81,7 @@ display: inline-block; margin: 0 4px; padding: 8px; - background: #f5f5f5; + background: var(--brighter-background-color); border-radius: 4px; min-width: 80px; text-align: center; diff --git a/preview/src/components/select/docs.md b/preview/src/components/select/docs.md new file mode 100644 index 00000000..66692a6c --- /dev/null +++ b/preview/src/components/select/docs.md @@ -0,0 +1,27 @@ +The Select component is used to create a dropdown menu that allows users to select one or more options from the select groups. + +## Component Structure + +```rust +// The Select component wraps all select items in the dropdown. +Select { + // The currently selected value(s) in the dropdown. + value: "option1", + // Callback function triggered when the selected value changes. + on_value_change: |value: String| { + // Handle the change in selected value. + }, + // An group within the select dropdown which may contain multiple items. + SelectGroup { + // The label for the group, which is displayed as a header in the dropdown. + label: "Group 1", + // Each select option represents an individual option in the dropdown. + SelectOption { + // The value of the item, which will be passed to the on_value_change callback when selected. + value: "option1", + // The content of the select option + {children} + } + } +} +``` \ No newline at end of file diff --git a/preview/src/components/select/mod.rs b/preview/src/components/select/mod.rs new file mode 100644 index 00000000..90f9cb5d --- /dev/null +++ b/preview/src/components/select/mod.rs @@ -0,0 +1,45 @@ +use dioxus::prelude::*; +use dioxus_primitives::select::{Select, SelectGroup, SelectOption}; +#[component] +pub(super) fn Demo() -> Element { + let mut selected = use_signal(|| None::); + use_effect(move || { + if let Some(value) = selected() { + tracing::info!("Selected value: {value}"); + } + }); + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/select/style.css"), + } + div { class: "select-example", + div { class: "select-container", + label { class: "select-label", "Choose a fruit:" } + Select { + class: "select", + value: selected, + on_value_change: move |value| selected.set(value), + placeholder: "Select a fruit...", + SelectGroup { label: "Fruits".to_string(), + SelectOption { value: "apple".to_string(), "Apple" } + SelectOption { value: "banana".to_string(), "Banana" } + SelectOption { value: "orange".to_string(), "Orange" } + SelectOption { value: "strawberry".to_string(), "Strawberry" } + SelectOption { value: "watermelon".to_string(), "Watermelon" } + } + SelectGroup { label: "Other".to_string(), + SelectOption { value: "other".to_string(), "Other" } + } + } + } + div { class: "selected-value", + if let Some(value) = selected() { + "Selected: {value}" + } else { + "No selection" + } + } + } + } +} diff --git a/preview/assets/select.css b/preview/src/components/select/style.css similarity index 75% rename from preview/assets/select.css rename to preview/src/components/select/style.css index be6dbb31..2e4b4ba4 100644 --- a/preview/assets/select.css +++ b/preview/src/components/select/style.css @@ -3,6 +3,15 @@ position: relative; width: 100%; max-width: 300px; + padding: 8px 16px; + color: var(--text-color); + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); + border-radius: 4px; + cursor: pointer; + font-size: 14px; + transition: all 0.2s ease; + appearance: none; } .select-label { @@ -10,7 +19,7 @@ margin-bottom: 8px; font-size: 14px; font-weight: 500; - color: #333; + color: var(--dim-text-color); } .select-trigger { @@ -19,8 +28,8 @@ justify-content: space-between; width: 100%; padding: 10px 12px; - background-color: #fff; - border: 1px solid #ccc; + background-color: var(--background-color); + border: 1px solid var(--dim-border-color); border-radius: 4px; font-size: 14px; text-align: left; @@ -29,7 +38,7 @@ } .select-trigger:hover { - border-color: #999; + border-color: var(--hover-border-color); } .select-trigger:focus { @@ -48,16 +57,16 @@ } .select-placeholder { - color: #999; + color: var(--text-color); } .select-value { - color: #333; + color: var(--text-color); } .select-icon { margin-left: 8px; - color: #666; + color: var(--text-color); transition: transform 0.2s; } @@ -71,8 +80,8 @@ width: 100%; max-height: 200px; overflow-y: auto; - background-color: #fff; - border: 1px solid #ccc; + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); border-radius: 4px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); z-index: 100; @@ -100,16 +109,16 @@ } .select-item:hover { - background-color: #f5f5f5; + background-color: var(--hover-background-color); } .select-item:focus { outline: none; - background-color: #e0e0ff; + background-color: var(--focused-background-color); } .select-item[data-highlighted="true"] { - background-color: #e0e0ff; + background-color: var(--focused-background-color); } .select-item[data-state="selected"] { @@ -128,7 +137,7 @@ .select-separator { height: 1px; - background-color: #eee; + background-color: var(--dim-border-color); margin: 5px 0; } @@ -177,7 +186,7 @@ .selected-value { margin-top: 20px; padding: 10px; - background-color: #f5f5f5; + background-color: var(--brighter-background-color); border-radius: 4px; font-size: 14px; } diff --git a/preview/src/components/separator/docs.md b/preview/src/components/separator/docs.md new file mode 100644 index 00000000..cae3359f --- /dev/null +++ b/preview/src/components/separator/docs.md @@ -0,0 +1,13 @@ +The Separator component is a simple horizontal or vertical line that can be used to visually separate content in your application. + +## Component Structure + +```rust +// The Separator component can be oriented horizontally or vertically. +Separator { + // The orientation of the separator line. true for horizontal, false for vertical. + horizontal: true, + // The decorative property controls if the separator is decorative and should not be visible to screen readers. + decorative: false, +} +``` diff --git a/preview/src/components/separator/mod.rs b/preview/src/components/separator/mod.rs new file mode 100644 index 00000000..592d266e --- /dev/null +++ b/preview/src/components/separator/mod.rs @@ -0,0 +1,19 @@ +use dioxus::prelude::*; +use dioxus_primitives::separator::Separator; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/separator/style.css"), + } + "One thing" + Separator { + class: "separator", + style: "margin: 15px 0; width: 50%;", + horizontal: true, + decorative: true, + } + "Another thing" + } +} diff --git a/preview/assets/separator.css b/preview/src/components/separator/style.css similarity index 78% rename from preview/assets/separator.css rename to preview/src/components/separator/style.css index b66f7d60..3a55b255 100644 --- a/preview/assets/separator.css +++ b/preview/src/components/separator/style.css @@ -1,5 +1,5 @@ .separator { - background-color: rgb(43, 43, 43); + background-color: var(--dim-border-color); } .separator[data-orientation="horizontal"] { diff --git a/preview/src/components/slider/docs.md b/preview/src/components/slider/docs.md new file mode 100644 index 00000000..ca992776 --- /dev/null +++ b/preview/src/components/slider/docs.md @@ -0,0 +1,32 @@ +The slider component allows users to select a value from a range by sliding a handle along a track. + +## Component Structure + +```rust +// The slider component wraps all slider-related elements. +Slider { + // The current value of the slider, which should be updated as the user interacts with the slider. + value: SliderValue::Single(0.0), + // The orientation of the slider, true for horizontal and false for vertical. + horizontal: true, + // Callback function triggered when the slider value changes. + on_value_change: |value: u32| { + // Handle the change in slider value. + }, + // The track represents the visual track along which the handle moves. + SliderTrack { + // The slider range represents the filled portion of the track + SliderRange { + // The content of the range + {children} + } + // The slider thumb represents the draggable handle that the user moves along the track. + SliderThumb { + // An optional index which can be either 0 or 1 to indicate if this is the first or second thumb in a range slider. + index: 0, + // The content of the thumb button + {children} + } + } +} +``` \ No newline at end of file diff --git a/preview/src/components/slider/mod.rs b/preview/src/components/slider/mod.rs new file mode 100644 index 00000000..140215c0 --- /dev/null +++ b/preview/src/components/slider/mod.rs @@ -0,0 +1,42 @@ +use dioxus::prelude::*; +use dioxus_primitives::slider::{ + Slider, SliderRange, SliderThumb, SliderTrack, SliderValue, +}; +#[component] +pub(super) fn Demo() -> Element { + let mut value = use_signal(|| SliderValue::Single(50.0)); + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/slider/style.css"), + } + div { class: "slider-example", + div { + label { "Single Value Slider" } + div { style: "display: flex; flex-wrap: wrap; align-items: center; gap: 1rem;", + Slider { + class: "slider", + value, + horizontal: true, + on_value_change: move |v| { + value.set(v); + }, + SliderTrack { class: "slider-track", + SliderRange { class: "slider-range" } + SliderThumb { class: "slider-thumb" } + } + } + input { + class: "slider-value", + r#type: "text", + readonly: true, + value: match value() { + SliderValue::Single(v) => format!("{v:.1}"), + _ => String::new(), + }, + } + } + } + } + } +} diff --git a/preview/assets/slider.css b/preview/src/components/slider/style.css similarity index 75% rename from preview/assets/slider.css rename to preview/src/components/slider/style.css index efbdbb62..552c1ec3 100644 --- a/preview/assets/slider.css +++ b/preview/src/components/slider/style.css @@ -41,7 +41,7 @@ .slider-range { position: absolute; - background-color: rgb(34, 197, 94); + background-color: var(--contrast-background-color); border-radius: 9999px; height: 100%; } @@ -55,10 +55,10 @@ display: block; width: 16px; height: 16px; - background-color: white; + background-color: var(--brighter-background-color); box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); border-radius: 50%; - border: 2px solid rgb(34, 197, 94); + border: 2px solid var(--contrast-background-color); position: absolute; top: 50%; transform: translate(-50%, -50%); @@ -72,11 +72,11 @@ } .slider-thumb:hover { - border-color: rgb(21, 170, 75); + border-color: var(--hover-border-color); } .slider-thumb:focus-visible { - outline: 2px solid rgb(34, 197, 94); + outline: 2px solid var(--focused-border-color); outline-offset: 2px; } @@ -87,4 +87,13 @@ .slider[data-disabled="true"] .slider-thumb { cursor: not-allowed; -} \ No newline at end of file +} + +.slider-value { + font-size: 14px; + color: var(--text-color); + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); + border-radius: 4px; + padding: 0.25rem 0.5rem; +} diff --git a/preview/src/components/switch/docs.md b/preview/src/components/switch/docs.md new file mode 100644 index 00000000..fce9ca56 --- /dev/null +++ b/preview/src/components/switch/docs.md @@ -0,0 +1,20 @@ +The Switch component allows users to toggle between two states, such as on and off. + +## Component Structure + +```rust +// The Switch component wraps the switch thumb +Switch { + // The current state of the switch, true for on and false for off. + checked: true, + // Callback function triggered when the switch state changes. + on_checked_change: |checked: bool| { + // Handle the change in switch state. + }, + // The switch thumb represents the draggable handle that the user moves to toggle the switch. + SwitchThumb { + // The content of the thumb + {children} + } +} +``` \ No newline at end of file diff --git a/preview/src/components/switch/mod.rs b/preview/src/components/switch/mod.rs new file mode 100644 index 00000000..b38f2842 --- /dev/null +++ b/preview/src/components/switch/mod.rs @@ -0,0 +1,23 @@ +use dioxus::prelude::*; +use dioxus_primitives::switch::{Switch, SwitchThumb}; +#[component] +pub(super) fn Demo() -> Element { + let mut checked = use_signal(|| false); + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/switch/style.css"), + } + div { class: "switch-example", + Switch { + class: "switch", + checked, + on_checked_change: move |new_checked| { + checked.set(new_checked); + tracing::info!("Switch toggled: {new_checked}"); + }, + SwitchThumb { class: "switch-thumb" } + } + } + } +} diff --git a/preview/assets/switch.css b/preview/src/components/switch/style.css similarity index 78% rename from preview/assets/switch.css rename to preview/src/components/switch/style.css index f8258280..488559b0 100644 --- a/preview/assets/switch.css +++ b/preview/src/components/switch/style.css @@ -9,7 +9,7 @@ all: unset; width: 42px; height: 25px; - background-color: rgba(100, 116, 139, 0.1); + background-color: var(--background-color); border-radius: 9999px; position: relative; transition: background-color 150ms; @@ -17,14 +17,14 @@ } .switch[data-state="checked"] { - background-color: rgb(34, 197, 94); + background-color: var(--contrast-background-color); } .switch-thumb { display: block; width: 21px; height: 21px; - background-color: white; + background-color: var(--contrast-background-color); border-radius: 9999px; box-shadow: 0 2px 2px rgba(0, 0, 0, 0.1); transition: transform 150ms; @@ -34,6 +34,7 @@ .switch[data-state="checked"] .switch-thumb { transform: translateX(19px); + background-color: var(--background-color); } /* Only apply disabled styles when data-disabled is "true" */ diff --git a/preview/src/components/tabs/docs.md b/preview/src/components/tabs/docs.md new file mode 100644 index 00000000..ce350f9e --- /dev/null +++ b/preview/src/components/tabs/docs.md @@ -0,0 +1,25 @@ +The Tabs component is used to create a tabbed interface, allowing users to switch between different views or sections of content. + +## Component Structure + +```rust +// The Tabs component wraps all tab triggers and contents and orders them based on their index. +Tabs { + // The TabTrigger component is used to create a clickable tab button that switches the active tab. + TabTrigger { + // The index of the tab trigger, used to determine the focus order of the tabs. + index: 0, + // The value of the tab trigger, which must be unique and is used to identify the active tab. + value: "tab1", + // The contents of the tab trigger button + {children} + } + // The TabContent component contains the content that is displayed when the corresponding tab is active. + TabContent { + // The value of the tab content, which must match the value of the corresponding TabTrigger to be displayed. + value: "tab1", + // The content of the tab, which is displayed when the tab is active. + {children} + } +} +``` \ No newline at end of file diff --git a/preview/src/components/tabs/mod.rs b/preview/src/components/tabs/mod.rs new file mode 100644 index 00000000..9407b029 --- /dev/null +++ b/preview/src/components/tabs/mod.rs @@ -0,0 +1,33 @@ +use dioxus::prelude::*; +use dioxus_primitives::tabs::{TabContent, TabTrigger, Tabs}; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { rel: "stylesheet", href: asset!("/src/components/tabs/style.css") } + Tabs { class: "tabs", default_value: "tab1".to_string(), + div { class: "tabs-list", + TabTrigger { + class: "tabs-trigger", + value: "tab1".to_string(), + index: 0usize, + "Tab 1" + } + TabTrigger { + class: "tabs-trigger", + value: "tab2".to_string(), + index: 1usize, + "Tab 2" + } + TabTrigger { + class: "tabs-trigger", + value: "tab3".to_string(), + index: 2usize, + "Tab 3" + } + } + TabContent { class: "tabs-content", value: "tab1".to_string(), "Tab 1 Content" } + TabContent { class: "tabs-content", value: "tab2".to_string(), "Tab 2 Content" } + TabContent { class: "tabs-content", value: "tab3".to_string(), "Tab 3 Content" } + } + } +} diff --git a/preview/src/components/tabs/style.css b/preview/src/components/tabs/style.css new file mode 100644 index 00000000..35324514 --- /dev/null +++ b/preview/src/components/tabs/style.css @@ -0,0 +1,63 @@ +.tabs { + width: 100%; + display: flex; + flex-direction: column; + background: var(--background-color); +} + +.tabs-list { + display: flex; + /* border-style: solid; + border-color: var(--dim-border-color); + border-width: 1px 0px 1px 1px; */ +} + +.tabs-trigger { + all: unset; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + padding: 8px 16px; + font-size: 14px; + color: var(--text-color); + cursor: pointer; + border-left: 1px solid var(--dim-border-color); + border-bottom: 1px solid var(--dim-border-color); + transition: background-color 0.2s; + box-sizing: border-box; +} + +.tabs-trigger:first-child { + border-left: none; +} + +.tabs-trigger:hover { + color: var(--hover-text-color); + background: var(--hover-background-color); +} + +.tabs-trigger[data-state="active"] { + color: var(--text-color); + border-bottom: none; +} + +.tabs-trigger:focus-visible { + outline: 2px solid #3b82f6; + outline-offset: -2px; +} + +.tabs-trigger[data-disabled="true"] { + opacity: 0.5; + cursor: not-allowed; +} + +.tabs-content { + padding: 16px; + font-size: 14px; + box-sizing: border-box; +} + +.tabs-content[data-state="inactive"] { + display: none; +} diff --git a/preview/src/components/toast/docs.md b/preview/src/components/toast/docs.md new file mode 100644 index 00000000..0b945a58 --- /dev/null +++ b/preview/src/components/toast/docs.md @@ -0,0 +1,25 @@ +The Toast component is used to display brief messages to the user, typically for notifications or alerts. + +## Component Structure + +```rust +// The Toast provider provides the toast context to its children and handler rendering any toasts that are sent. +ToastProvider { + // Any child component can consume the toast context and send a toast to be rendered. + button { + onclick: |event: MouseEvent| { + // Consume the toast context to send a toast. + let toast_api = consume_toast(); + toast_api + .error( + "Critical Error".to_string(), + Some(ToastOptions { + permanent: true, + ..Default::default() + }), + ); + }, + "Show Toast" + } +} +``` diff --git a/preview/src/components/toast/mod.rs b/preview/src/components/toast/mod.rs new file mode 100644 index 00000000..ef912009 --- /dev/null +++ b/preview/src/components/toast/mod.rs @@ -0,0 +1,140 @@ +use dioxus::prelude::*; +use dioxus_primitives::toast::{ToastOptions, ToastProvider, use_toast}; +use std::time::Duration; + +#[component] +pub(super) fn Demo() -> Element { + rsx! { + ToastProvider { ToastButton {} } + } +} + +#[component] +fn ToastButton() -> Element { + let toast_api = use_toast(); + + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/toast/style.css"), + } + div { class: "toast-example", + h4 { "Timed Toasts (auto-dismiss)" } + div { class: "toast-buttons", + button { + onclick: move |_| { + toast_api + .success( + "Success".to_string(), + Some(ToastOptions { + duration: Some(Duration::from_secs(3)), + ..Default::default() + }), + ); + }, + "Success (3s)" + } + button { + onclick: move |_| { + toast_api + .error( + "Error".to_string(), + Some(ToastOptions { + duration: Some(Duration::from_secs(5)), + ..Default::default() + }), + ); + }, + "Error (5s)" + } + button { + onclick: move |_| { + toast_api + .warning( + "Warning".to_string(), + Some(ToastOptions { + description: Some("This action might cause issues".to_string()), + duration: Some(Duration::from_secs(3)), + ..Default::default() + }), + ); + }, + "Warning (3s)" + } + button { + onclick: move |_| { + toast_api + .info( + "Custom Toast".to_string(), + Some(ToastOptions { + description: Some( + "This is a custom toast with specific settings".to_string(), + ), + duration: Some(Duration::from_secs(10)), + permanent: false, + }), + ); + }, + "Custom Info (10s)" + } + } + h4 { "Permanent Toasts (manual close)" } + div { class: "toast-buttons", + button { + onclick: move |_| { + toast_api + .success( + "Important".to_string(), + Some(ToastOptions { + permanent: true, + ..Default::default() + }), + ); + }, + "Permanent Success" + } + button { + onclick: move |_| { + toast_api + .error( + "Critical Error".to_string(), + Some(ToastOptions { + permanent: true, + ..Default::default() + }), + ); + }, + "Permanent Error" + } + button { + onclick: move |_| { + toast_api + .warning( + "Attention Needed".to_string(), + Some(ToastOptions { + description: Some("This requires your attention".to_string()), + permanent: true, + ..Default::default() + }), + ); + }, + "Permanent Warning" + } + button { + onclick: move |_| { + toast_api + .info( + "Info Toast".to_string(), + Some(ToastOptions { + description: Some("This is an informational message".to_string()), + permanent: true, + ..Default::default() + }), + ); + }, + "Permanent Info" + } + } + } + } +} diff --git a/preview/assets/toast.css b/preview/src/components/toast/style.css similarity index 59% rename from preview/assets/toast.css rename to preview/src/components/toast/style.css index d7de13b5..d7285fb1 100644 --- a/preview/assets/toast.css +++ b/preview/src/components/toast/style.css @@ -10,7 +10,7 @@ } .toast { - background-color: white; + background-color: var(--dim-background-color); border-radius: 6px; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); padding: 12px 16px; @@ -19,23 +19,23 @@ justify-content: space-between; animation: toast-slide-in 0.2s ease-out; overflow: hidden; - border-left: 4px solid #6b7280; + border-left: 4px solid var(--dim-border-color); } .toast[data-type="success"] { - border-left-color: #10b981; + border-left-color: var(--success-background-color); } .toast[data-type="error"] { - border-left-color: #ef4444; + border-left-color: var(--error-background-color); } .toast[data-type="warning"] { - border-left-color: #f59e0b; + border-left-color: var(--warning-background-color); } .toast[data-type="info"] { - border-left-color: #3b82f6; + border-left-color: var(--info-background-color); } /* Permanent toast styling */ @@ -52,12 +52,12 @@ .toast-title { font-weight: 600; margin-bottom: 4px; - color: #1f2937; + color: var(--text-color); } .toast-description { font-size: 0.875rem; - color: #6b7280; + color: var(--dim-text-color); } .toast-close { @@ -65,7 +65,7 @@ border: none; font-size: 18px; cursor: pointer; - color: #9ca3af; + color: var(--dim-text-color); padding: 0; margin: 0; line-height: 1; @@ -73,7 +73,7 @@ } .toast-close:hover { - color: #4b5563; + color: var(--text-color); } @keyframes toast-slide-in { @@ -90,6 +90,9 @@ .toast-example { padding: 20px; + display: flex; + flex-direction: column; + align-items: center; } .toast-example h3 { @@ -112,33 +115,44 @@ .toast-buttons button { padding: 8px 16px; + color: var(--text-color); + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); border-radius: 4px; - border: none; cursor: pointer; - font-weight: 500; - transition: background-color 0.2s; + font-size: 14px; + transition: all 0.2s ease; +} + +.toast-buttons button:hover { + background-color: var(--dim-background-color); +} + +.toast-buttons button:focus { + outline: none; + box-shadow: 0 0 0 2px rgba(13, 110, 253, 0.25); } .toast-buttons button:nth-child(1) { - background-color: #ecfdf5; - color: #10b981; + background-color: var(--success-background-color); + color: var(--success-text-color); } .toast-buttons button:nth-child(2) { - background-color: #fef2f2; - color: #ef4444; + background-color: var(--error-background-color); + color: var(--error-text-color); } .toast-buttons button:nth-child(3) { - background-color: #fffbeb; - color: #f59e0b; + background-color: var(--warning-background-color); + color: var(--warning-text-color); } .toast-buttons button:nth-child(4) { - background-color: #eff6ff; - color: #3b82f6; + background-color: var(--info-background-color); + color: var(--info-text-color); } .toast-buttons button:hover { filter: brightness(0.95); -} \ No newline at end of file +} diff --git a/preview/src/components/toggle_group/docs.md b/preview/src/components/toggle_group/docs.md new file mode 100644 index 00000000..5cff2489 --- /dev/null +++ b/preview/src/components/toggle_group/docs.md @@ -0,0 +1,18 @@ +The Toggle Group component is used to create a group of toggle buttons that allows the user to select one or more options from a set. It is useful for creating a set of options. + +## Component Structure + +```rust +// The ToggleGroup component wraps all toggle items in the group. +ToggleGroup { + // The orientation of the toggle group, true for horizontal and false for vertical. + horizontal: true, + // The toggle item represents each individual toggle button in the group. + ToggleItem { + // The index of the toggle item, used to determine the order in which items are focused. + index: 0, + // The contents of the toggle item button + {children} + } +} +``` diff --git a/preview/src/components/toggle_group/mod.rs b/preview/src/components/toggle_group/mod.rs new file mode 100644 index 00000000..a86442c2 --- /dev/null +++ b/preview/src/components/toggle_group/mod.rs @@ -0,0 +1,16 @@ +use dioxus::prelude::*; +use dioxus_primitives::toggle_group::{ToggleGroup, ToggleItem}; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/toggle_group/style.css"), + } + ToggleGroup { class: "toggle-group", horizontal: true, + ToggleItem { class: "toggle-item", index: 0usize, "Align Left" } + ToggleItem { class: "toggle-item", index: 1usize, "Align Middle" } + ToggleItem { class: "toggle-item", index: 2usize, "Align Right" } + } + } +} diff --git a/preview/assets/toggle-group.css b/preview/src/components/toggle_group/style.css similarity index 64% rename from preview/assets/toggle-group.css rename to preview/src/components/toggle_group/style.css index 0ed4a37f..08618554 100644 --- a/preview/assets/toggle-group.css +++ b/preview/src/components/toggle_group/style.css @@ -10,21 +10,22 @@ font-size: 14px; padding: 10px; min-width: 35px; - background-color: rgb(228, 228, 228); + color: var(--text-color); + background-color: var(--brighter-background-color); transition: background-color 200ms ease, border 200ms ease; - border-top: 1px solid rgb(94, 94, 94); - border-bottom: 1px solid rgb(94, 94, 94); + border-top: 1px solid var(--dim-border-color); + border-bottom: 1px solid var(--dim-border-color); } .toggle-item:hover, .toggle-item:focus { cursor: pointer; - background-color: rgb(57, 146, 206); + background-color: var(--hover-background-color); } .toggle-item[data-state="on"] { - background-color: rgb(69, 175, 247); + background-color: var(--focused-background-color); } .toggle-item:first-child { @@ -38,5 +39,5 @@ } .toggle-item:first-child, .toggle-item:last-child { - border: 1px solid rgb(94, 94, 94); + border: 1px solid var(--dim-border-color); } \ No newline at end of file diff --git a/preview/src/components/toolbar/docs.md b/preview/src/components/toolbar/docs.md new file mode 100644 index 00000000..510eec48 --- /dev/null +++ b/preview/src/components/toolbar/docs.md @@ -0,0 +1,28 @@ +The toolbar component is a flexible and customizable component that can be used to create a variety of toolbars. It can be used to create a simple toolbar with a title, or a more complex toolbar with multiple buttons and actions. + +## Component Structure + +```rust +// The Toolbar component wraps all toolbar items. +Toolbar { + // The aria_label of the toolbar, used for accessibility purposes. + aria_label: "Toolbar Title", + // The ToolbarButton component represents each individual button in the toolbar. + ToolbarButton { + // The index of the toolbar button, used to determine the order in which buttons are focused. + index: 0, + on_click: |_: ()| { + // This callback is triggered when the button is clicked. + }, + // The contents of the toolbar button + {children} + } + // The ToolbarSeparator component represents a separator line in the toolbar. + ToolbarSeparator { + // The orientation of the separator, true for horizontal and false for vertical. + horizontal: true, + // The decorative property controls if the separator is decorative and should not be visible to screen readers. + decorative: false, + } +} +``` \ No newline at end of file diff --git a/preview/src/components/toolbar/mod.rs b/preview/src/components/toolbar/mod.rs new file mode 100644 index 00000000..13ee1192 --- /dev/null +++ b/preview/src/components/toolbar/mod.rs @@ -0,0 +1,93 @@ +use dioxus::prelude::*; +use dioxus_primitives::toolbar::{Toolbar, ToolbarButton, ToolbarSeparator}; +#[component] +pub(super) fn Demo() -> Element { + let mut text_style = use_signal(Vec::new); + let mut text_align = use_signal(|| String::from("left")); + let mut toggle_style = move |style: &str| { + let mut current_styles = text_style(); + if current_styles.contains(&style.to_string()) { + current_styles.retain(|s| s != style); + } else { + current_styles.push(style.to_string()); + } + text_style.set(current_styles); + }; + let mut set_align = move |align: &str| { + text_align.set(align.to_string()); + }; + let text_classes = use_memo(move || { + let mut classes = Vec::new(); + for style in text_style() { + match style.as_str() { + "bold" => classes.push("toolbar-bold"), + "italic" => classes.push("toolbar-italic"), + "underline" => classes.push("toolbar-underline"), + _ => {} + } + } + classes.join(" ") + }); + let text_align_style = use_memo(move || format!("text-align: {};", text_align())); + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/toolbar/style.css"), + } + div { class: "toolbar-example", + h3 { + width: "100%", + text_align: "center", + "Text Formatting Toolbar" + } + Toolbar { class: "toolbar", aria_label: "Text formatting", + div { class: "toolbar-group", + ToolbarButton { + class: "toolbar-button", + index: 0usize, + on_click: move |_| toggle_style("bold"), + "Bold" + } + ToolbarButton { + class: "toolbar-button", + index: 1usize, + on_click: move |_| toggle_style("italic"), + "Italic" + } + ToolbarButton { + class: "toolbar-button", + index: 2usize, + on_click: move |_| toggle_style("underline"), + "Underline" + } + } + ToolbarSeparator { class: "toolbar-separator" } + div { class: "toolbar-group", + ToolbarButton { + class: "toolbar-button", + index: 3usize, + on_click: move |_| set_align("left"), + "Align Left" + } + ToolbarButton { + class: "toolbar-button", + index: 4usize, + on_click: move |_| set_align("center"), + "Align Center" + } + ToolbarButton { + class: "toolbar-button", + index: 5usize, + on_click: move |_| set_align("right"), + "Align Right" + } + } + } + div { class: "toolbar-content", + p { class: text_classes, style: text_align_style, + "This is a sample text that will be formatted according to the toolbar buttons you click. Try clicking the buttons above to see how the text formatting changes." + } + } + } + } +} diff --git a/preview/assets/toolbar.css b/preview/src/components/toolbar/style.css similarity index 53% rename from preview/assets/toolbar.css rename to preview/src/components/toolbar/style.css index 7d66e6f9..37209ccb 100644 --- a/preview/assets/toolbar.css +++ b/preview/src/components/toolbar/style.css @@ -1,30 +1,37 @@ .toolbar-example { + width: 35rem; + max-width: 100%; margin: 20px; padding: 10px; - border: 1px solid #ccc; - border-radius: 4px; - background-color: #f5f5f5; + border: 1px solid var(--dim-border-color); + border-radius: .5em; + background-color: var(--background-color); } .toolbar { display: flex; + flex-wrap: wrap; + flex-direction: row; + align-items: center; + justify-content: space-between; gap: 5px; padding: 5px; - background-color: #e0e0e0; + background-color: var(--brighter-background-color); border-radius: 4px; } .toolbar button { padding: 8px 12px; - border: 1px solid #ccc; + border: 1px solid var(--dim-border-color); border-radius: 4px; - background-color: #fff; + color: var(--text-color); + background-color: var(--background-color); cursor: pointer; font-size: 14px; } .toolbar button:hover { - background-color: #f0f0f0; + background-color: var(--hover-background-color); } .toolbar button:focus { @@ -37,19 +44,25 @@ cursor: not-allowed; } +.toolbar-group { + display: flex; + flex-direction: row; + gap: 5px; +} + .toolbar-separator { width: 1px; height: 24px; - background-color: #ccc; + background-color: var(--dim-border-color); margin: 0 5px; } .toolbar-content { margin-top: 20px; padding: 20px; - border: 1px solid #ddd; + border: 1px solid var(--dim-border-color); border-radius: 4px; - background-color: #fff; + background-color: var(--background-color); } .toolbar-content p { diff --git a/preview/src/components/tooltip/docs.md b/preview/src/components/tooltip/docs.md new file mode 100644 index 00000000..8fd80b17 --- /dev/null +++ b/preview/src/components/tooltip/docs.md @@ -0,0 +1,23 @@ +The Tooltip component is used to display additional information when a user hovers over an element. + +## Component Structure + +```rust +// The Tooltip component wraps the trigger element and the content that will be displayed on hover. +Tooltip { + // The TooltipTrigger contains the elements that will trigger the tooltip to display when hovered over. + TooltipTrigger { + // The elements that will trigger the tooltip when hovered over. + {children} + } + // The TooltipContent contains the content that will be displayed when the user hovers over the trigger. + TooltipContent { + // The side of the TooltipTrigger where the content will be displayed. Can be one of Top, Right, Bottom, or Left. + side: TooltipSide::Top, + // The alignment of the TooltipContent relative to the TooltipTrigger. Can be one of Start, Center, or End. + align: TooltipAlign::Center, + // The content of the tooltip, which can include text, images, or any other elements. + {children} + } +} +``` \ No newline at end of file diff --git a/preview/src/components/tooltip/mod.rs b/preview/src/components/tooltip/mod.rs new file mode 100644 index 00000000..5b80429b --- /dev/null +++ b/preview/src/components/tooltip/mod.rs @@ -0,0 +1,38 @@ +use dioxus::prelude::*; +use dioxus_primitives::tooltip::{Tooltip, TooltipContent, TooltipSide, TooltipTrigger}; +#[component] +pub(super) fn Demo() -> Element { + rsx! { + document::Link { + rel: "stylesheet", + href: asset!("/src/components/tooltip/style.css"), + } + div { + class: "tooltip-example", + style: "padding: 50px; display: flex; gap: 20px;", + Tooltip { class: "tooltip", + TooltipTrigger { class: "tooltip-trigger", + button { "Hover me" } + } + TooltipContent { class: "tooltip-content", "This is a basic tooltip" } + } + Tooltip { class: "tooltip", + TooltipTrigger { class: "tooltip-trigger", + button { "Right tooltip" } + } + TooltipContent { class: "tooltip-content", side: TooltipSide::Right, + "This tooltip appears on the right" + } + } + Tooltip { class: "tooltip", + TooltipTrigger { class: "tooltip-trigger", + button { "Rich content" } + } + TooltipContent { class: "tooltip-content", style: "width: 200px;", + h4 { style: "margin-top: 0; margin-bottom: 8px;", "Tooltip title" } + p { style: "margin: 0;", "This tooltip contains rich HTML content with styling." } + } + } + } + } +} diff --git a/preview/assets/tooltip.css b/preview/src/components/tooltip/style.css similarity index 81% rename from preview/assets/tooltip.css rename to preview/src/components/tooltip/style.css index cd811a9e..ef956576 100644 --- a/preview/assets/tooltip.css +++ b/preview/src/components/tooltip/style.css @@ -14,8 +14,8 @@ max-width: 250px; padding: 8px 12px; border-radius: 4px; - background-color: #333; - color: white; + background-color: var(--brighter-background-color); + color: var(--text-color); font-size: 14px; line-height: 1.4; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.2); @@ -111,4 +111,24 @@ .tooltip-content[data-state="open"] { display: block; -} \ No newline at end of file +} + +.tooltip button { + padding: 8px 12px; + border-radius: 4px; + cursor: pointer; + user-select: none; + outline: none; + font-size: 14px; + background-color: var(--brighter-background-color); + border: 1px solid var(--dim-border-color); + color: var(--text-color); +} + +.tooltip button:hover { + background: var(--hover-background-color); +} + +.tooltip button:focus { + background: var(--focused-background-color); +} diff --git a/preview/src/main.rs b/preview/src/main.rs index 94a1b6c4..2b00966d 100644 --- a/preview/src/main.rs +++ b/preview/src/main.rs @@ -1,29 +1,17 @@ -use dioxus::{document::eval, prelude::*}; +use dioxus::prelude::*; use dioxus_primitives::{ - accordion::{Accordion, AccordionContent, AccordionItem, AccordionTrigger}, - aspect_ratio::AspectRatio, - avatar::{Avatar, AvatarFallback, AvatarImage}, - calendar::{Calendar, CalendarDate, CalendarGrid, CalendarHeader, CalendarNavigation}, - checkbox::{Checkbox, CheckboxIndicator}, - collapsible::{Collapsible, CollapsibleContent, CollapsibleTrigger}, - context_menu::{ContextMenu, ContextMenuContent, ContextMenuItem, ContextMenuTrigger}, - dropdown_menu::{DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger}, - hover_card::{HoverCard, HoverCardAlign, HoverCardContent, HoverCardSide, HoverCardTrigger}, - menubar::{Menubar, MenubarContent, MenubarItem, MenubarMenu, MenubarTrigger}, - progress::{Progress, ProgressIndicator}, - radio_group::{RadioGroup, RadioItem}, - scroll_area::{ScrollArea, ScrollDirection}, - select::{Select, SelectGroup, SelectOption}, separator::Separator, - slider::{Slider, SliderRange, SliderThumb, SliderTrack, SliderValue}, - switch::{Switch, SwitchThumb}, tabs::{TabContent, TabTrigger, Tabs}, - toast::{ToastOptions, ToastProvider, use_toast}, - toggle_group::{ToggleGroup, ToggleItem}, - toolbar::{Toolbar, ToolbarButton, ToolbarSeparator}, - tooltip::{Tooltip, TooltipContent, TooltipSide, TooltipTrigger}, }; -use std::time::Duration; +mod components; +#[derive(Clone, PartialEq)] +struct ComponentDemoData { + name: &'static str, + docs: &'static str, + rs_highlighted: HighlightedCode, + css_highlighted: HighlightedCode, + component: fn() -> Element, +} fn main() { dioxus::launch(App); @@ -32,767 +20,158 @@ fn main() { #[component] fn App() -> Element { rsx! { - ToastProvider { - document::Link { rel: "stylesheet", href: asset!("/assets/main.css") } - document::Link { rel: "stylesheet", href: asset!("/assets/separator.css") } - - document::Link { rel: "stylesheet", href: asset!("/assets/hero.css") } - div { id: "hero", - h1 { "Dioxus Primitives" } - h2 { "Accessible, unstyled foundational components for Dioxus." } - } - Separator { id: "hero-separator", class: "separator", horizontal: true } - - - document::Link { rel: "stylesheet", href: asset!("/assets/toggle-group.css") } - ToggleGroup { class: "toggle-group", horizontal: true, - ToggleItem { class: "toggle-item", index: 0, "Align Left" } - ToggleItem { class: "toggle-item", index: 1, "Align Middle" } - ToggleItem { class: "toggle-item", index: 2, "Align Right" } - } - - - Collapsible { - CollapsibleTrigger { "Form Example" } - CollapsibleContent { FormExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - Collapsible { - CollapsibleTrigger { "Aspect Ratio Example" } - CollapsibleContent { AspectRatioExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - document::Link { rel: "stylesheet", href: asset!("/assets/progress.css") } - Collapsible { - CollapsibleTrigger { "Progress Example" } - CollapsibleContent { ProgressExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - Collapsible { - CollapsibleTrigger { "Accordion Example" } - CollapsibleContent { AccordionExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - document::Link { rel: "stylesheet", href: asset!("/assets/switch.css") } - Collapsible { - CollapsibleTrigger { "Switch Example" } - CollapsibleContent { SwitchExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - document::Link { rel: "stylesheet", href: asset!("/assets/slider.css") } - Collapsible { - CollapsibleTrigger { "Slider Example" } - CollapsibleContent { SliderExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - document::Link { rel: "stylesheet", href: asset!("/assets/toast.css") } - Collapsible { - CollapsibleTrigger { "Toast Example" } - CollapsibleContent { ToastExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - } - - Collapsible { - CollapsibleTrigger { "Avatar Example" } - CollapsibleContent { AvatarExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - document::Link { rel: "stylesheet", href: asset!("/assets/radio-group.css") } - Collapsible { - CollapsibleTrigger { "Radio Group Example" } - CollapsibleContent { RadioGroupExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - Collapsible { - CollapsibleTrigger { "Tabs Example" } - CollapsibleContent { TabsExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - Collapsible { - CollapsibleTrigger { "Dropdown Menu Example" } - CollapsibleContent { DropdownMenuExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - Collapsible { - CollapsibleTrigger { "Menubar Example" } - CollapsibleContent { MenubarExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - document::Link { rel: "stylesheet", href: asset!("/assets/scroll-area.css") } - Collapsible { - CollapsibleTrigger { "Scroll Area Example" } - CollapsibleContent { ScrollAreaExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - document::Link { rel: "stylesheet", href: asset!("./assets/context-menu.css") } - Collapsible { - CollapsibleTrigger { "Context Menu Example" } - CollapsibleContent { ContextMenuExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - Collapsible { - CollapsibleTrigger { "Toolbar Example" } - CollapsibleContent { ToolbarExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - Collapsible { - CollapsibleTrigger { "Hover Card Example" } - CollapsibleContent { HoverCardExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - document::Link { rel: "stylesheet", href: asset!("./assets/tooltip.css") } - Collapsible { - CollapsibleTrigger { "Tooltip Example" } - CollapsibleContent { TooltipExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - document::Link { rel: "stylesheet", href: asset!("./assets/select.css") } - Collapsible { - CollapsibleTrigger { "Select Example" } - CollapsibleContent { SelectExample {} } - } - - Separator { - class: "separator", - style: "margin: 15px 0;", - horizontal: true, - decorative: true, - } - - document::Link { rel: "stylesheet", href: asset!("./assets/calendar.css") } - Collapsible { - CollapsibleTrigger { "Calendar Example" } - CollapsibleContent { CalendarExample {} } - } + Router:: {} } } -#[component] -fn TooltipExample() -> Element { - rsx! { - div { - class: "tooltip-example", - style: "padding: 50px; display: flex; gap: 20px;", - // Basic tooltip - Tooltip { class: "tooltip", - TooltipTrigger { class: "tooltip-trigger", - button { "Hover me" } - } - TooltipContent { class: "tooltip-content", "This is a basic tooltip" } - } - // Tooltip with different position - Tooltip { class: "tooltip", - TooltipTrigger { class: "tooltip-trigger", - button { "Right tooltip" } - } - TooltipContent { class: "tooltip-content", side: TooltipSide::Right, - "This tooltip appears on the right" - } - } - // Tooltip with HTML content - Tooltip { class: "tooltip", - TooltipTrigger { class: "tooltip-trigger", - button { "Rich content" } - } - TooltipContent { class: "tooltip-content", style: "width: 200px;", - h4 { style: "margin-top: 0; margin-bottom: 8px;", "Tooltip title" } - p { style: "margin: 0;", "This tooltip contains rich HTML content with styling." } - } - } - } - } +#[derive(Routable, Clone, PartialEq)] +pub(crate) enum Route { + #[layout(NavigationLayout)] + #[route("/")] + Home, + #[route("/component/:component_name")] + ComponentDemo { component_name: String }, } #[component] -fn FormExample() -> Element { +fn NavigationLayout() -> Element { rsx! { - form { - onsubmit: move |e| { - println!("{:?}", e.values()); - }, - - Checkbox { id: "tos-check", name: "tos-check", - CheckboxIndicator { "+" } - } - label { r#for: "tos-check", "I agree to the terms presented." } - br {} - button { r#type: "submit", "Submit" } - } + Navbar {} + document::Link { rel: "stylesheet", href: asset!("/assets/main.css") } + document::Link { rel: "stylesheet", href: asset!("/assets/hero.css") } + document::Link { rel: "stylesheet", href: asset!("/src/components/tabs/style.css") } + Outlet:: {} } } #[component] -fn AspectRatioExample() -> Element { +fn Navbar() -> Element { rsx! { - document::Link { rel: "stylesheet", href: asset!("/assets/aspect-ratio.css") } - div { class: "aspect-ratio-container", - AspectRatio { ratio: 4.0 / 3.0, + nav { class: "navbar", + Link { + to: Route::Home, + class: "navbar-brand", img { - class: "aspect-ratio-image", - src: "https://upload.wikimedia.org/wikipedia/commons/thumb/e/ea/Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg/1280px-Van_Gogh_-_Starry_Night_-_Google_Art_Project.jpg", + src: asset!("/assets/dioxus_color.svg"), + alt: "Dioxus Logo", + width: "32", + height: "32", } } - } - } -} - -#[component] -fn AccordionExample() -> Element { - rsx! { - document::Link { rel: "stylesheet", href: asset!("/assets/accordion.css") } - Accordion { - class: "accordion", - allow_multiple_open: false, - horizontal: false, - - for i in 0..4 { - AccordionItem { - class: "accordion-item", - index: i, - - on_change: move |open| { - eval(&format!("console.log({open});")); - }, - on_trigger_click: move || { - eval("console.log('trigger');"); - }, - - AccordionTrigger { class: "accordion-trigger", "the quick brown fox" } - AccordionContent { class: "accordion-content", - div { class: "accordion-content-inner", - p { "lorem ipsum lorem ipsum" } - } - } + div { class: "navbar-links", + Link { + to: Route::Home, + class: "navbar-link", + "Home" } - } - } - } -} - -#[component] -fn ProgressExample() -> Element { - let mut progress = use_signal(|| 80.0); - - rsx! { - Progress { class: "progress", value: Some(progress.into()), - ProgressIndicator { class: "progress-indicator" } - } - button { onclick: move |_| progress.set(progress() + 10.0), "Increment" } - button { onclick: move |_| progress.set(progress() - 10.0), "Decrement" } - button { onclick: move |_| progress.set(0.0), "Reset" } - button { onclick: move |_| progress.set(100.0), "Complete" } - } -} - -#[component] -fn SwitchExample() -> Element { - let mut checked = use_signal(|| false); - - rsx! { - div { class: "switch-example", - label { "Airplane Mode" } - Switch { - class: "switch", - checked, - on_checked_change: move |new_checked| { - checked.set(new_checked); - eval(&format!("console.log('Switch toggled: {}')", new_checked)); - }, - - SwitchThumb { class: "switch-thumb" } - } - } - } -} - -#[component] -fn ToastExample() -> Element { - // Get the toast API - let toast_api = use_toast(); - - rsx! { - div { class: "toast-example", - h3 { "Toast Notifications" } - p { "Click the buttons below to show different types of toast notifications." } - - h4 { "Timed Toasts (auto-dismiss)" } - div { class: "toast-buttons", - button { - onclick: move |_| { - toast_api - .success( - "Success".to_string(), - Some(ToastOptions { - duration: Some(Duration::from_secs(3)), - ..Default::default() - }), - ); - }, - "Success (3s)" - } - - button { - onclick: move |_| { - toast_api - .error( - "Error".to_string(), - Some(ToastOptions { - duration: Some(Duration::from_secs(5)), - ..Default::default() - }), - ); - }, - "Error (5s)" - } - - button { - onclick: move |_| { - toast_api - .warning( - "Warning".to_string(), - Some(ToastOptions { - description: Some("This action might cause issues".to_string()), - duration: Some(Duration::from_secs(3)), - ..Default::default() - }), - ); - }, - "Warning (3s)" - } - } - - h4 { "Permanent Toasts (manual close)" } - div { class: "toast-buttons", - button { - onclick: move |_| { - toast_api - .success( - "Important".to_string(), - Some(ToastOptions { - permanent: true, - ..Default::default() - }), - ); - }, - "Permanent Success" - } - - button { - onclick: move |_| { - toast_api - .error( - "Critical Error".to_string(), - Some(ToastOptions { - permanent: true, - ..Default::default() - }), - ); - }, - "Permanent Error" - } - - button { - onclick: move |_| { - toast_api - .info( - "Custom Toast".to_string(), - Some(ToastOptions { - description: Some( - "This is a custom toast with specific settings".to_string(), - ), - duration: Some(Duration::from_secs(10)), - permanent: false, - }), - ); - }, - "Custom Info (10s)" + Link { + to: "https://docs.rs/crate/dioxus-components/latest", + class: "navbar-link", + "docs.rs" } } } } } -#[component] -fn SliderExample() -> Element { - let mut value = use_signal(|| SliderValue::Single(50.0)); - let range_value = use_signal(|| SliderValue::Range(25.0, 75.0)); - - rsx! { - div { class: "slider-example", - // Single value slider - div { - label { "Single Value Slider" } - div { style: "display: flex; align-items: center; gap: 1rem;", - Slider { - class: "slider", - value, - horizontal: true, - on_value_change: move |v| { - value.set(v); - }, - - SliderTrack { class: "slider-track", - SliderRange { class: "slider-range" } - SliderThumb { class: "slider-thumb" } - } - } - input { - r#type: "text", - readonly: true, - value: match value() { - SliderValue::Single(v) => format!("{:.1}", v), - _ => String::new(), - }, - } - } - } - - // Range slider - // div { - // label { "Range Slider" } - // div { style: "display: flex; align-items: center; gap: 1rem;", - // Slider { - // class: "slider", - // value: range_value, - // on_value_change: move |v| { - // range_value.set(v); - // }, - // - // SliderTrack { class: "slider-track", - // SliderRange { class: "slider-range" } - // SliderThumb { class: "slider-thumb", index: 0 } - // SliderThumb { class: "slider-thumb", index: 1 } - // } - // } - // input { - // r#type: "text", - // readonly: true, - // value: match range_value() { - // SliderValue::Range(start, end) => format!("{:.1}, {:.1}", start, end), - // _ => String::new(), - // }, - // } - // } - // } - } - } +#[derive(Copy, Clone, PartialEq)] +struct HighlightedCode { + light: &'static str, + dark: &'static str, } #[component] -fn AvatarExample() -> Element { - let mut avatar_state = use_signal(|| "No state yet".to_string()); - +fn CodeBlock(source: HighlightedCode, collapsed: bool) -> Element { + let mut copied = use_signal(|| false); rsx! { - document::Link { rel: "stylesheet", href: asset!("./assets/avatar.css") } - - // Basic examples section - div { class: "avatar-example-section", - h4 { "Basic Examples" } - div { class: "avatar-example", - // Basic Avatar with image and fallback - div { class: "avatar-item", - p { class: "avatar-label", "Basic Usage" } - Avatar { - class: "avatar", - on_state_change: move |state| { - avatar_state.set(format!("Avatar 1: {:?}", state)); - }, - - AvatarImage { - src: "https://github.com/DioxusLabs.png", - alt: "User avatar", - } - - AvatarFallback { class: "avatar-fallback", "UA" } - } - } - - // Avatar with error state (fallback shown) - div { class: "avatar-item", - p { class: "avatar-label", "Error State" } - Avatar { - class: "avatar", - on_state_change: move |state| { - avatar_state.set(format!("Avatar 2: {:?}", state)); - }, - - AvatarImage { - src: "https://invalid-url.example/image.jpg", - alt: "Invalid image", - } - - AvatarFallback { class: "avatar-fallback", "JD" } - } - } - - // Avatar with emoji fallback - div { class: "avatar-item", - p { class: "avatar-label", "Emoji Fallback" } - Avatar { - class: "avatar", - on_state_change: move |state| { - avatar_state.set(format!("Avatar 3: {:?}", state)); - }, - - AvatarImage { - src: "https://invalid-url.example/image.jpg", - alt: "Invalid image", - } - - AvatarFallback { class: "avatar-fallback", "👤" } - } - } - - // Avatar with different size - div { class: "avatar-item", - p { class: "avatar-label", "Large Size" } - Avatar { - class: "avatar avatar-lg", - on_state_change: move |state| { - avatar_state.set(format!("Avatar 4: {:?}", state)); - }, - - AvatarImage { - src: "https://github.com/DioxusLabs.png", - alt: "Large avatar", - } - - AvatarFallback { class: "avatar-fallback", "LG" } - } - } - } + pre { + class: "code-block code-block-dark", + "data-collapsed": "{collapsed}", + dangerous_inner_html: source.dark, + } + pre { + class: "code-block code-block-light", + "data-collapsed": "{collapsed}", + dangerous_inner_html: source.light, + } + button { + class: "copy-button", + "data-copied": copied, + "onclick": "navigator.clipboard.writeText(this.parentNode.firstChild.innerText);", + onclick: move |_| copied.set(true), + if copied() { + "Copied!" + } + CopyIcon {} } } } #[component] -fn RadioGroupExample() -> Element { - let mut value = use_signal(|| String::from("option1")); - +fn CopyIcon() -> Element { rsx! { - document::Link { rel: "stylesheet", href: asset!("/assets/radio-group.css") } - RadioGroup { - class: "radio-group", - value, - on_value_change: move |new_value| { - value.set(new_value); - }, - - RadioItem { - class: "radio-item", - value: ReadOnlySignal::new(Signal::new("option1".to_string())), - index: ReadOnlySignal::new(Signal::new(0)), - "Option 1" - } - RadioItem { - class: "radio-item", - value: ReadOnlySignal::new(Signal::new("option2".to_string())), - index: ReadOnlySignal::new(Signal::new(1)), - "Option 2" - } - RadioItem { - class: "radio-item", - value: ReadOnlySignal::new(Signal::new("option3".to_string())), - index: ReadOnlySignal::new(Signal::new(2)), - "Option 3" - } + svg { + width: "24", + height: "24", + stroke_width: "1.5", + fill: "none", + stroke: "currentColor", + path { d: "M8 16c0 1.886 0 2.828.586 3.414C9.172 20 10.114 20 12 20h4c1.886 0 2.828 0 3.414-.586C20 18.828 20 17.886 20 16v-4c0-1.886 0-2.828-.586-3.414C18.828 8 17.886 8 16 8m-8 8h4c1.886 0 2.828 0 3.414-.586C16 14.828 16 13.886 16 12V8m-8 8c-1.886 0-2.828 0-3.414-.586C4 14.828 4 13.886 4 12V8c0-1.886 0-2.828.586-3.414C5.172 4 6.114 4 8 4h4c1.886 0 2.828 0 3.414.586C16 5.172 16 6.114 16 8" } } - - div { style: "margin-top: 1rem;", "Selected value: {value()}" } } } #[component] -fn TabsExample() -> Element { - rsx! { - document::Link { rel: "stylesheet", href: asset!("/assets/tabs.css") } - Tabs { class: "tabs", default_value: "tab1".to_string(), +fn ComponentCode(rs_highlighted: HighlightedCode, css_highlighted: HighlightedCode) -> Element { + let mut collapsed = use_signal(|| true); + rsx! { + Tabs { class: "tabs", default_value: "main.rs", + border_bottom_left_radius: "0.5rem", + border_bottom_right_radius: "0.5rem", div { class: "tabs-list", TabTrigger { class: "tabs-trigger", - value: "tab1".to_string(), - index: ReadOnlySignal::new(Signal::new(0)), - "Tab 1" + value: "main.rs", + index: 0usize, + "main.rs" } TabTrigger { class: "tabs-trigger", - value: "tab2".to_string(), - index: ReadOnlySignal::new(Signal::new(1)), - "Tab 2" - } - TabTrigger { - class: "tabs-trigger", - value: "tab3".to_string(), - index: ReadOnlySignal::new(Signal::new(2)), - "Tab 3" + value: "style.css", + index: 1usize, + "style.css" } } - - TabContent { class: "tabs-content", value: "tab1".to_string(), "Tab 1 Content" } - TabContent { class: "tabs-content", value: "tab2".to_string(), "Tab 2 Content" } - TabContent { class: "tabs-content", value: "tab3".to_string(), "Tab 3 Content" } - } - } -} - -#[component] -fn DropdownMenuExample() -> Element { - rsx! { - document::Link { rel: "stylesheet", href: asset!("./assets/dropdown-menu.css") } - DropdownMenu { class: "dropdown-menu", default_open: false, - - DropdownMenuTrigger { class: "dropdown-menu-trigger", "Open Menu" } - - DropdownMenuContent { class: "dropdown-menu-content", - - DropdownMenuItem { - class: "dropdown-menu-item", - value: ReadOnlySignal::new(Signal::new("item1".to_string())), - index: ReadOnlySignal::new(Signal::new(0)), - on_select: move |value| { - eval(&format!("console.log('Selected: {}')", value)); - }, - "Item 1" - } - - DropdownMenuItem { - class: "dropdown-menu-item", - value: ReadOnlySignal::new(Signal::new("item2".to_string())), - index: ReadOnlySignal::new(Signal::new(1)), - on_select: move |value| { - eval(&format!("console.log('Selected: {}')", value)); - }, - "Item 2" + div { + width: "100%", + height: "100%", + display: "flex", + flex_direction: "column", + justify_content: "center", + align_items: "center", + TabContent { class: "tabs-content", value: "main.rs", width: "100%", position: "relative", + CodeBlock { source: rs_highlighted, collapsed: collapsed() } + } + TabContent { class: "tabs-content", value: "style.css", width: "100%", position: "relative", + CodeBlock { source: css_highlighted, collapsed: collapsed() } } - - DropdownMenuItem { - class: "dropdown-menu-item", - value: ReadOnlySignal::new(Signal::new("item3".to_string())), - index: ReadOnlySignal::new(Signal::new(2)), - on_select: move |value| { - eval(&format!("console.log('Selected: {}')", value)); + button { + width: "100%", + height: "2rem", + color: "var(--text-color)", + background_color: "rgba(0, 0, 0, 0)", + border_radius: "0 0 0.5rem 0.5rem", + border: "none", + text_align: "center", + onclick: move |_| { + collapsed.toggle(); }, - "Item 3" + if collapsed() { + "↓" + } else { + "↑" + } } } } @@ -800,369 +179,114 @@ fn DropdownMenuExample() -> Element { } #[component] -fn MenubarExample() -> Element { +fn ComponentDemo(component_name: String) -> Element { + let Some(demo) = components::DEMOS + .iter() + .find(|demo| demo.name == component_name) + .cloned() + else { + return rsx! { + div { class: "component-demo-not-found", + h3 { "Component not found" } + p { "The requested component does not exist." } + } + }; + }; rsx! { - document::Link { rel: "stylesheet", href: asset!("/assets/menubar.css") } - div { class: "menubar-example", - Menubar { class: "menubar", - MenubarMenu { class: "menubar-menu", index: 0, - MenubarTrigger { class: "menubar-trigger", "File" } - MenubarContent { class: "menubar-content", - MenubarItem { - class: "menubar-item", - value: "new".to_string(), - on_select: move |value| { - eval(&format!("console.log('Selected: {}')", value)); - }, - "New" - } - MenubarItem { - class: "menubar-item", - value: "open".to_string(), - on_select: move |value| { - eval(&format!("console.log('Selected: {}')", value)); - }, - "Open" - } - MenubarItem { - class: "menubar-item", - value: "save".to_string(), - on_select: move |value| { - eval(&format!("console.log('Selected: {}')", value)); - }, - "Save" - } - } - } - - MenubarMenu { class: "menubar-menu", index: 1, - MenubarTrigger { class: "menubar-trigger", "Edit" } - MenubarContent { class: "menubar-content", - MenubarItem { - class: "menubar-item", - value: "cut".to_string(), - on_select: move |value| { - eval(&format!("console.log('Selected: {}')", value)); - }, - "Cut" - } - MenubarItem { - class: "menubar-item", - value: "copy".to_string(), - on_select: move |value| { - eval(&format!("console.log('Selected: {}')", value)); - }, - "Copy" - } - MenubarItem { - class: "menubar-item", - value: "paste".to_string(), - on_select: move |value| { - eval(&format!("console.log('Selected: {}')", value)); - }, - "Paste" - } - } - } - } - } + document::Link { rel: "stylesheet", href: asset!("/assets/prism.css") } + script { src: asset!("/assets/prism.js") } + ComponentHighlight { demo } } } #[component] -fn ScrollAreaExample() -> Element { +fn ComponentHighlight(demo: ComponentDemoData) -> Element { + let ComponentDemoData { + name, + docs, + rs_highlighted, + css_highlighted, + component: Comp, + } = demo; + let name = name.replace("_", " "); rsx! { - div { class: "scroll-area-demo", - // Vertical scroll example - div { class: "scroll-demo-section", - h3 { "Vertical Scroll" } - ScrollArea { - class: "demo-scroll-area", - direction: ScrollDirection::Vertical, - - div { class: "scroll-content", - for i in 1..=20 { - p { "Scrollable content item {i}" } - } + div { class: "component-demo", + h3 { class: "component-title", {name} } + div { class: "component-preview", + div { class: "component-preview-contents", + div { class: "component-preview-frame", Comp {} } + Separator { + class: "component-preview-separator", + horizontal: true, } - } - } - - // Horizontal scroll example - div { class: "scroll-demo-section", - h3 { "Horizontal Scroll" } - ScrollArea { - class: "demo-scroll-area", - direction: ScrollDirection::Horizontal, - - div { class: "scroll-content-horizontal", - for i in 1..=20 { - span { "Column {i} " } + div { class: "component-code", + ComponentCode { + rs_highlighted: rs_highlighted, + css_highlighted: css_highlighted, } } } } - - // Both directions example - div { class: "scroll-demo-section", - h3 { "Both Directions" } - ScrollArea { - class: "demo-scroll-area", - direction: ScrollDirection::Both, - - div { class: "scroll-content-both", - for i in 1..=20 { - div { - for j in 1..=20 { - span { "Cell {i},{j} " } - } - } - } - } - } + div { class: "component-description", + div { dangerous_inner_html: docs } } } } } #[component] -fn ContextMenuExample() -> Element { - let mut selected_value = use_signal(String::new); +fn Home() -> Element { + let mut search = use_signal(|| String::new()); rsx! { - document::Link { rel: "stylesheet", href: asset!("./assets/context-menu.css") } - div { class: "context-menu-example", - ContextMenu { - ContextMenuTrigger { class: "context-menu-trigger", "Right click here to open context menu" } - - ContextMenuContent { class: "context-menu-content", - ContextMenuItem { - class: "context-menu-item", - value: ReadOnlySignal::new(Signal::new("edit".to_string())), - index: ReadOnlySignal::new(Signal::new(0)), - on_select: move |value| { - selected_value.set(value); - }, - "Edit" - } - - ContextMenuItem { - class: "context-menu-item", - value: ReadOnlySignal::new(Signal::new("duplicate".to_string())), - index: ReadOnlySignal::new(Signal::new(1)), - on_select: move |value| { - selected_value.set(value); - }, - "Duplicate" - } - - ContextMenuItem { - class: "context-menu-item", - value: ReadOnlySignal::new(Signal::new("delete".to_string())), - index: ReadOnlySignal::new(Signal::new(2)), - on_select: move |value| { - selected_value.set(value); - }, - "Delete" - } - } + div { id: "hero", + h1 { "Dioxus Primitives" } + h2 { + b{ "Accessible" } + ", " + i { "unstyled" } + " foundational components for Dioxus." } - - div { class: "selected-value", - if selected_value().is_empty() { - "No action selected" - } else { - "Selected action: {selected_value()}" + div { + id: "hero-search-container", + input { + id: "hero-search-input", + type: "search", + placeholder: "Search components...", + value: search, + oninput: move |e| { + search.set(e.value()); + }, } } } - } -} - -#[component] -fn ToolbarExample() -> Element { - let mut text_style = use_signal(Vec::new); - let mut text_align = use_signal(|| String::from("left")); - - let mut toggle_style = move |style: &str| { - let mut current_styles = text_style(); - if current_styles.contains(&style.to_string()) { - current_styles.retain(|s| s != style); - } else { - current_styles.push(style.to_string()); - } - text_style.set(current_styles); - }; - - let mut set_align = move |align: &str| { - text_align.set(align.to_string()); - }; - - let text_classes = use_memo(move || { - let mut classes = Vec::new(); - for style in text_style() { - match style.as_str() { - "bold" => classes.push("toolbar-bold"), - "italic" => classes.push("toolbar-italic"), - "underline" => classes.push("toolbar-underline"), - _ => {} - } - } - classes.join(" ") - }); - - let text_align_style = use_memo(move || format!("text-align: {};", text_align())); - - rsx! { - document::Link { rel: "stylesheet", href: asset!("/assets/toolbar.css") } - - div { class: "toolbar-example", - h3 { "Text Formatting Toolbar" } - - Toolbar { class: "toolbar", aria_label: "Text formatting", - - ToolbarButton { - class: "toolbar-button", - index: ReadOnlySignal::new(Signal::new(0)), - on_click: move |_| toggle_style("bold"), - "Bold" - } - - ToolbarButton { - class: "toolbar-button", - index: ReadOnlySignal::new(Signal::new(1)), - on_click: move |_| toggle_style("italic"), - "Italic" - } - - ToolbarButton { - class: "toolbar-button", - index: ReadOnlySignal::new(Signal::new(2)), - on_click: move |_| toggle_style("underline"), - "Underline" - } - - ToolbarSeparator { class: "toolbar-separator" } - - ToolbarButton { - class: "toolbar-button", - index: ReadOnlySignal::new(Signal::new(3)), - on_click: move |_| set_align("left"), - "Align Left" - } - - ToolbarButton { - class: "toolbar-button", - index: ReadOnlySignal::new(Signal::new(4)), - on_click: move |_| set_align("center"), - "Align Center" - } - - ToolbarButton { - class: "toolbar-button", - index: ReadOnlySignal::new(Signal::new(5)), - on_click: move |_| set_align("right"), - "Align Right" - } - } - - div { class: "toolbar-content", - p { class: text_classes, style: text_align_style, - "This is a sample text that will be formatted according to the toolbar buttons you click. Try clicking the buttons above to see how the text formatting changes." - } - } + ComponentGallery { + search } } } #[component] -fn HoverCardExample() -> Element { +fn ComponentGallery(search: String) -> Element { rsx! { - document::Link { rel: "stylesheet", href: asset!("/assets/hover-card.css") } - - div { - class: "hover-card-example", - style: "padding: 50px; display: flex; gap: 40px;", - // User profile hover card - HoverCard { class: "hover-card", - HoverCardTrigger { class: "hover-card-trigger", - button { class: "user-trigger", "@johndoe" } - } - - HoverCardContent { class: "hover-card-content", side: HoverCardSide::Bottom, - div { class: "user-card", - div { class: "user-card-header", - img { - class: "user-card-avatar", - src: "https://github.com/DioxusLabs.png", - alt: "User avatar", - } - div { - h4 { class: "user-card-name", "John Doe" } - p { class: "user-card-username", "@johndoe" } - } - } - - p { class: "user-card-bio", - "Software developer passionate about Rust and web technologies. Building awesome UI components with Dioxus." - } - - div { class: "user-card-stats", - div { class: "user-card-stat", - span { class: "user-card-stat-value", "142" } - span { class: "user-card-stat-label", "Posts" } - } - div { class: "user-card-stat", - span { class: "user-card-stat-value", "2.5k" } - span { class: "user-card-stat-label", "Followers" } - } - div { class: "user-card-stat", - span { class: "user-card-stat-value", "350" } - span { class: "user-card-stat-label", "Following" } - } - } - } - } - } - - // Product hover card - HoverCard { class: "hover-card", - HoverCardTrigger { class: "hover-card-trigger", - button { class: "product-trigger", "View Product" } - } - - HoverCardContent { - class: "hover-card-content", - side: HoverCardSide::Right, - align: HoverCardAlign::Start, - div { class: "product-card", - img { - class: "product-card-image", - src: "https://images.unsplash.com/photo-1505740420928-5e560c06d30e", - alt: "Product image", + div { class: "masonry-with-columns", + for ComponentDemoData { component : Comp, name, .. } in components::DEMOS.iter().cloned() { + if search.is_empty() || name.to_lowercase().contains(&search.to_lowercase()) { + div { class: "masonry-preview-frame", position: "relative", + h3 { class: "component-title", {name.replace("_", " ")} } + GotoIcon { + class: "goto-icon", + position: "absolute", + margin: "0.5rem", + top: "0", + right: "0", + to: Route::ComponentDemo { + component_name: name.to_string(), + }, } - h4 { class: "product-card-title", "Wireless Headphones" } - p { class: "product-card-price", "$129.99" } - p { class: "product-card-description", - "High-quality wireless headphones with noise cancellation and 30-hour battery life." + div { class: "masonry-component-frame", + Comp {} } - div { class: "product-card-rating", "★★★★☆ (4.5)" } - } - } - } - - // Link hover card - HoverCard { class: "hover-card", - HoverCardTrigger { class: "hover-card-trigger", - a { href: "#", "Hover over this link" } - } - - HoverCardContent { - class: "hover-card-content", - side: HoverCardSide::Top, - align: HoverCardAlign::Center, - div { style: "padding: 8px;", - p { style: "margin: 0;", "This link will take you to an external website." } } } } @@ -1171,100 +295,18 @@ fn HoverCardExample() -> Element { } #[component] -fn SelectExample() -> Element { - let mut selected = use_signal(|| None::); - - // Debug output for selected value - use_effect(move || { - if let Some(value) = selected() { - println!("Selected value: {}", value); - } - }); - - rsx! { - document::Link { rel: "stylesheet", href: asset!("./assets/select.css") } - div { class: "select-example", - h3 { "Select Example" } - - // Basic select - div { class: "select-container", - // Label for the select - label { class: "select-label", "Choose a fruit:" } - - // Native select element - Select { - class: "select", - value: selected, - on_value_change: move |value| selected.set(value), - placeholder: "Select a fruit...", - - // Fruits group - SelectGroup { label: "Fruits".to_string(), - - SelectOption { value: "apple".to_string(), "Apple" } - SelectOption { value: "banana".to_string(), "Banana" } - SelectOption { value: "orange".to_string(), "Orange" } - SelectOption { value: "strawberry".to_string(), "Strawberry" } - SelectOption { value: "watermelon".to_string(), "Watermelon" } - } - - // Other options group - SelectGroup { label: "Other".to_string(), - - SelectOption { value: "other".to_string(), "Other" } - } - } - } - - // Display selected value - div { class: "selected-value", - if let Some(value) = selected() { - "Selected: {value}" - } else { - "No selection" - } - } - } - } -} - -#[component] -fn CalendarExample() -> Element { - let mut selected_date = use_signal(|| None::); - let mut view_date = use_signal(|| CalendarDate::new(2024, 5, 15)); - - rsx! { - document::Link { rel: "stylesheet", href: asset!("/assets/calendar.css") } - - div { class: "calendar-example", style: "padding: 20px;", - // Basic calendar - div { class: "calendar", - Calendar { - selected_date: selected_date(), - on_date_change: move |date| { - println!("Selected date: {:?}", date); - selected_date.set(date); - }, - view_date: view_date(), - on_view_change: move |new_view: CalendarDate| { - println!("View changed to: {}-{}", new_view.year, new_view.month); - view_date.set(new_view); - }, - - CalendarHeader { CalendarNavigation {} } - - CalendarGrid {} - } - } - - // Display selected date - div { class: "selected-date", style: "margin-top: 20px;", - if let Some(date) = selected_date() { - p { style: "font-weight: bold;", "Selected date: {date}" } - } else { - p { style: "color: #666;", "No date selected" } - } +fn GotoIcon(mut props: LinkProps) -> Element { + props.children = rsx! { + svg { + width: "20", + height: "20", + view_box: "0 0 24 24", + xmlns: "http://www.w3.org/2000/svg", + path { + d: "M5 21q-.825 0-1.412-.587T3 19V5q0-.825.588-1.412T5 3h7v2H5v14h14v-7h2v7q0 .825-.587 1.413T19 21zm4.7-5.3l-1.4-1.4L17.6 5H14V3h7v7h-2V6.4z", + fill: "var(--text-color)", } } - } + }; + Link(props) } diff --git a/primitives/Cargo.toml b/primitives/Cargo.toml index 10bd2326..8f5d37d3 100644 --- a/primitives/Cargo.toml +++ b/primitives/Cargo.toml @@ -12,5 +12,6 @@ repository = "https://github.com/DioxusLabs/components" [dependencies] dioxus-lib.workspace = true +dioxus.workspace = true dioxus-time = "=0.1.0-alpha.1" -tracing.workspace = true \ No newline at end of file +tracing.workspace = true diff --git a/primitives/src/accordion.rs b/primitives/src/accordion.rs index f41f8c4a..96e2cd6f 100644 --- a/primitives/src/accordion.rs +++ b/primitives/src/accordion.rs @@ -1,4 +1,4 @@ -use crate::{use_id_or, use_unique_id}; +use crate::{use_effect_cleanup, use_id_or, use_unique_id}; use dioxus_lib::prelude::*; use std::rc::Rc; @@ -257,7 +257,7 @@ pub fn AccordionItem(props: AccordionItemProps) -> Element { on_trigger_click: props.on_trigger_click, }); - use_drop(move || ctx.unregister_item()); + use_effect_cleanup(move || ctx.unregister_item()); // Open this item if we're set as default. use_hook(move || { diff --git a/primitives/src/calendar.rs b/primitives/src/calendar.rs index 711e81d2..c86ff0f9 100644 --- a/primitives/src/calendar.rs +++ b/primitives/src/calendar.rs @@ -1,4 +1,4 @@ -use crate::{use_controlled, use_unique_id}; +use crate::use_unique_id; use dioxus_lib::prelude::*; use std::fmt; @@ -140,14 +140,14 @@ struct CalendarContext { pub struct CalendarProps { /// The selected date #[props(default)] - selected_date: Option, + selected_date: ReadOnlySignal>, /// Callback when selected date changes #[props(default)] on_date_change: Callback>, /// The month being viewed - view_date: CalendarDate, + view_date: ReadOnlySignal, /// Callback when view date changes #[props(default)] @@ -197,7 +197,7 @@ pub struct CalendarProps { pub fn Calendar(props: CalendarProps) -> Element { // State for calendar mode let mut mode = use_signal(|| props.mode); - let set_mode = Callback::new(move |new_mode: CalendarMode| { + let set_mode = use_callback(move |new_mode: CalendarMode| { mode.set(new_mode); props.on_mode_change.call(new_mode); }); @@ -210,9 +210,9 @@ pub fn Calendar(props: CalendarProps) -> Element { // Create context provider for child components let _ctx = use_context_provider(|| CalendarContext { - selected_date: ReadOnlySignal::new(Signal::new(props.selected_date.clone())), + selected_date: props.selected_date, set_selected_date: props.on_date_change.clone(), - view_date: ReadOnlySignal::new(Signal::new(props.view_date.clone())), + view_date: props.view_date, set_view_date: props.on_view_change.clone(), mode: mode.into(), set_mode, @@ -328,7 +328,7 @@ pub fn CalendarNavigation(props: CalendarNavigationProps) -> Element { r#type: "button", onclick: handle_prev_month, disabled: (ctx.disabled)(), - "←" + "⬅" } div { class: "calendar-nav-title", {month_year} } @@ -339,7 +339,7 @@ pub fn CalendarNavigation(props: CalendarNavigationProps) -> Element { r#type: "button", onclick: handle_next_month, disabled: (ctx.disabled)(), - "→" + "⮕" } } } @@ -376,7 +376,6 @@ pub fn CalendarGrid(props: CalendarGridProps) -> Element { let days_grid = use_memo(move || { // Get the current view date from context let view_date = (ctx.view_date)(); - println!("Generating grid for {}-{}", view_date.year, view_date.month); let days_in_month = view_date.days_in_month(); // For a proper calendar grid, we need to determine the day of week for the first day diff --git a/primitives/src/checkbox.rs b/primitives/src/checkbox.rs index d1acd164..6cbe88be 100644 --- a/primitives/src/checkbox.rs +++ b/primitives/src/checkbox.rs @@ -195,12 +195,12 @@ fn BubbleInput( id, type: "checkbox", aria_hidden: "true", - tabindex: -1, + tabindex: "-1", position: "absolute", pointer_events: "none", - opacity: 0, - margin: 0, - style: "transform: 'translateX(-100%)';", + opacity: "0", + margin: "0", + transform: "translateX(-100%)", // Default checked checked: default_checked != CheckboxState::Unchecked, diff --git a/primitives/src/context_menu.rs b/primitives/src/context_menu.rs index bab8f8b6..f2d3b45e 100644 --- a/primitives/src/context_menu.rs +++ b/primitives/src/context_menu.rs @@ -1,4 +1,4 @@ -use crate::use_controlled; +use crate::{use_controlled, use_effect_cleanup}; use dioxus_lib::prelude::*; #[derive(Clone, Copy)] @@ -276,7 +276,7 @@ pub fn ContextMenuItem(props: ContextMenuItemProps) -> Element { }); // Cleanup when the component is unmounted - use_drop(move || { + use_effect_cleanup(move || { ctx.item_count -= 1; if (ctx.current_focus)() == Some((props.index)()) { ctx.set_focus(None); diff --git a/primitives/src/dropdown_menu.rs b/primitives/src/dropdown_menu.rs index f4623436..da027d14 100644 --- a/primitives/src/dropdown_menu.rs +++ b/primitives/src/dropdown_menu.rs @@ -1,4 +1,4 @@ -use crate::use_controlled; +use crate::{use_controlled, use_effect_cleanup}; use dioxus_lib::prelude::*; #[derive(Clone, Copy)] @@ -176,7 +176,7 @@ pub fn DropdownMenuItem(props: DropdownMenuItemProps) -> Element { }); // Cleanup when the component is unmounted - use_drop(move || { + use_effect_cleanup(move || { ctx.item_count -= 1; if (ctx.current_focus)() == Some((props.index)()) { ctx.set_focus(None); diff --git a/primitives/src/lib.rs b/primitives/src/lib.rs index fcac966c..244650ae 100644 --- a/primitives/src/lib.rs +++ b/primitives/src/lib.rs @@ -1,3 +1,5 @@ +use std::sync::atomic::{AtomicUsize, Ordering}; + use dioxus_lib::prelude::*; pub mod accordion; @@ -29,17 +31,22 @@ pub mod tooltip; /// Generate a runtime-unique id. fn use_unique_id() -> Signal { - static NEXT_ID: GlobalSignal = Signal::global(|| 0); - - let id = *NEXT_ID.peek(); - let id_str = format!("dxc-{id}"); + static NEXT_ID: AtomicUsize = AtomicUsize::new(0); - // Update the ID counter in an effect to avoid signal writes during rendering - use_effect(move || { - *NEXT_ID.write() += 1; + #[allow(unused_mut)] + let mut initial_value = use_hook(|| { + let id = NEXT_ID.fetch_add(1, Ordering::Relaxed); + let id_str = format!("dxc-{id}"); + id_str }); - use_signal(|| id_str) + fullstack! { + let server_id = dioxus::prelude::use_server_cached(move || { + initial_value.clone() + }); + initial_value = server_id; + } + use_signal(|| initial_value) } // Elements can only have one id so if the user provides their own, we must use it as the aria id. @@ -73,10 +80,15 @@ fn use_controlled( let mut internal_value = use_signal(|| prop.map(|x| x()).unwrap_or(default)); let value = use_memo(move || prop.unwrap_or(internal_value)()); - let set_value = Callback::new(move |x: T| { + let set_value = use_callback(move |x: T| { internal_value.set(x.clone()); on_change.call(x); }); (value, set_value) } + +/// Run some cleanup code when the component is unmounted if the effect was run. +fn use_effect_cleanup(#[allow(unused)] cleanup: F) { + web!(use_drop(cleanup)) +} diff --git a/primitives/src/menubar.rs b/primitives/src/menubar.rs index 8536b6f1..da52e606 100644 --- a/primitives/src/menubar.rs +++ b/primitives/src/menubar.rs @@ -1,5 +1,7 @@ use dioxus_lib::prelude::*; +use crate::use_effect_cleanup; + #[derive(Clone, Copy)] struct MenubarContext { // Currently open menu index @@ -58,7 +60,7 @@ pub struct MenubarProps { #[component] pub fn Menubar(props: MenubarProps) -> Element { let mut open_menu = use_signal(|| None); - let set_open_menu = Callback::new(move |idx| open_menu.set(idx)); + let set_open_menu = use_callback(move |idx| open_menu.set(idx)); let mut ctx = use_context_provider(|| MenubarContext { open_menu, @@ -102,7 +104,7 @@ pub fn MenubarMenu(props: MenubarMenuProps) -> Element { ctx.menu_count += 1; }); - use_drop(move || { + use_effect_cleanup(move || { ctx.menu_count -= 1; if (ctx.current_focus)() == Some(props.index) { ctx.set_focus(None); diff --git a/primitives/src/portal.rs b/primitives/src/portal.rs index ebbc83d2..69adc6d1 100644 --- a/primitives/src/portal.rs +++ b/primitives/src/portal.rs @@ -1,6 +1,8 @@ use dioxus_lib::{prelude::*, warnings::Warning}; use std::collections::HashMap; +use crate::use_effect_cleanup; + #[derive(Debug, Clone, Copy, PartialEq)] pub struct PortalId(usize); @@ -34,7 +36,7 @@ pub fn use_portal() -> PortalId { }); // Cleanup the portal. - use_drop(move || { + use_effect_cleanup(move || { let mut ctx = consume_context::(); ctx.portals.write().remove(&id.0); sig.manually_drop(); diff --git a/primitives/src/progress.rs b/primitives/src/progress.rs index f60c1d9b..bd3a706a 100644 --- a/primitives/src/progress.rs +++ b/primitives/src/progress.rs @@ -3,7 +3,7 @@ use dioxus_lib::prelude::*; #[derive(Props, Clone, PartialEq)] pub struct ProgressProps { /// The current progress value, between 0 and max - value: Option>, + value: ReadOnlySignal>, /// The maximum value. Defaults to 100 #[props(default = ReadOnlySignal::new(Signal::new(100.0)))] @@ -19,9 +19,9 @@ pub struct ProgressProps { pub fn Progress(props: ProgressProps) -> Element { // Calculate percentage for styling and "data-state" let percentage = use_memo(move || { - props.value.map(|v| { + props.value.cloned().map(|v| { let max = (props.max)(); - (v() / max) * 100.0 + (v / max) * 100.0 }) }); @@ -35,9 +35,9 @@ pub fn Progress(props: ProgressProps) -> Element { role: "progressbar", "aria-valuemin": 0, "aria-valuemax": props.max, - "aria-valuenow": props.value.map(|v| v()), + "aria-valuenow": props.value.cloned(), "data-state": state, - "data-value": props.value.map(|v| v().to_string()), + "data-value": props.value.cloned().map(|v| v.to_string()), "data-max": props.max, style: percentage().map(|p| format!("--progress-value: {}%", p)), ..props.attributes, diff --git a/primitives/src/slider.rs b/primitives/src/slider.rs index 71eb34ce..d91e5561 100644 --- a/primitives/src/slider.rs +++ b/primitives/src/slider.rs @@ -1,8 +1,8 @@ use crate::use_controlled; +use dioxus_lib::html::geometry::Pixels; +use dioxus_lib::html::geometry::euclid::Rect; use dioxus_lib::prelude::*; use std::ops::RangeInclusive; -use dioxus_lib::html::geometry::euclid::Rect; -use dioxus_lib::html::geometry::Pixels; #[derive(Debug, Clone, PartialEq)] pub enum SliderValue { @@ -77,8 +77,6 @@ pub fn Slider(props: SliderProps) -> Element { }; let range = props.min..=props.max; - - let mut dragging = use_signal(|| false); let ctx = use_context_provider(|| SliderContext { @@ -94,8 +92,8 @@ pub fn Slider(props: SliderProps) -> Element { dragging: dragging.into(), }); - - let rect = use_signal(|| None); + let mut rect = use_signal(|| None); + let mut div_element = use_signal(|| None); rsx! { div { @@ -103,14 +101,22 @@ pub fn Slider(props: SliderProps) -> Element { "data-disabled": props.disabled, "data-orientation": orientation, - onmounted: move |evt| { - let mut rect = rect.clone(); + onmounted: move |evt| async move { // Get the bounding rect of the slider - spawn(async move { - if let Ok(r) = evt.data().get_client_rect().await { - rect.set(Some(r)); - } - }); + if let Ok(r) = evt.data().get_client_rect().await { + rect.set(Some(r)); + } + div_element.set(Some(evt.data())); + }, + onresize: move |_| async move { + // Update the rect on resize + let Some(div_element) = div_element() else { + tracing::warn!("Slider div element is not (yet) set"); + return; + }; + if let Ok(r) = div_element.get_client_rect().await { + rect.set(Some(r)); + } }, onmousemove: move |e| { if !dragging() || (ctx.disabled)() { @@ -143,7 +149,7 @@ pub fn Slider(props: SliderProps) -> Element { if (ctx.disabled)() { return; } - let Some(rect) = rect() else { + let Some(rect) = rect() else { tracing::warn!("Slider rect is not (yet) set"); return; }; @@ -307,11 +313,11 @@ pub fn SliderThumb(props: SliderThumbProps) -> Element { fn linear_scale(input: [f64; 2], output: [f64; 2]) -> impl Fn(f64) -> f64 { let [in_min, in_max] = input; let [out_min, out_max] = output; - + move |x: f64| { // Calculate position in input range (0.0 ~ 1.0) let normalized = (x - in_min) / (in_max - in_min); - + // Convert to output range out_min + normalized * (out_max - out_min) } @@ -330,11 +336,17 @@ fn linear_scale(input: [f64; 2], output: [f64; 2]) -> impl Fn(f64) -> f64 { /// # Returns /// /// The calculated value within the range -fn get_value_from_pointer(pointer_position: f64, rect: &Rect, min: f64, max: f64, inverted: bool) -> f64 { +fn get_value_from_pointer( + pointer_position: f64, + rect: &Rect, + min: f64, + max: f64, + inverted: bool, +) -> f64 { let input = [0.0, rect.width()]; let output = if !inverted { [min, max] } else { [max, min] }; let value = linear_scale(input, output); - + value(pointer_position - rect.origin.x) } diff --git a/primitives/src/tabs.rs b/primitives/src/tabs.rs index a35f0142..358d966e 100644 --- a/primitives/src/tabs.rs +++ b/primitives/src/tabs.rs @@ -1,4 +1,4 @@ -use crate::use_controlled; +use crate::{use_controlled, use_effect_cleanup}; use dioxus_lib::prelude::*; #[derive(Clone, Copy)] @@ -147,7 +147,7 @@ pub fn TabTrigger(props: TabTriggerProps) -> Element { ctx.item_count += 1; }); - use_drop(move || { + use_effect_cleanup(move || { ctx.item_count -= 1; if (ctx.current_focus)() == Some((props.index)()) { ctx.set_focus(None); @@ -221,6 +221,9 @@ pub struct TabContentProps { id: Option, class: Option, + #[props(extends = GlobalAttributes)] + #[props(extends = div)] + attributes: Vec, children: Element, } @@ -239,6 +242,7 @@ pub fn TabContent(props: TabContentProps) -> Element { tabindex: "0", "data-state": if selected() { "active" } else { "inactive" }, hidden: !selected(), + ..props.attributes, {props.children} } diff --git a/primitives/src/toast.rs b/primitives/src/toast.rs index 3b8a9d45..4104d24d 100644 --- a/primitives/src/toast.rs +++ b/primitives/src/toast.rs @@ -69,14 +69,16 @@ pub fn ToastProvider(props: ToastProviderProps) -> Element { let portal = use_portal(); // Create context first so we can reference it in the callbacks + let add_toast = use_callback(|_| {}); // Temporary placeholder + let remove_toast = use_callback(|_| {}); // Temporary placeholder let ctx = ToastCtx { toasts, - add_toast: Callback::new(|_| {}), // Temporary placeholder - remove_toast: Callback::new(|_| {}), // Temporary placeholder + add_toast, + remove_toast, }; // Remove toast callback - let remove_toast = Callback::new(move |id: usize| { + let remove_toast = use_callback(move |id: usize| { let mut toasts_vec = toasts.write(); if let Some(pos) = toasts_vec.iter().position(|t| t.id == id) { toasts_vec.remove(pos); @@ -84,7 +86,7 @@ pub fn ToastProvider(props: ToastProviderProps) -> Element { }); // Add toast callback - let add_toast = Callback::new( + let add_toast = use_callback( move |(title, description, toast_type, duration, permanent): ( String, Option, @@ -166,7 +168,7 @@ pub fn ToastProvider(props: ToastProviderProps) -> Element { // Render all toasts for toast in toast_list().iter() { Toast { - key: format!("{}", toast.id), + key: "{toast.id}", id: toast.id, title: toast.title.clone(), description: toast.description.clone(), @@ -322,7 +324,12 @@ impl Toasts { // Hook to use the toast API pub fn use_toast() -> Toasts { - let ctx = use_context::(); + use_hook(consume_toast) +} + +// Consume the toast API from the context +pub fn consume_toast() -> Toasts { + let ctx = consume_context::(); let add_toast = ctx.add_toast; let remove_toast = ctx.remove_toast; diff --git a/primitives/src/toggle_group.rs b/primitives/src/toggle_group.rs index 324a186d..f75bf8ff 100644 --- a/primitives/src/toggle_group.rs +++ b/primitives/src/toggle_group.rs @@ -1,4 +1,4 @@ -use crate::{toggle::Toggle, use_controlled}; +use crate::{toggle::Toggle, use_controlled, use_effect_cleanup}; use dioxus_lib::prelude::*; use std::{collections::HashSet, rc::Rc}; @@ -219,7 +219,7 @@ pub fn ToggleItem(props: ToggleItemProps) -> Element { // un/register item with ctx use_hook(move || ctx.register_item()); - use_drop(move || ctx.unregister_item()); + use_effect_cleanup(move || ctx.unregister_item()); // We need a kept-alive signal to control the toggle. let mut pressed = use_signal(|| ctx.is_pressed(props.index));