diff --git a/.bumpversion.toml b/.bumpversion.toml new file mode 100755 index 0000000..9e33567 --- /dev/null +++ b/.bumpversion.toml @@ -0,0 +1,6 @@ +[bumpversion] +current_version = 0.0.1 + +[bumpversion:file:Cargo.toml] +search = version = "{current_version}" +replace = version = "{new_version}" diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..e8d486a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +# To get started with Dependabot version updates, you'll need to specify which +# package ecosystems to update and where the package manifests are located. +# Please see the documentation for all configuration options: +# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates + +version: 2 +updates: + - package-ecosystem: "cargo" # See documentation for possible values + directory: "/" # Location of package manifests + schedule: + interval: "weekly" diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml new file mode 100644 index 0000000..ad8dfc8 --- /dev/null +++ b/.github/workflows/rust.yml @@ -0,0 +1,21 @@ +name: CI + +on: + push: + branches: ["main"] + pull_request: + branches: ["main"] + +env: + CARGO_TERM_COLOR: always + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Build + run: cargo build --verbose + - name: Run tests + run: cargo test --all-features diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c24ee2b --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +**/target +**/dist \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..915db36 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1397 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "anymap2" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "boolinator" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfa8873f51c92e232f9bac4065cddef41b714152812bfc5f7672ba16d6ef8cd9" + +[[package]] +name = "bump2version" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e36c41d33255a91625cd331c58b76323b084c42d2b79ae37b3471fe239ef23d" +dependencies = [ + "clap", + "regex", +] + +[[package]] +name = "bumpalo" +version = "3.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" + +[[package]] +name = "bytes" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "clap" +version = "4.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3135e7ec2ef7b10c6ed8950f0f792ed96ee093fa088608f1c76e569722700c84" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30582fc632330df2bd26877bde0c1f4470d57c582bbc070376afcd04d8cb4838" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_derive" +version = "4.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ac6a0c7b1a9e9a5186361f67dfa1b88213572f427fb9ab038efb2bd8c582dab" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi", + "wasm-bindgen", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "gloo" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28999cda5ef6916ffd33fb4a7b87e1de633c47c0dc6d97905fee1cdaa142b94d" +dependencies = [ + "gloo-console 0.2.3", + "gloo-dialogs 0.1.1", + "gloo-events 0.1.2", + "gloo-file 0.2.3", + "gloo-history 0.1.5", + "gloo-net 0.3.1", + "gloo-render 0.1.1", + "gloo-storage 0.2.2", + "gloo-timers 0.2.6", + "gloo-utils 0.1.7", + "gloo-worker 0.2.1", +] + +[[package]] +name = "gloo" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd35526c28cc55c1db77aed6296de58677dbab863b118483a27845631d870249" +dependencies = [ + "gloo-console 0.3.0", + "gloo-dialogs 0.2.0", + "gloo-events 0.2.0", + "gloo-file 0.3.0", + "gloo-history 0.2.2", + "gloo-net 0.4.0", + "gloo-render 0.2.0", + "gloo-storage 0.3.0", + "gloo-timers 0.3.0", + "gloo-utils 0.2.0", + "gloo-worker 0.4.0", +] + +[[package]] +name = "gloo-console" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b7ce3c05debe147233596904981848862b068862e9ec3e34be446077190d3f" +dependencies = [ + "gloo-utils 0.1.7", + "js-sys", + "serde", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-console" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a17868f56b4a24f677b17c8cb69958385102fa879418052d60b50bc1727e261" +dependencies = [ + "gloo-utils 0.2.0", + "js-sys", + "serde", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-dialogs" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67062364ac72d27f08445a46cab428188e2e224ec9e37efdba48ae8c289002e6" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-dialogs" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf4748e10122b01435750ff530095b1217cf6546173459448b83913ebe7815df" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-events" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68b107f8abed8105e4182de63845afcc7b69c098b7852a813ea7462a320992fc" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-events" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c26fb45f7c385ba980f5fa87ac677e363949e065a083722697ef1b2cc91e41" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-file" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d5564e570a38b43d78bdc063374a0c3098c4f0d64005b12f9bbe87e869b6d7" +dependencies = [ + "gloo-events 0.1.2", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-file" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97563d71863fb2824b2e974e754a81d19c4a7ec47b09ced8a0e6656b6d54bd1f" +dependencies = [ + "gloo-events 0.2.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-history" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85725d90bf0ed47063b3930ef28e863658a7905989e9929a8708aab74a1d5e7f" +dependencies = [ + "gloo-events 0.1.2", + "gloo-utils 0.1.7", + "serde", + "serde-wasm-bindgen 0.5.0", + "serde_urlencoded", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-history" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "903f432be5ba34427eac5e16048ef65604a82061fe93789f2212afc73d8617d6" +dependencies = [ + "getrandom", + "gloo-events 0.2.0", + "gloo-utils 0.2.0", + "serde", + "serde-wasm-bindgen 0.6.5", + "serde_urlencoded", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-net" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66b4e3c7d9ed8d315fd6b97c8b1f74a7c6ecbbc2320e65ae7ed38b7068cc620" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils 0.1.7", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-net" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ac9e8288ae2c632fa9f8657ac70bfe38a1530f345282d7ba66a1f70b72b7dc4" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils 0.2.0", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-render" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2fd9306aef67cfd4449823aadcd14e3958e0800aa2183955a309112a84ec7764" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-render" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56008b6744713a8e8d98ac3dcb7d06543d5662358c9c805b4ce2167ad4649833" +dependencies = [ + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-storage" +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", + "js-sys", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13471584da78061a28306d1359dd0178d8d6fc1c7c80e5e35d27260346e0516a" +dependencies = [ + "anymap2", + "bincode", + "gloo-console 0.2.3", + "gloo-utils 0.1.7", + "js-sys", + "serde", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-worker" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76495d3dd87de51da268fa3a593da118ab43eb7f8809e17eb38d3319b424e400" +dependencies = [ + "bincode", + "futures", + "gloo-utils 0.2.0", + "gloo-worker-macros", + "js-sys", + "pinned", + "serde", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-worker-macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956caa58d4857bc9941749d55e4bd3000032d8212762586fa5705632967140e7" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "hashbrown" +version = "0.15.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "implicit-clone" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a9aa791c7b5a71b636b7a68207fdebf171ddfc593d9c8506ec4cbc527b6a84" +dependencies = [ + "implicit-clone-derive", + "indexmap", +] + +[[package]] +name = "implicit-clone-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9311685eb9a34808bbb0608ad2fcab9ae216266beca5848613e95553ac914e3b" +dependencies = [ + "quote", + "syn 2.0.91", +] + +[[package]] +name = "indexmap" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itoa" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" + +[[package]] +name = "js-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6717b6b5b077764fb5966237269cb3c64edddde4b14ce42647430a78ced9e7b7" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "libc" +version = "0.2.169" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" + +[[package]] +name = "log" +version = "0.4.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "miniz_oxide" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ffbe83022cedc1d264172192511ae958937694cd57ce297164951b8b3568394" +dependencies = [ + "adler2", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" + +[[package]] +name = "percent-encoding" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" + +[[package]] +name = "pin-project" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be57f64e946e500c8ee36ef6331845d40a93055567ec57e8fae13efd33759b95" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c0f5fad0874fc7abcd4d750e76917eaebbecaa2c20bde22e1dbeeba8beb758c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pinned" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a829027bd95e54cfe13e3e258a1ae7b645960553fb82b75ff852c29688ee595b" +dependencies = [ + "futures", + "rustversion", + "thiserror", +] + +[[package]] +name = "prettyplease" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64d1ec885c64d0457d564db4ec299b2dae3f9c02808b8ad9c3a089c591b18033" +dependencies = [ + "proc-macro2", + "syn 2.0.91", +] + +[[package]] +name = "proc-macro-crate" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f4c021e1093a56626774e81216a4ce732a735e5bad4868a03f3ed65ca0c3919" +dependencies = [ + "once_cell", + "toml_edit", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.92" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37d3544b3f2748c54e147655edb5025752e2303145b5aefb3c3ea2c78b973bb0" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prokio" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03b55e106e5791fa5a13abd13c85d6127312e8e09098059ca2bc9b03ca4cf488" +dependencies = [ + "futures", + "gloo 0.8.1", + "num_cpus", + "once_cell", + "pin-project", + "pinned", + "tokio", + "tokio-stream", + "wasm-bindgen-futures", +] + +[[package]] +name = "quote" +version = "1.0.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "regex" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustversion" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248" + +[[package]] +name = "ryu" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" + +[[package]] +name = "selectrs" +version = "0.0.1" +dependencies = [ + "bump2version", + "log", + "yew", +] + +[[package]] +name = "serde" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9781016e935a97e8beecf0c933758c97a5520d32930e460142b4cd80c6338e" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde-wasm-bindgen" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8302e169f0eddcc139c70f139d19d6467353af16f9fce27e8c30158036a1e16b" +dependencies = [ + "js-sys", + "serde", + "wasm-bindgen", +] + +[[package]] +name = "serde_derive" +version = "1.0.216" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46f859dbbf73865c6627ed570e78961cd3ac92407a2d117204c49232485da55e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "serde_json" +version = "1.0.134" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d00f4175c42ee48b15416f6193a959ba3a0d67fc699a0db9ad12df9f83991c7d" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.91" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d53cbcb5a243bd33b7858b1d7f4aca2153490815872d86d955d6ea29f743c035" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "tokio" +version = "1.42.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cec9b21b0450273377fc97bd4c33a8acffc8c996c987a7c5b319a0083707551" +dependencies = [ + "backtrace", + "pin-project-lite", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", +] + +[[package]] +name = "unicode-ident" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a474f6281d1d70c17ae7aa6a613c87fce69a127e2624002df63dcb39d6cf6396" +dependencies = [ + "cfg-if", + "once_cell", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f89bb38646b4f81674e8f5c3fb81b562be1fd936d84320f3264486418519c79" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.91", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.49" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38176d9b44ea84e9184eff0bc34cc167ed044f816accfe5922e54d84cf48eca2" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc6181fd9a7492eef6fef1f33961e3695e4579b9872a6f7c83aee556666d4fe" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d7a95b763d3c45903ed6c81f156801839e5ee968bb07e534c44df0fcd330c2" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.91", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943aab3fdaaa029a6e0271b35ea10b72b943135afe9bffca82384098ad0e06a6" + +[[package]] +name = "web-sys" +version = "0.3.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04dd7223427d52553d3702c004d3b2fe07c148165faa56313cb00211e31c12bc" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "yew" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f1a03f255c70c7aa3e9c62e15292f142ede0564123543c1cc0c7a4f31660cac" +dependencies = [ + "console_error_panic_hook", + "futures", + "gloo 0.10.0", + "implicit-clone", + "indexmap", + "js-sys", + "prokio", + "rustversion", + "serde", + "slab", + "thiserror", + "tokio", + "tracing", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "yew-macro", +] + +[[package]] +name = "yew-macro" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02fd8ca5166d69e59f796500a2ce432ff751edecbbb308ca59fd3fe4d0343de2" +dependencies = [ + "boolinator", + "once_cell", + "prettyplease", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.91", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..e90e4d4 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "selectrs" +version = "0.0.1" +edition = "2021" +rust-version = "1.79" +description = "🔽 A highly customizable select component for WASM frameworks like Yew, Dioxus, and Leptos." +license = "MIT" +keywords = ["select", "yew", "rust", "dioxus", "leptos"] +categories = ["web-programming", "science"] +repository = "https://github.com/opensass/select-rs" +documentation = "https://docs.rs/selectrs/" +authors = ["Mahmoud Harmouch "] +exclude = ["assets", "examples"] + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +yew = { version = "0.21.0", default-features = false, optional = true } + +[features] +yew = ["dep:yew"] + +[profile.release] +opt-level = "z" +debug = false +lto = "thin" +codegen-units = 1 +panic = "abort" +strip = "symbols" +incremental = false + +[badges] +maintenance = { status = "actively-developed" } + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dev-dependencies] +log = "0.4.22" +bump2version = "0.1.4" diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..062d4e1 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 Open SASS Core Maintainers + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 14f68fd..53f21cb 100644 --- a/README.md +++ b/README.md @@ -1 +1,64 @@ -# select-rs +
+ +# 🔽 Select RS + +[![Crates.io](https://img.shields.io/crates/v/selectrs)](https://crates.io/crates/selectrs) +[![Crates.io Downloads](https://img.shields.io/crates/d/selectrs)](https://crates.io/crates/selectrs) +![Crates.io License](https://img.shields.io/crates/l/selectrs) +[![made-with-rust](https://img.shields.io/badge/Made%20with-Rust-1f425f.svg?logo=rust&logoColor=white)](https://www.rust-lang.org/) +[![Rust](https://img.shields.io/badge/Rust-1.79%2B-blue.svg)](https://www.rust-lang.org) +[![Maintenance](https://img.shields.io/badge/Maintained%3F-yes-green.svg)](https://github.com/wiseaidev) + +[![Join our Discord](https://dcbadge.limes.pink/api/server/b5JbvHW5nv)](https://discord.gg/b5JbvHW5nv) + +![logo](./assets/logo.webp) + +
+ +## 🎬 Demo + +![select-rs-demo](./assets/demo.gif) + +| Framework | Live Demo | +| --- | --- | +| Yew | [![Netlify Status](https://api.netlify.com/api/v1/badges/b2f7d257-599e-4eab-a6c6-7ff655f3caf4/deploy-status)](https://select-rs.netlify.app) | +| Dioxus | TODO | +| Leptos | TODO | + +## 📜 Intro + +Select RS is a highly customizable `select` dropdown component for Wasm-based frameworks like **Yew**, **Dioxus**, and **Leptos**. It supports both single and multiple selections, and offers extensive customization options for styling, interaction, and behavior. + +## 🤔 Why Use Select RS? + +The following are some reasons why you should consider using Select RS in your WASM-based projects: + +1. **🎨 Custom Styling**: Style your select dropdown with custom classes, inline styles, and more to fit your design needs. +1. **⚡ Callbacks**: Handle user selection with efficient callbacks to manage state changes dynamically. +1. **📱 Multiple Selections**: Supports single or multiple selection modes with visual enhancements such as selected chips that can be removed. +1. **🔍 Accessibility**: Ensures accessibility with built-in support for required fields, autocomplete, and focus handling. +1. **💡 Customizable Placeholders**: Easily configure placeholder text for a better user experience. + +## Yew Usage + +Refer to [our guide](YEW.md) to integrate this component into your Yew app. + +## 🧬 Dioxus Usage (TODO) + +Refer to [our guide](DIOXUS.md) to integrate this component into your Dioxus app. + +## 🌱 Leptos Usage (TODO) + +Refer to [our guide](LEPTOS.md) to integrate this component into your Leptos app. + +## 🤝 Contributions + +Contributions are welcome! Whether it's bug fixes, feature requests, or examples, we would love your help to improve Select RS. + +1. Fork the repository. +1. Create a new branch for your feature/bugfix. +1. Submit a pull request for review. + +## 📜 License + +Select RS is licensed under the [MIT License](LICENSE). You are free to use, modify, and distribute this library in your projects. diff --git a/YEW.md b/YEW.md new file mode 100644 index 0000000..a7aee99 --- /dev/null +++ b/YEW.md @@ -0,0 +1,210 @@ +# Y Select RS Yew Usage + +Adding Select RS to your project is simple: + +1. Make sure your project is set up with **Yew**. Follow their [Getting Started Guide](https://yew.rs/docs/getting-started/introduction) for setup instructions. + +1. Add the `select-rs` crate to your dependencies by including it in your `Cargo.toml` file: + + ```sh + cargo add selectrs --features=yew + ``` + +1. Import the `Select`, `Option`, and `Group` components into your Yew component and start using them in your app. + +## 🛠️ Usage + +Incorporating Select RS into your application is easy. Follow these steps: + +1. Import the `Select`, `Option`, and `Group` components into your Yew project: + + ```rust + use yew::prelude::*; + use selectrs::yew::{Select, Option, Group}; + ``` + +1. Use the `Select` component in your Yew application: + + ```rust + use yew::prelude::*; + use selectrs::yew::{Select, Option, Group}; + + #[function_component(App)] + pub fn app() -> Html { + let onchange = Callback::from(|selected_values: Vec| { + log::info!("Selected: {:?}", selected_values); + }); + + html! { + + } + } + ``` + +## 🔧 Props + +### Select Component + +#### Main Props + +| Property | Type | Description | Default | +| -------------- | -------------------------- | ----------------------------------------------------------------------------- | ------- | +| `name` | `&'static str` | The name attribute of the select component, important for form submission. | `""` | +| `id` | `&'static str` | The unique ID for the select element. | `""` | +| `placeholder` | `&'static str` | Placeholder text displayed when no option is selected. | `""` | +| `multiple` | `bool` | Whether multiple options can be selected. | `false` | +| `required` | `bool` | Marks the field as required for form submission. | `false` | +| `size` | `u64` | Number of visible options in the dropdown (applies only for `multiple=true`). | `0` | +| `form` | `&'static str` | Associates the select element with a specific form by its ID. | `""` | +| `autocomplete` | `&'static str` | Provides an autocomplete hint. | `""` | +| `autofocus` | `bool` | Automatically focuses the select element on page load. | `false` | +| `children` | `ChildrenWithProps` | Child `Group` components containing options to render within the select box. | `""` | + +#### Styling Props + +```sh ++--------------------------------------------------+ +| [Select Container] | <-- `class` & `style` +| | +| +------------------------------------------+ | +| | [Selected Labels] | | <-- Rendered only for `multiple=true` +| | | | +| | +----------------------------------+ | | +| | | [Label (Chip)] | | | <-- `label_class` & `label_style` +| | | +--------------------------+ | | | +| | | | Close Button ("x") | | | | <-- `close_class` & `close_style` +| | | +--------------------------+ | | | +| | +----------------------------------+ | | +| +------------------------------------------+ | +| | +| +------------------------------------------+ | +| | [Select Element] | | <-- `| state.set(value))} +> + + +"# } + + + + // Default Disabled Select +
+

