From 34e026751b20bd0c78e91effce64f756dc09b44d Mon Sep 17 00:00:00 2001 From: reya <123083837+reyamir@users.noreply.github.com> Date: Fri, 26 Dec 2025 08:20:18 +0700 Subject: [PATCH] feat: add support for multi-themes (#210) * chore: update deps * wip * add themes * add matrix theme * add flexoki and spaceduck themes * . * simple theme change function * . * respect shadow and radius settings * add rose pine themes * toggle theme --- Cargo.lock | 167 +- Cargo.toml | 1 + assets/themes/catppuccin-frappe.json | 136 + assets/themes/catppuccin-latte.json | 136 + assets/themes/catppuccin-macchiato.json | 136 + assets/themes/catppuccin-mocha.json | 136 + assets/themes/flexoki.json | 136 + assets/themes/rose-pine-dawn.json | 136 + assets/themes/rose-pine-moon.json | 136 + assets/themes/rose-pine.json | 136 + crates/assets/src/lib.rs | 10 +- crates/chat_ui/src/lib.rs | 6 +- crates/common/src/constants.rs | 6 +- crates/coop/src/actions.rs | 1 + crates/coop/src/chatspace.rs | 62 +- crates/coop/src/main.rs | 3 + crates/coop/src/sidebar/list_item.rs | 4 +- crates/coop/src/sidebar/mod.rs | 22 +- crates/coop/src/views/onboarding.rs | 10 +- crates/coop/src/views/screening.rs | 6 +- crates/coop/src/views/startup.rs | 2 +- crates/theme/Cargo.toml | 7 + crates/theme/src/colors.rs | 4685 +++++++++-------- crates/theme/src/lib.rs | 398 +- crates/theme/src/registry.rs | 70 + crates/theme/src/scrollbar_mode.rs | 9 +- crates/theme/src/theme.rs | 359 ++ crates/title_bar/src/lib.rs | 81 +- .../{theme => title_bar}/src/platform_kind.rs | 3 + crates/ui/src/dock_area/mod.rs | 2 +- crates/ui/src/dock_area/tab_panel.rs | 12 +- crates/ui/src/dropdown.rs | 16 +- crates/ui/src/focusable.rs | 2 +- crates/ui/src/input/element.rs | 2 +- crates/ui/src/input/state.rs | 2 +- crates/ui/src/lib.rs | 1 - crates/ui/src/list/list.rs | 2 +- crates/ui/src/menu/app_menu_bar.rs | 4 +- crates/ui/src/menu/context_menu.rs | 2 +- crates/ui/src/menu/popup_menu.rs | 8 +- crates/ui/src/modal.rs | 4 +- crates/ui/src/notification.rs | 4 +- crates/ui/src/popover.rs | 4 +- crates/ui/src/root.rs | 8 +- crates/ui/src/scroll/scrollbar.rs | 8 +- crates/ui/src/styled.rs | 2 +- crates/ui/src/switch.rs | 2 +- crates/ui/src/tab/mod.rs | 2 +- crates/ui/src/tooltip.rs | 5 +- 49 files changed, 4349 insertions(+), 2743 deletions(-) create mode 100644 assets/themes/catppuccin-frappe.json create mode 100644 assets/themes/catppuccin-latte.json create mode 100644 assets/themes/catppuccin-macchiato.json create mode 100644 assets/themes/catppuccin-mocha.json create mode 100644 assets/themes/flexoki.json create mode 100644 assets/themes/rose-pine-dawn.json create mode 100644 assets/themes/rose-pine-moon.json create mode 100644 assets/themes/rose-pine.json create mode 100644 crates/theme/src/registry.rs create mode 100644 crates/theme/src/theme.rs rename crates/{theme => title_bar}/src/platform_kind.rs (90%) diff --git a/Cargo.lock b/Cargo.lock index 94c3b63..5817c20 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,7 +206,7 @@ dependencies = [ "url", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.9", + "wayland-protocols", "zbus", ] @@ -346,9 +346,9 @@ dependencies = [ [[package]] name = "async-lock" -version = "3.4.1" +version = "3.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd03604047cee9b6ce9de9f70c6cd540a0520c813cbd49bae61f33ab80ed1dc" +checksum = "290f7f2596bd5b78a9fec8088ccd89180d7f9f55b94b0576823bbbdc72ee8311" dependencies = [ "event-listener 5.4.1", "event-listener-strategy", @@ -963,9 +963,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.49" +version = "1.2.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90583009037521a116abf44494efecd645ba48b6622457080f080b85544e2215" +checksum = "9f50d563227a1c37cc0a263f64eca3334388c01c5e4c4861a9def205c614383c" dependencies = [ "find-msvc-tools", "jobserver", @@ -1130,9 +1130,9 @@ dependencies = [ [[package]] name = "cmake" -version = "0.1.56" +version = "0.1.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b042e5d8a74ae91bb0961acd039822472ec99f8ab0948cbf6d1369588f8be586" +checksum = "75443c44cd6b379beb8c5b45d85d0773baf31cce901fe7bb252f4eff3008ef7d" dependencies = [ "cc", ] @@ -1211,7 +1211,7 @@ dependencies = [ [[package]] name = "collections" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "indexmap", "rustc-hash 2.1.1", @@ -1643,7 +1643,7 @@ dependencies = [ [[package]] name = "derive_refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "proc-macro2", "quote", @@ -1816,7 +1816,7 @@ dependencies = [ "cc", "memchr", "rustc_version", - "toml 0.9.8", + "toml 0.9.10+spec-1.1.0", "vswhom", "winreg", ] @@ -2101,9 +2101,9 @@ checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844" [[package]] name = "flatbuffers" -version = "25.9.23" +version = "25.12.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09b6620799e7340ebd9968d2e0708eb82cf1971e9a16821e2091b6d6e475eed5" +checksum = "35f6839d7b3b98adde531effaf34f0c2badc6f4735d26fe74709d8e513a96ef3" dependencies = [ "bitflags 2.10.0", "rustc_version", @@ -2583,7 +2583,7 @@ dependencies = [ [[package]] name = "gpui" version = "0.2.2" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "anyhow", "as-raw-xcb-connection", @@ -2665,7 +2665,7 @@ dependencies = [ "wayland-backend", "wayland-client", "wayland-cursor", - "wayland-protocols 0.31.2", + "wayland-protocols", "wayland-protocols-plasma", "wayland-protocols-wlr", "windows 0.61.3", @@ -2683,7 +2683,7 @@ dependencies = [ [[package]] name = "gpui_macros" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "heck 0.5.0", "proc-macro2", @@ -2694,7 +2694,7 @@ dependencies = [ [[package]] name = "gpui_tokio" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "anyhow", "gpui", @@ -2916,7 +2916,7 @@ dependencies = [ [[package]] name = "http_client" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "anyhow", "async-compression", @@ -2941,7 +2941,7 @@ dependencies = [ [[package]] name = "http_client_tls" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "rustls", "rustls-platform-verifier", @@ -3365,9 +3365,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.15" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +checksum = "7ee5b5339afb4c41626dde77b7a611bd4f2c202b897852b4bcf5d03eddc61010" [[package]] name = "jni" @@ -3734,7 +3734,7 @@ dependencies = [ [[package]] name = "media" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "anyhow", "bindgen", @@ -3984,7 +3984,7 @@ dependencies = [ [[package]] name = "nostr" version = "0.44.1" -source = "git+https://github.com/rust-nostr/nostr#577390dd1ffd7bc1fc577a96b9334b7894212dea" +source = "git+https://github.com/rust-nostr/nostr#e09c9d82a1778683d2a6b968d09eb2c619883bf3" dependencies = [ "aes", "base64", @@ -3997,7 +3997,7 @@ dependencies = [ "hex", "instant", "once_cell", - "rand 0.8.5", + "rand 0.9.2", "scrypt", "secp256k1", "serde", @@ -4009,7 +4009,7 @@ dependencies = [ [[package]] name = "nostr-connect" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#577390dd1ffd7bc1fc577a96b9334b7894212dea" +source = "git+https://github.com/rust-nostr/nostr#e09c9d82a1778683d2a6b968d09eb2c619883bf3" dependencies = [ "async-utility", "nostr", @@ -4021,7 +4021,7 @@ dependencies = [ [[package]] name = "nostr-database" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#577390dd1ffd7bc1fc577a96b9334b7894212dea" +source = "git+https://github.com/rust-nostr/nostr#e09c9d82a1778683d2a6b968d09eb2c619883bf3" dependencies = [ "btreecap", "flatbuffers", @@ -4033,7 +4033,7 @@ dependencies = [ [[package]] name = "nostr-gossip" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#577390dd1ffd7bc1fc577a96b9334b7894212dea" +source = "git+https://github.com/rust-nostr/nostr#e09c9d82a1778683d2a6b968d09eb2c619883bf3" dependencies = [ "nostr", ] @@ -4041,7 +4041,7 @@ dependencies = [ [[package]] name = "nostr-lmdb" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#577390dd1ffd7bc1fc577a96b9334b7894212dea" +source = "git+https://github.com/rust-nostr/nostr#e09c9d82a1778683d2a6b968d09eb2c619883bf3" dependencies = [ "async-utility", "flume", @@ -4055,7 +4055,7 @@ dependencies = [ [[package]] name = "nostr-relay-pool" version = "0.44.0" -source = "git+https://github.com/rust-nostr/nostr#577390dd1ffd7bc1fc577a96b9334b7894212dea" +source = "git+https://github.com/rust-nostr/nostr#e09c9d82a1778683d2a6b968d09eb2c619883bf3" dependencies = [ "async-utility", "async-wsocket", @@ -4072,7 +4072,7 @@ dependencies = [ [[package]] name = "nostr-sdk" version = "0.44.1" -source = "git+https://github.com/rust-nostr/nostr#577390dd1ffd7bc1fc577a96b9334b7894212dea" +source = "git+https://github.com/rust-nostr/nostr#e09c9d82a1778683d2a6b968d09eb2c619883bf3" dependencies = [ "async-utility", "nostr", @@ -4085,9 +4085,9 @@ dependencies = [ [[package]] name = "ntapi" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +checksum = "c70f219e21142367c70c0b30c6a9e3a14d55b4d12a204d897fbec83a0363f081" dependencies = [ "winapi", ] @@ -4589,7 +4589,7 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "perf" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "collections", "serde", @@ -4816,7 +4816,7 @@ version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "219cb19e96be00ab2e37d6e299658a0cfa83e52429179969b0f0121b4ac46983" dependencies = [ - "toml_edit 0.23.9", + "toml_edit 0.23.10+spec-1.0.0", ] [[package]] @@ -5061,9 +5061,9 @@ dependencies = [ [[package]] name = "rangemap" -version = "1.7.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbbbbea733ec66275512d0b9694f34102e7d5406fdbe2ad8d21b28dce92887c" +checksum = "973443cf09a9c8656b574a866ab68dfa19f0867d0340648c7d2f6a71b8a8ea68" [[package]] name = "rav1e" @@ -5224,7 +5224,7 @@ dependencies = [ [[package]] name = "refineable" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "derive_refineable", ] @@ -5277,9 +5277,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.12.26" +version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b4c14b2d9afca6a60277086b0cc6a6ae0b568f6f7916c943a8cdc79f8be240f" +checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ "base64", "bytes", @@ -5322,7 +5322,7 @@ dependencies = [ [[package]] name = "reqwest_client" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "anyhow", "bytes", @@ -5376,7 +5376,7 @@ dependencies = [ [[package]] name = "rope" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "arrayvec", "log", @@ -5579,9 +5579,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "708c0f9d5f54ba0272468c1d306a52c495b31fa155e91bc25371e6df7996908c" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" dependencies = [ "web-time", "zeroize", @@ -5669,9 +5669,9 @@ dependencies = [ [[package]] name = "ryu" -version = "1.0.20" +version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" +checksum = "62049b2877bf12821e8f9ad256ee38fdc31db7387ec2d3b3f403024de2034aea" [[package]] name = "salsa20" @@ -5902,9 +5902,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.145" +version = "1.0.146" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +checksum = "217ca874ae0207aac254aa02c957ded05585a90892cc8d87f9e5fa49669dadd8" dependencies = [ "indexmap", "itoa", @@ -5949,9 +5949,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "1.0.3" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" dependencies = [ "serde_core", ] @@ -6293,7 +6293,7 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sum_tree" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "arrayvec", "log", @@ -6572,6 +6572,11 @@ dependencies = [ "anyhow", "gpui", "log", + "schemars", + "serde", + "serde_json", + "smallvec", + "tempfile", ] [[package]] @@ -6817,14 +6822,14 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.8" +version = "0.9.10+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8" +checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48" dependencies = [ "indexmap", "serde_core", - "serde_spanned 1.0.3", - "toml_datetime 0.7.3", + "serde_spanned 1.0.4", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "toml_writer", "winnow", @@ -6841,9 +6846,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "0.7.3" +version = "0.7.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" dependencies = [ "serde_core", ] @@ -6864,21 +6869,21 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.23.9" +version = "0.23.10+spec-1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d7cbc3b4b49633d57a0509303158ca50de80ae32c265093b24c414705807832" +checksum = "84c8b9f757e028cee9fa244aea147aab2a9ec09d5325a9b01e0a49730c2b5269" dependencies = [ "indexmap", - "toml_datetime 0.7.3", + "toml_datetime 0.7.5+spec-1.1.0", "toml_parser", "winnow", ] [[package]] name = "toml_parser" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" dependencies = [ "winnow", ] @@ -6891,9 +6896,9 @@ checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" [[package]] name = "toml_writer" -version = "1.0.4" +version = "1.0.6+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] name = "tower" @@ -6942,9 +6947,9 @@ checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" -version = "0.1.43" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d15d90a0b5c19378952d479dc858407149d7bb45a14de0142f6c534b16fc647" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" dependencies = [ "log", "pin-project-lite", @@ -6965,9 +6970,9 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.35" +version = "0.1.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a04e24fab5c89c6a36eb8558c9656f30d81de51dfa4d3b45f26b21d61fa0a6c" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" dependencies = [ "once_cell", "valuable", @@ -7264,7 +7269,7 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" [[package]] name = "util" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "anyhow", "async-fs", @@ -7300,7 +7305,7 @@ dependencies = [ [[package]] name = "util_macros" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "perf", "quote", @@ -7559,18 +7564,6 @@ dependencies = [ "xcursor", ] -[[package]] -name = "wayland-protocols" -version = "0.31.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f81f365b8b4a97f422ac0e8737c438024b5951734506b0e1d775c73030561f4" -dependencies = [ - "bitflags 2.10.0", - "wayland-backend", - "wayland-client", - "wayland-scanner", -] - [[package]] name = "wayland-protocols" version = "0.32.9" @@ -7585,14 +7578,14 @@ dependencies = [ [[package]] name = "wayland-protocols-plasma" -version = "0.2.0" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23803551115ff9ea9bce586860c5c5a971e360825a0309264102a9495a5ff479" +checksum = "a07a14257c077ab3279987c4f8bb987851bf57081b93710381daea94f2c2c032" dependencies = [ "bitflags 2.10.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.31.2", + "wayland-protocols", "wayland-scanner", ] @@ -7605,7 +7598,7 @@ dependencies = [ "bitflags 2.10.0", "wayland-backend", "wayland-client", - "wayland-protocols 0.32.9", + "wayland-protocols", "wayland-scanner", ] @@ -8787,7 +8780,7 @@ dependencies = [ [[package]] name = "zlog" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "anyhow", "chrono", @@ -8798,7 +8791,7 @@ dependencies = [ [[package]] name = "ztracing" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" dependencies = [ "tracing", "tracing-subscriber", @@ -8809,7 +8802,7 @@ dependencies = [ [[package]] name = "ztracing_macro" version = "0.1.0" -source = "git+https://github.com/zed-industries/zed#975a76bbf09e2b3b0207c2d02947851591500c2f" +source = "git+https://github.com/zed-industries/zed#acee48bfda7b71e1347129bddccfcca85d40b4c7" [[package]] name = "zune-core" diff --git a/Cargo.toml b/Cargo.toml index 3fc09a4..767243c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,6 +39,7 @@ rust-embed = "8.5.0" rust-i18n = "3" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +schemars = "1" smallvec = "1.14.0" smol = "2" tracing = "0.1.40" diff --git a/assets/themes/catppuccin-frappe.json b/assets/themes/catppuccin-frappe.json new file mode 100644 index 0000000..b9b1f49 --- /dev/null +++ b/assets/themes/catppuccin-frappe.json @@ -0,0 +1,136 @@ +{ + "id": "catppuccin-frappe", + "name": "Catppuccin Frappé", + "author": "Catppuccin", + "url": "https://github.com/catppuccin/catppuccin", + "light": { + "background": "#303446", + "surface_background": "#292c3c", + "elevated_surface_background": "#232634", + "panel_background": "#303446", + "overlay": "#c6d0f51a", + "title_bar": "#00000000", + "title_bar_inactive": "#303446", + "window_border": "#626880", + "border": "#626880", + "border_variant": "#51576d", + "border_focused": "#8caaee", + "border_selected": "#8caaee", + "border_transparent": "#00000000", + "border_disabled": "#414559", + "ring": "#8caaee", + "text": "#c6d0f5", + "text_muted": "#b5bfe2", + "text_placeholder": "#a5adce", + "text_accent": "#8caaee", + "icon": "#c6d0f5", + "icon_muted": "#b5bfe2", + "icon_accent": "#8caaee", + "element_foreground": "#303446", + "element_background": "#8caaee", + "element_hover": "#8caaeee6", + "element_active": "#7e99d6", + "element_selected": "#7088be", + "element_disabled": "#8caaee4d", + "secondary_foreground": "#8caaee", + "secondary_background": "#414559", + "secondary_hover": "#8caaee1a", + "secondary_active": "#51576d", + "secondary_selected": "#51576d", + "secondary_disabled": "#8caaee4d", + "danger_foreground": "#303446", + "danger_background": "#e78284", + "danger_hover": "#e78284e6", + "danger_active": "#d07576", + "danger_selected": "#b96869", + "danger_disabled": "#e782844d", + "warning_foreground": "#303446", + "warning_background": "#e5c890", + "warning_hover": "#e5c890e6", + "warning_active": "#ceb481", + "warning_selected": "#b7a072", + "warning_disabled": "#e5c8904d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#414559", + "ghost_element_hover": "#c6d0f51a", + "ghost_element_active": "#51576d", + "ghost_element_selected": "#51576d", + "ghost_element_disabled": "#c6d0f50d", + "tab_inactive_background": "#414559", + "tab_hover_background": "#51576d", + "tab_active_background": "#626880", + "scrollbar_thumb_background": "#c6d0f533", + "scrollbar_thumb_hover_background": "#c6d0f54d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#51576d", + "drop_target_background": "#8caaee1a", + "cursor": "#99d1db", + "selection": "#99d1db40" + }, + "dark": { + "background": "#303446", + "surface_background": "#292c3c", + "elevated_surface_background": "#232634", + "panel_background": "#303446", + "overlay": "#c6d0f51a", + "title_bar": "#00000000", + "title_bar_inactive": "#303446", + "window_border": "#626880", + "border": "#626880", + "border_variant": "#51576d", + "border_focused": "#8caaee", + "border_selected": "#8caaee", + "border_transparent": "#00000000", + "border_disabled": "#414559", + "ring": "#8caaee", + "text": "#c6d0f5", + "text_muted": "#b5bfe2", + "text_placeholder": "#a5adce", + "text_accent": "#8caaee", + "icon": "#c6d0f5", + "icon_muted": "#b5bfe2", + "icon_accent": "#8caaee", + "element_foreground": "#303446", + "element_background": "#8caaee", + "element_hover": "#8caaeee6", + "element_active": "#7e99d6", + "element_selected": "#7088be", + "element_disabled": "#8caaee4d", + "secondary_foreground": "#8caaee", + "secondary_background": "#414559", + "secondary_hover": "#8caaee1a", + "secondary_active": "#51576d", + "secondary_selected": "#51576d", + "secondary_disabled": "#8caaee4d", + "danger_foreground": "#303446", + "danger_background": "#e78284", + "danger_hover": "#e78284e6", + "danger_active": "#d07576", + "danger_selected": "#b96869", + "danger_disabled": "#e782844d", + "warning_foreground": "#303446", + "warning_background": "#e5c890", + "warning_hover": "#e5c890e6", + "warning_active": "#ceb481", + "warning_selected": "#b7a072", + "warning_disabled": "#e5c8904d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#414559", + "ghost_element_hover": "#c6d0f51a", + "ghost_element_active": "#51576d", + "ghost_element_selected": "#51576d", + "ghost_element_disabled": "#c6d0f50d", + "tab_inactive_background": "#414559", + "tab_hover_background": "#51576d", + "tab_active_background": "#626880", + "scrollbar_thumb_background": "#c6d0f533", + "scrollbar_thumb_hover_background": "#c6d0f54d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#51576d", + "drop_target_background": "#8caaee1a", + "cursor": "#99d1db", + "selection": "#99d1db40" + } +} diff --git a/assets/themes/catppuccin-latte.json b/assets/themes/catppuccin-latte.json new file mode 100644 index 0000000..b0c074b --- /dev/null +++ b/assets/themes/catppuccin-latte.json @@ -0,0 +1,136 @@ +{ + "id": "catppuccin-latte", + "name": "Catppuccin Latte", + "author": "Catppuccin", + "url": "https://github.com/catppuccin/catppuccin", + "light": { + "background": "#eff1f5", + "surface_background": "#e6e9ef", + "elevated_surface_background": "#dce0e8", + "panel_background": "#eff1f5", + "overlay": "#4c4f691a", + "title_bar": "#00000000", + "title_bar_inactive": "#eff1f5", + "window_border": "#acb0be", + "border": "#acb0be", + "border_variant": "#bcc0cc", + "border_focused": "#1e66f5", + "border_selected": "#1e66f5", + "border_transparent": "#00000000", + "border_disabled": "#ccd0da", + "ring": "#1e66f5", + "text": "#4c4f69", + "text_muted": "#5c5f77", + "text_placeholder": "#6c6f85", + "text_accent": "#1e66f5", + "icon": "#4c4f69", + "icon_muted": "#5c5f77", + "icon_accent": "#1e66f5", + "element_foreground": "#eff1f5", + "element_background": "#1e66f5", + "element_hover": "#1e66f5e6", + "element_active": "#1b5cdc", + "element_selected": "#1852c3", + "element_disabled": "#1e66f54d", + "secondary_foreground": "#1e66f5", + "secondary_background": "#e6e9ef", + "secondary_hover": "#1e66f51a", + "secondary_active": "#dce0e8", + "secondary_selected": "#dce0e8", + "secondary_disabled": "#1e66f54d", + "danger_foreground": "#eff1f5", + "danger_background": "#d20f39", + "danger_hover": "#d20f39e6", + "danger_active": "#bc0e33", + "danger_selected": "#a60c2d", + "danger_disabled": "#d20f394d", + "warning_foreground": "#4c4f69", + "warning_background": "#df8e1d", + "warning_hover": "#df8e1de6", + "warning_active": "#c9801a", + "warning_selected": "#b47217", + "warning_disabled": "#df8e1d4d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#e6e9ef", + "ghost_element_hover": "#4c4f691a", + "ghost_element_active": "#dce0e8", + "ghost_element_selected": "#dce0e8", + "ghost_element_disabled": "#4c4f690d", + "tab_inactive_background": "#e6e9ef", + "tab_hover_background": "#dce0e8", + "tab_active_background": "#ccd0da", + "scrollbar_thumb_background": "#4c4f6933", + "scrollbar_thumb_hover_background": "#4c4f694d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#dce0e8", + "drop_target_background": "#1e66f51a", + "cursor": "#04a5e5", + "selection": "#04a5e540" + }, + "dark": { + "background": "#eff1f5", + "surface_background": "#e6e9ef", + "elevated_surface_background": "#dce0e8", + "panel_background": "#eff1f5", + "overlay": "#4c4f691a", + "title_bar": "#00000000", + "title_bar_inactive": "#eff1f5", + "window_border": "#acb0be", + "border": "#acb0be", + "border_variant": "#bcc0cc", + "border_focused": "#1e66f5", + "border_selected": "#1e66f5", + "border_transparent": "#00000000", + "border_disabled": "#ccd0da", + "ring": "#1e66f5", + "text": "#4c4f69", + "text_muted": "#5c5f77", + "text_placeholder": "#6c6f85", + "text_accent": "#1e66f5", + "icon": "#4c4f69", + "icon_muted": "#5c5f77", + "icon_accent": "#1e66f5", + "element_foreground": "#eff1f5", + "element_background": "#1e66f5", + "element_hover": "#1e66f5e6", + "element_active": "#1b5cdc", + "element_selected": "#1852c3", + "element_disabled": "#1e66f54d", + "secondary_foreground": "#1e66f5", + "secondary_background": "#e6e9ef", + "secondary_hover": "#1e66f51a", + "secondary_active": "#dce0e8", + "secondary_selected": "#dce0e8", + "secondary_disabled": "#1e66f54d", + "danger_foreground": "#eff1f5", + "danger_background": "#d20f39", + "danger_hover": "#d20f39e6", + "danger_active": "#bc0e33", + "danger_selected": "#a60c2d", + "danger_disabled": "#d20f394d", + "warning_foreground": "#4c4f69", + "warning_background": "#df8e1d", + "warning_hover": "#df8e1de6", + "warning_active": "#c9801a", + "warning_selected": "#b47217", + "warning_disabled": "#df8e1d4d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#e6e9ef", + "ghost_element_hover": "#4c4f691a", + "ghost_element_active": "#dce0e8", + "ghost_element_selected": "#dce0e8", + "ghost_element_disabled": "#4c4f690d", + "tab_inactive_background": "#e6e9ef", + "tab_hover_background": "#dce0e8", + "tab_active_background": "#ccd0da", + "scrollbar_thumb_background": "#4c4f6933", + "scrollbar_thumb_hover_background": "#4c4f694d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#dce0e8", + "drop_target_background": "#1e66f51a", + "cursor": "#04a5e5", + "selection": "#04a5e540" + } +} diff --git a/assets/themes/catppuccin-macchiato.json b/assets/themes/catppuccin-macchiato.json new file mode 100644 index 0000000..09cb345 --- /dev/null +++ b/assets/themes/catppuccin-macchiato.json @@ -0,0 +1,136 @@ +{ + "id": "catppuccin-macchiato", + "name": "Catppuccin Macchiato", + "author": "Catppuccin", + "url": "https://github.com/catppuccin/catppuccin", + "light": { + "background": "#24273a", + "surface_background": "#1e2030", + "elevated_surface_background": "#181926", + "panel_background": "#24273a", + "overlay": "#cad3f51a", + "title_bar": "#00000000", + "title_bar_inactive": "#24273a", + "window_border": "#5b6078", + "border": "#5b6078", + "border_variant": "#494d64", + "border_focused": "#8aadf4", + "border_selected": "#8aadf4", + "border_transparent": "#00000000", + "border_disabled": "#363a4f", + "ring": "#8aadf4", + "text": "#cad3f5", + "text_muted": "#b8c0e0", + "text_placeholder": "#a5adcb", + "text_accent": "#8aadf4", + "icon": "#cad3f5", + "icon_muted": "#b8c0e0", + "icon_accent": "#8aadf4", + "element_foreground": "#24273a", + "element_background": "#8aadf4", + "element_hover": "#8aadf4e6", + "element_active": "#7c9cdc", + "element_selected": "#6e8bc4", + "element_disabled": "#8aadf44d", + "secondary_foreground": "#8aadf4", + "secondary_background": "#363a4f", + "secondary_hover": "#8aadf41a", + "secondary_active": "#494d64", + "secondary_selected": "#494d64", + "secondary_disabled": "#8aadf44d", + "danger_foreground": "#24273a", + "danger_background": "#ed8796", + "danger_hover": "#ed8796e6", + "danger_active": "#d57a87", + "danger_selected": "#bd6d78", + "danger_disabled": "#ed87964d", + "warning_foreground": "#24273a", + "warning_background": "#eed49f", + "warning_hover": "#eed49fe6", + "warning_active": "#d6bf8f", + "warning_selected": "#beaa7f", + "warning_disabled": "#eed49f4d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#363a4f", + "ghost_element_hover": "#cad3f51a", + "ghost_element_active": "#494d64", + "ghost_element_selected": "#494d64", + "ghost_element_disabled": "#cad3f50d", + "tab_inactive_background": "#363a4f", + "tab_hover_background": "#494d64", + "tab_active_background": "#5b6078", + "scrollbar_thumb_background": "#cad3f533", + "scrollbar_thumb_hover_background": "#cad3f54d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#494d64", + "drop_target_background": "#8aadf41a", + "cursor": "#91d7e3", + "selection": "#91d7e340" + }, + "dark": { + "background": "#24273a", + "surface_background": "#1e2030", + "elevated_surface_background": "#181926", + "panel_background": "#24273a", + "overlay": "#cad3f51a", + "title_bar": "#00000000", + "title_bar_inactive": "#24273a", + "window_border": "#5b6078", + "border": "#5b6078", + "border_variant": "#494d64", + "border_focused": "#8aadf4", + "border_selected": "#8aadf4", + "border_transparent": "#00000000", + "border_disabled": "#363a4f", + "ring": "#8aadf4", + "text": "#cad3f5", + "text_muted": "#b8c0e0", + "text_placeholder": "#a5adcb", + "text_accent": "#8aadf4", + "icon": "#cad3f5", + "icon_muted": "#b8c0e0", + "icon_accent": "#8aadf4", + "element_foreground": "#24273a", + "element_background": "#8aadf4", + "element_hover": "#8aadf4e6", + "element_active": "#7c9cdc", + "element_selected": "#6e8bc4", + "element_disabled": "#8aadf44d", + "secondary_foreground": "#8aadf4", + "secondary_background": "#363a4f", + "secondary_hover": "#8aadf41a", + "secondary_active": "#494d64", + "secondary_selected": "#494d64", + "secondary_disabled": "#8aadf44d", + "danger_foreground": "#24273a", + "danger_background": "#ed8796", + "danger_hover": "#ed8796e6", + "danger_active": "#d57a87", + "danger_selected": "#bd6d78", + "danger_disabled": "#ed87964d", + "warning_foreground": "#24273a", + "warning_background": "#eed49f", + "warning_hover": "#eed49fe6", + "warning_active": "#d6bf8f", + "warning_selected": "#beaa7f", + "warning_disabled": "#eed49f4d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#363a4f", + "ghost_element_hover": "#cad3f51a", + "ghost_element_active": "#494d64", + "ghost_element_selected": "#494d64", + "ghost_element_disabled": "#cad3f50d", + "tab_inactive_background": "#363a4f", + "tab_hover_background": "#494d64", + "tab_active_background": "#5b6078", + "scrollbar_thumb_background": "#cad3f533", + "scrollbar_thumb_hover_background": "#cad3f54d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#494d64", + "drop_target_background": "#8aadf41a", + "cursor": "#91d7e3", + "selection": "#91d7e340" + } +} diff --git a/assets/themes/catppuccin-mocha.json b/assets/themes/catppuccin-mocha.json new file mode 100644 index 0000000..292051d --- /dev/null +++ b/assets/themes/catppuccin-mocha.json @@ -0,0 +1,136 @@ +{ + "id": "catppuccin-mocha", + "name": "Catppuccin Mocha", + "author": "Catppuccin", + "url": "https://github.com/catppuccin/catppuccin", + "light": { + "background": "#1e1e2e", + "surface_background": "#181825", + "elevated_surface_background": "#11111b", + "panel_background": "#1e1e2e", + "overlay": "#cdd6f41a", + "title_bar": "#00000000", + "title_bar_inactive": "#1e1e2e", + "window_border": "#585b70", + "border": "#585b70", + "border_variant": "#45475a", + "border_focused": "#89b4fa", + "border_selected": "#89b4fa", + "border_transparent": "#00000000", + "border_disabled": "#313244", + "ring": "#89b4fa", + "text": "#cdd6f4", + "text_muted": "#bac2de", + "text_placeholder": "#a6adc8", + "text_accent": "#89b4fa", + "icon": "#cdd6f4", + "icon_muted": "#bac2de", + "icon_accent": "#89b4fa", + "element_foreground": "#1e1e2e", + "element_background": "#89b4fa", + "element_hover": "#89b4fae6", + "element_active": "#7ba2e1", + "element_selected": "#6d90c8", + "element_disabled": "#89b4fa4d", + "secondary_foreground": "#89b4fa", + "secondary_background": "#313244", + "secondary_hover": "#89b4fa1a", + "secondary_active": "#45475a", + "secondary_selected": "#45475a", + "secondary_disabled": "#89b4fa4d", + "danger_foreground": "#1e1e2e", + "danger_background": "#f38ba8", + "danger_hover": "#f38ba8e6", + "danger_active": "#db7d97", + "danger_selected": "#c36f86", + "danger_disabled": "#f38ba84d", + "warning_foreground": "#1e1e2e", + "warning_background": "#f9e2af", + "warning_hover": "#f9e2afe6", + "warning_active": "#e0cb9e", + "warning_selected": "#c7b48d", + "warning_disabled": "#f9e2af4d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#313244", + "ghost_element_hover": "#cdd6f41a", + "ghost_element_active": "#45475a", + "ghost_element_selected": "#45475a", + "ghost_element_disabled": "#cdd6f50d", + "tab_inactive_background": "#313244", + "tab_hover_background": "#45475a", + "tab_active_background": "#585b70", + "scrollbar_thumb_background": "#cdd6f533", + "scrollbar_thumb_hover_background": "#cdd6f54d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#45475a", + "drop_target_background": "#89b4fa1a", + "cursor": "#89dceb", + "selection": "#89dceb40" + }, + "dark": { + "background": "#1e1e2e", + "surface_background": "#181825", + "elevated_surface_background": "#11111b", + "panel_background": "#1e1e2e", + "overlay": "#cdd6f41a", + "title_bar": "#00000000", + "title_bar_inactive": "#1e1e2e", + "window_border": "#585b70", + "border": "#585b70", + "border_variant": "#45475a", + "border_focused": "#89b4fa", + "border_selected": "#89b4fa", + "border_transparent": "#00000000", + "border_disabled": "#313244", + "ring": "#89b4fa", + "text": "#cdd6f4", + "text_muted": "#bac2de", + "text_placeholder": "#a6adc8", + "text_accent": "#89b4fa", + "icon": "#cdd6f4", + "icon_muted": "#bac2de", + "icon_accent": "#89b4fa", + "element_foreground": "#1e1e2e", + "element_background": "#89b4fa", + "element_hover": "#89b4fae6", + "element_active": "#7ba2e1", + "element_selected": "#6d90c8", + "element_disabled": "#89b4fa4d", + "secondary_foreground": "#89b4fa", + "secondary_background": "#313244", + "secondary_hover": "#89b4fa1a", + "secondary_active": "#45475a", + "secondary_selected": "#45475a", + "secondary_disabled": "#89b4fa4d", + "danger_foreground": "#1e1e2e", + "danger_background": "#f38ba8", + "danger_hover": "#f38ba8e6", + "danger_active": "#db7d97", + "danger_selected": "#c36f86", + "danger_disabled": "#f38ba84d", + "warning_foreground": "#1e1e2e", + "warning_background": "#f9e2af", + "warning_hover": "#f9e2afe6", + "warning_active": "#e0cb9e", + "warning_selected": "#c7b48d", + "warning_disabled": "#f9e2af4d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#313244", + "ghost_element_hover": "#cdd6f41a", + "ghost_element_active": "#45475a", + "ghost_element_selected": "#45475a", + "ghost_element_disabled": "#cdd6f50d", + "tab_inactive_background": "#313244", + "tab_hover_background": "#45475a", + "tab_active_background": "#585b70", + "scrollbar_thumb_background": "#cdd6f533", + "scrollbar_thumb_hover_background": "#cdd6f54d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#45475a", + "drop_target_background": "#89b4fa1a", + "cursor": "#89dceb", + "selection": "#89dceb40" + } +} diff --git a/assets/themes/flexoki.json b/assets/themes/flexoki.json new file mode 100644 index 0000000..374c889 --- /dev/null +++ b/assets/themes/flexoki.json @@ -0,0 +1,136 @@ +{ + "id": "flexoki", + "name": "Flexoki", + "author": "Steph Ango", + "url": "https://stephango.com/flexoki", + "light": { + "background": "#FFFCF0", + "surface_background": "#F2F0E5", + "elevated_surface_background": "#E6E4D9", + "panel_background": "#FFFCF0", + "overlay": "#100F0F1a", + "title_bar": "#00000000", + "title_bar_inactive": "#FFFCF0", + "window_border": "#CECDC3", + "border": "#CECDC3", + "border_variant": "#DAD8CE", + "border_focused": "#24837B", + "border_selected": "#24837B", + "border_transparent": "#00000000", + "border_disabled": "#E6E4D9", + "ring": "#24837B", + "text": "#100F0F", + "text_muted": "#6F6E69", + "text_placeholder": "#878580", + "text_accent": "#24837B", + "icon": "#100F0F", + "icon_muted": "#6F6E69", + "icon_accent": "#24837B", + "element_foreground": "#DDF1E4", + "element_background": "#24837B", + "element_hover": "#24837Be5", + "element_active": "#20756E", + "element_selected": "#1C6861", + "element_disabled": "#24837B4c", + "secondary_foreground": "#24837B", + "secondary_background": "#E6E4D9", + "secondary_hover": "#24837B1a", + "secondary_active": "#DAD8CE", + "secondary_selected": "#DAD8CE", + "secondary_disabled": "#24837B4c", + "danger_foreground": "#FFE1D5", + "danger_background": "#AF3029", + "danger_hover": "#AF3029e5", + "danger_active": "#9E2B25", + "danger_selected": "#8D2620", + "danger_disabled": "#AF30294c", + "warning_foreground": "#FFE7CE", + "warning_background": "#BC5215", + "warning_hover": "#BC5215e5", + "warning_active": "#A94913", + "warning_selected": "#964011", + "warning_disabled": "#BC52154c", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#E6E4D9", + "ghost_element_hover": "#100F0F1a", + "ghost_element_active": "#DAD8CE", + "ghost_element_selected": "#DAD8CE", + "ghost_element_disabled": "#100F0F0d", + "tab_inactive_background": "#E6E4D9", + "tab_hover_background": "#DAD8CE", + "tab_active_background": "#CECDC3", + "scrollbar_thumb_background": "#100F0F33", + "scrollbar_thumb_hover_background": "#100F0F4d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#DAD8CE", + "drop_target_background": "#24837B1a", + "cursor": "#205EA6", + "selection": "#24837B40" + }, + "dark": { + "background": "#100F0F", + "surface_background": "#1C1B1A", + "elevated_surface_background": "#282726", + "panel_background": "#100F0F", + "overlay": "#FFFCF01a", + "title_bar": "#00000000", + "title_bar_inactive": "#100F0F", + "window_border": "#403E3C", + "border": "#403E3C", + "border_variant": "#343331", + "border_focused": "#3AA99F", + "border_selected": "#3AA99F", + "border_transparent": "#00000000", + "border_disabled": "#282726", + "ring": "#3AA99F", + "text": "#FFFCF0", + "text_muted": "#878580", + "text_placeholder": "#575653", + "text_accent": "#3AA99F", + "icon": "#FFFCF0", + "icon_muted": "#878580", + "icon_accent": "#3AA99F", + "element_foreground": "#101F1D", + "element_background": "#3AA99F", + "element_hover": "#3AA99Fe5", + "element_active": "#34988F", + "element_selected": "#2F877F", + "element_disabled": "#3AA99F4c", + "secondary_foreground": "#3AA99F", + "secondary_background": "#282726", + "secondary_hover": "#3AA99F1a", + "secondary_active": "#343331", + "secondary_selected": "#343331", + "secondary_disabled": "#3AA99F4c", + "danger_foreground": "#261312", + "danger_background": "#D14D41", + "danger_hover": "#D14D41e5", + "danger_active": "#BC453A", + "danger_selected": "#A73D33", + "danger_disabled": "#D14D414c", + "warning_foreground": "#27180E", + "warning_background": "#DA702C", + "warning_hover": "#DA702Ce5", + "warning_active": "#C46527", + "warning_selected": "#AF5A22", + "warning_disabled": "#DA702C4c", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#282726", + "ghost_element_hover": "#FFFCF01a", + "ghost_element_active": "#343331", + "ghost_element_selected": "#343331", + "ghost_element_disabled": "#FFFCF00d", + "tab_inactive_background": "#282726", + "tab_hover_background": "#343331", + "tab_active_background": "#403E3C", + "scrollbar_thumb_background": "#FFFCF033", + "scrollbar_thumb_hover_background": "#FFFCF04d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#343331", + "drop_target_background": "#3AA99F1a", + "cursor": "#4385BE", + "selection": "#3AA99F40" + } +} diff --git a/assets/themes/rose-pine-dawn.json b/assets/themes/rose-pine-dawn.json new file mode 100644 index 0000000..533fb54 --- /dev/null +++ b/assets/themes/rose-pine-dawn.json @@ -0,0 +1,136 @@ +{ + "id": "rose-pine-dawn", + "name": "Rosé Pine Dawn", + "author": "Rosé Pine", + "url": "https://rosepinetheme.com/", + "light": { + "background": "#faf4ed", + "surface_background": "#fffaf3", + "elevated_surface_background": "#f2e9e1", + "panel_background": "#fffaf3", + "overlay": "#5752791a", + "title_bar": "#00000000", + "title_bar_inactive": "#faf4ed", + "window_border": "#cecacd", + "border": "#cecacd", + "border_variant": "#dfdad9", + "border_focused": "#286983", + "border_selected": "#286983", + "border_transparent": "#00000000", + "border_disabled": "#f4ede8", + "ring": "#286983", + "text": "#575279", + "text_muted": "#797593", + "text_placeholder": "#9893a5", + "text_accent": "#907aa9", + "icon": "#575279", + "icon_muted": "#797593", + "icon_accent": "#907aa9", + "element_foreground": "#faf4ed", + "element_background": "#286983", + "element_hover": "#286983e6", + "element_active": "#245f76", + "element_selected": "#205569", + "element_disabled": "#2869834d", + "secondary_foreground": "#286983", + "secondary_background": "#f4ede8", + "secondary_hover": "#2869831a", + "secondary_active": "#dfdad9", + "secondary_selected": "#dfdad9", + "secondary_disabled": "#2869834d", + "danger_foreground": "#faf4ed", + "danger_background": "#b4637a", + "danger_hover": "#b4637ae6", + "danger_active": "#a2596e", + "danger_selected": "#904f62", + "danger_disabled": "#b4637a4d", + "warning_foreground": "#faf4ed", + "warning_background": "#ea9d34", + "warning_hover": "#ea9d34e6", + "warning_active": "#d38d2f", + "warning_selected": "#bc7d2a", + "warning_disabled": "#ea9d344d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#f4ede8", + "ghost_element_hover": "#5752791a", + "ghost_element_active": "#dfdad9", + "ghost_element_selected": "#dfdad9", + "ghost_element_disabled": "#5752790d", + "tab_inactive_background": "#f4ede8", + "tab_hover_background": "#dfdad9", + "tab_active_background": "#cecacd", + "scrollbar_thumb_background": "#57527933", + "scrollbar_thumb_hover_background": "#5752794d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#dfdad9", + "drop_target_background": "#2869831a", + "cursor": "#56949f", + "selection": "#56949f40" + }, + "dark": { + "background": "#faf4ed", + "surface_background": "#fffaf3", + "elevated_surface_background": "#f2e9e1", + "panel_background": "#fffaf3", + "overlay": "#5752791a", + "title_bar": "#00000000", + "title_bar_inactive": "#faf4ed", + "window_border": "#cecacd", + "border": "#cecacd", + "border_variant": "#dfdad9", + "border_focused": "#286983", + "border_selected": "#286983", + "border_transparent": "#00000000", + "border_disabled": "#f4ede8", + "ring": "#286983", + "text": "#575279", + "text_muted": "#797593", + "text_placeholder": "#9893a5", + "text_accent": "#907aa9", + "icon": "#575279", + "icon_muted": "#797593", + "icon_accent": "#907aa9", + "element_foreground": "#faf4ed", + "element_background": "#286983", + "element_hover": "#286983e6", + "element_active": "#245f76", + "element_selected": "#205569", + "element_disabled": "#2869834d", + "secondary_foreground": "#286983", + "secondary_background": "#f4ede8", + "secondary_hover": "#2869831a", + "secondary_active": "#dfdad9", + "secondary_selected": "#dfdad9", + "secondary_disabled": "#2869834d", + "danger_foreground": "#faf4ed", + "danger_background": "#b4637a", + "danger_hover": "#b4637ae6", + "danger_active": "#a2596e", + "danger_selected": "#904f62", + "danger_disabled": "#b4637a4d", + "warning_foreground": "#faf4ed", + "warning_background": "#ea9d34", + "warning_hover": "#ea9d34e6", + "warning_active": "#d38d2f", + "warning_selected": "#bc7d2a", + "warning_disabled": "#ea9d344d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#f4ede8", + "ghost_element_hover": "#5752791a", + "ghost_element_active": "#dfdad9", + "ghost_element_selected": "#dfdad9", + "ghost_element_disabled": "#5752790d", + "tab_inactive_background": "#f4ede8", + "tab_hover_background": "#dfdad9", + "tab_active_background": "#cecacd", + "scrollbar_thumb_background": "#57527933", + "scrollbar_thumb_hover_background": "#5752794d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#dfdad9", + "drop_target_background": "#2869831a", + "cursor": "#56949f", + "selection": "#56949f40" + } +} diff --git a/assets/themes/rose-pine-moon.json b/assets/themes/rose-pine-moon.json new file mode 100644 index 0000000..102299b --- /dev/null +++ b/assets/themes/rose-pine-moon.json @@ -0,0 +1,136 @@ +{ + "id": "rose-pine-moon", + "name": "Rosé Pine Moon", + "author": "Rosé Pine", + "url": "https://rosepinetheme.com/", + "light": { + "background": "#232136", + "surface_background": "#2a273f", + "elevated_surface_background": "#393552", + "panel_background": "#2a273f", + "overlay": "#e0def41a", + "title_bar": "#00000000", + "title_bar_inactive": "#232136", + "window_border": "#56526e", + "border": "#56526e", + "border_variant": "#44415a", + "border_focused": "#3e8fb0", + "border_selected": "#3e8fb0", + "border_transparent": "#00000000", + "border_disabled": "#2a283e", + "ring": "#3e8fb0", + "text": "#e0def4", + "text_muted": "#908caa", + "text_placeholder": "#6e6a86", + "text_accent": "#c4a7e7", + "icon": "#e0def4", + "icon_muted": "#908caa", + "icon_accent": "#c4a7e7", + "element_foreground": "#232136", + "element_background": "#3e8fb0", + "element_hover": "#3e8fb0e6", + "element_active": "#38809d", + "element_selected": "#32718a", + "element_disabled": "#3e8fb04d", + "secondary_foreground": "#3e8fb0", + "secondary_background": "#2a283e", + "secondary_hover": "#3e8fb01a", + "secondary_active": "#44415a", + "secondary_selected": "#44415a", + "secondary_disabled": "#3e8fb04d", + "danger_foreground": "#232136", + "danger_background": "#eb6f92", + "danger_hover": "#eb6f92e6", + "danger_active": "#d46483", + "danger_selected": "#bd5974", + "danger_disabled": "#eb6f924d", + "warning_foreground": "#232136", + "warning_background": "#f6c177", + "warning_hover": "#f6c177e6", + "warning_active": "#ddae6b", + "warning_selected": "#c49b5f", + "warning_disabled": "#f6c1774d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#2a283e", + "ghost_element_hover": "#e0def41a", + "ghost_element_active": "#44415a", + "ghost_element_selected": "#44415a", + "ghost_element_disabled": "#e0def40d", + "tab_inactive_background": "#2a283e", + "tab_hover_background": "#44415a", + "tab_active_background": "#56526e", + "scrollbar_thumb_background": "#e0def433", + "scrollbar_thumb_hover_background": "#e0def44d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#44415a", + "drop_target_background": "#3e8fb01a", + "cursor": "#9ccfd8", + "selection": "#9ccfd840" + }, + "dark": { + "background": "#232136", + "surface_background": "#2a273f", + "elevated_surface_background": "#393552", + "panel_background": "#2a273f", + "overlay": "#e0def41a", + "title_bar": "#00000000", + "title_bar_inactive": "#232136", + "window_border": "#56526e", + "border": "#56526e", + "border_variant": "#44415a", + "border_focused": "#3e8fb0", + "border_selected": "#3e8fb0", + "border_transparent": "#00000000", + "border_disabled": "#2a283e", + "ring": "#3e8fb0", + "text": "#e0def4", + "text_muted": "#908caa", + "text_placeholder": "#6e6a86", + "text_accent": "#c4a7e7", + "icon": "#e0def4", + "icon_muted": "#908caa", + "icon_accent": "#c4a7e7", + "element_foreground": "#232136", + "element_background": "#3e8fb0", + "element_hover": "#3e8fb0e6", + "element_active": "#38809d", + "element_selected": "#32718a", + "element_disabled": "#3e8fb04d", + "secondary_foreground": "#3e8fb0", + "secondary_background": "#2a283e", + "secondary_hover": "#3e8fb01a", + "secondary_active": "#44415a", + "secondary_selected": "#44415a", + "secondary_disabled": "#3e8fb04d", + "danger_foreground": "#232136", + "danger_background": "#eb6f92", + "danger_hover": "#eb6f92e6", + "danger_active": "#d46483", + "danger_selected": "#bd5974", + "danger_disabled": "#eb6f924d", + "warning_foreground": "#232136", + "warning_background": "#f6c177", + "warning_hover": "#f6c177e6", + "warning_active": "#ddae6b", + "warning_selected": "#c49b5f", + "warning_disabled": "#f6c1774d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#2a283e", + "ghost_element_hover": "#e0def41a", + "ghost_element_active": "#44415a", + "ghost_element_selected": "#44415a", + "ghost_element_disabled": "#e0def40d", + "tab_inactive_background": "#2a283e", + "tab_hover_background": "#44415a", + "tab_active_background": "#56526e", + "scrollbar_thumb_background": "#e0def433", + "scrollbar_thumb_hover_background": "#e0def44d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#44415a", + "drop_target_background": "#3e8fb01a", + "cursor": "#9ccfd8", + "selection": "#9ccfd840" + } +} diff --git a/assets/themes/rose-pine.json b/assets/themes/rose-pine.json new file mode 100644 index 0000000..7715730 --- /dev/null +++ b/assets/themes/rose-pine.json @@ -0,0 +1,136 @@ +{ + "id": "rose-pine", + "name": "Rosé Pine", + "author": "Rosé Pine", + "url": "https://rosepinetheme.com/", + "light": { + "background": "#191724", + "surface_background": "#1f1d2e", + "elevated_surface_background": "#26233a", + "panel_background": "#1f1d2e", + "overlay": "#e0def41a", + "title_bar": "#00000000", + "title_bar_inactive": "#191724", + "window_border": "#524f67", + "border": "#524f67", + "border_variant": "#403d52", + "border_focused": "#31748f", + "border_selected": "#31748f", + "border_transparent": "#00000000", + "border_disabled": "#21202e", + "ring": "#31748f", + "text": "#e0def4", + "text_muted": "#908caa", + "text_placeholder": "#6e6a86", + "text_accent": "#c4a7e7", + "icon": "#e0def4", + "icon_muted": "#908caa", + "icon_accent": "#c4a7e7", + "element_foreground": "#191724", + "element_background": "#31748f", + "element_hover": "#31748fe6", + "element_active": "#2c6980", + "element_selected": "#275e71", + "element_disabled": "#31748f4d", + "secondary_foreground": "#31748f", + "secondary_background": "#21202e", + "secondary_hover": "#31748f1a", + "secondary_active": "#403d52", + "secondary_selected": "#403d52", + "secondary_disabled": "#31748f4d", + "danger_foreground": "#191724", + "danger_background": "#eb6f92", + "danger_hover": "#eb6f92e6", + "danger_active": "#d46483", + "danger_selected": "#bd5974", + "danger_disabled": "#eb6f924d", + "warning_foreground": "#191724", + "warning_background": "#f6c177", + "warning_hover": "#f6c177e6", + "warning_active": "#ddae6b", + "warning_selected": "#c49b5f", + "warning_disabled": "#f6c1774d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#21202e", + "ghost_element_hover": "#e0def41a", + "ghost_element_active": "#403d52", + "ghost_element_selected": "#403d52", + "ghost_element_disabled": "#e0def40d", + "tab_inactive_background": "#21202e", + "tab_hover_background": "#403d52", + "tab_active_background": "#524f67", + "scrollbar_thumb_background": "#e0def433", + "scrollbar_thumb_hover_background": "#e0def44d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#403d52", + "drop_target_background": "#31748f1a", + "cursor": "#9ccfd8", + "selection": "#9ccfd840" + }, + "dark": { + "background": "#191724", + "surface_background": "#1f1d2e", + "elevated_surface_background": "#26233a", + "panel_background": "#1f1d2e", + "overlay": "#e0def41a", + "title_bar": "#00000000", + "title_bar_inactive": "#191724", + "window_border": "#524f67", + "border": "#524f67", + "border_variant": "#403d52", + "border_focused": "#31748f", + "border_selected": "#31748f", + "border_transparent": "#00000000", + "border_disabled": "#21202e", + "ring": "#31748f", + "text": "#e0def4", + "text_muted": "#908caa", + "text_placeholder": "#6e6a86", + "text_accent": "#c4a7e7", + "icon": "#e0def4", + "icon_muted": "#908caa", + "icon_accent": "#c4a7e7", + "element_foreground": "#191724", + "element_background": "#31748f", + "element_hover": "#31748fe6", + "element_active": "#2c6980", + "element_selected": "#275e71", + "element_disabled": "#31748f4d", + "secondary_foreground": "#31748f", + "secondary_background": "#21202e", + "secondary_hover": "#31748f1a", + "secondary_active": "#403d52", + "secondary_selected": "#403d52", + "secondary_disabled": "#31748f4d", + "danger_foreground": "#191724", + "danger_background": "#eb6f92", + "danger_hover": "#eb6f92e6", + "danger_active": "#d46483", + "danger_selected": "#bd5974", + "danger_disabled": "#eb6f924d", + "warning_foreground": "#191724", + "warning_background": "#f6c177", + "warning_hover": "#f6c177e6", + "warning_active": "#ddae6b", + "warning_selected": "#c49b5f", + "warning_disabled": "#f6c1774d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#21202e", + "ghost_element_hover": "#e0def41a", + "ghost_element_active": "#403d52", + "ghost_element_selected": "#403d52", + "ghost_element_disabled": "#e0def40d", + "tab_inactive_background": "#21202e", + "tab_hover_background": "#403d52", + "tab_active_background": "#524f67", + "scrollbar_thumb_background": "#e0def433", + "scrollbar_thumb_hover_background": "#e0def44d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#403d52", + "drop_target_background": "#31748f1a", + "cursor": "#9ccfd8", + "selection": "#9ccfd840" + } +} diff --git a/crates/assets/src/lib.rs b/crates/assets/src/lib.rs index 65b7b75..8229e2a 100644 --- a/crates/assets/src/lib.rs +++ b/crates/assets/src/lib.rs @@ -7,6 +7,7 @@ use rust_embed::RustEmbed; #[include = "fonts/**/*"] #[include = "brand/**/*"] #[include = "icons/**/*"] +#[include = "themes/**/*"] #[exclude = "*.DS_Store"] pub struct Assets; @@ -47,13 +48,4 @@ impl Assets { cx.text_system().add_fonts(embedded_fonts) } - - pub fn load_test_fonts(&self, cx: &App) { - cx.text_system() - .add_fonts(vec![self - .load("fonts/plex-mono/ZedPlexMono-Regular.ttf") - .unwrap() - .unwrap()]) - .unwrap() - } } diff --git a/crates/chat_ui/src/lib.rs b/crates/chat_ui/src/lib.rs index ec040ca..bd4ccd5 100644 --- a/crates/chat_ui/src/lib.rs +++ b/crates/chat_ui/src/lib.rs @@ -1021,8 +1021,8 @@ impl ChatPanel { .absolute() .right_4() .top_neg_2() - .shadow_sm() - .rounded_md() + .when(cx.theme().shadow, |this| this.shadow_sm()) + .rounded(cx.theme().radius) .border_1() .border_color(cx.theme().border) .bg(cx.theme().background) @@ -1074,7 +1074,7 @@ impl ChatPanel { .child( img(url.as_str()) .size_16() - .shadow_lg() + .when(cx.theme().shadow, |this| this.shadow_lg()) .rounded(cx.theme().radius) .object_fit(ObjectFit::ScaleDown), ) diff --git a/crates/common/src/constants.rs b/crates/common/src/constants.rs index 4119c6d..5e12fb5 100644 --- a/crates/common/src/constants.rs +++ b/crates/common/src/constants.rs @@ -11,11 +11,7 @@ pub const BOOTSTRAP_RELAYS: [&str; 5] = [ ]; /// Search Relays. -pub const SEARCH_RELAYS: [&str; 3] = [ - "wss://relay.nostr.band", - "wss://search.nos.today", - "wss://relay.noswhere.com", -]; +pub const SEARCH_RELAYS: [&str; 2] = ["wss://search.nos.today", "wss://relay.noswhere.com"]; /// Default relay for Nostr Connect pub const NOSTR_CONNECT_RELAY: &str = "wss://relay.nsec.app"; diff --git a/crates/coop/src/actions.rs b/crates/coop/src/actions.rs index 4fa8e1c..0a189bb 100644 --- a/crates/coop/src/actions.rs +++ b/crates/coop/src/actions.rs @@ -16,6 +16,7 @@ actions!( DarkMode, ViewProfile, ViewRelays, + Themes, Settings, Logout, Quit diff --git a/crates/coop/src/chatspace.rs b/crates/coop/src/chatspace.rs index 82ed391..4562c93 100644 --- a/crates/coop/src/chatspace.rs +++ b/crates/coop/src/chatspace.rs @@ -9,7 +9,7 @@ use encryption::Encryption; use encryption_ui::EncryptionPanel; use gpui::prelude::FluentBuilder; use gpui::{ - deferred, div, px, rems, App, AppContext, Axis, ClipboardItem, Context, Entity, + deferred, div, px, relative, rems, App, AppContext, Axis, ClipboardItem, Context, Entity, InteractiveElement, IntoElement, ParentElement, Render, SharedString, StatefulInteractiveElement, Styled, Subscription, Window, }; @@ -20,7 +20,7 @@ use person::PersonRegistry; use relay_auth::RelayAuth; use settings::AppSettings; use smallvec::{smallvec, SmallVec}; -use theme::{ActiveTheme, Theme, ThemeMode}; +use theme::{ActiveTheme, Theme, ThemeMode, ThemeRegistry}; use title_bar::TitleBar; use ui::avatar::Avatar; use ui::button::{Button, ButtonVariants}; @@ -32,7 +32,9 @@ use ui::popover::{Popover, PopoverContent}; use ui::popup_menu::PopupMenuExt; use ui::{h_flex, v_flex, ContextModal, IconName, Root, Sizable, StyledExt}; -use crate::actions::{reset, DarkMode, KeyringPopup, Logout, Settings, ViewProfile, ViewRelays}; +use crate::actions::{ + reset, DarkMode, KeyringPopup, Logout, Settings, Themes, ViewProfile, ViewRelays, +}; use crate::user::viewer; use crate::views::compose::compose_button; use crate::views::{onboarding, preferences, setup_relay, startup, welcome}; @@ -313,6 +315,58 @@ impl ChatSpace { } } + fn on_themes(&mut self, _ev: &Themes, window: &mut Window, cx: &mut Context) { + window.open_modal(cx, move |this, _window, cx| { + let registry = ThemeRegistry::global(cx); + let themes = registry.read(cx).themes(); + + this.title("Select theme") + .show_close(true) + .overlay_closable(true) + .child(v_flex().gap_2().pb_4().children({ + let mut items = Vec::with_capacity(themes.len()); + + for (name, theme) in themes.iter() { + items.push( + h_flex() + .h_10() + .justify_between() + .child( + v_flex() + .child( + div() + .text_sm() + .text_color(cx.theme().text) + .line_height(relative(1.3)) + .child(theme.name.clone()), + ) + .child( + div() + .text_xs() + .text_color(cx.theme().text_muted) + .child(theme.author.clone()), + ), + ) + .child( + Button::new(format!("change-{name}")) + .label("Set") + .small() + .ghost() + .on_click({ + let theme = theme.clone(); + move |_ev, window, cx| { + Theme::apply_theme(theme.clone(), Some(window), cx); + } + }), + ), + ); + } + + items + })) + }) + } + fn on_sign_out(&mut self, _e: &Logout, _window: &mut Window, cx: &mut Context) { reset(cx); } @@ -567,6 +621,7 @@ impl ChatSpace { IconName::Sun, Box::new(DarkMode), ) + .menu_with_icon("Themes", IconName::Moon, Box::new(Themes)) .menu_with_icon( "Settings", IconName::Settings, @@ -646,6 +701,7 @@ impl Render for ChatSpace { .on_action(cx.listener(Self::on_profile)) .on_action(cx.listener(Self::on_relays)) .on_action(cx.listener(Self::on_dark_mode)) + .on_action(cx.listener(Self::on_themes)) .on_action(cx.listener(Self::on_sign_out)) .on_action(cx.listener(Self::on_open_pubkey)) .on_action(cx.listener(Self::on_copy_pubkey)) diff --git a/crates/coop/src/main.rs b/crates/coop/src/main.rs index 4493d62..bcdba52 100644 --- a/crates/coop/src/main.rs +++ b/crates/coop/src/main.rs @@ -83,6 +83,9 @@ fn main() { // Initialize components ui::init(cx); + // Initialize theme registry + theme::init(cx); + // Initialize backend for keys storage key_store::init(cx); diff --git a/crates/coop/src/sidebar/list_item.rs b/crates/coop/src/sidebar/list_item.rs index 3256e26..485890a 100644 --- a/crates/coop/src/sidebar/list_item.rs +++ b/crates/coop/src/sidebar/list_item.rs @@ -120,8 +120,8 @@ impl RenderOnce for RoomListItem { .flex_1() .flex() .justify_between() - .child(Skeleton::new().w_32().h_2p5().rounded_sm()) - .child(Skeleton::new().w_6().h_2p5().rounded_sm()), + .child(Skeleton::new().w_32().h_2p5().rounded(cx.theme().radius)) + .child(Skeleton::new().w_6().h_2p5().rounded(cx.theme().radius)), ); }; diff --git a/crates/coop/src/sidebar/mod.rs b/crates/coop/src/sidebar/mod.rs index b923f3f..3533664 100644 --- a/crates/coop/src/sidebar/mod.rs +++ b/crates/coop/src/sidebar/mod.rs @@ -151,18 +151,20 @@ impl Sidebar { let mut results: Vec = Vec::with_capacity(FIND_LIMIT); - while let Some(event) = stream.next().await { - // Skip if author is match current user - if event.pubkey == public_key { - continue; - } + while let Some((_url, event)) = stream.next().await { + if let Ok(event) = event { + // Skip if author is match current user + if event.pubkey == public_key { + continue; + } - // Skip if the event has already been added - if results.iter().any(|this| this.pubkey == event.pubkey) { - continue; - } + // Skip if the event has already been added + if results.iter().any(|this| this.pubkey == event.pubkey) { + continue; + } - results.push(event); + results.push(event); + } } if results.is_empty() { diff --git a/crates/coop/src/views/onboarding.rs b/crates/coop/src/views/onboarding.rs index bc1d7b0..2a3d94e 100644 --- a/crates/coop/src/views/onboarding.rs +++ b/crates/coop/src/views/onboarding.rs @@ -191,7 +191,7 @@ impl Onboarding { div() .id(ix) .flex_1() - .rounded_md() + .rounded(cx.theme().radius) .py_0p5() .px_2() .bg(cx.theme().ghost_element_background_alt) @@ -308,13 +308,13 @@ impl Render for Onboarding { .p_2() .flex_1() .h_full() - .rounded_2xl() + .rounded(cx.theme().radius_lg) .child( v_flex() .size_full() .justify_center() .bg(cx.theme().surface_background) - .rounded_2xl() + .rounded(cx.theme().radius_lg) .child( v_flex() .gap_5() @@ -324,8 +324,8 @@ impl Render for Onboarding { this.child( img(qr.clone()) .size(px(256.)) - .rounded_xl() - .shadow_lg() + .rounded(cx.theme().radius_lg) + .when(cx.theme().shadow, |this| this.shadow_lg()) .border_1() .border_color(cx.theme().element_active), ) diff --git a/crates/coop/src/views/screening.rs b/crates/coop/src/views/screening.rs index 1e4a087..ab31d2b 100644 --- a/crates/coop/src/views/screening.rs +++ b/crates/coop/src/views/screening.rs @@ -77,8 +77,10 @@ impl Screening { .stream_events_from(BOOTSTRAP_RELAYS, filter, Duration::from_secs(2)) .await { - while let Some(event) = stream.next().await { - activity = Some(event.created_at); + while let Some((_url, event)) = stream.next().await { + if let Ok(event) = event { + activity = Some(event.created_at); + } } } diff --git a/crates/coop/src/views/startup.rs b/crates/coop/src/views/startup.rs index fafc749..496a445 100644 --- a/crates/coop/src/views/startup.rs +++ b/crates/coop/src/views/startup.rs @@ -249,7 +249,7 @@ impl Render for Startup { .h_10() .w_72() .bg(cx.theme().elevated_surface_background) - .rounded_lg() + .rounded(cx.theme().radius_lg) .text_sm() .when(self.loading, |this| { this.child( diff --git a/crates/theme/Cargo.toml b/crates/theme/Cargo.toml index 316455e..80e07c1 100644 --- a/crates/theme/Cargo.toml +++ b/crates/theme/Cargo.toml @@ -8,3 +8,10 @@ publish.workspace = true gpui.workspace = true anyhow.workspace = true log.workspace = true +serde.workspace = true +serde_json.workspace = true +schemars.workspace = true +smallvec.workspace = true + +[dev-dependencies] +tempfile = "3.10" diff --git a/crates/theme/src/colors.rs b/crates/theme/src/colors.rs index 23408ad..bdb9426 100644 --- a/crates/theme/src/colors.rs +++ b/crates/theme/src/colors.rs @@ -1,2213 +1,2472 @@ -#![allow(dead_code)] - -use gpui::{hsla, Hsla, Rgba}; - -use crate::scale::{ColorScale, ColorScaleSet, ColorScales}; - -pub(crate) fn neutral() -> ColorScaleSet { - gray() -} - -pub(crate) fn brand() -> ColorScaleSet { - yellow() -} - -pub(crate) fn danger() -> ColorScaleSet { - tomato() -} - -pub(crate) fn warning() -> ColorScaleSet { - orange() -} - -/// Make a [gpui::Hsla] color. -/// -/// - h: 0..360.0 -/// - s: 0.0..100.0 -/// - l: 0.0..100.0 -pub fn hsl(h: f32, s: f32, l: f32) -> Hsla { - hsla(h / 360., s / 100.0, l / 100.0, 1.0) -} - -type StaticColorScale = [&'static str; 12]; - -struct StaticColorScaleSet { - scale: &'static str, - light: StaticColorScale, - light_alpha: StaticColorScale, - dark: StaticColorScale, - dark_alpha: StaticColorScale, -} - -impl TryFrom for ColorScaleSet { - type Error = anyhow::Error; - - fn try_from(value: StaticColorScaleSet) -> Result { - fn to_color_scale(scale: StaticColorScale) -> Result { - scale - .into_iter() - .map(|color| Rgba::try_from(color).map(Hsla::from)) - .collect::, _>>() - .map(ColorScale::from_iter) - } - - Ok(Self::new( - value.scale, - to_color_scale(value.light)?, - to_color_scale(value.light_alpha)?, - to_color_scale(value.dark)?, - to_color_scale(value.dark_alpha)?, - )) - } -} - -/// Color scales used to build the default themes. -pub fn default_color_scales() -> ColorScales { - ColorScales { - gray: gray(), - mauve: mauve(), - slate: slate(), - sage: sage(), - olive: olive(), - sand: sand(), - gold: gold(), - bronze: bronze(), - brown: brown(), - yellow: yellow(), - amber: amber(), - orange: orange(), - tomato: tomato(), - red: red(), - ruby: ruby(), - crimson: crimson(), - pink: pink(), - plum: plum(), - purple: purple(), - violet: violet(), - iris: iris(), - indigo: indigo(), - blue: blue(), - cyan: cyan(), - teal: teal(), - jade: jade(), - green: green(), - grass: grass(), - lime: lime(), - mint: mint(), - sky: sky(), - black: black(), - white: white(), - } -} - -pub(crate) fn gray() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Gray", - light: [ - "#fcfcfcff", - "#f9f9f9ff", - "#f0f0f0ff", - "#e8e8e8ff", - "#e0e0e0ff", - "#d9d9d9ff", - "#cececeff", - "#bbbbbbff", - "#8d8d8dff", - "#838383ff", - "#646464ff", - "#202020ff", - ], - light_alpha: [ - "#00000003", - "#00000006", - "#0000000f", - "#00000017", - "#0000001f", - "#00000026", - "#00000031", - "#00000044", - "#00000072", - "#0000007c", - "#0000009b", - "#000000df", - ], - dark: [ - "#111111ff", - "#191919ff", - "#222222ff", - "#2a2a2aff", - "#313131ff", - "#3a3a3aff", - "#484848ff", - "#606060ff", - "#6e6e6eff", - "#7b7b7bff", - "#b4b4b4ff", - "#eeeeeeff", - ], - dark_alpha: [ - "#00000000", - "#ffffff09", - "#ffffff12", - "#ffffff1b", - "#ffffff22", - "#ffffff2c", - "#ffffff3b", - "#ffffff55", - "#ffffff64", - "#ffffff72", - "#ffffffaf", - "#ffffffed", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn mauve() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Mauve", - light: [ - "#fdfcfdff", - "#faf9fbff", - "#f2eff3ff", - "#eae7ecff", - "#e3dfe6ff", - "#dbd8e0ff", - "#d0cdd7ff", - "#bcbac7ff", - "#8e8c99ff", - "#84828eff", - "#65636dff", - "#211f26ff", - ], - light_alpha: [ - "#55005503", - "#2b005506", - "#30004010", - "#20003618", - "#20003820", - "#14003527", - "#10003332", - "#08003145", - "#05001d73", - "#0500197d", - "#0400119c", - "#020008e0", - ], - dark: [ - "#121113ff", - "#1a191bff", - "#232225ff", - "#2b292dff", - "#323035ff", - "#3c393fff", - "#49474eff", - "#625f69ff", - "#6f6d78ff", - "#7c7a85ff", - "#b5b2bcff", - "#eeeef0ff", - ], - dark_alpha: [ - "#00000000", - "#f5f4f609", - "#ebeaf814", - "#eee5f81d", - "#efe6fe25", - "#f1e6fd30", - "#eee9ff40", - "#eee7ff5d", - "#eae6fd6e", - "#ece9fd7c", - "#f5f1ffb7", - "#fdfdffef", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn slate() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Slate", - light: [ - "#fcfcfdff", - "#f9f9fbff", - "#f0f0f3ff", - "#e8e8ecff", - "#e0e1e6ff", - "#d9d9e0ff", - "#cdced6ff", - "#b9bbc6ff", - "#8b8d98ff", - "#80838dff", - "#60646cff", - "#1c2024ff", - ], - light_alpha: [ - "#00005503", - "#00005506", - "#0000330f", - "#00002d17", - "#0009321f", - "#00002f26", - "#00062e32", - "#00083046", - "#00051d74", - "#00071b7f", - "#0007149f", - "#000509e3", - ], - dark: [ - "#111113ff", - "#18191bff", - "#212225ff", - "#272a2dff", - "#2e3135ff", - "#363a3fff", - "#43484eff", - "#5a6169ff", - "#696e77ff", - "#777b84ff", - "#b0b4baff", - "#edeef0ff", - ], - dark_alpha: [ - "#00000000", - "#d8f4f609", - "#ddeaf814", - "#d3edf81d", - "#d9edfe25", - "#d6ebfd30", - "#d9edff40", - "#d9edff5d", - "#dfebfd6d", - "#e5edfd7b", - "#f1f7feb5", - "#fcfdffef", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn sage() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Sage", - light: [ - "#fbfdfcff", - "#f7f9f8ff", - "#eef1f0ff", - "#e6e9e8ff", - "#dfe2e0ff", - "#d7dad9ff", - "#cbcfcdff", - "#b8bcbaff", - "#868e8bff", - "#7c8481ff", - "#5f6563ff", - "#1a211eff", - ], - light_alpha: [ - "#00804004", - "#00402008", - "#002d1e11", - "#001f1519", - "#00180820", - "#00140d28", - "#00140a34", - "#000f0847", - "#00110b79", - "#00100a83", - "#000a07a0", - "#000805e5", - ], - dark: [ - "#101211ff", - "#171918ff", - "#202221ff", - "#272a29ff", - "#2e3130ff", - "#373b39ff", - "#444947ff", - "#5b625fff", - "#63706bff", - "#717d79ff", - "#adb5b2ff", - "#eceeedff", - ], - dark_alpha: [ - "#00000000", - "#f0f2f108", - "#f3f5f412", - "#f2fefd1a", - "#f1fbfa22", - "#edfbf42d", - "#edfcf73c", - "#ebfdf657", - "#dffdf266", - "#e5fdf674", - "#f4fefbb0", - "#fdfffeed", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn olive() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Olive", - light: [ - "#fcfdfcff", - "#f8faf8ff", - "#eff1efff", - "#e7e9e7ff", - "#dfe2dfff", - "#d7dad7ff", - "#cccfccff", - "#b9bcb8ff", - "#898e87ff", - "#7f847dff", - "#60655fff", - "#1d211cff", - ], - light_alpha: [ - "#00550003", - "#00490007", - "#00200010", - "#00160018", - "#00180020", - "#00140028", - "#000f0033", - "#040f0047", - "#050f0078", - "#040e0082", - "#020a00a0", - "#010600e3", - ], - dark: [ - "#111210ff", - "#181917ff", - "#212220ff", - "#282a27ff", - "#2f312eff", - "#383a36ff", - "#454843ff", - "#5c625bff", - "#687066ff", - "#767d74ff", - "#afb5adff", - "#eceeecff", - ], - dark_alpha: [ - "#00000000", - "#f1f2f008", - "#f4f5f312", - "#f3fef21a", - "#f2fbf122", - "#f4faed2c", - "#f2fced3b", - "#edfdeb57", - "#ebfde766", - "#f0fdec74", - "#f6fef4b0", - "#fdfffded", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn sand() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Sand", - light: [ - "#fdfdfcff", - "#f9f9f8ff", - "#f1f0efff", - "#e9e8e6ff", - "#e2e1deff", - "#dad9d6ff", - "#cfcecaff", - "#bcbbb5ff", - "#8d8d86ff", - "#82827cff", - "#63635eff", - "#21201cff", - ], - light_alpha: [ - "#55550003", - "#25250007", - "#20100010", - "#1f150019", - "#1f180021", - "#19130029", - "#19140035", - "#1915014a", - "#0f0f0079", - "#0c0c0083", - "#080800a1", - "#060500e3", - ], - dark: [ - "#111110ff", - "#191918ff", - "#222221ff", - "#2a2a28ff", - "#31312eff", - "#3b3a37ff", - "#494844ff", - "#62605bff", - "#6f6d66ff", - "#7c7b74ff", - "#b5b3adff", - "#eeeeecff", - ], - dark_alpha: [ - "#00000000", - "#f4f4f309", - "#f6f6f513", - "#fefef31b", - "#fbfbeb23", - "#fffaed2d", - "#fffbed3c", - "#fff9eb57", - "#fffae965", - "#fffdee73", - "#fffcf4b0", - "#fffffded", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn gold() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Gold", - light: [ - "#fdfdfcff", - "#faf9f2ff", - "#f2f0e7ff", - "#eae6dbff", - "#e1dccfff", - "#d8d0bfff", - "#cbc0aaff", - "#b9a88dff", - "#978365ff", - "#8c7a5eff", - "#71624bff", - "#3b352bff", - ], - light_alpha: [ - "#55550003", - "#9d8a000d", - "#75600018", - "#6b4e0024", - "#60460030", - "#64440040", - "#63420055", - "#633d0072", - "#5332009a", - "#492d00a1", - "#362100b4", - "#130c00d4", - ], - dark: [ - "#121211ff", - "#1b1a17ff", - "#24231fff", - "#2d2b26ff", - "#38352eff", - "#444039ff", - "#544f46ff", - "#696256ff", - "#978365ff", - "#a39073ff", - "#cbb99fff", - "#e8e2d9ff", - ], - dark_alpha: [ - "#91911102", - "#f9e29d0b", - "#f8ecbb15", - "#ffeec41e", - "#feecc22a", - "#feebcb37", - "#ffedcd48", - "#fdeaca5f", - "#ffdba690", - "#fedfb09d", - "#fee7c6c8", - "#fef7ede7", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn bronze() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Bronze", - light: [ - "#fdfcfcff", - "#fdf7f5ff", - "#f6edeaff", - "#efe4dfff", - "#e7d9d3ff", - "#dfcdc5ff", - "#d3bcb3ff", - "#c2a499ff", - "#a18072ff", - "#957468ff", - "#7d5e54ff", - "#43302bff", - ], - light_alpha: [ - "#55000003", - "#cc33000a", - "#92250015", - "#80280020", - "#7423002c", - "#7324003a", - "#6c1f004c", - "#671c0066", - "#551a008d", - "#4c150097", - "#3d0f00ab", - "#1d0600d4", - ], - dark: [ - "#141110ff", - "#1c1917ff", - "#262220ff", - "#302a27ff", - "#3b3330ff", - "#493e3aff", - "#5a4c47ff", - "#6f5f58ff", - "#a18072ff", - "#ae8c7eff", - "#d4b3a5ff", - "#ede0d9ff", - ], - dark_alpha: [ - "#d1110004", - "#fbbc910c", - "#faceb817", - "#facdb622", - "#ffd2c12d", - "#ffd1c03c", - "#fdd0c04f", - "#ffd6c565", - "#fec7b09b", - "#fecab5a9", - "#ffd7c6d1", - "#fff1e9ec", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn brown() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Brown", - light: [ - "#fefdfcff", - "#fcf9f6ff", - "#f6eee7ff", - "#f0e4d9ff", - "#ebdacaff", - "#e4cdb7ff", - "#dcbc9fff", - "#cea37eff", - "#ad7f58ff", - "#a07553ff", - "#815e46ff", - "#3e332eff", - ], - light_alpha: [ - "#aa550003", - "#aa550009", - "#a04b0018", - "#9b4a0026", - "#9f4d0035", - "#a04e0048", - "#a34e0060", - "#9f4a0081", - "#823c00a7", - "#723300ac", - "#522100b9", - "#140600d1", - ], - dark: [ - "#12110fff", - "#1c1816ff", - "#28211dff", - "#322922ff", - "#3e3128ff", - "#4d3c2fff", - "#614a39ff", - "#7c5f46ff", - "#ad7f58ff", - "#b88c67ff", - "#dbb594ff", - "#f2e1caff", - ], - dark_alpha: [ - "#91110002", - "#fba67c0c", - "#fcb58c19", - "#fbbb8a24", - "#fcb88931", - "#fdba8741", - "#ffbb8856", - "#ffbe8773", - "#feb87da8", - "#ffc18cb3", - "#fed1aad9", - "#feecd4f2", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn yellow() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Yellow", - light: [ - "#fdfdf9ff", - "#fefce9ff", - "#fffab8ff", - "#fff394ff", - "#ffe770ff", - "#f3d768ff", - "#e4c767ff", - "#d5ae39ff", - "#ffe629ff", - "#ffdc00ff", - "#9e6c00ff", - "#473b1fff", - ], - light_alpha: [ - "#aaaa0006", - "#f4dd0016", - "#ffee0047", - "#ffe3016b", - "#ffd5008f", - "#ebbc0097", - "#d2a10098", - "#c99700c6", - "#ffe100d6", - "#ffdc00ff", - "#9e6c00ff", - "#2e2000e0", - ], - dark: [ - "#14120bff", - "#1b180fff", - "#2d2305ff", - "#362b00ff", - "#433500ff", - "#524202ff", - "#665417ff", - "#836a21ff", - "#ffe629ff", - "#ffff57ff", - "#f5e147ff", - "#f6eeb4ff", - ], - dark_alpha: [ - "#d1510004", - "#f9b4000b", - "#ffaa001e", - "#fdb70028", - "#febb0036", - "#fec40046", - "#fdcb225c", - "#fdca327b", - "#ffe629ff", - "#ffff57ff", - "#fee949f5", - "#fef6baf6", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn amber() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Amber", - light: [ - "#fefdfbff", - "#fefbe9ff", - "#fff7c2ff", - "#ffee9cff", - "#fbe577ff", - "#f3d673ff", - "#e9c162ff", - "#e2a336ff", - "#ffc53dff", - "#ffba18ff", - "#ab6400ff", - "#4f3422ff", - ], - light_alpha: [ - "#c0800004", - "#f4d10016", - "#ffde003d", - "#ffd40063", - "#f8cf0088", - "#eab5008c", - "#dc9b009d", - "#da8a00c9", - "#ffb300c2", - "#ffb300e7", - "#ab6400ff", - "#341500dd", - ], - dark: [ - "#16120cff", - "#1d180fff", - "#302008ff", - "#3f2700ff", - "#4d3000ff", - "#5c3d05ff", - "#714f19ff", - "#8f6424ff", - "#ffc53dff", - "#ffd60aff", - "#ffca16ff", - "#ffe7b3ff", - ], - dark_alpha: [ - "#e63c0006", - "#fd9b000d", - "#fa820022", - "#fc820032", - "#fd8b0041", - "#fd9b0051", - "#ffab2567", - "#ffae3587", - "#ffc53dff", - "#ffd60aff", - "#ffca16ff", - "#ffe7b3ff", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn orange() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Orange", - light: [ - "#fefcfbff", - "#fff7edff", - "#ffefd6ff", - "#ffdfb5ff", - "#ffd19aff", - "#ffc182ff", - "#f5ae73ff", - "#ec9455ff", - "#f76b15ff", - "#ef5f00ff", - "#cc4e00ff", - "#582d1dff", - ], - light_alpha: [ - "#c0400004", - "#ff8e0012", - "#ff9c0029", - "#ff91014a", - "#ff8b0065", - "#ff81007d", - "#ed6c008c", - "#e35f00aa", - "#f65e00ea", - "#ef5f00ff", - "#cc4e00ff", - "#431200e2", - ], - dark: [ - "#17120eff", - "#1e160fff", - "#331e0bff", - "#462100ff", - "#562800ff", - "#66350cff", - "#7e451dff", - "#a35829ff", - "#f76b15ff", - "#ff801fff", - "#ffa057ff", - "#ffe0c2ff", - ], - dark_alpha: [ - "#ec360007", - "#fe6d000e", - "#fb6a0025", - "#ff590039", - "#ff61004a", - "#fd75045c", - "#ff832c75", - "#fe84389d", - "#fe6d15f7", - "#ff801fff", - "#ffa057ff", - "#ffe0c2ff", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn tomato() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Tomato", - light: [ - "#fffcfcff", - "#fff8f7ff", - "#feebe7ff", - "#ffdcd3ff", - "#ffcdc2ff", - "#fdbdafff", - "#f5a898ff", - "#ec8e7bff", - "#e54d2eff", - "#dd4425ff", - "#d13415ff", - "#5c271fff", - ], - light_alpha: [ - "#ff000003", - "#ff200008", - "#f52b0018", - "#ff35002c", - "#ff2e003d", - "#f92d0050", - "#e7280067", - "#db250084", - "#df2600d1", - "#d72400da", - "#cd2200ea", - "#460900e0", - ], - dark: [ - "#181111ff", - "#1f1513ff", - "#391714ff", - "#4e1511ff", - "#5e1c16ff", - "#6e2920ff", - "#853a2dff", - "#ac4d39ff", - "#e54d2eff", - "#ec6142ff", - "#ff977dff", - "#fbd3cbff", - ], - dark_alpha: [ - "#f1121208", - "#ff55330f", - "#ff35232b", - "#fd201142", - "#fe332153", - "#ff4f3864", - "#fd644a7d", - "#fe6d4ea7", - "#fe5431e4", - "#ff6847eb", - "#ff977dff", - "#ffd6cefb", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn red() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Red", - light: [ - "#fffcfcff", - "#fff7f7ff", - "#feebecff", - "#ffdbdcff", - "#ffcdceff", - "#fdbdbeff", - "#f4a9aaff", - "#eb8e90ff", - "#e5484dff", - "#dc3e42ff", - "#ce2c31ff", - "#641723ff", - ], - light_alpha: [ - "#ff000003", - "#ff000008", - "#f3000d14", - "#ff000824", - "#ff000632", - "#f8000442", - "#df000356", - "#d2000571", - "#db0007b7", - "#d10005c1", - "#c40006d3", - "#55000de8", - ], - dark: [ - "#191111ff", - "#201314ff", - "#3b1219ff", - "#500f1cff", - "#611623ff", - "#72232dff", - "#8c333aff", - "#b54548ff", - "#e5484dff", - "#ec5d5eff", - "#ff9592ff", - "#ffd1d9ff", - ], - dark_alpha: [ - "#f4121209", - "#f22f3e11", - "#ff173f2d", - "#fe0a3b44", - "#ff204756", - "#ff3e5668", - "#ff536184", - "#ff5d61b0", - "#fe4e54e4", - "#ff6465eb", - "#ff9592ff", - "#ffd1d9ff", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn ruby() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Ruby", - light: [ - "#fffcfdff", - "#fff7f8ff", - "#feeaedff", - "#ffdce1ff", - "#ffced6ff", - "#f8bfc8ff", - "#efacb8ff", - "#e592a3ff", - "#e54666ff", - "#dc3b5dff", - "#ca244dff", - "#64172bff", - ], - light_alpha: [ - "#ff005503", - "#ff002008", - "#f3002515", - "#ff002523", - "#ff002a31", - "#e4002440", - "#ce002553", - "#c300286d", - "#db002cb9", - "#d2002cc4", - "#c10030db", - "#550016e8", - ], - dark: [ - "#191113ff", - "#1e1517ff", - "#3a141eff", - "#4e1325ff", - "#5e1a2eff", - "#6f2539ff", - "#883447ff", - "#b3445aff", - "#e54666ff", - "#ec5a72ff", - "#ff949dff", - "#fed2e1ff", - ], - dark_alpha: [ - "#f4124a09", - "#fe5a7f0e", - "#ff235d2c", - "#fd195e42", - "#fe2d6b53", - "#ff447665", - "#ff577d80", - "#ff5c7cae", - "#fe4c70e4", - "#ff617beb", - "#ff949dff", - "#ffd3e2fe", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn crimson() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Crimson", - light: [ - "#fffcfdff", - "#fef7f9ff", - "#ffe9f0ff", - "#fedce7ff", - "#faceddff", - "#f3bed1ff", - "#eaacc3ff", - "#e093b2ff", - "#e93d82ff", - "#df3478ff", - "#cb1d63ff", - "#621639ff", - ], - light_alpha: [ - "#ff005503", - "#e0004008", - "#ff005216", - "#f8005123", - "#e5004f31", - "#d0004b41", - "#bf004753", - "#b6004a6c", - "#e2005bc2", - "#d70056cb", - "#c4004fe2", - "#530026e9", - ], - dark: [ - "#191114ff", - "#201318ff", - "#381525ff", - "#4d122fff", - "#5c1839ff", - "#6d2545ff", - "#873356ff", - "#b0436eff", - "#e93d82ff", - "#ee518aff", - "#ff92adff", - "#fdd3e8ff", - ], - dark_alpha: [ - "#f4126709", - "#f22f7a11", - "#fe2a8b2a", - "#fd158741", - "#fd278f51", - "#fe459763", - "#fd559b7f", - "#fe5b9bab", - "#fe418de8", - "#ff5693ed", - "#ff92adff", - "#ffd5eafd", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn pink() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Pink", - light: [ - "#fffcfeff", - "#fef7fbff", - "#fee9f5ff", - "#fbdcefff", - "#f6cee7ff", - "#efbfddff", - "#e7acd0ff", - "#dd93c2ff", - "#d6409fff", - "#cf3897ff", - "#c2298aff", - "#651249ff", - ], - light_alpha: [ - "#ff00aa03", - "#e0008008", - "#f4008c16", - "#e2008b23", - "#d1008331", - "#c0007840", - "#b6006f53", - "#af006f6c", - "#c8007fbf", - "#c2007ac7", - "#b60074d6", - "#59003bed", - ], - dark: [ - "#191117ff", - "#21121dff", - "#37172fff", - "#4b143dff", - "#591c47ff", - "#692955ff", - "#833869ff", - "#a84885ff", - "#d6409fff", - "#de51a8ff", - "#ff8dccff", - "#fdd1eaff", - ], - dark_alpha: [ - "#f412bc09", - "#f420bb12", - "#fe37cc29", - "#fc1ec43f", - "#fd35c24e", - "#fd51c75f", - "#fd62c87b", - "#ff68c8a2", - "#fe49bcd4", - "#ff5cc0dc", - "#ff8dccff", - "#ffd3ecfd", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn plum() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Plum", - light: [ - "#fefcffff", - "#fdf7fdff", - "#fbebfbff", - "#f7def8ff", - "#f2d1f3ff", - "#e9c2ecff", - "#deade3ff", - "#cf91d8ff", - "#ab4abaff", - "#a144afff", - "#953ea3ff", - "#53195dff", - ], - light_alpha: [ - "#aa00ff03", - "#c000c008", - "#cc00cc14", - "#c200c921", - "#b700bd2e", - "#a400b03d", - "#9900a852", - "#9000a56e", - "#89009eb5", - "#7f0092bb", - "#730086c1", - "#40004be6", - ], - dark: [ - "#181118ff", - "#201320ff", - "#351a35ff", - "#451d47ff", - "#512454ff", - "#5e3061ff", - "#734079ff", - "#92549cff", - "#ab4abaff", - "#b658c4ff", - "#e796f3ff", - "#f4d4f4ff", - ], - dark_alpha: [ - "#f112f108", - "#f22ff211", - "#fd4cfd27", - "#f646ff3a", - "#f455ff48", - "#f66dff56", - "#f07cfd70", - "#ee84ff95", - "#e961feb6", - "#ed70ffc0", - "#f19cfef3", - "#feddfef4", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn purple() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Purple", - light: [ - "#fefcfeff", - "#fbf7feff", - "#f7edfeff", - "#f2e2fcff", - "#ead5f9ff", - "#e0c4f4ff", - "#d1afecff", - "#be93e4ff", - "#8e4ec6ff", - "#8347b9ff", - "#8145b5ff", - "#402060ff", - ], - light_alpha: [ - "#aa00aa03", - "#8000e008", - "#8e00f112", - "#8d00e51d", - "#8000db2a", - "#7a01d03b", - "#6d00c350", - "#6600c06c", - "#5c00adb1", - "#53009eb8", - "#52009aba", - "#250049df", - ], - dark: [ - "#18111bff", - "#1e1523ff", - "#301c3bff", - "#3d224eff", - "#48295cff", - "#54346bff", - "#664282ff", - "#8457aaff", - "#8e4ec6ff", - "#9a5cd0ff", - "#d19dffff", - "#ecd9faff", - ], - dark_alpha: [ - "#b412f90b", - "#b744f714", - "#c150ff2d", - "#bb53fd42", - "#be5cfd51", - "#c16dfd61", - "#c378fd7a", - "#c47effa4", - "#b661ffc2", - "#bc6fffcd", - "#d19dffff", - "#f1ddfffa", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn violet() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Violet", - light: [ - "#fdfcfeff", - "#faf8ffff", - "#f4f0feff", - "#ebe4ffff", - "#e1d9ffff", - "#d4cafeff", - "#c2b5f5ff", - "#aa99ecff", - "#6e56cfff", - "#654dc4ff", - "#6550b9ff", - "#2f265fff", - ], - light_alpha: [ - "#5500aa03", - "#4900ff07", - "#4400ee0f", - "#4300ff1b", - "#3600ff26", - "#3100fb35", - "#2d01dd4a", - "#2b00d066", - "#2400b7a9", - "#2300abb2", - "#1f0099af", - "#0b0043d9", - ], - dark: [ - "#14121fff", - "#1b1525ff", - "#291f43ff", - "#33255bff", - "#3c2e69ff", - "#473876ff", - "#56468bff", - "#6958adff", - "#6e56cfff", - "#7d66d9ff", - "#baa7ffff", - "#e2ddfeff", - ], - dark_alpha: [ - "#4422ff0f", - "#853ff916", - "#8354fe36", - "#7d51fd50", - "#845ffd5f", - "#8f6cfd6d", - "#9879ff83", - "#977dfea8", - "#8668ffcc", - "#9176fed7", - "#baa7ffff", - "#e3defffe", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn iris() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Iris", - light: [ - "#fdfdffff", - "#f8f8ffff", - "#f0f1feff", - "#e6e7ffff", - "#dadcffff", - "#cbcdffff", - "#b8baf8ff", - "#9b9ef0ff", - "#5b5bd6ff", - "#5151cdff", - "#5753c6ff", - "#272962ff", - ], - light_alpha: [ - "#0000ff02", - "#0000ff07", - "#0011ee0f", - "#000bff19", - "#000eff25", - "#000aff34", - "#0008e647", - "#0008d964", - "#0000c0a4", - "#0000b6ae", - "#0600abac", - "#000246d8", - ], - dark: [ - "#13131eff", - "#171625ff", - "#202248ff", - "#262a65ff", - "#303374ff", - "#3d3e82ff", - "#4a4a95ff", - "#5958b1ff", - "#5b5bd6ff", - "#6e6adeff", - "#b1a9ffff", - "#e0dffeff", - ], - dark_alpha: [ - "#3636fe0e", - "#564bf916", - "#525bff3b", - "#4d58ff5a", - "#5b62fd6b", - "#6d6ffd7a", - "#7777fe8e", - "#7b7afeac", - "#6a6afed4", - "#7d79ffdc", - "#b1a9ffff", - "#e1e0fffe", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn indigo() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Indigo", - light: [ - "#fdfdfeff", - "#f7f9ffff", - "#edf2feff", - "#e1e9ffff", - "#d2deffff", - "#c1d0ffff", - "#abbdf9ff", - "#8da4efff", - "#3e63ddff", - "#3358d4ff", - "#3a5bc7ff", - "#1f2d5cff", - ], - light_alpha: [ - "#00008002", - "#0040ff08", - "#0047f112", - "#0044ff1e", - "#0044ff2d", - "#003eff3e", - "#0037ed54", - "#0034dc72", - "#0031d2c1", - "#002ec9cc", - "#002bb7c5", - "#001046e0", - ], - dark: [ - "#11131fff", - "#141726ff", - "#182449ff", - "#1d2e62ff", - "#253974ff", - "#304384ff", - "#3a4f97ff", - "#435db1ff", - "#3e63ddff", - "#5472e4ff", - "#9eb1ffff", - "#d6e1ffff", - ], - dark_alpha: [ - "#1133ff0f", - "#3354fa17", - "#2f62ff3c", - "#3566ff57", - "#4171fd6b", - "#5178fd7c", - "#5a7fff90", - "#5b81feac", - "#4671ffdb", - "#5c7efee3", - "#9eb1ffff", - "#d6e1ffff", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn blue() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Blue", - light: [ - "#fbfdffff", - "#f4faffff", - "#e6f4feff", - "#d5efffff", - "#c2e5ffff", - "#acd8fcff", - "#8ec8f6ff", - "#5eb1efff", - "#0090ffff", - "#0588f0ff", - "#0d74ceff", - "#113264ff", - ], - light_alpha: [ - "#0080ff04", - "#008cff0b", - "#008ff519", - "#009eff2a", - "#0093ff3d", - "#0088f653", - "#0083eb71", - "#0084e6a1", - "#0090ffff", - "#0086f0fa", - "#006dcbf2", - "#002359ee", - ], - dark: [ - "#0d1520ff", - "#111927ff", - "#0d2847ff", - "#003362ff", - "#004074ff", - "#104d87ff", - "#205d9eff", - "#2870bdff", - "#0090ffff", - "#3b9effff", - "#70b8ffff", - "#c2e6ffff", - ], - dark_alpha: [ - "#004df211", - "#1166fb18", - "#0077ff3a", - "#0075ff57", - "#0081fd6b", - "#0f89fd7f", - "#2a91fe98", - "#3094feb9", - "#0090ffff", - "#3b9effff", - "#70b8ffff", - "#c2e6ffff", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn cyan() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Cyan", - light: [ - "#fafdfeff", - "#f2fafbff", - "#def7f9ff", - "#caf1f6ff", - "#b5e9f0ff", - "#9ddde7ff", - "#7dcedcff", - "#3db9cfff", - "#00a2c7ff", - "#0797b9ff", - "#107d98ff", - "#0d3c48ff", - ], - light_alpha: [ - "#0099cc05", - "#009db10d", - "#00c2d121", - "#00bcd435", - "#01b4cc4a", - "#00a7c162", - "#009fbb82", - "#00a3c0c2", - "#00a2c7ff", - "#0094b7f8", - "#007491ef", - "#00323ef2", - ], - dark: [ - "#0b161aff", - "#101b20ff", - "#082c36ff", - "#003848ff", - "#004558ff", - "#045468ff", - "#12677eff", - "#11809cff", - "#00a2c7ff", - "#23afd0ff", - "#4ccce6ff", - "#b6ecf7ff", - ], - dark_alpha: [ - "#0091f70a", - "#02a7f211", - "#00befd28", - "#00baff3b", - "#00befd4d", - "#00c7fd5e", - "#14cdff75", - "#11cfff95", - "#00cfffc3", - "#28d6ffcd", - "#52e1fee5", - "#bbf3fef7", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn teal() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Teal", - light: [ - "#fafefdff", - "#f3fbf9ff", - "#e0f8f3ff", - "#ccf3eaff", - "#b8eae0ff", - "#a1ded2ff", - "#83cdc1ff", - "#53b9abff", - "#12a594ff", - "#0d9b8aff", - "#008573ff", - "#0d3d38ff", - ], - light_alpha: [ - "#00cc9905", - "#00aa800c", - "#00c69d1f", - "#00c39633", - "#00b49047", - "#00a6855e", - "#0099807c", - "#009783ac", - "#009e8ced", - "#009684f2", - "#008573ff", - "#00332df2", - ], - dark: [ - "#0d1514ff", - "#111c1bff", - "#0d2d2aff", - "#023b37ff", - "#084843ff", - "#145750ff", - "#1c6961ff", - "#207e73ff", - "#12a594ff", - "#0eb39eff", - "#0bd8b6ff", - "#adf0ddff", - ], - dark_alpha: [ - "#00deab05", - "#12fbe60c", - "#00ffe61e", - "#00ffe92d", - "#00ffea3b", - "#1cffe84b", - "#2efde85f", - "#32ffe775", - "#13ffe49f", - "#0dffe0ae", - "#0afed5d6", - "#b8ffebef", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn jade() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Jade", - light: [ - "#fbfefdff", - "#f4fbf7ff", - "#e6f7edff", - "#d6f1e3ff", - "#c3e9d7ff", - "#acdec8ff", - "#8bceb6ff", - "#56ba9fff", - "#29a383ff", - "#26997bff", - "#208368ff", - "#1d3b31ff", - ], - light_alpha: [ - "#00c08004", - "#00a3460b", - "#00ae4819", - "#00a85129", - "#00a2553c", - "#009a5753", - "#00945f74", - "#00976ea9", - "#00916bd6", - "#008764d9", - "#007152df", - "#002217e2", - ], - dark: [ - "#0d1512ff", - "#121c18ff", - "#0f2e22ff", - "#0b3b2cff", - "#114837ff", - "#1b5745ff", - "#246854ff", - "#2a7e68ff", - "#29a383ff", - "#27b08bff", - "#1fd8a4ff", - "#adf0d4ff", - ], - dark_alpha: [ - "#00de4505", - "#27fba60c", - "#02f99920", - "#00ffaa2d", - "#11ffb63b", - "#34ffc24b", - "#45fdc75e", - "#48ffcf75", - "#38feca9d", - "#31fec7ab", - "#21fec0d6", - "#b8ffe1ef", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn green() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Green", - light: [ - "#fbfefcff", - "#f4fbf6ff", - "#e6f6ebff", - "#d6f1dfff", - "#c4e8d1ff", - "#adddc0ff", - "#8eceaaff", - "#5bb98bff", - "#30a46cff", - "#2b9a66ff", - "#218358ff", - "#193b2dff", - ], - light_alpha: [ - "#00c04004", - "#00a32f0b", - "#00a43319", - "#00a83829", - "#019c393b", - "#00963c52", - "#00914071", - "#00924ba4", - "#008f4acf", - "#008647d4", - "#00713fde", - "#002616e6", - ], - dark: [ - "#0e1512ff", - "#121b17ff", - "#132d21ff", - "#113b29ff", - "#174933ff", - "#20573eff", - "#28684aff", - "#2f7c57ff", - "#30a46cff", - "#33b074ff", - "#3dd68cff", - "#b1f1cbff", - ], - dark_alpha: [ - "#00de4505", - "#29f99d0b", - "#22ff991e", - "#11ff992d", - "#2bffa23c", - "#44ffaa4b", - "#50fdac5e", - "#54ffad73", - "#44ffa49e", - "#43fea4ab", - "#46fea5d4", - "#bbffd7f0", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn grass() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Grass", - light: [ - "#fbfefbff", - "#f5fbf5ff", - "#e9f6e9ff", - "#daf1dbff", - "#c9e8caff", - "#b2ddb5ff", - "#94ce9aff", - "#65ba74ff", - "#46a758ff", - "#3e9b4fff", - "#2a7e3bff", - "#203c25ff", - ], - light_alpha: [ - "#00c00004", - "#0099000a", - "#00970016", - "#009f0725", - "#00930536", - "#008f0a4d", - "#018b0f6b", - "#008d199a", - "#008619b9", - "#007b17c1", - "#006514d5", - "#002006df", - ], - dark: [ - "#0e1511ff", - "#141a15ff", - "#1b2a1eff", - "#1d3a24ff", - "#25482dff", - "#2d5736ff", - "#366740ff", - "#3e7949ff", - "#46a758ff", - "#53b365ff", - "#71d083ff", - "#c2f0c2ff", - ], - dark_alpha: [ - "#00de1205", - "#5ef7780a", - "#70fe8c1b", - "#57ff802c", - "#68ff8b3b", - "#71ff8f4b", - "#77fd925d", - "#77fd9070", - "#65ff82a1", - "#72ff8dae", - "#89ff9fcd", - "#ceffceef", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn lime() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Lime", - light: [ - "#fcfdfaff", - "#f8faf3ff", - "#eef6d6ff", - "#e2f0bdff", - "#d3e7a6ff", - "#c2da91ff", - "#abc978ff", - "#8db654ff", - "#bdee63ff", - "#b0e64cff", - "#5c7c2fff", - "#37401cff", - ], - light_alpha: [ - "#66990005", - "#6b95000c", - "#96c80029", - "#8fc60042", - "#81bb0059", - "#72aa006e", - "#61990087", - "#559200ab", - "#93e4009c", - "#8fdc00b3", - "#375f00d0", - "#1e2900e3", - ], - dark: [ - "#11130cff", - "#151a10ff", - "#1f2917ff", - "#29371dff", - "#334423ff", - "#3d522aff", - "#496231ff", - "#577538ff", - "#bdee63ff", - "#d4ff70ff", - "#bde56cff", - "#e3f7baff", - ], - dark_alpha: [ - "#11bb0003", - "#78f7000a", - "#9bfd4c1a", - "#a7fe5c29", - "#affe6537", - "#b2fe6d46", - "#b6ff6f57", - "#b6fd6d6c", - "#caff69ed", - "#d4ff70ff", - "#d1fe77e4", - "#e9febff7", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn mint() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Mint", - light: [ - "#f9fefdff", - "#f2fbf9ff", - "#ddf9f2ff", - "#c8f4e9ff", - "#b3ecdeff", - "#9ce0d0ff", - "#7ecfbdff", - "#4cbba5ff", - "#86ead4ff", - "#7de0cbff", - "#027864ff", - "#16433cff", - ], - light_alpha: [ - "#00d5aa06", - "#00b18a0d", - "#00d29e22", - "#00cc9937", - "#00c0914c", - "#00b08663", - "#00a17d81", - "#009e7fb3", - "#00d3a579", - "#00c39982", - "#007763fd", - "#00312ae9", - ], - dark: [ - "#0e1515ff", - "#0f1b1bff", - "#092c2bff", - "#003a38ff", - "#004744ff", - "#105650ff", - "#1e685fff", - "#277f70ff", - "#86ead4ff", - "#a8f5e5ff", - "#58d5baff", - "#c4f5e1ff", - ], - dark_alpha: [ - "#00dede05", - "#00f9f90b", - "#00fff61d", - "#00fff42c", - "#00fff23a", - "#0effeb4a", - "#34fde55e", - "#41ffdf76", - "#92ffe7e9", - "#aefeedf5", - "#67ffded2", - "#cbfee9f5", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn sky() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Sky", - light: [ - "#f9feffff", - "#f1fafdff", - "#e1f6fdff", - "#d1f0faff", - "#bee7f5ff", - "#a9daedff", - "#8dcae3ff", - "#60b3d7ff", - "#7ce2feff", - "#74daf8ff", - "#00749eff", - "#1d3e56ff", - ], - light_alpha: [ - "#00d5ff06", - "#00a4db0e", - "#00b3ee1e", - "#00ace42e", - "#00a1d841", - "#0092ca56", - "#0089c172", - "#0085bf9f", - "#00c7fe83", - "#00bcf38b", - "#00749eff", - "#002540e2", - ], - dark: [ - "#0d141fff", - "#111a27ff", - "#112840ff", - "#113555ff", - "#154467ff", - "#1b537bff", - "#1f6692ff", - "#197caeff", - "#7ce2feff", - "#a8eeffff", - "#75c7f0ff", - "#c2f3ffff", - ], - dark_alpha: [ - "#0044ff0f", - "#1171fb18", - "#1184fc33", - "#128fff49", - "#1c9dfd5d", - "#28a5ff72", - "#2badfe8b", - "#1db2fea9", - "#7ce3fffe", - "#a8eeffff", - "#7cd3ffef", - "#c2f3ffff", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn black() -> ColorScaleSet { - StaticColorScaleSet { - scale: "Black", - light: [ - "#0000000d", - "#0000001a", - "#00000026", - "#00000033", - "#0000004d", - "#00000066", - "#00000080", - "#00000099", - "#000000b3", - "#000000cc", - "#000000e6", - "#000000f2", - ], - light_alpha: [ - "#0000000d", - "#0000001a", - "#00000026", - "#00000033", - "#0000004d", - "#00000066", - "#00000080", - "#00000099", - "#000000b3", - "#000000cc", - "#000000e6", - "#000000f2", - ], - dark: [ - "#0000000d", - "#0000001a", - "#00000026", - "#00000033", - "#0000004d", - "#00000066", - "#00000080", - "#00000099", - "#000000b3", - "#000000cc", - "#000000e6", - "#000000f2", - ], - dark_alpha: [ - "#0000000d", - "#0000001a", - "#00000026", - "#00000033", - "#0000004d", - "#00000066", - "#00000080", - "#00000099", - "#000000b3", - "#000000cc", - "#000000e6", - "#000000f2", - ], - } - .try_into() - .unwrap() -} - -pub(crate) fn white() -> ColorScaleSet { - StaticColorScaleSet { - scale: "White", - light: [ - "#ffffff0d", - "#ffffff1a", - "#ffffff26", - "#ffffff33", - "#ffffff4d", - "#ffffff66", - "#ffffff80", - "#ffffff99", - "#ffffffb3", - "#ffffffcc", - "#ffffffe6", - "#fffffff2", - ], - light_alpha: [ - "#ffffff0d", - "#ffffff1a", - "#ffffff26", - "#ffffff33", - "#ffffff4d", - "#ffffff66", - "#ffffff80", - "#ffffff99", - "#ffffffb3", - "#ffffffcc", - "#ffffffe6", - "#fffffff2", - ], - dark: [ - "#ffffff0d", - "#ffffff1a", - "#ffffff26", - "#ffffff33", - "#ffffff4d", - "#ffffff66", - "#ffffff80", - "#ffffff99", - "#ffffffb3", - "#ffffffcc", - "#ffffffe6", - "#fffffff2", - ], - dark_alpha: [ - "#ffffff0d", - "#ffffff1a", - "#ffffff26", - "#ffffff33", - "#ffffff4d", - "#ffffff66", - "#ffffff80", - "#ffffff99", - "#ffffffb3", - "#ffffffcc", - "#ffffffe6", - "#fffffff2", - ], - } - .try_into() - .unwrap() -} +use gpui::{hsla, Hsla, Rgba}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::scale::{ColorScale, ColorScaleSet, ColorScales}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Default, Deserialize, Serialize, JsonSchema)] +pub struct ThemeColors { + // Surface colors + pub background: Hsla, + pub surface_background: Hsla, + pub elevated_surface_background: Hsla, + pub panel_background: Hsla, + pub overlay: Hsla, + pub title_bar: Hsla, + pub title_bar_inactive: Hsla, + pub window_border: Hsla, + + // Border colors + pub border: Hsla, + pub border_variant: Hsla, + pub border_focused: Hsla, + pub border_selected: Hsla, + pub border_transparent: Hsla, + pub border_disabled: Hsla, + pub ring: Hsla, + + // Text colors + pub text: Hsla, + pub text_muted: Hsla, + pub text_placeholder: Hsla, + pub text_accent: Hsla, + + // Icon colors + pub icon: Hsla, + pub icon_muted: Hsla, + pub icon_accent: Hsla, + + // Element colors + pub element_foreground: Hsla, + pub element_background: Hsla, + pub element_hover: Hsla, + pub element_active: Hsla, + pub element_selected: Hsla, + pub element_disabled: Hsla, + + // Secondary element colors + pub secondary_foreground: Hsla, + pub secondary_background: Hsla, + pub secondary_hover: Hsla, + pub secondary_active: Hsla, + pub secondary_selected: Hsla, + pub secondary_disabled: Hsla, + + // Danger element colors + pub danger_foreground: Hsla, + pub danger_background: Hsla, + pub danger_hover: Hsla, + pub danger_active: Hsla, + pub danger_selected: Hsla, + pub danger_disabled: Hsla, + + // Warning element colors + pub warning_foreground: Hsla, + pub warning_background: Hsla, + pub warning_hover: Hsla, + pub warning_active: Hsla, + pub warning_selected: Hsla, + pub warning_disabled: Hsla, + + // Ghost element colors + pub ghost_element_background: Hsla, + pub ghost_element_background_alt: Hsla, + pub ghost_element_hover: Hsla, + pub ghost_element_active: Hsla, + pub ghost_element_selected: Hsla, + pub ghost_element_disabled: Hsla, + + // Tab colors + pub tab_inactive_background: Hsla, + pub tab_hover_background: Hsla, + pub tab_active_background: Hsla, + + // Scrollbar colors + pub scrollbar_thumb_background: Hsla, + pub scrollbar_thumb_hover_background: Hsla, + pub scrollbar_thumb_border: Hsla, + pub scrollbar_track_background: Hsla, + pub scrollbar_track_border: Hsla, + + // Interactive colors + pub drop_target_background: Hsla, + pub cursor: Hsla, + pub selection: Hsla, +} + +/// The default colors for the theme. +/// +/// Themes that do not specify all colors are refined off of these defaults. +impl ThemeColors { + /// Returns the default colors for light themes. + /// + /// Themes that do not specify all colors are refined off of these defaults. + pub fn light() -> Self { + Self { + background: neutral().light().step_1(), + surface_background: neutral().light().step_2(), + elevated_surface_background: neutral().light().step_3(), + panel_background: gpui::white(), + overlay: neutral().light_alpha().step_3(), + title_bar: gpui::transparent_black(), + title_bar_inactive: neutral().light().step_1(), + window_border: hsl(240.0, 5.9, 78.0), + + border: neutral().light().step_6(), + border_variant: neutral().light().step_5(), + border_focused: brand().light().step_7(), + border_selected: brand().light().step_7(), + border_transparent: gpui::transparent_black(), + border_disabled: neutral().light().step_3(), + ring: brand().light().step_8(), + + text: neutral().light().step_12(), + text_muted: neutral().light().step_11(), + text_placeholder: neutral().light().step_10(), + text_accent: brand().light().step_11(), + + icon: neutral().light().step_11(), + icon_muted: neutral().light().step_10(), + icon_accent: brand().light().step_11(), + + element_foreground: brand().light().step_12(), + element_background: brand().light().step_9(), + element_hover: brand().light_alpha().step_10(), + element_active: brand().light().step_10(), + element_selected: brand().light().step_11(), + element_disabled: brand().light_alpha().step_3(), + + secondary_foreground: brand().light().step_11(), + secondary_background: brand().light().step_3(), + secondary_hover: brand().light_alpha().step_4(), + secondary_active: brand().light().step_5(), + secondary_selected: brand().light().step_5(), + secondary_disabled: brand().light_alpha().step_3(), + + danger_foreground: danger().light().step_12(), + danger_background: danger().light().step_3(), + danger_hover: danger().light_alpha().step_4(), + danger_active: danger().light().step_5(), + danger_selected: danger().light().step_5(), + danger_disabled: danger().light_alpha().step_3(), + + warning_foreground: warning().light().step_12(), + warning_background: warning().light().step_3(), + warning_hover: warning().light_alpha().step_4(), + warning_active: warning().light().step_5(), + warning_selected: warning().light().step_5(), + warning_disabled: warning().light_alpha().step_3(), + + ghost_element_background: gpui::transparent_black(), + ghost_element_background_alt: neutral().light().step_3(), + ghost_element_hover: neutral().light_alpha().step_4(), + ghost_element_active: neutral().light().step_5(), + ghost_element_selected: neutral().light().step_5(), + ghost_element_disabled: neutral().light_alpha().step_2(), + + tab_inactive_background: neutral().light().step_3(), + tab_hover_background: neutral().light().step_4(), + tab_active_background: neutral().light().step_5(), + + scrollbar_thumb_background: neutral().light_alpha().step_3(), + scrollbar_thumb_hover_background: neutral().light_alpha().step_4(), + scrollbar_thumb_border: gpui::transparent_black(), + scrollbar_track_background: gpui::transparent_black(), + scrollbar_track_border: neutral().light().step_5(), + + drop_target_background: brand().light_alpha().step_2(), + cursor: hsl(200., 100., 50.), + selection: hsl(200., 100., 50.).alpha(0.25), + } + } + + /// Returns the default colors for dark themes. + /// + /// Themes that do not specify all colors are refined off of these defaults. + pub fn dark() -> Self { + Self { + background: neutral().dark().step_1(), + surface_background: neutral().dark().step_2(), + elevated_surface_background: neutral().dark().step_3(), + panel_background: gpui::black(), + overlay: neutral().dark_alpha().step_3(), + title_bar: gpui::transparent_black(), + title_bar_inactive: neutral().dark().step_1(), + window_border: hsl(240.0, 3.7, 28.0), + + border: neutral().dark().step_6(), + border_variant: neutral().dark().step_5(), + border_focused: brand().dark().step_7(), + border_selected: brand().dark().step_7(), + border_transparent: gpui::transparent_black(), + border_disabled: neutral().dark().step_3(), + ring: brand().dark().step_8(), + + text: neutral().dark().step_12(), + text_muted: neutral().dark().step_11(), + text_placeholder: neutral().dark().step_10(), + text_accent: brand().dark().step_11(), + + icon: neutral().dark().step_11(), + icon_muted: neutral().dark().step_10(), + icon_accent: brand().dark().step_11(), + + element_foreground: brand().dark().step_1(), + element_background: brand().dark().step_9(), + element_hover: brand().dark_alpha().step_10(), + element_active: brand().dark().step_10(), + element_selected: brand().dark().step_11(), + element_disabled: brand().dark_alpha().step_3(), + + secondary_foreground: brand().dark().step_12(), + secondary_background: brand().dark().step_3(), + secondary_hover: brand().dark_alpha().step_4(), + secondary_active: brand().dark().step_5(), + secondary_selected: brand().dark().step_5(), + secondary_disabled: brand().dark_alpha().step_3(), + + danger_foreground: danger().dark().step_12(), + danger_background: danger().dark().step_3(), + danger_hover: danger().dark_alpha().step_4(), + danger_active: danger().dark().step_5(), + danger_selected: danger().dark().step_5(), + danger_disabled: danger().dark_alpha().step_3(), + + warning_foreground: warning().dark().step_12(), + warning_background: warning().dark().step_3(), + warning_hover: warning().dark_alpha().step_4(), + warning_active: warning().dark().step_5(), + warning_selected: warning().dark().step_5(), + warning_disabled: warning().dark_alpha().step_3(), + + ghost_element_background: gpui::transparent_black(), + ghost_element_background_alt: neutral().dark().step_3(), + ghost_element_hover: neutral().dark_alpha().step_4(), + ghost_element_active: neutral().dark().step_5(), + ghost_element_selected: neutral().dark().step_5(), + ghost_element_disabled: neutral().dark_alpha().step_2(), + + tab_inactive_background: neutral().dark().step_3(), + tab_hover_background: neutral().dark().step_4(), + tab_active_background: neutral().dark().step_5(), + + scrollbar_thumb_background: neutral().dark_alpha().step_3(), + scrollbar_thumb_hover_background: neutral().dark_alpha().step_4(), + scrollbar_thumb_border: gpui::transparent_black(), + scrollbar_track_background: gpui::transparent_black(), + scrollbar_track_border: neutral().dark().step_5(), + + drop_target_background: brand().dark_alpha().step_2(), + cursor: hsl(200., 100., 50.), + selection: hsl(200., 100., 50.).alpha(0.25), + } + } +} + +fn neutral() -> ColorScaleSet { + gray() +} + +fn brand() -> ColorScaleSet { + yellow() +} + +fn danger() -> ColorScaleSet { + tomato() +} + +fn warning() -> ColorScaleSet { + orange() +} + +/// Make a [gpui::Hsla] color. +/// +/// - h: 0..360.0 +/// - s: 0.0..100.0 +/// - l: 0.0..100.0 +pub fn hsl(h: f32, s: f32, l: f32) -> Hsla { + hsla(h / 360., s / 100.0, l / 100.0, 1.0) +} + +type StaticColorScale = [&'static str; 12]; + +struct StaticColorScaleSet { + scale: &'static str, + light: StaticColorScale, + light_alpha: StaticColorScale, + dark: StaticColorScale, + dark_alpha: StaticColorScale, +} + +impl TryFrom for ColorScaleSet { + type Error = anyhow::Error; + + fn try_from(value: StaticColorScaleSet) -> Result { + fn to_color_scale(scale: StaticColorScale) -> Result { + scale + .into_iter() + .map(|color| Rgba::try_from(color).map(Hsla::from)) + .collect::, _>>() + .map(ColorScale::from_iter) + } + + Ok(Self::new( + value.scale, + to_color_scale(value.light)?, + to_color_scale(value.light_alpha)?, + to_color_scale(value.dark)?, + to_color_scale(value.dark_alpha)?, + )) + } +} + +/// Color scales used to build the default themes. +pub fn default_color_scales() -> ColorScales { + ColorScales { + gray: gray(), + mauve: mauve(), + slate: slate(), + sage: sage(), + olive: olive(), + sand: sand(), + gold: gold(), + bronze: bronze(), + brown: brown(), + yellow: yellow(), + amber: amber(), + orange: orange(), + tomato: tomato(), + red: red(), + ruby: ruby(), + crimson: crimson(), + pink: pink(), + plum: plum(), + purple: purple(), + violet: violet(), + iris: iris(), + indigo: indigo(), + blue: blue(), + cyan: cyan(), + teal: teal(), + jade: jade(), + green: green(), + grass: grass(), + lime: lime(), + mint: mint(), + sky: sky(), + black: black(), + white: white(), + } +} + +pub(crate) fn gray() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Gray", + light: [ + "#fcfcfcff", + "#f9f9f9ff", + "#f0f0f0ff", + "#e8e8e8ff", + "#e0e0e0ff", + "#d9d9d9ff", + "#cececeff", + "#bbbbbbff", + "#8d8d8dff", + "#838383ff", + "#646464ff", + "#202020ff", + ], + light_alpha: [ + "#00000003", + "#00000006", + "#0000000f", + "#00000017", + "#0000001f", + "#00000026", + "#00000031", + "#00000044", + "#00000072", + "#0000007c", + "#0000009b", + "#000000df", + ], + dark: [ + "#111111ff", + "#191919ff", + "#222222ff", + "#2a2a2aff", + "#313131ff", + "#3a3a3aff", + "#484848ff", + "#606060ff", + "#6e6e6eff", + "#7b7b7bff", + "#b4b4b4ff", + "#eeeeeeff", + ], + dark_alpha: [ + "#00000000", + "#ffffff09", + "#ffffff12", + "#ffffff1b", + "#ffffff22", + "#ffffff2c", + "#ffffff3b", + "#ffffff55", + "#ffffff64", + "#ffffff72", + "#ffffffaf", + "#ffffffed", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn mauve() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Mauve", + light: [ + "#fdfcfdff", + "#faf9fbff", + "#f2eff3ff", + "#eae7ecff", + "#e3dfe6ff", + "#dbd8e0ff", + "#d0cdd7ff", + "#bcbac7ff", + "#8e8c99ff", + "#84828eff", + "#65636dff", + "#211f26ff", + ], + light_alpha: [ + "#55005503", + "#2b005506", + "#30004010", + "#20003618", + "#20003820", + "#14003527", + "#10003332", + "#08003145", + "#05001d73", + "#0500197d", + "#0400119c", + "#020008e0", + ], + dark: [ + "#121113ff", + "#1a191bff", + "#232225ff", + "#2b292dff", + "#323035ff", + "#3c393fff", + "#49474eff", + "#625f69ff", + "#6f6d78ff", + "#7c7a85ff", + "#b5b2bcff", + "#eeeef0ff", + ], + dark_alpha: [ + "#00000000", + "#f5f4f609", + "#ebeaf814", + "#eee5f81d", + "#efe6fe25", + "#f1e6fd30", + "#eee9ff40", + "#eee7ff5d", + "#eae6fd6e", + "#ece9fd7c", + "#f5f1ffb7", + "#fdfdffef", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn slate() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Slate", + light: [ + "#fcfcfdff", + "#f9f9fbff", + "#f0f0f3ff", + "#e8e8ecff", + "#e0e1e6ff", + "#d9d9e0ff", + "#cdced6ff", + "#b9bbc6ff", + "#8b8d98ff", + "#80838dff", + "#60646cff", + "#1c2024ff", + ], + light_alpha: [ + "#00005503", + "#00005506", + "#0000330f", + "#00002d17", + "#0009321f", + "#00002f26", + "#00062e32", + "#00083046", + "#00051d74", + "#00071b7f", + "#0007149f", + "#000509e3", + ], + dark: [ + "#111113ff", + "#18191bff", + "#212225ff", + "#272a2dff", + "#2e3135ff", + "#363a3fff", + "#43484eff", + "#5a6169ff", + "#696e77ff", + "#777b84ff", + "#b0b4baff", + "#edeef0ff", + ], + dark_alpha: [ + "#00000000", + "#d8f4f609", + "#ddeaf814", + "#d3edf81d", + "#d9edfe25", + "#d6ebfd30", + "#d9edff40", + "#d9edff5d", + "#dfebfd6d", + "#e5edfd7b", + "#f1f7feb5", + "#fcfdffef", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn sage() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Sage", + light: [ + "#fbfdfcff", + "#f7f9f8ff", + "#eef1f0ff", + "#e6e9e8ff", + "#dfe2e0ff", + "#d7dad9ff", + "#cbcfcdff", + "#b8bcbaff", + "#868e8bff", + "#7c8481ff", + "#5f6563ff", + "#1a211eff", + ], + light_alpha: [ + "#00804004", + "#00402008", + "#002d1e11", + "#001f1519", + "#00180820", + "#00140d28", + "#00140a34", + "#000f0847", + "#00110b79", + "#00100a83", + "#000a07a0", + "#000805e5", + ], + dark: [ + "#101211ff", + "#171918ff", + "#202221ff", + "#272a29ff", + "#2e3130ff", + "#373b39ff", + "#444947ff", + "#5b625fff", + "#63706bff", + "#717d79ff", + "#adb5b2ff", + "#eceeedff", + ], + dark_alpha: [ + "#00000000", + "#f0f2f108", + "#f3f5f412", + "#f2fefd1a", + "#f1fbfa22", + "#edfbf42d", + "#edfcf73c", + "#ebfdf657", + "#dffdf266", + "#e5fdf674", + "#f4fefbb0", + "#fdfffeed", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn olive() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Olive", + light: [ + "#fcfdfcff", + "#f8faf8ff", + "#eff1efff", + "#e7e9e7ff", + "#dfe2dfff", + "#d7dad7ff", + "#cccfccff", + "#b9bcb8ff", + "#898e87ff", + "#7f847dff", + "#60655fff", + "#1d211cff", + ], + light_alpha: [ + "#00550003", + "#00490007", + "#00200010", + "#00160018", + "#00180020", + "#00140028", + "#000f0033", + "#040f0047", + "#050f0078", + "#040e0082", + "#020a00a0", + "#010600e3", + ], + dark: [ + "#111210ff", + "#181917ff", + "#212220ff", + "#282a27ff", + "#2f312eff", + "#383a36ff", + "#454843ff", + "#5c625bff", + "#687066ff", + "#767d74ff", + "#afb5adff", + "#eceeecff", + ], + dark_alpha: [ + "#00000000", + "#f1f2f008", + "#f4f5f312", + "#f3fef21a", + "#f2fbf122", + "#f4faed2c", + "#f2fced3b", + "#edfdeb57", + "#ebfde766", + "#f0fdec74", + "#f6fef4b0", + "#fdfffded", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn sand() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Sand", + light: [ + "#fdfdfcff", + "#f9f9f8ff", + "#f1f0efff", + "#e9e8e6ff", + "#e2e1deff", + "#dad9d6ff", + "#cfcecaff", + "#bcbbb5ff", + "#8d8d86ff", + "#82827cff", + "#63635eff", + "#21201cff", + ], + light_alpha: [ + "#55550003", + "#25250007", + "#20100010", + "#1f150019", + "#1f180021", + "#19130029", + "#19140035", + "#1915014a", + "#0f0f0079", + "#0c0c0083", + "#080800a1", + "#060500e3", + ], + dark: [ + "#111110ff", + "#191918ff", + "#222221ff", + "#2a2a28ff", + "#31312eff", + "#3b3a37ff", + "#494844ff", + "#62605bff", + "#6f6d66ff", + "#7c7b74ff", + "#b5b3adff", + "#eeeeecff", + ], + dark_alpha: [ + "#00000000", + "#f4f4f309", + "#f6f6f513", + "#fefef31b", + "#fbfbeb23", + "#fffaed2d", + "#fffbed3c", + "#fff9eb57", + "#fffae965", + "#fffdee73", + "#fffcf4b0", + "#fffffded", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn gold() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Gold", + light: [ + "#fdfdfcff", + "#faf9f2ff", + "#f2f0e7ff", + "#eae6dbff", + "#e1dccfff", + "#d8d0bfff", + "#cbc0aaff", + "#b9a88dff", + "#978365ff", + "#8c7a5eff", + "#71624bff", + "#3b352bff", + ], + light_alpha: [ + "#55550003", + "#9d8a000d", + "#75600018", + "#6b4e0024", + "#60460030", + "#64440040", + "#63420055", + "#633d0072", + "#5332009a", + "#492d00a1", + "#362100b4", + "#130c00d4", + ], + dark: [ + "#121211ff", + "#1b1a17ff", + "#24231fff", + "#2d2b26ff", + "#38352eff", + "#444039ff", + "#544f46ff", + "#696256ff", + "#978365ff", + "#a39073ff", + "#cbb99fff", + "#e8e2d9ff", + ], + dark_alpha: [ + "#91911102", + "#f9e29d0b", + "#f8ecbb15", + "#ffeec41e", + "#feecc22a", + "#feebcb37", + "#ffedcd48", + "#fdeaca5f", + "#ffdba690", + "#fedfb09d", + "#fee7c6c8", + "#fef7ede7", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn bronze() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Bronze", + light: [ + "#fdfcfcff", + "#fdf7f5ff", + "#f6edeaff", + "#efe4dfff", + "#e7d9d3ff", + "#dfcdc5ff", + "#d3bcb3ff", + "#c2a499ff", + "#a18072ff", + "#957468ff", + "#7d5e54ff", + "#43302bff", + ], + light_alpha: [ + "#55000003", + "#cc33000a", + "#92250015", + "#80280020", + "#7423002c", + "#7324003a", + "#6c1f004c", + "#671c0066", + "#551a008d", + "#4c150097", + "#3d0f00ab", + "#1d0600d4", + ], + dark: [ + "#141110ff", + "#1c1917ff", + "#262220ff", + "#302a27ff", + "#3b3330ff", + "#493e3aff", + "#5a4c47ff", + "#6f5f58ff", + "#a18072ff", + "#ae8c7eff", + "#d4b3a5ff", + "#ede0d9ff", + ], + dark_alpha: [ + "#d1110004", + "#fbbc910c", + "#faceb817", + "#facdb622", + "#ffd2c12d", + "#ffd1c03c", + "#fdd0c04f", + "#ffd6c565", + "#fec7b09b", + "#fecab5a9", + "#ffd7c6d1", + "#fff1e9ec", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn brown() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Brown", + light: [ + "#fefdfcff", + "#fcf9f6ff", + "#f6eee7ff", + "#f0e4d9ff", + "#ebdacaff", + "#e4cdb7ff", + "#dcbc9fff", + "#cea37eff", + "#ad7f58ff", + "#a07553ff", + "#815e46ff", + "#3e332eff", + ], + light_alpha: [ + "#aa550003", + "#aa550009", + "#a04b0018", + "#9b4a0026", + "#9f4d0035", + "#a04e0048", + "#a34e0060", + "#9f4a0081", + "#823c00a7", + "#723300ac", + "#522100b9", + "#140600d1", + ], + dark: [ + "#12110fff", + "#1c1816ff", + "#28211dff", + "#322922ff", + "#3e3128ff", + "#4d3c2fff", + "#614a39ff", + "#7c5f46ff", + "#ad7f58ff", + "#b88c67ff", + "#dbb594ff", + "#f2e1caff", + ], + dark_alpha: [ + "#91110002", + "#fba67c0c", + "#fcb58c19", + "#fbbb8a24", + "#fcb88931", + "#fdba8741", + "#ffbb8856", + "#ffbe8773", + "#feb87da8", + "#ffc18cb3", + "#fed1aad9", + "#feecd4f2", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn yellow() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Yellow", + light: [ + "#fdfdf9ff", + "#fefce9ff", + "#fffab8ff", + "#fff394ff", + "#ffe770ff", + "#f3d768ff", + "#e4c767ff", + "#d5ae39ff", + "#ffe629ff", + "#ffdc00ff", + "#9e6c00ff", + "#473b1fff", + ], + light_alpha: [ + "#aaaa0006", + "#f4dd0016", + "#ffee0047", + "#ffe3016b", + "#ffd5008f", + "#ebbc0097", + "#d2a10098", + "#c99700c6", + "#ffe100d6", + "#ffdc00ff", + "#9e6c00ff", + "#2e2000e0", + ], + dark: [ + "#14120bff", + "#1b180fff", + "#2d2305ff", + "#362b00ff", + "#433500ff", + "#524202ff", + "#665417ff", + "#836a21ff", + "#ffe629ff", + "#ffff57ff", + "#f5e147ff", + "#f6eeb4ff", + ], + dark_alpha: [ + "#d1510004", + "#f9b4000b", + "#ffaa001e", + "#fdb70028", + "#febb0036", + "#fec40046", + "#fdcb225c", + "#fdca327b", + "#ffe629ff", + "#ffff57ff", + "#fee949f5", + "#fef6baf6", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn amber() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Amber", + light: [ + "#fefdfbff", + "#fefbe9ff", + "#fff7c2ff", + "#ffee9cff", + "#fbe577ff", + "#f3d673ff", + "#e9c162ff", + "#e2a336ff", + "#ffc53dff", + "#ffba18ff", + "#ab6400ff", + "#4f3422ff", + ], + light_alpha: [ + "#c0800004", + "#f4d10016", + "#ffde003d", + "#ffd40063", + "#f8cf0088", + "#eab5008c", + "#dc9b009d", + "#da8a00c9", + "#ffb300c2", + "#ffb300e7", + "#ab6400ff", + "#341500dd", + ], + dark: [ + "#16120cff", + "#1d180fff", + "#302008ff", + "#3f2700ff", + "#4d3000ff", + "#5c3d05ff", + "#714f19ff", + "#8f6424ff", + "#ffc53dff", + "#ffd60aff", + "#ffca16ff", + "#ffe7b3ff", + ], + dark_alpha: [ + "#e63c0006", + "#fd9b000d", + "#fa820022", + "#fc820032", + "#fd8b0041", + "#fd9b0051", + "#ffab2567", + "#ffae3587", + "#ffc53dff", + "#ffd60aff", + "#ffca16ff", + "#ffe7b3ff", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn orange() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Orange", + light: [ + "#fefcfbff", + "#fff7edff", + "#ffefd6ff", + "#ffdfb5ff", + "#ffd19aff", + "#ffc182ff", + "#f5ae73ff", + "#ec9455ff", + "#f76b15ff", + "#ef5f00ff", + "#cc4e00ff", + "#582d1dff", + ], + light_alpha: [ + "#c0400004", + "#ff8e0012", + "#ff9c0029", + "#ff91014a", + "#ff8b0065", + "#ff81007d", + "#ed6c008c", + "#e35f00aa", + "#f65e00ea", + "#ef5f00ff", + "#cc4e00ff", + "#431200e2", + ], + dark: [ + "#17120eff", + "#1e160fff", + "#331e0bff", + "#462100ff", + "#562800ff", + "#66350cff", + "#7e451dff", + "#a35829ff", + "#f76b15ff", + "#ff801fff", + "#ffa057ff", + "#ffe0c2ff", + ], + dark_alpha: [ + "#ec360007", + "#fe6d000e", + "#fb6a0025", + "#ff590039", + "#ff61004a", + "#fd75045c", + "#ff832c75", + "#fe84389d", + "#fe6d15f7", + "#ff801fff", + "#ffa057ff", + "#ffe0c2ff", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn tomato() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Tomato", + light: [ + "#fffcfcff", + "#fff8f7ff", + "#feebe7ff", + "#ffdcd3ff", + "#ffcdc2ff", + "#fdbdafff", + "#f5a898ff", + "#ec8e7bff", + "#e54d2eff", + "#dd4425ff", + "#d13415ff", + "#5c271fff", + ], + light_alpha: [ + "#ff000003", + "#ff200008", + "#f52b0018", + "#ff35002c", + "#ff2e003d", + "#f92d0050", + "#e7280067", + "#db250084", + "#df2600d1", + "#d72400da", + "#cd2200ea", + "#460900e0", + ], + dark: [ + "#181111ff", + "#1f1513ff", + "#391714ff", + "#4e1511ff", + "#5e1c16ff", + "#6e2920ff", + "#853a2dff", + "#ac4d39ff", + "#e54d2eff", + "#ec6142ff", + "#ff977dff", + "#fbd3cbff", + ], + dark_alpha: [ + "#f1121208", + "#ff55330f", + "#ff35232b", + "#fd201142", + "#fe332153", + "#ff4f3864", + "#fd644a7d", + "#fe6d4ea7", + "#fe5431e4", + "#ff6847eb", + "#ff977dff", + "#ffd6cefb", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn red() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Red", + light: [ + "#fffcfcff", + "#fff7f7ff", + "#feebecff", + "#ffdbdcff", + "#ffcdceff", + "#fdbdbeff", + "#f4a9aaff", + "#eb8e90ff", + "#e5484dff", + "#dc3e42ff", + "#ce2c31ff", + "#641723ff", + ], + light_alpha: [ + "#ff000003", + "#ff000008", + "#f3000d14", + "#ff000824", + "#ff000632", + "#f8000442", + "#df000356", + "#d2000571", + "#db0007b7", + "#d10005c1", + "#c40006d3", + "#55000de8", + ], + dark: [ + "#191111ff", + "#201314ff", + "#3b1219ff", + "#500f1cff", + "#611623ff", + "#72232dff", + "#8c333aff", + "#b54548ff", + "#e5484dff", + "#ec5d5eff", + "#ff9592ff", + "#ffd1d9ff", + ], + dark_alpha: [ + "#f4121209", + "#f22f3e11", + "#ff173f2d", + "#fe0a3b44", + "#ff204756", + "#ff3e5668", + "#ff536184", + "#ff5d61b0", + "#fe4e54e4", + "#ff6465eb", + "#ff9592ff", + "#ffd1d9ff", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn ruby() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Ruby", + light: [ + "#fffcfdff", + "#fff7f8ff", + "#feeaedff", + "#ffdce1ff", + "#ffced6ff", + "#f8bfc8ff", + "#efacb8ff", + "#e592a3ff", + "#e54666ff", + "#dc3b5dff", + "#ca244dff", + "#64172bff", + ], + light_alpha: [ + "#ff005503", + "#ff002008", + "#f3002515", + "#ff002523", + "#ff002a31", + "#e4002440", + "#ce002553", + "#c300286d", + "#db002cb9", + "#d2002cc4", + "#c10030db", + "#550016e8", + ], + dark: [ + "#191113ff", + "#1e1517ff", + "#3a141eff", + "#4e1325ff", + "#5e1a2eff", + "#6f2539ff", + "#883447ff", + "#b3445aff", + "#e54666ff", + "#ec5a72ff", + "#ff949dff", + "#fed2e1ff", + ], + dark_alpha: [ + "#f4124a09", + "#fe5a7f0e", + "#ff235d2c", + "#fd195e42", + "#fe2d6b53", + "#ff447665", + "#ff577d80", + "#ff5c7cae", + "#fe4c70e4", + "#ff617beb", + "#ff949dff", + "#ffd3e2fe", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn crimson() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Crimson", + light: [ + "#fffcfdff", + "#fef7f9ff", + "#ffe9f0ff", + "#fedce7ff", + "#faceddff", + "#f3bed1ff", + "#eaacc3ff", + "#e093b2ff", + "#e93d82ff", + "#df3478ff", + "#cb1d63ff", + "#621639ff", + ], + light_alpha: [ + "#ff005503", + "#e0004008", + "#ff005216", + "#f8005123", + "#e5004f31", + "#d0004b41", + "#bf004753", + "#b6004a6c", + "#e2005bc2", + "#d70056cb", + "#c4004fe2", + "#530026e9", + ], + dark: [ + "#191114ff", + "#201318ff", + "#381525ff", + "#4d122fff", + "#5c1839ff", + "#6d2545ff", + "#873356ff", + "#b0436eff", + "#e93d82ff", + "#ee518aff", + "#ff92adff", + "#fdd3e8ff", + ], + dark_alpha: [ + "#f4126709", + "#f22f7a11", + "#fe2a8b2a", + "#fd158741", + "#fd278f51", + "#fe459763", + "#fd559b7f", + "#fe5b9bab", + "#fe418de8", + "#ff5693ed", + "#ff92adff", + "#ffd5eafd", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn pink() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Pink", + light: [ + "#fffcfeff", + "#fef7fbff", + "#fee9f5ff", + "#fbdcefff", + "#f6cee7ff", + "#efbfddff", + "#e7acd0ff", + "#dd93c2ff", + "#d6409fff", + "#cf3897ff", + "#c2298aff", + "#651249ff", + ], + light_alpha: [ + "#ff00aa03", + "#e0008008", + "#f4008c16", + "#e2008b23", + "#d1008331", + "#c0007840", + "#b6006f53", + "#af006f6c", + "#c8007fbf", + "#c2007ac7", + "#b60074d6", + "#59003bed", + ], + dark: [ + "#191117ff", + "#21121dff", + "#37172fff", + "#4b143dff", + "#591c47ff", + "#692955ff", + "#833869ff", + "#a84885ff", + "#d6409fff", + "#de51a8ff", + "#ff8dccff", + "#fdd1eaff", + ], + dark_alpha: [ + "#f412bc09", + "#f420bb12", + "#fe37cc29", + "#fc1ec43f", + "#fd35c24e", + "#fd51c75f", + "#fd62c87b", + "#ff68c8a2", + "#fe49bcd4", + "#ff5cc0dc", + "#ff8dccff", + "#ffd3ecfd", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn plum() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Plum", + light: [ + "#fefcffff", + "#fdf7fdff", + "#fbebfbff", + "#f7def8ff", + "#f2d1f3ff", + "#e9c2ecff", + "#deade3ff", + "#cf91d8ff", + "#ab4abaff", + "#a144afff", + "#953ea3ff", + "#53195dff", + ], + light_alpha: [ + "#aa00ff03", + "#c000c008", + "#cc00cc14", + "#c200c921", + "#b700bd2e", + "#a400b03d", + "#9900a852", + "#9000a56e", + "#89009eb5", + "#7f0092bb", + "#730086c1", + "#40004be6", + ], + dark: [ + "#181118ff", + "#201320ff", + "#351a35ff", + "#451d47ff", + "#512454ff", + "#5e3061ff", + "#734079ff", + "#92549cff", + "#ab4abaff", + "#b658c4ff", + "#e796f3ff", + "#f4d4f4ff", + ], + dark_alpha: [ + "#f112f108", + "#f22ff211", + "#fd4cfd27", + "#f646ff3a", + "#f455ff48", + "#f66dff56", + "#f07cfd70", + "#ee84ff95", + "#e961feb6", + "#ed70ffc0", + "#f19cfef3", + "#feddfef4", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn purple() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Purple", + light: [ + "#fefcfeff", + "#fbf7feff", + "#f7edfeff", + "#f2e2fcff", + "#ead5f9ff", + "#e0c4f4ff", + "#d1afecff", + "#be93e4ff", + "#8e4ec6ff", + "#8347b9ff", + "#8145b5ff", + "#402060ff", + ], + light_alpha: [ + "#aa00aa03", + "#8000e008", + "#8e00f112", + "#8d00e51d", + "#8000db2a", + "#7a01d03b", + "#6d00c350", + "#6600c06c", + "#5c00adb1", + "#53009eb8", + "#52009aba", + "#250049df", + ], + dark: [ + "#18111bff", + "#1e1523ff", + "#301c3bff", + "#3d224eff", + "#48295cff", + "#54346bff", + "#664282ff", + "#8457aaff", + "#8e4ec6ff", + "#9a5cd0ff", + "#d19dffff", + "#ecd9faff", + ], + dark_alpha: [ + "#b412f90b", + "#b744f714", + "#c150ff2d", + "#bb53fd42", + "#be5cfd51", + "#c16dfd61", + "#c378fd7a", + "#c47effa4", + "#b661ffc2", + "#bc6fffcd", + "#d19dffff", + "#f1ddfffa", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn violet() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Violet", + light: [ + "#fdfcfeff", + "#faf8ffff", + "#f4f0feff", + "#ebe4ffff", + "#e1d9ffff", + "#d4cafeff", + "#c2b5f5ff", + "#aa99ecff", + "#6e56cfff", + "#654dc4ff", + "#6550b9ff", + "#2f265fff", + ], + light_alpha: [ + "#5500aa03", + "#4900ff07", + "#4400ee0f", + "#4300ff1b", + "#3600ff26", + "#3100fb35", + "#2d01dd4a", + "#2b00d066", + "#2400b7a9", + "#2300abb2", + "#1f0099af", + "#0b0043d9", + ], + dark: [ + "#14121fff", + "#1b1525ff", + "#291f43ff", + "#33255bff", + "#3c2e69ff", + "#473876ff", + "#56468bff", + "#6958adff", + "#6e56cfff", + "#7d66d9ff", + "#baa7ffff", + "#e2ddfeff", + ], + dark_alpha: [ + "#4422ff0f", + "#853ff916", + "#8354fe36", + "#7d51fd50", + "#845ffd5f", + "#8f6cfd6d", + "#9879ff83", + "#977dfea8", + "#8668ffcc", + "#9176fed7", + "#baa7ffff", + "#e3defffe", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn iris() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Iris", + light: [ + "#fdfdffff", + "#f8f8ffff", + "#f0f1feff", + "#e6e7ffff", + "#dadcffff", + "#cbcdffff", + "#b8baf8ff", + "#9b9ef0ff", + "#5b5bd6ff", + "#5151cdff", + "#5753c6ff", + "#272962ff", + ], + light_alpha: [ + "#0000ff02", + "#0000ff07", + "#0011ee0f", + "#000bff19", + "#000eff25", + "#000aff34", + "#0008e647", + "#0008d964", + "#0000c0a4", + "#0000b6ae", + "#0600abac", + "#000246d8", + ], + dark: [ + "#13131eff", + "#171625ff", + "#202248ff", + "#262a65ff", + "#303374ff", + "#3d3e82ff", + "#4a4a95ff", + "#5958b1ff", + "#5b5bd6ff", + "#6e6adeff", + "#b1a9ffff", + "#e0dffeff", + ], + dark_alpha: [ + "#3636fe0e", + "#564bf916", + "#525bff3b", + "#4d58ff5a", + "#5b62fd6b", + "#6d6ffd7a", + "#7777fe8e", + "#7b7afeac", + "#6a6afed4", + "#7d79ffdc", + "#b1a9ffff", + "#e1e0fffe", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn indigo() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Indigo", + light: [ + "#fdfdfeff", + "#f7f9ffff", + "#edf2feff", + "#e1e9ffff", + "#d2deffff", + "#c1d0ffff", + "#abbdf9ff", + "#8da4efff", + "#3e63ddff", + "#3358d4ff", + "#3a5bc7ff", + "#1f2d5cff", + ], + light_alpha: [ + "#00008002", + "#0040ff08", + "#0047f112", + "#0044ff1e", + "#0044ff2d", + "#003eff3e", + "#0037ed54", + "#0034dc72", + "#0031d2c1", + "#002ec9cc", + "#002bb7c5", + "#001046e0", + ], + dark: [ + "#11131fff", + "#141726ff", + "#182449ff", + "#1d2e62ff", + "#253974ff", + "#304384ff", + "#3a4f97ff", + "#435db1ff", + "#3e63ddff", + "#5472e4ff", + "#9eb1ffff", + "#d6e1ffff", + ], + dark_alpha: [ + "#1133ff0f", + "#3354fa17", + "#2f62ff3c", + "#3566ff57", + "#4171fd6b", + "#5178fd7c", + "#5a7fff90", + "#5b81feac", + "#4671ffdb", + "#5c7efee3", + "#9eb1ffff", + "#d6e1ffff", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn blue() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Blue", + light: [ + "#fbfdffff", + "#f4faffff", + "#e6f4feff", + "#d5efffff", + "#c2e5ffff", + "#acd8fcff", + "#8ec8f6ff", + "#5eb1efff", + "#0090ffff", + "#0588f0ff", + "#0d74ceff", + "#113264ff", + ], + light_alpha: [ + "#0080ff04", + "#008cff0b", + "#008ff519", + "#009eff2a", + "#0093ff3d", + "#0088f653", + "#0083eb71", + "#0084e6a1", + "#0090ffff", + "#0086f0fa", + "#006dcbf2", + "#002359ee", + ], + dark: [ + "#0d1520ff", + "#111927ff", + "#0d2847ff", + "#003362ff", + "#004074ff", + "#104d87ff", + "#205d9eff", + "#2870bdff", + "#0090ffff", + "#3b9effff", + "#70b8ffff", + "#c2e6ffff", + ], + dark_alpha: [ + "#004df211", + "#1166fb18", + "#0077ff3a", + "#0075ff57", + "#0081fd6b", + "#0f89fd7f", + "#2a91fe98", + "#3094feb9", + "#0090ffff", + "#3b9effff", + "#70b8ffff", + "#c2e6ffff", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn cyan() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Cyan", + light: [ + "#fafdfeff", + "#f2fafbff", + "#def7f9ff", + "#caf1f6ff", + "#b5e9f0ff", + "#9ddde7ff", + "#7dcedcff", + "#3db9cfff", + "#00a2c7ff", + "#0797b9ff", + "#107d98ff", + "#0d3c48ff", + ], + light_alpha: [ + "#0099cc05", + "#009db10d", + "#00c2d121", + "#00bcd435", + "#01b4cc4a", + "#00a7c162", + "#009fbb82", + "#00a3c0c2", + "#00a2c7ff", + "#0094b7f8", + "#007491ef", + "#00323ef2", + ], + dark: [ + "#0b161aff", + "#101b20ff", + "#082c36ff", + "#003848ff", + "#004558ff", + "#045468ff", + "#12677eff", + "#11809cff", + "#00a2c7ff", + "#23afd0ff", + "#4ccce6ff", + "#b6ecf7ff", + ], + dark_alpha: [ + "#0091f70a", + "#02a7f211", + "#00befd28", + "#00baff3b", + "#00befd4d", + "#00c7fd5e", + "#14cdff75", + "#11cfff95", + "#00cfffc3", + "#28d6ffcd", + "#52e1fee5", + "#bbf3fef7", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn teal() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Teal", + light: [ + "#fafefdff", + "#f3fbf9ff", + "#e0f8f3ff", + "#ccf3eaff", + "#b8eae0ff", + "#a1ded2ff", + "#83cdc1ff", + "#53b9abff", + "#12a594ff", + "#0d9b8aff", + "#008573ff", + "#0d3d38ff", + ], + light_alpha: [ + "#00cc9905", + "#00aa800c", + "#00c69d1f", + "#00c39633", + "#00b49047", + "#00a6855e", + "#0099807c", + "#009783ac", + "#009e8ced", + "#009684f2", + "#008573ff", + "#00332df2", + ], + dark: [ + "#0d1514ff", + "#111c1bff", + "#0d2d2aff", + "#023b37ff", + "#084843ff", + "#145750ff", + "#1c6961ff", + "#207e73ff", + "#12a594ff", + "#0eb39eff", + "#0bd8b6ff", + "#adf0ddff", + ], + dark_alpha: [ + "#00deab05", + "#12fbe60c", + "#00ffe61e", + "#00ffe92d", + "#00ffea3b", + "#1cffe84b", + "#2efde85f", + "#32ffe775", + "#13ffe49f", + "#0dffe0ae", + "#0afed5d6", + "#b8ffebef", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn jade() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Jade", + light: [ + "#fbfefdff", + "#f4fbf7ff", + "#e6f7edff", + "#d6f1e3ff", + "#c3e9d7ff", + "#acdec8ff", + "#8bceb6ff", + "#56ba9fff", + "#29a383ff", + "#26997bff", + "#208368ff", + "#1d3b31ff", + ], + light_alpha: [ + "#00c08004", + "#00a3460b", + "#00ae4819", + "#00a85129", + "#00a2553c", + "#009a5753", + "#00945f74", + "#00976ea9", + "#00916bd6", + "#008764d9", + "#007152df", + "#002217e2", + ], + dark: [ + "#0d1512ff", + "#121c18ff", + "#0f2e22ff", + "#0b3b2cff", + "#114837ff", + "#1b5745ff", + "#246854ff", + "#2a7e68ff", + "#29a383ff", + "#27b08bff", + "#1fd8a4ff", + "#adf0d4ff", + ], + dark_alpha: [ + "#00de4505", + "#27fba60c", + "#02f99920", + "#00ffaa2d", + "#11ffb63b", + "#34ffc24b", + "#45fdc75e", + "#48ffcf75", + "#38feca9d", + "#31fec7ab", + "#21fec0d6", + "#b8ffe1ef", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn green() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Green", + light: [ + "#fbfefcff", + "#f4fbf6ff", + "#e6f6ebff", + "#d6f1dfff", + "#c4e8d1ff", + "#adddc0ff", + "#8eceaaff", + "#5bb98bff", + "#30a46cff", + "#2b9a66ff", + "#218358ff", + "#193b2dff", + ], + light_alpha: [ + "#00c04004", + "#00a32f0b", + "#00a43319", + "#00a83829", + "#019c393b", + "#00963c52", + "#00914071", + "#00924ba4", + "#008f4acf", + "#008647d4", + "#00713fde", + "#002616e6", + ], + dark: [ + "#0e1512ff", + "#121b17ff", + "#132d21ff", + "#113b29ff", + "#174933ff", + "#20573eff", + "#28684aff", + "#2f7c57ff", + "#30a46cff", + "#33b074ff", + "#3dd68cff", + "#b1f1cbff", + ], + dark_alpha: [ + "#00de4505", + "#29f99d0b", + "#22ff991e", + "#11ff992d", + "#2bffa23c", + "#44ffaa4b", + "#50fdac5e", + "#54ffad73", + "#44ffa49e", + "#43fea4ab", + "#46fea5d4", + "#bbffd7f0", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn grass() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Grass", + light: [ + "#fbfefbff", + "#f5fbf5ff", + "#e9f6e9ff", + "#daf1dbff", + "#c9e8caff", + "#b2ddb5ff", + "#94ce9aff", + "#65ba74ff", + "#46a758ff", + "#3e9b4fff", + "#2a7e3bff", + "#203c25ff", + ], + light_alpha: [ + "#00c00004", + "#0099000a", + "#00970016", + "#009f0725", + "#00930536", + "#008f0a4d", + "#018b0f6b", + "#008d199a", + "#008619b9", + "#007b17c1", + "#006514d5", + "#002006df", + ], + dark: [ + "#0e1511ff", + "#141a15ff", + "#1b2a1eff", + "#1d3a24ff", + "#25482dff", + "#2d5736ff", + "#366740ff", + "#3e7949ff", + "#46a758ff", + "#53b365ff", + "#71d083ff", + "#c2f0c2ff", + ], + dark_alpha: [ + "#00de1205", + "#5ef7780a", + "#70fe8c1b", + "#57ff802c", + "#68ff8b3b", + "#71ff8f4b", + "#77fd925d", + "#77fd9070", + "#65ff82a1", + "#72ff8dae", + "#89ff9fcd", + "#ceffceef", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn lime() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Lime", + light: [ + "#fcfdfaff", + "#f8faf3ff", + "#eef6d6ff", + "#e2f0bdff", + "#d3e7a6ff", + "#c2da91ff", + "#abc978ff", + "#8db654ff", + "#bdee63ff", + "#b0e64cff", + "#5c7c2fff", + "#37401cff", + ], + light_alpha: [ + "#66990005", + "#6b95000c", + "#96c80029", + "#8fc60042", + "#81bb0059", + "#72aa006e", + "#61990087", + "#559200ab", + "#93e4009c", + "#8fdc00b3", + "#375f00d0", + "#1e2900e3", + ], + dark: [ + "#11130cff", + "#151a10ff", + "#1f2917ff", + "#29371dff", + "#334423ff", + "#3d522aff", + "#496231ff", + "#577538ff", + "#bdee63ff", + "#d4ff70ff", + "#bde56cff", + "#e3f7baff", + ], + dark_alpha: [ + "#11bb0003", + "#78f7000a", + "#9bfd4c1a", + "#a7fe5c29", + "#affe6537", + "#b2fe6d46", + "#b6ff6f57", + "#b6fd6d6c", + "#caff69ed", + "#d4ff70ff", + "#d1fe77e4", + "#e9febff7", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn mint() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Mint", + light: [ + "#f9fefdff", + "#f2fbf9ff", + "#ddf9f2ff", + "#c8f4e9ff", + "#b3ecdeff", + "#9ce0d0ff", + "#7ecfbdff", + "#4cbba5ff", + "#86ead4ff", + "#7de0cbff", + "#027864ff", + "#16433cff", + ], + light_alpha: [ + "#00d5aa06", + "#00b18a0d", + "#00d29e22", + "#00cc9937", + "#00c0914c", + "#00b08663", + "#00a17d81", + "#009e7fb3", + "#00d3a579", + "#00c39982", + "#007763fd", + "#00312ae9", + ], + dark: [ + "#0e1515ff", + "#0f1b1bff", + "#092c2bff", + "#003a38ff", + "#004744ff", + "#105650ff", + "#1e685fff", + "#277f70ff", + "#86ead4ff", + "#a8f5e5ff", + "#58d5baff", + "#c4f5e1ff", + ], + dark_alpha: [ + "#00dede05", + "#00f9f90b", + "#00fff61d", + "#00fff42c", + "#00fff23a", + "#0effeb4a", + "#34fde55e", + "#41ffdf76", + "#92ffe7e9", + "#aefeedf5", + "#67ffded2", + "#cbfee9f5", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn sky() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Sky", + light: [ + "#f9feffff", + "#f1fafdff", + "#e1f6fdff", + "#d1f0faff", + "#bee7f5ff", + "#a9daedff", + "#8dcae3ff", + "#60b3d7ff", + "#7ce2feff", + "#74daf8ff", + "#00749eff", + "#1d3e56ff", + ], + light_alpha: [ + "#00d5ff06", + "#00a4db0e", + "#00b3ee1e", + "#00ace42e", + "#00a1d841", + "#0092ca56", + "#0089c172", + "#0085bf9f", + "#00c7fe83", + "#00bcf38b", + "#00749eff", + "#002540e2", + ], + dark: [ + "#0d141fff", + "#111a27ff", + "#112840ff", + "#113555ff", + "#154467ff", + "#1b537bff", + "#1f6692ff", + "#197caeff", + "#7ce2feff", + "#a8eeffff", + "#75c7f0ff", + "#c2f3ffff", + ], + dark_alpha: [ + "#0044ff0f", + "#1171fb18", + "#1184fc33", + "#128fff49", + "#1c9dfd5d", + "#28a5ff72", + "#2badfe8b", + "#1db2fea9", + "#7ce3fffe", + "#a8eeffff", + "#7cd3ffef", + "#c2f3ffff", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn black() -> ColorScaleSet { + StaticColorScaleSet { + scale: "Black", + light: [ + "#0000000d", + "#0000001a", + "#00000026", + "#00000033", + "#0000004d", + "#00000066", + "#00000080", + "#00000099", + "#000000b3", + "#000000cc", + "#000000e6", + "#000000f2", + ], + light_alpha: [ + "#0000000d", + "#0000001a", + "#00000026", + "#00000033", + "#0000004d", + "#00000066", + "#00000080", + "#00000099", + "#000000b3", + "#000000cc", + "#000000e6", + "#000000f2", + ], + dark: [ + "#0000000d", + "#0000001a", + "#00000026", + "#00000033", + "#0000004d", + "#00000066", + "#00000080", + "#00000099", + "#000000b3", + "#000000cc", + "#000000e6", + "#000000f2", + ], + dark_alpha: [ + "#0000000d", + "#0000001a", + "#00000026", + "#00000033", + "#0000004d", + "#00000066", + "#00000080", + "#00000099", + "#000000b3", + "#000000cc", + "#000000e6", + "#000000f2", + ], + } + .try_into() + .unwrap() +} + +pub(crate) fn white() -> ColorScaleSet { + StaticColorScaleSet { + scale: "White", + light: [ + "#ffffff0d", + "#ffffff1a", + "#ffffff26", + "#ffffff33", + "#ffffff4d", + "#ffffff66", + "#ffffff80", + "#ffffff99", + "#ffffffb3", + "#ffffffcc", + "#ffffffe6", + "#fffffff2", + ], + light_alpha: [ + "#ffffff0d", + "#ffffff1a", + "#ffffff26", + "#ffffff33", + "#ffffff4d", + "#ffffff66", + "#ffffff80", + "#ffffff99", + "#ffffffb3", + "#ffffffcc", + "#ffffffe6", + "#fffffff2", + ], + dark: [ + "#ffffff0d", + "#ffffff1a", + "#ffffff26", + "#ffffff33", + "#ffffff4d", + "#ffffff66", + "#ffffff80", + "#ffffff99", + "#ffffffb3", + "#ffffffcc", + "#ffffffe6", + "#fffffff2", + ], + dark_alpha: [ + "#ffffff0d", + "#ffffff1a", + "#ffffff26", + "#ffffff33", + "#ffffff4d", + "#ffffff66", + "#ffffff80", + "#ffffff99", + "#ffffffb3", + "#ffffffcc", + "#ffffffe6", + "#fffffff2", + ], + } + .try_into() + .unwrap() +} diff --git a/crates/theme/src/lib.rs b/crates/theme/src/lib.rs index 1ec4cb9..14a06c3 100644 --- a/crates/theme/src/lib.rs +++ b/crates/theme/src/lib.rs @@ -1,284 +1,31 @@ use std::ops::{Deref, DerefMut}; +use std::rc::Rc; -use colors::{brand, hsl, neutral}; -use gpui::{px, App, Global, Hsla, Pixels, SharedString, Window, WindowAppearance}; - -use crate::colors::{danger, warning}; -use crate::platform_kind::PlatformKind; -use crate::scrollbar_mode::ScrollBarMode; +use gpui::{px, App, Global, Pixels, SharedString, Window}; mod colors; +mod registry; mod scale; +mod scrollbar_mode; +mod theme; -pub mod platform_kind; -pub mod scrollbar_mode; +pub use colors::*; +pub use registry::*; +pub use scale::*; +pub use scrollbar_mode::*; +pub use theme::*; /// Defines window border radius for platforms that use client side decorations. pub const CLIENT_SIDE_DECORATION_ROUNDING: Pixels = px(10.0); + /// Defines window shadow size for platforms that use client side decorations. pub const CLIENT_SIDE_DECORATION_SHADOW: Pixels = px(10.0); pub fn init(cx: &mut App) { + registry::init(cx); + Theme::sync_system_appearance(None, cx); -} - -#[derive(Debug, Clone, Copy, Default)] -pub struct ThemeColor { - // Surface colors - pub background: Hsla, - pub surface_background: Hsla, - pub elevated_surface_background: Hsla, - pub panel_background: Hsla, - pub overlay: Hsla, - pub title_bar: Hsla, - pub title_bar_inactive: Hsla, - pub window_border: Hsla, - - // Border colors - pub border: Hsla, - pub border_variant: Hsla, - pub border_focused: Hsla, - pub border_selected: Hsla, - pub border_transparent: Hsla, - pub border_disabled: Hsla, - pub ring: Hsla, - - // Text colors - pub text: Hsla, - pub text_muted: Hsla, - pub text_placeholder: Hsla, - pub text_accent: Hsla, - - // Icon colors - pub icon: Hsla, - pub icon_muted: Hsla, - pub icon_accent: Hsla, - - // Element colors - pub element_foreground: Hsla, - pub element_background: Hsla, - pub element_hover: Hsla, - pub element_active: Hsla, - pub element_selected: Hsla, - pub element_disabled: Hsla, - - // Secondary element colors - pub secondary_foreground: Hsla, - pub secondary_background: Hsla, - pub secondary_hover: Hsla, - pub secondary_active: Hsla, - pub secondary_selected: Hsla, - pub secondary_disabled: Hsla, - - // Danger element colors - pub danger_foreground: Hsla, - pub danger_background: Hsla, - pub danger_hover: Hsla, - pub danger_active: Hsla, - pub danger_selected: Hsla, - pub danger_disabled: Hsla, - - // Warning element colors - pub warning_foreground: Hsla, - pub warning_background: Hsla, - pub warning_hover: Hsla, - pub warning_active: Hsla, - pub warning_selected: Hsla, - pub warning_disabled: Hsla, - - // Ghost element colors - pub ghost_element_background: Hsla, - pub ghost_element_background_alt: Hsla, - pub ghost_element_hover: Hsla, - pub ghost_element_active: Hsla, - pub ghost_element_selected: Hsla, - pub ghost_element_disabled: Hsla, - - // Tab colors - pub tab_inactive_background: Hsla, - pub tab_hover_background: Hsla, - pub tab_active_background: Hsla, - - // Scrollbar colors - pub scrollbar_thumb_background: Hsla, - pub scrollbar_thumb_hover_background: Hsla, - pub scrollbar_thumb_border: Hsla, - pub scrollbar_track_background: Hsla, - pub scrollbar_track_border: Hsla, - - // Interactive colors - pub drop_target_background: Hsla, - pub cursor: Hsla, - pub selection: Hsla, -} - -/// The default colors for the theme. -/// -/// Themes that do not specify all colors are refined off of these defaults. -impl ThemeColor { - /// Returns the default colors for light themes. - /// - /// Themes that do not specify all colors are refined off of these defaults. - pub fn light() -> Self { - Self { - background: neutral().light().step_1(), - surface_background: neutral().light().step_2(), - elevated_surface_background: neutral().light().step_3(), - panel_background: gpui::white(), - overlay: neutral().light_alpha().step_3(), - title_bar: gpui::transparent_black(), - title_bar_inactive: neutral().light().step_1(), - window_border: hsl(240.0, 5.9, 78.0), - - border: neutral().light().step_6(), - border_variant: neutral().light().step_5(), - border_focused: brand().light().step_7(), - border_selected: brand().light().step_7(), - border_transparent: gpui::transparent_black(), - border_disabled: neutral().light().step_3(), - ring: brand().light().step_8(), - - text: neutral().light().step_12(), - text_muted: neutral().light().step_11(), - text_placeholder: neutral().light().step_10(), - text_accent: brand().light().step_11(), - - icon: neutral().light().step_11(), - icon_muted: neutral().light().step_10(), - icon_accent: brand().light().step_11(), - - element_foreground: brand().light().step_12(), - element_background: brand().light().step_9(), - element_hover: brand().light_alpha().step_10(), - element_active: brand().light().step_10(), - element_selected: brand().light().step_11(), - element_disabled: brand().light_alpha().step_3(), - - secondary_foreground: brand().light().step_11(), - secondary_background: brand().light().step_3(), - secondary_hover: brand().light_alpha().step_4(), - secondary_active: brand().light().step_5(), - secondary_selected: brand().light().step_5(), - secondary_disabled: brand().light_alpha().step_3(), - - danger_foreground: danger().light().step_12(), - danger_background: danger().light().step_3(), - danger_hover: danger().light_alpha().step_4(), - danger_active: danger().light().step_5(), - danger_selected: danger().light().step_5(), - danger_disabled: danger().light_alpha().step_3(), - - warning_foreground: warning().light().step_12(), - warning_background: warning().light().step_3(), - warning_hover: warning().light_alpha().step_4(), - warning_active: warning().light().step_5(), - warning_selected: warning().light().step_5(), - warning_disabled: warning().light_alpha().step_3(), - - ghost_element_background: gpui::transparent_black(), - ghost_element_background_alt: neutral().light().step_3(), - ghost_element_hover: neutral().light_alpha().step_4(), - ghost_element_active: neutral().light().step_5(), - ghost_element_selected: neutral().light().step_5(), - ghost_element_disabled: neutral().light_alpha().step_2(), - - tab_inactive_background: neutral().light().step_3(), - tab_hover_background: neutral().light().step_4(), - tab_active_background: neutral().light().step_5(), - - scrollbar_thumb_background: neutral().light_alpha().step_3(), - scrollbar_thumb_hover_background: neutral().light_alpha().step_4(), - scrollbar_thumb_border: gpui::transparent_black(), - scrollbar_track_background: gpui::transparent_black(), - scrollbar_track_border: neutral().light().step_5(), - - drop_target_background: brand().light_alpha().step_2(), - cursor: hsl(200., 100., 50.), - selection: hsl(200., 100., 50.).alpha(0.25), - } - } - - /// Returns the default colors for dark themes. - /// - /// Themes that do not specify all colors are refined off of these defaults. - pub fn dark() -> Self { - Self { - background: neutral().dark().step_1(), - surface_background: neutral().dark().step_2(), - elevated_surface_background: neutral().dark().step_3(), - panel_background: gpui::black(), - overlay: neutral().dark_alpha().step_3(), - title_bar: gpui::transparent_black(), - title_bar_inactive: neutral().dark().step_1(), - window_border: hsl(240.0, 3.7, 28.0), - - border: neutral().dark().step_6(), - border_variant: neutral().dark().step_5(), - border_focused: brand().dark().step_7(), - border_selected: brand().dark().step_7(), - border_transparent: gpui::transparent_black(), - border_disabled: neutral().dark().step_3(), - ring: brand().dark().step_8(), - - text: neutral().dark().step_12(), - text_muted: neutral().dark().step_11(), - text_placeholder: neutral().dark().step_10(), - text_accent: brand().dark().step_11(), - - icon: neutral().dark().step_11(), - icon_muted: neutral().dark().step_10(), - icon_accent: brand().dark().step_11(), - - element_foreground: brand().dark().step_1(), - element_background: brand().dark().step_9(), - element_hover: brand().dark_alpha().step_10(), - element_active: brand().dark().step_10(), - element_selected: brand().dark().step_11(), - element_disabled: brand().dark_alpha().step_3(), - - secondary_foreground: brand().dark().step_12(), - secondary_background: brand().dark().step_3(), - secondary_hover: brand().dark_alpha().step_4(), - secondary_active: brand().dark().step_5(), - secondary_selected: brand().dark().step_5(), - secondary_disabled: brand().dark_alpha().step_3(), - - danger_foreground: danger().dark().step_12(), - danger_background: danger().dark().step_3(), - danger_hover: danger().dark_alpha().step_4(), - danger_active: danger().dark().step_5(), - danger_selected: danger().dark().step_5(), - danger_disabled: danger().dark_alpha().step_3(), - - warning_foreground: warning().dark().step_12(), - warning_background: warning().dark().step_3(), - warning_hover: warning().dark_alpha().step_4(), - warning_active: warning().dark().step_5(), - warning_selected: warning().dark().step_5(), - warning_disabled: warning().dark_alpha().step_3(), - - ghost_element_background: gpui::transparent_black(), - ghost_element_background_alt: neutral().dark().step_3(), - ghost_element_hover: neutral().dark_alpha().step_4(), - ghost_element_active: neutral().dark().step_5(), - ghost_element_selected: neutral().dark().step_5(), - ghost_element_disabled: neutral().dark_alpha().step_2(), - - tab_inactive_background: neutral().dark().step_3(), - tab_hover_background: neutral().dark().step_4(), - tab_active_background: neutral().dark().step_5(), - - scrollbar_thumb_background: neutral().dark_alpha().step_3(), - scrollbar_thumb_hover_background: neutral().dark_alpha().step_4(), - scrollbar_thumb_border: gpui::transparent_black(), - scrollbar_track_background: gpui::transparent_black(), - scrollbar_track_border: neutral().dark().step_5(), - - drop_target_background: brand().dark_alpha().step_2(), - cursor: hsl(200., 100., 50.), - selection: hsl(200., 100., 50.).alpha(0.25), - } - } + Theme::sync_scrollbar_appearance(cx); } pub trait ActiveTheme { @@ -292,49 +39,38 @@ impl ActiveTheme for App { } } -#[derive(Debug, Clone, Copy, Default, PartialEq, PartialOrd, Eq, Hash)] -pub enum ThemeMode { - Light, - #[default] - Dark, -} - -impl ThemeMode { - pub fn is_dark(&self) -> bool { - matches!(self, Self::Dark) - } - - /// Return lower_case theme name: `light`, `dark`. - pub fn name(&self) -> &'static str { - match self { - ThemeMode::Light => "light", - ThemeMode::Dark => "dark", - } - } -} - -impl From for ThemeMode { - fn from(appearance: WindowAppearance) -> Self { - match appearance { - WindowAppearance::Dark | WindowAppearance::VibrantDark => Self::Dark, - WindowAppearance::Light | WindowAppearance::VibrantLight => Self::Light, - } - } -} - #[derive(Debug, Clone)] pub struct Theme { - pub colors: ThemeColor, + /// Theme colors + pub colors: ThemeColors, + + /// Theme family + pub theme: Rc, + + /// The appearance of the theme (light or dark). pub mode: ThemeMode, + + /// The font family for the application. pub font_family: SharedString, + + /// The root font size for the application, default is 15px. pub font_size: Pixels, + + /// Radius for the general elements. pub radius: Pixels, - pub scrollbar_mode: ScrollBarMode, - pub platform_kind: PlatformKind, + + /// Radius for the large elements, e.g.: modal, notification. + pub radius_lg: Pixels, + + /// Enable shadow for the general elements. default is true + pub shadow: bool, + + /// Show the scrollbar mode, default: scrolling + pub scrollbar_mode: ScrollbarMode, } impl Deref for Theme { - type Target = ThemeColor; + type Target = ThemeColors; fn deref(&self) -> &Self::Target { &self.colors @@ -375,42 +111,76 @@ impl Theme { Self::change(appearance, window, cx); } - /// Change the app's appearance - pub fn change(mode: impl Into, window: Option<&mut Window>, cx: &mut App) { - let mode = mode.into(); - let colors = match mode { - ThemeMode::Light => ThemeColor::light(), - ThemeMode::Dark => ThemeColor::dark(), + /// Sync the Scrollbar showing behavior with the system + pub fn sync_scrollbar_appearance(cx: &mut App) { + Theme::global_mut(cx).scrollbar_mode = if cx.should_auto_hide_scrollbars() { + ScrollbarMode::Scrolling + } else { + ScrollbarMode::Hover }; + } + /// Apply a new theme to the application. + pub fn apply_theme(new_theme: Rc, window: Option<&mut Window>, cx: &mut App) { + let theme = cx.global_mut::(); + let mode = theme.mode; + // Update the theme + theme.theme = new_theme; + // Emit a theme change event + Self::change(mode, window, cx); + } + + /// Change the app's appearance + pub fn change(mode: M, window: Option<&mut Window>, cx: &mut App) + where + M: Into, + { if !cx.has_global::() { - let theme = Theme::from(colors); + let default_theme = ThemeFamily::default(); + let theme = Theme::from(default_theme); + cx.set_global(theme); } + let mode = mode.into(); let theme = cx.global_mut::(); + // Set the theme mode theme.mode = mode; - theme.colors = colors; + // Set the theme colors + if mode.is_dark() { + theme.colors = *theme.theme.dark(); + } else { + theme.colors = *theme.theme.light(); + } + + // Refresh the window if available if let Some(window) = window { window.refresh(); } } } -impl From for Theme { - fn from(colors: ThemeColor) -> Self { +impl From for Theme { + fn from(family: ThemeFamily) -> Self { let mode = ThemeMode::default(); + // Define the theme colors based on the appearance + let colors = match mode { + ThemeMode::Light => family.light(), + ThemeMode::Dark => family.dark(), + }; Theme { font_size: px(15.), font_family: ".SystemUIFont".into(), radius: px(5.), - scrollbar_mode: ScrollBarMode::default(), - platform_kind: PlatformKind::platform(), + radius_lg: px(10.), + shadow: true, + scrollbar_mode: ScrollbarMode::default(), mode, - colors, + colors: *colors, + theme: Rc::new(family), } } } diff --git a/crates/theme/src/registry.rs b/crates/theme/src/registry.rs new file mode 100644 index 0000000..3cf3719 --- /dev/null +++ b/crates/theme/src/registry.rs @@ -0,0 +1,70 @@ +use std::collections::HashMap; +use std::rc::Rc; +use std::sync::Arc; + +use anyhow::{Context as AnyhowContext, Error}; +use gpui::{App, AppContext, AssetSource, Context, Entity, Global, SharedString}; + +use crate::ThemeFamily; + +pub fn init(cx: &mut App) { + ThemeRegistry::set_global(cx.new(ThemeRegistry::new), cx); +} + +struct GlobalThemeRegistry(Entity); + +impl Global for GlobalThemeRegistry {} + +pub struct ThemeRegistry { + /// Map of theme names to theme families + themes: HashMap>, +} + +impl ThemeRegistry { + /// Retrieve the global theme registry state + pub fn global(cx: &App) -> Entity { + cx.global::().0.clone() + } + + /// Set the global theme registry instance + pub(crate) fn set_global(state: Entity, cx: &mut App) { + cx.set_global(GlobalThemeRegistry(state)); + } + + /// Create a new theme registry instance + pub(crate) fn new(cx: &mut Context) -> Self { + let mut themes = HashMap::new(); + let asset = cx.asset_source(); + + if let Ok(paths) = asset.list("themes") { + for path in paths.into_iter() { + match Self::load(&path, asset) { + Ok(theme) => { + themes.insert(path, Rc::new(theme)); + } + Err(e) => { + log::error!("Failed to load theme: {path}. Error: {e}"); + } + } + } + } + + Self { themes } + } + + /// Load a theme from the asset source. + fn load(path: &str, asset: &Arc) -> Result { + // Load the theme file from the assets + let content = asset.load(path)?.context("Theme not found")?; + + // Parse the JSON content into a Theme Family struct + let theme: ThemeFamily = serde_json::from_slice(&content)?; + + Ok(theme) + } + + /// Returns a reference to the map of themes. + pub fn themes(&self) -> &HashMap> { + &self.themes + } +} diff --git a/crates/theme/src/scrollbar_mode.rs b/crates/theme/src/scrollbar_mode.rs index 2c09ac8..e9fbf76 100644 --- a/crates/theme/src/scrollbar_mode.rs +++ b/crates/theme/src/scrollbar_mode.rs @@ -1,12 +1,15 @@ -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] -pub enum ScrollBarMode { +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default, Serialize, Deserialize, JsonSchema)] +pub enum ScrollbarMode { #[default] Scrolling, Hover, Always, } -impl ScrollBarMode { +impl ScrollbarMode { pub fn is_scrolling(&self) -> bool { matches!(self, Self::Scrolling) } diff --git a/crates/theme/src/theme.rs b/crates/theme/src/theme.rs new file mode 100644 index 0000000..b22a865 --- /dev/null +++ b/crates/theme/src/theme.rs @@ -0,0 +1,359 @@ +use std::path::Path; + +use gpui::{SharedString, WindowAppearance}; +use schemars::JsonSchema; +use serde::{Deserialize, Serialize}; + +use crate::ThemeColors; + +#[derive(Debug, Clone, Copy, Default, PartialEq, PartialOrd, Eq, Hash)] +pub enum ThemeMode { + #[default] + Light, + Dark, +} + +impl ThemeMode { + pub fn is_dark(&self) -> bool { + matches!(self, Self::Dark) + } + + /// Return lower_case theme name: `light`, `dark`. + pub fn name(&self) -> &'static str { + match self { + ThemeMode::Light => "light", + ThemeMode::Dark => "dark", + } + } +} + +impl From for ThemeMode { + fn from(appearance: WindowAppearance) -> Self { + match appearance { + WindowAppearance::Dark | WindowAppearance::VibrantDark => Self::Dark, + WindowAppearance::Light | WindowAppearance::VibrantLight => Self::Light, + } + } +} + +/// Theme family +#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, JsonSchema)] +pub struct ThemeFamily { + /// The unique identifier for the theme. + pub id: String, + + /// The name of the theme. + pub name: SharedString, + + /// The author of the theme. + pub author: SharedString, + + /// The URL of the theme. + pub url: String, + + /// The light colors for the theme. + pub light: ThemeColors, + + /// The dark colors for the theme. + pub dark: ThemeColors, +} + +impl Default for ThemeFamily { + fn default() -> Self { + ThemeFamily { + id: "coop".into(), + name: "Coop Default Theme".into(), + author: "Coop".into(), + url: "https://github.com/lumehq/coop".into(), + light: ThemeColors::light(), + dark: ThemeColors::dark(), + } + } +} + +impl ThemeFamily { + /// Returns the light colors for the theme. + #[inline(always)] + pub fn light(&self) -> &ThemeColors { + &self.light + } + + /// Returns the dark colors for the theme. + #[inline(always)] + pub fn dark(&self) -> &ThemeColors { + &self.dark + } + + /// Load a theme family from a JSON file. + /// + /// # Arguments + /// + /// * `path` - Path to the JSON file containing the theme family. This can be + /// an absolute path or a path relative to the current working directory. + /// + /// # Returns + /// + /// Returns `Ok(ThemeFamily)` if the file was successfully loaded and parsed, + /// or `Err(anyhow::Error)` if there was an error reading or parsing the file. + /// + /// # Errors + /// + /// This function will return an error if: + /// - The file cannot be read (permission issues, file doesn't exist, etc.) + /// - The file contains invalid JSON + /// - The JSON structure doesn't match the `ThemeFamily` schema + /// + /// # Example + /// + /// ```no_run + /// use theme::ThemeFamily; + /// + /// # fn main() -> anyhow::Result<()> { + /// // Load from a relative path + /// let theme = ThemeFamily::from_file("assets/themes/my-theme.json")?; + /// + /// // Load from an absolute path + /// let theme = ThemeFamily::from_file("/path/to/themes/my-theme.json")?; + /// # Ok(()) + /// # } + /// ``` + pub fn from_file>(path: P) -> anyhow::Result { + let json_data = std::fs::read(path)?; + let theme_family = serde_json::from_slice(&json_data)?; + + Ok(theme_family) + } + + /// Load a theme family from a JSON file in the assets/themes directory. + /// + /// This function looks for the file at `assets/themes/{name}.json` relative + /// to the current working directory. This is useful for loading themes + /// from the standard theme directory in the project structure. + /// + /// # Arguments + /// + /// * `name` - Name of the theme file (without the .json extension) + /// + /// # Returns + /// + /// Returns `Ok(ThemeFamily)` if the file was successfully loaded and parsed, + /// or `Err(anyhow::Error)` if there was an error reading or parsing the file. + /// + /// # Errors + /// + /// This function will return an error if: + /// - The file cannot be read (permission issues, file doesn't exist, etc.) + /// - The file contains invalid JSON + /// - The JSON structure doesn't match the `ThemeFamily` schema + /// + /// # Example + /// + /// ```no_run + /// use theme::ThemeFamily; + /// + /// # fn main() -> anyhow::Result<()> { + /// // Assuming the file exists at `assets/themes/my-theme.json` + /// let theme = ThemeFamily::from_assets("my-theme")?; + /// + /// println!("Loaded theme: {}", theme.name); + /// # Ok(()) + /// # } + /// ``` + pub fn from_assets(name: &str) -> anyhow::Result { + let path = format!("assets/themes/{}.json", name); + Self::from_file(path) + } +} + +#[cfg(test)] +mod tests { + use std::fs; + + use tempfile::tempdir; + + use super::*; + + #[test] + fn test_from_file() { + // Create a temporary directory for our test + let dir = tempdir().unwrap(); + let file_path = dir.path().join("test-theme.json"); + + // Create a minimal valid theme JSON with hex colors + // Using simple hex colors that Hsla can parse + // Note: We need to escape the # characters in the raw string + let json_data = r##"{ + "id": "test-theme", + "name": "Test Theme", + "author": "Coop", + "url": "https://github.com/lumehq/coop", + "light": { + "background": "#ffffff", + "surface_background": "#fafafa", + "elevated_surface_background": "#f5f5f5", + "panel_background": "#ffffff", + "overlay": "#0000001a", + "title_bar": "#00000000", + "title_bar_inactive": "#ffffff", + "window_border": "#c7c7cf", + "border": "#dbdbdb", + "border_variant": "#d1d1d1", + "border_focused": "#3366cc", + "border_selected": "#3366cc", + "border_transparent": "#00000000", + "border_disabled": "#e6e6e6", + "ring": "#4d79d6", + "text": "#1a1a1a", + "text_muted": "#4d4d4d", + "text_placeholder": "#808080", + "text_accent": "#3366cc", + "icon": "#4d4d4d", + "icon_muted": "#808080", + "icon_accent": "#3366cc", + "element_foreground": "#ffffff", + "element_background": "#3366cc", + "element_hover": "#3366cce6", + "element_active": "#2e5cb8", + "element_selected": "#2952a3", + "element_disabled": "#3366cc4d", + "secondary_foreground": "#2952a3", + "secondary_background": "#e6ecf5", + "secondary_hover": "#3366cc1a", + "secondary_active": "#d9e2f0", + "secondary_selected": "#d9e2f0", + "secondary_disabled": "#3366cc4d", + "danger_foreground": "#ffffff", + "danger_background": "#f5e6e6", + "danger_hover": "#cc33331a", + "danger_active": "#f0d9d9", + "danger_selected": "#f0d9d9", + "danger_disabled": "#cc33334d", + "warning_foreground": "#1a1a1a", + "warning_background": "#f5f0e6", + "warning_hover": "#cc99331a", + "warning_active": "#f0ead9", + "warning_selected": "#f0ead9", + "warning_disabled": "#cc99334d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#e6e6e6", + "ghost_element_hover": "#0000001a", + "ghost_element_active": "#d9d9d9", + "ghost_element_selected": "#d9d9d9", + "ghost_element_disabled": "#0000000d", + "tab_inactive_background": "#e6e6e6", + "tab_hover_background": "#e0e0e0", + "tab_active_background": "#d9d9d9", + "scrollbar_thumb_background": "#00000033", + "scrollbar_thumb_hover_background": "#0000004d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#d9d9d9", + "drop_target_background": "#3366cc1a", + "cursor": "#3399ff", + "selection": "#3399ff40" + }, + "dark": { + "background": "#1a1a1a", + "surface_background": "#1f1f1f", + "elevated_surface_background": "#242424", + "panel_background": "#262626", + "overlay": "#ffffff1a", + "title_bar": "#00000000", + "title_bar_inactive": "#1a1a1a", + "window_border": "#404046", + "border": "#404040", + "border_variant": "#383838", + "border_focused": "#4d79d6", + "border_selected": "#4d79d6", + "border_transparent": "#00000000", + "border_disabled": "#2e2e2e", + "ring": "#668cdf", + "text": "#f2f2f2", + "text_muted": "#b3b3b3", + "text_placeholder": "#808080", + "text_accent": "#668cdf", + "icon": "#b3b3b3", + "icon_muted": "#808080", + "icon_accent": "#668cdf", + "element_foreground": "#ffffff", + "element_background": "#4d79d6", + "element_hover": "#4d79d6e6", + "element_active": "#456dc1", + "element_selected": "#3e62ac", + "element_disabled": "#4d79d64d", + "secondary_foreground": "#3e62ac", + "secondary_background": "#2a3652", + "secondary_hover": "#4d79d61a", + "secondary_active": "#303d5c", + "secondary_selected": "#303d5c", + "secondary_disabled": "#4d79d64d", + "danger_foreground": "#ffffff", + "danger_background": "#522a2a", + "danger_hover": "#d64d4d1a", + "danger_active": "#5c3030", + "danger_selected": "#5c3030", + "danger_disabled": "#d64d4d4d", + "warning_foreground": "#f2f2f2", + "warning_background": "#52482a", + "warning_hover": "#d6b34d1a", + "warning_active": "#5c5430", + "warning_selected": "#5c5430", + "warning_disabled": "#d6b34d4d", + "ghost_element_background": "#00000000", + "ghost_element_background_alt": "#2e2e2e", + "ghost_element_hover": "#ffffff1a", + "ghost_element_active": "#383838", + "ghost_element_selected": "#383838", + "ghost_element_disabled": "#ffffff0d", + "tab_inactive_background": "#2e2e2e", + "tab_hover_background": "#333333", + "tab_active_background": "#383838", + "scrollbar_thumb_background": "#ffffff33", + "scrollbar_thumb_hover_background": "#ffffff4d", + "scrollbar_thumb_border": "#00000000", + "scrollbar_track_background": "#00000000", + "scrollbar_track_border": "#383838", + "drop_target_background": "#4d79d61a", + "cursor": "#4db3ff", + "selection": "#4db3ff40" + } + }"##; + + // Write the JSON to the file + fs::write(&file_path, json_data).unwrap(); + + // Test loading the theme from file + let theme = ThemeFamily::from_file(&file_path).unwrap(); + + // Verify the loaded theme + assert_eq!(theme.id, "test-theme"); + assert_eq!(theme.name, "Test Theme"); + + // Clean up + dir.close().unwrap(); + } + + #[test] + fn test_from_file_nonexistent() { + // Test that loading a non-existent file returns an error + let result = ThemeFamily::from_file("non-existent-file.json"); + assert!(result.is_err()); + } + + #[test] + fn test_from_file_invalid_json() { + // Create a temporary directory for our test + let dir = tempdir().unwrap(); + let file_path = dir.path().join("invalid-theme.json"); + + // Write invalid JSON + fs::write(&file_path, "invalid json").unwrap(); + + // Test that loading invalid JSON returns an error + let result = ThemeFamily::from_file(&file_path); + assert!(result.is_err()); + + // Clean up + dir.close().unwrap(); + } +} diff --git a/crates/title_bar/src/lib.rs b/crates/title_bar/src/lib.rs index 00caca3..f4f9471 100644 --- a/crates/title_bar/src/lib.rs +++ b/crates/title_bar/src/lib.rs @@ -9,18 +9,20 @@ use gpui::{ WindowControlArea, }; use smallvec::{smallvec, SmallVec}; -use theme::platform_kind::PlatformKind; use theme::{ActiveTheme, CLIENT_SIDE_DECORATION_ROUNDING}; use ui::h_flex; +use crate::platform_kind::PlatformKind; #[cfg(target_os = "linux")] use crate::platforms::linux::LinuxWindowControls; use crate::platforms::windows::WindowsWindowControls; +mod platform_kind; mod platforms; pub struct TitleBar { children: SmallVec<[AnyElement; 2]>, + platform_kind: PlatformKind, should_move: bool, } @@ -34,6 +36,7 @@ impl TitleBar { pub fn new() -> Self { Self { children: smallvec![], + platform_kind: PlatformKind::platform(), should_move: false, } } @@ -90,7 +93,7 @@ impl Render for TitleBar { .map(|this| { if window.is_fullscreen() { this.px_2() - } else if cx.theme().platform_kind.is_mac() { + } else if self.platform_kind.is_mac() { this.pl(px(platforms::mac::TRAFFIC_LIGHT_PADDING)) .pr_2() .when(children.len() <= 1, |this| { @@ -120,14 +123,14 @@ impl Render for TitleBar { .items_center() .justify_between() .w_full() - .when(cx.theme().platform_kind.is_mac(), |this| { + .when(self.platform_kind.is_mac(), |this| { this.on_click(|event, window, _| { if event.click_count() == 2 { window.titlebar_double_click(); } }) }) - .when(cx.theme().platform_kind.is_linux(), |this| { + .when(self.platform_kind.is_linux(), |this| { this.on_click(|event, window, _| { if event.click_count() == 2 { window.zoom_window(); @@ -136,47 +139,45 @@ impl Render for TitleBar { }) .children(children), ) - .when(!window.is_fullscreen(), |this| { - match cx.theme().platform_kind { - PlatformKind::Linux => { - #[cfg(target_os = "linux")] - if matches!(decorations, Decorations::Client { .. }) { - this.child(LinuxWindowControls::new(None)) - .when(supported_controls.window_menu, |this| { - this.on_mouse_down(MouseButton::Right, move |ev, window, _| { - window.show_window_menu(ev.position) - }) + .when(!window.is_fullscreen(), |this| match self.platform_kind { + PlatformKind::Linux => { + #[cfg(target_os = "linux")] + if matches!(decorations, Decorations::Client { .. }) { + this.child(LinuxWindowControls::new(None)) + .when(supported_controls.window_menu, |this| { + this.on_mouse_down(MouseButton::Right, move |ev, window, _| { + window.show_window_menu(ev.position) }) - .on_mouse_move(cx.listener(move |this, _ev, window, _| { - if this.should_move { - this.should_move = false; - window.start_window_move(); - } - })) - .on_mouse_down_out(cx.listener(move |this, _ev, _window, _cx| { + }) + .on_mouse_move(cx.listener(move |this, _ev, window, _| { + if this.should_move { this.should_move = false; - })) - .on_mouse_up( - MouseButton::Left, - cx.listener(move |this, _ev, _window, _cx| { - this.should_move = false; - }), - ) - .on_mouse_down( - MouseButton::Left, - cx.listener(move |this, _ev, _window, _cx| { - this.should_move = true; - }), - ) - } else { - this - } - #[cfg(not(target_os = "linux"))] + window.start_window_move(); + } + })) + .on_mouse_down_out(cx.listener(move |this, _ev, _window, _cx| { + this.should_move = false; + })) + .on_mouse_up( + MouseButton::Left, + cx.listener(move |this, _ev, _window, _cx| { + this.should_move = false; + }), + ) + .on_mouse_down( + MouseButton::Left, + cx.listener(move |this, _ev, _window, _cx| { + this.should_move = true; + }), + ) + } else { this } - PlatformKind::Windows => this.child(WindowsWindowControls::new(height)), - PlatformKind::Mac => this, + #[cfg(not(target_os = "linux"))] + this } + PlatformKind::Windows => this.child(WindowsWindowControls::new(height)), + PlatformKind::Mac => this, }) } } diff --git a/crates/theme/src/platform_kind.rs b/crates/title_bar/src/platform_kind.rs similarity index 90% rename from crates/theme/src/platform_kind.rs rename to crates/title_bar/src/platform_kind.rs index bca3e77..95db95b 100644 --- a/crates/theme/src/platform_kind.rs +++ b/crates/title_bar/src/platform_kind.rs @@ -16,14 +16,17 @@ impl PlatformKind { } } + #[allow(dead_code)] pub fn is_linux(&self) -> bool { matches!(self, Self::Linux) } + #[allow(dead_code)] pub fn is_windows(&self) -> bool { matches!(self, Self::Windows) } + #[allow(dead_code)] pub fn is_mac(&self) -> bool { matches!(self, Self::Mac) } diff --git a/crates/ui/src/dock_area/mod.rs b/crates/ui/src/dock_area/mod.rs index a8aa865..a2fb704 100644 --- a/crates/ui/src/dock_area/mod.rs +++ b/crates/ui/src/dock_area/mod.rs @@ -309,7 +309,7 @@ impl DockItem { pub(crate) fn focus_tab_panel(&self, window: &mut Window, cx: &mut App) { if let DockItem::Tabs { view, .. } = self { - window.focus(&view.read(cx).focus_handle(cx)); + window.focus(&view.read(cx).focus_handle(cx), cx); } } } diff --git a/crates/ui/src/dock_area/tab_panel.rs b/crates/ui/src/dock_area/tab_panel.rs index ccd707f..9a6ffe6 100644 --- a/crates/ui/src/dock_area/tab_panel.rs +++ b/crates/ui/src/dock_area/tab_panel.rs @@ -53,9 +53,9 @@ impl Render for DragPanel { .justify_center() .overflow_hidden() .whitespace_nowrap() - .rounded(cx.theme().radius) + .rounded(cx.theme().radius_lg) .text_xs() - .shadow_lg() + .when(cx.theme().shadow, |this| this.shadow_lg()) .bg(cx.theme().background) .text_color(cx.theme().text_accent) .child(self.panel.title(cx)) @@ -651,8 +651,8 @@ impl TabPanel { .child( div() .size_full() - .rounded_xl() - .shadow_sm() + .rounded(cx.theme().radius_lg) + .when(cx.theme().shadow, |this| this.shadow_sm()) .when(cx.theme().mode.is_dark(), |this| this.shadow_lg()) .bg(cx.theme().panel_background) .overflow_hidden() @@ -671,7 +671,7 @@ impl TabPanel { .p_1() .child( div() - .rounded_xl() + .rounded(cx.theme().radius_lg) .border_1() .border_color(cx.theme().element_disabled) .bg(cx.theme().drop_target_background) @@ -898,7 +898,7 @@ impl TabPanel { fn focus_active_panel(&self, window: &mut Window, cx: &mut Context) { if let Some(active_panel) = self.active_panel(cx) { - window.focus(&active_panel.focus_handle(cx)); + window.focus(&active_panel.focus_handle(cx), cx); } } diff --git a/crates/ui/src/dropdown.rs b/crates/ui/src/dropdown.rs index 22651f5..ce09a67 100644 --- a/crates/ui/src/dropdown.rs +++ b/crates/ui/src/dropdown.rs @@ -426,8 +426,8 @@ where self.selected_value.as_ref() } - pub fn focus(&self, window: &mut Window, _: &mut App) { - self.focus_handle.focus(window); + pub fn focus(&self, window: &mut Window, cx: &mut App) { + self.focus_handle.focus(window, cx); } fn on_blur(&mut self, window: &mut Window, cx: &mut Context) { @@ -445,7 +445,7 @@ where return; } - self.list.focus_handle(cx).focus(window); + self.list.focus_handle(cx).focus(window, cx); cx.propagate(); } @@ -454,7 +454,7 @@ where self.open = true; } - self.list.focus_handle(cx).focus(window); + self.list.focus_handle(cx).focus(window, cx); cx.propagate(); } @@ -466,7 +466,7 @@ where self.open = true; cx.notify(); } else { - self.list.focus_handle(cx).focus(window); + self.list.focus_handle(cx).focus(window, cx); } } @@ -475,7 +475,7 @@ where self.open = !self.open; if self.open { - self.list.focus_handle(cx).focus(window); + self.list.focus_handle(cx).focus(window, cx); } cx.notify(); } @@ -708,7 +708,7 @@ where .border_1() .border_color(cx.theme().border) .rounded(cx.theme().radius) - .shadow_sm() + .when(cx.theme().shadow, |this| this.shadow_sm()) .overflow_hidden() .input_font_size(self.size) .map(|this| match self.width { @@ -793,7 +793,7 @@ where .border_1() .border_color(cx.theme().border) .rounded(popup_radius) - .shadow_md() + .when(cx.theme().shadow, |this| this.shadow_md()) .child(state.list.clone()), ) .on_mouse_down_out(window.listener_for( diff --git a/crates/ui/src/focusable.rs b/crates/ui/src/focusable.rs index 1ece9df..7ecd843 100644 --- a/crates/ui/src/focusable.rs +++ b/crates/ui/src/focusable.rs @@ -33,7 +33,7 @@ pub trait FocusableCycle { .nth(1) .unwrap_or(fallback_handle); - target_focus_handle.focus(window); + target_focus_handle.focus(window, cx); cx.stop_propagation(); } } diff --git a/crates/ui/src/input/element.rs b/crates/ui/src/input/element.rs index f324f74..589db65 100644 --- a/crates/ui/src/input/element.rs +++ b/crates/ui/src/input/element.rs @@ -859,7 +859,7 @@ impl Element for TextElement { let p = point(input_bounds.origin.x, origin.y + offset_y); for line in lines { - _ = line.paint(p, line_height, window, cx); + _ = line.paint(p, line_height, TextAlign::Left, None, window, cx); offset_y += line_height; } } diff --git a/crates/ui/src/input/state.rs b/crates/ui/src/input/state.rs index 8db93b2..1dbbf84 100644 --- a/crates/ui/src/input/state.rs +++ b/crates/ui/src/input/state.rs @@ -766,7 +766,7 @@ impl InputState { /// Focus the input field. pub fn focus(&self, window: &mut Window, cx: &mut Context) { - self.focus_handle.focus(window); + self.focus_handle.focus(window, cx); self.blink_cursor.update(cx, |cursor, cx| { cursor.start(cx); }); diff --git a/crates/ui/src/lib.rs b/crates/ui/src/lib.rs index 06a1573..5cbbe7e 100644 --- a/crates/ui/src/lib.rs +++ b/crates/ui/src/lib.rs @@ -45,7 +45,6 @@ mod window_border; /// This must be called before using any of the UI components. /// You can initialize the UI module at your application's entry point. pub fn init(cx: &mut gpui::App) { - theme::init(cx); dropdown::init(cx); input::init(cx); list::init(cx); diff --git a/crates/ui/src/list/list.rs b/crates/ui/src/list/list.rs index cb297b7..79d52ab 100644 --- a/crates/ui/src/list/list.rs +++ b/crates/ui/src/list/list.rs @@ -244,7 +244,7 @@ where } pub fn focus(&mut self, window: &mut Window, cx: &mut App) { - self.focus_handle(cx).focus(window); + self.focus_handle(cx).focus(window, cx); } /// Set the selected index of the list, this will also scroll to the selected item. diff --git a/crates/ui/src/menu/app_menu_bar.rs b/crates/ui/src/menu/app_menu_bar.rs index c51f677..9548a49 100644 --- a/crates/ui/src/menu/app_menu_bar.rs +++ b/crates/ui/src/menu/app_menu_bar.rs @@ -145,7 +145,7 @@ impl AppMenu { }) .with_menu_items(items, window, cx) }); - popup_menu.read(cx).focus_handle(cx).focus(window); + popup_menu.read(cx).focus_handle(cx).focus(window, cx); self._subscription = Some(cx.subscribe_in(&popup_menu, window, Self::handle_dismiss)); self.popup_menu = Some(popup_menu.clone()); @@ -157,7 +157,7 @@ impl AppMenu { let focus_handle = popup_menu.read(cx).focus_handle(cx); if !focus_handle.contains_focused(window, cx) { - focus_handle.focus(window); + focus_handle.focus(window, cx); } popup_menu diff --git a/crates/ui/src/menu/context_menu.rs b/crates/ui/src/menu/context_menu.rs index 3848f9f..a371e84 100644 --- a/crates/ui/src/menu/context_menu.rs +++ b/crates/ui/src/menu/context_menu.rs @@ -156,7 +156,7 @@ impl Element for ContextMenu { .when_some(menu_view, |this, menu| { // Focus the menu, so that can be handle the action. if !menu.focus_handle(cx).contains_focused(window, cx) { - menu.focus_handle(cx).focus(window); + menu.focus_handle(cx).focus(window, cx); } this.child(div().occlude().child(menu.clone())) diff --git a/crates/ui/src/menu/popup_menu.rs b/crates/ui/src/menu/popup_menu.rs index 61d1ba5..7e08e52 100644 --- a/crates/ui/src/menu/popup_menu.rs +++ b/crates/ui/src/menu/popup_menu.rs @@ -659,7 +659,7 @@ impl PopupMenu { cx: &mut Context, ) { if let Some(context) = self.action_context.as_ref() { - context.focus(window); + context.focus(window, cx); } window.dispatch_action(action.boxed_clone(), cx); @@ -759,7 +759,7 @@ impl PopupMenu { // Focus the submenu, so that can be handle the action. active_submenu.update(cx, |view, cx| { view.set_selected_index(0, cx); - view.focus_handle.focus(window); + view.focus_handle.focus(window, cx); }); cx.notify(); return true; @@ -790,7 +790,7 @@ impl PopupMenu { self.selected_index = None; parent.update(cx, |view, cx| { - view.focus_handle.focus(window); + view.focus_handle.focus(window, cx); cx.notify(); }); } @@ -819,7 +819,7 @@ impl PopupMenu { // Focus back to the previous focused handle. if let Some(action_context) = self.action_context.as_ref() { - window.focus(action_context); + window.focus(action_context, cx); } let Some(parent_menu) = self.parent_menu.clone() else { diff --git a/crates/ui/src/modal.rs b/crates/ui/src/modal.rs index 16c4570..6678b88 100644 --- a/crates/ui/src/modal.rs +++ b/crates/ui/src/modal.rs @@ -342,7 +342,7 @@ impl RenderOnce for Modal { }); let window_paddings = crate::window_border::window_paddings(window, cx); - let radius = (cx.theme().radius * 2.).min(px(20.)); + let radius = (cx.theme().radius_lg * 2.).min(px(20.)); let view_size = window.viewport_size() - gpui::size( @@ -407,7 +407,7 @@ impl RenderOnce for Modal { .border_1() .border_color(cx.theme().border.alpha(0.4)) .rounded(radius) - .shadow_xl() + .when(cx.theme().shadow, |this| this.shadow_xl()) .min_h_24() .key_context(CONTEXT) .track_focus(&self.focus_handle) diff --git a/crates/ui/src/notification.rs b/crates/ui/src/notification.rs index bdb74f5..8c8b2e4 100644 --- a/crates/ui/src/notification.rs +++ b/crates/ui/src/notification.rs @@ -295,8 +295,8 @@ impl Render for Notification { .border_1() .border_color(cx.theme().border) .bg(cx.theme().surface_background) - .rounded(cx.theme().radius * 1.6) - .shadow_md() + .rounded(cx.theme().radius_lg) + .when(cx.theme().shadow, |this| this.shadow_md()) .p_2() .gap_3() .justify_start() diff --git a/crates/ui/src/popover.rs b/crates/ui/src/popover.rs index c142e12..df42c93 100644 --- a/crates/ui/src/popover.rs +++ b/crates/ui/src/popover.rs @@ -445,7 +445,7 @@ impl Element for Popover { if let Some(previous_focus_handle) = previous_focus_handle.as_ref() { - window.focus(previous_focus_handle); + window.focus(previous_focus_handle, cx); } } *old_content_view1.borrow_mut() = None; @@ -455,7 +455,7 @@ impl Element for Popover { ) .detach(); - window.focus(&new_content_view.focus_handle(cx)); + window.focus(&new_content_view.focus_handle(cx), cx); *old_content_view.borrow_mut() = Some(new_content_view); window.refresh(); } diff --git a/crates/ui/src/root.rs b/crates/ui/src/root.rs index 96ddfe3..3dbddbc 100644 --- a/crates/ui/src/root.rs +++ b/crates/ui/src/root.rs @@ -60,7 +60,7 @@ impl ContextModal for Window { } let focus_handle = cx.focus_handle(); - focus_handle.focus(window); + focus_handle.focus(window, cx); root.active_modals.push(ActiveModal { focus_handle, @@ -81,7 +81,7 @@ impl ContextModal for Window { if let Some(top_modal) = root.active_modals.last() { // Focus the next modal. - top_modal.focus_handle.focus(window); + top_modal.focus_handle.focus(window, cx); } else { // Restore focus if there are no more modals. root.focus_back(window, cx); @@ -188,9 +188,9 @@ impl Root { .read(cx) } - fn focus_back(&mut self, window: &mut Window, _: &mut App) { + fn focus_back(&mut self, window: &mut Window, cx: &mut App) { if let Some(handle) = self.previous_focus_handle.clone() { - window.focus(&handle); + window.focus(&handle, cx); } } diff --git a/crates/ui/src/scroll/scrollbar.rs b/crates/ui/src/scroll/scrollbar.rs index cd0b48c..394dff7 100644 --- a/crates/ui/src/scroll/scrollbar.rs +++ b/crates/ui/src/scroll/scrollbar.rs @@ -9,7 +9,6 @@ use gpui::{ IntoElement, LayoutId, MouseDownEvent, MouseMoveEvent, MouseUpEvent, PaintQuad, Pixels, Point, Position, ScrollHandle, ScrollWheelEvent, Size, UniformListScrollHandle, Window, }; -use theme::scrollbar_mode::ScrollBarMode; use theme::ActiveTheme; use crate::AxisExt; @@ -355,9 +354,10 @@ impl Scrollbar { } fn style_for_idle(cx: &App) -> (Hsla, Hsla, Hsla, Pixels, Pixels, Pixels) { - let (width, inset, radius) = match cx.theme().scrollbar_mode { - ScrollBarMode::Scrolling => (THUMB_WIDTH, THUMB_INSET, THUMB_RADIUS), - _ => (THUMB_ACTIVE_WIDTH, THUMB_ACTIVE_INSET, THUMB_ACTIVE_RADIUS), + let (width, inset, radius) = if cx.theme().scrollbar_mode.is_scrolling() { + (THUMB_WIDTH, THUMB_INSET, THUMB_RADIUS) + } else { + (THUMB_ACTIVE_WIDTH, THUMB_ACTIVE_INSET, THUMB_ACTIVE_RADIUS) }; ( diff --git a/crates/ui/src/styled.rs b/crates/ui/src/styled.rs index 82e388d..8e40768 100644 --- a/crates/ui/src/styled.rs +++ b/crates/ui/src/styled.rs @@ -78,7 +78,7 @@ pub trait StyledExt: Styled + Sized { .border_1() .border_color(cx.theme().border) .shadow_lg() - .rounded_lg() + .rounded(cx.theme().radius_lg) } } diff --git a/crates/ui/src/switch.rs b/crates/ui/src/switch.rs index 36895d2..467d1d6 100644 --- a/crates/ui/src/switch.rs +++ b/crates/ui/src/switch.rs @@ -181,7 +181,7 @@ impl Element for Switch { // Switch Toggle div() .rounded_full() - .shadow_sm() + .when(cx.theme().shadow, |this| this.shadow_sm()) .bg(toggle_bg) .size(bar_width) .map(|this| { diff --git a/crates/ui/src/tab/mod.rs b/crates/ui/src/tab/mod.rs index 906d020..572b7d8 100644 --- a/crates/ui/src/tab/mod.rs +++ b/crates/ui/src/tab/mod.rs @@ -115,7 +115,7 @@ impl RenderOnce for Tab { .text_ellipsis() .text_color(text_color) .bg(bg_color) - .rounded(cx.theme().radius) + .rounded(cx.theme().radius_lg) .hover(|this| this.bg(hover_bg_color)) .when_some(self.prefix, |this, prefix| { this.child(prefix).text_color(text_color) diff --git a/crates/ui/src/tooltip.rs b/crates/ui/src/tooltip.rs index e71b395..12035e0 100644 --- a/crates/ui/src/tooltip.rs +++ b/crates/ui/src/tooltip.rs @@ -1,3 +1,4 @@ +use gpui::prelude::FluentBuilder; use gpui::{ div, relative, App, AppContext, Context, Entity, IntoElement, ParentElement, Render, SharedString, Styled, Window, @@ -24,8 +25,8 @@ impl Render for Tooltip { .border_1() .border_color(cx.theme().border) .bg(cx.theme().surface_background) - .shadow_md() - .rounded_lg() + .when(cx.theme().shadow, |this| this.shadow_md()) + .rounded(cx.theme().radius_lg) .text_sm() .text_color(cx.theme().text_muted) .line_height(relative(1.25))