Settings: an accent palette folds inside a narrow box

The accent picker's palette takes what the custom well leaves and folds
its swatches; a test puts twelve presets in a 280px box and asserts
they fold under each other inside it. The settings tests split their
appearance cases into a file of their own. AGENTS says editing takes
the owner's handler itself.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ZacharyZhang-NYandClaude Opus 5.5 committed 2026-09-27 13:03:55 -04:00
1 parent 9a8dbcb92e
commit 6e5a742148
5 files changed
+81 -43

No files matched your search

+9 -6
View File
@@ -1,8 +1,8 @@
use std::rc::Rc;
use gpui::{
App, ElementId, Hsla, IntoElement, ParentElement, Pixels, RenderOnce, SharedString, Styled,
Window, div,
App, ElementId, Hsla, InteractiveElement, IntoElement, ParentElement, Pixels, RenderOnce,
SharedString, Styled, Window, div,
};
use crate::{
@@ -140,14 +140,17 @@ impl RenderOnce for AccentColorPicker {
};
let columns = u16::try_from(self.presets.len()).expect("a handful of presets");
div()
.debug_selector(|| "accent-color-picker".into())
.flex()
.items_start()
.gap_2()
.child(
ColorPalette::new((self.id.clone(), "presets"), self.presets)
.columns(columns)
.selected(self.color)
.on_change(report(picked)),
div().flex_1().min_w_0().child(
ColorPalette::new((self.id.clone(), "presets"), self.presets)
.columns(columns)
.selected(self.color)
.on_change(report(picked)),
),
)
.child(color_well(
(self.id, "custom").into(),
+63
View File
@@ -0,0 +1,63 @@
use gpui::{
AnyElement, App, Entity, IntoElement, ParentElement, Styled, TestAppContext, Window, div, hsla,
px,
};
use super::{Desk, desk, said, say, tab, tap};
use crate::settings::{AccentColorPicker, FontSizeControl};
fn accent(_: &mut Window, _: &mut App, owner: Entity<Desk>) -> AnyElement {
let (red, blue) = (hsla(0.0, 0.6, 0.5, 1.0), hsla(0.6, 0.6, 0.5, 1.0));
AccentColorPicker::new("accent", red, [("Red", red), ("Blue", blue)])
.on_change(move |color, _, cx| say(&owner, format!("blue {}", color == blue), cx))
.into_any_element()
}
/// Stops: the presets, Red then Blue, then the custom well.
#[gpui::test]
fn a_preset_sets_the_accent(cx: &mut TestAppContext) {
let (host, cx) = desk(accent, cx);
tab(2, cx);
tap("space", cx);
assert_eq!(said(&host, cx), ["blue true"]);
}
fn default_size(_: &mut Window, _: &mut App, owner: Entity<Desk>) -> AnyElement {
FontSizeControl::new("size", 14.0, 14.0, (12.0, 24.0))
.on_change(move |size, _, cx| say(&owner, format!("size {size}"), cx))
.into_any_element()
}
/// At the default size the way back rests, so the second stop wraps to the slider.
#[gpui::test]
fn the_way_back_rests_at_the_default_size(cx: &mut TestAppContext) {
let (host, cx) = desk(default_size, cx);
tab(2, cx);
tap("space", cx);
assert!(said(&host, cx).is_empty());
}
fn many_presets(_: &mut Window, _: &mut App, _: Entity<Desk>) -> AnyElement {
let presets: Vec<(String, gpui::Hsla)> = (0..12)
.map(|ix| (format!("hue {ix}"), hsla(ix as f32 / 12.0, 0.5, 0.5, 1.0)))
.collect();
div()
.w(px(280.0))
.child(AccentColorPicker::new("accent", presets[0].1, presets).on_change(|_, _, _| {}))
.into_any_element()
}
/// Twelve swatches do not fit in one 280px row, so they fold under each other inside the box.
#[gpui::test]
fn many_presets_fold_inside_a_narrow_box(cx: &mut TestAppContext) {
let (_, cx) = desk(many_presets, cx);
let picker = cx.debug_bounds("accent-color-picker").expect("the picker");
assert!(
picker.size.width <= px(280.0),
"no wider than its box: {picker:?}"
);
assert!(
picker.size.height > px(40.0),
"its swatches fold to a second row: {picker:?}"
);
}
@@ -1,13 +1,13 @@
use gpui::{
AnyElement, App, Context, Entity, IntoElement, KeyBinding, ParentElement, Render, Styled,
TestAppContext, VisualTestContext, Window, div, hsla, px,
TestAppContext, VisualTestContext, Window, div, px,
};
use super::{
AccentColorPicker, Appearance, Changed, DeveloperModeToggle, FeatureFlags, Flag,
FontSizeControl, ImportExportSettings, Notices, NotificationSettings, Privacy, PrivacySettings,
Proxy, ProxySettings, ResetToDefault, SettingEntry, SettingsLayout, SettingsSearch, Stage,
Startup, StartupSettings, StorageSettings, Store, ThemeSelector,
Appearance, Changed, DeveloperModeToggle, FeatureFlags, Flag, FontSizeControl,
ImportExportSettings, Notices, NotificationSettings, Privacy, PrivacySettings, Proxy,
ProxySettings, ResetToDefault, SettingEntry, SettingsLayout, SettingsSearch, Stage, Startup,
StartupSettings, StorageSettings, Store, ThemeSelector,
};
use crate::{
forms::{self, Choice, TextInput},
@@ -306,22 +306,6 @@ fn the_arrows_open_the_next_section(cx: &mut TestAppContext) {
assert_eq!(said(&host, cx), ["open b"]);
}
fn accent(_: &mut Window, _: &mut App, owner: Entity<Desk>) -> AnyElement {
let (red, blue) = (hsla(0.0, 0.6, 0.5, 1.0), hsla(0.6, 0.6, 0.5, 1.0));
AccentColorPicker::new("accent", red, [("Red", red), ("Blue", blue)])
.on_change(move |color, _, cx| say(&owner, format!("blue {}", color == blue), cx))
.into_any_element()
}
/// Stops: the presets, Red then Blue, then the custom well.
#[gpui::test]
fn a_preset_sets_the_accent(cx: &mut TestAppContext) {
let (host, cx) = desk(accent, cx);
tab(2, cx);
tap("space", cx);
assert_eq!(said(&host, cx), ["blue true"]);
}
fn privacy(_: &mut Window, _: &mut App, owner: Entity<Desk>) -> AnyElement {
let privacy = Privacy {
telemetry: true,
@@ -455,21 +439,6 @@ fn apply_rests_while_the_port_is_bad(cx: &mut TestAppContext) {
assert!(said(&host, cx).is_empty());
}
fn default_size(_: &mut Window, _: &mut App, owner: Entity<Desk>) -> AnyElement {
FontSizeControl::new("size", 14.0, 14.0, (12.0, 24.0))
.on_change(move |size, _, cx| say(&owner, format!("size {size}"), cx))
.into_any_element()
}
/// At the default size the way back rests, so the second stop wraps to the slider.
#[gpui::test]
fn the_way_back_rests_at_the_default_size(cx: &mut TestAppContext) {
let (host, cx) = desk(default_size, cx);
tab(2, cx);
tap("space", cx);
assert!(said(&host, cx).is_empty());
}
/// Stops: Do not disturb, then App, which is on.
#[gpui::test]
fn a_box_pressed_off_lets_its_pair_go(cx: &mut TestAppContext) {
@@ -478,3 +447,5 @@ fn a_box_pressed_off_lets_its_pair_go(cx: &mut TestAppContext) {
tap("space", cx);
assert_eq!(said(&host, cx), ["[] false"]);
}
mod appearance;