diff --git a/.github/free_space.sh b/.github/free_space.sh new file mode 100644 index 000000000..70bef384d --- /dev/null +++ b/.github/free_space.sh @@ -0,0 +1,12 @@ +df -h +sudo rm -rf ${GITHUB_WORKSPACE}/.git +sudo rm -rf "$AGENT_TOOLSDIRECTORY" +sudo rm -rf /usr/share/dotnet +sudo apt-get remove -y '^ghc-8.*' +sudo apt-get remove -y '^dotnet-.*' +sudo apt-get remove -y '^llvm-.*' +sudo apt-get remove -y 'php.*' +sudo apt-get remove -y azure-cli google-cloud-sdk hhvm google-chrome-stable firefox powershell mono-devel +sudo apt-get autoremove -y +sudo apt-get clean +df -h diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 7e5cfe5fa..de7efb060 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -13,7 +13,6 @@ on: - lib.rs - Cargo.toml - Makefile.toml - - playwright-tests/** pull_request: types: [opened, synchronize, reopened, ready_for_review] @@ -70,12 +69,13 @@ jobs: - uses: davidB/rust-cargo-make@v1 - uses: browser-actions/setup-firefox@latest - uses: jetli/wasm-pack-action@v0.4.0 - - run: sudo rm -rf /usr/share/dotnet - - run: sudo rm -rf "$AGENT_TOOLSDIRECTORY" - - run: | - df -h - sudo rm -rf ${GITHUB_WORKSPACE}/.git - df -h + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@v1.3.1 + with: # speed things up a bit + large-packages: false + docker-images: false + swap-storage: false + - run: cargo make tests fmt: @@ -112,42 +112,43 @@ jobs: save-if: ${{ github.ref == 'refs/heads/master' }} - run: cargo clippy --workspace --examples --tests -- -D warnings - miri: - if: github.event.pull_request.draft == false - name: Miri - runs-on: ubuntu-latest - env: - CARGO_UNSTABLE_SPARSE_REGISTRY: 'true' - RUSTFLAGS: -Dwarnings - RUST_BACKTRACE: 1 - MIRIFLAGS: -Zmiri-tag-gc=1 - # Change to specific Rust release to pin - rust_stable: stable - rust_nightly: nightly-2023-11-16 - rust_clippy: 1.70.0 + # We removed most unsafe that we can, and using nightly doubles our cache size + # miri: + # if: github.event.pull_request.draft == false + # name: Miri + # runs-on: ubuntu-latest + # env: + # CARGO_UNSTABLE_SPARSE_REGISTRY: 'true' + # RUSTFLAGS: -Dwarnings + # RUST_BACKTRACE: 1 + # MIRIFLAGS: -Zmiri-tag-gc=1 + # # Change to specific Rust release to pin + # rust_stable: stable + # rust_nightly: nightly-2023-11-16 + # rust_clippy: 1.70.0 - steps: - - uses: actions/checkout@v4 - - uses: ilammy/setup-nasm@v1 - - name: Install Rust ${{ env.rust_nightly }} - uses: dtolnay/rust-toolchain@master - with: - toolchain: ${{ env.rust_nightly }} - components: miri - - uses: Swatinem/rust-cache@v2 - with: - cache-all-crates: "true" - save-if: ${{ github.ref == 'refs/heads/master' }} - - name: miri - # Many of tests in tokio/tests and doctests use #[tokio::test] or - # #[tokio::main] that calls epoll_create1 that Miri does not support. - # run: cargo miri test --features full --lib --no-fail-fast - run: | - cargo miri test --package dioxus-core -- --exact --nocapture - cargo miri test --package dioxus-native-core --test miri_native -- --exact --nocapture - env: - MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-retag-fields - PROPTEST_CASES: 10 + # steps: + # - uses: actions/checkout@v4 + # - uses: ilammy/setup-nasm@v1 + # - name: Install Rust ${{ env.rust_nightly }} + # uses: dtolnay/rust-toolchain@master + # with: + # toolchain: ${{ env.rust_nightly }} + # components: miri + # - uses: Swatinem/rust-cache@v2 + # with: + # cache-all-crates: "true" + # save-if: ${{ github.ref == 'refs/heads/master' }} + # - name: miri + # # Many of tests in tokio/tests and doctests use #[tokio::test] or + # # #[tokio::main] that calls epoll_create1 that Miri does not support. + # # run: cargo miri test --features full --lib --no-fail-fast + # run: | + # cargo miri test --package dioxus-core -- --exact --nocapture + # cargo miri test --package dioxus-native-core --test miri_native -- --exact --nocapture + # env: + # MIRIFLAGS: -Zmiri-disable-isolation -Zmiri-strict-provenance -Zmiri-retag-fields + # PROPTEST_CASES: 10 playwright: if: github.event.pull_request.draft == false @@ -160,6 +161,12 @@ jobs: - uses: actions/setup-node@v4 with: node-version: 16 + - name: Free Disk Space (Ubuntu) + uses: jlumbroso/free-disk-space@v1.3.1 + with: # speed things up a bit + large-packages: false + docker-images: false + swap-storage: false - name: Install Rust uses: dtolnay/rust-toolchain@master with: @@ -172,19 +179,19 @@ jobs: - name: Install dependencies run: npm ci - working-directory: ./playwright-tests + working-directory: ./packages/playwright-tests - name: Install Playwright run: npm install -D @playwright/test - working-directory: ./playwright-tests + working-directory: ./packages/playwright-tests - name: Install Playwright Browsers run: npx playwright install --with-deps - working-directory: ./playwright-tests + working-directory: ./packages/playwright-tests - name: Run Playwright tests run: npx playwright test - working-directory: ./playwright-tests + working-directory: ./packages/playwright-tests - uses: actions/upload-artifact@v4 if: always() @@ -205,7 +212,7 @@ jobs: - { target: x86_64-pc-windows-msvc, os: windows-latest, - toolchain: "1.70.0", + toolchain: "1.75.0", cross: false, command: "test", args: "--all --tests", @@ -213,7 +220,7 @@ jobs: - { target: x86_64-apple-darwin, os: macos-latest, - toolchain: "1.70.0", + toolchain: "1.75.0", cross: false, command: "test", args: "--all --tests", @@ -221,7 +228,7 @@ jobs: - { target: aarch64-apple-ios, os: macos-latest, - toolchain: "1.70.0", + toolchain: "1.75.0", cross: false, command: "build", args: "--package dioxus-mobile", @@ -229,7 +236,7 @@ jobs: - { target: aarch64-linux-android, os: ubuntu-latest, - toolchain: "1.70.0", + toolchain: "1.75.0", cross: true, command: "build", args: "--package dioxus-mobile", @@ -250,6 +257,14 @@ jobs: uses: taiki-e/install-action@cross + - name: Free Disk Space (Ubuntu) + if: ${{ matrix.platform.os == 'ubuntu-latest' }} + uses: jlumbroso/free-disk-space@v1.3.1 + with: # speed things up a bit + large-packages: false + docker-images: false + swap-storage: false + - uses: Swatinem/rust-cache@v2 with: key: "${{ matrix.platform.target }}" diff --git a/.gitignore b/.gitignore index da3dfceb6..9f61ad64e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ /target -/playwright-tests/web/dist -/playwright-tests/fullstack/dist +/packages/playwright-tests/web/dist +/packages/playwright-tests/fullstack/dist /dist .DS_Store /examples/assets/test_video.mp4 @@ -19,5 +19,5 @@ tarpaulin-report.html .idea/ node_modules/ /test-results/ -/playwright-report/ -/playwright/.cache/ +/packages/playwright-report/ +/packages/playwright/.cache/ diff --git a/Cargo.lock b/Cargo.lock index 2fa0eaccd..471818cf6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -154,9 +154,9 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" [[package]] name = "anstream" -version = "0.6.5" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d664a92ecae85fd0a7392615844904654d1d5f5514837f471ddef4a057aba1b6" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" dependencies = [ "anstyle", "anstyle-parse", @@ -168,9 +168,9 @@ dependencies = [ [[package]] name = "anstyle" -version = "1.0.4" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" [[package]] name = "anstyle-parse" @@ -324,17 +324,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-channel" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" -dependencies = [ - "concurrent-queue", - "event-listener 2.5.3", - "futures-core", -] - [[package]] name = "async-channel" version = "2.1.1" @@ -364,9 +353,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.5" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc2d0cfb2a7388d34f590e76686704c494ed7aaceed62ee1ba35cbf363abc2a5" +checksum = "a116f46a969224200a0a97f29cfd4c50e7534e4b4826bd23ea2c3c533039c82c" dependencies = [ "flate2", "futures-core", @@ -423,9 +412,9 @@ dependencies = [ [[package]] name = "async-io" -version = "2.2.2" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +checksum = "8f97ab0c5b00a7cdbe5a371b9a782ee7be1316095885c8a4ea1daf490eb0ef65" dependencies = [ "async-lock 3.3.0", "cfg-if", @@ -433,8 +422,8 @@ dependencies = [ "futures-io", "futures-lite 2.2.0", "parking", - "polling 3.3.1", - "rustix 0.38.28", + "polling 3.4.0", + "rustix 0.38.31", "slab", "tracing", "windows-sys 0.52.0", @@ -473,7 +462,7 @@ dependencies = [ "cfg-if", "event-listener 3.1.0", "futures-lite 1.13.0", - "rustix 0.38.28", + "rustix 0.38.31", "windows-sys 0.48.0", ] @@ -494,13 +483,13 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" dependencies = [ - "async-io 2.2.2", + "async-io 2.3.1", "async-lock 2.8.0", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.28", + "rustix 0.38.31", "signal-hook-registry", "slab", "windows-sys 0.48.0", @@ -792,9 +781,6 @@ version = "0.1.0" dependencies = [ "axum 0.6.20", "dioxus", - "dioxus-desktop", - "dioxus-fullstack", - "dioxus-router", "serde", "tokio", ] @@ -804,7 +790,6 @@ name = "axum-hello-world" version = "0.1.0" dependencies = [ "dioxus", - "dioxus-fullstack", "reqwest", "serde", "simple_logger", @@ -831,9 +816,6 @@ version = "0.1.0" dependencies = [ "axum 0.6.20", "dioxus", - "dioxus-fullstack", - "dioxus-router", - "dioxus-web", "serde", "tokio", ] @@ -925,22 +907,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - -[[package]] -name = "base64" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" -dependencies = [ - "byteorder", - "safemem", -] - [[package]] name = "base64" version = "0.13.1" @@ -1023,22 +989,13 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" dependencies = [ "serde", ] -[[package]] -name = "bitmaps" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "031043d04099746d8db04daf1fa424b2bc8bd69d92b25962dcde24da39ab64a2" -dependencies = [ - "typenum", -] - [[package]] name = "bitstream-io" version = "1.10.0" @@ -1084,7 +1041,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" dependencies = [ - "async-channel 2.1.1", + "async-channel", "async-lock 3.3.0", "async-task", "fastrand 2.0.1", @@ -1096,9 +1053,9 @@ dependencies = [ [[package]] name = "borsh" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d4d6dafc1a3bb54687538972158f07b2c948bc57d5890df22c0739098b3028" +checksum = "f58b559fd6448c6e2fd0adb5720cd98a2506594cafa4737ff98c396f3e82f667" dependencies = [ "borsh-derive", "cfg_aliases", @@ -1106,12 +1063,12 @@ dependencies = [ [[package]] name = "borsh-derive" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4918709cc4dd777ad2b6303ed03cb37f3ca0ccede8c1b0d28ac6db8f4710e0" +checksum = "7aadb5b6ccbd078890f6d7003694e33816e6b784358f18e15e7e6d9f065a57cd" dependencies = [ "once_cell", - "proc-macro-crate 2.0.0", + "proc-macro-crate 3.1.0", "proc-macro2", "quote", "syn 2.0.48", @@ -1155,7 +1112,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" dependencies = [ "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.5", "serde", ] @@ -1191,9 +1148,9 @@ checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" [[package]] name = "bytecheck" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6372023ac861f6e6dc89c8344a8f398fb42aaba2b5dbc649ca0c0e9dbcb627" +checksum = "23cdc57ce23ac53c931e88a43d06d070a6fd142f2617be5855eb75efc9beb1c2" dependencies = [ "bytecheck_derive", "ptr_meta", @@ -1202,9 +1159,9 @@ dependencies = [ [[package]] name = "bytecheck_derive" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ec4c6f261935ad534c0c22dbef2201b45918860eb1c574b972bd213a76af61" +checksum = "3db406d29fbcd95542e92559bed4d8ad92636d1ca8b3b72ede10b4bcc010e659" dependencies = [ "proc-macro2", "quote", @@ -1213,9 +1170,9 @@ dependencies = [ [[package]] name = "bytemuck" -version = "1.14.0" +version = "1.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "374d28ec25809ee0e23827c2ab573d729e293f281dfe393500e7ad618baa61c6" +checksum = "ea31d69bda4949c1c1562c1e6f042a1caefac98cdc8a298260a2ff41c1e2d42b" [[package]] name = "byteorder" @@ -1256,7 +1213,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ca26ef0159422fb77631dc9d17b102f253b876fe1586b03b803e63a309b4ee2" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cairo-sys-rs", "glib", "libc", @@ -1292,7 +1249,7 @@ checksum = "92c1b6f44358912a9538fa3b6ac8d3aa3f585444f9dc32f12ed85d1545a9df9f" dependencies = [ "anyhow", "auth-git2", - "clap 4.4.15", + "clap 4.4.18", "console", "dialoguer", "env_logger", @@ -1302,7 +1259,7 @@ dependencies = [ "heck 0.4.1", "home", "ignore", - "indexmap 2.1.0", + "indexmap 2.2.2", "indicatif", "liquid", "liquid-core", @@ -1320,7 +1277,7 @@ dependencies = [ "serde", "tempfile", "thiserror", - "toml 0.8.8", + "toml 0.8.10", "walkdir", ] @@ -1407,7 +1364,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3f9629bc6c4388ea699781dc988c2b99766d7679b151c81990b4fa1208fafd3" dependencies = [ "serde", - "toml 0.8.8", + "toml 0.8.10", ] [[package]] @@ -1417,7 +1374,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "802b755090e39835a4b0440fb0bbee0df7495a8b337f63db21e616f7821c7e8c" dependencies = [ "serde", - "toml 0.8.8", + "toml 0.8.10", ] [[package]] @@ -1492,9 +1449,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb" dependencies = [ "android-tzdata", "iana-time-zone", @@ -1502,14 +1459,14 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-targets 0.52.0", ] [[package]] name = "ciborium" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "effd91f6c78e5a4ace8a5d3c0b6bfaec9e2baaef55f3efc00e45fb2e477ee926" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" dependencies = [ "ciborium-io", "ciborium-ll", @@ -1518,18 +1475,18 @@ dependencies = [ [[package]] name = "ciborium-io" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdf919175532b369853f5d5e20b26b43112613fd6fe7aee757e35f7a44642656" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" [[package]] name = "ciborium-ll" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "defaa24ecc093c77630e6c15e17c51f5e187bf35ee514f4e2d67baaa96dae22b" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" dependencies = [ "ciborium-io", - "half 1.8.2", + "half 2.3.1", ] [[package]] @@ -1555,9 +1512,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.4.15" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c12ed66a79a555082f595f7eb980d08669de95009dd4b3d61168c573ebe38fc9" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" dependencies = [ "clap_builder", "clap_derive", @@ -1565,9 +1522,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.4.15" +version = "4.4.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f4645eab3431e5a8403a96bea02506a8b35d28cd0f0330977dd5d22f9c84f43" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" dependencies = [ "anstream", "anstyle", @@ -1593,12 +1550,6 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" -[[package]] -name = "closure" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6173fd61b610d15a7566dd7b7620775627441c4ab9dac8906e17cb93a24b782" - [[package]] name = "cocoa" version = "0.25.0" @@ -1943,7 +1894,7 @@ dependencies = [ "anes", "cast", "ciborium", - "clap 4.4.15", + "clap 4.4.18", "criterion-plot 0.5.0", "futures", "is-terminal", @@ -2047,7 +1998,7 @@ version = "0.27.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f476fe445d41c9e991fd07515a6f463074b782242ccf4a5b7b1d1012e70824df" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "crossterm_winapi", "libc", "mio", @@ -2082,18 +2033,6 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array 0.14.7", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -2122,23 +2061,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "cssparser" -version = "0.29.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f93d03419cb5950ccfd3daf3ff1c7a36ace64609a1a8746d493df1ca0afde0fa" -dependencies = [ - "cssparser-macros", - "dtoa-short", - "itoa 1.0.10", - "matches", - "phf 0.10.1", - "proc-macro2", - "quote", - "smallvec", - "syn 1.0.109", -] - [[package]] name = "cssparser" version = "0.33.0" @@ -2221,34 +2143,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "curve25519-dalek" -version = "4.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" -dependencies = [ - "cfg-if", - "cpufeatures", - "curve25519-dalek-derive", - "digest", - "fiat-crypto", - "platforms", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "cvt" version = "0.1.2" @@ -2260,9 +2154,9 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "fc5d6b04b3fd0ba9926f945895de7d806260a2d7431ba82e7edaecb043c4c6b8" dependencies = [ "darling_core", "darling_macro", @@ -2270,9 +2164,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "04e48a959bcd5c761246f5d090ebc2fbf7b9cd527a492b07a67510c108f1e7e3" dependencies = [ "fnv", "ident_case", @@ -2284,9 +2178,9 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "1d1545d67a2149e1d93b7e5c7752dce5a7426eb5d1357ddcfd89336b94444f77" dependencies = [ "darling_core", "quote", @@ -2392,7 +2286,7 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "proc-macro2", "proc-macro2-diagnostics", "quote", @@ -2435,15 +2329,25 @@ name = "dioxus" version = "0.4.3" dependencies = [ "criterion 0.3.6", + "dioxus-config-macro", "dioxus-core", "dioxus-core-macro", + "dioxus-desktop", + "dioxus-fullstack", "dioxus-hooks", "dioxus-hot-reload", "dioxus-html", - "dioxus-rsx", + "dioxus-liveview", + "dioxus-mobile", + "dioxus-router", + "dioxus-signals", + "dioxus-ssr", + "dioxus-tui", + "dioxus-web", "env_logger", "futures-util", "rand 0.8.5", + "serde", "thiserror", "tokio", "tracing", @@ -2486,7 +2390,7 @@ dependencies = [ "cargo_metadata 0.18.1", "cargo_toml 0.18.0", "chrono", - "clap 4.4.15", + "clap 4.4.18", "colored 2.1.0", "ctrlc", "dioxus-autofmt", @@ -2525,8 +2429,8 @@ dependencies = [ "tempfile", "thiserror", "tokio", - "toml 0.8.8", - "toml_edit 0.21.0", + "toml 0.8.10", + "toml_edit 0.21.1", "tower", "tower-http 0.2.5", "walkdir", @@ -2539,7 +2443,7 @@ name = "dioxus-cli-config" version = "0.4.1" dependencies = [ "cargo_toml 0.16.3", - "clap 4.4.15", + "clap 4.4.18", "once_cell", "serde", "serde_json", @@ -2549,13 +2453,19 @@ dependencies = [ "tracing", ] +[[package]] +name = "dioxus-config-macro" +version = "0.4.3" +dependencies = [ + "proc-macro2", + "quote", +] + [[package]] name = "dioxus-core" version = "0.4.3" dependencies = [ - "bumpalo", "dioxus", - "dioxus-html", "dioxus-ssr", "futures-channel", "futures-util", @@ -2565,10 +2475,8 @@ dependencies = [ "rustc-hash", "serde", "slab", - "smallbox", "tokio", "tracing", - "trybuild", ] [[package]] @@ -2578,7 +2486,6 @@ dependencies = [ "constcat", "convert_case 0.6.0", "dioxus", - "dioxus-core", "dioxus-rsx", "prettyplease", "proc-macro2", @@ -2604,7 +2511,6 @@ dependencies = [ "dioxus", "dioxus-cli-config", "dioxus-core", - "dioxus-core-macro", "dioxus-hooks", "dioxus-hot-reload", "dioxus-html", @@ -2613,15 +2519,14 @@ dependencies = [ "exitcode", "futures-channel", "futures-util", + "generational-box", "global-hotkey", "infer 0.11.0", - "minify-js", "muda", "objc", "objc_id", "rfd", "rustc-hash", - "scraper", "serde", "serde_json", "slab", @@ -2638,29 +2543,19 @@ dependencies = [ name = "dioxus-examples" version = "0.4.3" dependencies = [ - "anyhow", "dioxus", - "dioxus-desktop", - "dioxus-router", - "dioxus-signals", "dioxus-ssr", - "env_logger", - "fermi", + "form_urlencoded", "futures-util", + "getrandom 0.2.12", "http-range", - "im-rc", - "log", "manganis", - "num-format", "rand 0.8.5", "reqwest", "separator", "serde", "serde_json", - "simple_logger", - "thiserror", "tokio", - "tracing-subscriber", ] [[package]] @@ -2683,10 +2578,11 @@ dependencies = [ "base64 0.21.7", "bytes", "ciborium", - "dioxus", + "dioxus-cli-config", "dioxus-desktop", "dioxus-hot-reload", - "dioxus-router", + "dioxus-lib", + "dioxus-mobile", "dioxus-ssr", "dioxus-web", "dioxus_server_macro", @@ -2720,6 +2616,7 @@ dependencies = [ "dioxus", "dioxus-core", "dioxus-debug-cell", + "dioxus-signals", "futures-channel", "futures-util", "slab", @@ -2749,13 +2646,14 @@ dependencies = [ name = "dioxus-html" version = "0.4.3" dependencies = [ - "async-channel 1.9.0", "async-trait", "dioxus-core", "dioxus-html-internal-macro", "dioxus-rsx", "enumset", "euclid", + "futures-channel", + "generational-box", "keyboard-types", "rfd", "serde", @@ -2782,6 +2680,8 @@ dependencies = [ name = "dioxus-interpreter-js" version = "0.4.3" dependencies = [ + "dioxus-core", + "dioxus-html", "js-sys", "serde", "sledgehammer_bindgen", @@ -2790,6 +2690,19 @@ dependencies = [ "web-sys", ] +[[package]] +name = "dioxus-lib" +version = "0.4.3" +dependencies = [ + "dioxus-config-macro", + "dioxus-core", + "dioxus-core-macro", + "dioxus-hooks", + "dioxus-html", + "dioxus-rsx", + "dioxus-signals", +] + [[package]] name = "dioxus-liveview" version = "0.4.3" @@ -2797,12 +2710,14 @@ dependencies = [ "async-trait", "axum 0.6.20", "dioxus", + "dioxus-cli-config", "dioxus-core", "dioxus-hot-reload", "dioxus-html", "dioxus-interpreter-js", "futures-channel", "futures-util", + "generational-box", "minify-js", "once_cell", "pretty_env_logger", @@ -2822,16 +2737,6 @@ dependencies = [ "warp", ] -[[package]] -name = "dioxus-logger" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d7cbab0b5519060fe9e14b3c21e3f2329b8386cd905618f78c7b929cd00cf54" -dependencies = [ - "log", - "web-sys", -] - [[package]] name = "dioxus-mobile" version = "0.4.3" @@ -2877,13 +2782,8 @@ dependencies = [ name = "dioxus-playwright-fullstack-test" version = "0.1.0" dependencies = [ - "axum 0.6.20", "dioxus", - "dioxus-fullstack", - "dioxus-web", - "execute", "serde", - "tokio", ] [[package]] @@ -2901,9 +2801,9 @@ name = "dioxus-playwright-web-test" version = "0.0.1" dependencies = [ "dioxus", - "dioxus-html", - "dioxus-web", "serde_json", + "tracing", + "tracing-wasm", ] [[package]] @@ -2926,14 +2826,14 @@ dependencies = [ "criterion 0.5.1", "dioxus", "dioxus-cli-config", - "dioxus-desktop", + "dioxus-fullstack", + "dioxus-lib", "dioxus-liveview", "dioxus-router", "dioxus-router-macro", "dioxus-ssr", - "dioxus-web", "gloo", - "gloo-utils 0.1.7", + "gloo-utils", "js-sys", "serde", "serde_json", @@ -2943,7 +2843,6 @@ dependencies = [ "urlencoding", "wasm-bindgen", "wasm-bindgen-test", - "wasm-logger", "web-sys", ] @@ -2977,12 +2876,18 @@ version = "0.4.3" dependencies = [ "dioxus", "dioxus-core", - "dioxus-desktop", + "flume", + "futures-channel", + "futures-util", "generational-box", + "once_cell", + "parking_lot", + "rustc-hash", "serde", "simple_logger", "tokio", "tracing", + "tracing-subscriber", ] [[package]] @@ -2996,8 +2901,10 @@ dependencies = [ "dioxus", "dioxus-core", "dioxus-html", + "dioxus-signals", "fern", "fs_extra", + "generational-box", "http 0.2.11", "lru 0.10.1", "rustc-hash", @@ -3013,8 +2920,6 @@ name = "dioxus-tailwind" version = "0.0.0" dependencies = [ "dioxus", - "dioxus-desktop", - "dioxus-web", "manganis", ] @@ -3040,7 +2945,6 @@ dependencies = [ name = "dioxus-web" version = "0.4.3" dependencies = [ - "async-channel 1.9.0", "async-trait", "console_error_panic_hook", "dioxus", @@ -3051,6 +2955,7 @@ dependencies = [ "dioxus-web", "futures-channel", "futures-util", + "generational-box", "gloo-dialogs", "gloo-timers", "js-sys", @@ -3063,7 +2968,6 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "wasm-bindgen-test", - "wasm-logger", "web-sys", ] @@ -3165,56 +3069,6 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" -[[package]] -name = "dyn-clone" -version = "1.0.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" - -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest", - "elliptic-curve", - "rfc6979", - "signature", - "spki", -] - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8", - "signature", -] - -[[package]] -name = "ed25519-dalek" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0" -dependencies = [ - "curve25519-dalek", - "ed25519", - "serde", - "sha2", - "subtle", - "zeroize", -] - -[[package]] -name = "ego-tree" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a68a4904193147e0a8dec3314640e6db742afd5f6e634f428a6af230d9b3591" - [[package]] name = "either" version = "1.9.0" @@ -3224,27 +3078,6 @@ dependencies = [ "serde", ] -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest", - "ff", - "generic-array 0.14.7", - "group", - "hkdf", - "pem-rfc7468", - "pkcs8", - "rand_core 0.6.4", - "sec1", - "subtle", - "zeroize", -] - [[package]] name = "encode_unicode" version = "0.3.6" @@ -3316,9 +3149,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.10.1" +version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "4cd405aab171cb85d6735e5c8d9db038c17d3ca007a4d2c25f337935c3d90580" dependencies = [ "humantime", "is-terminal", @@ -3457,13 +3290,13 @@ checksum = "de853764b47027c2e862a995c34978ffa63c1501f2e15f987ba11bd4f9bba193" [[package]] name = "exr" -version = "1.71.0" +version = "1.72.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "832a761f35ab3e6664babfbdc6cef35a4860e816ec3916dcfd0882954e98a8a8" +checksum = "887d93f60543e9a9362ef8a21beedd0a833c5d9610e18c67abe15a5963dcb1a4" dependencies = [ "bit_field", "flume", - "half 2.2.1", + "half 2.3.1", "lebe", "miniz_oxide", "rayon-core", @@ -3503,23 +3336,13 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" [[package]] name = "fdeflate" -version = "0.3.3" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "209098dd6dfc4445aa6111f0e98653ac323eaa4dfd212c9ca3931bf9955c31bd" +checksum = "4f9bfee30e4dedf0ab8b422f03af778d9612b63f502710fc500a334ebe2de645" dependencies = [ "simd-adler32", ] -[[package]] -name = "fermi" -version = "0.4.3" -dependencies = [ - "closure", - "dioxus-core", - "im-rc", - "tracing", -] - [[package]] name = "fern" version = "0.6.2" @@ -3530,22 +3353,6 @@ dependencies = [ "log", ] -[[package]] -name = "ff" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "fiat-crypto" -version = "0.2.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" - [[package]] name = "field-offset" version = "0.3.6" @@ -3558,14 +3365,14 @@ dependencies = [ [[package]] name = "figment" -version = "0.10.13" +version = "0.10.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7629b8c7bcd214a072c2c88b263b5bb3ceb54c34365d8c41c1665461aeae0993" +checksum = "2b6e5bc7bd59d60d0d45a6ccab6cf0f4ce28698fb4e81e750ddf229c9b824026" dependencies = [ "atomic 0.6.0", "pear", "serde", - "toml 0.8.8", + "toml 0.8.10", "uncased", "version_check", ] @@ -3966,7 +3773,8 @@ dependencies = [ name = "generational-box" version = "0.4.3" dependencies = [ - "bumpalo", + "criterion 0.3.6", + "parking_lot", "rand 0.8.5", ] @@ -3991,7 +3799,6 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", - "zeroize", ] [[package]] @@ -4003,15 +3810,6 @@ dependencies = [ "typenum", ] -[[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" @@ -4107,11 +3905,11 @@ dependencies = [ [[package]] name = "git2" -version = "0.18.1" +version = "0.18.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbf97ba92db08df386e10c8ede66a2a0369bd277090afd8710e19e38de9ec0cd" +checksum = "1b3ba52851e73b46a4c3df1d89343741112003f0f6f13beb0dfac9e457c3fdcd" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libc", "libgit2-sys", "log", @@ -4157,11 +3955,11 @@ dependencies = [ [[package]] name = "gix-config-value" -version = "0.14.3" +version = "0.14.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e0be46f4cf1f8f9e88d0e3eb7b29718aff23889563249f379119bd1ab6910e" +checksum = "5b8a1e7bfb37a46ed0b8468db37a6d8a0a61d56bdbe4603ae492cb322e5f3958" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "bstr 1.9.0", "gix-path", "libc", @@ -4209,7 +4007,7 @@ version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5db19298c5eeea2961e5b3bf190767a2d1f09b8802aeb5f258e42276350aff19" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "bstr 1.9.0", "gix-features", "gix-path", @@ -4257,9 +4055,9 @@ dependencies = [ [[package]] name = "gix-path" -version = "0.10.3" +version = "0.10.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8dd0998ab245f33d40ca2267e58d542fe54185ebd1dc41923346cf28d179fb6" +checksum = "97e9ad649bf5e109562d6acba657ca428661ec08e77eaf3a755d8fa55485be9c" dependencies = [ "bstr 1.9.0", "gix-trace", @@ -4291,14 +4089,14 @@ dependencies = [ [[package]] name = "gix-sec" -version = "0.10.3" +version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f6dce0c6683e2219e8169aac4b1c29e89540a8262fef7056b31d80d969408c" +checksum = "f8d9bf462feaf05f2121cba7399dbc6c34d88a9cad58fc1e95027791d6a3c6d2" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "gix-path", "libc", - "windows 0.52.0", + "windows-sys 0.52.0", ] [[package]] @@ -4316,17 +4114,18 @@ dependencies = [ [[package]] name = "gix-trace" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8e1127ede0475b58f4fe9c0aaa0d9bb0bad2af90bbd93ccd307c8632b863d89" +checksum = "02b202d766a7fefc596e2cc6a89cda8ad8ad733aed82da635ac120691112a9b1" [[package]] name = "gix-utils" -version = "0.1.8" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de6225e2de30b6e9bca2d9f1cc4731640fcef0fb3cabddceee366e7e85d3e94f" +checksum = "56e839f3d0798b296411263da6bee780a176ef8008a5dfc31287f7eda9266ab8" dependencies = [ "fastrand 2.0.1", + "unicode-normalization", ] [[package]] @@ -4345,7 +4144,7 @@ version = "0.18.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "233daaf6e83ae6a12a52055f568f9d7cf4671dabb78ff9560ab6da230ce00ee5" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "futures-channel", "futures-core", "futures-executor", @@ -4394,9 +4193,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "global-hotkey" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d505f007b733fc3b3261ca0710e7e689411422ace5f5b2a63a14d8596159db23" +checksum = "927a00fd7c31d82029f99ce2481a8de1ae974758017d6a55ebbe7f22edcd1617" dependencies = [ "crossbeam-channel", "keyboard-types", @@ -4415,7 +4214,7 @@ dependencies = [ "aho-corasick 1.1.2", "bstr 1.9.0", "log", - "regex-automata 0.4.3", + "regex-automata 0.4.5", "regex-syntax 0.8.2", ] @@ -4432,9 +4231,9 @@ dependencies = [ "gloo-history", "gloo-net 0.3.1", "gloo-render", - "gloo-storage 0.2.2", + "gloo-storage", "gloo-timers", - "gloo-utils 0.1.7", + "gloo-utils", "gloo-worker", ] @@ -4444,7 +4243,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82b7ce3c05debe147233596904981848862b068862e9ec3e34be446077190d3f" dependencies = [ - "gloo-utils 0.1.7", + "gloo-utils", "js-sys", "serde", "wasm-bindgen", @@ -4490,7 +4289,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85725d90bf0ed47063b3930ef28e863658a7905989e9929a8708aab74a1d5e7f" dependencies = [ "gloo-events", - "gloo-utils 0.1.7", + "gloo-utils", "serde", "serde-wasm-bindgen", "serde_urlencoded", @@ -4508,7 +4307,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-sink", - "gloo-utils 0.1.7", + "gloo-utils", "js-sys", "pin-project", "serde", @@ -4528,7 +4327,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-sink", - "gloo-utils 0.1.7", + "gloo-utils", "http 0.2.11", "js-sys", "pin-project", @@ -4556,22 +4355,7 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5d6ab60bf5dbfd6f0ed1f7843da31b41010515c745735c970e821945ca91e480" dependencies = [ - "gloo-utils 0.1.7", - "js-sys", - "serde", - "serde_json", - "thiserror", - "wasm-bindgen", - "web-sys", -] - -[[package]] -name = "gloo-storage" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc8031e8c92758af912f9bc08fbbadd3c6f3cfcbf6b64cdf3d6a81f0139277a" -dependencies = [ - "gloo-utils 0.2.0", + "gloo-utils", "js-sys", "serde", "serde_json", @@ -4603,19 +4387,6 @@ dependencies = [ "web-sys", ] -[[package]] -name = "gloo-utils" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b5555354113b18c547c1d3a98fbf7fb32a9ff4f6fa112ce823a21641a0ba3aa" -dependencies = [ - "js-sys", - "serde", - "serde_json", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "gloo-worker" version = "0.2.1" @@ -4625,7 +4396,7 @@ dependencies = [ "anymap2", "bincode", "gloo-console", - "gloo-utils 0.1.7", + "gloo-utils", "js-sys", "serde", "wasm-bindgen", @@ -4650,17 +4421,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eec1c01eb1de97451ee0d60de7d81cf1e72aabefb021616027f3d1c3ec1c723c" -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "gtk" version = "0.18.1" @@ -4725,7 +4485,7 @@ dependencies = [ "futures-sink", "futures-util", "http 0.2.11", - "indexmap 2.1.0", + "indexmap 2.2.2", "slab", "tokio", "tokio-util", @@ -4734,9 +4494,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "991910e35c615d8cab86b5ab04be67e6ad24d2bf5f4f11fdbbed26da999bbeab" +checksum = "31d030e59af851932b72ceebadf4a2b5986dba4c3b99dd2493f8273a0f151943" dependencies = [ "bytes", "fnv", @@ -4744,7 +4504,7 @@ dependencies = [ "futures-sink", "futures-util", "http 1.0.0", - "indexmap 2.1.0", + "indexmap 2.2.2", "slab", "tokio", "tokio-util", @@ -4759,10 +4519,11 @@ checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7" [[package]] name = "half" -version = "2.2.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b4af3693f1b705df946e9fe5631932443781d0aabb423b62fcd4d73f6d2fd0" +checksum = "bc52e53916c08643f1b56ec082790d1e86a32e58dc5268f897f313fbae7b4872" dependencies = [ + "cfg-if", "crunchy", ] @@ -4895,9 +4656,9 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.3.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" [[package]] name = "hex" @@ -5091,7 +4852,7 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.1", + "h2 0.4.2", "http 1.0.0", "http-body 1.0.0", "httparse", @@ -5146,12 +4907,11 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bdea9aac0dbe5a9240d68cfd9501e2db94222c6dc06843e06640b9e07f0fdc67" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ "bytes", - "futures-channel", "futures-util", "http 1.0.0", "http-body 1.0.0", @@ -5159,14 +4919,13 @@ dependencies = [ "pin-project-lite", "socket2 0.5.5", "tokio", - "tracing", ] [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -5227,32 +4986,17 @@ dependencies = [ "globset", "log", "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.5", "same-file", "walkdir", "winapi-util", ] -[[package]] -name = "im-rc" -version = "15.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "af1955a75fa080c677d3972822ec4bad316169ab1cfc6c257a942c2265dbe5fe" -dependencies = [ - "bitmaps", - "rand_core 0.6.4", - "rand_xoshiro", - "serde", - "sized-chunks", - "typenum", - "version_check", -] - [[package]] name = "image" -version = "0.24.7" +version = "0.24.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f3dfdbdd72063086ff443e297b61695500514b1e41095b6fb9a5ab48a70a711" +checksum = "034bbe799d1909622a74d1193aa50147769440040ff36cb2baa947609b0a4e23" dependencies = [ "bytemuck", "byteorder", @@ -5260,7 +5004,6 @@ dependencies = [ "exr", "gif", "jpeg-decoder", - "num-rational", "num-traits", "png", "qoi", @@ -5272,9 +5015,9 @@ dependencies = [ [[package]] name = "imagequant" -version = "4.2.2" +version = "4.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84d51957ac48371e8e2eaaeb4eba56150ff2109c1c8c200002afb7dd6e2d260f" +checksum = "85a7f142d232ccbdc00cbef49d17f45639aeb07d9bfe28e17c21dea3efac64e5" dependencies = [ "arrayvec", "once_cell", @@ -5285,9 +5028,9 @@ dependencies = [ [[package]] name = "imgref" -version = "1.10.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90d944e334f00f4449c9640b440a171f816be0152305c12ef90424fc35fd035c" +checksum = "44feda355f4159a7c757171a77de25daf6411e217b4cabd03bd6650690468126" [[package]] name = "indexmap" @@ -5302,9 +5045,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.1.0" +version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" dependencies = [ "equivalent", "hashbrown 0.14.3", @@ -5441,9 +5184,9 @@ checksum = "ae52f28f45ac2bc96edb7714de995cffc174a395fb0abf5bff453587c980d7b9" [[package]] name = "inventory" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8573b2b1fb643a372c73b23f4da5f888677feef3305146d68a539250a9bccc7" +checksum = "f958d3d68f4167080a18141e10381e7634563984a537f2a49a30fd8e53ac5767" [[package]] name = "io-lifetimes" @@ -5451,7 +5194,7 @@ version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.5", "libc", "windows-sys 0.48.0", ] @@ -5507,8 +5250,8 @@ version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" dependencies = [ - "hermit-abi 0.3.3", - "rustix 0.38.28", + "hermit-abi 0.3.5", + "rustix 0.38.31", "windows-sys 0.52.0", ] @@ -5524,9 +5267,9 @@ dependencies = [ [[package]] name = "is_ci" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616cde7c720bb2bb5824a224687d8f77bfd38922027f01d825cd7453be5099fb" +checksum = "7655c9839580ee829dfacba1d1278c2b7883e50a277ff7541299489d6bdfdc45" [[package]] name = "itertools" @@ -5548,9 +5291,9 @@ dependencies = [ [[package]] name = "itertools" -version = "0.12.0" +version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" dependencies = [ "either", ] @@ -5623,18 +5366,18 @@ dependencies = [ [[package]] name = "jpeg-decoder" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0000e42512c92e31c2252315bda326620a4e034105e900c98ec492fa077b3e" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" dependencies = [ "rayon", ] [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" dependencies = [ "wasm-bindgen", ] @@ -5657,7 +5400,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b750dcadc39a09dbadd74e118f6dd6598df77fa01df0cfcdc52c28dece74528a" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "serde", "unicode-segmentation", ] @@ -5714,7 +5457,7 @@ dependencies = [ "html5ever", "indexmap 1.9.3", "matches", - "selectors 0.22.0", + "selectors", ] [[package]] @@ -5740,9 +5483,9 @@ checksum = "03087c2bad5e1034e8cace5926dec053fb3790248370865f5117a7d0213354c8" [[package]] name = "libc" -version = "0.2.152" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libflate" @@ -5787,9 +5530,9 @@ dependencies = [ [[package]] name = "libgit2-sys" -version = "0.16.1+1.7.1" +version = "0.16.2+1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2a2bb3680b094add03bb3732ec520ece34da31a8cd2d633d1389d0f0fb60d0c" +checksum = "ee4126d8b4ee5c9d9ea891dd875cfdc1e9d0950437179104b183d7d8a74d24e8" dependencies = [ "cc", "libc", @@ -5811,7 +5554,7 @@ version = "0.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "libc", "redox_syscall", ] @@ -5872,9 +5615,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.14" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "295c17e837573c8c821dbaeb3cceb3d745ad082f7572191409e69cbc1b3fd050" +checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" dependencies = [ "cc", "libc", @@ -5884,12 +5627,12 @@ dependencies = [ [[package]] name = "lightningcss" -version = "1.0.0-alpha.51" +version = "1.0.0-alpha.52" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d6ad516c08b24c246b339159dc2ee2144c012e8ebdf4db4bddefb8734b2b69" +checksum = "771a62dedf5ec563bbfea9760f6c6a6bc546e67355eba0cd7d00c0dc34b11d90" dependencies = [ "ahash 0.7.7", - "bitflags 2.4.1", + "bitflags 2.4.2", "const-str", "cssparser 0.33.0", "cssparser-color", @@ -5935,9 +5678,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.12" +version = "0.4.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" [[package]] name = "liquid" @@ -6038,9 +5781,9 @@ dependencies = [ [[package]] name = "loop9" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81a837f917de41d61ab531ba255d1913208d02325cab0d6a66a706e0dbaa699d" +checksum = "0fae87c125b03c1d2c0150c90365d7d6bcc53fb73a9acaef207d2d065860f062" dependencies = [ "imgref", ] @@ -6065,9 +5808,9 @@ dependencies = [ [[package]] name = "lru" -version = "0.12.1" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2994eeba8ed550fd9b47a0b38f0242bc3344e496483c6180b69139cc2fa5d1d7" +checksum = "db2c024b41519440580066ba82aab04092b333e09066a5eb86c7c4890df31f22" dependencies = [ "hashbrown 0.14.3", ] @@ -6128,7 +5871,7 @@ dependencies = [ [[package]] name = "manganis" version = "0.1.0" -source = "git+https://github.com/DioxusLabs/collect-assets?rev=e0093a4#e0093a47f0fa3bb50c49cd21aee5aa674faa24ad" +source = "git+https://github.com/DioxusLabs/collect-assets?rev=f982698#f982698027fc27d22acfb4121fba389ec125d538" dependencies = [ "manganis-macro", ] @@ -6136,7 +5879,7 @@ dependencies = [ [[package]] name = "manganis-cli-support" version = "0.1.0" -source = "git+https://github.com/DioxusLabs/collect-assets?rev=e0093a4#e0093a47f0fa3bb50c49cd21aee5aa674faa24ad" +source = "git+https://github.com/DioxusLabs/collect-assets?rev=f982698#f982698027fc27d22acfb4121fba389ec125d538" dependencies = [ "anyhow", "cargo-lock 9.0.0", @@ -6162,7 +5905,7 @@ dependencies = [ [[package]] name = "manganis-common" version = "0.1.0" -source = "git+https://github.com/DioxusLabs/collect-assets?rev=e0093a4#e0093a47f0fa3bb50c49cd21aee5aa674faa24ad" +source = "git+https://github.com/DioxusLabs/collect-assets?rev=f982698#f982698027fc27d22acfb4121fba389ec125d538" dependencies = [ "anyhow", "base64 0.21.7", @@ -6177,7 +5920,7 @@ dependencies = [ [[package]] name = "manganis-macro" version = "0.0.1" -source = "git+https://github.com/DioxusLabs/collect-assets?rev=e0093a4#e0093a47f0fa3bb50c49cd21aee5aa674faa24ad" +source = "git+https://github.com/DioxusLabs/collect-assets?rev=f982698#f982698027fc27d22acfb4121fba389ec125d538" dependencies = [ "base64 0.21.7", "manganis-cli-support", @@ -6346,9 +6089,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" dependencies = [ "adler", "simd-adler32", @@ -6427,9 +6170,9 @@ dependencies = [ [[package]] name = "muda" -version = "0.11.3" +version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "884427679a3ef726cd4a0ad6eec2ca618737ba11ebe8c9320dc305c09c78c8fc" +checksum = "e406691fa7749604bbc7964bde28a300572d52621bb84540f6907c0f8fe08737" dependencies = [ "cocoa", "crossbeam-channel", @@ -6592,7 +6335,7 @@ version = "0.27.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if", "libc", ] @@ -6685,6 +6428,12 @@ dependencies = [ "zeroize", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-derive" version = "0.3.3" @@ -6698,25 +6447,15 @@ dependencies = [ [[package]] name = "num-derive" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", "syn 2.0.48", ] -[[package]] -name = "num-format" -version = "0.4.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a652d9771a63711fd3c3deb670acfbe5c30a4072e664d7a3bf5a9e1056ac72c3" -dependencies = [ - "arrayvec", - "itoa 1.0.10", -] - [[package]] name = "num-integer" version = "0.1.45" @@ -6766,7 +6505,7 @@ version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" dependencies = [ - "hermit-abi 0.3.3", + "hermit-abi 0.3.5", "libc", ] @@ -6806,26 +6545,6 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" -[[package]] -name = "oauth2" -version = "4.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c38841cdd844847e3e7c8d29cef9dcfed8877f8f56f9071f77843ecf3baf937f" -dependencies = [ - "base64 0.13.1", - "chrono", - "getrandom 0.2.12", - "http 0.2.11", - "rand 0.8.5", - "reqwest", - "serde", - "serde_json", - "serde_path_to_error", - "sha2", - "thiserror", - "url", -] - [[package]] name = "objc" version = "0.2.7" @@ -6903,67 +6622,13 @@ dependencies = [ "pathdiff", ] -[[package]] -name = "openid_auth_demo" -version = "0.1.0" -dependencies = [ - "console_error_panic_hook", - "dioxus", - "dioxus-logger", - "dioxus-router", - "dioxus-web", - "fermi", - "form_urlencoded", - "gloo-storage 0.3.0", - "log", - "openidconnect", - "reqwest", - "serde", - "serde_json", - "thiserror", - "uuid", - "web-sys", -] - -[[package]] -name = "openidconnect" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62d6050f6a84b81f23c569f5607ad883293e57491036e318fafe6fc4895fadb1" -dependencies = [ - "base64 0.13.1", - "chrono", - "dyn-clone", - "ed25519-dalek", - "hmac", - "http 0.2.11", - "itertools 0.10.5", - "log", - "oauth2", - "p256", - "p384", - "rand 0.8.5", - "rsa", - "serde", - "serde-value", - "serde_derive", - "serde_json", - "serde_path_to_error", - "serde_plain", - "serde_with", - "sha2", - "subtle", - "thiserror", - "url", -] - [[package]] name = "openssl" -version = "0.10.62" +version = "0.10.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cfg-if", "foreign-types 0.3.2", "libc", @@ -6991,18 +6656,18 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.2.1+3.2.0" +version = "300.2.2+3.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fe476c29791a5ca0d1273c697e96085bbabbbea2ef7afd5617e78a4b40332d3" +checksum = "8bbfad0063610ac26ee79f7484739e2b07555a75c42453b89263830b5c8103bc" dependencies = [ "cc", ] [[package]] name = "openssl-sys" -version = "0.9.98" +version = "0.9.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" dependencies = [ "cc", "libc", @@ -7067,30 +6732,6 @@ dependencies = [ "supports-color", ] -[[package]] -name = "p256" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2", -] - -[[package]] -name = "p384" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70786f51bcc69f6a4c0360e063a4cac5419ef7c5cd5b3c99ad70f3be5ba79209" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2", -] - [[package]] name = "pango" version = "0.18.3" @@ -7122,7 +6763,7 @@ version = "0.26.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05d74befe2d076330d9a58bf9ca2da424568724ab278adf15fb5718253133887" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cssparser 0.33.0", "fxhash", "log", @@ -7287,9 +6928,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pest" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" dependencies = [ "memchr", "thiserror", @@ -7298,9 +6939,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" dependencies = [ "pest", "pest_generator", @@ -7308,9 +6949,9 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" dependencies = [ "pest", "pest_meta", @@ -7321,9 +6962,9 @@ dependencies = [ [[package]] name = "pest_meta" -version = "2.7.6" +version = "2.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" dependencies = [ "once_cell", "pest", @@ -7337,7 +6978,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9" dependencies = [ "fixedbitset", - "indexmap 2.1.0", + "indexmap 2.2.2", ] [[package]] @@ -7357,9 +6998,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ - "phf_macros 0.10.0", "phf_shared 0.10.0", - "proc-macro-hack", ] [[package]] @@ -7436,20 +7075,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "phf_macros" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "phf_macros" version = "0.11.2" @@ -7492,18 +7117,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.3" +version = "1.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" dependencies = [ "proc-macro2", "quote", @@ -7556,9 +7181,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" [[package]] name = "plasmo" @@ -7582,12 +7207,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "platforms" -version = "3.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" - [[package]] name = "plist" version = "1.6.0" @@ -7595,7 +7214,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5699cc8a63d1aa2b1ee8e12b9ad70ac790d65788cd36101fa37f87ea46c4cef" dependencies = [ "base64 0.21.7", - "indexmap 2.1.0", + "indexmap 2.2.2", "line-wrap", "quick-xml", "serde", @@ -7632,9 +7251,9 @@ dependencies = [ [[package]] name = "png" -version = "0.17.10" +version = "0.17.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd75bf2d8dd3702b9707cdbc56a5b9ef42cec752eb8b3bafc01234558442aa64" +checksum = "1f6c3c3e617595665b8ea2ff95a86066be38fb121ff920a9c0eb282abcd1da5a" dependencies = [ "bitflags 1.3.2", "crc32fast", @@ -7661,14 +7280,14 @@ dependencies = [ [[package]] name = "polling" -version = "3.3.1" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" +checksum = "30054e72317ab98eddd8561db0f6524df3367636884b7b21b703e4b280a84a14" dependencies = [ "cfg-if", "concurrent-queue", "pin-project-lite", - "rustix 0.38.28", + "rustix 0.38.31", "tracing", "windows-sys 0.52.0", ] @@ -7749,15 +7368,6 @@ dependencies = [ "syn 2.0.48", ] -[[package]] -name = "primeorder" -version = "0.13.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" -dependencies = [ - "elliptic-curve", -] - [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -7774,7 +7384,16 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" dependencies = [ - "toml_edit 0.20.2", + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +dependencies = [ + "toml_edit 0.21.1", ] [[package]] @@ -7809,9 +7428,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -7837,18 +7456,18 @@ checksum = "794b5bf8e2d19b53dcdcec3e4bba628e20f5b6062503ba89281fa7037dd7bbcf" [[package]] name = "profiling" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d135ede8821cf6376eb7a64148901e1690b788c11ae94dc297ae917dbc91dc0e" +checksum = "0f0f7f43585c34e4fdd7497d746bc32e14458cf11c69341cc0587b1d825dde42" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.13" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b322d7d65c1ab449be3c890fcbd0db6e1092d0dd05d79dba2dd28032cebeb05" +checksum = "ce97fecd27bc49296e5e20518b5a1bb54a14f7d5fe6228bc9686ee2a74915cc8" dependencies = [ "quote", "syn 2.0.48", @@ -7883,16 +7502,6 @@ dependencies = [ "bytemuck", ] -[[package]] -name = "query_segments_demo" -version = "0.1.0" -dependencies = [ - "dioxus", - "dioxus-router", - "dioxus-web", - "form_urlencoded", -] - [[package]] name = "quick-error" version = "1.2.3" @@ -8026,27 +7635,18 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "rand_xoshiro" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f97cdb2a36ed4183de61b2f824cc45c9f1037f28afe0a322e9fff4c108b5aaa" -dependencies = [ - "rand_core 0.6.4", -] - [[package]] name = "ratatui" version = "0.24.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ebc917cfb527a566c37ecb94c7e3fd098353516fb4eb6bea17015ade0182425" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "cassowary", "crossterm 0.27.0", "indoc", "itertools 0.11.0", - "lru 0.12.1", + "lru 0.12.2", "paste", "strum", "unicode-segmentation", @@ -8106,7 +7706,7 @@ dependencies = [ "cc", "cfg-if", "interpolate_name", - "itertools 0.12.0", + "itertools 0.12.1", "libc", "libfuzzer-sys 0.4.7", "log", @@ -8114,7 +7714,7 @@ dependencies = [ "nasm-rs", "new_debug_unreachable", "noop_proc_macro", - "num-derive 0.4.1", + "num-derive 0.4.2", "num-traits", "once_cell", "paste", @@ -8157,9 +7757,9 @@ checksum = "42a9830a0e1b9fb145ebb365b8bc4ccd75f290f98c0247deafbbe2c75cefb544" [[package]] name = "rayon" -version = "1.8.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" dependencies = [ "either", "rayon-core", @@ -8167,9 +7767,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -8217,13 +7817,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick 1.1.2", "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.5", "regex-syntax 0.8.2", ] @@ -8238,9 +7838,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" dependencies = [ "aho-corasick 1.1.2", "memchr", @@ -8277,18 +7877,18 @@ dependencies = [ [[package]] name = "rend" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2571463863a6bd50c32f94402933f03457a3fbaf697a707c5be741e459f08fd" +checksum = "71fe3824f5629716b1589be05dacd749f6aa084c87e00e016714a8cdfccc997c" dependencies = [ "bytecheck", ] [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "c6920094eb85afde5e4a138be3f2de8bbdf28000f0029e72c45025a56b042251" dependencies = [ "base64 0.21.7", "bytes", @@ -8314,6 +7914,7 @@ dependencies = [ "serde", "serde_json", "serde_urlencoded", + "sync_wrapper", "system-configuration", "tokio", "tokio-native-tls", @@ -8340,16 +7941,6 @@ dependencies = [ "quick-error 1.2.3", ] -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - [[package]] name = "rfd" version = "0.12.1" @@ -8389,7 +7980,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3625f343d89990133d013e39c46e350915178cf94f1bec9f49b0cbef98a3e3c" dependencies = [ "ahash 0.8.7", - "bitflags 2.4.1", + "bitflags 2.4.2", "instant", "num-traits", "once_cell", @@ -8440,9 +8031,9 @@ dependencies = [ [[package]] name = "rkyv" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "527a97cdfef66f65998b5f3b637c26f5a5ec09cc52a3f9932313ac645f4190f5" +checksum = "5cba464629b3394fc4dbc6f940ff8f5b4ff5c7aef40f29166fd4ad12acbc99c0" dependencies = [ "bitvec", "bytecheck", @@ -8458,9 +8049,9 @@ dependencies = [ [[package]] name = "rkyv_derive" -version = "0.7.43" +version = "0.7.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5c462a1328c8e67e4d6dbad1eb0355dd43e8ab432c6e227a43657f16ade5033" +checksum = "a7dddfff8de25e6f62b9d64e6e432bf1c6736c57d20323e15ee10435fbda7c65" dependencies = [ "proc-macro2", "quote", @@ -8487,7 +8078,7 @@ dependencies = [ "either", "figment", "futures", - "indexmap 2.1.0", + "indexmap 2.2.2", "log", "memchr", "multer 2.1.0", @@ -8518,7 +8109,7 @@ checksum = "a2238066abf75f21be6cd7dc1a09d5414a671f4246e384e49fe3f8a4936bd04c" dependencies = [ "devise", "glob", - "indexmap 2.1.0", + "indexmap 2.2.2", "proc-macro2", "quote", "rocket_http", @@ -8538,7 +8129,7 @@ dependencies = [ "futures", "http 0.2.11", "hyper 0.14.28", - "indexmap 2.1.0", + "indexmap 2.2.2", "log", "memchr", "pear", @@ -8571,8 +8162,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94" dependencies = [ "base64 0.21.7", - "bitflags 2.4.1", - "indexmap 2.1.0", + "bitflags 2.4.2", + "indexmap 2.2.2", "serde", "serde_derive", ] @@ -8648,9 +8239,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.33.1" +version = "1.34.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06676aec5ccb8fc1da723cc8c0f9a46549f21ebb8753d3915c6c41db1e7f1dc4" +checksum = "755392e1a2f77afd95580d3f0d0e94ac83eeeb7167552c9b5bca549e61a94d83" dependencies = [ "arrayvec", "borsh", @@ -8721,14 +8312,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.28" +version = "0.38.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.4.2", "errno", "libc", - "linux-raw-sys 0.4.12", + "linux-raw-sys 0.4.13", "windows-sys 0.52.0", ] @@ -8827,7 +8418,7 @@ dependencies = [ "bytes", "flate2", "futures-util", - "indexmap 2.1.0", + "indexmap 2.2.2", "salvo_core", "tokio", "tokio-util", @@ -8892,7 +8483,7 @@ dependencies = [ "http-body-util", "hyper 1.1.0", "hyper-util", - "indexmap 2.1.0", + "indexmap 2.2.2", "mime", "mime-infer", "multer 3.0.0", @@ -8990,23 +8581,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "scraper" -version = "0.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59e25654b5e9fd557a67dbaab5a5d36b8c448d0561beb4c041b6dbb902eddfa6" -dependencies = [ - "ahash 0.8.7", - "cssparser 0.29.6", - "ego-tree", - "getopts", - "html5ever", - "once_cell", - "selectors 0.24.0", - "smallvec", - "tendril", -] - [[package]] name = "sct" version = "0.7.1" @@ -9023,20 +8597,6 @@ version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array 0.14.7", - "pkcs8", - "subtle", - "zeroize", -] - [[package]] name = "security-framework" version = "2.9.2" @@ -9075,29 +8635,11 @@ dependencies = [ "phf 0.8.0", "phf_codegen 0.8.0", "precomputed-hash", - "servo_arc 0.1.1", + "servo_arc", "smallvec", "thin-slice", ] -[[package]] -name = "selectors" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c37578180969d00692904465fb7f6b3d50b9a2b952b87c23d0e2e5cb5013416" -dependencies = [ - "bitflags 1.3.2", - "cssparser 0.29.6", - "derive_more", - "fxhash", - "log", - "phf 0.8.0", - "phf_codegen 0.8.0", - "precomputed-hash", - "servo_arc 0.2.0", - "smallvec", -] - [[package]] name = "semver" version = "1.0.21" @@ -9115,9 +8657,9 @@ checksum = "f97841a747eef040fcd2e7b3b9a220a7205926e60488e673d9e4926d27772ce5" [[package]] name = "serde" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] @@ -9167,9 +8709,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.195" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", @@ -9178,9 +8720,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.111" +version = "1.0.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" dependencies = [ "itoa 1.0.10", "ryu", @@ -9197,15 +8739,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_plain" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1fc6db65a611022b23a0dec6975d63fb80a302cb3388835ff02c097258d50" -dependencies = [ - "serde", -] - [[package]] name = "serde_qs" version = "0.12.0" @@ -9261,15 +8794,15 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.4.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +checksum = "1b0ed1662c5a68664f45b76d18deb0e234aff37207086803165c961eb695e981" dependencies = [ "base64 0.21.7", "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.1.0", + "indexmap 2.2.2", "serde", "serde_json", "serde_with_macros", @@ -9278,9 +8811,9 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.4.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +checksum = "568577ff0ef47b879f736cd66740e022f3672788cdf002a05a4e609ea5a6fb15" dependencies = [ "darling", "proc-macro2", @@ -9290,9 +8823,9 @@ dependencies = [ [[package]] name = "server_fn" -version = "0.5.4" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cfed18dfcc8d9004579c40482c3419c07f60ffb9c5b250542edca99f508b0ce9" +checksum = "6c265de965fe48e09ad8899d0ab1ffebdfa1a9914e4de5ff107b07bd94cf7541" dependencies = [ "ciborium", "const_format", @@ -9315,9 +8848,9 @@ dependencies = [ [[package]] name = "server_fn_macro" -version = "0.5.4" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b70ae8e22546ba85500391b36c08e3fba64871be8a26557a3663a8e08acb56f" +checksum = "f77000541a62ceeec01eef3ee0f86c155c33dac5fae750ad04a40852c6d5469a" dependencies = [ "const_format", "proc-macro-error", @@ -9330,9 +8863,9 @@ dependencies = [ [[package]] name = "server_fn_macro_default" -version = "0.5.4" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7256ba61dfadb220598db418376e7bc2a34b96df36c4dc48f24ffe161810fc0b" +checksum = "8a3353f22e2bcc451074d4feaa37317d9d17dff11d4311928384734ea17ab9ca" dependencies = [ "server_fn_macro", "syn 2.0.48", @@ -9348,16 +8881,6 @@ dependencies = [ "stable_deref_trait", ] -[[package]] -name = "servo_arc" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52aa42f8fdf0fed91e5ce7f23d8138441002fa31dca008acf47e6fd4721f741" -dependencies = [ - "nodrop", - "stable_deref_trait", -] - [[package]] name = "sha-1" version = "0.10.1" @@ -9523,16 +9046,6 @@ version = "0.3.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" -[[package]] -name = "sized-chunks" -version = "0.6.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16d69225bde7a69b235da73377861095455d298f2b970996eec25ddbb42b3d1e" -dependencies = [ - "bitmaps", - "typenum", -] - [[package]] name = "slab" version = "0.4.9" @@ -9572,17 +9085,11 @@ dependencies = [ "version_check", ] -[[package]] -name = "smallbox" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d92359f97e6b417da4328a970cf04a044db104fbd57f7d72cb7ff665bb8806af" - [[package]] name = "smallvec" -version = "1.11.2" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "smartstring" @@ -9681,7 +9188,7 @@ version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" dependencies = [ - "itertools 0.12.0", + "itertools 0.12.1", "nom", "unicode_categories", ] @@ -9724,7 +9231,7 @@ dependencies = [ "futures-util", "hashlink", "hex", - "indexmap 2.1.0", + "indexmap 2.2.2", "ipnetwork", "log", "mac_address", @@ -9799,7 +9306,7 @@ dependencies = [ "atoi", "base64 0.21.7", "bigdecimal", - "bitflags 2.4.1", + "bitflags 2.4.2", "byteorder", "bytes", "chrono", @@ -9847,7 +9354,7 @@ dependencies = [ "base64 0.21.7", "bigdecimal", "bit-vec", - "bitflags 2.4.1", + "bitflags 2.4.2", "byteorder", "chrono", "crc", @@ -9955,9 +9462,9 @@ checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] name = "str-buf" -version = "3.0.2" +version = "3.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e75b72ee54e2f93c3ea1354066162be893ee5e25773ab743de3e088cecbb4f31" +checksum = "0ceb97b7225c713c2fd4db0153cb6b3cab244eb37900c3f634ed4d43310d8c34" [[package]] name = "string_cache" @@ -10120,7 +9627,7 @@ dependencies = [ "cfg-expr 0.15.6", "heck 0.4.1", "pkg-config", - "toml 0.8.8", + "toml 0.8.10", "version-compare", ] @@ -10138,9 +9645,9 @@ dependencies = [ [[package]] name = "tao" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0dff18fed076d29cb5779e918ef4b8a5dbb756204e4a027794f0bce233d949" +checksum = "75d4a64cfac8e487c61d778fe4ab8480f162451e8af7f247aafadcb3b2560852" dependencies = [ "bitflags 1.3.2", "cc", @@ -10300,7 +9807,7 @@ dependencies = [ "cfg-if", "fastrand 2.0.1", "redox_syscall", - "rustix 0.38.28", + "rustix 0.38.31", "windows-sys 0.48.0", ] @@ -10381,9 +9888,9 @@ dependencies = [ [[package]] name = "tiff" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d172b0f4d3fba17ba89811858b9d3d97f928aece846475bbda076ca46736211" +checksum = "ba1310fcea54c6a9a4fd1aad794ecc02c31682f6bfbecdf460bf19533eed1e3e" dependencies = [ "flate2", "jpeg-decoder", @@ -10392,13 +9899,14 @@ dependencies = [ [[package]] name = "time" -version = "0.3.31" +version = "0.3.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" dependencies = [ "deranged", "itoa 1.0.10", "libc", + "num-conv", "num_threads", "powerfmt", "serde", @@ -10414,10 +9922,11 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" dependencies = [ + "num-conv", "time-core", ] @@ -10463,9 +9972,9 @@ checksum = "c7c4ceeeca15c8384bbc3e011dbd8fccb7f068a440b752b7d9b32ceb0ca0e2e8" [[package]] name = "tokio" -version = "1.35.1" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" dependencies = [ "backtrace", "bytes", @@ -10609,15 +10118,15 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.8" +version = "0.8.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1a195ec8c9da26928f773888e0742ca3ca1040c6cd859c919c9f59c1954ab35" +checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.2", "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.21.0", + "toml_edit 0.22.4", ] [[package]] @@ -10635,7 +10144,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.2", "serde", "serde_spanned", "toml_datetime", @@ -10644,22 +10153,33 @@ dependencies = [ [[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.1.0", + "indexmap 2.2.2", "toml_datetime", "winnow", ] [[package]] name = "toml_edit" -version = "0.21.0" +version = "0.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d34d383cd00a163b4a5b85053df514d45bc330f6de7737edfe0a93311d1eaa03" +checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" dependencies = [ - "indexmap 2.1.0", + "indexmap 2.2.2", + "toml_datetime", + "winnow", +] + +[[package]] +name = "toml_edit" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ffdf896f8daaabf9b66ba8e77ea1ed5ed0f72821b398aba62352e95062951" +dependencies = [ + "indexmap 2.2.2", "serde", "serde_spanned", "toml_datetime", @@ -10736,9 +10256,9 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140" dependencies = [ - "async-compression 0.4.5", + "async-compression 0.4.6", "base64 0.21.7", - "bitflags 2.4.1", + "bitflags 2.4.2", "bytes", "futures-core", "futures-util", @@ -10854,9 +10374,9 @@ dependencies = [ [[package]] name = "treediff" -version = "4.0.2" +version = "4.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52984d277bdf2a751072b5df30ec0377febdb02f7696d64c2d7d54630bac4303" +checksum = "4d127780145176e2b5d16611cc25a900150e86e9fd79d3bde6ff3a37359c9cb5" dependencies = [ "serde_json", ] @@ -10915,9 +10435,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "trybuild" -version = "1.0.88" +version = "1.0.89" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76de4f783e610194f6c98bfd53f9fc52bb2e0d02c947621e8a0f4ecc799b2880" +checksum = "9a9d3ba662913483d6722303f619e75ea10b7855b0f8e0d72799cf8621bb488f" dependencies = [ "basic-toml", "dissimilar", @@ -11015,18 +10535,20 @@ dependencies = [ [[package]] name = "ulid" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e37c4b6cbcc59a8dcd09a6429fbc7890286bcbb79215cea7b38a3c4c0921d93" +checksum = "34778c17965aa2a08913b57e1f34db9b4a63f5de31768b55bf20d2795f921259" dependencies = [ + "getrandom 0.2.12", "rand 0.8.5", + "web-time", ] [[package]] name = "uncased" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b9bc53168a4be7402ab86c3aad243a84dd7381d09be0eddc81280c1da95ca68" +checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" dependencies = [ "serde", "version_check", @@ -11043,9 +10565,9 @@ dependencies = [ [[package]] name = "unicode-bidi" -version = "0.3.14" +version = "0.3.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" [[package]] name = "unicode-bom" @@ -11070,9 +10592,9 @@ dependencies = [ [[package]] name = "unicode-segmentation" -version = "1.10.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" [[package]] name = "unicode-width" @@ -11162,9 +10684,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "uuid" -version = "1.6.1" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560" +checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a" dependencies = [ "getrandom 0.2.12", "serde", @@ -11179,7 +10701,7 @@ checksum = "c372e4e6fad129795fb86fda6021b258948560b39883b80ed00510a7d19846b0" dependencies = [ "cfg-if", "noop_proc_macro", - "num-derive 0.4.1", + "num-derive 0.4.2", "num-traits", "profiling", ] @@ -11192,9 +10714,9 @@ checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" [[package]] name = "value-bag" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cdbaf5e132e593e9fc1de6a15bbec912395b11fb9719e061cf64f804524c503" +checksum = "126e423afe2dd9ac52142e7e9d5ce4135d7e13776c529d27fd6bc49f19e3280b" [[package]] name = "vcpkg" @@ -11310,16 +10832,11 @@ name = "warp-hello-world" version = "0.1.0" dependencies = [ "dioxus", - "dioxus-fullstack", - "dioxus-web", - "execute", "reqwest", "serde", - "simple_logger", "tracing", "tracing-subscriber", "tracing-wasm", - "warp", ] [[package]] @@ -11336,9 +10853,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" dependencies = [ "cfg-if", "wasm-bindgen-macro", @@ -11346,9 +10863,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" dependencies = [ "bumpalo", "log", @@ -11361,12 +10878,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-cli-support" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf8226e223e2dfbe8f921b7f20b82d1b5d86a6b143e9d6286cca8edd16695583" +checksum = "806a045c4ec4ef7c3ad86dc27bcb641b84d9eeb3846200f56d7ab0885241d654" dependencies = [ "anyhow", - "base64 0.9.3", + "base64 0.21.7", "log", "rustc-demangle", "serde_json", @@ -11383,9 +10900,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-externref-xform" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8a719be856d8b0802c7195ca26ee6eb02cb9639a12b80be32db960ce9640cb8" +checksum = "12b6ac5fca1d0992d2328147488169ea166bfe899c88f8ad06cf583f4c492fcf" dependencies = [ "anyhow", "walrus", @@ -11393,9 +10910,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "877b9c3f61ceea0e56331985743b13f3d25c406a7098d45180fb5f09bc19ed97" dependencies = [ "cfg-if", "js-sys", @@ -11405,9 +10922,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -11415,9 +10932,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" dependencies = [ "proc-macro2", "quote", @@ -11428,9 +10945,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-multi-value-xform" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a12766255d4b9026700376cc81894eeb62903e4414cbc94675f6f9babd9cfb76" +checksum = "d1e019acde479e2f090fb7f14a51fa0077ec3a7bb12a56e0e888a82be7b5bd3f" dependencies = [ "anyhow", "walrus", @@ -11438,15 +10955,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" [[package]] name = "wasm-bindgen-test" -version = "0.3.39" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2cf9242c0d27999b831eae4767b2a146feb0b27d332d553e605864acd2afd403" +checksum = "143ddeb4f833e2ed0d252e618986e18bfc7b0e52f2d28d77d05b2f045dd8eb61" dependencies = [ "console_error_panic_hook", "js-sys", @@ -11458,9 +10975,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-test-macro" -version = "0.3.39" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "794645f5408c9a039fd09f4d113cdfb2e7eba5ff1956b07bcf701cf4b394fe89" +checksum = "a5211b7550606857312bba1d978a8ec75692eae187becc5e680444fffc5e6f89" dependencies = [ "proc-macro2", "quote", @@ -11469,9 +10986,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-threads-xform" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2b14c5b9c2c7aa9dd1eb7161857de9783f40e98582e7f41f2d7c04ffdc155" +checksum = "90a2e577034352f9aa9352730fcf2562c68957f2e9b9ee70ab6379510e49e2fe" dependencies = [ "anyhow", "walrus", @@ -11480,9 +10997,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-wasm-conventions" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aaedf88769cb23c6fd2e3bfed65bcbff6c5d92c8336afbd80d2dfcc8eb5cf047" +checksum = "4e6b653f6820409609bda0f176e6949302307af7a7b9479cd4d4b1bdc31eb9cd" dependencies = [ "anyhow", "walrus", @@ -11490,9 +11007,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-wasm-interpreter" -version = "0.2.89" +version = "0.2.91" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a8a79039df1e0822e6d66508ec86052993deac201e26060f62abcd85e1daf951" +checksum = "682940195a701dbf887f20017418b8cac916a37b3f91ededec33226619e973c1" dependencies = [ "anyhow", "log", @@ -11522,9 +11039,9 @@ dependencies = [ [[package]] name = "wasm-streams" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4609d447824375f43e1ffbc051b50ad8f4b3ae8219680c94452ea05eb240ac7" +checksum = "b65dc4c90b63b118468cf747d8bf3566c1913ef60be765b5730ead9e0a3ba129" dependencies = [ "futures-util", "js-sys", @@ -11541,9 +11058,19 @@ checksum = "449167e2832691a1bff24cde28d2804e90e09586a448c8e76984792c44334a6b" [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "96565907687f7aceb35bc5fc03770a8a0471d82e479f25832f54a0e3f4b28446" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ee269d72cc29bf77a2c4bc689cc750fb39f5cbd493d2205bbb3f5c7779cf7b0" dependencies = [ "js-sys", "wasm-bindgen", @@ -11631,9 +11158,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.25.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" [[package]] name = "webview2-com" @@ -11673,9 +11200,9 @@ dependencies = [ [[package]] name = "weezl" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" +checksum = "53a85b86a771b1c87058196170769dd264f66c0782acf1ae6cc51bfd64b39082" [[package]] name = "which" @@ -11686,7 +11213,7 @@ dependencies = [ "either", "home", "once_cell", - "rustix 0.38.28", + "rustix 0.38.31", ] [[package]] @@ -11993,9 +11520,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" [[package]] name = "winnow" -version = "0.5.34" +version = "0.5.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +checksum = "5389a154b01683d28c77f8f68f49dea75f0a4da32557a58f68ee51ebba472d29" dependencies = [ "memchr", ] @@ -12087,22 +11614,22 @@ dependencies = [ [[package]] name = "xattr" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "914566e6413e7fa959cc394fb30e563ba80f3541fbd40816d4c05a0fc3f2a0f1" +checksum = "8da84f1a25939b27f6820d92aed108f83ff920fdf11a7b19366c27c4cda81d4f" dependencies = [ "libc", - "linux-raw-sys 0.4.12", - "rustix 0.38.28", + "linux-raw-sys 0.4.13", + "rustix 0.38.31", ] [[package]] name = "xdg-home" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2769203cd13a0c6015d515be729c526d041e9cf2c0cc478d57faee85f40c6dcd" +checksum = "21e5a325c3cb8398ad6cf859c1135b25dd29e186679cf2da7581d9679f63b38e" dependencies = [ - "nix 0.26.4", + "libc", "winapi", ] @@ -12135,9 +11662,9 @@ dependencies = [ [[package]] name = "zbus" -version = "3.14.1" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31de390a2d872e4cd04edd71b425e29853f786dc99317ed72d73d6fcf5ebb948" +checksum = "c45d06ae3b0f9ba1fb2671268b975557d8f5a84bb5ec6e43964f87e763d8bca8" dependencies = [ "async-broadcast", "async-executor", @@ -12176,9 +11703,9 @@ dependencies = [ [[package]] name = "zbus_macros" -version = "3.14.1" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41d1794a946878c0e807f55a397187c11fc7a038ba5d868e7db4f3bd7760bc9d" +checksum = "b4a1ba45ed0ad344b85a2bb5a1fe9830aed23d67812ea39a586e7d0136439c7d" dependencies = [ "proc-macro-crate 1.3.1", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index 31862400d..5fcbca6e8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,10 +2,12 @@ resolver = "2" members = [ "packages/dioxus", + "packages/dioxus-lib", "packages/core", "packages/cli", "packages/cli-config", "packages/core-macro", + "packages/config-macro", "packages/router-macro", "packages/extension", "packages/router", @@ -17,13 +19,12 @@ members = [ "packages/desktop", "packages/mobile", "packages/interpreter", - "packages/fermi", "packages/liveview", "packages/autofmt", "packages/check", "packages/rsx", "packages/dioxus-tui", - "packages/rink", + "packages/plasmo", "packages/native-core", "packages/native-core-macro", "packages/rsx-rosetta", @@ -42,14 +43,13 @@ members = [ # Full project examples "examples/tailwind", "examples/PWA-example", - "examples/query_segments_demo", - "examples/openid_connect_demo", + # "examples/openid_connect_demo", # Playwright tests - "playwright-tests/liveview", - "playwright-tests/web", - "playwright-tests/fullstack", + "packages/playwright-tests/liveview", + "packages/playwright-tests/web", + "packages/playwright-tests/fullstack", ] -exclude = ["examples/mobile_demo"] +exclude = ["examples/mobile_demo", "examples/openid_connect_demo",] [workspace.package] version = "0.4.3" @@ -57,25 +57,26 @@ version = "0.4.3" # dependencies that are shared across packages [workspace.dependencies] dioxus = { path = "packages/dioxus", version = "0.4.0" } +dioxus-lib = { path = "packages/dioxus-lib", version = "0.4.0" } dioxus-core = { path = "packages/core", version = "0.4.2" } dioxus-core-macro = { path = "packages/core-macro", version = "0.4.0" } -dioxus-router = { path = "packages/router", version = "0.4.1" } +dioxus-config-macro = { path = "packages/config-macro", version = "0.4.0" } +dioxus-router = { path = "packages/router", version = "0.4.1" } dioxus-router-macro = { path = "packages/router-macro", version = "0.4.1" } -dioxus-html = { path = "packages/html", default-features = false, version = "0.4.0" } -dioxus-html-internal-macro = { path = "packages/html-internal-macro", version = "0.4.0" } +dioxus-html = { path = "packages/html", version = "0.4.0" } +dioxus-html-internal-macro = { path = "packages/html-internal-macro", version = "0.4.0" } dioxus-hooks = { path = "packages/hooks", version = "0.4.0" } dioxus-web = { path = "packages/web", version = "0.4.0" } -dioxus-ssr = { path = "packages/ssr", version = "0.4.0" } +dioxus-ssr = { path = "packages/ssr", version = "0.4.0", default-features = false } dioxus-desktop = { path = "packages/desktop", version = "0.4.0" } -dioxus-mobile = { path = "packages/mobile", version = "0.4.0" } +dioxus-mobile = { path = "packages/mobile", version = "0.4.0" } dioxus-interpreter-js = { path = "packages/interpreter", version = "0.4.0" } -fermi = { path = "packages/fermi", version = "0.4.0" } -dioxus-liveview = { path = "packages/liveview", version = "0.4.0" } -dioxus-autofmt = { path = "packages/autofmt", version = "0.4.0" } -dioxus-check = { path = "packages/check", version = "0.4.0" } -dioxus-rsx = { path = "packages/rsx", version = "0.4.0" } -dioxus-tui = { path = "packages/dioxus-tui", version = "0.4.0" } -plasmo = { path = "packages/rink", version = "0.4.0" } +dioxus-liveview = { path = "packages/liveview", version = "0.4.0" } +dioxus-autofmt = { path = "packages/autofmt", version = "0.4.0" } +dioxus-check = { path = "packages/check", version = "0.4.0" } +dioxus-rsx = { path = "packages/rsx", version = "0.4.0" } +dioxus-tui = { path = "packages/dioxus-tui", version = "0.4.0" } +plasmo = { path = "packages/plasmo", version = "0.4.0" } dioxus-native-core = { path = "packages/native-core", version = "0.4.0" } dioxus-native-core-macro = { path = "packages/native-core-macro", version = "0.4.0" } rsx-rosetta = { path = "packages/rsx-rosetta", version = "0.4.0" } @@ -98,11 +99,11 @@ thiserror = "1.0.40" prettyplease = { package = "prettier-please", version = "0.2", features = [ "verbatim", ] } -manganis-cli-support = { git = "https://github.com/DioxusLabs/collect-assets", rev = "e0093a4", features = [ +manganis-cli-support = { git = "https://github.com/DioxusLabs/collect-assets", rev = "f982698", features = [ "webp", "html", ] } -manganis = { git = "https://github.com/DioxusLabs/collect-assets", rev = "e0093a4" } +manganis = { git = "https://github.com/DioxusLabs/collect-assets", rev = "f982698" } # This is a "virtual package" # It is not meant to be published, but is used so "cargo run --example XYZ" works properly @@ -120,27 +121,53 @@ keywords = ["dom", "ui", "gui", "react", "wasm"] rust-version = "1.60.0" publish = false +[dependencies] +manganis = { workspace = true, optional = true} +reqwest = { version = "0.11.9", features = ["json"], optional = true} +http-range = {version = "0.1.5", optional = true } + [dev-dependencies] -dioxus = { workspace = true } -dioxus-desktop = { workspace = true, features = ["transparent"] } +dioxus = { workspace = true, features = ["router"] } dioxus-ssr = { workspace = true } -dioxus-router = { workspace = true } -dioxus-signals = { workspace = true } -fermi = { workspace = true } futures-util = "0.3.21" -log = "0.4.14" -num-format = "0.4.0" separator = "0.4.1" serde = { version = "1.0.136", features = ["derive"] } -im-rc = "15.0.0" -anyhow = "1.0.53" serde_json = "1.0.79" rand = { version = "0.8.4", features = ["small_rng"] } +form_urlencoded = "1.2.0" + +[target.'cfg(target_arch = "wasm32")'.dev-dependencies] +getrandom = { version = "0.2.12", features = ["js"] } + +[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] tokio = { version = "1.16.1", features = ["full"] } -reqwest = { version = "0.11.9", features = ["json"] } -env_logger = "0.10.0" -simple_logger = "4.0.0" -thiserror = { workspace = true } -manganis = { workspace = true } -tracing-subscriber = "0.3.17" -http-range = "0.1.5" + +# To make most examples faster to compile, we split out assets and http-related stuff +# This trims off like 270 dependencies, leading to a significant speedup in compilation time +[features] +liveview = ["dioxus/liveview"] +fullstack = ["dioxus/fullstack"] +axum = ["dioxus/axum"] +salvo = ["dioxus/salvo"] +rocket = ["dioxus/rocket"] +server = ["dioxus/axum"] +default = ["dioxus/desktop"] +web = ["dioxus/web"] +collect-assets = ["manganis"] +http = ["reqwest", "http-range"] + +[[example]] +name = "login_form" +required-features = ["http"] + +[[example]] +name = "dog_app" +required-features = ["http"] + +[[example]] +name = "video_stream" +required-features = ["http"] + +[[example]] +name = "suspense" +required-features = ["http"] diff --git a/README.md b/README.md index c5c41090b..77b409d79 100644 --- a/README.md +++ b/README.md @@ -52,17 +52,20 @@
+> [!WARNING] +> Dioxus 0.5 (currently in master) contains massive breaking changes and is not compatible with Dioxus 0.4 + Dioxus is a portable, performant, and ergonomic framework for building cross-platform user interfaces in Rust. ```rust -fn app(cx: Scope) -> Element { - let mut count = use_state(cx, || 0); +fn app() -> Element { + let mut count = use_signal(|| 0); - cx.render(rsx! { + rsx! { h1 { "High-Five counter: {count}" } button { onclick: move |_| count += 1, "Up high!" } button { onclick: move |_| count -= 1, "Down low!" } - }) + } } ``` diff --git a/examples/PWA-example/src/main.rs b/examples/PWA-example/src/main.rs index 4c09a9bc5..3e4d5b236 100644 --- a/examples/PWA-example/src/main.rs +++ b/examples/PWA-example/src/main.rs @@ -5,16 +5,17 @@ fn main() { wasm_logger::init(wasm_logger::Config::default()); console_error_panic_hook::set_once(); - dioxus_web::launch(app); + launch(app); } -fn app(cx: Scope) -> Element { - cx.render(rsx! ( - div { - style: "text-align: center;", +fn app() -> Element { + rsx! ( + div { style: "text-align: center;", h1 { "🌗 Dioxus 🚀" } h3 { "Frontend that scales." } - p { "Dioxus is a portable, performant, and ergonomic framework for building cross-platform user interfaces in Rust." } + p { + "Dioxus is a portable, performant, and ergonomic framework for building cross-platform user interfaces in Rust." + } } - )) + ) } diff --git a/examples/all_css.rs b/examples/all_css.rs deleted file mode 100644 index 5e646a284..000000000 --- a/examples/all_css.rs +++ /dev/null @@ -1,413 +0,0 @@ -use dioxus::prelude::*; - -fn main() { - dioxus_desktop::launch(app); -} - -fn app(cx: Scope) -> Element { - cx.render(rsx! { - div { - align_content: "a", - align_items: "a", - align_self: "a", - alignment_adjust: "a", - alignment_baseline: "a", - all: "a", - alt: "a", - animation: "a", - animation_delay: "a", - animation_direction: "a", - animation_duration: "a", - animation_fill_mode: "a", - animation_iteration_count: "a", - animation_name: "a", - animation_play_state: "a", - animation_timing_function: "a", - azimuth: "a", - backface_visibility: "a", - background: "a", - background_attachment: "a", - background_clip: "a", - background_color: "a", - background_image: "a", - background_origin: "a", - background_position: "a", - background_repeat: "a", - background_size: "a", - background_blend_mode: "a", - baseline_shift: "a", - bleed: "a", - bookmark_label: "a", - bookmark_level: "a", - bookmark_state: "a", - border: "a", - border_color: "a", - border_style: "a", - border_width: "a", - border_bottom: "a", - border_bottom_color: "a", - border_bottom_style: "a", - border_bottom_width: "a", - border_left: "a", - border_left_color: "a", - border_left_style: "a", - border_left_width: "a", - border_right: "a", - border_right_color: "a", - border_right_style: "a", - border_right_width: "a", - border_top: "a", - border_top_color: "a", - border_top_style: "a", - border_top_width: "a", - border_collapse: "a", - border_image: "a", - border_image_outset: "a", - border_image_repeat: "a", - border_image_slice: "a", - border_image_source: "a", - border_image_width: "a", - border_radius: "a", - border_bottom_left_radius: "a", - border_bottom_right_radius: "a", - border_top_left_radius: "a", - border_top_right_radius: "a", - border_spacing: "a", - bottom: "a", - box_decoration_break: "a", - box_shadow: "a", - box_sizing: "a", - box_snap: "a", - break_after: "a", - break_before: "a", - break_inside: "a", - buffered_rendering: "a", - caption_side: "a", - clear: "a", - clear_side: "a", - clip: "a", - clip_path: "a", - clip_rule: "a", - color: "a", - color_adjust: "a", - color_correction: "a", - color_interpolation: "a", - color_interpolation_filters: "a", - color_profile: "a", - color_rendering: "a", - column_fill: "a", - column_gap: "a", - column_rule: "a", - column_rule_color: "a", - column_rule_style: "a", - column_rule_width: "a", - column_span: "a", - columns: "a", - column_count: "a", - column_width: "a", - contain: "a", - content: "a", - counter_increment: "a", - counter_reset: "a", - counter_set: "a", - cue: "a", - cue_after: "a", - cue_before: "a", - cursor: "a", - direction: "a", - display: "a", - display_inside: "a", - display_outside: "a", - display_extras: "a", - display_box: "a", - dominant_baseline: "a", - elevation: "a", - empty_cells: "a", - enable_background: "a", - fill: "a", - fill_opacity: "a", - fill_rule: "a", - filter: "a", - float: "a", - float_defer_column: "a", - float_defer_page: "a", - float_offset: "a", - float_wrap: "a", - flow_into: "a", - flow_from: "a", - flex: "a", - flex_basis: "a", - flex_grow: "a", - flex_shrink: "a", - flex_flow: "a", - flex_direction: "a", - flex_wrap: "a", - flood_color: "a", - flood_opacity: "a", - font: "a", - font_family: "a", - font_size: "a", - font_stretch: "a", - font_style: "a", - font_weight: "a", - font_feature_settings: "a", - font_kerning: "a", - font_language_override: "a", - font_size_adjust: "a", - font_synthesis: "a", - font_variant: "a", - font_variant_alternates: "a", - font_variant_caps: "a", - font_variant_east_asian: "a", - font_variant_ligatures: "a", - font_variant_numeric: "a", - font_variant_position: "a", - footnote_policy: "a", - glyph_orientation_horizontal: "a", - glyph_orientation_vertical: "a", - grid: "a", - grid_auto_flow: "a", - grid_auto_columns: "a", - grid_auto_rows: "a", - grid_template: "a", - grid_template_areas: "a", - grid_template_columns: "a", - grid_template_rows: "a", - grid_area: "a", - grid_column: "a", - grid_column_start: "a", - grid_column_end: "a", - grid_row: "a", - grid_row_start: "a", - grid_row_end: "a", - hanging_punctuation: "a", - height: "a", - hyphenate_character: "a", - hyphenate_limit_chars: "a", - hyphenate_limit_last: "a", - hyphenate_limit_lines: "a", - hyphenate_limit_zone: "a", - hyphens: "a", - icon: "a", - image_orientation: "a", - image_resolution: "a", - image_rendering: "a", - ime: "a", - ime_align: "a", - ime_mode: "a", - ime_offset: "a", - ime_width: "a", - initial_letters: "a", - inline_box_align: "a", - isolation: "a", - justify_content: "a", - justify_items: "a", - justify_self: "a", - kerning: "a", - left: "a", - letter_spacing: "a", - lighting_color: "a", - line_box_contain: "a", - line_break: "a", - line_grid: "a", - line_height: "a", - line_slack: "a", - line_snap: "a", - list_style: "a", - list_style_image: "a", - list_style_position: "a", - list_style_type: "a", - margin: "a", - margin_bottom: "a", - margin_left: "a", - margin_right: "a", - margin_top: "a", - marker: "a", - marker_end: "a", - marker_mid: "a", - marker_pattern: "a", - marker_segment: "a", - marker_start: "a", - marker_knockout_left: "a", - marker_knockout_right: "a", - marker_side: "a", - marks: "a", - marquee_direction: "a", - marquee_play_count: "a", - marquee_speed: "a", - marquee_style: "a", - mask: "a", - mask_image: "a", - mask_repeat: "a", - mask_position: "a", - mask_clip: "a", - mask_origin: "a", - mask_size: "a", - mask_box: "a", - mask_box_outset: "a", - mask_box_repeat: "a", - mask_box_slice: "a", - mask_box_source: "a", - mask_box_width: "a", - mask_type: "a", - max_height: "a", - max_lines: "a", - max_width: "a", - min_height: "a", - min_width: "a", - mix_blend_mode: "a", - nav_down: "a", - nav_index: "a", - nav_left: "a", - nav_right: "a", - nav_up: "a", - object_fit: "a", - object_position: "a", - offset_after: "a", - offset_before: "a", - offset_end: "a", - offset_start: "a", - opacity: "a", - order: "a", - orphans: "a", - outline: "a", - outline_color: "a", - outline_style: "a", - outline_width: "a", - outline_offset: "a", - overflow: "a", - overflow_x: "a", - overflow_y: "a", - overflow_style: "a", - overflow_wrap: "a", - padding: "a", - padding_bottom: "a", - padding_left: "a", - padding_right: "a", - padding_top: "a", - page: "a", - page_break_after: "a", - page_break_before: "a", - page_break_inside: "a", - paint_order: "a", - pause: "a", - pause_after: "a", - pause_before: "a", - perspective: "a", - perspective_origin: "a", - pitch: "a", - pitch_range: "a", - play_during: "a", - pointer_events: "a", - position: "a", - quotes: "a", - region_fragment: "a", - resize: "a", - rest: "a", - rest_after: "a", - rest_before: "a", - richness: "a", - right: "a", - ruby_align: "a", - ruby_merge: "a", - ruby_position: "a", - scroll_behavior: "a", - scroll_snap_coordinate: "a", - scroll_snap_destination: "a", - scroll_snap_points_x: "a", - scroll_snap_points_y: "a", - scroll_snap_type: "a", - shape_image_threshold: "a", - shape_inside: "a", - shape_margin: "a", - shape_outside: "a", - shape_padding: "a", - shape_rendering: "a", - size: "a", - speak: "a", - speak_as: "a", - speak_header: "a", - speak_numeral: "a", - speak_punctuation: "a", - speech_rate: "a", - stop_color: "a", - stop_opacity: "a", - stress: "a", - string_set: "a", - stroke: "a", - stroke_dasharray: "a", - stroke_dashoffset: "a", - stroke_linecap: "a", - stroke_linejoin: "a", - stroke_miterlimit: "a", - stroke_opacity: "a", - stroke_width: "a", - tab_size: "a", - table_layout: "a", - text_align: "a", - text_align_all: "a", - text_align_last: "a", - text_anchor: "a", - text_combine_upright: "a", - text_decoration: "a", - text_decoration_color: "a", - text_decoration_line: "a", - text_decoration_style: "a", - text_decoration_skip: "a", - text_emphasis: "a", - text_emphasis_color: "a", - text_emphasis_style: "a", - text_emphasis_position: "a", - text_emphasis_skip: "a", - text_height: "a", - text_indent: "a", - text_justify: "a", - text_orientation: "a", - text_overflow: "a", - text_rendering: "a", - text_shadow: "a", - text_size_adjust: "a", - text_space_collapse: "a", - text_spacing: "a", - text_transform: "a", - text_underline_position: "a", - text_wrap: "a", - top: "a", - touch_action: "a", - transform: "a", - transform_box: "a", - transform_origin: "a", - transform_style: "a", - transition: "a", - transition_delay: "a", - transition_duration: "a", - transition_property: "a", - unicode_bidi: "a", - vector_effect: "a", - vertical_align: "a", - visibility: "a", - voice_balance: "a", - voice_duration: "a", - voice_family: "a", - voice_pitch: "a", - voice_range: "a", - voice_rate: "a", - voice_stress: "a", - voice_volumn: "a", - volume: "a", - white_space: "a", - widows: "a", - width: "a", - will_change: "a", - word_break: "a", - word_spacing: "a", - word_wrap: "a", - wrap_flow: "a", - wrap_through: "a", - writing_mode: "a", - z_index: "a", - - "This example isn't quite useful yet" - } - }) -} diff --git a/examples/all_events.rs b/examples/all_events.rs index 14fd1282e..4ceca1a5a 100644 --- a/examples/all_events.rs +++ b/examples/all_events.rs @@ -1,78 +1,59 @@ -use dioxus::{events::*, html::MouseEvent, prelude::*}; +use dioxus::prelude::*; +use std::{collections::VecDeque, fmt::Debug, rc::Rc}; fn main() { - dioxus_desktop::launch(app); -} - -#[derive(Debug)] -enum Event { - MouseMove(MouseEvent), - MouseClick(MouseEvent), - MouseDoubleClick(MouseEvent), - MouseDown(MouseEvent), - MouseUp(MouseEvent), - - Wheel(WheelEvent), - - KeyDown(KeyboardEvent), - KeyUp(KeyboardEvent), - KeyPress(KeyboardEvent), - - FocusIn(FocusEvent), - FocusOut(FocusEvent), + launch(app); } const MAX_EVENTS: usize = 8; const CONTAINER_STYLE: &str = r#" - display: flex; - flex-direction: column; - align-items: center; - "#; + display: flex; + flex-direction: column; + align-items: center; +"#; const RECT_STYLE: &str = r#" - background: deepskyblue; - height: 50vh; - width: 50vw; - color: white; - padding: 20px; - margin: 20px; - text-aligh: center; - "#; + background: deepskyblue; + height: 50vh; + width: 50vw; + color: white; + padding: 20px; + margin: 20px; + text-aligh: center; +"#; -fn app(cx: Scope) -> Element { - let events = use_ref(cx, std::collections::VecDeque::new); +fn app() -> Element { + let mut events = use_signal(|| VecDeque::new() as VecDeque>); - let log_event = move |event: Event| { + let mut log_event = move |event: Rc| { let mut events = events.write(); if events.len() >= MAX_EVENTS { events.pop_front(); } + events.push_back(event); }; - cx.render(rsx! ( + rsx! { div { style: "{CONTAINER_STYLE}", - div { - style: "{RECT_STYLE}", - // focusing is necessary to catch keyboard events - tabindex: "0", + // focusing is necessary to catch keyboard events + div { style: "{RECT_STYLE}", tabindex: 0, + onmousemove: move |event| log_event(event.data()), + onclick: move |event| log_event(event.data()), + ondoubleclick: move |event| log_event(event.data()), + onmousedown: move |event| log_event(event.data()), + onmouseup: move |event| log_event(event.data()), - onmousemove: move |event| log_event(Event::MouseMove(event)), - onclick: move |event| log_event(Event::MouseClick(event)), - ondoubleclick: move |event| log_event(Event::MouseDoubleClick(event)), - onmousedown: move |event| log_event(Event::MouseDown(event)), - onmouseup: move |event| log_event(Event::MouseUp(event)), + onwheel: move |event| log_event(event.data()), - onwheel: move |event| log_event(Event::Wheel(event)), + onkeydown: move |event| log_event(event.data()), + onkeyup: move |event| log_event(event.data()), + onkeypress: move |event| log_event(event.data()), - onkeydown: move |event| log_event(Event::KeyDown(event)), - onkeyup: move |event| log_event(Event::KeyUp(event)), - onkeypress: move |event| log_event(Event::KeyPress(event)), - - onfocusin: move |event| log_event(Event::FocusIn(event)), - onfocusout: move |event| log_event(Event::FocusOut(event)), + onfocusin: move |event| log_event(event.data()), + onfocusout: move |event| log_event(event.data()), "Hover, click, type or scroll to see the info down below" } @@ -82,5 +63,5 @@ fn app(cx: Scope) -> Element { } } } - )) + } } diff --git a/examples/assets/calculator.css b/examples/assets/calculator.css index 047b618ad..d2a622dc9 100644 --- a/examples/assets/calculator.css +++ b/examples/assets/calculator.css @@ -1,13 +1,17 @@ html { box-sizing: border-box; } -*, *:before, *:after { + +*, +*:before, +*:after { box-sizing: inherit; } body { margin: 0; font: 100 14px 'Roboto'; + font-family: Arial; overflow: hidden; } @@ -20,18 +24,18 @@ button { user-select: none; cursor: pointer; outline: none; - - -webkit-tap-highlight-color: rgba(0,0,0,0); + + -webkit-tap-highlight-color: rgba(0, 0, 0, 0); } button:active { - box-shadow: inset 0px 0px 80px 0px rgba(0,0,0,0.25); + box-shadow: inset 0px 0px 80px 0px rgba(0, 0, 0, 0.25); } #wrapper { /* height: 100vh; */ height: max-content; - + display: flex; align-items: center; justify-content: center; @@ -47,7 +51,7 @@ button:active { width: 100%; height: 100%; background: black; - + display: flex; flex-direction: column; } @@ -61,14 +65,14 @@ button:active { background: #1c191c; line-height: 130px; /* font-size: 6em; */ - font-size: 16px; - font-size: 4vw; + font-size: 16px; + font-size: 4vw; max-height: 160px; padding: 0 30px; /* height: 80px; */ - + flex: 1; } @@ -85,7 +89,7 @@ button:active { .calculator-keypad { height: 400px; - + display: flex; } @@ -99,7 +103,7 @@ button:active { .calculator .digit-keys { background: #e0e0e7; - + display: flex; flex-direction: row; flex-wrap: wrap-reverse; @@ -109,28 +113,34 @@ button:active { width: 80px; height: 80px; border-top: 1px solid #777; - border-right: 1px solid #666; + border-right: 1px solid #666; text-align: center; line-height: 80px; } + .calculator .function-keys .calculator-key { font-size: 2em; } + .calculator .function-keys .key-multiply { line-height: 50px; } + .calculator .digit-keys .calculator-key { font-size: 2.25em; } + .calculator .digit-keys .key-0 { width: 160px; text-align: left; padding-left: 32px; } + .calculator .digit-keys .key-dot { padding-top: 1em; font-size: 0.75em; } + .calculator .operator-keys .calculator-key { color: white; border-right: 0; @@ -138,8 +148,9 @@ button:active { } .calculator .function-keys { - background: linear-gradient(to bottom, rgba(202,202,204,1) 0%, rgba(196,194,204,1) 100%); + background: linear-gradient(to bottom, rgba(202, 202, 204, 1) 0%, rgba(196, 194, 204, 1) 100%); } + .calculator .operator-keys { - background: linear-gradient(to bottom, rgba(252,156,23,1) 0%, rgba(247,126,27,1) 100%); + background: linear-gradient(to bottom, rgba(252, 156, 23, 1) 0%, rgba(247, 126, 27, 1) 100%); } diff --git a/examples/backgrounded_futures.rs b/examples/backgrounded_futures.rs new file mode 100644 index 000000000..2877daab3 --- /dev/null +++ b/examples/backgrounded_futures.rs @@ -0,0 +1,55 @@ +use dioxus::prelude::*; + +fn main() { + launch_desktop(app); +} + +fn app() -> Element { + let mut show_child = use_signal(|| true); + let mut count = use_signal(|| 0); + + let child = use_memo(move || { + rsx! { + Child { + count + } + } + }); + + rsx! { + button { onclick: move |_| show_child.toggle(), "Toggle child" } + button { onclick: move |_| count += 1, "Increment count" } + if show_child() { + {child.cloned()} + } + } +} + +#[component] +fn Child(count: Signal) -> Element { + let mut early_return = use_signal(|| false); + + let early = rsx! { + button { onclick: move |_| early_return.toggle(), "Toggle {early_return} early return" } + }; + + if early_return() { + return early; + } + + use_future(move || async move { + loop { + tokio::time::sleep(std::time::Duration::from_millis(100)).await; + println!("Child") + } + }); + + use_effect(move || { + println!("Child count: {}", count()); + }); + + rsx! { + "hellO!" + {early} + } +} diff --git a/examples/borrowed.rs b/examples/borrowed.rs deleted file mode 100644 index 95641bbbc..000000000 --- a/examples/borrowed.rs +++ /dev/null @@ -1,73 +0,0 @@ -#![allow(non_snake_case)] - -/* -Dioxus manages borrow lifetimes for you. This means any child may borrow from its parent. However, it is not possible -to hand out an &mut T to children - all props are consumed by &P, so you'd only get an &&mut T. - -How does it work? - -Dioxus will manually drop closures and props - things that borrow data before the component is ran again. This is done -"bottom up" from the lowest child all the way to the initiating parent. As it traverses each listener and prop, the -drop implementation is manually called, freeing any memory and ensuring that memory is not leaked. - -We cannot drop from the parent to the children - if the drop implementation modifies the data, downstream references -might be broken since we take an &mut T and and &T to the data. Instead, we work bottom up, making sure to remove any -potential references to the data before finally giving out an &mut T. This prevents us from mutably aliasing the data, -and is proven to be safe with MIRI. -*/ - -use dioxus::prelude::*; - -fn main() { - dioxus_desktop::launch(app); -} - -fn app(cx: Scope) -> Element { - let text = cx.use_hook(|| vec![String::from("abc=def")]); - - let first = text.get_mut(0).unwrap(); - - cx.render(rsx! { - div { - Child1 { text: first } - } - }) -} - -#[derive(Props)] -struct C1Props<'a> { - text: &'a mut String, -} - -fn Child1<'a>(cx: Scope<'a, C1Props<'a>>) -> Element { - let (left, right) = cx.props.text.split_once('=').unwrap(); - - cx.render(rsx! { - div { - Child2 { text: left } - Child2 { text: right } - } - }) -} - -#[derive(Props)] -struct C2Props<'a> { - text: &'a str, -} - -fn Child2<'a>(cx: Scope<'a, C2Props<'a>>) -> Element { - cx.render(rsx! { - Child3 { text: cx.props.text } - }) -} - -#[derive(Props)] -struct C3Props<'a> { - text: &'a str, -} - -fn Child3<'a>(cx: Scope<'a, C3Props<'a>>) -> Element { - cx.render(rsx! { - div { "{cx.props.text}"} - }) -} diff --git a/examples/calculator.rs b/examples/calculator.rs index 11151dcbf..88c1e8fa5 100644 --- a/examples/calculator.rs +++ b/examples/calculator.rs @@ -6,65 +6,58 @@ This calculator version uses React-style state management. All state is held as use dioxus::events::*; use dioxus::html::input_data::keyboard_types::Key; use dioxus::prelude::*; -use dioxus_desktop::{Config, LogicalSize, WindowBuilder}; fn main() { - let config = Config::new().with_window( - WindowBuilder::default() - .with_title("Calculator") - .with_inner_size(LogicalSize::new(300.0, 500.0)), - ); - - dioxus_desktop::launch_cfg(app, config); + LaunchBuilder::new() + .with_cfg(desktop!({ + use dioxus::desktop::{Config, LogicalSize, WindowBuilder}; + Config::new().with_window( + WindowBuilder::default() + .with_title("Calculator") + .with_inner_size(LogicalSize::new(300.0, 525.0)), + ) + })) + .launch(app); } -fn app(cx: Scope) -> Element { - let val = use_state(cx, || String::from("0")); +fn app() -> Element { + let mut val = use_signal(|| String::from("0")); - let input_digit = move |num: u8| { - if val.get() == "0" { + let mut input_digit = move |num: String| { + if val() == "0" { val.set(String::new()); } - - val.make_mut().push_str(num.to_string().as_str()); + val.write().push_str(num.as_str()); }; - let input_operator = move |key: &str| val.make_mut().push_str(key); + let mut input_operator = move |key: &str| val.write().push_str(key); let handle_key_down_event = move |evt: KeyboardEvent| match evt.key() { Key::Backspace => { - if !val.len() != 0 { - val.make_mut().pop(); + if !val().is_empty() { + val.write().pop(); } } Key::Character(character) => match character.as_str() { - "+" => input_operator("+"), - "-" => input_operator("-"), - "/" => input_operator("/"), - "*" => input_operator("*"), - "0" => input_digit(0), - "1" => input_digit(1), - "2" => input_digit(2), - "3" => input_digit(3), - "4" => input_digit(4), - "5" => input_digit(5), - "6" => input_digit(6), - "7" => input_digit(7), - "8" => input_digit(8), - "9" => input_digit(9), + "+" | "-" | "/" | "*" => input_operator(&character), + "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" => input_digit(character), _ => {} }, _ => {} }; - cx.render(rsx!( + rsx! { style { {include_str!("./assets/calculator.css")} } div { id: "wrapper", div { class: "app", - div { class: "calculator", - tabindex: "0", - onkeydown: handle_key_down_event, - div { class: "calculator-display", "{val}" } + div { class: "calculator", tabindex: "0", onkeydown: handle_key_down_event, + div { class: "calculator-display", + if val().is_empty() { + "0" + } else { + "{val}" + } + } div { class: "calculator-keypad", div { class: "input-keys", div { class: "function-keys", @@ -72,55 +65,62 @@ fn app(cx: Scope) -> Element { class: "calculator-key key-clear", onclick: move |_| { val.set(String::new()); - if !val.is_empty(){ + if !val.cloned().is_empty() { val.set("0".into()); } }, - if val.is_empty() { "C" } else { "AC" } + if val.cloned().is_empty() { "C" } else { "AC" } } button { class: "calculator-key key-sign", onclick: move |_| { - let temp = calc_val(val.as_str()); - if temp > 0.0 { - val.set(format!("-{temp}")); + let new_val = calc_val(val.cloned().as_str()); + if new_val > 0.0 { + val.set(format!("-{new_val}")); } else { - val.set(format!("{}", temp.abs())); + val.set(format!("{}", new_val.abs())); } }, "±" } button { class: "calculator-key key-percent", - onclick: move |_| { - val.set( - format!("{}", calc_val(val.as_str()) / 100.0) - ); - }, + onclick: move |_| val.set(format!("{}", calc_val(val.cloned().as_str()) / 100.0)), "%" } } div { class: "digit-keys", - button { class: "calculator-key key-0", onclick: move |_| input_digit(0), "0" } - button { class: "calculator-key key-dot", onclick: move |_| val.make_mut().push('.'), "●" } + button { + class: "calculator-key key-0", + onclick: move |_| input_digit(0.to_string()), + "0" + } + button { + class: "calculator-key key-dot", + onclick: move |_| val.write().push('.'), + "●" + } for k in 1..10 { button { class: "calculator-key {k}", name: "key-{k}", - onclick: move |_| input_digit(k), + onclick: move |_| input_digit(k.to_string()), "{k}" } } } } div { class: "operator-keys", - button { class: "calculator-key key-divide", onclick: move |_| input_operator("/"), "÷" } - button { class: "calculator-key key-multiply", onclick: move |_| input_operator("*"), "×" } - button { class: "calculator-key key-subtract", onclick: move |_| input_operator("-"), "−" } - button { class: "calculator-key key-add", onclick: move |_| input_operator("+"), "+" } + for (key, class) in [("/", "key-divide"), ("*", "key-multiply"), ("-", "key-subtract"), ("+", "key-add")] { + button { + class: "calculator-key {class}", + onclick: move |_| input_operator(key), + "{key}" + } + } button { class: "calculator-key key-equals", - onclick: move |_| val.set(format!("{}", calc_val(val.as_str()))), + onclick: move |_| val.set(format!("{}", calc_val(val.cloned().as_str()))), "=" } } @@ -128,8 +128,7 @@ fn app(cx: Scope) -> Element { } } } - - )) + } } fn calc_val(val: &str) -> f64 { diff --git a/examples/pattern_model.rs b/examples/calculator_mutable.rs similarity index 73% rename from examples/pattern_model.rs rename to examples/calculator_mutable.rs index 6dd3e8825..ae1a6f353 100644 --- a/examples/pattern_model.rs +++ b/examples/calculator_mutable.rs @@ -17,12 +17,12 @@ //! the RefCell will panic and crash. You can use `try_get_mut` or `.modify` to avoid this problem, or just not hold two //! RefMuts at the same time. +use dioxus::desktop::tao::dpi::LogicalSize; +use dioxus::desktop::{Config, WindowBuilder}; use dioxus::events::*; use dioxus::html::input_data::keyboard_types::Key; use dioxus::html::MouseEvent; use dioxus::prelude::*; -use dioxus_desktop::tao::dpi::LogicalSize; -use dioxus_desktop::{Config, WindowBuilder}; fn main() { let cfg = Config::new().with_window( @@ -32,50 +32,34 @@ fn main() { .with_inner_size(LogicalSize::new(320.0, 530.0)), ); - dioxus_desktop::launch_cfg(app, cfg); + LaunchBuilder::desktop().with_cfg(cfg).launch(app); } const STYLE: &str = include_str!("./assets/calculator.css"); -fn app(cx: Scope) -> Element { - let state = use_ref(cx, Calculator::new); +fn app() -> Element { + let mut state = use_signal(Calculator::new); - cx.render(rsx! { + rsx! { style { {STYLE} } div { id: "wrapper", div { class: "app", - div { class: "calculator", onkeypress: move |evt| state.write().handle_keydown(evt), + div { + class: "calculator", + onkeypress: move |evt| state.write().handle_keydown(evt), div { class: "calculator-display", {state.read().formatted_display()} } div { class: "calculator-keypad", div { class: "input-keys", div { class: "function-keys", - CalculatorKey { - name: "key-clear", - onclick: move |_| state.write().clear_display(), + CalculatorKey { name: "key-clear", onclick: move |_| state.write().clear_display(), if state.read().display_value == "0" { "C" } else { "AC" } } - CalculatorKey { - name: "key-sign", - onclick: move |_| state.write().toggle_sign(), - "±" - } - CalculatorKey { - name: "key-percent", - onclick: move |_| state.write().toggle_percent(), - "%" - } + CalculatorKey { name: "key-sign", onclick: move |_| state.write().toggle_sign(), "±" } + CalculatorKey { name: "key-percent", onclick: move |_| state.write().toggle_percent(), "%" } } div { class: "digit-keys", - CalculatorKey { - name: "key-0", - onclick: move |_| state.write().input_digit(0), - "0" - } - CalculatorKey { - name: "key-dot", - onclick: move |_| state.write().input_dot(), - "●" - } + CalculatorKey { name: "key-0", onclick: move |_| state.write().input_digit(0), "0" } + CalculatorKey { name: "key-dot", onclick: move |_| state.write().input_dot(), "●" } for k in 1..10 { CalculatorKey { key: "{k}", @@ -102,39 +86,21 @@ fn app(cx: Scope) -> Element { onclick: move |_| state.write().set_operator(Operator::Sub), "−" } - CalculatorKey { - name: "key-add", - onclick: move |_| state.write().set_operator(Operator::Add), - "+" - } - CalculatorKey { - name: "key-equals", - onclick: move |_| state.write().perform_operation(), - "=" - } + CalculatorKey { name: "key-add", onclick: move |_| state.write().set_operator(Operator::Add), "+" } + CalculatorKey { name: "key-equals", onclick: move |_| state.write().perform_operation(), "=" } } } } } } - }) + } } -#[derive(Props)] -struct CalculatorKeyProps<'a> { - name: &'a str, - onclick: EventHandler<'a, MouseEvent>, - children: Element<'a>, -} - -fn CalculatorKey<'a>(cx: Scope<'a, CalculatorKeyProps<'a>>) -> Element { - cx.render(rsx! { - button { - class: "calculator-key {cx.props.name}", - onclick: move |e| cx.props.onclick.call(e), - {&cx.props.children} - } - }) +#[component] +fn CalculatorKey(name: String, onclick: EventHandler, children: Element) -> Element { + rsx! { + button { class: "calculator-key {name}", onclick: move |e| onclick.call(e), {&children} } + } } struct Calculator { diff --git a/examples/callback.rs b/examples/callback.rs deleted file mode 100644 index cb300b701..000000000 --- a/examples/callback.rs +++ /dev/null @@ -1,22 +0,0 @@ -use dioxus::prelude::*; - -fn main() { - dioxus_desktop::launch(app); -} - -fn app(cx: Scope) -> Element { - let login = use_callback!(cx, move |_| async move { - let res = reqwest::get("https://dog.ceo/api/breeds/list/all") - .await - .unwrap() - .text() - .await - .unwrap(); - - println!("{res:#?}, "); - }); - - cx.render(rsx! { - button { onclick: login, "Click me!" } - }) -} diff --git a/examples/clock.rs b/examples/clock.rs index ba47d994a..b48a4053f 100644 --- a/examples/clock.rs +++ b/examples/clock.rs @@ -1,22 +1,24 @@ use dioxus::prelude::*; -use dioxus_signals::use_signal; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - let mut count = use_signal(cx, || 0); +fn app() -> Element { + let mut count = use_signal(|| 0); - use_future!(cx, || async move { + use_future(move || async move { loop { tokio::time::sleep(std::time::Duration::from_millis(10)).await; count += 1; - println!("current: {count}"); } }); - cx.render(rsx! { + use_effect(move || { + println!("High-Five counter: {}", count()); + }); + + rsx! { div { "High-Five counter: {count}" } - }) + } } diff --git a/examples/compose.rs b/examples/compose.rs index 180cd6983..20ee392d0 100644 --- a/examples/compose.rs +++ b/examples/compose.rs @@ -1,68 +1,62 @@ //! This example shows how to create a popup window and send data back to the parent window. +use std::rc::Rc; + use dioxus::prelude::*; use futures_util::StreamExt; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - let emails_sent = use_ref(cx, Vec::new); +fn app() -> Element { + let mut emails_sent = use_signal(|| Vec::new() as Vec); - let tx = use_coroutine(cx, |mut rx: UnboundedReceiver| { - to_owned![emails_sent]; - async move { - while let Some(message) = rx.next().await { - emails_sent.write().push(message); - } + // Wait for responses to the compose channel, and then push them to the emails_sent signal. + let handle = use_coroutine(|mut rx: UnboundedReceiver| async move { + while let Some(message) = rx.next().await { + emails_sent.write().push(message); } }); - cx.render(rsx! { - div { - h1 { "This is your email" } + let open_compose_window = move |_evt: MouseEvent| { + let tx = handle.tx(); + dioxus::desktop::window().new_window( + VirtualDom::new_with_props(compose, Rc::new(move |s| tx.unbounded_send(s).unwrap())), + Default::default(), + ); + }; - button { - onclick: move |_| { - let dom = VirtualDom::new_with_props(compose, ComposeProps { app_tx: tx.clone() }); - dioxus_desktop::window().new_window(dom, Default::default()); - }, - "Click to compose a new email" - } - - ul { - for message in emails_sent.read().iter() { - li { - h3 { "email" } - span {"{message}"} - } + rsx! { + h1 { "This is your email" } + button { onclick: open_compose_window, "Click to compose a new email" } + ul { + for message in emails_sent.read().iter() { + li { + h3 { "email" } + span { "{message}" } } } } - }) + } } -struct ComposeProps { - app_tx: Coroutine, -} +fn compose(send: Rc) -> Element { + let mut user_input = use_signal(String::new); -fn compose(cx: Scope) -> Element { - let user_input = use_state(cx, String::new); - - cx.render(rsx! { + rsx! { div { h1 { "Compose a new email" } button { onclick: move |_| { - cx.props.app_tx.send(user_input.get().clone()); - dioxus_desktop::window().close(); + send(user_input.cloned()); + dioxus::desktop::window().close(); }, "Click to send" } input { oninput: move |e| user_input.set(e.value()), value: "{user_input}" } } - }) + } } diff --git a/examples/control_focus.rs b/examples/control_focus.rs index f161652f0..1172327ea 100644 --- a/examples/control_focus.rs +++ b/examples/control_focus.rs @@ -3,36 +3,41 @@ use std::rc::Rc; use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - let elements: &UseRef>> = use_ref(cx, Vec::new); - let running = use_state(cx, || true); +fn app() -> Element { + let mut elements = use_signal(Vec::>::new); + let mut running = use_signal(|| true); - use_future!(cx, |(elements, running)| async move { + use_future(move || async move { let mut focused = 0; - if *running.current() { - loop { - tokio::time::sleep(std::time::Duration::from_millis(10)).await; - if let Some(element) = elements.with(|f| f.get(focused).cloned()) { - _ = element.set_focus(true).await; - } else { - focused = 0; - } - focused += 1; + + loop { + tokio::time::sleep(std::time::Duration::from_millis(10)).await; + + if !running() { + continue; } + + if let Some(element) = elements.with(|f| f.get(focused).cloned()) { + _ = element.set_focus(true).await; + } else { + focused = 0; + } + + focused += 1; } }); - cx.render(rsx!( + rsx! { div { h1 { "Input Roulette" } for i in 0..100 { input { value: "{i}", onmounted: move |cx| { - elements.write().push(cx.inner().clone()); + elements.write().push(cx.data()); }, oninput: move |_| { running.set(false); @@ -40,5 +45,5 @@ fn app(cx: Scope) -> Element { } } } - )) + } } diff --git a/examples/counter.rs b/examples/counter.rs index 1de77dc38..a25115b22 100644 --- a/examples/counter.rs +++ b/examples/counter.rs @@ -4,32 +4,49 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch(app); } -fn app(cx: Scope) -> Element { - let counters = use_state(cx, || vec![0, 0, 0]); - let sum: usize = counters.iter().copied().sum(); +fn app() -> Element { + let mut counters = use_signal(|| vec![0, 0, 0]); + let sum = use_memo(move || counters.read().iter().copied().sum::()); - render! { + rsx! { div { - button { onclick: move |_| counters.make_mut().push(0), "Add counter" } - button { onclick: move |_| { counters.make_mut().pop(); }, "Remove counter" } + button { onclick: move |_| counters.write().push(0), "Add counter" } + button { + onclick: move |_| { + counters.write().pop(); + }, + "Remove counter" + } p { "Total: {sum}" } - for (i, counter) in counters.iter().enumerate() { - li { - button { onclick: move |_| counters.make_mut()[i] -= 1, "-1" } - input { - value: "{counter}", - oninput: move |e| { - if let Ok(value) = e.value().parse::() { - counters.make_mut()[i] = value; - } - } + for i in 0..counters.len() { + Child { i, counters } + } + } + } +} + +#[component] +fn Child(counters: Signal>, i: usize) -> Element { + rsx! { + li { + button { onclick: move |_| counters.write()[i] -= 1, "-1" } + input { + value: "{counters.read()[i]}", + oninput: move |e| { + if let Ok(value) = e.value().parse::() { + counters.write()[i] = value; } - button { onclick: move |_| counters.make_mut()[i] += 1, "+1" } - button { onclick: move |_| { counters.make_mut().remove(i); }, "x" } } + } + button { onclick: move |_| counters.write()[i] += 1, "+1" } + button { + onclick: move |_| { + counters.write().remove(i); + }, + "x" } } } diff --git a/examples/crm.rs b/examples/crm.rs index cd9ea330d..d9f2c9a38 100644 --- a/examples/crm.rs +++ b/examples/crm.rs @@ -1,112 +1,100 @@ //! Tiny CRM: A port of the Yew CRM example to Dioxus. use dioxus::prelude::*; -use dioxus_router::prelude::*; fn main() { - dioxus_desktop::launch(App); + LaunchBuilder::new() + .with_cfg(desktop!({ + use dioxus::desktop::{LogicalSize, WindowBuilder}; + dioxus::desktop::Config::default() + .with_window(WindowBuilder::new().with_inner_size(LogicalSize::new(800, 600))) + })) + .launch(|| { + rsx! { + link { + rel: "stylesheet", + href: "https://unpkg.com/purecss@2.0.6/build/pure-min.css", + integrity: "sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5", + crossorigin: "anonymous" + } + style { {r#" .red { background-color: rgb(202, 60, 60) !important; } "#} } + h1 { "Dioxus CRM Example" } + Router:: {} + } + }); +} + +/// We only have one list of clients for the whole app, so we can use a global signal. +static CLIENTS: GlobalSignal> = Signal::global(Vec::new); + +struct Client { + first_name: String, + last_name: String, + description: String, } #[derive(Routable, Clone)] -#[rustfmt::skip] enum Route { #[route("/")] - ClientList {}, + ClientList, + #[route("/new")] - ClientAdd {}, + ClientAdd, + #[route("/settings")] - Settings {}, -} - -#[derive(Clone, Debug, Default)] -pub struct Client { - pub first_name: String, - pub last_name: String, - pub description: String, -} - -type ClientContext = Vec; - -#[component] -fn App(cx: Scope) -> Element { - use_shared_state_provider::(cx, Default::default); - - render! { - link { - rel: "stylesheet", - href: "https://unpkg.com/purecss@2.0.6/build/pure-min.css", - integrity: "sha384-Uu6IeWbM+gzNVXJcM9XV3SohHtmWE+3VGi496jvgX1jyvDTXfdK+rfZc8C1Aehk5", - crossorigin: "anonymous" - } - - style { - " - .red {{ - background-color: rgb(202, 60, 60) !important; - }} - " - } - - h1 { "Dioxus CRM Example" } - - Router:: {} - } + Settings, } #[component] -fn ClientList(cx: Scope) -> Element { - let clients = use_shared_state::(cx).unwrap(); - - cx.render(rsx! { +fn ClientList() -> Element { + rsx! { h2 { "List of Clients" } - - Link { to: Route::ClientAdd {}, class: "pure-button pure-button-primary", "Add Client" } - Link { to: Route::Settings {}, class: "pure-button", "Settings" } - - for client in clients.read().iter() { - div { - class: "client", - style: "margin-bottom: 50px", - + Link { to: Route::ClientAdd, class: "pure-button pure-button-primary", "Add Client" } + Link { to: Route::Settings, class: "pure-button", "Settings" } + for client in CLIENTS.read().iter() { + div { class: "client", style: "margin-bottom: 50px", p { "Name: {client.first_name} {client.last_name}" } p { "Description: {client.description}" } } } - }) + } } #[component] -fn ClientAdd(cx: Scope) -> Element { - let clients = use_shared_state::(cx).unwrap(); - let first_name = use_state(cx, String::new); - let last_name = use_state(cx, String::new); - let description = use_state(cx, String::new); +fn ClientAdd() -> Element { + let mut first_name = use_signal(String::new); + let mut last_name = use_signal(String::new); + let mut description = use_signal(String::new); - cx.render(rsx! { + let submit_client = move |_: FormEvent| { + // Write the client + CLIENTS.write().push(Client { + first_name: first_name(), + last_name: last_name(), + description: description(), + }); + + // And then navigate back to the client list + dioxus::router::router().push(Route::ClientList); + }; + + rsx! { h2 { "Add new Client" } - - form { - class: "pure-form pure-form-aligned", - onsubmit: move |_| { - let mut clients = clients.write(); - clients - .push(Client { - first_name: first_name.to_string(), - last_name: last_name.to_string(), - description: description.to_string(), - }); - dioxus_router::router().push(Route::ClientList {}); - }, - + form { class: "pure-form pure-form-aligned", onsubmit: submit_client, fieldset { div { class: "pure-control-group", - label { "for": "first_name", "First Name" } + label { r#for: "first_name", "First Name" } input { id: "first_name", - "type": "text", + r#type: "text", placeholder: "First Name…", required: "", value: "{first_name}", - oninput: move |e| first_name.set(e.value()) + oninput: move |e| first_name.set(e.value()), + + // when the form mounts, focus the first name input + onmounted: move |e| async move { + _ = e.set_focus(true).await; + }, } } @@ -114,7 +102,7 @@ fn ClientAdd(cx: Scope) -> Element { label { "for": "last_name", "Last Name" } input { id: "last_name", - "type": "text", + r#type: "text", placeholder: "Last Name…", required: "", value: "{last_name}", @@ -133,30 +121,26 @@ fn ClientAdd(cx: Scope) -> Element { } div { class: "pure-controls", - button { "type": "submit", class: "pure-button pure-button-primary", "Save" } - Link { to: Route::ClientList {}, class: "pure-button pure-button-primary red", "Cancel" } + button { r#type: "submit", class: "pure-button pure-button-primary", "Save" } + Link { to: Route::ClientList, class: "pure-button pure-button-primary red", "Cancel" } } } } - }) + } } #[component] -fn Settings(cx: Scope) -> Element { - let clients = use_shared_state::(cx).unwrap(); - - cx.render(rsx! { +fn Settings() -> Element { + rsx! { h2 { "Settings" } - button { class: "pure-button pure-button-primary red", onclick: move |_| { - let mut clients = clients.write(); - clients.clear(); + CLIENTS.write().clear(); + dioxus::router::router().push(Route::ClientList); }, "Remove all Clients" } - - Link { to: Route::ClientList {}, class: "pure-button", "Go back" } - }) + Link { to: Route::ClientList, class: "pure-button", "Go back" } + } } diff --git a/examples/custom_assets.rs b/examples/custom_assets.rs index 9f46df924..54ed831d5 100644 --- a/examples/custom_assets.rs +++ b/examples/custom_assets.rs @@ -1,16 +1,21 @@ use dioxus::prelude::*; +#[cfg(not(feature = "collect-assets"))] +static ASSET_PATH: &str = "examples/assets/logo.png"; + +#[cfg(feature = "collect-assets")] +static ASSET_PATH: &str = + manganis::mg!(image("examples/assets/logo.png").format(ImageType::Avif)).path(); + fn main() { - dioxus_desktop::launch(app); + launch(app); } -fn app(cx: Scope) -> Element { - cx.render(rsx! { +fn app() -> Element { + rsx! { div { - p { - "This should show an image:" - } - img { src: manganis::mg!(image("examples/assets/logo.png").format(ImageType::Avif)).to_string() } + p { "This should show an image:" } + img { src: ASSET_PATH.to_string() } } - }) + } } diff --git a/examples/custom_html.rs b/examples/custom_html.rs index a73394de1..37d1f3808 100644 --- a/examples/custom_html.rs +++ b/examples/custom_html.rs @@ -1,19 +1,20 @@ //! This example shows how to use a custom index.html and custom extensions //! to add things like stylesheets, scripts, and third-party JS libraries. +use dioxus::desktop::Config; use dioxus::prelude::*; -use dioxus_desktop::Config; fn main() { - dioxus_desktop::launch_cfg( - app, - Config::new().with_custom_head("".into()), - ); + LaunchBuilder::desktop() + .with_cfg( + Config::new().with_custom_head("".into()), + ) + .launch(app); - dioxus_desktop::launch_cfg( - app, - Config::new().with_custom_index( - r#" + LaunchBuilder::desktop() + .with_cfg( + Config::new().with_custom_index( + r#" @@ -26,15 +27,14 @@ fn main() { "# - .into(), - ), - ); + .into(), + ), + ) + .launch(app); } -fn app(cx: Scope) -> Element { - cx.render(rsx! { - div { - h1 {"hello world!"} - } - }) +fn app() -> Element { + rsx! { + div { h1 { "hello world!" } } + } } diff --git a/examples/disabled.rs b/examples/disabled.rs index 5be75b8b4..c7288f352 100644 --- a/examples/disabled.rs +++ b/examples/disabled.rs @@ -1,25 +1,21 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch(app); } -fn app(cx: Scope) -> Element { - let disabled = use_state(cx, || false); +fn app() -> Element { + let mut disabled = use_signal(|| false); - cx.render(rsx! { + rsx! { div { - button { - onclick: move |_| disabled.set(!disabled), + button { onclick: move |_| disabled.toggle(), "click to " - if disabled == true { "enable" } else { "disable" } + if disabled() { "enable" } else { "disable" } " the lower button" } - button { - disabled: "{disabled}", - "lower button" - } + button { disabled, "lower button" } } - }) + } } diff --git a/examples/dog_app.rs b/examples/dog_app.rs index 66a3c615c..4d3005f97 100644 --- a/examples/dog_app.rs +++ b/examples/dog_app.rs @@ -2,57 +2,49 @@ use dioxus::prelude::*; use std::collections::HashMap; fn main() { - dioxus_desktop::launch(|cx| render!(AppRoot {})); + launch(app); } -#[derive(Debug, Clone, PartialEq, serde::Deserialize)] -struct ListBreeds { - message: HashMap>, -} - -#[component] -fn AppRoot(cx: Scope<'_>) -> Element { - let breed = use_state(cx, || "deerhound".to_string()); - - let breeds = use_future!(cx, || async move { - reqwest::get("https://dog.ceo/api/breeds/list/all") +fn app() -> Element { + let mut breed = use_signal(|| "deerhound".to_string()); + let breed_list = use_resource(move || async move { + let list = reqwest::get("https://dog.ceo/api/breeds/list/all") .await .unwrap() .json::() - .await - }); + .await; - match breeds.value()? { - Ok(breed_list) => cx.render(rsx! { - div { height: "500px", - h1 { "Select a dog breed!" } - div { display: "flex", - ul { flex: "50%", - for cur_breed in breed_list.message.keys().take(10) { - li { key: "{cur_breed}", - button { - onclick: move |_| breed.set(cur_breed.clone()), - "{cur_breed}" - } - } - } + let Ok(breeds) = list else { + return rsx! { "error fetching breeds" }; + }; + + rsx! { + for cur_breed in breeds.message.keys().take(10).cloned() { + li { key: "{cur_breed}", + button { onclick: move |_| breed.set(cur_breed.clone()), + "{cur_breed}" } - div { flex: "50%", BreedPic { breed: breed.to_string() } } } } - }), - Err(_e) => cx.render(rsx! { div { "Error fetching breeds" } }), + } + }); + + let Some(breed_list) = breed_list() else { + return rsx! { "loading breeds..." }; + }; + + rsx! { + h1 { "Select a dog breed!" } + div { height: "500px", display: "flex", + ul { flex: "50%", {breed_list} } + div { flex: "50%", BreedPic { breed } } + } } } -#[derive(serde::Deserialize, Debug)] -struct DogApi { - message: String, -} - #[component] -fn BreedPic(cx: Scope, breed: String) -> Element { - let fut = use_future!(cx, |breed| async move { +fn BreedPic(breed: Signal) -> Element { + let mut fut = use_resource(move || async move { reqwest::get(format!("https://dog.ceo/api/breed/{breed}/images/random")) .await .unwrap() @@ -60,23 +52,22 @@ fn BreedPic(cx: Scope, breed: String) -> Element { .await }); - match fut.value()? { - Ok(resp) => render! { - div { - button { - onclick: move |_| { - println!("clicked"); - fut.restart() - }, - "Click to fetch another doggo" - } - img { - src: "{resp.message}", - max_width: "500px", - max_height: "500px", - } - } + match fut.read().as_ref() { + Some(Ok(resp)) => rsx! { + button { onclick: move |_| fut.restart(), "Click to fetch another doggo" } + img { max_width: "500px", max_height: "500px", src: "{resp.message}" } }, - Err(_) => render! { div { "loading dogs failed" } }, + Some(Err(_)) => rsx! { "loading image failed" }, + None => rsx! { "loading image..." }, } } + +#[derive(Debug, Clone, PartialEq, serde::Deserialize)] +struct ListBreeds { + message: HashMap>, +} + +#[derive(serde::Deserialize, Debug)] +struct DogApi { + message: String, +} diff --git a/examples/drops.rs b/examples/drops.rs deleted file mode 100644 index 6328a3f64..000000000 --- a/examples/drops.rs +++ /dev/null @@ -1,36 +0,0 @@ -use dioxus::prelude::*; - -fn main() { - dioxus_desktop::launch(app); -} - -fn app(cx: Scope) -> Element { - let count = if cx.generation() % 2 == 0 { 10 } else { 0 }; - - println!("Generation: {}", cx.generation()); - - if cx.generation() < 10 { - cx.needs_update(); - } - - render! { - for _ in 0..count { - drop_child {} - } - } -} - -fn drop_child(cx: Scope) -> Element { - cx.use_hook(|| Drops); - render! { - div{} - } -} - -struct Drops; - -impl Drop for Drops { - fn drop(&mut self) { - println!("Dropped!"); - } -} diff --git a/examples/dynamic_asset.rs b/examples/dynamic_asset.rs index ac2ad82c1..3f20c30e7 100644 --- a/examples/dynamic_asset.rs +++ b/examples/dynamic_asset.rs @@ -1,23 +1,21 @@ +use dioxus::desktop::{use_asset_handler, wry::http::Response}; use dioxus::prelude::*; -use dioxus_desktop::{use_asset_handler, wry::http::Response}; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - use_asset_handler(cx, "logos", |request, response| { - // Note that the "logos" prefix is stripped from the URI - // - // However, the asset is absolute to its "virtual folder" - meaning it starts with a leading slash - if request.uri().path() != "/logo.png" { +fn app() -> Element { + use_asset_handler("logos", |request, response| { + // We get the original path - make sure you handle that! + if request.uri().path() != "/logos/logo.png" { return; } response.respond(Response::new(include_bytes!("./assets/logo.png").to_vec())); }); - render! { + rsx! { div { img { src: "/logos/logo.png" } } diff --git a/examples/error_handle.rs b/examples/error_handle.rs index 5461032fd..02410629c 100644 --- a/examples/error_handle.rs +++ b/examples/error_handle.rs @@ -1,28 +1,25 @@ -use dioxus::{core::CapturedError, prelude::*}; +use dioxus::{dioxus_core::CapturedError, prelude::*}; fn main() { - dioxus_desktop::launch(App); + launch_desktop(app); } -#[component] -fn App(cx: Scope) -> Element { - cx.render(rsx! { +fn app() -> Element { + rsx! { ErrorBoundary { handle_error: |error: CapturedError| rsx! {"Found error {error}"}, - DemoC { - x: 1 - } + DemoC { x: 1 } } - }) + } } #[component] -fn DemoC(cx: Scope, x: i32) -> Element { +fn DemoC(x: i32) -> Element { let result = Err("Error"); result.throw()?; - render! { + rsx! { h1 { "{x}" } } } diff --git a/examples/eval.rs b/examples/eval.rs index 65c8acbeb..99d701022 100644 --- a/examples/eval.rs +++ b/examples/eval.rs @@ -1,12 +1,12 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch(app); } -fn app(cx: Scope) -> Element { - let future = use_future(cx, (), |_| async move { - let eval = eval( +fn app() -> Element { + let future = use_resource(move || async move { + let mut eval = eval( r#" dioxus.send("Hi from JS!"); let msg = await dioxus.recv(); @@ -22,12 +22,8 @@ fn app(cx: Scope) -> Element { res }); - match future.value() { - Some(v) => cx.render(rsx!( - p { "{v}" } - )), - _ => cx.render(rsx!( - p { "hello" } - )), + match future.value().as_ref() { + Some(v) => rsx!( p { "{v}" } ), + _ => rsx!( p { "waiting.." } ), } } diff --git a/examples/fermi.rs b/examples/fermi.rs deleted file mode 100644 index 3250471a4..000000000 --- a/examples/fermi.rs +++ /dev/null @@ -1,57 +0,0 @@ -#![allow(non_snake_case)] - -use dioxus::prelude::*; -use fermi::*; - -fn main() { - dioxus_desktop::launch(app) -} - -static NAME: Atom = Atom(|_| "world".to_string()); - -fn app(cx: Scope) -> Element { - use_init_atom_root(cx); - let name = use_read(cx, &NAME); - - cx.render(rsx! { - div { "hello {name}!" } - Child {} - ChildWithRef {} - }) -} - -fn Child(cx: Scope) -> Element { - let set_name = use_set(cx, &NAME); - - cx.render(rsx! { - button { - onclick: move |_| set_name("dioxus".to_string()), - "reset name" - } - }) -} - -static NAMES: AtomRef> = AtomRef(|_| vec!["world".to_string()]); - -fn ChildWithRef(cx: Scope) -> Element { - let names = use_atom_ref(cx, &NAMES); - - cx.render(rsx! { - div { - ul { - for name in names.read().iter() { - li { "hello: {name}" } - } - } - button { - onclick: move |_| { - let names = names.clone(); - cx.spawn(async move { - names.write().push("asd".to_string()); - }) - }, - "Add name" - } - } - }) -} diff --git a/examples/file_explorer.rs b/examples/file_explorer.rs index ea89fab77..958aec9ac 100644 --- a/examples/file_explorer.rs +++ b/examples/file_explorer.rs @@ -8,30 +8,34 @@ //! It also uses `use_ref` to maintain a model, rather than `use_state`. That way, //! we dont need to clutter our code with `read` commands. +use dioxus::desktop::{Config, WindowBuilder}; use dioxus::prelude::*; -use dioxus_desktop::{Config, WindowBuilder}; fn main() { - dioxus_desktop::launch_cfg( - app, - Config::new().with_window(WindowBuilder::new().with_resizable(true)), - ); + LaunchBuilder::desktop() + .with_cfg(Config::new().with_window(WindowBuilder::new().with_resizable(true))) + .launch(app) } +#[cfg(not(feature = "collect-assets"))] +const _STYLE: &str = include_str!("../examples/assets/fileexplorer.css"); + +#[cfg(feature = "collect-assets")] const _STYLE: &str = manganis::mg!(file("./examples/assets/fileexplorer.css")); -fn app(cx: Scope) -> Element { - let files = use_ref(cx, Files::new); +fn app() -> Element { + let mut files = use_signal(Files::new); - cx.render(rsx! { + rsx! { div { - link { href:"https://fonts.googleapis.com/icon?family=Material+Icons", rel:"stylesheet", } + link { href:"https://fonts.googleapis.com/icon?family=Material+Icons", rel:"stylesheet" } header { i { class: "material-icons icon-menu", "menu" } h1 { "Files: ", {files.read().current()} } span { } i { class: "material-icons", onclick: move |_| files.write().go_up(), "logout" } } + style { "{_STYLE}" } main { {files.read().path_names.iter().enumerate().map(|(dir_id, path)| { let path_end = path.split('/').last().unwrap_or(path.as_str()); @@ -60,7 +64,7 @@ fn app(cx: Scope) -> Element { } } } - }) + } } struct Files { diff --git a/examples/file_upload.rs b/examples/file_upload.rs index b78a5b343..c98221c16 100644 --- a/examples/file_upload.rs +++ b/examples/file_upload.rs @@ -4,21 +4,38 @@ use dioxus::prelude::*; use tokio::time::sleep; fn main() { - dioxus_desktop::launch(App); + launch(App); } -fn App(cx: Scope) -> Element { - let enable_directory_upload = use_state(cx, || false); - let files_uploaded: &UseRef> = use_ref(cx, Vec::new); +fn App() -> Element { + let mut enable_directory_upload = use_signal(|| false); + let mut files_uploaded = use_signal(|| Vec::new() as Vec); - cx.render(rsx! { + let upload_files = move |evt: FormEvent| async move { + for file_name in evt.files().unwrap().files() { + // no files on form inputs? + sleep(std::time::Duration::from_secs(1)).await; + files_uploaded.write().push(file_name); + } + }; + + let handle_file_drop = move |evt: DragEvent| async move { + if let Some(file_engine) = &evt.files() { + let files = file_engine.files(); + for file_name in &files { + if let Some(file) = file_engine.read_file_to_string(file_name).await { + files_uploaded.write().push(file); + } + } + } + }; + + rsx! { label { input { r#type: "checkbox", - checked: "{enable_directory_upload}", - oninput: move |evt| { - enable_directory_upload.set(evt.value().parse().unwrap()); - }, + checked: enable_directory_upload, + oninput: move |evt| enable_directory_upload.set(evt.checked()), }, "Enable directory upload" } @@ -27,41 +44,16 @@ fn App(cx: Scope) -> Element { r#type: "file", accept: ".txt,.rs", multiple: true, - directory: **enable_directory_upload, - onchange: |evt| { - to_owned![files_uploaded]; - async move { - if let Some(file_engine) = &evt.files() { - let files = file_engine.files(); - for file_name in files { - sleep(std::time::Duration::from_secs(1)).await; - files_uploaded.write().push(file_name); - } - } - } - }, + directory: enable_directory_upload, + onchange: upload_files, } div { width: "100px", height: "100px", border: "1px solid black", prevent_default: "ondrop dragover dragenter", - ondrop: move |evt| { - to_owned![files_uploaded]; - async move { - if let Some(file_engine) = &evt.files() { - let files = file_engine.files(); - for file_name in &files { - if let Some(file) = file_engine.read_file_to_string(file_name).await{ - files_uploaded.write().push(file); - } - } - } - } - }, - ondragover: move |event: DragEvent| { - event.stop_propagation(); - }, + ondrop: handle_file_drop, + ondragover: move |event| event.stop_propagation(), "Drop files here" } @@ -70,5 +62,5 @@ fn App(cx: Scope) -> Element { li { "{file}" } } } - }) + } } diff --git a/examples/filedragdrop.rs b/examples/filedragdrop.rs index f5b760493..cf4f1742a 100644 --- a/examples/filedragdrop.rs +++ b/examples/filedragdrop.rs @@ -1,19 +1,17 @@ +use dioxus::desktop::Config; use dioxus::prelude::*; -use dioxus_desktop::Config; fn main() { - let cfg = Config::new().with_file_drop_handler(|_w, e| { - println!("{e:?}"); - true - }); - - dioxus_desktop::launch_with_props(app, (), cfg); + LaunchBuilder::desktop() + .with_cfg(Config::new().with_file_drop_handler(|_w, e| { + println!("{e:?}"); + true + })) + .launch(app) } -fn app(cx: Scope) -> Element { - cx.render(rsx!( - div { - h1 { "drag a file here and check your console" } - } - )) +fn app() -> Element { + rsx!( + div { h1 { "drag a file here and check your console" } } + ) } diff --git a/examples/flat_router.rs b/examples/flat_router.rs index ec6e2f417..a981e4fb0 100644 --- a/examples/flat_router.rs +++ b/examples/flat_router.rs @@ -1,24 +1,11 @@ use dioxus::prelude::*; -use dioxus_desktop::{tao::dpi::LogicalSize, Config, WindowBuilder}; -use dioxus_router::prelude::*; fn main() { - env_logger::init(); - - let cfg = Config::new().with_window( - WindowBuilder::new() - .with_inner_size(LogicalSize::new(600, 1000)) - .with_resizable(false), - ); - - dioxus_desktop::launch_cfg(App, cfg) -} - -#[component] -fn App(cx: Scope) -> Element { - render! { - Router:: {} - } + launch(|| { + rsx! { + Router:: {} + } + }) } #[derive(Routable, Clone)] @@ -27,52 +14,59 @@ enum Route { #[layout(Footer)] #[route("/")] Home {}, + #[route("/games")] Games {}, + #[route("/play")] Play {}, + #[route("/settings")] Settings {}, } #[component] -fn Footer(cx: Scope) -> Element { - render! { - div { - Outlet:: { } - - p { - "----" - } - - nav { - ul { - li { Link { to: Route::Home {}, "Home" } } - li { Link { to: Route::Games {}, "Games" } } - li { Link { to: Route::Play {}, "Play" } } - li { Link { to: Route::Settings {}, "Settings" } } - } - } +fn Footer() -> Element { + rsx! { + Outlet:: {} + p { "----" } + nav { + style { {STYLE} } + Link { to: Route::Home {}, class: "nav-btn", "Home" } + Link { to: Route::Games {}, class: "nav-btn", "Games" } + Link { to: Route::Play {}, class: "nav-btn", "Play" } + Link { to: Route::Settings {}, class: "nav-btn", "Settings" } } } } #[component] -fn Home(cx: Scope) -> Element { - render!("Home") +fn Home() -> Element { + rsx!("Home") } #[component] -fn Games(cx: Scope) -> Element { - render!("Games") +fn Games() -> Element { + rsx!("Games") } #[component] -fn Play(cx: Scope) -> Element { - render!("Play") +fn Play() -> Element { + rsx!("Play") } #[component] -fn Settings(cx: Scope) -> Element { - render!("Settings") +fn Settings() -> Element { + rsx!("Settings") } + +const STYLE: &str = r#" + nav { + display: flex; + justify-content: space-around; + } + .nav-btn { + text-decoration: none; + color: black; + } +"#; diff --git a/examples/form.rs b/examples/form.rs index 897ffc710..897587daa 100644 --- a/examples/form.rs +++ b/examples/form.rs @@ -6,11 +6,11 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - cx.render(rsx! { +fn app() -> Element { + rsx! { div { h1 { "Form" } form { @@ -24,5 +24,5 @@ fn app(cx: Scope) -> Element { button { r#type: "submit", value: "Submit", "Submit the form" } } } - }) + } } diff --git a/examples/framework_benchmark.rs b/examples/framework_benchmark.rs deleted file mode 100644 index 3e286332b..000000000 --- a/examples/framework_benchmark.rs +++ /dev/null @@ -1,152 +0,0 @@ -#![allow(non_snake_case)] - -use dioxus::prelude::*; -use rand::prelude::*; - -fn main() { - dioxus_desktop::launch(app); -} - -#[derive(Clone, PartialEq)] -struct Label { - key: usize, - labels: [&'static str; 3], -} - -impl Label { - fn new_list(num: usize) -> Vec { - let mut rng = SmallRng::from_entropy(); - let mut labels = Vec::with_capacity(num); - for x in 0..num { - labels.push(Label { - key: x, - labels: [ - ADJECTIVES.choose(&mut rng).unwrap(), - COLOURS.choose(&mut rng).unwrap(), - NOUNS.choose(&mut rng).unwrap(), - ], - }); - } - labels - } -} - -fn app(cx: Scope) -> Element { - let items = use_ref(cx, Vec::new); - let selected = use_state(cx, || None); - - cx.render(rsx! { - div { class: "container", - div { class: "jumbotron", - div { class: "row", - div { class: "col-md-6", h1 { "Dioxus" } } - div { class: "col-md-6", - div { class: "row", - ActionButton { name: "Create 1,000 rows", id: "run", - onclick: move |_| items.set(Label::new_list(1_000)), - } - ActionButton { name: "Create 10,000 rows", id: "runlots", - onclick: move |_| items.set(Label::new_list(10_000)), - } - ActionButton { name: "Append 1,000 rows", id: "add", - onclick: move |_| items.write().extend(Label::new_list(1_000)), - } - ActionButton { name: "Update every 10th row", id: "update", - onclick: move |_| items.write().iter_mut().step_by(10).for_each(|item| item.labels[2] = "!!!"), - } - ActionButton { name: "Clear", id: "clear", - onclick: move |_| items.write().clear(), - } - ActionButton { name: "Swap rows", id: "swaprows", - onclick: move |_| items.write().swap(0, 998), - } - } - } - } - } - table { - tbody { - for (id, item) in items.read().iter().enumerate() { - tr { - class: if (*selected).map(|s| s == id).unwrap_or(false) { "danger" }, - td { class:"col-md-1" } - td { class:"col-md-1", "{item.key}" } - td { class:"col-md-1", onclick: move |_| selected.set(Some(id)), - a { class: "lbl", "{item.labels[0]}{item.labels[1]}{item.labels[2]}" } - } - td { class: "col-md-1", - a { class: "remove", onclick: move |_| { items.write().remove(id); }, - span { class: "glyphicon glyphicon-remove remove", aria_hidden: "true" } - } - } - td { class: "col-md-6" } - } - } - - } - } - span { class: "preloadicon glyphicon glyphicon-remove", aria_hidden: "true" } - } - }) -} - -#[derive(Props)] -struct ActionButtonProps<'a> { - name: &'a str, - id: &'a str, - onclick: EventHandler<'a>, -} - -fn ActionButton<'a>(cx: Scope<'a, ActionButtonProps<'a>>) -> Element { - cx.render(rsx! { - div { - class: "col-sm-6 smallpad", - button { - class:"btn btn-primary btn-block", - r#type: "button", - id: "{cx.props.id}", - onclick: move |_| cx.props.onclick.call(()), - - "{cx.props.name}" - } - } - }) -} - -static ADJECTIVES: &[&str] = &[ - "pretty", - "large", - "big", - "small", - "tall", - "short", - "long", - "handsome", - "plain", - "quaint", - "clean", - "elegant", - "easy", - "angry", - "crazy", - "helpful", - "mushy", - "odd", - "unsightly", - "adorable", - "important", - "inexpensive", - "cheap", - "expensive", - "fancy", -]; - -static COLOURS: &[&str] = &[ - "red", "yellow", "blue", "green", "pink", "brown", "purple", "brown", "white", "black", - "orange", -]; - -static NOUNS: &[&str] = &[ - "table", "chair", "house", "bbq", "desk", "car", "pony", "cookie", "sandwich", "burger", - "pizza", "mouse", "keyboard", -]; diff --git a/examples/generic_component.rs b/examples/generic_component.rs index ec8eeb660..06513aa02 100644 --- a/examples/generic_component.rs +++ b/examples/generic_component.rs @@ -3,22 +3,22 @@ use std::fmt::Display; use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - render! { +fn app() -> Element { + rsx! { generic_child { data: 0 } } } -#[derive(PartialEq, Props)] -struct GenericChildProps { +#[derive(PartialEq, Props, Clone)] +struct GenericChildProps { data: T, } -fn generic_child(cx: Scope>) -> Element { - render! { - div { "{&cx.props.data}" } +fn generic_child(props: GenericChildProps) -> Element { + rsx! { + div { "{props.data}" } } } diff --git a/examples/global.rs b/examples/global.rs new file mode 100644 index 000000000..f3659845c --- /dev/null +++ b/examples/global.rs @@ -0,0 +1,20 @@ +//! Example: README.md showcase +//! +//! The example from the README.md. + +use dioxus::prelude::*; + +fn main() { + launch(app); +} + +static COUNT: GlobalSignal = Signal::global(|| 0); +static DOUBLED_COUNT: GlobalMemo = Signal::global_memo(|| COUNT() * 2); + +fn app() -> Element { + rsx! { + h1 { "{COUNT} x 2 = {DOUBLED_COUNT}" } + button { onclick: move |_| *COUNT.write() += 1, "Up high!" } + button { onclick: move |_| *COUNT.write() -= 1, "Down low!" } + } +} diff --git a/examples/heavy_compute.rs b/examples/heavy_compute.rs deleted file mode 100644 index 641037211..000000000 --- a/examples/heavy_compute.rs +++ /dev/null @@ -1,28 +0,0 @@ -//! This example shows that you can place heavy work on the main thread, and then -//! -//! You *should* be using `tokio::spawn_blocking` instead. -//! -//! Your app runs in an async runtime (Tokio), so you should avoid blocking -//! the rendering of the VirtualDom. -//! -//! - -use dioxus::prelude::*; - -fn main() { - dioxus_desktop::launch(app); -} - -fn app(cx: Scope) -> Element { - // This is discouraged - std::thread::sleep(std::time::Duration::from_millis(2_000)); - - // This is suggested - tokio::task::spawn_blocking(move || { - std::thread::sleep(std::time::Duration::from_millis(2_000)); - }); - - cx.render(rsx! { - div { "Hello, world!" } - }) -} diff --git a/examples/hello_world.rs b/examples/hello_world.rs index 52d9e9886..da046a634 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -1,11 +1,11 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch(app); } -fn app(cx: Scope) -> Element { - render! { +fn app() -> Element { + rsx! { div { "Hello, world!" } } } diff --git a/examples/hydration.rs b/examples/hydration.rs index 88b32bb11..1e7de2706 100644 --- a/examples/hydration.rs +++ b/examples/hydration.rs @@ -9,27 +9,28 @@ //! In this example, we pre-render the page to HTML and then pass it into the desktop configuration. This serves as a //! proof-of-concept for the hydration feature, but you'll probably only want to use hydration for the web. +use dioxus::desktop::Config; use dioxus::prelude::*; -use dioxus_desktop::Config; fn main() { - let mut vdom = VirtualDom::new(app); - let _ = vdom.rebuild(); - let content = dioxus_ssr::pre_render(&vdom); + LaunchBuilder::desktop() + .with_cfg(Config::new().with_prerendered({ + // We build the dom a first time, then pre-render it to HTML + let pre_rendered_dom = VirtualDom::prebuilt(app); - dioxus_desktop::launch_cfg(app, Config::new().with_prerendered(content)); + // We then launch the app with the pre-rendered HTML + dioxus_ssr::pre_render(&pre_rendered_dom) + })) + .launch(app) } -fn app(cx: Scope) -> Element { - let val = use_state(cx, || 0); +fn app() -> Element { + let mut val = use_signal(|| 0); - cx.render(rsx! { + rsx! { div { h1 { "hello world. Count: {val}" } - button { - onclick: move |_| *val.make_mut() += 1, - "click to increment" - } + button { onclick: move |_| val += 1, "click to increment" } } - }) + } } diff --git a/examples/inlineprops.rs b/examples/inlineprops.rs deleted file mode 100644 index 6d5534064..000000000 --- a/examples/inlineprops.rs +++ /dev/null @@ -1,43 +0,0 @@ -//! Run with `cargo-expand` to see what each one expands to. -//! This file is named `inlineprops.rs`, because there used to be a `#[inline_props]` macro to -//! do this. However, it's now deprecated (and will likely be removed in a future major version), -//! so please use `#[component]` instead! -use dioxus::prelude::*; - -#[component] -fn Thing1(cx: Scope, _a: T) -> Element { - cx.render(rsx! { "" }) -} - -#[component] -fn Thing2(cx: Scope, _a: u32) -> Element<'a> { - cx.render(rsx! { "" }) -} - -#[component] -fn Thing3<'a, T>(cx: Scope<'a>, _a: &'a T) -> Element<'a> { - cx.render(rsx! { "" }) -} - -#[component] -fn Thing4<'a>(cx: Scope<'a>, _a: &'a u32) -> Element<'a> { - cx.render(rsx! { "" }) -} - -fn main() { - dioxus_desktop::launch(App); -} - -#[component] -fn App(cx: Scope) -> Element { - let state = use_state(cx, || 1); - - cx.render(rsx! { - div { - Thing1 { _a: 1 }, - Thing2 { _a: 1 }, - Thing3 { _a: state }, - Thing4 { _a: state }, - } - }) -} diff --git a/examples/inputs.rs b/examples/inputs.rs index 00fc279ed..66d4fe696 100644 --- a/examples/inputs.rs +++ b/examples/inputs.rs @@ -5,7 +5,7 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } const FIELDS: &[(&str, &str)] = &[ @@ -34,23 +34,21 @@ const FIELDS: &[(&str, &str)] = &[ ("week", ""), // degrades to text most of the time ]; -fn app(cx: Scope) -> Element { - cx.render(rsx! { +fn app() -> Element { + rsx! { div { margin_left: "30px", - {select_example(cx)}, + {select_example()}, div { // handling inputs on divs will catch all input events below // so the value of our input event will be either huey, dewey, louie, or true/false (because of the checkboxe) // be mindful in grouping inputs together, as they will all be handled by the same event handler - oninput: move |evt| { - println!("{evt:?}"); - }, + oninput: move |evt| println!("{evt:?}"), div { input { id: "huey", r#type: "radio", value: "huey", - checked: "", + checked: true, name: "drone", } label { @@ -65,10 +63,7 @@ fn app(cx: Scope) -> Element { value: "dewey", name: "drone", } - label { - r#for: "dewey", - "Dewey" - } + label { r#for: "dewey", "Dewey" } } div { input { @@ -133,36 +128,35 @@ fn app(cx: Scope) -> Element { } } } - }) + } } -fn select_example(cx: Scope) -> Element { - cx.render(rsx! { - div { - select { - id: "selection", - name: "selection", - multiple: true, - oninput: move |evt| { - println!("{evt:?}"); - }, - option { - value : "Option 1", - label : "Option 1", +fn select_example() -> Element { + rsx! { + div { + select { + id: "selection", + name: "selection", + multiple: true, + oninput: move |evt| println!("{evt:?}"), + option { + value: "Option 1", + label: "Option 1", + } + option { + value: "Option 2", + label: "Option 2", + selected: true, + }, + option { + value: "Option 3", + label: "Option 3", + } } - option { - value : "Option 2", - label : "Option 2", - selected : true, - }, - option { - value : "Option 3", - label : "Option 3", + label { + r#for: "selection", + "select element" } } - label { - r#for: "selection", - "select element" - } - }}) + } } diff --git a/examples/link.rs b/examples/link.rs index 726fe3d79..f11408c2e 100644 --- a/examples/link.rs +++ b/examples/link.rs @@ -1,30 +1,25 @@ use dioxus::prelude::*; -use dioxus_router::prelude::*; fn main() { - dioxus_desktop::launch(App); + launch_desktop(App); } #[component] -fn App(cx: Scope) -> Element { - cx.render(rsx! ( +fn App() -> Element { + rsx! ( div { - p { - a { href: "http://dioxuslabs.com/", "Default link - links outside of your app" } - } + p { a { href: "http://dioxuslabs.com/", "Default link - links outside of your app" } } p { a { href: "http://dioxuslabs.com/", prevent_default: "onclick", onclick: |_| println!("Hello Dioxus"), - "Custom event link - links inside of your app", + "Custom event link - links inside of your app" } } } - div { - Router:: {} - } - )) + div { Router:: {} } + ) } #[derive(Routable, Clone)] @@ -38,23 +33,27 @@ enum Route { } #[component] -fn Header(cx: Scope) -> Element { - render! { +fn Header() -> Element { + rsx! { h1 { "Your app here" } ul { - li { Link { to: Route::Home {}, "home" } } - li { Link { to: Route::Settings {}, "settings" } } + li { + Link { to: Route::Home {}, "home" } + } + li { + Link { to: Route::Settings {}, "settings" } + } } Outlet:: {} } } #[component] -fn Home(cx: Scope) -> Element { - render!(h1 { "Home" }) +fn Home() -> Element { + rsx!( h1 { "Home" } ) } #[component] -fn Settings(cx: Scope) -> Element { - render!(h1 { "Settings" }) +fn Settings() -> Element { + rsx!( h1 { "Settings" } ) } diff --git a/examples/login_form.rs b/examples/login_form.rs index 3e8220aef..220472886 100644 --- a/examples/login_form.rs +++ b/examples/login_form.rs @@ -4,10 +4,10 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { +fn app() -> Element { let onsubmit = move |evt: FormEvent| async move { let resp = reqwest::Client::new() .post("http://localhost:8080/login") @@ -29,9 +29,9 @@ fn app(cx: Scope) -> Element { } }; - cx.render(rsx! { + rsx! { h1 { "Login" } - form { onsubmit: onsubmit, + form { onsubmit, input { r#type: "text", id: "username", name: "username" } label { "Username" } br {} @@ -40,5 +40,5 @@ fn app(cx: Scope) -> Element { br {} button { "Login" } } - }) + } } diff --git a/examples/memo_chain.rs b/examples/memo_chain.rs new file mode 100644 index 000000000..56c3aad71 --- /dev/null +++ b/examples/memo_chain.rs @@ -0,0 +1,44 @@ +use dioxus::prelude::*; + +fn main() { + launch_desktop(app); +} + +fn app() -> Element { + let mut value = use_signal(|| 0); + let mut depth = use_signal(|| 0_usize); + let items = use_memo(move || (0..depth()).map(|f| f as _).collect::>()); + let state = use_memo(move || value() + 1); + + println!("rendering app"); + + rsx! { + button { onclick: move |_| value += 1, "Increment" } + button { onclick: move |_| depth += 1, "Add depth" } + button { onclick: move |_| depth -= 1, "Remove depth" } + Child { depth, items, state } + } +} + +#[component] +fn Child( + state: ReadOnlySignal, + items: ReadOnlySignal>, + depth: ReadOnlySignal, +) -> Element { + if depth() == 0 { + return None; + } + + // These memos don't get re-computed when early returns happen + let state = use_memo(move || state() + 1); + let item = use_memo(move || items()[depth()]); + let depth = use_memo(move || depth() - 1); + + println!("rendering child: {}", depth()); + + rsx! { + h3 { "Depth({depth})-Item({item}): {state}"} + Child { depth, state, items } + } +} diff --git a/examples/mobile_demo/Cargo.toml b/examples/mobile_demo/Cargo.toml index e980774e7..a3219c015 100644 --- a/examples/mobile_demo/Cargo.toml +++ b/examples/mobile_demo/Cargo.toml @@ -2,7 +2,7 @@ name = "mobile-demo" version = "0.1.0" authors = ["Jonathan Kelley "] -edition = "2018" +edition = "2021" [lib] crate-type = ["staticlib", "cdylib", "rlib"] diff --git a/examples/mobile_demo/src/lib.rs b/examples/mobile_demo/src/lib.rs index 992c53541..c6b4e8f7e 100644 --- a/examples/mobile_demo/src/lib.rs +++ b/examples/mobile_demo/src/lib.rs @@ -1,6 +1,6 @@ use anyhow::Result; +use dioxus::desktop::Config; use dioxus::prelude::*; -use dioxus_desktop::Config; #[cfg(target_os = "android")] use wry::android_binding; @@ -49,8 +49,7 @@ pub fn main() -> Result<()> { // Right now we're going through dioxus-desktop but we'd like to go through dioxus-mobile // That will seed the index.html with some fixes that prevent the page from scrolling/zooming etc - dioxus_desktop::launch_cfg( - app, + LaunchBuilder::new().cfg( // Note that we have to disable the viewport goofiness of the browser. // Dioxus_mobile should do this for us Config::default().with_custom_index(include_str!("index.html").to_string()), @@ -59,17 +58,22 @@ pub fn main() -> Result<()> { Ok(()) } -fn app(cx: Scope) -> Element { +fn app() -> Element { let items = cx.use_hook(|| vec![1, 2, 3]); log::debug!("Hello from the app"); - render! { + rsx! { div { - h1 { "Hello, Mobile"} - div { margin_left: "auto", margin_right: "auto", width: "200px", padding: "10px", border: "1px solid black", + h1 { "Hello, Mobile" } + div { + margin_left: "auto", + margin_right: "auto", + width: "200px", + padding: "10px", + border: "1px solid black", button { - onclick: move|_| { + onclick: move |_| { println!("Clicked!"); items.push(items.len()); cx.needs_update_any(ScopeId::ROOT); diff --git a/examples/multiwindow.rs b/examples/multiwindow.rs index c7ad2c603..974e024d7 100644 --- a/examples/multiwindow.rs +++ b/examples/multiwindow.rs @@ -1,25 +1,22 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - cx.render(rsx! { - div { - button { - onclick: move |_| { - let dom = VirtualDom::new(popup); - dioxus_desktop::window().new_window(dom, Default::default()); - }, - "New Window" - } - } - }) +fn app() -> Element { + let onclick = move |_| { + let dom = VirtualDom::new(popup); + dioxus::desktop::window().new_window(dom, Default::default()); + }; + + rsx! { + button { onclick, "New Window" } + } } -fn popup(cx: Scope) -> Element { - cx.render(rsx! { - div { "This is a popup!" } - }) +fn popup() -> Element { + rsx! { + div { "This is a popup window!" } + } } diff --git a/examples/nested_listeners.rs b/examples/nested_listeners.rs index 4d68b281b..aaee9757e 100644 --- a/examples/nested_listeners.rs +++ b/examples/nested_listeners.rs @@ -7,11 +7,11 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch(app); } -fn app(cx: Scope) -> Element { - cx.render(rsx! { +fn app() -> Element { + rsx! { div { onclick: move |_| println!("clicked! top"), "- div" @@ -30,5 +30,5 @@ fn app(cx: Scope) -> Element { "Does not handle clicks - only propagate" } } - }) + } } diff --git a/examples/openid_connect_demo/src/main.rs b/examples/openid_connect_demo/src/main.rs index 7ed8db8a9..af5aad323 100644 --- a/examples/openid_connect_demo/src/main.rs +++ b/examples/openid_connect_demo/src/main.rs @@ -14,8 +14,6 @@ pub(crate) mod views; use oidc::{AuthRequestState, AuthTokenState}; use router::Route; -use dioxus_router::prelude::*; - use crate::{ constants::{DIOXUS_FRONT_AUTH_REQUEST, DIOXUS_FRONT_AUTH_TOKEN}, oidc::ClientState, @@ -30,14 +28,14 @@ pub static DIOXUS_FRONT_ISSUER_URL: &str = env!("DIOXUS_FRONT_ISSUER_URL"); pub static DIOXUS_FRONT_CLIENT_ID: &str = env!("DIOXUS_FRONT_CLIENT_ID"); pub static DIOXUS_FRONT_URL: &str = env!("DIOXUS_FRONT_URL"); -fn App(cx: Scope) -> Element { +fn App() -> Element { use_init_atom_root(cx); // Retrieve the value stored in the browser's storage let stored_auth_token = LocalStorage::get(DIOXUS_FRONT_AUTH_TOKEN) .ok() .unwrap_or(AuthTokenState::default()); - let fermi_auth_token = use_atom_ref(cx, &FERMI_AUTH_TOKEN); + let fermi_auth_token = use_atom_ref(&FERMI_AUTH_TOKEN); if fermi_auth_token.read().is_none() { *fermi_auth_token.write() = Some(stored_auth_token); } @@ -45,11 +43,11 @@ fn App(cx: Scope) -> Element { let stored_auth_request = LocalStorage::get(DIOXUS_FRONT_AUTH_REQUEST) .ok() .unwrap_or(AuthRequestState::default()); - let fermi_auth_request = use_atom_ref(cx, &FERMI_AUTH_REQUEST); + let fermi_auth_request = use_atom_ref(&FERMI_AUTH_REQUEST); if fermi_auth_request.read().is_none() { *fermi_auth_request.write() = Some(stored_auth_request); } - render! { Router:: {} } + rsx! { Router:: {} } } fn main() { diff --git a/examples/openid_connect_demo/src/router.rs b/examples/openid_connect_demo/src/router.rs index 0bb80afbb..8f4b1b36a 100644 --- a/examples/openid_connect_demo/src/router.rs +++ b/examples/openid_connect_demo/src/router.rs @@ -1,6 +1,5 @@ use crate::views::{header::AuthHeader, home::Home, login::Login, not_found::NotFound}; use dioxus::prelude::*; -use dioxus_router::prelude::*; #[derive(Routable, Clone)] pub enum Route { diff --git a/examples/openid_connect_demo/src/views/header.rs b/examples/openid_connect_demo/src/views/header.rs index b9b99e584..5c40cd674 100644 --- a/examples/openid_connect_demo/src/views/header.rs +++ b/examples/openid_connect_demo/src/views/header.rs @@ -9,15 +9,15 @@ use crate::{ FERMI_AUTH_REQUEST, FERMI_AUTH_TOKEN, FERMI_CLIENT, }; use dioxus::prelude::*; -use dioxus_router::prelude::{Link, Outlet}; +use dioxus::router::prelude::{Link, Outlet}; use fermi::*; use openidconnect::{url::Url, OAuth2TokenResponse, TokenResponse}; #[component] pub fn LogOut(cx: Scope) -> Element { - let fermi_auth_token = use_atom_ref(cx, &FERMI_AUTH_TOKEN); + let fermi_auth_token = use_atom_ref(&FERMI_AUTH_TOKEN); let fermi_auth_token_read = fermi_auth_token.read().clone(); - let log_out_url_state = use_state(cx, || None::>>); + let log_out_url_state = use_signal(|| None::>>); cx.render(match fermi_auth_token_read { Some(fermi_auth_token_read) => match fermi_auth_token_read.id_token.clone() { Some(id_token) => match log_out_url_state.get() { @@ -40,9 +40,7 @@ pub fn LogOut(cx: Scope) -> Element { } } Err(error) => { - rsx! { - div { "Failed to load disconnection url: {error:?}" } - } + rsx! { div { "Failed to load disconnection url: {error:?}" } } } }, None => { @@ -61,7 +59,7 @@ pub fn LogOut(cx: Scope) -> Element { }) }; logout_url_task(); - rsx! { div{"Loading log out url... Please wait"}} + rsx! { div { "Loading log out url... Please wait" } } } }, None => { @@ -76,8 +74,8 @@ pub fn LogOut(cx: Scope) -> Element { #[component] pub fn RefreshToken(cx: Scope) -> Element { - let fermi_auth_token = use_atom_ref(cx, &FERMI_AUTH_TOKEN); - let fermi_auth_request = use_atom_ref(cx, &FERMI_AUTH_REQUEST); + let fermi_auth_token = use_atom_ref(&FERMI_AUTH_TOKEN); + let fermi_auth_request = use_atom_ref(&FERMI_AUTH_REQUEST); let fermi_auth_token_read = fermi_auth_token.read().clone(); cx.render(match fermi_auth_token_read { Some(fermi_auth_client_read) => match fermi_auth_client_read.refresh_token { @@ -128,9 +126,9 @@ pub fn RefreshToken(cx: Scope) -> Element { } #[component] -pub fn LoadClient(cx: Scope) -> Element { - let init_client_future = use_future(cx, (), |_| async move { init_oidc_client().await }); - let fermi_client: &UseAtomRef = use_atom_ref(cx, &FERMI_CLIENT); +pub fn LoadClient() -> Element { + let init_client_future = use_future(move || async move { init_oidc_client().await }); + let fermi_client: &UseAtomRef = use_atom_ref(&FERMI_CLIENT); cx.render(match init_client_future.value() { Some(client_props) => match client_props { Ok((client_id, client)) => { @@ -162,10 +160,10 @@ pub fn LoadClient(cx: Scope) -> Element { } #[component] -pub fn AuthHeader(cx: Scope) -> Element { - let auth_token = use_atom_ref(cx, &FERMI_AUTH_TOKEN); - let fermi_auth_request = use_atom_ref(cx, &FERMI_AUTH_REQUEST); - let fermi_client: &UseAtomRef = use_atom_ref(cx, &FERMI_CLIENT); +pub fn AuthHeader() -> Element { + let auth_token = use_atom_ref(&FERMI_AUTH_TOKEN); + let fermi_auth_request = use_atom_ref(&FERMI_AUTH_REQUEST); + let fermi_client: &UseAtomRef = use_atom_ref(&FERMI_CLIENT); let client = fermi_client.read().oidc_client.clone(); let auth_request_read = fermi_auth_request.read().clone(); let auth_token_read = auth_token.read().clone(); @@ -197,7 +195,7 @@ pub fn AuthHeader(cx: Scope) -> Element { log::info!("Token expired"); rsx! { div { - RefreshToken {client_id: client_props.client_id, client: client_props.client} + RefreshToken { client_id: client_props.client_id, client: client_props.client } Outlet:: {} } } diff --git a/examples/openid_connect_demo/src/views/home.rs b/examples/openid_connect_demo/src/views/home.rs index f39695302..d91b5c203 100644 --- a/examples/openid_connect_demo/src/views/home.rs +++ b/examples/openid_connect_demo/src/views/home.rs @@ -1,5 +1,5 @@ use dioxus::prelude::*; -pub fn Home(cx: Scope) -> Element { - render! { div { "Hello world" } } +pub fn Home() -> Element { + rsx! { div { "Hello world" } } } diff --git a/examples/openid_connect_demo/src/views/login.rs b/examples/openid_connect_demo/src/views/login.rs index 2583503de..c1c904a63 100644 --- a/examples/openid_connect_demo/src/views/login.rs +++ b/examples/openid_connect_demo/src/views/login.rs @@ -5,16 +5,16 @@ use crate::{ DIOXUS_FRONT_URL, FERMI_AUTH_REQUEST, FERMI_AUTH_TOKEN, FERMI_CLIENT, }; use dioxus::prelude::*; -use dioxus_router::prelude::{Link, NavigationTarget}; +use dioxus::router::prelude::{Link, NavigationTarget}; use fermi::*; use openidconnect::{OAuth2TokenResponse, TokenResponse}; #[component] -pub fn Login(cx: Scope, query_string: String) -> Element { - let fermi_client = use_atom_ref(cx, &FERMI_CLIENT); - let fermi_auth_token = use_atom_ref(cx, &FERMI_AUTH_TOKEN); +pub fn Login(query_string: String) -> Element { + let fermi_client = use_atom_ref(&FERMI_CLIENT); + let fermi_auth_token = use_atom_ref(&FERMI_AUTH_TOKEN); let home_url: NavigationTarget = DIOXUS_FRONT_URL.parse().unwrap(); - let fermi_auth_request = use_atom_ref(cx, &FERMI_AUTH_REQUEST); + let fermi_auth_request = use_atom_ref(&FERMI_AUTH_REQUEST); let client = fermi_client.read().oidc_client.clone(); let auth_token_read = fermi_auth_token.read().clone(); cx.render(match (client, auth_token_read) { diff --git a/examples/openid_connect_demo/src/views/not_found.rs b/examples/openid_connect_demo/src/views/not_found.rs index b8fb1d8b8..833c61067 100644 --- a/examples/openid_connect_demo/src/views/not_found.rs +++ b/examples/openid_connect_demo/src/views/not_found.rs @@ -1,8 +1,8 @@ use dioxus::prelude::*; #[component] -pub fn NotFound(cx: Scope, route: Vec) -> Element { - render! { +pub fn NotFound(route: Vec) -> Element { + rsx! { div{ {route.join("")} } diff --git a/examples/optional_props.rs b/examples/optional_props.rs index 8108d437d..75ba1e3be 100644 --- a/examples/optional_props.rs +++ b/examples/optional_props.rs @@ -7,11 +7,11 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch(app); } -fn app(cx: Scope) -> Element { - cx.render(rsx! { +fn app() -> Element { + rsx! { Button { a: "asd".to_string(), c: "asd".to_string(), @@ -30,12 +30,10 @@ fn app(cx: Scope) -> Element { c: "asd".to_string(), d: Some("asd".to_string()), } - }) + } } -type SthElse = Option; - -#[derive(Props, PartialEq)] +#[derive(Props, PartialEq, Clone)] struct ButtonProps { a: String, @@ -51,14 +49,16 @@ struct ButtonProps { e: SthElse, } -fn Button(cx: Scope) -> Element { - cx.render(rsx! { +type SthElse = Option; + +fn Button(props: ButtonProps) -> Element { + rsx! { button { - "{cx.props.a} | " - "{cx.props.b:?} | " - "{cx.props.c:?} | " - "{cx.props.d:?} | " - "{cx.props.e:?}" + "{props.a} | " + "{props.b:?} | " + "{props.c:?} | " + "{props.d:?} | " + "{props.e:?}" } - }) + } } diff --git a/examples/overlay.rs b/examples/overlay.rs index a4b9e7bfe..a4a927558 100644 --- a/examples/overlay.rs +++ b/examples/overlay.rs @@ -1,12 +1,12 @@ +use dioxus::desktop::{tao::dpi::PhysicalPosition, LogicalSize, WindowBuilder}; use dioxus::prelude::*; -use dioxus_desktop::{tao::dpi::PhysicalPosition, LogicalSize, WindowBuilder}; fn main() { - dioxus_desktop::launch_cfg(app, make_config()); + LaunchBuilder::desktop().with_cfg(make_config()).launch(app); } -fn app(cx: Scope) -> Element { - cx.render(rsx! { +fn app() -> Element { + rsx! { div { width: "100%", height: "100%", @@ -17,16 +17,16 @@ fn app(cx: Scope) -> Element { width: "100%", height: "10px", background_color: "black", - onmousedown: move |_| dioxus_desktop::window().drag(), + onmousedown: move |_| dioxus::desktop::window().drag(), } "This is an overlay!" } - }) + } } -fn make_config() -> dioxus_desktop::Config { - dioxus_desktop::Config::default() +fn make_config() -> dioxus::desktop::Config { + dioxus::desktop::Config::default() .with_window(make_window()) .with_custom_head( r#" diff --git a/examples/query_segments_demo/src/main.rs b/examples/query_segments.rs similarity index 73% rename from examples/query_segments_demo/src/main.rs rename to examples/query_segments.rs index 24896a403..3f7542970 100644 --- a/examples/query_segments_demo/src/main.rs +++ b/examples/query_segments.rs @@ -1,16 +1,12 @@ -#![allow(unused)] //! Example: Url query segments usage //! ------------------------------------ //! //! This example shows how to access and use multiple query segments present in an url on the web. //! //! Run `dx serve` and navigate to `http://localhost:8080/blog?name=John&surname=Doe` +use dioxus::prelude::*; use std::fmt::Display; -use dioxus::prelude::*; -use dioxus_router::prelude::*; - -// ANCHOR: route #[derive(Routable, Clone)] #[rustfmt::skip] enum Route { @@ -20,6 +16,7 @@ enum Route { // You must include query segments in child variants query_params: ManualBlogQuerySegments, }, + // segments that follow the ?:field&:other_field syntax are query segments that follow the standard url query syntax #[route("/autoblog?:name&:surname")] AutomaticBlogPost { @@ -41,7 +38,7 @@ impl Display for ManualBlogQuerySegments { } } -/// The query segment is anything that implements . You can implement that trait for a struct if you want to parse multiple query parameters. +/// The query segment is anything that implements . You can implement that trait for a struct if you want to parse multiple query parameters. impl FromQuery for ManualBlogQuerySegments { fn from_query(query: &str) -> Self { let mut name = None; @@ -63,26 +60,26 @@ impl FromQuery for ManualBlogQuerySegments { } #[component] -fn BlogPost(cx: Scope, query_params: ManualBlogQuerySegments) -> Element { - render! { - div{"This is your blogpost with a query segment:"} - div{ "{query_params:?}" } +fn BlogPost(query_params: ManualBlogQuerySegments) -> Element { + rsx! { + div { "This is your blogpost with a query segment:" } + div { "{query_params:?}" } } } #[component] -fn AutomaticBlogPost(cx: Scope, name: String, surname: String) -> Element { - render! { - div{"This is your blogpost with a query segment:"} - div{ "name={name}&surname={surname}" } +fn AutomaticBlogPost(name: String, surname: String) -> Element { + rsx! { + div { "This is your blogpost with a query segment:" } + div { "name={name}&surname={surname}" } } } #[component] -fn App(cx: Scope) -> Element { - render! { Router::{} } +fn App() -> Element { + rsx! { Router:: {} } } fn main() { - dioxus_web::launch(App); + launch(App); } diff --git a/examples/query_segments_demo/Cargo.toml b/examples/query_segments_demo/Cargo.toml deleted file mode 100644 index ee9f49c70..000000000 --- a/examples/query_segments_demo/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "query_segments_demo" -version = "0.1.0" -edition = "2021" -publish = false - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -dioxus = { path = "../../packages/dioxus", version = "*" } -dioxus-router = { path = "../../packages/router", version = "*" } -dioxus-web = { path = "../../packages/web", version = "*" } -form_urlencoded = "1.2.0" diff --git a/examples/read_size.rs b/examples/read_size.rs index 806f71f80..0a9f802b8 100644 --- a/examples/read_size.rs +++ b/examples/read_size.rs @@ -4,10 +4,10 @@ use std::rc::Rc; use dioxus::{html::geometry::euclid::Rect, prelude::*}; fn main() { - dioxus_desktop::launch_cfg( - app, - dioxus_desktop::Config::default().with_custom_head( - r#" + LaunchBuilder::desktop() + .with_cfg( + dioxus::desktop::Config::default().with_custom_head( + r#" "# - .to_owned(), - ), - ); + .to_owned(), + ), + ) + .launch(app); } -fn app(cx: Scope) -> Element { - let div_element: &UseRef>> = use_ref(cx, || None); +fn app() -> Element { + let mut div_element = use_signal(|| None as Option>); + let mut dimensions = use_signal(Rect::zero); - let dimentions = use_ref(cx, Rect::zero); + let read_dims = move |_| async move { + let read = div_element.read(); + let client_rect = read.as_ref().map(|el| el.get_client_rect()); + if let Some(client_rect) = client_rect { + if let Ok(rect) = client_rect.await { + dimensions.set(rect); + } + } + }; - cx.render(rsx!( + rsx!( div { width: "50%", height: "50%", background_color: "red", - onmounted: move |cx| { - div_element.set(Some(cx.inner().clone())); - }, - "This element is {dimentions.read():?}" + onmounted: move |cx| div_element.set(Some(cx.data())), + "This element is {dimensions():?}" } - button { - onclick: move |_| { - to_owned![div_element, dimentions]; - async move { - let read = div_element.read(); - let client_rect = read.as_ref().map(|el| el.get_client_rect()); - if let Some(client_rect) = client_rect { - if let Ok(rect) = client_rect.await { - dimentions.set(rect); - } - } - } - }, - "Read dimentions" - } - )) + button { onclick: read_dims, "Read dimensions" } + ) } diff --git a/examples/readme.rs b/examples/readme.rs index f4668488b..d29a24bdc 100644 --- a/examples/readme.rs +++ b/examples/readme.rs @@ -1,19 +1,15 @@ -//! Example: README.md showcase -//! -//! The example from the README.md. - use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch(app); } -fn app(cx: Scope) -> Element { - let mut count = use_state(cx, || 0); +fn app() -> Element { + let mut count = use_signal(|| 0); - cx.render(rsx! { + rsx! { h1 { "High-Five counter: {count}" } button { onclick: move |_| count += 1, "Up high!" } button { onclick: move |_| count -= 1, "Down low!" } - }) + } } diff --git a/examples/pattern_reducer.rs b/examples/reducer.rs similarity index 58% rename from examples/pattern_reducer.rs rename to examples/reducer.rs index 98c4fb2c6..cc685a8e1 100644 --- a/examples/pattern_reducer.rs +++ b/examples/reducer.rs @@ -4,31 +4,24 @@ //! This example shows how to encapsulate state in dioxus components with the reducer pattern. //! This pattern is very useful when a single component can handle many types of input that can //! be represented by an enum. -//! -//! Currently we don't have a reducer pattern hook. If you'd like to add it, -//! feel free to make a PR. use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch(app); } -fn app(cx: Scope) -> Element { - let state = use_state(cx, PlayerState::new); +fn app() -> Element { + let mut state = use_signal(|| PlayerState { is_playing: false }); - cx.render(rsx!( + rsx!( div { h1 {"Select an option"} - h3 { "The radio is... ", {state.is_playing()}, "!" } - button { onclick: move |_| state.make_mut().reduce(PlayerAction::Pause), - "Pause" - } - button { onclick: move |_| state.make_mut().reduce(PlayerAction::Play), - "Play" - } + h3 { "The radio is... ", {state.read().is_playing()}, "!" } + button { onclick: move |_| state.write().reduce(PlayerAction::Pause), "Pause" } + button { onclick: move |_| state.write().reduce(PlayerAction::Play), "Play" } } - )) + ) } enum PlayerAction { @@ -42,9 +35,6 @@ struct PlayerState { } impl PlayerState { - fn new() -> Self { - Self { is_playing: false } - } fn reduce(&mut self, action: PlayerAction) { match action { PlayerAction::Pause => self.is_playing = false, diff --git a/examples/router.rs b/examples/router.rs index d00c747b9..5230d92a6 100644 --- a/examples/router.rs +++ b/examples/router.rs @@ -1,15 +1,14 @@ use dioxus::prelude::*; -use dioxus_router::prelude::*; fn main() { - #[cfg(target_arch = "wasm32")] - dioxus_web::launch(App); - #[cfg(not(target_arch = "wasm32"))] - dioxus_desktop::launch(App); + launch_desktop(|| { + rsx! { + Router:: {} + } + }); } -// ANCHOR: router -#[derive(Routable, Clone)] +#[derive(Routable, Clone, Debug, PartialEq)] #[rustfmt::skip] enum Route { #[layout(NavBar)] @@ -19,7 +18,7 @@ enum Route { #[layout(Blog)] #[route("/")] BlogList {}, - #[route("/blog/:name")] + #[route("/:name")] BlogPost { name: String }, #[end_layout] #[end_nest] @@ -33,22 +32,18 @@ enum Route { route: Vec, }, } -// ANCHOR_END: router #[component] -fn App(cx: Scope) -> Element { - render! { - Router:: {} - } -} - -#[component] -fn NavBar(cx: Scope) -> Element { - render! { +fn NavBar() -> Element { + rsx! { nav { ul { - li { Link { to: Route::Home {}, "Home" } } - li { Link { to: Route::BlogList {}, "Blog" } } + li { + Link { to: Route::Home {}, "Home" } + } + li { + Link { to: Route::BlogList {}, "Blog" } + } } } Outlet:: {} @@ -56,34 +51,36 @@ fn NavBar(cx: Scope) -> Element { } #[component] -fn Home(cx: Scope) -> Element { - render! { - h1 { "Welcome to the Dioxus Blog!" } - } +fn Home() -> Element { + rsx! { h1 { "Welcome to the Dioxus Blog!" } } } #[component] -fn Blog(cx: Scope) -> Element { - render! { +fn Blog() -> Element { + rsx! { h1 { "Blog" } Outlet:: {} } } #[component] -fn BlogList(cx: Scope) -> Element { - render! { +fn BlogList() -> Element { + rsx! { h2 { "Choose a post" } ul { li { Link { - to: Route::BlogPost { name: "Blog post 1".into() }, + to: Route::BlogPost { + name: "Blog post 1".into(), + }, "Read the first blog post" } } li { Link { - to: Route::BlogPost { name: "Blog post 2".into() }, + to: Route::BlogPost { + name: "Blog post 2".into(), + }, "Read the second blog post" } } @@ -92,20 +89,15 @@ fn BlogList(cx: Scope) -> Element { } #[component] -fn BlogPost(cx: Scope, name: String) -> Element { - render! { - h2 { "Blog Post: {name}"} - } +fn BlogPost(name: String) -> Element { + rsx! { h2 { "Blog Post: {name}" } } } #[component] -fn PageNotFound(cx: Scope, route: Vec) -> Element { - render! { +fn PageNotFound(route: Vec) -> Element { + rsx! { h1 { "Page not found" } p { "We are terribly sorry, but the page you requested doesn't exist." } - pre { - color: "red", - "log:\nattemped to navigate to: {route:?}" - } + pre { color: "red", "log:\nattemped to navigate to: {route:?}" } } } diff --git a/examples/rsx_compile_fail.rs b/examples/rsx_compile_fail.rs deleted file mode 100644 index ad2577b08..000000000 --- a/examples/rsx_compile_fail.rs +++ /dev/null @@ -1,58 +0,0 @@ -//! This example just flexes the ability to use arbitrary expressions within RSX. -//! It also proves that lifetimes work properly, especially when used with use_ref - -use dioxus::prelude::*; - -fn main() { - let mut vdom = VirtualDom::new(example); - _ = vdom.rebuild(); - - let mut renderer = dioxus_ssr::Renderer::new(); - renderer.pretty = true; - renderer.render(&vdom); -} - -fn example(cx: Scope) -> Element { - let items = use_state(cx, || { - vec![Thing { - a: "asd".to_string(), - b: 10, - }] - }); - - let things = use_ref(cx, || { - vec![Thing { - a: "asd".to_string(), - b: 10, - }] - }); - let things_list = things.read(); - - let mything = use_ref(cx, || Some(String::from("asd"))); - let mything_read = mything.read(); - - cx.render(rsx!( - div { - div { id: "asd", - "your neighborhood spiderman" - - for item in items.iter().cycle().take(5) { - div { "{item.a}" } - } - - for thing in things_list.iter() { - div { "{thing.a}" "{thing.b}" } - } - - if let Some(f) = mything_read.as_ref() { - div { "{f}" } - } - } - } - )) -} - -struct Thing { - a: String, - b: u32, -} diff --git a/examples/rsx_usage.rs b/examples/rsx_usage.rs index dc452af48..e9cfa57aa 100644 --- a/examples/rsx_usage.rs +++ b/examples/rsx_usage.rs @@ -39,269 +39,263 @@ //! - Allow top-level fragments fn main() { - dioxus_desktop::launch(App); -} - -use core::{fmt, str::FromStr}; -use std::fmt::Display; - -use baller::Baller; -use dioxus::prelude::*; - -#[component] -fn App(cx: Scope) -> Element { - let formatting = "formatting!"; - let formatting_tuple = ("a", "b"); - let lazy_fmt = format_args!("lazily formatted text"); - let asd = 123; - cx.render(rsx! { - div { - // Elements - div {} - h1 {"Some text"} - h1 {"Some text with {formatting}"} - h1 {"Formatting basic expressions {formatting_tuple.0} and {formatting_tuple.1}"} - h1 {"Formatting without interpolation " {formatting_tuple.0} "and" {formatting_tuple.1} } - h2 { - "Multiple" - "Text" - "Blocks" - "Use comments as separators in html" - } - div { - h1 {"multiple"} - h2 {"nested"} - h3 {"elements"} - } - div { - class: "my special div", - h1 {"Headers and attributes!"} - } - div { - // pass simple rust expressions in - class: lazy_fmt, - id: format_args!("attributes can be passed lazily with std::fmt::Arguments"), - class: "asd", - class: "{asd}", - // if statements can be used to conditionally render attributes - class: if formatting.contains("form") { "{asd}" }, - div { - class: { - const WORD: &str = "expressions"; - format_args!("Arguments can be passed in through curly braces for complex {WORD}") - } - } - } - - // Expressions can be used in element position too: - {rsx!(p { "More templating!" })}, - - // Iterators - {(0..10).map(|i| rsx!(li { "{i}" }))}, - - // Iterators within expressions - { - let data = std::collections::HashMap::<&'static str, &'static str>::new(); - // Iterators *should* have keys when you can provide them. - // Keys make your app run faster. Make sure your keys are stable, unique, and predictable. - // Using an "ID" associated with your data is a good idea. - data.into_iter().map(|(k, v)| rsx!(li { key: "{k}", "{v}" })) - } - - // Matching - match true { - true => rsx!( h1 {"Top text"}), - false => rsx!( h1 {"Bottom text"}) - } - - // Conditional rendering - // Dioxus conditional rendering is based around None/Some. We have no special syntax for conditionals. - // You can convert a bool condition to rsx! with .then and .or - {true.then(|| rsx!(div {}))}, - - // Alternatively, you can use the "if" syntax - but both branches must be resolve to Element - if false { - h1 {"Top text"} - } else { - h1 {"Bottom text"} - } - - // Using optionals for diverging branches - // Note that since this is wrapped in curlies, it's interpreted as an expression - {if true { - Some(rsx!(h1 {"Top text"})) - } else { - None - }} - - // returning "None" without a diverging branch is a bit noisy... but rare in practice - {None as Option<()>}, - - // can also just use empty fragments - Fragment {} - - // Fragments let you insert groups of nodes without a parent. - // This lets you make components that insert elements as siblings without a container. - div {"A"} - Fragment { - div {"B"} - div {"C"} - Fragment { - "D" - Fragment { - "E" - "F" - } - } - } - - // Components - // Can accept any paths - // Notice how you still get syntax highlighting and IDE support :) - Baller {} - baller::Baller {} - crate::baller::Baller {} - - // Can take properties - Taller { a: "asd" } - - // Can take optional properties - Taller { a: "asd" } - - // Can pass in props directly as an expression - { - let props = TallerProps {a: "hello", children: None }; - rsx!(Taller { ..props }) - } - - // Spreading can also be overridden manually - Taller { - ..TallerProps { a: "ballin!", children: None }, - a: "not ballin!" - } - - // Can take children too! - Taller { a: "asd", div {"hello world!"} } - - // This component's props are defined *inline* with the `inline_props` macro - WithInline { text: "using functionc all syntax" } - - // Components can be generic too - // This component takes i32 type to give you typed input - TypedInput:: {} - - // Type inference can be used too - TypedInput { initial: 10.0 } - - // geneircs with the `inline_props` macro - Label { text: "hello geneirc world!" } - Label { text: 99.9 } - - // Lowercase components work too, as long as they are access using a path - baller::lowercase_component {} - - // For in-scope lowercase components, use the `self` keyword - self::lowercase_helper {} - - // helper functions - // Anything that implements IntoVnode can be dropped directly into Rsx - {helper(cx, "hello world!")} - - // Strings can be supplied directly - {String::from("Hello world!")} - - // So can format_args - {format_args!("Hello {}!", "world")} - - // Or we can shell out to a helper function - {format_dollars(10, 50)} - } - }) -} - -fn format_dollars(dollars: u32, cents: u32) -> String { - format!("${dollars}.{cents:02}") -} - -fn helper<'a>(cx: &'a ScopeState, text: &'a str) -> Element<'a> { - cx.render(rsx! { - p { "{text}" } - }) -} - -// no_case_check disables PascalCase checking if you *really* want a snake_case component. -// This will likely be deprecated/removed in a future update that will introduce a more polished linting system, -// something like Clippy. -#[component(no_case_check)] -fn lowercase_helper(cx: Scope) -> Element { - cx.render(rsx! { - "asd" - }) -} - -mod baller { - use super::*; - #[derive(Props, PartialEq, Eq)] - pub struct BallerProps {} - - #[component] - /// This component totally balls - pub fn Baller(_cx: Scope) -> Element { - todo!() - } - - // no_case_check disables PascalCase checking if you *really* want a snake_case component. - // This will likely be deprecated/removed in a future update that will introduce a more polished linting system, - // something like Clippy. - #[component(no_case_check)] - pub fn lowercase_component(cx: Scope) -> Element { - cx.render(rsx! { "look ma, no uppercase" }) - } -} - -#[derive(Props)] -pub struct TallerProps<'a> { - /// Fields are documented and accessible in rsx! - a: &'static str, - children: Element<'a>, -} - -/// Documention for this component is visible within the rsx macro -#[component] -pub fn Taller<'a>(cx: Scope<'a, TallerProps<'a>>) -> Element { - cx.render(rsx! { - {&cx.props.children} - }) -} - -#[derive(Props, PartialEq, Eq)] -pub struct TypedInputProps { - #[props(optional, default)] - initial: Option, -} - -#[allow(non_snake_case)] -pub fn TypedInput(_: Scope>) -> Element -where - T: FromStr + fmt::Display, - ::Err: std::fmt::Display, -{ todo!() + //launch_desktop(App); } -#[component] -fn WithInline<'a>(cx: Scope<'a>, text: &'a str) -> Element { - cx.render(rsx! { - p { "{text}" } - }) -} +// use core::{fmt, str::FromStr}; +// use std::fmt::Display; -#[component] -fn Label(cx: Scope, text: T) -> Element -where - T: Display, -{ - cx.render(rsx! { - p { "{text}" } - }) -} +// use baller::Baller; +// use dioxus::prelude::*; + +// #[component] +// fn App() -> Element { +// let formatting = "formatting!"; +// let formatting_tuple = ("a", "b"); +// let lazy_fmt = format_args!("lazily formatted text"); +// let asd = 123; +// rsx! { +// div { +// // Elements +// div {} +// h1 {"Some text"} +// h1 {"Some text with {formatting}"} +// h1 {"Formatting basic expressions {formatting_tuple.0} and {formatting_tuple.1}"} +// h1 {"Formatting without interpolation " {formatting_tuple.0} "and" {formatting_tuple.1} } +// h2 { +// "Multiple" +// "Text" +// "Blocks" +// "Use comments as separators in html" +// } +// div { +// h1 {"multiple"} +// h2 {"nested"} +// h3 {"elements"} +// } +// div { +// class: "my special div", +// h1 {"Headers and attributes!"} +// } +// div { +// // pass simple rust expressions in +// class: lazy_fmt, +// id: format_args!("attributes can be passed lazily with std::fmt::Arguments"), +// class: "asd", +// class: "{asd}", +// // if statements can be used to conditionally render attributes +// class: if formatting.contains("form") { "{asd}" }, +// div { +// class: { +// const WORD: &str = "expressions"; +// format_args!("Arguments can be passed in through curly braces for complex {WORD}") +// } +// } +// } + +// // Expressions can be used in element position too: +// {rsx!(p { "More templating!" })}, + +// // Iterators +// {(0..10).map(|i| rsx!(li { "{i}" }))}, + +// // Iterators within expressions +// { +// let data = std::collections::HashMap::<&'static str, &'static str>::new(); +// // Iterators *should* have keys when you can provide them. +// // Keys make your app run faster. Make sure your keys are stable, unique, and predictable. +// // Using an "ID" associated with your data is a good idea. +// data.into_iter().map(|(k, v)| rsx!(li { key: "{k}", "{v}" })) +// } + +// // Matching +// match true { +// true => rsx!( h1 {"Top text"}), +// false => rsx!( h1 {"Bottom text"}) +// } + +// // Conditional rendering +// // Dioxus conditional rendering is based around None/Some. We have no special syntax for conditionals. +// // You can convert a bool condition to rsx! with .then and .or +// {true.then(|| rsx!(div {}))}, + +// // Alternatively, you can use the "if" syntax - but both branches must be resolve to Element +// if false { +// h1 {"Top text"} +// } else { +// h1 {"Bottom text"} +// } + +// // Using optionals for diverging branches +// // Note that since this is wrapped in curlies, it's interpreted as an expression +// {if true { +// Some(rsx!(h1 {"Top text"})) +// } else { +// None +// }} + +// // returning "None" without a diverging branch is a bit noisy... but rare in practice +// {None as Option<()>}, + +// // can also just use empty fragments +// Fragment {} + +// // Fragments let you insert groups of nodes without a parent. +// // This lets you make components that insert elements as siblings without a container. +// div {"A"} +// Fragment { +// div {"B"} +// div {"C"} +// Fragment { +// "D" +// Fragment { +// "E" +// "F" +// } +// } +// } + +// // Components +// // Can accept any paths +// // Notice how you still get syntax highlighting and IDE support :) +// Baller {} +// baller::Baller {} +// crate::baller::Baller {} + +// // Can take properties +// Taller { a: "asd" } + +// // Can take optional properties +// Taller { a: "asd" } + +// // Can pass in props directly as an expression +// { +// let props = TallerProps {a: "hello", children: None }; +// rsx!(Taller { ..props }) +// } + +// // Spreading can also be overridden manually +// Taller { +// ..TallerProps { a: "ballin!", children: None }, +// a: "not ballin!" +// } + +// // Can take children too! +// Taller { a: "asd", div {"hello world!"} } + +// // This component's props are defined *inline* with the `inline_props` macro +// WithInline { text: "using functionc all syntax" } + +// // Components can be generic too +// // This component takes i32 type to give you typed input +// TypedInput:: {} + +// // Type inference can be used too +// TypedInput { initial: 10.0 } + +// // geneircs with the `inline_props` macro +// Label { text: "hello geneirc world!" } +// Label { text: 99.9 } + +// // Lowercase components work too, as long as they are access using a path +// baller::lowercase_component {} + +// // For in-scope lowercase components, use the `self` keyword +// self::lowercase_helper {} + +// // helper functions +// // Anything that implements IntoVnode can be dropped directly into Rsx +// {helper("hello world!")} + +// // Strings can be supplied directly +// {String::from("Hello world!")} + +// // So can format_args +// {format_args!("Hello {}!", "world")} + +// // Or we can shell out to a helper function +// {format_dollars(10, 50)} +// } +// } +// } + +// fn format_dollars(dollars: u32, cents: u32) -> String { +// format!("${dollars}.{cents:02}") +// } + +// fn helper<'a>(cx: &'a ScopeState, text: &'a str) -> Element { +// rsx! { +// p { "{text}" } +// } +// } + +// // no_case_check disables PascalCase checking if you *really* want a snake_case component. +// // This will likely be deprecated/removed in a future update that will introduce a more polished linting system, +// // something like Clippy. +// #[component(no_case_check)] +// fn lowercase_helper() -> Element { +// rsx! { +// "asd" +// } +// } + +// mod baller { +// use super::*; + +// #[component] +// /// This component totally balls +// pub fn Baller() -> Element { +// todo!() +// } + +// // no_case_check disables PascalCase checking if you *really* want a snake_case component. +// // This will likely be deprecated/removed in a future update that will introduce a more polished linting system, +// // something like Clippy. +// #[component(no_case_check)] +// pub fn lowercase_component() -> Element { +// rsx! { "look ma, no uppercase" } +// } +// } + +// /// Documention for this component is visible within the rsx macro +// #[component] +// pub fn Taller( +// /// Fields are documented and accessible in rsx! +// a: &'static str, +// children: Element, +// ) -> Element { +// rsx! { {&children} } +// } + +// #[derive(Props, PartialEq, Eq)] +// pub struct TypedInputProps { +// #[props(optional, default)] +// initial: Option, +// } + +// #[allow(non_snake_case)] +// pub fn TypedInput(_: Scope>) -> Element +// where +// T: FromStr + fmt::Display, +// ::Err: std::fmt::Display, +// { +// todo!() +// } + +// #[component] +// fn WithInline(cx: Scope<'a>, text: &'a str) -> Element { +// rsx! { +// p { "{text}" } +// } +// } + +// #[component] +// fn Label(text: T) -> Element +// where +// T: Display, +// { +// rsx! { +// p { "{text}" } +// } +// } diff --git a/examples/scroll_to_top.rs b/examples/scroll_to_top.rs index eed0a00b5..1c042b912 100644 --- a/examples/scroll_to_top.rs +++ b/examples/scroll_to_top.rs @@ -1,18 +1,16 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - let header_element = use_ref(cx, || None); +fn app() -> Element { + let mut header_element = use_signal(|| None); - cx.render(rsx!( + rsx! { div { h1 { - onmounted: move |cx| { - header_element.set(Some(cx.inner().clone())); - }, + onmounted: move |cx| header_element.set(Some(cx.data())), "Scroll to top example" } @@ -21,15 +19,13 @@ fn app(cx: Scope) -> Element { } button { - onclick: move |_| { - if let Some(header) = header_element.read().as_ref().cloned() { - cx.spawn(async move { - let _ = header.scroll_to(ScrollBehavior::Smooth).await; - }); + onclick: move |_| async move { + if let Some(header) = header_element.cloned() { + let _ = header.scroll_to(ScrollBehavior::Smooth).await; } }, "Scroll to top" } } - )) + } } diff --git a/examples/shared_state.rs b/examples/shared_state.rs deleted file mode 100644 index 65ec76a71..000000000 --- a/examples/shared_state.rs +++ /dev/null @@ -1,73 +0,0 @@ -use std::collections::HashMap; - -use dioxus::prelude::*; - -fn main() { - dioxus_desktop::launch(App); -} - -#[derive(Default)] -struct CoolData { - data: HashMap, -} - -impl CoolData { - pub fn new(data: HashMap) -> Self { - Self { data } - } - - pub fn view(&self, id: &usize) -> Option<&String> { - self.data.get(id) - } - - pub fn set(&mut self, id: usize, data: String) { - self.data.insert(id, data); - } -} - -#[component] -#[rustfmt::skip] -pub fn App(cx: Scope) -> Element { - use_shared_state_provider(cx, || CoolData::new(HashMap::from([ - (0, "Hello, World!".to_string()), - (1, "Dioxus is amazing!".to_string()) - ]))); - - render!( - DataEditor { - id: 0 - } - DataEditor { - id: 1 - } - DataView { - id: 0 - } - DataView { - id: 1 - } - ) -} - -#[component] -fn DataEditor(cx: Scope, id: usize) -> Element { - let data = use_shared_state::(cx)?; - - render! { - p { - {data.read().view(id)?} - } - } -} - -#[component] -fn DataView(cx: Scope, id: usize) -> Element { - let data = use_shared_state::(cx)?; - - render! { - input { - oninput: move |e: FormEvent| data.write().set(*id, e.value()), - value: data.read().view(id)? - } - } -} diff --git a/examples/shortcut.rs b/examples/shortcut.rs index 53c3aace3..d7e849870 100644 --- a/examples/shortcut.rs +++ b/examples/shortcut.rs @@ -1,17 +1,14 @@ +use dioxus::desktop::use_global_shortcut; use dioxus::prelude::*; -use dioxus_desktop::use_global_shortcut; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - let toggled = use_state(cx, || false); +fn app() -> Element { + let mut toggled = use_signal(|| false); - use_global_shortcut(cx, "ctrl+s", { - to_owned![toggled]; - move || toggled.modify(|t| !*t) - }); + _ = use_global_shortcut("ctrl+s", move || toggled.toggle()); - cx.render(rsx!("toggle: {toggled.get()}")) + rsx!("toggle: {toggled}") } diff --git a/examples/shorthand.rs b/examples/shorthand.rs index 2d71b046b..c53e0146b 100644 --- a/examples/shorthand.rs +++ b/examples/shorthand.rs @@ -1,10 +1,10 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { +fn app() -> Element { let a = 123; let b = 456; let c = 789; @@ -14,10 +14,10 @@ fn app(cx: Scope) -> Element { // todo: i'd like it for children on elements to be inferred as the children of the element // also should shorthands understand references/dereferences? // ie **a, *a, &a, &mut a, etc - let children = render! { "Child" }; + let children = rsx! { "Child" }; let onclick = move |_| println!("Clicked!"); - render! { + rsx! { div { class, id, {&children} } Component { a, b, c, children, onclick } Component { a, ..ComponentProps { a: 1, b: 2, c: 3, children: None, onclick: Default::default() } } @@ -25,21 +25,12 @@ fn app(cx: Scope) -> Element { } #[component] -fn Component<'a>( - cx: Scope<'a>, - a: i32, - b: i32, - c: i32, - children: Element<'a>, - onclick: EventHandler<'a, ()>, -) -> Element { - render! { +fn Component(a: i32, b: i32, c: i32, children: Element, onclick: EventHandler) -> Element { + rsx! { div { "{a}" } div { "{b}" } div { "{c}" } div { {children} } - div { - onclick: move |_| onclick.call(()), - } + div { onclick: move |_| onclick.call(()) } } } diff --git a/examples/signals.rs b/examples/signals.rs index e72488443..5b217c508 100644 --- a/examples/signals.rs +++ b/examples/signals.rs @@ -2,40 +2,60 @@ use dioxus::prelude::*; use std::time::Duration; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - let running = dioxus_signals::use_signal(cx, || true); - let mut count = dioxus_signals::use_signal(cx, || 0); - let saved_values = dioxus_signals::use_signal(cx, || vec![0.to_string()]); +fn app() -> Element { + let mut running = use_signal(|| true); + let mut count = use_signal(|| 0); + let mut saved_values = use_signal(|| vec![0.to_string()]); - // Signals can be used in async functions without an explicit clone since they're 'static and Copy - // Signals are backed by a runtime that is designed to deeply integrate with Dioxus apps - use_future!(cx, || async move { + // use_memo will recompute the value of the signal whenever the captured signals change + let doubled_count = use_memo(move || count() * 2); + + // use_effect will subscribe to any changes in the signal values it captures + // effects will always run after first mount and then whenever the signal values change + use_effect(move || println!("Count changed to {count}")); + + // We can do early returns and conditional rendering which will pause all futures that haven't been polled + if count() > 30 { + return rsx! { + h1 { "Count is too high!" } + button { onclick: move |_| count.set(0), "Press to reset" } + }; + } + + // use_future will spawn an infinitely running future that can be started and stopped + use_future(move || async move { loop { - if running.value() { + if running() { count += 1; } tokio::time::sleep(Duration::from_millis(400)).await; } }); - cx.render(rsx! { + // use_resource will spawn a future that resolves to a value + let _slow_count = use_resource(move || async move { + tokio::time::sleep(Duration::from_millis(200)).await; + count() * 2 + }); + + rsx! { h1 { "High-Five counter: {count}" } button { onclick: move |_| count += 1, "Up high!" } button { onclick: move |_| count -= 1, "Down low!" } button { onclick: move |_| running.toggle(), "Toggle counter" } - button { onclick: move |_| saved_values.push(count.value().to_string()), "Save this value" } - button { onclick: move |_| saved_values.write().clear(), "Clear saved values" } + button { onclick: move |_| saved_values.push(count.to_string()), "Save this value" } + button { onclick: move |_| saved_values.clear(), "Clear saved values" } // We can do boolean operations on the current signal value - if count.value() > 5 { + if count() > 5 { h2 { "High five!" } } // We can cleanly map signals with iterators - for value in saved_values.read().iter() { + for value in saved_values.iter() { h3 { "Saved value: {value}" } } @@ -45,5 +65,18 @@ fn app(cx: Scope) -> Element { } else { "No saved values" } - }) + + // You can pass a value directly to any prop that accepts a signal + Child { count: doubled_count() } + Child { count: doubled_count } + } +} + +#[component] +fn Child(mut count: ReadOnlySignal) -> Element { + println!("rendering child with count {count}"); + + rsx! { + h1 { "{count}" } + } } diff --git a/examples/simple_desktop.rs b/examples/simple_desktop.rs deleted file mode 100644 index 4eac5e3a9..000000000 --- a/examples/simple_desktop.rs +++ /dev/null @@ -1,82 +0,0 @@ -#![allow(non_snake_case)] - -use dioxus::prelude::*; -use dioxus_router::prelude::*; - -fn main() { - simple_logger::SimpleLogger::new() - .with_level(log::LevelFilter::Debug) - .with_module_level("dioxus", log::LevelFilter::Trace) - .init() - .unwrap(); - dioxus_desktop::launch(App); -} - -#[component] -fn App(cx: Scope) -> Element { - render! { - Router:: {} - } -} - -#[derive(Routable, Clone)] -#[rustfmt::skip] -enum Route { - #[layout(NavBar)] - #[route("/")] - Home {}, - #[nest("/new")] - #[route("/")] - BlogList {}, - #[route("/:post")] - BlogPost { - post: String, - }, - #[end_nest] - #[route("/oranges")] - Oranges {}, -} - -#[component] -fn NavBar(cx: Scope) -> Element { - render! { - h1 { "Your app here" } - ul { - li { Link { to: Route::Home {}, "home" } } - li { Link { to: Route::BlogList {}, "blog" } } - li { Link { to: Route::BlogPost { post: "tim".into() }, "tims' blog" } } - li { Link { to: Route::BlogPost { post: "bill".into() }, "bills' blog" } } - li { Link { to: Route::BlogPost { post: "james".into() }, "james amazing' blog" } } - } - Outlet:: {} - } -} - -#[component] -fn Home(cx: Scope) -> Element { - log::debug!("rendering home {:?}", cx.scope_id()); - render! { h1 { "Home" } } -} - -#[component] -fn BlogList(cx: Scope) -> Element { - log::debug!("rendering blog list {:?}", cx.scope_id()); - render! { div { "Blog List" } } -} - -#[component] -fn BlogPost(cx: Scope, post: String) -> Element { - log::debug!("rendering blog post {}", post); - - render! { - div { - h3 { "blog post: {post}" } - Link { to: Route::BlogList {}, "back to blog list" } - } - } -} - -#[component] -fn Oranges(cx: Scope) -> Element { - render!("Oranges are not apples!") -} diff --git a/examples/simple_list.rs b/examples/simple_list.rs index feb5aa3b4..67e9e64ff 100644 --- a/examples/simple_list.rs +++ b/examples/simple_list.rs @@ -1,11 +1,11 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - cx.render(rsx!( +fn app() -> Element { + rsx!( div { // Use Map directly to lazily pull elements {(0..10).map(|f| rsx! { "{f}" })}, @@ -22,7 +22,7 @@ fn app(cx: Scope) -> Element { // use a for loop where the body itself is RSX for name in 0..10 { - div {"{name}"} + div { "{name}" } } // Or even use an unterminated conditional @@ -30,5 +30,5 @@ fn app(cx: Scope) -> Element { "hello world!" } } - )) + ) } diff --git a/examples/simple_router.rs b/examples/simple_router.rs index 7ed55885e..7ad44fbb3 100644 --- a/examples/simple_router.rs +++ b/examples/simple_router.rs @@ -1,6 +1,6 @@ #![allow(non_snake_case)] + use dioxus::prelude::*; -use dioxus_router::prelude::*; #[derive(Routable, Clone, PartialEq)] enum Route { @@ -13,30 +13,46 @@ enum Route { } #[component] -fn Homepage(cx: Scope) -> Element { - render! { h1 { "Welcome home" } } +fn Homepage() -> Element { + rsx! { h1 { "Welcome home" } } } #[component] -fn Blog(cx: Scope, id: String) -> Element { - render! { +fn Blog(id: String) -> Element { + rsx! { h1 { "How to make: " } p { "{id}" } } } #[component] -fn Nav(cx: Scope) -> Element { - render! { +fn Nav() -> Element { + rsx! { nav { - li { Link { to: Route::Homepage { }, "Go home" } } - li { Link { to: Route::Blog { id: "Brownies".to_string() }, "Learn Brownies" } } - li { Link { to: Route::Blog { id: "Cookies".to_string() }, "Learn Cookies" } } + li { + Link { to: Route::Homepage {}, "Go home" } + } + li { + Link { + to: Route::Blog { + id: "Brownies".to_string(), + }, + "Learn Brownies" + } + } + li { + Link { + to: Route::Blog { + id: "Cookies".to_string(), + }, + "Learn Cookies" + } + } } div { Outlet:: {} } } } fn main() { - dioxus_desktop::launch(|cx| render!(Router:: {})); + launch_desktop(|| rsx! { Router:: {} }); } diff --git a/examples/spread.rs b/examples/spread.rs index 45bdc90af..763a48e12 100644 --- a/examples/spread.rs +++ b/examples/spread.rs @@ -1,16 +1,15 @@ use dioxus::prelude::*; fn main() { - let mut dom = VirtualDom::new(app); - let _ = dom.rebuild(); + let dom = VirtualDom::prebuilt(app); let html = dioxus_ssr::render(&dom); println!("{}", html); } -fn app(cx: Scope) -> Element { - render! { - Component { +fn app() -> Element { + rsx! { + spreadable_component { width: "10px", extra_data: "hello{1}", extra_data2: "hello{2}", @@ -20,17 +19,18 @@ fn app(cx: Scope) -> Element { } } -#[component] -fn Component<'a>(cx: Scope<'a, Props<'a>>) -> Element<'a> { - render! { - audio { ..cx.props.attributes, "1: {cx.props.extra_data}\n2: {cx.props.extra_data2}" } - } +#[derive(Props, PartialEq, Clone)] +struct Props { + #[props(extends = GlobalAttributes)] + attributes: Vec, + + extra_data: String, + + extra_data2: String, } -#[derive(Props)] -struct Props<'a> { - #[props(extends = GlobalAttributes)] - attributes: Vec>, - extra_data: &'a str, - extra_data2: &'a str, +fn spreadable_component(props: Props) -> Element { + rsx! { + audio { ..props.attributes, "1: {props.extra_data}\n2: {props.extra_data2}" } + } } diff --git a/examples/ssr.rs b/examples/ssr.rs index 2bc1657cb..e2a6acd90 100644 --- a/examples/ssr.rs +++ b/examples/ssr.rs @@ -6,14 +6,13 @@ use dioxus::prelude::*; fn main() { // We can render VirtualDoms - let mut vdom = VirtualDom::new(app); - let _ = vdom.rebuild(); + let vdom = VirtualDom::prebuilt(app); println!("{}", dioxus_ssr::render(&vdom)); // Or we can render rsx! calls themselves println!( "{}", - dioxus_ssr::render_lazy(rsx! { + dioxus_ssr::render_element(rsx! { div { h1 { "Hello, world!" } } @@ -30,11 +29,11 @@ fn main() { println!("{file}"); } -fn app(cx: Scope) -> Element { - cx.render(rsx!( +fn app() -> Element { + rsx!( div { h1 { "Title" } p { "Body" } } - )) + ) } diff --git a/examples/stale_memo.rs b/examples/stale_memo.rs new file mode 100644 index 000000000..f44c7297a --- /dev/null +++ b/examples/stale_memo.rs @@ -0,0 +1,36 @@ +use dioxus::prelude::*; + +fn main() { + launch_desktop(app); +} + +fn app() -> Element { + let mut state = use_signal(|| 0); + let mut depth = use_signal(|| 1_usize); + + if depth() == 5 { + return rsx! { + div { "Max depth reached" } + button { onclick: move |_| depth -= 1, "Remove depth" } + }; + } + + let items = use_memo(move || (0..depth()).map(|f| f as _).collect::>()); + + rsx! { + button { onclick: move |_| state += 1, "Increment" } + button { onclick: move |_| depth += 1, "Add depth" } + button { + onclick: move |_| async move { + depth += 1; + tokio::time::sleep(std::time::Duration::from_millis(100)).await; + dbg!(items.read()); + // if depth() is 5, this will be the old since the memo hasn't been re-computed + // use_memos are only re-computed when the signals they capture change + // *and* they are used in the current render + // If the use_memo isn't used, it can't be re-computed! + }, + "Add depth with sleep" + } + } +} diff --git a/examples/streams.rs b/examples/streams.rs index 005f73f53..8f692596a 100644 --- a/examples/streams.rs +++ b/examples/streams.rs @@ -1,16 +1,15 @@ use dioxus::prelude::*; -use dioxus_signals::use_signal; use futures_util::{future, stream, Stream, StreamExt}; use std::time::Duration; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - let count = use_signal(cx, || 10); +fn app() -> Element { + let mut count = use_signal(|| 10); - use_future(cx, (), |_| async move { + use_future(move || async move { let mut stream = some_stream(); while let Some(second) = stream.next().await { @@ -18,9 +17,9 @@ fn app(cx: Scope) -> Element { } }); - cx.render(rsx! { + rsx! { h1 { "High-Five counter: {count}" } - }) + } } fn some_stream() -> std::pin::Pin>> { diff --git a/examples/suspense.rs b/examples/suspense.rs index 40be30cd0..2fa9757fe 100644 --- a/examples/suspense.rs +++ b/examples/suspense.rs @@ -13,28 +13,25 @@ //! We can achieve the majority of suspense functionality by composing "suspenseful" //! primitives in our own custom components. +use dioxus::desktop::{Config, LogicalSize, WindowBuilder}; use dioxus::prelude::*; -use dioxus_desktop::{Config, LogicalSize, WindowBuilder}; fn main() { - let cfg = Config::new().with_window( - WindowBuilder::new() - .with_title("Doggo Fetcher") - .with_inner_size(LogicalSize::new(600.0, 800.0)), - ); - - dioxus_desktop::launch_cfg(app, cfg); + LaunchBuilder::desktop() + .with_cfg( + Config::new().with_window( + WindowBuilder::new() + .with_title("Doggo Fetcher") + .with_inner_size(LogicalSize::new(600.0, 800.0)), + ), + ) + .launch(app) } -#[derive(serde::Deserialize)] -struct DogApi { - message: String, -} - -fn app(cx: Scope) -> Element { - cx.render(rsx! { +fn app() -> Element { + rsx! { div { - h1 {"Dogs are very important"} + h1 { "Dogs are very important" } p { "The dog or domestic dog (Canis familiaris[4][5] or Canis lupus familiaris[5])" "is a domesticated descendant of the wolf which is characterized by an upturning tail." @@ -44,16 +41,21 @@ fn app(cx: Scope) -> Element { } h3 { "Illustrious Dog Photo" } - Doggo { } + Doggo {} } - }) + } } /// This component will re-render when the future has finished /// Suspense is achieved my moving the future into only the component that /// actually renders the data. -fn Doggo(cx: Scope) -> Element { - let fut = use_future(cx, (), |_| async move { +fn Doggo() -> Element { + let mut fut = use_resource(move || async move { + #[derive(serde::Deserialize)] + struct DogApi { + message: String, + } + reqwest::get("https://dog.ceo/api/breeds/image/random/") .await .unwrap() @@ -61,21 +63,12 @@ fn Doggo(cx: Scope) -> Element { .await }); - cx.render(match fut.value() { + match fut.read().as_ref() { Some(Ok(resp)) => rsx! { - button { - onclick: move |_| fut.restart(), - "Click to fetch another doggo" - } - div { - img { - max_width: "500px", - max_height: "500px", - src: "{resp.message}", - } - } + button { onclick: move |_| fut.restart(), "Click to fetch another doggo" } + div { img { max_width: "500px", max_height: "500px", src: "{resp.message}" } } }, Some(Err(_)) => rsx! { div { "loading dogs failed" } }, None => rsx! { div { "loading dogs..." } }, - }) + } } diff --git a/examples/svg.rs b/examples/svg.rs index f7a28d0cb..022a2aa81 100644 --- a/examples/svg.rs +++ b/examples/svg.rs @@ -1,103 +1,50 @@ // Thanks to @japsu and their project https://github.com/japsu/jatsi for the example! use dioxus::prelude::*; +use rand::{thread_rng, Rng}; fn main() { - dioxus_desktop::launch(app); -} - -fn app(cx: Scope) -> Element { - let val = use_state(cx, || 5); - - cx.render(rsx! { - div { - user_select: "none", - webkit_user_select: "none", - margin_left: "10%", - margin_right: "10%", - h1 { "Click die to generate a new value" } - div { - cursor: "pointer", - height: "80%", - width: "80%", - Die { - value: **val, - keep: true, - onclick: move |_| { - use rand::Rng; - let mut rng = rand::thread_rng(); - val.set(rng.gen_range(1..=6)); - } - } + launch(|| { + rsx! { + div { user_select: "none", webkit_user_select: "none", margin_left: "10%", margin_right: "10%", + h1 { "Click die to generate a new value" } + div { cursor: "pointer", height: "100%", width: "100%", Dice {} } } } - }) + }); } -#[derive(Props)] -pub struct DieProps<'a> { - pub value: u64, - pub keep: bool, - pub onclick: EventHandler<'a, MouseEvent>, -} +#[component] +fn Dice() -> Element { + const Y: bool = true; + const N: bool = false; + const DOTS: [(i64, i64); 7] = [(-1, -1), (-1, -0), (-1, 1), (1, -1), (1, 0), (1, 1), (0, 0)]; + const DOTS_FOR_VALUE: [[bool; 7]; 6] = [ + [N, N, N, N, N, N, Y], + [N, N, Y, Y, N, N, N], + [N, N, Y, Y, N, N, Y], + [Y, N, Y, Y, N, Y, N], + [Y, N, Y, Y, N, Y, Y], + [Y, Y, Y, Y, Y, Y, N], + ]; -const DOTS: [(i64, i64); 7] = [(-1, -1), (-1, -0), (-1, 1), (1, -1), (1, 0), (1, 1), (0, 0)]; -const DOTS_FOR_VALUE: [[bool; 7]; 6] = [ - [false, false, false, false, false, false, true], - [false, false, true, true, false, false, false], - [false, false, true, true, false, false, true], - [true, false, true, true, false, true, false], - [true, false, true, true, false, true, true], - [true, true, true, true, true, true, false], -]; + let mut value = use_signal(|| 5); + let active_dots = use_memo(move || &DOTS_FOR_VALUE[(value() - 1) as usize]); -const OFFSET: i64 = 600; -const DOT_RADIUS: &str = "200"; -const HELD_COLOR: &str = "#aaa"; -const UNHELD_COLOR: &str = "#ddd"; - -// A six-sided die (D6) with dots. -#[allow(non_snake_case)] -pub fn Die<'a>(cx: Scope<'a, DieProps<'a>>) -> Element { - let &DieProps { value, keep, .. } = cx.props; - - let active_dots = &DOTS_FOR_VALUE[(value - 1) as usize]; - let fill = if keep { HELD_COLOR } else { UNHELD_COLOR }; - let dots = DOTS - .iter() - .zip(active_dots.iter()) - .filter(|(_, &active)| active) - .map(|((x, y), _)| { - let dcx = x * OFFSET; - let dcy = y * OFFSET; - - rsx! { + rsx! { + svg { + view_box: "-1000 -1000 2000 2000", + prevent_default: "onclick", + onclick: move |_| value.set(thread_rng().gen_range(1..=6)), + rect { x: -1000, y: -1000, width: 2000, height: 2000, rx: 200, fill: "#aaa" } + for ((x, y), _) in DOTS.iter().zip(active_dots.read().iter()).filter(|(_, &active)| active) { circle { - cx: "{dcx}", - cy: "{dcy}", - r: "{DOT_RADIUS}", + cx: *x * 600, + cy: *y * 600, + r: 200, fill: "#333" } } - }); - - cx.render(rsx! { - svg { - onclick: move |e| cx.props.onclick.call(e), - prevent_default: "onclick", - class: "die", - view_box: "-1000 -1000 2000 2000", - - rect { - x: "-1000", - y: "-1000", - width: "2000", - height: "2000", - rx: "{DOT_RADIUS}", - fill: "{fill}", } - - {dots} - } - }) + } } diff --git a/examples/svg_basic.rs b/examples/svg_basic.rs deleted file mode 100644 index 1264aa001..000000000 --- a/examples/svg_basic.rs +++ /dev/null @@ -1,81 +0,0 @@ -use dioxus::prelude::*; - -fn app(cx: Scope) -> Element { - cx.render(rsx!( svg { - width: "200", - height: "250", - xmlns: "http://www.w3.org/2000/svg", - version: "1.1", - rect { - x: "10", - y: "10", - width: "30", - height: "30", - stroke: "black", - fill: "transparent", - stroke_width: "5", - } - rect { - x: "60", - y: "10", - width: "30", - height: "30", - stroke: "black", - fill: "transparent", - stroke_width: "5", - } - circle { - cx: "25", - cy: "75", - r: "20", - stroke: "red", - fill: "transparent", - stroke_width: "5", - } - ellipse { - cx: "75", - cy: "75", - rx: "20", - ry: "5", - stroke: "red", - fill: "transparent", - stroke_width: "5", - } - line { - x1: "10", - x2: "50", - y1: "110", - y2: "150", - stroke: "orange", - stroke_width: "5", - } - polyline { - points: "60 110 65 120 70 115 75 130 80 125 85 140 90 135 95 150 100 145", - stroke: "orange", - fill: "transparent", - stroke_width: "5", - } - polygon { - points: "50 160 55 180 70 180 60 190 65 205 50 195 35 205 40 190 30 180 45 180", - stroke: "green", - fill: "transparent", - stroke_width: "5", - } - path { - d: "M20,230 Q40,205 50,230 T90,230", - fill: "none", - stroke: "blue", - stroke_width: "5", - } - path { - d: "M9.00001 9C9 62 103.5 124 103.5 178", - stroke: "#3CC4DC", - "stroke-linecap": "square", - "stroke-width": "square", - } - })) -} - -fn main() { - dioxus_desktop::launch(app); -} diff --git a/examples/tailwind/Cargo.toml b/examples/tailwind/Cargo.toml index f61f1def8..4a2158c9b 100644 --- a/examples/tailwind/Cargo.toml +++ b/examples/tailwind/Cargo.toml @@ -12,11 +12,10 @@ rust-version = "1.60.0" publish = false [dependencies] -dioxus = { path = "../../packages/dioxus" } manganis = { workspace = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -dioxus-desktop = { path = "../../packages/desktop" } +dioxus = { path = "../../packages/dioxus", features = ["desktop"] } [target.'cfg(target_arch = "wasm32")'.dependencies] -dioxus-web = { path = "../../packages/web" } +dioxus = { path = "../../packages/dioxus", features = ["web"] } diff --git a/examples/tailwind/dist/tailwind3531548035813279582.css b/examples/tailwind/dist/tailwind3531548035813279582.css deleted file mode 100644 index 2196a9412..000000000 --- a/examples/tailwind/dist/tailwind3531548035813279582.css +++ /dev/null @@ -1 +0,0 @@ -*,:before,:after{box-sizing:border-box;border:0 solid #e5e7eb}:before,:after{--tw-content:""}html{-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-feature-settings:normal;font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,Noto Sans,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol,Noto Color Emoji;line-height:1.5}body{line-height:inherit;margin:0}hr{color:inherit;border-top-width:1px;height:0}abbr:where([title]){text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;font-weight:inherit;line-height:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,[type=button],[type=reset],[type=submit]{-webkit-appearance:button;background-color:#0000;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{margin:0;padding:0;list-style:none}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}[hidden]{display:none}*,:before,:after,::backdrop{--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-translate-x:0;--tw-translate-y:0;--tw-rotate:0;--tw-skew-x:0;--tw-skew-y:0;--tw-scale-x:1;--tw-scale-y:1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness:proximity;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-color:#3b82f680;--tw-ring-offset-shadow:0 0 #0000;--tw-ring-shadow:0 0 #0000;--tw-shadow:0 0 #0000;--tw-shadow-colored:0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: }.container{width:100%}@media (width>=640px){.container{max-width:640px}}@media (width>=768px){.container{max-width:768px}}@media (width>=1024px){.container{max-width:1024px}}@media (width>=1280px){.container{max-width:1280px}}@media (width>=1536px){.container{max-width:1536px}}.mx-auto{margin-left:auto;margin-right:auto}.mb-16{margin-bottom:4rem}.mb-4{margin-bottom:1rem}.mb-8{margin-bottom:2rem}.ml-1{margin-left:.25rem}.ml-3{margin-left:.75rem}.ml-4{margin-left:1rem}.mr-5{margin-right:1.25rem}.mt-4{margin-top:1rem}.flex{display:flex}.inline-flex{display:inline-flex}.hidden{display:none}.h-10{height:2.5rem}.h-4{height:1rem}.w-10{width:2.5rem}.w-4{width:1rem}.w-5\/6{width:83.3333%}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.border-0{border-width:0}.bg-gray-800{--tw-bg-opacity:1;background-color:rgb(31 41 55/var(--tw-bg-opacity))}.bg-gray-900{--tw-bg-opacity:1;background-color:rgb(17 24 39/var(--tw-bg-opacity))}.bg-indigo-500{--tw-bg-opacity:1;background-color:rgb(99 102 241/var(--tw-bg-opacity))}.object-cover{-o-object-fit:cover;object-fit:cover}.object-center{-o-object-position:center;object-position:center}.p-2{padding:.5rem}.p-5{padding:1.25rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-24{padding-top:6rem;padding-bottom:6rem}.text-center{text-align:center}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.font-medium{font-weight:500}.leading-relaxed{line-height:1.625}.text-gray-400{--tw-text-opacity:1;color:rgb(156 163 175/var(--tw-text-opacity))}.text-white{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.hover\:bg-gray-700:hover{--tw-bg-opacity:1;background-color:rgb(55 65 81/var(--tw-bg-opacity))}.hover\:bg-indigo-600:hover{--tw-bg-opacity:1;background-color:rgb(79 70 229/var(--tw-bg-opacity))}.hover\:text-white:hover{--tw-text-opacity:1;color:rgb(255 255 255/var(--tw-text-opacity))}.focus\:outline-none:focus{outline-offset:2px;outline:2px solid #0000}@media (width>=640px){.sm\:text-4xl{font-size:2.25rem;line-height:2.5rem}}@media (width>=768px){.md\:mb-0{margin-bottom:0}.md\:ml-auto{margin-left:auto}.md\:mt-0{margin-top:0}.md\:w-1\/2{width:50%}.md\:flex-row{flex-direction:row}.md\:items-start{align-items:flex-start}.md\:pr-16{padding-right:4rem}.md\:text-left{text-align:left}}@media (width>=1024px){.lg\:inline-block{display:inline-block}.lg\:w-full{width:100%}.lg\:max-w-lg{max-width:32rem}.lg\:flex-grow{flex-grow:1}.lg\:pr-24{padding-right:6rem}} \ No newline at end of file diff --git a/examples/tailwind/src/main.rs b/examples/tailwind/src/main.rs index fe0016651..05c7a1021 100644 --- a/examples/tailwind/src/main.rs +++ b/examples/tailwind/src/main.rs @@ -2,36 +2,34 @@ use dioxus::prelude::*; -const _STYLE: &str = manganis::mg!(file("./public/tailwind.css")); +const _STYLE: &str = manganis::mg!(file("public/tailwind.css")); fn main() { - #[cfg(not(target_arch = "wasm32"))] - dioxus_desktop::launch(app); - #[cfg(target_arch = "wasm32")] - dioxus_web::launch(app); + launch(app); } -pub fn app(cx: Scope) -> Element { +pub fn app() -> Element { let grey_background = true; - cx.render(rsx!( + rsx!( div { header { class: "text-gray-400 body-font", // you can use optional attributes to optionally apply a tailwind class - class: if grey_background { "bg-gray-900" }, + class: if grey_background { + "bg-gray-900" + }, div { class: "container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center", a { class: "flex title-font font-medium items-center text-white mb-4 md:mb-0", StacksIcon {} - span { class: "ml-3 text-xl", "Hello Dioxus!"} + span { class: "ml-3 text-xl", "Hello Dioxus!" } } nav { class: "md:ml-auto flex flex-wrap items-center text-base justify-center", - a { class: "mr-5 hover:text-white", "First Link"} - a { class: "mr-5 hover:text-white", "Second Link"} - a { class: "mr-5 hover:text-white", "Third Link"} - a { class: "mr-5 hover:text-white", "Fourth Link"} + a { class: "mr-5 hover:text-white", "First Link" } + a { class: "mr-5 hover:text-white", "Second Link" } + a { class: "mr-5 hover:text-white", "Third Link" } + a { class: "mr-5 hover:text-white", "Fourth Link" } } - button { - class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0", + button { class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0", "Button" RightArrowIcon {} } @@ -45,21 +43,17 @@ pub fn app(cx: Scope) -> Element { br { class: "hidden lg:inline-block" } "Dioxus Sneak Peek" } - p { - class: "mb-8 leading-relaxed", + p { class: "mb-8 leading-relaxed", "Dioxus is a new UI framework that makes it easy and simple to write cross-platform apps using web technologies! It is functional, fast, and portable. Dioxus can run on the web, on the desktop, and on mobile and embedded platforms." - } div { class: "flex justify-center", - button { - class: "inline-flex text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg", + button { class: "inline-flex text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded text-lg", "Learn more" } - button { - class: "ml-4 inline-flex text-gray-400 bg-gray-800 border-0 py-2 px-6 focus:outline-none hover:bg-gray-700 hover:text-white rounded text-lg", + button { class: "ml-4 inline-flex text-gray-400 bg-gray-800 border-0 py-2 px-6 focus:outline-none hover:bg-gray-700 hover:text-white rounded text-lg", "Build an app" } } @@ -68,18 +62,18 @@ pub fn app(cx: Scope) -> Element { img { class: "object-cover object-center rounded", src: "https://i.imgur.com/oK6BLtw.png", - referrerpolicy:"no-referrer", - alt: "hero", + referrerpolicy: "no-referrer", + alt: "hero" } } } } } - )) + ) } -pub fn StacksIcon(cx: Scope) -> Element { - cx.render(rsx!( +pub fn StacksIcon() -> Element { + rsx!( svg { fill: "none", stroke: "currentColor", @@ -88,13 +82,13 @@ pub fn StacksIcon(cx: Scope) -> Element { stroke_width: "2", class: "w-10 h-10 text-white p-2 bg-indigo-500 rounded-full", view_box: "0 0 24 24", - path { d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"} + path { d: "M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5" } } - )) + ) } -pub fn RightArrowIcon(cx: Scope) -> Element { - cx.render(rsx!( +pub fn RightArrowIcon() -> Element { + rsx!( svg { fill: "none", stroke: "currentColor", @@ -103,7 +97,7 @@ pub fn RightArrowIcon(cx: Scope) -> Element { stroke_width: "2", class: "w-4 h-4 ml-1", view_box: "0 0 24 24", - path { d: "M5 12h14M12 5l7 7-7 7"} + path { d: "M5 12h14M12 5l7 7-7 7" } } - )) + ) } diff --git a/examples/tasks.rs b/examples/tasks.rs index 874666c22..887668fb9 100644 --- a/examples/tasks.rs +++ b/examples/tasks.rs @@ -6,29 +6,23 @@ use dioxus::prelude::*; use std::time::Duration; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - let count = use_state(cx, || 0); +fn app() -> Element { + let mut count = use_signal(|| 0); - use_future(cx, (), move |_| { - let mut count = count.clone(); - async move { - loop { - tokio::time::sleep(Duration::from_millis(1000)).await; - count += 1; - } + use_future(move || async move { + loop { + tokio::time::sleep(Duration::from_millis(1000)).await; + count += 1; } }); - cx.render(rsx! { + rsx! { div { h1 { "Current count: {count}" } - button { - onclick: move |_| count.set(0), - "Reset the count" - } + button { onclick: move |_| count.set(0), "Reset the count" } } - }) + } } diff --git a/examples/textarea.rs b/examples/textarea.rs index 62afc45bb..3ad2143ec 100644 --- a/examples/textarea.rs +++ b/examples/textarea.rs @@ -3,15 +3,13 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - let model = use_state(cx, || String::from("asd")); +fn app() -> Element { + let mut model = use_signal(|| String::from("asd")); - println!("{model}"); - - cx.render(rsx! { + rsx! { textarea { class: "border", rows: "10", @@ -19,5 +17,5 @@ fn app(cx: Scope) -> Element { value: "{model}", oninput: move |e| model.set(e.value().clone()), } - }) + } } diff --git a/examples/todomvc.rs b/examples/todomvc.rs index d5e56dd1a..25a124c71 100644 --- a/examples/todomvc.rs +++ b/examples/todomvc.rs @@ -1,104 +1,108 @@ #![allow(non_snake_case)] - use dioxus::prelude::*; use dioxus_elements::input_data::keyboard_types::Key; +use std::collections::HashMap; fn main() { - dioxus_desktop::launch(app); + launch(app); } #[derive(PartialEq, Eq, Clone, Copy)] -pub enum FilterState { +enum FilterState { All, Active, Completed, } -#[derive(Debug, PartialEq, Eq, Clone)] -pub struct TodoItem { - pub id: u32, - pub checked: bool, - pub contents: String, +#[derive(Debug, PartialEq, Eq)] +struct TodoItem { + id: u32, + checked: bool, + contents: String, } -pub fn app(cx: Scope<()>) -> Element { - let todos = use_state(cx, im_rc::HashMap::::default); - let filter = use_state(cx, || FilterState::All); +const STYLE: &str = include_str!("./assets/todomvc.css"); - // Filter the todos based on the filter state - let mut filtered_todos = todos - .iter() - .filter(|(_, item)| match **filter { - FilterState::All => true, - FilterState::Active => !item.checked, - FilterState::Completed => item.checked, - }) - .map(|f| *f.0) - .collect::>(); - filtered_todos.sort_unstable(); +fn app() -> Element { + let mut todos = use_signal(HashMap::::new); + let filter = use_signal(|| FilterState::All); - let active_todo_count = todos.values().filter(|item| !item.checked).count(); - let active_todo_text = match active_todo_count { - 1 => "item", - _ => "items", + let active_todo_count = + use_memo(move || todos.read().values().filter(|item| !item.checked).count()); + + let filtered_todos = use_memo(move || { + let mut filtered_todos = todos + .read() + .iter() + .filter(|(_, item)| match filter() { + FilterState::All => true, + FilterState::Active => !item.checked, + FilterState::Completed => item.checked, + }) + .map(|f| *f.0) + .collect::>(); + + filtered_todos.sort_unstable(); + + filtered_todos + }); + + let toggle_all = move |_| { + let check = active_todo_count() != 0; + for (_, item) in todos.write().iter_mut() { + item.checked = check; + } }; - let show_clear_completed = todos.values().any(|todo| todo.checked); - - cx.render(rsx! { + rsx! { section { class: "todoapp", - style { {include_str!("./assets/todomvc.css")} } - TodoHeader { todos: todos } + style { {STYLE} } + TodoHeader { todos } section { class: "main", - if !todos.is_empty() { + if !todos.read().is_empty() { input { id: "toggle-all", class: "toggle-all", r#type: "checkbox", - onchange: move |_| { - let check = active_todo_count != 0; - for (_, item) in todos.make_mut().iter_mut() { - item.checked = check; - } - }, - checked: if active_todo_count == 0 { "true" } else { "false" }, + onchange: toggle_all, + checked: active_todo_count() == 0, } label { r#for: "toggle-all" } } ul { class: "todo-list", - for id in filtered_todos.iter() { - TodoEntry { - key: "{id}", - id: *id, - todos: todos, - } + for id in filtered_todos() { + TodoEntry { key: "{id}", id, todos } } } - if !todos.is_empty() { - ListFooter { - active_todo_count: active_todo_count, - active_todo_text: active_todo_text, - show_clear_completed: show_clear_completed, - todos: todos, - filter: filter, - } + if !todos.read().is_empty() { + ListFooter { active_todo_count, todos, filter } } } } PageFooter {} - }) + } } -#[derive(Props)] -pub struct TodoHeaderProps<'a> { - todos: &'a UseState>, -} +#[component] +fn TodoHeader(mut todos: Signal>) -> Element { + let mut draft = use_signal(|| "".to_string()); + let mut todo_id = use_signal(|| 0); -pub fn TodoHeader<'a>(cx: Scope<'a, TodoHeaderProps<'a>>) -> Element { - let draft = use_state(cx, || "".to_string()); - let todo_id = use_state(cx, || 0); + let onkeydown = move |evt: KeyboardEvent| { + if evt.key() == Key::Enter && !draft.read().is_empty() { + let id = todo_id(); + let todo = TodoItem { + id, + checked: false, + contents: draft.to_string(), + }; + todos.write().insert(id, todo); + todo_id += 1; + draft.set("".to_string()); + } + }; - cx.render(rsx! { + rsx! { header { class: "header", h1 { "todos" } input { @@ -106,76 +110,46 @@ pub fn TodoHeader<'a>(cx: Scope<'a, TodoHeaderProps<'a>>) -> Element { placeholder: "What needs to be done?", value: "{draft}", autofocus: "true", - oninput: move |evt| { - draft.set(evt.value().clone()); - }, - onkeydown: move |evt| { - if evt.key() == Key::Enter && !draft.is_empty() { - cx.props - .todos - .make_mut() - .insert( - **todo_id, - TodoItem { - id: **todo_id, - checked: false, - contents: draft.to_string(), - }, - ); - *todo_id.make_mut() += 1; - draft.set("".to_string()); - } - } + oninput: move |evt| draft.set(evt.value().clone()), + onkeydown, } } - }) + } } -#[derive(Props)] -pub struct TodoEntryProps<'a> { - todos: &'a UseState>, - id: u32, -} +#[component] +fn TodoEntry(mut todos: Signal>, id: u32) -> Element { + let mut is_editing = use_signal(|| false); + let checked = use_memo(move || todos.read().get(&id).unwrap().checked); + let contents = use_memo(move || todos.read().get(&id).unwrap().contents.clone()); -pub fn TodoEntry<'a>(cx: Scope<'a, TodoEntryProps<'a>>) -> Element { - let is_editing = use_state(cx, || false); - - let todos = cx.props.todos.get(); - let todo = &todos[&cx.props.id]; - let completed = if todo.checked { "completed" } else { "" }; - let editing = if **is_editing { "editing" } else { "" }; - - cx.render(rsx!{ - li { class: "{completed} {editing}", + rsx! { + li { class: if checked() { "completed" }, class: if is_editing() { "editing" }, div { class: "view", input { class: "toggle", r#type: "checkbox", - id: "cbg-{todo.id}", - checked: "{todo.checked}", - oninput: move |evt| { - cx.props.todos.make_mut()[&cx.props.id].checked = evt.value().parse().unwrap(); - } + id: "cbg-{id}", + checked: "{checked}", + oninput: move |evt| todos.write().get_mut(&id).unwrap().checked = evt.value().parse().unwrap(), } label { - r#for: "cbg-{todo.id}", + r#for: "cbg-{id}", ondoubleclick: move |_| is_editing.set(true), prevent_default: "onclick", - "{todo.contents}" + "{contents}" } button { class: "destroy", - onclick: move |_| { - cx.props.todos.make_mut().remove(&todo.id); - }, + onclick: move |_| { todos.write().remove(&id); }, prevent_default: "onclick" } } - if **is_editing { + if is_editing() { input { class: "edit", - value: "{todo.contents}", - oninput: move |evt| cx.props.todos.make_mut()[&cx.props.id].contents = evt.value(), + value: "{contents}", + oninput: move |evt| todos.write().get_mut(&id).unwrap().contents = evt.value(), autofocus: "true", onfocusout: move |_| is_editing.set(false), onkeydown: move |evt| { @@ -183,39 +157,32 @@ pub fn TodoEntry<'a>(cx: Scope<'a, TodoEntryProps<'a>>) -> Element { Key::Enter | Key::Escape | Key::Tab => is_editing.set(false), _ => {} } - }, + } } } } - }) + } } -#[derive(Props)] -pub struct ListFooterProps<'a> { - todos: &'a UseState>, - active_todo_count: usize, - active_todo_text: &'a str, - show_clear_completed: bool, - filter: &'a UseState, -} +#[component] +fn ListFooter( + mut todos: Signal>, + active_todo_count: ReadOnlySignal, + mut filter: Signal, +) -> Element { + let show_clear_completed = use_memo(move || todos.read().values().any(|todo| todo.checked)); -pub fn ListFooter<'a>(cx: Scope<'a, ListFooterProps<'a>>) -> Element { - let active_todo_count = cx.props.active_todo_count; - let active_todo_text = cx.props.active_todo_text; - - let selected = |state| { - if *cx.props.filter == state { - "selected" - } else { - "false" - } - }; - - cx.render(rsx! { + rsx! { footer { class: "footer", span { class: "todo-count", strong { "{active_todo_count} " } - span { "{active_todo_text} left" } + span { + match active_todo_count() { + 1 => "item", + _ => "items", + } + " left" + } } ul { class: "filters", for (state , state_text , url) in [ @@ -226,27 +193,27 @@ pub fn ListFooter<'a>(cx: Scope<'a, ListFooterProps<'a>>) -> Element { li { a { href: url, - class: selected(state), - onclick: move |_| cx.props.filter.set(state), + class: if filter() == state { "selected" }, + onclick: move |_| filter.set(state), prevent_default: "onclick", {state_text} } } } } - if cx.props.show_clear_completed { + if show_clear_completed() { button { class: "clear-completed", - onclick: move |_| cx.props.todos.make_mut().retain(|_, todo| !todo.checked), + onclick: move |_| todos.write().retain(|_, todo| !todo.checked), "Clear completed" } } } - }) + } } -pub fn PageFooter(cx: Scope) -> Element { - cx.render(rsx! { +fn PageFooter() -> Element { + rsx! { footer { class: "info", p { "Double-click to edit a todo" } p { @@ -258,5 +225,5 @@ pub fn PageFooter(cx: Scope) -> Element { a { href: "http://todomvc.com", "TodoMVC" } } } - }) + } } diff --git a/examples/video_stream.rs b/examples/video_stream.rs index c1e0c3c49..b1e23e20d 100644 --- a/examples/video_stream.rs +++ b/examples/video_stream.rs @@ -1,7 +1,7 @@ +use dioxus::desktop::wry::http; +use dioxus::desktop::wry::http::Response; +use dioxus::desktop::{use_asset_handler, AssetRequest}; use dioxus::prelude::*; -use dioxus_desktop::wry::http; -use dioxus_desktop::wry::http::Response; -use dioxus_desktop::{use_asset_handler, AssetRequest}; use http::{header::*, response::Builder as ResponseBuilder, status::StatusCode}; use std::{io::SeekFrom, path::PathBuf}; use tokio::io::AsyncReadExt; @@ -26,11 +26,11 @@ fn main() { } }); } - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - use_asset_handler(cx, "videos", move |request, responder| { +fn app() -> Element { + use_asset_handler("videos", move |request, responder| { // Using dioxus::spawn works, but is slower than a dedicated thread tokio::task::spawn(async move { let video_file = PathBuf::from(VIDEO_PATH); @@ -43,7 +43,7 @@ fn app(cx: Scope) -> Element { }); }); - render! { + rsx! { div { video { src: "/videos/test_video.mp4", diff --git a/examples/web_component.rs b/examples/web_component.rs index bd0f7eb15..9aa712891 100644 --- a/examples/web_component.rs +++ b/examples/web_component.rs @@ -1,13 +1,13 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch(app); } -fn app(cx: Scope) -> Element { - cx.render(rsx! { +fn app() -> Element { + rsx! { web-component { "my-prop": "5%", } - }) + } } diff --git a/examples/window_event.rs b/examples/window_event.rs index ca9b8bab8..edb7c68d8 100644 --- a/examples/window_event.rs +++ b/examples/window_event.rs @@ -1,75 +1,70 @@ +use dioxus::desktop::{window, Config, WindowBuilder}; use dioxus::prelude::*; -use dioxus_desktop::{Config, WindowBuilder}; fn main() { - let cfg = Config::new().with_window( - WindowBuilder::new() - .with_title("Borderless Window") - .with_decorations(false), - ); - - dioxus_desktop::launch_cfg(app, cfg); + LaunchBuilder::desktop() + .with_cfg( + Config::new().with_window( + WindowBuilder::new() + .with_title("Borderless Window") + .with_decorations(false), + ), + ) + .launch(app) } -fn app(cx: Scope) -> Element { - let window = dioxus_desktop::use_window(cx); +fn app() -> Element { + let mut fullscreen = use_signal(|| false); + let mut always_on_top = use_signal(|| false); + let mut decorations = use_signal(|| false); - // if you want to make window fullscreen, you need close the resizable. - // window.set_fullscreen(true); - // window.set_resizable(false); - - let fullscreen = use_state(cx, || false); - let always_on_top = use_state(cx, || false); - let decorations = use_state(cx, || false); - - cx.render(rsx!( - link { href:"https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css", rel:"stylesheet" } + rsx!( + link { + href: "https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css", + rel: "stylesheet" + } header { class: "text-gray-400 bg-gray-900 body-font", - onmousedown: move |_| window.drag(), - div { - class: "container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center", + onmousedown: move |_| window().drag(), + div { class: "container mx-auto flex flex-wrap p-5 flex-col md:flex-row items-center", a { class: "flex title-font font-medium items-center text-white mb-4 md:mb-0", - span { class: "ml-3 text-xl", "Dioxus"} + span { class: "ml-3 text-xl", "Dioxus" } } nav { class: "md:ml-auto flex flex-wrap items-center text-base justify-center" } button { class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0", onmousedown: |evt| evt.stop_propagation(), - onclick: move |_| window.set_minimized(true), + onclick: move |_| window().set_minimized(true), "Minimize" } button { class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0", onmousedown: |evt| evt.stop_propagation(), onclick: move |_| { - - window.set_fullscreen(!**fullscreen); - window.set_resizable(**fullscreen); - fullscreen.modify(|f| !*f); + window().set_fullscreen(!fullscreen()); + window().set_resizable(fullscreen()); + fullscreen.toggle(); }, "Fullscreen" } button { class: "inline-flex items-center bg-gray-800 border-0 py-1 px-3 focus:outline-none hover:bg-gray-700 rounded text-base mt-4 md:mt-0", onmousedown: |evt| evt.stop_propagation(), - onclick: move |_| window.close(), + onclick: move |_| window().close(), "Close" } } } br {} - div { - class: "container mx-auto", - div { - class: "grid grid-cols-5", + div { class: "container mx-auto", + div { class: "grid grid-cols-5", div { button { class: "inline-flex items-center text-white bg-green-500 border-0 py-1 px-3 hover:bg-green-700 rounded", onmousedown: |evt| evt.stop_propagation(), onclick: move |_| { - window.set_always_on_top(!always_on_top); - always_on_top.set(!always_on_top); + window().set_always_on_top(!always_on_top()); + always_on_top.toggle(); }, "Always On Top" } @@ -79,8 +74,8 @@ fn app(cx: Scope) -> Element { class: "inline-flex items-center text-white bg-blue-500 border-0 py-1 px-3 hover:bg-green-700 rounded", onmousedown: |evt| evt.stop_propagation(), onclick: move |_| { - window.set_decorations(!decorations); - decorations.set(!decorations); + window().set_decorations(!decorations()); + decorations.toggle(); }, "Set Decorations" } @@ -89,11 +84,11 @@ fn app(cx: Scope) -> Element { button { class: "inline-flex items-center text-white bg-blue-500 border-0 py-1 px-3 hover:bg-green-700 rounded", onmousedown: |evt| evt.stop_propagation(), - onclick: move |_| window.set_title("Dioxus Application"), + onclick: move |_| window().set_title("Dioxus Application"), "Change Title" } } } } - )) + ) } diff --git a/examples/window_focus.rs b/examples/window_focus.rs index 612e38d6d..04a4b22ae 100644 --- a/examples/window_focus.rs +++ b/examples/window_focus.rs @@ -1,45 +1,35 @@ +use dioxus::desktop::tao::event::Event as WryEvent; +use dioxus::desktop::tao::event::WindowEvent; +use dioxus::desktop::use_wry_event_handler; +use dioxus::desktop::{Config, WindowCloseBehaviour}; use dioxus::prelude::*; -use dioxus_desktop::tao::event::Event as WryEvent; -use dioxus_desktop::tao::event::WindowEvent; -use dioxus_desktop::use_wry_event_handler; -use dioxus_desktop::{Config, WindowCloseBehaviour}; fn main() { - let cfg = Config::new().with_close_behaviour(WindowCloseBehaviour::CloseWindow); - - dioxus_desktop::launch_cfg(app, cfg); + LaunchBuilder::desktop() + .with_cfg(Config::new().with_close_behaviour(WindowCloseBehaviour::CloseWindow)) + .launch(app) } -fn app(cx: Scope) -> Element { - let focused = use_state(cx, || false); +fn app() -> Element { + let mut focused = use_signal(|| true); - use_wry_event_handler(cx, { - to_owned![focused]; - move |event, _| { - if let WryEvent::WindowEvent { - event: WindowEvent::Focused(new_focused), - .. - } = event - { - focused.set(*new_focused); - } + use_wry_event_handler(move |event, _| { + if let WryEvent::WindowEvent { + event: WindowEvent::Focused(new_focused), + .. + } = event + { + focused.set(*new_focused) } }); - cx.render(rsx! { - div{ - width: "100%", - height: "100%", - display: "flex", - flex_direction: "column", - align_items: "center", - { - if *focused.get() { - "This window is focused!" - } else { - "This window is not focused!" - } + rsx! { + div { width: "100%", height: "100%", display: "flex", flex_direction: "column", align_items: "center", + if focused() { + "This window is focused!" + } else { + "This window is not focused!" } } - }) + } } diff --git a/examples/window_zoom.rs b/examples/window_zoom.rs index 840c12215..0c8e19e10 100644 --- a/examples/window_zoom.rs +++ b/examples/window_zoom.rs @@ -1,22 +1,22 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - let level = use_state(cx, || 1.0); +fn app() -> Element { + let mut level = use_signal(|| 1.0); - cx.render(rsx! { + rsx! { input { r#type: "number", value: "{level}", - oninput: |e| { + oninput: move |e| { if let Ok(new_zoom) = e.value().parse::() { level.set(new_zoom); - dioxus_desktop::window().webview.zoom(new_zoom); + dioxus::desktop::window().webview.zoom(new_zoom); } } } - }) + } } diff --git a/examples/xss_safety.rs b/examples/xss_safety.rs index 73da2ff14..8f4dc7245 100644 --- a/examples/xss_safety.rs +++ b/examples/xss_safety.rs @@ -5,15 +5,13 @@ use dioxus::prelude::*; fn main() { - dioxus_desktop::launch(app); + launch_desktop(app); } -fn app(cx: Scope) -> Element { - let contents = use_state(cx, || { - String::from("") - }); +fn app() -> Element { + let mut contents = use_signal(|| String::from("")); - cx.render(rsx! { + rsx! { div { h1 {"Dioxus is XSS-Safe"} h3 { "{contents}" } @@ -23,5 +21,5 @@ fn app(cx: Scope) -> Element { oninput: move |e| contents.set(e.value()), } } - }) + } } diff --git a/packages/autofmt/tests/samples/immediate_expr.rsx b/packages/autofmt/tests/samples/immediate_expr.rsx index cea8dc7db..a88522cb0 100644 --- a/packages/autofmt/tests/samples/immediate_expr.rsx +++ b/packages/autofmt/tests/samples/immediate_expr.rsx @@ -1,4 +1,4 @@ fn it_works() { - cx.render(rsx!({()})) + rsx!({()}) } diff --git a/packages/autofmt/tests/samples/long.rsx b/packages/autofmt/tests/samples/long.rsx index 056e16061..4b283475a 100644 --- a/packages/autofmt/tests/samples/long.rsx +++ b/packages/autofmt/tests/samples/long.rsx @@ -5,8 +5,8 @@ pub fn Explainer<'a>( cx: Scope<'a>, invert: bool, title: &'static str, - content: Element<'a>, - flasher: Element<'a>, + content: Element, + flasher: Element, ) -> Element { // pt-5 sm:pt-24 lg:pt-24 @@ -32,10 +32,10 @@ pub fn Explainer<'a>( std::mem::swap(&mut left, &mut right); } - cx.render(rsx! { + rsx! { div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", {left}, {right} } - }) + } } diff --git a/packages/autofmt/tests/samples/messy_indent.rsx b/packages/autofmt/tests/samples/messy_indent.rsx index 0fba72031..9cb04001d 100644 --- a/packages/autofmt/tests/samples/messy_indent.rsx +++ b/packages/autofmt/tests/samples/messy_indent.rsx @@ -1,4 +1,4 @@ -fn SaveClipboard(cx: Scope) -> Element { +fn SaveClipboard() -> Element { rsx! { div { class: "relative w-1/2 {align} max-w-md leading-8", h2 { class: "mb-6 text-3xl leading-tight md:text-4xl md:leading-tight lg:text-3xl lg:leading-tight font-heading font-mono font-bold", @@ -7,7 +7,7 @@ fn SaveClipboard(cx: Scope) -> Element { } }; - cx.render(rsx! { + rsx! { div { "hello world", "hello world", "hello world" } - }) + } } diff --git a/packages/autofmt/tests/samples/reallylong.rsx b/packages/autofmt/tests/samples/reallylong.rsx index 98e9765ae..544e470dc 100644 --- a/packages/autofmt/tests/samples/reallylong.rsx +++ b/packages/autofmt/tests/samples/reallylong.rsx @@ -1,5 +1,5 @@ pub static Icon3: Component<()> = |cx| { - cx.render(rsx! { + rsx! { svg { class: "w-6 h-6", stroke_linecap: "round", @@ -11,5 +11,5 @@ pub static Icon3: Component<()> = |cx| { path { d: "M20 21v-2a4 4 0 00-4-4H8a4 4 0 00-4 4v2" } circle { cx: "12", cy: "7", r: "4" } } - }) + } }; diff --git a/packages/autofmt/tests/samples/trailing_expr.rsx b/packages/autofmt/tests/samples/trailing_expr.rsx index a57a822ab..8f5054351 100644 --- a/packages/autofmt/tests/samples/trailing_expr.rsx +++ b/packages/autofmt/tests/samples/trailing_expr.rsx @@ -1,7 +1,7 @@ fn it_works() { - cx.render(rsx! { + rsx! { div { span { "Description: ", {package.description.as_deref().unwrap_or("❌❌❌❌ missing")} } } - }) + } } diff --git a/packages/autofmt/tests/wrong/multi-4sp.rsx b/packages/autofmt/tests/wrong/multi-4sp.rsx index d43b9a1e9..0f4a1a473 100644 --- a/packages/autofmt/tests/wrong/multi-4sp.rsx +++ b/packages/autofmt/tests/wrong/multi-4sp.rsx @@ -1,3 +1,3 @@ -fn app(cx: Scope) -> Element { - cx.render(rsx! { div { "hello world" } }) +fn app() -> Element { + rsx! { div { "hello world" } } } diff --git a/packages/autofmt/tests/wrong/multi-4sp.wrong.rsx b/packages/autofmt/tests/wrong/multi-4sp.wrong.rsx index ccb6cab03..2c7203122 100644 --- a/packages/autofmt/tests/wrong/multi-4sp.wrong.rsx +++ b/packages/autofmt/tests/wrong/multi-4sp.wrong.rsx @@ -1,5 +1,5 @@ -fn app(cx: Scope) -> Element { - cx.render(rsx! { +fn app() -> Element { + rsx! { div {"hello world" } - }) + } } diff --git a/packages/autofmt/tests/wrong/multi-tab.rsx b/packages/autofmt/tests/wrong/multi-tab.rsx index 1fb85c3d0..86058a8b8 100644 --- a/packages/autofmt/tests/wrong/multi-tab.rsx +++ b/packages/autofmt/tests/wrong/multi-tab.rsx @@ -1,3 +1,3 @@ -fn app(cx: Scope) -> Element { - cx.render(rsx! { div { "hello world" } }) +fn app() -> Element { + rsx! { div { "hello world" } } } diff --git a/packages/autofmt/tests/wrong/multi-tab.wrong.rsx b/packages/autofmt/tests/wrong/multi-tab.wrong.rsx index d818f9535..a5c6f5d68 100644 --- a/packages/autofmt/tests/wrong/multi-tab.wrong.rsx +++ b/packages/autofmt/tests/wrong/multi-tab.wrong.rsx @@ -1,5 +1,5 @@ -fn app(cx: Scope) -> Element { - cx.render(rsx! { +fn app() -> Element { + rsx! { div {"hello world" } - }) + } } diff --git a/packages/autofmt/tests/wrong/multiexpr-4sp.rsx b/packages/autofmt/tests/wrong/multiexpr-4sp.rsx index ecb2f8bdc..cbf84a125 100644 --- a/packages/autofmt/tests/wrong/multiexpr-4sp.rsx +++ b/packages/autofmt/tests/wrong/multiexpr-4sp.rsx @@ -1,8 +1,8 @@ fn ItWroks() { - cx.render(rsx! { + rsx! { div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", {left}, {right} } - }) + } } diff --git a/packages/autofmt/tests/wrong/multiexpr-4sp.wrong.rsx b/packages/autofmt/tests/wrong/multiexpr-4sp.wrong.rsx index 15752f172..e7ea98f37 100644 --- a/packages/autofmt/tests/wrong/multiexpr-4sp.wrong.rsx +++ b/packages/autofmt/tests/wrong/multiexpr-4sp.wrong.rsx @@ -1,5 +1,5 @@ fn ItWroks() { - cx.render(rsx! { + rsx! { div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", {left}, {right} } - }) + } } diff --git a/packages/autofmt/tests/wrong/multiexpr-tab.rsx b/packages/autofmt/tests/wrong/multiexpr-tab.rsx index 85f2216a1..faf6d717d 100644 --- a/packages/autofmt/tests/wrong/multiexpr-tab.rsx +++ b/packages/autofmt/tests/wrong/multiexpr-tab.rsx @@ -1,8 +1,8 @@ fn ItWroks() { - cx.render(rsx! { + rsx! { div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", {left}, {right} } - }) + } } diff --git a/packages/autofmt/tests/wrong/multiexpr-tab.wrong.rsx b/packages/autofmt/tests/wrong/multiexpr-tab.wrong.rsx index 6872d0b43..e024b50d2 100644 --- a/packages/autofmt/tests/wrong/multiexpr-tab.wrong.rsx +++ b/packages/autofmt/tests/wrong/multiexpr-tab.wrong.rsx @@ -1,5 +1,5 @@ fn ItWroks() { - cx.render(rsx! { + rsx! { div { class: "flex flex-wrap items-center dark:text-white py-16 border-t font-light", {left}, {right} } - }) + } } diff --git a/packages/check/src/check.rs b/packages/check/src/check.rs index c3a8ecf2f..d5fdd5f33 100644 --- a/packages/check/src/check.rs +++ b/packages/check/src/check.rs @@ -279,7 +279,7 @@ mod tests { #[test] fn test_no_hooks() { let contents = indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { rsx! { p { "Hello World" } } @@ -294,8 +294,8 @@ mod tests { #[test] fn test_hook_correctly_used_inside_component() { let contents = indoc! {r#" - fn App(cx: Scope) -> Element { - let count = use_state(cx, || 0); + fn App() -> Element { + let count = use_signal(|| 0); rsx! { p { "Hello World: {count}" } } @@ -310,8 +310,8 @@ mod tests { #[test] fn test_hook_correctly_used_inside_hook_fn() { let contents = indoc! {r#" - fn use_thing(cx: Scope) -> UseState { - use_state(cx, || 0) + fn use_thing() -> UseState { + use_signal(|| 0) } "#}; @@ -323,9 +323,9 @@ mod tests { #[test] fn test_hook_correctly_used_inside_hook_closure() { let contents = indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { let use_thing = || { - use_state(cx, || 0) + use_signal(|| 0) }; let count = use_thing(); rsx! { @@ -342,9 +342,9 @@ mod tests { #[test] fn test_conditional_hook_if() { let contents = indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { if you_are_happy && you_know_it { - let something = use_state(cx, || "hands"); + let something = use_signal(|| "hands"); println!("clap your {something}") } } @@ -357,18 +357,18 @@ mod tests { vec![Issue::HookInsideConditional( HookInfo::new( Span::new_from_str( - r#"use_state(cx, || "hands")"#, + r#"use_signal(|| "hands")"#, LineColumn { line: 3, column: 24 }, ), Span::new_from_str( - r#"use_state"#, + r#"use_signal"#, LineColumn { line: 3, column: 24 }, ), - "use_state".to_string() + "use_signal".to_string() ), ConditionalInfo::If(IfInfo::new( Span::new_from_str( - "if you_are_happy && you_know_it {\n let something = use_state(cx, || \"hands\");\n println!(\"clap your {something}\")\n }", + "if you_are_happy && you_know_it {\n let something = use_signal(|| \"hands\");\n println!(\"clap your {something}\")\n }", LineColumn { line: 2, column: 4 }, ), Span::new_from_str( @@ -383,10 +383,10 @@ mod tests { #[test] fn test_conditional_hook_match() { let contents = indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { match you_are_happy && you_know_it { true => { - let something = use_state(cx, || "hands"); + let something = use_signal(|| "hands"); println!("clap your {something}") } false => {} @@ -400,13 +400,13 @@ mod tests { report.issues, vec![Issue::HookInsideConditional( HookInfo::new( - Span::new_from_str(r#"use_state(cx, || "hands")"#, LineColumn { line: 4, column: 28 }), - Span::new_from_str(r#"use_state"#, LineColumn { line: 4, column: 28 }), - "use_state".to_string() + Span::new_from_str(r#"use_signal(|| "hands")"#, LineColumn { line: 4, column: 28 }), + Span::new_from_str(r#"use_signal"#, LineColumn { line: 4, column: 28 }), + "use_signal".to_string() ), ConditionalInfo::Match(MatchInfo::new( Span::new_from_str( - "match you_are_happy && you_know_it {\n true => {\n let something = use_state(cx, || \"hands\");\n println!(\"clap your {something}\")\n }\n false => {}\n }", + "match you_are_happy && you_know_it {\n true => {\n let something = use_signal(|| \"hands\");\n println!(\"clap your {something}\")\n }\n false => {}\n }", LineColumn { line: 2, column: 4 }, ), Span::new_from_str("match you_are_happy && you_know_it", LineColumn { line: 2, column: 4 }) @@ -418,9 +418,9 @@ mod tests { #[test] fn test_for_loop_hook() { let contents = indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { for _name in &names { - let is_selected = use_state(cx, || false); + let is_selected = use_signal(|| false); println!("selected: {is_selected}"); } } @@ -433,18 +433,18 @@ mod tests { vec![Issue::HookInsideLoop( HookInfo::new( Span::new_from_str( - "use_state(cx, || false)", + "use_signal(|| false)", LineColumn { line: 3, column: 26 }, ), Span::new_from_str( - "use_state", + "use_signal", LineColumn { line: 3, column: 26 }, ), - "use_state".to_string() + "use_signal".to_string() ), AnyLoopInfo::For(ForInfo::new( Span::new_from_str( - "for _name in &names {\n let is_selected = use_state(cx, || false);\n println!(\"selected: {is_selected}\");\n }", + "for _name in &names {\n let is_selected = use_signal(|| false);\n println!(\"selected: {is_selected}\");\n }", LineColumn { line: 2, column: 4 }, ), Span::new_from_str( @@ -459,9 +459,9 @@ mod tests { #[test] fn test_while_loop_hook() { let contents = indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { while true { - let something = use_state(cx, || "hands"); + let something = use_signal(|| "hands"); println!("clap your {something}") } } @@ -474,18 +474,18 @@ mod tests { vec![Issue::HookInsideLoop( HookInfo::new( Span::new_from_str( - r#"use_state(cx, || "hands")"#, + r#"use_signal(|| "hands")"#, LineColumn { line: 3, column: 24 }, ), Span::new_from_str( - "use_state", + "use_signal", LineColumn { line: 3, column: 24 }, ), - "use_state".to_string() + "use_signal".to_string() ), AnyLoopInfo::While(WhileInfo::new( Span::new_from_str( - "while true {\n let something = use_state(cx, || \"hands\");\n println!(\"clap your {something}\")\n }", + "while true {\n let something = use_signal(|| \"hands\");\n println!(\"clap your {something}\")\n }", LineColumn { line: 2, column: 4 }, ), Span::new_from_str( @@ -500,9 +500,9 @@ mod tests { #[test] fn test_loop_hook() { let contents = indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { loop { - let something = use_state(cx, || "hands"); + let something = use_signal(|| "hands"); println!("clap your {something}") } } @@ -515,17 +515,17 @@ mod tests { vec![Issue::HookInsideLoop( HookInfo::new( Span::new_from_str( - r#"use_state(cx, || "hands")"#, + r#"use_signal(|| "hands")"#, LineColumn { line: 3, column: 24 }, ), Span::new_from_str( - "use_state", + "use_signal", LineColumn { line: 3, column: 24 }, ), - "use_state".to_string() + "use_signal".to_string() ), AnyLoopInfo::Loop(LoopInfo::new(Span::new_from_str( - "loop {\n let something = use_state(cx, || \"hands\");\n println!(\"clap your {something}\")\n }", + "loop {\n let something = use_signal(|| \"hands\");\n println!(\"clap your {something}\")\n }", LineColumn { line: 2, column: 4 }, ))) )], @@ -535,8 +535,8 @@ mod tests { #[test] fn test_conditional_okay() { let contents = indoc! {r#" - fn App(cx: Scope) -> Element { - let something = use_state(cx, || "hands"); + fn App() -> Element { + let something = use_signal(|| "hands"); if you_are_happy && you_know_it { println!("clap your {something}") } @@ -551,9 +551,9 @@ mod tests { #[test] fn test_closure_hook() { let contents = indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { let _a = || { - let b = use_state(cx, || 0); + let b = use_signal(|| 0); b.get() }; } @@ -566,23 +566,23 @@ mod tests { vec![Issue::HookInsideClosure( HookInfo::new( Span::new_from_str( - "use_state(cx, || 0)", + "use_signal(|| 0)", LineColumn { line: 3, column: 16 }, ), Span::new_from_str( - "use_state", + "use_signal", LineColumn { line: 3, column: 16 }, ), - "use_state".to_string() + "use_signal".to_string() ), ClosureInfo::new(Span::new_from_str( - "|| {\n let b = use_state(cx, || 0);\n b.get()\n }", + "|| {\n let b = use_signal(|| 0);\n b.get()\n }", LineColumn { line: 2, column: 13 @@ -595,8 +595,8 @@ mod tests { #[test] fn test_hook_outside_component() { let contents = indoc! {r#" - fn not_component_or_hook(cx: Scope) { - let _a = use_state(cx, || 0); + fn not_component_or_hook() { + let _a = use_signal(|| 0); } "#}; @@ -606,20 +606,20 @@ mod tests { report.issues, vec![Issue::HookOutsideComponent(HookInfo::new( Span::new_from_str( - "use_state(cx, || 0)", + "use_signal(|| 0)", LineColumn { line: 2, column: 13 } ), Span::new_from_str( - "use_state", + "use_signal", LineColumn { line: 2, column: 13 }, ), - "use_state".to_string() + "use_signal".to_string() ))] ); } @@ -627,8 +627,8 @@ mod tests { #[test] fn test_hook_inside_hook() { let contents = indoc! {r#" - fn use_thing(cx: Scope) { - let _a = use_state(cx, || 0); + fn use_thing() { + let _a = use_signal(|| 0); } "#}; diff --git a/packages/check/src/issues.rs b/packages/check/src/issues.rs index 34d20eaef..bd6aed3c9 100644 --- a/packages/check/src/issues.rs +++ b/packages/check/src/issues.rs @@ -230,9 +230,9 @@ mod tests { let issue_report = check_file( "src/main.rs".into(), indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { if you_are_happy && you_know_it { - let something = use_state(cx, || "hands"); + let something = use_signal(|| "hands"); println!("clap your {something}") } } @@ -240,11 +240,11 @@ mod tests { ); let expected = indoc! {r#" - error: hook called conditionally: `use_state` (inside `if`) + error: hook called conditionally: `use_signal` (inside `if`) --> src/main.rs:3:25 | - 3 | let something = use_state(cx, || "hands"); - | ^^^^^^^^^ + 3 | let something = use_signal(|| "hands"); + | ^^^^^^^^^^ | = note: `if you_are_happy && you_know_it { … }` is the conditional "#}; @@ -258,10 +258,10 @@ mod tests { let issue_report = check_file( "src/main.rs".into(), indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { match you_are_happy && you_know_it { true => { - let something = use_state(cx, || "hands"); + let something = use_signal(|| "hands"); println!("clap your {something}") } _ => {} @@ -271,11 +271,11 @@ mod tests { ); let expected = indoc! {r#" - error: hook called conditionally: `use_state` (inside `match`) + error: hook called conditionally: `use_signal` (inside `match`) --> src/main.rs:4:29 | - 4 | let something = use_state(cx, || "hands"); - | ^^^^^^^^^ + 4 | let something = use_signal(|| "hands"); + | ^^^^^^^^^^ | = note: `match you_are_happy && you_know_it { … }` is the conditional "#}; @@ -289,9 +289,9 @@ mod tests { let issue_report = check_file( "src/main.rs".into(), indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { for i in 0..10 { - let something = use_state(cx, || "hands"); + let something = use_signal(|| "hands"); println!("clap your {something}") } } @@ -299,11 +299,11 @@ mod tests { ); let expected = indoc! {r#" - error: hook called in a loop: `use_state` (inside `for` loop) + error: hook called in a loop: `use_signal` (inside `for` loop) --> src/main.rs:3:25 | - 3 | let something = use_state(cx, || "hands"); - | ^^^^^^^^^ + 3 | let something = use_signal(|| "hands"); + | ^^^^^^^^^^ | = note: `for i in 0..10 { … }` is the loop "#}; @@ -317,9 +317,9 @@ mod tests { let issue_report = check_file( "src/main.rs".into(), indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { while check_thing() { - let something = use_state(cx, || "hands"); + let something = use_signal(|| "hands"); println!("clap your {something}") } } @@ -327,11 +327,11 @@ mod tests { ); let expected = indoc! {r#" - error: hook called in a loop: `use_state` (inside `while` loop) + error: hook called in a loop: `use_signal` (inside `while` loop) --> src/main.rs:3:25 | - 3 | let something = use_state(cx, || "hands"); - | ^^^^^^^^^ + 3 | let something = use_signal(|| "hands"); + | ^^^^^^^^^^ | = note: `while check_thing() { … }` is the loop "#}; @@ -345,9 +345,9 @@ mod tests { let issue_report = check_file( "src/main.rs".into(), indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { loop { - let something = use_state(cx, || "hands"); + let something = use_signal(|| "hands"); println!("clap your {something}") } } @@ -355,11 +355,11 @@ mod tests { ); let expected = indoc! {r#" - error: hook called in a loop: `use_state` (inside `loop`) + error: hook called in a loop: `use_signal` (inside `loop`) --> src/main.rs:3:25 | - 3 | let something = use_state(cx, || "hands"); - | ^^^^^^^^^ + 3 | let something = use_signal(|| "hands"); + | ^^^^^^^^^^ | = note: `loop { … }` is the loop "#}; @@ -373,9 +373,9 @@ mod tests { let issue_report = check_file( "src/main.rs".into(), indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { let something = || { - let something = use_state(cx, || "hands"); + let something = use_signal(|| "hands"); println!("clap your {something}") }; } @@ -383,11 +383,11 @@ mod tests { ); let expected = indoc! {r#" - error: hook called in a closure: `use_state` + error: hook called in a closure: `use_signal` --> src/main.rs:3:25 | - 3 | let something = use_state(cx, || "hands"); - | ^^^^^^^^^ + 3 | let something = use_signal(|| "hands"); + | ^^^^^^^^^^ "#}; assert_eq!(expected, issue_report.to_string()); @@ -399,9 +399,9 @@ mod tests { let issue_report = check_file( "src/main.rs".into(), indoc! {r#" - fn App(cx: Scope) -> Element { + fn App() -> Element { if you_are_happy && you_know_it { - let something = use_state(cx, || { + let something = use_signal(|| { "hands" }); println!("clap your {something}") @@ -411,11 +411,11 @@ mod tests { ); let expected = indoc! {r#" - error: hook called conditionally: `use_state` (inside `if`) + error: hook called conditionally: `use_signal` (inside `if`) --> src/main.rs:3:25 | - 3 | let something = use_state(cx, || { - | ^^^^^^^^^ + 3 | let something = use_signal(|| { + | ^^^^^^^^^^ 4 | "hands" 5 | }); | diff --git a/packages/check/src/metadata.rs b/packages/check/src/metadata.rs index 28ab87b74..19c3b7f7b 100644 --- a/packages/check/src/metadata.rs +++ b/packages/check/src/metadata.rs @@ -3,7 +3,7 @@ pub struct HookInfo { /// The name of the hook, e.g. `use_state`. pub name: String, - /// The span of the hook, e.g. `use_state(cx, || 0)`. + /// The span of the hook, e.g. `use_signal(|| 0)`. pub span: Span, /// The span of the name, e.g. `use_state`. pub name_span: Span, diff --git a/packages/cli-config/Cargo.toml b/packages/cli-config/Cargo.toml index d6f422b3c..2bcbea1f1 100644 --- a/packages/cli-config/Cargo.toml +++ b/packages/cli-config/Cargo.toml @@ -15,7 +15,7 @@ serde_json = "1.0.79" toml = { version = "0.5.8", optional = true } cargo_toml = { version = "0.16.0", optional = true } once_cell = "1.18.0" -tracing.workspace = true +tracing = { workspace = true } # bundling tauri-bundler = { version = "=1.4.0", features = ["native-tls-vendored"], optional = true } diff --git a/packages/cli-config/src/config.rs b/packages/cli-config/src/config.rs index bdfcf016b..7ef92dcf0 100644 --- a/packages/cli-config/src/config.rs +++ b/packages/cli-config/src/config.rs @@ -392,7 +392,12 @@ impl CrateConfig { None => manifest .bin .iter() - .find(|b| b.name == manifest.package.as_ref().map(|pkg| pkg.name.clone())) + .find(|b| { + #[allow(clippy::useless_asref)] + let matching_bin = + b.name == manifest.package.as_ref().map(|pkg| pkg.name.clone()); + matching_bin + }) .or(manifest .bin .iter() @@ -448,6 +453,22 @@ impl CrateConfig { self.crate_dir.join(&self.dioxus_config.application.out_dir) } + /// Compose an out directory for the fullstack platform. See `out_dir()` + /// method. + pub fn fullstack_out_dir(&self) -> PathBuf { + self.crate_dir.join(".dioxus") + } + + /// Compose a target directory for the server (fullstack-only?). + pub fn server_target_dir(&self) -> PathBuf { + self.fullstack_out_dir().join("ssr") + } + + /// Compose a target directory for the client (fullstack-only?). + pub fn client_target_dir(&self) -> PathBuf { + self.fullstack_out_dir().join("web") + } + pub fn as_example(&mut self, example_name: String) -> &mut Self { self.executable = ExecutableType::Example(example_name); self diff --git a/packages/cli/Cargo.toml b/packages/cli/Cargo.toml index dc53b7442..82c16e0dc 100644 --- a/packages/cli/Cargo.toml +++ b/packages/cli/Cargo.toml @@ -24,7 +24,7 @@ serde_json = "1.0.79" toml = "0.8.8" fs_extra = "1.2.0" cargo_toml = "0.18.0" -futures-util.workspace = true +futures-util = { workspace = true } notify = { version = "5.0.0-pre.16", features = ["serde"] } html_parser = { workspace = true } cargo_metadata = "0.18.1" diff --git a/packages/cli/src/assets.rs b/packages/cli/src/assets.rs index c9fee435f..897ba6320 100644 --- a/packages/cli/src/assets.rs +++ b/packages/cli/src/assets.rs @@ -37,9 +37,9 @@ pub(crate) fn process_assets(config: &CrateConfig, manifest: &AssetManifest) -> } /// A guard that sets up the environment for the web renderer to compile in. This guard sets the location that assets will be served from -pub(crate) struct WebAssetConfigDropGuard; +pub(crate) struct AssetConfigDropGuard; -impl WebAssetConfigDropGuard { +impl AssetConfigDropGuard { pub fn new() -> Self { // Set up the collect asset config manganis_cli_support::Config::default() @@ -49,7 +49,7 @@ impl WebAssetConfigDropGuard { } } -impl Drop for WebAssetConfigDropGuard { +impl Drop for AssetConfigDropGuard { fn drop(&mut self) { // Reset the config manganis_cli_support::Config::default().save(); diff --git a/packages/cli/src/builder.rs b/packages/cli/src/builder.rs index 40563fccd..d33778ec9 100644 --- a/packages/cli/src/builder.rs +++ b/packages/cli/src/builder.rs @@ -1,5 +1,5 @@ use crate::{ - assets::{asset_manifest, create_assets_head, process_assets, WebAssetConfigDropGuard}, + assets::{asset_manifest, create_assets_head, process_assets, AssetConfigDropGuard}, error::{Error, Result}, tools::Tool, }; @@ -11,6 +11,7 @@ use indicatif::{ProgressBar, ProgressStyle}; use lazy_static::lazy_static; use manganis_cli_support::{AssetManifest, ManganisSupportGuard}; use std::{ + env, fs::{copy, create_dir_all, File}, io::Read, panic, @@ -30,7 +31,45 @@ pub struct BuildResult { pub assets: Option, } -pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result { +/// This trait is only created for the convenient and concise way to set +/// `RUSTFLAGS` environment variable for the `subprocess::Exec`. +pub trait ExecWithRustFlagsSetter { + fn set_rust_flags(self, rust_flags: Option) -> Self; +} + +impl ExecWithRustFlagsSetter for subprocess::Exec { + /// Sets (appends to, if already set) `RUSTFLAGS` environment variable if + /// `rust_flags` is not `None`. + fn set_rust_flags(self, rust_flags: Option) -> Self { + if let Some(rust_flags) = rust_flags { + // Some `RUSTFLAGS` might be already set in the environment or provided + // by the user. They should take higher priority than the default flags. + // If no default flags are provided, then there is no point in + // redefining the environment variable with the same value, if it is + // even set. If no custom flags are set, then there is no point in + // adding the unnecessary whitespace to the command. + self.env( + "RUSTFLAGS", + if let Ok(custom_rust_flags) = env::var("RUSTFLAGS") { + rust_flags + " " + custom_rust_flags.as_str() + } else { + rust_flags + }, + ) + } else { + self + } + } +} + +/// Build client (WASM). +/// Note: `rust_flags` argument is only used for the fullstack platform. +pub fn build( + config: &CrateConfig, + _: bool, + skip_assets: bool, + rust_flags: Option, +) -> Result { // [1] Build the project with cargo, generating a wasm32-unknown-unknown target (is there a more specific, better target to leverage?) // [2] Generate the appropriate build folders // [3] Wasm-bindgen the .wasm file, and move it into the {builddir}/modules/xxxx/xxxx_bg.wasm @@ -48,7 +87,7 @@ pub fn build(config: &CrateConfig, _: bool, skip_assets: bool) -> Result Result Result Result, ) -> Result { log::info!("🚅 Running build [Desktop] command..."); @@ -294,8 +339,10 @@ pub fn build_desktop( let ignore_files = build_assets(config)?; let _guard = dioxus_cli_config::__private::save_config(config); let _manganis_support = ManganisSupportGuard::default(); + let _guard = AssetConfigDropGuard::new(); let mut cmd = subprocess::Exec::cmd("cargo") + .set_rust_flags(rust_flags) .env("CARGO_TARGET_DIR", &config.target_dir) .cwd(&config.crate_dir) .arg("build") @@ -489,7 +536,7 @@ fn prettier_build(cmd: subprocess::Exec) -> anyhow::Result> { } pub fn gen_page(config: &CrateConfig, manifest: Option<&AssetManifest>, serve: bool) -> String { - let _gaurd = WebAssetConfigDropGuard::new(); + let _guard = AssetConfigDropGuard::new(); let crate_root = crate_root().unwrap(); let custom_html_file = crate_root.join("index.html"); diff --git a/packages/cli/src/cli/autoformat.rs b/packages/cli/src/cli/autoformat.rs index 83fbdc1b8..2b8093f75 100644 --- a/packages/cli/src/cli/autoformat.rs +++ b/packages/cli/src/cli/autoformat.rs @@ -161,6 +161,10 @@ async fn autoformat_project( return Ok(()); } + if files_to_format.is_empty() { + return Ok(()); + } + let indent = indentation_for(&files_to_format[0], split_line_attributes)?; let counts = files_to_format diff --git a/packages/cli/src/cli/build.rs b/packages/cli/src/cli/build.rs index ad15a8cf5..8c47fcda7 100644 --- a/packages/cli/src/cli/build.rs +++ b/packages/cli/src/cli/build.rs @@ -1,8 +1,7 @@ -use crate::assets::WebAssetConfigDropGuard; +use crate::assets::AssetConfigDropGuard; #[cfg(feature = "plugin")] use crate::plugin::PluginManager; -use crate::server::fullstack::FullstackServerEnvGuard; -use crate::server::fullstack::FullstackWebEnvGuard; +use crate::server::fullstack; use dioxus_cli_config::Platform; use super::*; @@ -16,7 +15,13 @@ pub struct Build { } impl Build { - pub fn build(self, bin: Option, target_dir: Option<&std::path::Path>) -> Result<()> { + /// Note: `rust_flags` argument is only used for the fullstack platform. + pub fn build( + self, + bin: Option, + target_dir: Option<&std::path::Path>, + rust_flags: Option, + ) -> Result<()> { let mut crate_config = dioxus_cli_config::CrateConfig::new(bin)?; if let Some(target_dir) = target_dir { crate_config.target_dir = target_dir.to_path_buf(); @@ -53,16 +58,23 @@ impl Build { // let _ = PluginManager::on_build_start(&crate_config, &platform); let build_result = match platform { - Platform::Web => crate::builder::build(&crate_config, false, self.build.skip_assets)?, + Platform::Web => { + // `rust_flags` are used by fullstack's client build. + crate::builder::build(&crate_config, false, self.build.skip_assets, rust_flags)? + } Platform::Desktop => { - crate::builder::build_desktop(&crate_config, false, self.build.skip_assets)? + // Since desktop platform doesn't use `rust_flags`, this + // argument is explicitly set to `None`. + crate::builder::build_desktop(&crate_config, false, self.build.skip_assets, None)? } Platform::Fullstack => { - // Fullstack mode must be built with web configs on the desktop (server) binary as well as the web binary - let _config = WebAssetConfigDropGuard::new(); + // Fullstack mode must be built with web configs on the desktop + // (server) binary as well as the web binary + let _config = AssetConfigDropGuard::new(); + let client_rust_flags = fullstack::client_rust_flags(&self.build); + let server_rust_flags = fullstack::server_rust_flags(&self.build); { let mut web_config = crate_config.clone(); - let _gaurd = FullstackWebEnvGuard::new(&self.build); let web_feature = self.build.client_feature; let features = &mut web_config.features; match features { @@ -71,7 +83,12 @@ impl Build { } None => web_config.features = Some(vec![web_feature]), }; - crate::builder::build(&crate_config, false, self.build.skip_assets)?; + crate::builder::build( + &web_config, + false, + self.build.skip_assets, + Some(client_rust_flags), + )?; } { let mut desktop_config = crate_config.clone(); @@ -83,21 +100,19 @@ impl Build { } None => desktop_config.features = Some(vec![desktop_feature]), }; - let _gaurd = - FullstackServerEnvGuard::new(self.build.force_debug, self.build.release); - crate::builder::build_desktop(&desktop_config, false, self.build.skip_assets)? + crate::builder::build_desktop( + &desktop_config, + false, + self.build.skip_assets, + Some(server_rust_flags), + )? } } }; let temp = gen_page(&crate_config, build_result.assets.as_ref(), false); - let mut file = std::fs::File::create( - crate_config - .crate_dir - .join(crate_config.dioxus_config.application.out_dir.clone()) - .join("index.html"), - )?; + let mut file = std::fs::File::create(crate_config.out_dir().join("index.html"))?; file.write_all(temp.as_bytes())?; // #[cfg(feature = "plugin")] diff --git a/packages/cli/src/cli/bundle.rs b/packages/cli/src/cli/bundle.rs index 1bc3a4ff6..44c8548b3 100644 --- a/packages/cli/src/cli/bundle.rs +++ b/packages/cli/src/cli/bundle.rs @@ -84,7 +84,9 @@ impl Bundle { crate_config.set_cargo_args(self.build.cargo_args); // build the desktop app - build_desktop(&crate_config, false, false)?; + // Since the `bundle()` function is only run for the desktop platform, + // the `rust_flags` argument is set to `None`. + build_desktop(&crate_config, false, false, None)?; // copy the binary to the out dir let package = crate_config.manifest.package.as_ref().unwrap(); diff --git a/packages/cli/src/cli/cfg.rs b/packages/cli/src/cli/cfg.rs index 6f0fe247f..c764d77d6 100644 --- a/packages/cli/src/cli/cfg.rs +++ b/packages/cli/src/cli/cfg.rs @@ -6,7 +6,7 @@ use super::*; #[derive(Clone, Debug, Default, Deserialize, Parser)] pub struct ConfigOptsBuild { /// Build in release mode [default: false] - #[clap(long)] + #[clap(long, short)] #[serde(default)] pub release: bool, @@ -45,8 +45,8 @@ pub struct ConfigOptsBuild { #[clap(long, default_value_t = { "web".to_string() })] pub client_feature: String, - /// The feature to use for the server in a fullstack app [default: "ssr"] - #[clap(long, default_value_t = { "ssr".to_string() })] + /// The feature to use for the server in a fullstack app [default: "server"] + #[clap(long, default_value_t = { "server".to_string() })] pub server_feature: String, /// Rustc platform triple @@ -142,8 +142,8 @@ pub struct ConfigOptsServe { #[clap(long, default_value_t = { "web".to_string() })] pub client_feature: String, - /// The feature to use for the server in a fullstack app [default: "ssr"] - #[clap(long, default_value_t = { "ssr".to_string() })] + /// The feature to use for the server in a fullstack app [default: "server"] + #[clap(long, default_value_t = { "server".to_string() })] pub server_feature: String, /// Rustc platform triple @@ -159,7 +159,7 @@ pub struct ConfigOptsServe { #[derive(Clone, Debug, Default, Deserialize, Parser)] pub struct ConfigOptsBundle { /// Build in release mode [default: false] - #[clap(long)] + #[clap(long, short)] #[serde(default)] pub release: bool, diff --git a/packages/cli/src/cli/clean.rs b/packages/cli/src/cli/clean.rs index 04e0cb45b..a66bac3ac 100644 --- a/packages/cli/src/cli/clean.rs +++ b/packages/cli/src/cli/clean.rs @@ -19,12 +19,12 @@ impl Clean { return custom_error!("Cargo clean failed."); } - let out_dir = crate_config.dioxus_config.application.out_dir; - if crate_config.crate_dir.join(&out_dir).is_dir() { - remove_dir_all(crate_config.crate_dir.join(&out_dir))?; + let out_dir = &crate_config.out_dir(); + if out_dir.is_dir() { + remove_dir_all(out_dir)?; } - let fullstack_out_dir = crate_config.crate_dir.join(".dioxus"); + let fullstack_out_dir = crate_config.fullstack_out_dir(); if fullstack_out_dir.is_dir() { remove_dir_all(fullstack_out_dir)?; diff --git a/packages/cli/src/cli/serve.rs b/packages/cli/src/cli/serve.rs index 5a483ec54..3ace461ef 100644 --- a/packages/cli/src/cli/serve.rs +++ b/packages/cli/src/cli/serve.rs @@ -73,9 +73,7 @@ impl Serve { ) -> anyhow::Result<()> { let serve_html = gen_page(crate_config, manifest, true); - let dist_path = crate_config - .crate_dir - .join(crate_config.dioxus_config.application.out_dir.clone()); + let dist_path = crate_config.out_dir(); if !dist_path.is_dir() { create_dir_all(&dist_path)?; } diff --git a/packages/cli/src/cli/translate.rs b/packages/cli/src/cli/translate.rs index d3901e651..2dfbfe8c2 100644 --- a/packages/cli/src/cli/translate.rs +++ b/packages/cli/src/cli/translate.rs @@ -71,7 +71,7 @@ fn write_callbody_with_icon_section(mut callbody: CallBody) -> String { } fn write_component_body(raw: String) -> String { - let mut out = String::from("fn component(cx: Scope) -> Element {\n cx.render(rsx! {"); + let mut out = String::from("fn component() -> Element {\n rsx! {"); indent_and_write(&raw, 1, &mut out); out.push_str(" })\n}"); out @@ -84,7 +84,7 @@ fn write_svg_section(out: &mut String, svgs: Vec) { let raw = dioxus_autofmt::write_block_out(CallBody { roots: vec![icon] }).unwrap(); out.push_str("\n\n pub fn icon_"); out.push_str(&idx.to_string()); - out.push_str("(cx: Scope) -> Element {\n cx.render(rsx! {"); + out.push_str("() -> Element {\n rsx! {"); indent_and_write(&raw, 2, out); out.push_str(" })\n }"); } diff --git a/packages/cli/src/main.rs b/packages/cli/src/main.rs index d09dea9e4..0a57735db 100644 --- a/packages/cli/src/main.rs +++ b/packages/cli/src/main.rs @@ -99,7 +99,7 @@ async fn main() -> anyhow::Result<()> { match action { Build(opts) => opts - .build(Some(bin.clone()), None) + .build(Some(bin.clone()), None, None) .context(error_wrapper("Building project failed")), Clean(opts) => opts diff --git a/packages/cli/src/plugin/mod.rs b/packages/cli/src/plugin/mod.rs index 2aa1f9868..03bf34c5f 100644 --- a/packages/cli/src/plugin/mod.rs +++ b/packages/cli/src/plugin/mod.rs @@ -4,14 +4,11 @@ use std::{ sync::Mutex, }; +use crate::tools::{app_path, clone_repo}; +use dioxus_cli_config::CrateConfig; use mlua::{Lua, Table}; use serde_json::json; -use crate::{ - tools::{app_path, clone_repo}, - CrateConfig, -}; - use self::{ interface::{ command::PluginCommander, dirs::PluginDirs, fs::PluginFileSystem, log::PluginLogger, diff --git a/packages/cli/src/server/desktop/mod.rs b/packages/cli/src/server/desktop/mod.rs index c91ac1397..22aeb407d 100644 --- a/packages/cli/src/server/desktop/mod.rs +++ b/packages/cli/src/server/desktop/mod.rs @@ -14,6 +14,7 @@ use dioxus_hot_reload::HotReloadMsg; use dioxus_html::HtmlCtx; use dioxus_rsx::hot_reload::*; use interprocess_docfix::local_socket::LocalSocketListener; +use std::fs::create_dir_all; use std::{ process::{Child, Command}, sync::{Arc, Mutex, RwLock}, @@ -21,7 +22,7 @@ use std::{ use tokio::sync::broadcast::{self}; #[cfg(feature = "plugin")] -use plugin::PluginManager; +use crate::plugin::PluginManager; use super::HotReloadState; @@ -109,6 +110,7 @@ async fn start_desktop_hot_reload(hot_reload_state: HotReloadState) -> Result<() .exec() .unwrap(); let target_dir = metadata.target_directory.as_std_path(); + let _ = create_dir_all(target_dir); // `_all` is for good measure and future-proofness. let path = target_dir.join("dioxusin"); clear_paths(&path); match LocalSocketListener::bind(path) { @@ -213,9 +215,14 @@ fn send_msg(msg: HotReloadMsg, channel: &mut impl std::io::Write) -> bool { } } -fn start_desktop(config: &CrateConfig, skip_assets: bool) -> Result<(RAIIChild, BuildResult)> { +fn start_desktop( + config: &CrateConfig, + skip_assets: bool, + rust_flags: Option, +) -> Result<(RAIIChild, BuildResult)> { // Run the desktop application - let result = crate::builder::build_desktop(config, true, skip_assets)?; + // Only used for the fullstack platform, + let result = crate::builder::build_desktop(config, true, skip_assets, rust_flags)?; match &config.executable { ExecutableType::Binary(name) @@ -242,9 +249,15 @@ pub(crate) struct DesktopPlatform { skip_assets: bool, } -impl Platform for DesktopPlatform { - fn start(config: &CrateConfig, serve: &ConfigOptsServe) -> Result { - let (child, first_build_result) = start_desktop(config, serve.skip_assets)?; +impl DesktopPlatform { + /// `rust_flags` argument is added because it is used by the + /// `DesktopPlatform`'s implementation of the `Platform::start()`. + pub fn start_with_options( + config: &CrateConfig, + serve: &ConfigOptsServe, + rust_flags: Option, + ) -> Result { + let (child, first_build_result) = start_desktop(config, serve.skip_assets, rust_flags)?; log::info!("🚀 Starting development server..."); @@ -265,14 +278,38 @@ impl Platform for DesktopPlatform { }) } - fn rebuild(&mut self, config: &CrateConfig) -> Result { + /// `rust_flags` argument is added because it is used by the + /// `DesktopPlatform`'s implementation of the `Platform::rebuild()`. + pub fn rebuild_with_options( + &mut self, + config: &CrateConfig, + rust_flags: Option, + ) -> Result { self.currently_running_child.0.kill()?; - let (child, result) = start_desktop(config, self.skip_assets)?; + let (child, result) = start_desktop(config, self.skip_assets, rust_flags)?; self.currently_running_child = child; Ok(result) } } +impl Platform for DesktopPlatform { + fn start(config: &CrateConfig, serve: &ConfigOptsServe) -> Result { + // See `start_with_options()`'s docs for the explanation why the code + // was moved there. + // Since desktop platform doesn't use `rust_flags`, this argument is + // explicitly set to `None`. + DesktopPlatform::start_with_options(config, serve, None) + } + + fn rebuild(&mut self, config: &CrateConfig) -> Result { + // See `rebuild_with_options()`'s docs for the explanation why the code + // was moved there. + // Since desktop platform doesn't use `rust_flags`, this argument is + // explicitly set to `None`. + DesktopPlatform::rebuild_with_options(self, config, None) + } +} + struct RAIIChild(Child); impl Drop for RAIIChild { diff --git a/packages/cli/src/server/fullstack/mod.rs b/packages/cli/src/server/fullstack/mod.rs index 60d685ced..1f9a4446c 100644 --- a/packages/cli/src/server/fullstack/mod.rs +++ b/packages/cli/src/server/fullstack/mod.rs @@ -1,13 +1,38 @@ use dioxus_cli_config::CrateConfig; use crate::{ - assets::WebAssetConfigDropGuard, cfg::{ConfigOptsBuild, ConfigOptsServe}, Result, }; use super::{desktop, Platform}; +static CLIENT_RUST_FLAGS: &str = "-C debuginfo=none -C strip=debuginfo"; +// The `opt-level=2` increases build times, but can noticeably decrease time +// between saving changes and being able to interact with an app. The "overall" +// time difference (between having and not having the optimization) can be +// almost imperceptible (~1 s) but also can be very noticeable (~6 s) — depends +// on setup (hardware, OS, browser, idle load). +static SERVER_RUST_FLAGS: &str = "-C opt-level=2"; +static DEBUG_RUST_FLAG: &str = "-C debug-assertions"; + +fn rust_flags(build: &ConfigOptsBuild, base_flags: &str) -> String { + let mut rust_flags = base_flags.to_string(); + if !build.release { + rust_flags += " "; + rust_flags += DEBUG_RUST_FLAG; + }; + rust_flags +} + +pub fn client_rust_flags(build: &ConfigOptsBuild) -> String { + rust_flags(build, CLIENT_RUST_FLAGS) +} + +pub fn server_rust_flags(build: &ConfigOptsBuild) -> String { + rust_flags(build, SERVER_RUST_FLAGS) +} + pub async fn startup(config: CrateConfig, serve: &ConfigOptsServe) -> Result<()> { desktop::startup_with_platform::(config, serve).await } @@ -17,15 +42,29 @@ fn start_web_build_thread( serve: &ConfigOptsServe, ) -> std::thread::JoinHandle> { let serve = serve.clone(); - let target_directory = config.crate_dir.join(".dioxus").join("web"); + let target_directory = config.client_target_dir(); std::fs::create_dir_all(&target_directory).unwrap(); std::thread::spawn(move || build_web(serve, &target_directory)) } +fn make_desktop_config(config: &CrateConfig, serve: &ConfigOptsServe) -> CrateConfig { + let mut desktop_config = config.clone(); + desktop_config.target_dir = config.server_target_dir(); + let desktop_feature = serve.server_feature.clone(); + let features = &mut desktop_config.features; + match features { + Some(features) => { + features.push(desktop_feature); + } + None => desktop_config.features = Some(vec![desktop_feature]), + }; + desktop_config +} + struct FullstackPlatform { serve: ConfigOptsServe, desktop: desktop::DesktopPlatform, - _config: WebAssetConfigDropGuard, + server_rust_flags: String, } impl Platform for FullstackPlatform { @@ -35,17 +74,13 @@ impl Platform for FullstackPlatform { { let thread_handle = start_web_build_thread(config, serve); - let mut desktop_config = config.clone(); - let desktop_feature = serve.server_feature.clone(); - let features = &mut desktop_config.features; - match features { - Some(features) => { - features.push(desktop_feature); - } - None => desktop_config.features = Some(vec![desktop_feature]), - }; - let config = WebAssetConfigDropGuard::new(); - let desktop = desktop::DesktopPlatform::start(&desktop_config, serve)?; + let desktop_config = make_desktop_config(config, serve); + let server_rust_flags = server_rust_flags(&serve.clone().into()); + let desktop = desktop::DesktopPlatform::start_with_options( + &desktop_config, + serve, + Some(server_rust_flags.clone()), + )?; thread_handle .join() .map_err(|_| anyhow::anyhow!("Failed to join thread"))??; @@ -53,25 +88,16 @@ impl Platform for FullstackPlatform { Ok(Self { desktop, serve: serve.clone(), - _config: config, + server_rust_flags, }) } fn rebuild(&mut self, crate_config: &CrateConfig) -> Result { let thread_handle = start_web_build_thread(crate_config, &self.serve); - let result = { - let mut desktop_config = crate_config.clone(); - let desktop_feature = self.serve.server_feature.clone(); - let features = &mut desktop_config.features; - match features { - Some(features) => { - features.push(desktop_feature); - } - None => desktop_config.features = Some(vec![desktop_feature]), - }; - let _gaurd = FullstackServerEnvGuard::new(self.serve.force_debug, self.serve.release); - self.desktop.rebuild(&desktop_config) - }; + let desktop_config = make_desktop_config(crate_config, &self.serve); + let result = self + .desktop + .rebuild_with_options(&desktop_config, Some(self.server_rust_flags.clone())); thread_handle .join() .map_err(|_| anyhow::anyhow!("Failed to join thread"))??; @@ -91,74 +117,12 @@ fn build_web(serve: ConfigOptsServe, target_directory: &std::path::Path) -> Resu }; web_config.platform = Some(dioxus_cli_config::Platform::Web); - let _gaurd = FullstackWebEnvGuard::new(&web_config); - crate::cli::build::Build { build: web_config }.build(None, Some(target_directory)) -} - -// Debug mode web builds have a very large size by default. If debug mode is not enabled, we strip some of the debug info by default -// This reduces a hello world from ~40MB to ~2MB -pub(crate) struct FullstackWebEnvGuard { - old_rustflags: Option, -} - -impl FullstackWebEnvGuard { - pub fn new(serve: &ConfigOptsBuild) -> Self { - Self { - old_rustflags: (!serve.force_debug).then(|| { - let old_rustflags = std::env::var("RUSTFLAGS").unwrap_or_default(); - let debug_assertions = if serve.release { - "" - } else { - " -C debug-assertions" - }; - - std::env::set_var( - "RUSTFLAGS", - format!( - "{old_rustflags} -C debuginfo=none -C strip=debuginfo{debug_assertions}" - ), - ); - old_rustflags - }), - } - } -} - -impl Drop for FullstackWebEnvGuard { - fn drop(&mut self) { - if let Some(old_rustflags) = self.old_rustflags.take() { - std::env::set_var("RUSTFLAGS", old_rustflags); - } - } -} - -// Debug mode web builds have a very large size by default. If debug mode is not enabled, we strip some of the debug info by default -// This reduces a hello world from ~40MB to ~2MB -pub(crate) struct FullstackServerEnvGuard { - old_rustflags: Option, -} - -impl FullstackServerEnvGuard { - pub fn new(debug: bool, release: bool) -> Self { - Self { - old_rustflags: (!debug).then(|| { - let old_rustflags = std::env::var("RUSTFLAGS").unwrap_or_default(); - let debug_assertions = if release { "" } else { " -C debug-assertions" }; - - std::env::set_var( - "RUSTFLAGS", - format!("{old_rustflags} -C opt-level=2 {debug_assertions}"), - ); - old_rustflags - }), - } - } -} - -impl Drop for FullstackServerEnvGuard { - fn drop(&mut self) { - if let Some(old_rustflags) = self.old_rustflags.take() { - std::env::set_var("RUSTFLAGS", old_rustflags); - } + crate::cli::build::Build { + build: web_config.clone(), } + .build( + None, + Some(target_directory), + Some(client_rust_flags(&web_config)), + ) } diff --git a/packages/cli/src/server/mod.rs b/packages/cli/src/server/mod.rs index d5fc7cf41..bd1cafdd8 100644 --- a/packages/cli/src/server/mod.rs +++ b/packages/cli/src/server/mod.rs @@ -40,7 +40,7 @@ async fn setup_file_watcher Result + Send + 'static>( if let Some(hot_reload) = &hot_reload { // find changes to the rsx in the file let mut rsx_file_map = hot_reload.file_map.lock().unwrap(); - let mut messages: Vec> = Vec::new(); + let mut messages: Vec