+ { "Headless Disabled Select" } +

+
+                        { r#""# }
+                    
+ +
+ // Disabled Options +
+

{ "Disabled Options" }

+
+                        { r#""# }
+                    
+ +
+ // Select with Custom Styles +
+

+ { "Custom Styled Select" } +

+
+                        { r#""# }
+                    
+ +
+ // Grouped Select +
+

{ "Grouped Select" }

+
+                        { r#""# }
+                    
+ +
+ // 4. Multi-Select with Chips +
+

+ { "Native Multi-Select with Chips" } +

+
+                        { r#""# }
+                    
+ +
+ + + } +} diff --git a/examples/yew/src/router.rs b/examples/yew/src/router.rs new file mode 100644 index 0000000..9d49b4c --- /dev/null +++ b/examples/yew/src/router.rs @@ -0,0 +1,16 @@ +use yew::prelude::*; +use yew_router::prelude::*; + +use crate::pages::landing::LandingPage; + +#[derive(Clone, Routable, PartialEq)] +pub enum Route { + #[at("/")] + LandingPage, +} + +pub fn switch(routes: Route) -> Html { + match routes { + Route::LandingPage => html! { }, + } +} diff --git a/examples/yew/tailwind.config.js b/examples/yew/tailwind.config.js new file mode 100644 index 0000000..88f1dfd --- /dev/null +++ b/examples/yew/tailwind.config.js @@ -0,0 +1,42 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: [ + "./index.html", + "./src/**/*.{rs,html}" + ], + theme: { + extend: { + colors: { + 'ct-dark-600': '#222', + 'ct-dark-200': '#e5e7eb', + 'ct-dark-100': '#f5f6f7', + 'ct-blue-600': '#2363eb', + 'ct-yellow-600': '#f9d13e', + 'ct-red-500': '#ef4444', + }, + fontFamily: { + sans: ['Roboto', 'sans-serif'], + serif: ['Roboto', 'serif'], + }, + container: { + center: true, + padding: '1rem', + screens: { + sm: '480px', + md: '768px', + lg: '976px', + xl: '1440px', + }, + spacing: { + '128': '32rem', + '144': '36rem', + }, + borderRadius: { + '4xl': '2rem', + } + }, + }, + }, + plugins: [], +} + diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..40f4fef --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,9 @@ +#![doc( + html_logo_url = "https://raw.githubusercontent.com/opensass/select-rs/refs/heads/main/assets/logo.webp", + html_favicon_url = "https://github.com/opensass/select-rs/blob/main/assets/favicon.png" +)] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![doc = include_str!("../README.md")] + +#[cfg(feature = "yew")] +pub mod yew; diff --git a/src/yew.rs b/src/yew.rs new file mode 100644 index 0000000..a7c5765 --- /dev/null +++ b/src/yew.rs @@ -0,0 +1,662 @@ +use std::rc::Rc; +use yew::prelude::*; + +/// Properties for configuring the `Select` component. +/// +/// The `Select` component creates a customizable dropdown list that allows you to choose +/// a single or multiple options. It can be styled with custom classes and inline styles, +/// and supports additional behaviors like multiple selections, disabled options, and +/// change events for updating the selected value. +/// +/// It works in combination with `Group` and `Option` components to provide a rich UI for +/// selecting options from a list. +/// Refer to the [MDN docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#attributes) for more info. +#[derive(Properties, PartialEq, Clone)] +pub struct SelectProps { + /// The name of the select component. + /// + /// This represents the name attribute used in the underlying HTML `select` element. + /// It is important when the component is part of a form, as it defines the field name. + /// Defaults to an empty string if not provided. + #[prop_or_default] + pub name: &'static str, + + /// The id of the select component. + /// + /// This represents the id attribute used in the underlying HTML `select` element. + /// It helps in uniquely identifying the component within the DOM. + /// Defaults to an empty string if not provided. + #[prop_or_default] + pub id: &'static str, + + /// The placeholder text for the select component. + /// + /// This text is displayed when no option is selected and the `select` element is empty. + /// It provides a hint to the user on what to select. It is not visible after an option is chosen. + /// Defaults to an empty string if not provided. + #[prop_or_default] + pub placeholder: &'static str, + + /// Whether the select component allows multiple selections. + /// + /// If set to `true`, the user can select more than one option. If set to `false`, only one option can be selected at a time. + /// Defaults to `false` if not provided. + #[prop_or_default] + pub multiple: bool, + + /// Whether the select component is disabled. + /// + /// If set to `true`, the select component will be unresponsive and users will not be able to interact with it. + /// Defaults to `false` if not provided. + #[prop_or_default] + pub disabled: bool, + + /// Whether the select option is required. + /// + /// This Boolean attribute indicates that a value must be selected from the dropdown. + /// If not selected, form submission will be blocked. Defaults to `false` if not provided. + #[prop_or_default] + pub required: bool, + + /// The visible size of the select dropdown. + /// + /// If the `multiple` attribute is specified, this defines the number of visible rows in the list. + /// This is helpful when displaying a scrollable list of options. + /// Defaults to `0`, which means the default layout will be used. + #[prop_or(0)] + pub size: u64, + + /// The form to associate the select element with. + /// + /// This attribute allows you to associate the select element with a form elsewhere in the document. + /// The value must be the `id` of a form element in the same document. If not provided, the `select` + /// element will be associated with its nearest ancestor form. Defaults to an empty string if not provided. + #[prop_or_default] + pub form: &'static str, + + /// The autocomplete hint for the select element. + /// + /// This string provides a hint to the user agent's autocomplete feature, helping it to + /// pre-fill values based on the user's past selections. The value should match one of the + /// valid autocomplete values for the ` +/// +/// +/// +/// } +/// } +/// ``` +/// +/// ## Multiple Selection +/// ```rust +/// use yew::prelude::*; +/// use selectrs::yew::{Select, Option, Group}; +/// +/// #[function_component(App)] +/// pub fn app() -> Html { +/// let onchange = Callback::from(|selected_values: Vec| { +/// // Handle the selected values +/// log::info!("Selected: {:?}", selected_values); +/// }); +/// +/// html! { +/// +/// } +/// } +/// ``` +/// +/// ## Custom Styling and Placeholder +/// ```rust +/// use yew::prelude::*; +/// use selectrs::yew::{Select, Option, Group}; +/// +/// #[function_component(App)] +/// pub fn app() -> Html { +/// html! { +/// +/// } +/// } +/// ``` +/// +/// ## With a Required Field +/// ```rust +/// use yew::prelude::*; +/// use selectrs::yew::{Select, Option, Group}; +/// +/// #[function_component(App)] +/// pub fn app() -> Html { +/// html! { +/// +/// } +/// } +/// ``` +/// +/// # Behavior +/// - The `Select` component handles single and multiple selections dynamically. +/// - The selected values are updated using the `onchange` callback whenever the user interacts with the select options. +/// - When multiple selection mode is enabled, selected values are displayed as chips with a close button to remove individual selections. +/// - A placeholder option is displayed when no value is selected and the select is not disabled. +/// +/// # Notes +/// - The `children` property must contain `Option` components to populate the select dropdown. +/// - If the `multiple` property is `true`, multiple options can be selected at once. If `false`, only one option can be selected. +/// - Custom styling can be applied to the select container, options, and labels via CSS classes or inline styles. +#[function_component(Select)] +pub fn select(props: &SelectProps) -> Html { + let SelectProps { + name, + id, + placeholder, + multiple, + disabled, + onchange, + children, + class, + style, + labels_class, + labels_style, + label_class, + label_style, + close_class, + close_style, + select_class, + select_style, + size, + required, + form, + autocomplete, + autofocus, + } = props.clone(); + + let selected_values = use_state(Vec::::new); + let selected = (*selected_values).clone(); + + let handle_group_change = { + let selected_values = selected_values.clone(); + let on_change = onchange.clone(); + Callback::from(move |value: String| { + let mut current_values = (*selected_values).clone(); + if multiple { + if current_values.contains(&value) { + current_values.retain(|v| v != &value); + } else { + current_values.push(value); + } + } else { + current_values = vec![value]; + } + selected_values.set(current_values.clone()); + on_change.emit(current_values); + }) + }; + + let remove_chip = { + let selected_values = selected_values.clone(); + let on_change = onchange.clone(); + Callback::from(move |value: String| { + let mut current_values = (*selected_values).clone(); + current_values.retain(|v| v != &value); + selected_values.set(current_values.clone()); + on_change.emit(current_values); + }) + }; + + html! { +
+ { if multiple { + html! { +
+ { for selected.clone().into_iter().map(|value| html! { +
+ { value.clone() } + +
+ }) } +
+ } + } else { + html! {} + } } + +
+ } +} + +/// Properties for configuring the `Group` component. +/// +/// The `Group` component allows you to group together `Option` elements. +/// It provides customization for labels, selection behavior, and event handling. The group allows a common state and +/// behavior across the contained options. This component supports customization of styles and classes, as well as +/// interaction handling through the `onchange` callback. +#[derive(Properties, PartialEq, Clone)] +pub struct GroupProps { + /// The label for the group. + /// + /// This is the text that labels the entire group of options. This can be used to describe + /// the set of options the user is about to choose from, making it useful for accessibility. + /// Defaults to an empty string if not provided. + #[prop_or_default] + pub label: &'static str, + + /// Indicates whether this is a group options. + /// + /// If `group` is set to `true`, the options in this group will be considered as part of the + /// `label` options group, where only one option can be selected at a time. If set to `false`, the + /// group is disabled. Defaults to `false` if not provided. + #[prop_or_default] + pub group: bool, + + /// The currently selected option in the group. + /// + /// This represents the selected value within the group. It should be bound to a state to + /// reflect changes as the user selects different options. Defaults to an empty string if not provided. + #[prop_or_default] + pub selected: String, + + /// Callback for when the selected option changes. + /// + /// This callback is triggered whenever the user selects a different option within the group. + /// The callback receives a string representing the newly selected option's value. Defaults to a no-op. + #[prop_or_default] + pub onchange: Callback, + + /// Child components of type `Option` for the group. + /// + /// This property allows you to pass one or more `Option` components as children of the `Group` component. + /// These `Option` components represent the individual selectable options within the group. + /// Defaults to an empty string if not provided. + #[prop_or_default] + pub children: ChildrenWithProps + { for children.iter().map(|mut child| { + let props = Rc::make_mut(&mut child.props); + let is_selected = props.value == selected; + let onchange = onchange.clone(); + let value = props.value; + + props.selected = is_selected; + props.on_click = Callback::from(move |_| { + onchange.emit(value.to_string()); + }); + + child + }) } + + } + } else { + html! { + { for children.iter().map(|mut child| { + let props = Rc::make_mut(&mut child.props); + let is_selected = props.value == selected; + let onchange = onchange.clone(); + let value = props.value; + + props.selected = is_selected; + props.on_click = Callback::from(move |_| { + onchange.emit(value.to_string()); + }); + + child + }) } + } + } +} + +/// Properties for configuring the `Option` component. +/// +/// The `Option` component represents an individual selectable option within a group of options, such as a +/// string, a radio button, checkbox, or a custom select element. It allows for customization of the option's value, +/// label, selection state, and appearance. The component also supports event handling for user interactions +/// (e.g., click events). +#[derive(Properties, PartialEq, Clone)] +pub struct OptionProps { + /// The value of the option. + /// + /// This is the underlying value associated with the option. It is typically used when the user selects + /// this option, and is submitted or processed based on the selected state of the option. Defaults to an + /// empty string if not provided. + #[prop_or_default] + pub value: &'static str, + + /// The label displayed for the option. + /// + /// This property defines the content that is shown to the user as the label for the option. It can be + /// any valid child element, such as text, icons, or other components. Defaults to no label (empty). + #[prop_or_default] + pub label: Children, + + /// Whether the option is selected. + /// + /// This property indicates if the option is currently selected. If set to `true`, the option is visually + /// marked as selected, and it may trigger related behavior such as updating state or submitting a form. + /// Defaults to `false` if not provided. + #[prop_or_default] + pub selected: bool, + + /// Whether the option is disabled. + /// + /// If set to `true`, the option is considered disabled, meaning it cannot be interacted with by the user. + /// Disabled options may be visually different (e.g., grayed out). Defaults to `false` if not provided. + #[prop_or_default] + pub disabled: bool, + + /// Callback for when the option is clicked. + /// + /// This callback is invoked when the user clicks on the option. It can be used to trigger actions such as + /// updating the selected state or performing any other interaction. Defaults to a no-op (no action). + #[prop_or_default] + pub on_click: Callback<()>, + + /// Custom CSS class for the option. + /// + /// This property allows you to specify a custom CSS class for the option. This class is applied to the + /// individual option container, enabling you to style it differently from other options. Defaults to an empty + /// string if not provided. + #[prop_or_default] + pub class: &'static str, + + /// Inline styles for the option. + /// + /// This property enables you to apply inline styles directly to the option element. It allows for precise + /// customization of the option's appearance without needing an external stylesheet. Defaults to an empty string + /// if not provided. + #[prop_or_default] + pub style: &'static str, + + /// Custom class for a selected option. + /// + /// This property defines a custom CSS class that is applied when the option is selected. It enables you to + /// style the selected option differently, such as changing its background color or text style. Defaults to an + /// empty string if not provided. + #[prop_or_default] + pub selected_class: &'static str, + + /// Inline styles for a selected option. + /// + /// This property defines inline styles applied when the option is selected. It provides direct control over + /// the selected state styling, allowing for unique visual differentiation between selected and non-selected + /// options. Defaults to an empty string if not provided. + #[prop_or_default] + pub selected_style: &'static str, +} + +#[function_component(Option)] +pub fn option(props: &OptionProps) -> Html { + let OptionProps { + label, + selected, + disabled, + on_click, + class, + style, + selected_style, + selected_class, + .. + } = props.clone(); + + let handle_click = { + let on_click = on_click.clone(); + Callback::from(move |_| on_click.emit(())) + }; + + html! { + + } +}