app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit d7a796fa2a9323e3c963531770a00274ba3ee5e7
parent 3595b85a04d4dd9fe1dfd5a5fbb0d5fd23547a93
Author: triesap <tyson@radroots.org>
Date:   Fri, 17 Apr 2026 18:14:22 +0000

ui: expand the radroots_app theme contract

- add the approved gpui component workspace dependencies and refresh the mounted app lockfile for the upgraded shell surface
- expand radroots_app_ui theme ownership to cover the paperwhite color system, control token families, and deeper settings layout values
- export the new token families through the shared ui crate so later slices can build controls without reopening the theme boundary
- add radroots_app_ui theme tests and verify cargo test -p radroots_app_ui plus cargo check --manifest-path Cargo.toml

Diffstat:
MCargo.lock | 543+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MCargo.toml | 2++
Mcrates/launchers/desktop/Cargo.toml | 2++
Mcrates/shared/ui/Cargo.toml | 1+
Mcrates/shared/ui/src/lib.rs | 6++++--
Mcrates/shared/ui/src/theme.rs | 257+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
6 files changed, 797 insertions(+), 14 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -91,6 +91,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c3d036a3c4ab069c7b410a2ce876bd74808d2d0888a82667669f8e783a898bf1" [[package]] +name = "arc-swap" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" +dependencies = [ + "rustversion", +] + +[[package]] name = "arg_enum_proc_macro" version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -480,6 +489,12 @@ dependencies = [ ] [[package]] +name = "base62" +version = "2.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd637ac531c60eb7fbc4684dc061c2d7d90d73d758181aa02eeff0464b9eee4b" + +[[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1521,6 +1536,26 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "66b7e2430c6dff6a955451e2cfc438f09cea1965a9d6f87f7e3b90decc014099" [[package]] +name = "enum-iterator" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4549325971814bda7a44061bf3fe7e487d447cba01e4220a4b454d630d7a016" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685adfa4d6f3d765a26bc5dbc936577de9abf756c1feeb3089b01dd395034842" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] name = "enumflags2" version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1756,6 +1791,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8bf7cc16383c4b8d58b9905a8509f02926ce3058053c056376248d958c9df1e8" [[package]] +name = "fluent-uri" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17c704e9dbe1ddd863da1e6ff3567795087b1eb201ce80d8fa81162e1516500d" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] name = "flume" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1873,6 +1917,15 @@ dependencies = [ ] [[package]] +name = "fsevent-sys" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" +dependencies = [ + "libc", +] + +[[package]] name = "futf" version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2088,6 +2141,17 @@ dependencies = [ ] [[package]] +name = "globwalk" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" +dependencies = [ + "bitflags 1.3.2", + "ignore", + "walkdir", +] + +[[package]] name = "gloo-timers" version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2238,6 +2302,68 @@ dependencies = [ ] [[package]] +name = "gpui-component" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d021d46b4088d3d93a57ccdf443da85695a77272108caca2f6fe5369f584966a" +dependencies = [ + "aho-corasick", + "anyhow", + "chrono", + "core-text", + "enum-iterator", + "gpui", + "gpui-component-macros", + "gpui-macros", + "html5ever", + "itertools 0.13.0", + "lsp-types", + "markdown", + "markup5ever_rcdom", + "notify", + "num-traits", + "once_cell", + "paste", + "regex", + "ropey", + "rust-i18n", + "schemars", + "serde", + "serde_json", + "serde_repr", + "smallvec", + "smol", + "tracing", + "tree-sitter", + "tree-sitter-json", + "unicode-segmentation", + "uuid", + "zed-sum-tree", +] + +[[package]] +name = "gpui-component-assets" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc6e4c6551a1a12d4e8b69c3e8eba3cef43331c8c87898a0d4d040c78c6865e" +dependencies = [ + "anyhow", + "gpui", + "rust-embed", +] + +[[package]] +name = "gpui-component-macros" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86fbc2d84bf91717b171320e6adc600d91ccb3ed259448f3b006787633c1c615" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] name = "gpui-macros" version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2527,6 +2653,20 @@ dependencies = [ ] [[package]] +name = "html5ever" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13771afe0e6e846f1e67d038d4cb29998a6779f93c809212e4e9c32efd244d4" +dependencies = [ + "log", + "mac", + "markup5ever", + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] name = "http" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2756,6 +2896,22 @@ dependencies = [ ] [[package]] +name = "ignore" +version = "0.4.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3d782a365a015e0f5c04902246139249abf769125006fbe7649e2ee88169b4a" +dependencies = [ + "crossbeam-deque", + "globset", + "log", + "memchr", + "regex-automata", + "same-file", + "walkdir", + "winapi-util", +] + +[[package]] name = "image" version = "0.25.10" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2814,6 +2970,26 @@ dependencies = [ ] [[package]] +name = "inotify" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdd168d97690d0b8c412d6b6c10360277f4d7ee495c5d0d5d5fe0854923255cc" +dependencies = [ + "bitflags 1.3.2", + "inotify-sys", + "libc", +] + +[[package]] +name = "inotify-sys" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" +dependencies = [ + "libc", +] + +[[package]] name = "inout" version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2900,6 +3076,15 @@ dependencies = [ [[package]] name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" @@ -2955,6 +3140,26 @@ dependencies = [ ] [[package]] +name = "kqueue" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac30106d7dce88daf4a3fcb4879ea939476d5074a9b7ddd0fb97fa4bed5596a" +dependencies = [ + "kqueue-sys", + "libc", +] + +[[package]] +name = "kqueue-sys" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" +dependencies = [ + "bitflags 1.3.2", + "libc", +] + +[[package]] name = "kurbo" version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3107,6 +3312,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" [[package]] +name = "lsp-types" +version = "0.97.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53353550a17c04ac46c585feb189c2db82154fc84b79c7a66c96c2c644f66071" +dependencies = [ + "bitflags 1.3.2", + "fluent-uri", + "serde", + "serde_json", + "serde_repr", +] + +[[package]] name = "lyon" version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3174,6 +3392,41 @@ dependencies = [ ] [[package]] +name = "markdown" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5cab8f2cadc416a82d2e783a1946388b31654d391d1c7d92cc1f03e295b1deb" +dependencies = [ + "unicode-id", +] + +[[package]] +name = "markup5ever" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16ce3abbeba692c8b8441d036ef91aea6df8da2c6b6e21c7e14d3c18e526be45" +dependencies = [ + "log", + "phf", + "phf_codegen", + "string_cache", + "string_cache_codegen", + "tendril", +] + +[[package]] +name = "markup5ever_rcdom" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edaa21ab3701bfee5099ade5f7e1f84553fd19228cf332f13cd6e964bf59be18" +dependencies = [ + "html5ever", + "markup5ever", + "tendril", + "xml5ever", +] + +[[package]] name = "maybe-rayon" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3340,6 +3593,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", + "log", "wasi", "windows-sys 0.61.2", ] @@ -3453,6 +3707,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0676bb32a98c1a483ce53e500a81ad9c3d5b3f7c920c28c24e9cb0980d0b5bc8" [[package]] +name = "normpath" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf23ab2b905654b4cb177e30b629937b3868311d4e1cba859f899c041046e69b" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "notify" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c533b4c39709f9ba5005d8002048266593c1cfaf3c5f0739d5b8ab0c6c504009" +dependencies = [ + "bitflags 2.11.1", + "filetime", + "fsevent-sys", + "inotify", + "kqueue", + "libc", + "log", + "mio", + "notify-types", + "walkdir", + "windows-sys 0.52.0", +] + +[[package]] +name = "notify-types" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "585d3cb5e12e01aed9e8a1f70d5c6b5e86fe2a6e48fc8cd0b3e0b8df6f6eb174" +dependencies = [ + "instant", +] + +[[package]] name = "ntapi" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -3876,6 +4167,44 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] +name = "phf" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd6780a80ae0c52cc120a26a1a42c1ae51b247a253e4e06113d23d2c2edd078" +dependencies = [ + "phf_shared", +] + +[[package]] +name = "phf_codegen" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aef8048c789fa5e851558d709946d6d79a8ff88c0440c587967f8e94bfb1216a" +dependencies = [ + "phf_generator", + "phf_shared", +] + +[[package]] +name = "phf_generator" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c80231409c20246a13fddb31776fb942c38553c51e871f8cbd687a4cfb5843d" +dependencies = [ + "phf_shared", + "rand 0.8.6", +] + +[[package]] +name = "phf_shared" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eabc2ef2a60eb7faa00097bd1ffdb5bd28e62bf39990626a582201b7a754e5" +dependencies = [ + "siphasher", +] + +[[package]] name = "pico-args" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4028,6 +4357,12 @@ dependencies = [ ] [[package]] +name = "precomputed-hash" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" + +[[package]] name = "prettyplease" version = "0.2.37" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4232,6 +4567,8 @@ name = "radroots_app" version = "0.1.0" dependencies = [ "gpui", + "gpui-component", + "gpui-component-assets", "radroots_app_core", "radroots_app_i18n", "radroots_app_ui", @@ -4259,6 +4596,7 @@ name = "radroots_app_ui" version = "0.1.0" dependencies = [ "gpui", + "gpui-component", "radroots_app_core", "radroots_app_i18n", ] @@ -4551,6 +4889,15 @@ dependencies = [ ] [[package]] +name = "ropey" +version = "2.0.0-beta.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4045a00dc327d084a2bbf126976e14125b54f23bd30511d45b842eba76c52d74" +dependencies = [ + "str_indices", +] + +[[package]] name = "roxmltree" version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4576,6 +4923,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", + "shellexpand", "syn 2.0.117", "walkdir", ] @@ -4592,6 +4940,60 @@ dependencies = [ ] [[package]] +name = "rust-i18n" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda2551fdfaf6cc5ee283adc15e157047b92ae6535cf80f6d4962d05717dc332" +dependencies = [ + "globwalk", + "once_cell", + "regex", + "rust-i18n-macro", + "rust-i18n-support", + "smallvec", +] + +[[package]] +name = "rust-i18n-macro" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22baf7d7f56656d23ebe24f6bb57a5d40d2bce2a5f1c503e692b5b2fa450f965" +dependencies = [ + "glob", + "once_cell", + "proc-macro2", + "quote", + "rust-i18n-support", + "serde", + "serde_json", + "serde_yaml", + "syn 2.0.117", +] + +[[package]] +name = "rust-i18n-support" +version = "3.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "940ed4f52bba4c0152056d771e563b7133ad9607d4384af016a134b58d758f19" +dependencies = [ + "arc-swap", + "base62", + "globwalk", + "itertools 0.11.0", + "lazy_static", + "normpath", + "once_cell", + "proc-macro2", + "regex", + "serde", + "serde_json", + "serde_yaml", + "siphasher", + "toml 0.8.23", + "triomphe", +] + +[[package]] name = "rustc-hash" version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4980,6 +5382,19 @@ dependencies = [ ] [[package]] +name = "serde_yaml" +version = "0.9.34+deprecated" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" +dependencies = [ + "indexmap", + "itoa", + "ryu", + "serde", + "unsafe-libyaml", +] + +[[package]] name = "sha1_smol" version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -4997,6 +5412,15 @@ dependencies = [ ] [[package]] +name = "shellexpand" +version = "3.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32824fab5e16e6c4d86dc1ba84489390419a39f97699852b66480bb87d297ed8" +dependencies = [ + "dirs 5.0.1", +] + +[[package]] name = "shlex" version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5190,6 +5614,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" [[package]] +name = "str_indices" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d08889ec5408683408db66ad89e0e1f93dff55c73a4ccc71c427d5b277ee47e6" + +[[package]] +name = "streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520" + +[[package]] name = "strict-num" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5199,6 +5635,31 @@ dependencies = [ ] [[package]] +name = "string_cache" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf776ba3fa74f83bf4b63c3dcbbf82173db2632ed8452cb2d891d33f459de70f" +dependencies = [ + "new_debug_unreachable", + "parking_lot", + "phf_shared", + "precomputed-hash", + "serde", +] + +[[package]] +name = "string_cache_codegen" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c711928715f1fe0fe509c53b43e993a9a557babc2d0a3567d0a3006f1ac931a0" +dependencies = [ + "phf_generator", + "phf_shared", + "proc-macro2", + "quote", +] + +[[package]] name = "strum" version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5825,6 +6286,47 @@ dependencies = [ ] [[package]] +name = "tree-sitter" +version = "0.25.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78f873475d258561b06f1c595d93308a7ed124d9977cb26b148c2084a4a3cc87" +dependencies = [ + "cc", + "regex", + "regex-syntax", + "serde_json", + "streaming-iterator", + "tree-sitter-language", +] + +[[package]] +name = "tree-sitter-json" +version = "0.24.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d727acca406c0020cffc6cf35516764f36c8e3dc4408e5ebe2cb35a947ec471" +dependencies = [ + "cc", + "tree-sitter-language", +] + +[[package]] +name = "tree-sitter-language" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "009994f150cc0cd50ff54917d5bc8bffe8cad10ca10d81c34da2ec421ae61782" + +[[package]] +name = "triomphe" +version = "0.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd69c5aa8f924c7519d6372789a74eac5b94fb0f8fcf0d4a97eb0bfc3e785f39" +dependencies = [ + "arc-swap", + "serde", + "stable_deref_trait", +] + +[[package]] name = "try-lock" version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5929,6 +6431,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce61d488bcdc9bc8b5d1772c404828b17fc481c0a582b5581e95fb233aef503e" [[package]] +name = "unicode-id" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ba288e709927c043cbe476718d37be306be53fb1fafecd0dbe36d072be2580" + +[[package]] name = "unicode-ident" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -5977,6 +6485,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" [[package]] +name = "unsafe-libyaml" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" + +[[package]] name = "untrusted" version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7014,6 +7528,12 @@ dependencies = [ ] [[package]] +name = "workspace-hack" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "beffa227304dbaea3ad6a06ac674f9bc83a3dec3b7f63eeb442de37e7cb6bb01" + +[[package]] name = "writeable" version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7123,6 +7643,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9cc00251562a284751c9973bace760d86c0276c471b4be569fe6b068ee97a56" [[package]] +name = "xml5ever" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bbb26405d8e919bc1547a5aa9abc95cbfa438f04844f5fdd9dc7596b748bf69" +dependencies = [ + "log", + "mac", + "markup5ever", +] + +[[package]] name = "xmlwriter" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -7347,6 +7878,18 @@ dependencies = [ ] [[package]] +name = "zed-sum-tree" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d490156d0d7311855564d6e1d6dccab992405a0c0e15e1c8ef18920c02177e35" +dependencies = [ + "arrayvec", + "log", + "rayon", + "workspace-hack", +] + +[[package]] name = "zed-xim" version = "0.4.0-zed" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/Cargo.toml b/Cargo.toml @@ -19,6 +19,8 @@ readme = "README.md" [workspace.dependencies] gpui = "0.2.2" +gpui-component = "0.5.1" +gpui-component-assets = "0.5.1" hex = "0.4" mf2-i18n-build = { path = "../../../../vendor/triesap/mf2-i18n/crates/mf2-i18n-build", version = "0.1.0" } mf2-i18n-core = { path = "../../../../vendor/triesap/mf2-i18n/crates/mf2-i18n-core", version = "0.1.0" } diff --git a/crates/launchers/desktop/Cargo.toml b/crates/launchers/desktop/Cargo.toml @@ -9,6 +9,8 @@ publish = false [dependencies] gpui.workspace = true +gpui-component.workspace = true +gpui-component-assets.workspace = true radroots_app_core.workspace = true radroots_app_i18n.workspace = true radroots_app_ui.workspace = true diff --git a/crates/shared/ui/Cargo.toml b/crates/shared/ui/Cargo.toml @@ -9,6 +9,7 @@ publish = false [dependencies] gpui.workspace = true +gpui-component.workspace = true radroots_app_core.workspace = true radroots_app_i18n.workspace = true diff --git a/crates/shared/ui/src/lib.rs b/crates/shared/ui/src/lib.rs @@ -14,6 +14,8 @@ pub use text::{ settings_preferences_general_rows, }; pub use theme::{ - APP_UI_THEME, AppLayoutTokens, AppSurfaceTokens, AppTextTokens, AppTypographyTokens, - AppUiTheme, AppWindowTokens, + APP_UI_THEME, ActionButtonColors, ActionButtonSizing, ActionButtonTokens, AppControlTokens, + AppLayoutTokens, AppSurfaceTokens, AppTextTokens, AppTypographyTokens, AppUiTheme, + AppWindowTokens, CheckboxTokens, IconSegmentButtonColors, IconSegmentButtonSizing, + IconSegmentButtonTokens, StatusIndicatorTokens, }; diff --git a/crates/shared/ui/src/theme.rs b/crates/shared/ui/src/theme.rs @@ -5,6 +5,7 @@ pub struct AppUiTheme { pub text: AppTextTokens, pub typography: AppTypographyTokens, pub layout: AppLayoutTokens, + pub controls: AppControlTokens, } #[derive(Clone, Copy, Debug, PartialEq)] @@ -37,6 +38,8 @@ pub struct AppTypographyTokens { pub body_text_px: f32, pub brand_text_px: f32, pub settings_row_text_px: f32, + pub settings_account_identity_text_px: f32, + pub settings_account_detail_text_px: f32, } #[derive(Clone, Copy, Debug, PartialEq)] @@ -55,38 +58,136 @@ pub struct AppLayoutTokens { pub settings_navigation_row_padding_px: f32, pub settings_navigation_row_gap_px: f32, pub settings_content_padding_px: f32, + pub settings_account_sidebar_width_px: f32, + pub settings_account_sidebar_padding_px: f32, + pub settings_account_sidebar_button_height_px: f32, + pub settings_account_sidebar_button_padding_px: f32, + pub settings_account_sidebar_button_corner_radius_px: f32, + pub settings_account_sidebar_button_gap_px: f32, + pub settings_account_sidebar_avatar_size_px: f32, + pub settings_account_identity_text_gap_px: f32, + pub settings_account_sidebar_footer_padding_top_px: f32, + pub settings_account_sidebar_footer_row_gap_px: f32, + pub settings_account_sidebar_footer_button_gap_px: f32, + pub settings_account_main_padding_px: f32, + pub settings_account_content_max_width_px: f32, + pub settings_account_main_stack_gap_px: f32, + pub settings_account_profile_avatar_size_px: f32, + pub settings_account_detail_row_gap_px: f32, + pub settings_account_detail_value_gap_px: f32, + pub settings_checkbox_label_gap_px: f32, + pub settings_account_status_gap_px: f32, + pub settings_account_action_row_gap_px: f32, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct AppControlTokens { + pub icon_segment_button: IconSegmentButtonTokens, + pub action_button: ActionButtonTokens, + pub checkbox: CheckboxTokens, + pub status_indicator: StatusIndicatorTokens, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct IconSegmentButtonTokens { + pub sizing: IconSegmentButtonSizing, + pub colors: IconSegmentButtonColors, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct IconSegmentButtonSizing { + pub height_px: f32, + pub corner_radius_px: f32, + pub inner_padding_px: f32, + pub icon_size_px: f32, + pub label_size_px: f32, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct IconSegmentButtonColors { + pub active_background: u32, + pub inactive_background: u32, + pub active_foreground: u32, + pub inactive_foreground: u32, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct ActionButtonTokens { + pub sizing: ActionButtonSizing, + pub colors: ActionButtonColors, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct ActionButtonSizing { + pub height_px: f32, + pub corner_radius_px: f32, + pub horizontal_padding_px: f32, + pub compact_horizontal_padding_px: f32, + pub label_size_px: f32, + pub icon_size_px: f32, + pub square_width_px: f32, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct ActionButtonColors { + pub background: u32, + pub foreground: u32, + pub hover_changes_background: bool, + pub hover_background: u32, + pub active_background: u32, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct CheckboxTokens { + pub size_px: f32, + pub corner_radius_px: f32, + pub icon_size_px: f32, + pub checked_background: u32, + pub unchecked_background: u32, + pub unchecked_border: u32, + pub check_foreground: u32, +} + +#[derive(Clone, Copy, Debug, PartialEq)] +pub struct StatusIndicatorTokens { + pub size_px: f32, + pub online: u32, + pub offline: u32, + pub attention: u32, } pub const APP_UI_THEME: AppUiTheme = AppUiTheme { windows: AppWindowTokens { - home_min_width_px: 640.0, - home_min_height_px: 480.0, + home_min_width_px: 980.0, + home_min_height_px: 720.0, settings_width_px: 600.0, settings_height_px: 540.0, }, surfaces: AppSurfaceTokens { - window_background: 0xF5F1E8, - chrome_background: 0xEAE5D8, - panel_background: 0xF8F4EC, - card_background: 0xEFE8D8, - divider: 0xD4CCBA, + window_background: 0xFFFFFF, + chrome_background: 0xF5F5F7, + panel_background: 0xFFFFFF, + card_background: 0xF2F2F7, + divider: 0xD2D2D7, }, text: AppTextTokens { - primary: 0x1F2C23, - secondary: 0x5D665B, - accent: 0x3B6A3E, + primary: 0x1D1D1F, + secondary: 0x6E6E73, + accent: 0x0A84FF, }, typography: AppTypographyTokens { utility_title_text_px: 12.0, body_text_px: 14.0, - brand_text_px: 20.0, + brand_text_px: 14.0, settings_row_text_px: 13.0, + settings_account_identity_text_px: 14.0, + settings_account_detail_text_px: 14.0, }, layout: AppLayoutTokens { divider_thickness_px: 1.0, home_window_padding_px: 24.0, home_sidebar_width_px: 240.0, - home_card_max_width_px: 960.0, + home_card_max_width_px: 1080.0, home_card_padding_px: 24.0, home_stack_gap_px: 12.0, metadata_row_gap_px: 12.0, @@ -97,5 +198,137 @@ pub const APP_UI_THEME: AppUiTheme = AppUiTheme { settings_navigation_row_padding_px: 8.0, settings_navigation_row_gap_px: 8.0, settings_content_padding_px: 24.0, + settings_account_sidebar_width_px: 200.0, + settings_account_sidebar_padding_px: 8.0, + settings_account_sidebar_button_height_px: 42.0, + settings_account_sidebar_button_padding_px: 4.0, + settings_account_sidebar_button_corner_radius_px: 8.0, + settings_account_sidebar_button_gap_px: 8.0, + settings_account_sidebar_avatar_size_px: 32.0, + settings_account_identity_text_gap_px: 0.0, + settings_account_sidebar_footer_padding_top_px: 8.0, + settings_account_sidebar_footer_row_gap_px: 8.0, + settings_account_sidebar_footer_button_gap_px: 8.0, + settings_account_main_padding_px: 24.0, + settings_account_content_max_width_px: 260.0, + settings_account_main_stack_gap_px: 16.0, + settings_account_profile_avatar_size_px: 64.0, + settings_account_detail_row_gap_px: 16.0, + settings_account_detail_value_gap_px: 12.0, + settings_checkbox_label_gap_px: 8.0, + settings_account_status_gap_px: 4.0, + settings_account_action_row_gap_px: 8.0, + }, + controls: AppControlTokens { + icon_segment_button: IconSegmentButtonTokens { + sizing: IconSegmentButtonSizing { + height_px: 44.0, + corner_radius_px: 8.0, + inner_padding_px: 2.0, + icon_size_px: 16.0, + label_size_px: 12.0, + }, + colors: IconSegmentButtonColors { + active_background: 0xFFFFFF, + inactive_background: 0xF5F5F7, + active_foreground: 0x0A84FF, + inactive_foreground: 0x1D1D1F, + }, + }, + action_button: ActionButtonTokens { + sizing: ActionButtonSizing { + height_px: 24.0, + corner_radius_px: 8.0, + horizontal_padding_px: 12.0, + compact_horizontal_padding_px: 4.0, + label_size_px: 13.0, + icon_size_px: 14.0, + square_width_px: 24.0, + }, + colors: ActionButtonColors { + background: 0xE5E5EA, + foreground: 0x1D1D1F, + hover_changes_background: false, + hover_background: 0xDCDCE1, + active_background: 0xD1D1D6, + }, + }, + checkbox: CheckboxTokens { + size_px: 16.0, + corner_radius_px: 5.0, + icon_size_px: 13.0, + checked_background: 0x0A84FF, + unchecked_background: 0xF2F2F7, + unchecked_border: 0xD1D1D6, + check_foreground: 0xFFFFFF, + }, + status_indicator: StatusIndicatorTokens { + size_px: 12.0, + online: 0x34C759, + offline: 0xFFD60A, + attention: 0xFF3B30, + }, }, }; + +#[cfg(test)] +mod tests { + use super::APP_UI_THEME; + + #[test] + fn paperwhite_shell_layers_are_distinct() { + assert_eq!(APP_UI_THEME.surfaces.window_background, 0xFFFFFF); + assert_eq!(APP_UI_THEME.surfaces.chrome_background, 0xF5F5F7); + assert_eq!(APP_UI_THEME.surfaces.card_background, 0xF2F2F7); + assert_eq!(APP_UI_THEME.surfaces.divider, 0xD2D2D7); + assert_ne!( + APP_UI_THEME.surfaces.window_background, + APP_UI_THEME.surfaces.card_background + ); + } + + #[test] + fn home_window_minimums_match_the_upgraded_shell_budget() { + assert_eq!(APP_UI_THEME.windows.home_min_width_px, 980.0); + assert_eq!(APP_UI_THEME.windows.home_min_height_px, 720.0); + assert_eq!(APP_UI_THEME.layout.home_sidebar_width_px, 240.0); + assert_eq!(APP_UI_THEME.layout.home_window_padding_px, 24.0); + } + + #[test] + fn settings_shell_layout_contract_is_explicit() { + assert_eq!(APP_UI_THEME.windows.settings_width_px, 600.0); + assert_eq!(APP_UI_THEME.windows.settings_height_px, 540.0); + assert_eq!(APP_UI_THEME.layout.settings_chrome_height_px, 88.0); + assert_eq!(APP_UI_THEME.layout.settings_content_padding_px, 24.0); + assert_eq!(APP_UI_THEME.layout.settings_account_sidebar_width_px, 200.0); + assert_eq!(APP_UI_THEME.layout.settings_account_sidebar_button_height_px, 42.0); + } + + #[test] + fn control_tokens_match_the_frozen_budget() { + let segmented = APP_UI_THEME.controls.icon_segment_button.sizing; + let action = APP_UI_THEME.controls.action_button.sizing; + let checkbox = APP_UI_THEME.controls.checkbox; + let status = APP_UI_THEME.controls.status_indicator; + + assert_eq!(segmented.height_px, 44.0); + assert_eq!(segmented.corner_radius_px, 8.0); + assert_eq!(segmented.inner_padding_px, 2.0); + assert_eq!(action.height_px, 24.0); + assert_eq!(action.corner_radius_px, 8.0); + assert_eq!(action.square_width_px, 24.0); + assert_eq!(checkbox.size_px, 16.0); + assert_eq!(checkbox.corner_radius_px, 5.0); + assert_eq!(status.size_px, 12.0); + } + + #[test] + fn accent_and_status_colors_match_the_current_shell_contract() { + assert_eq!(APP_UI_THEME.text.accent, 0x0A84FF); + assert_eq!(APP_UI_THEME.controls.checkbox.checked_background, 0x0A84FF); + assert_eq!(APP_UI_THEME.controls.status_indicator.online, 0x34C759); + assert_eq!(APP_UI_THEME.controls.status_indicator.offline, 0xFFD60A); + assert_eq!(APP_UI_THEME.controls.status_indicator.attention, 0xFF3B30); + } +}