onboarding: Expand power of theme selector (#35421)

Closes #ISSUE

The behavior of the theme selector is documented above the function,
copied here for reference:
```rust
/// separates theme "mode" ("dark" | "light" | "system") into two separate states
/// - appearance = "dark" | "light"
/// - "system" true/false
/// when system selected:
///  - toggling between light and dark does not change theme.mode, just which variant will be changed
/// when system not selected:
///  - toggling between light and dark does change theme.mode
/// selecting a theme preview will always change theme.["light" | "dark"] to the selected theme,
///
/// this allows for selecting a dark and light theme option regardless of whether the mode is set to system or not
/// it does not support setting theme to a static value
```

Release Notes:

- N/A *or* Added/Fixed/Improved ...
This commit is contained in:
Ben Kunkle 2025-07-31 15:21:58 -05:00 committed by GitHub
parent c6947ee4f0
commit c946b98ea1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 254 additions and 173 deletions

View file

@ -13,8 +13,10 @@ use schemars::JsonSchema;
use serde::Deserialize;
use settings::{SettingsStore, VsCodeSettingsSource};
use std::sync::Arc;
use theme::{Theme, ThemeRegistry};
use ui::{Avatar, FluentBuilder, KeyBinding, Vector, VectorName, prelude::*, rems_from_px};
use ui::{
Avatar, FluentBuilder, Headline, KeyBinding, ParentElement as _, StatefulInteractiveElement,
Vector, VectorName, prelude::*, rems_from_px,
};
use workspace::{
AppState, Workspace, WorkspaceId,
dock::DockPosition,
@ -25,6 +27,7 @@ use workspace::{
mod basics_page;
mod editing_page;
mod theme_preview;
mod welcome;
pub struct OnBoardingFeatureFlag {}
@ -219,11 +222,8 @@ enum SelectedPage {
struct Onboarding {
workspace: WeakEntity<Workspace>,
light_themes: [Arc<Theme>; 3],
dark_themes: [Arc<Theme>; 3],
focus_handle: FocusHandle,
selected_page: SelectedPage,
fs: Arc<dyn Fs>,
user_store: Entity<UserStore>,
_settings_subscription: Subscription,
}
@ -234,36 +234,11 @@ impl Onboarding {
user_store: Entity<UserStore>,
cx: &mut App,
) -> Entity<Self> {
let theme_registry = ThemeRegistry::global(cx);
let one_dark = theme_registry
.get("One Dark")
.expect("Default themes are always present");
let ayu_dark = theme_registry
.get("Ayu Dark")
.expect("Default themes are always present");
let gruvbox_dark = theme_registry
.get("Gruvbox Dark")
.expect("Default themes are always present");
let one_light = theme_registry
.get("One Light")
.expect("Default themes are always present");
let ayu_light = theme_registry
.get("Ayu Light")
.expect("Default themes are always present");
let gruvbox_light = theme_registry
.get("Gruvbox Light")
.expect("Default themes are always present");
cx.new(|cx| Self {
workspace,
user_store,
focus_handle: cx.focus_handle(),
light_themes: [one_light, ayu_light, gruvbox_light],
dark_themes: [one_dark, ayu_dark, gruvbox_dark],
selected_page: SelectedPage::Basics,
fs: <dyn Fs>::global(cx),
_settings_subscription: cx.observe_global::<SettingsStore>(move |_, cx| cx.notify()),
})
}
@ -411,7 +386,7 @@ impl Onboarding {
fn render_page(&mut self, window: &mut Window, cx: &mut Context<Self>) -> AnyElement {
match self.selected_page {
SelectedPage::Basics => {
crate::basics_page::render_basics_page(&self, cx).into_any_element()
crate::basics_page::render_basics_page(window, cx).into_any_element()
}
SelectedPage::Editing => {
crate::editing_page::render_editing_page(window, cx).into_any_element()