tidy the theme switcher popover (T-237)

Per demo feedback on the T-234 status-bar popover: collapse the -hc
theme rows into a single 'High contrast' toggle at the top (applies the
chosen base theme's -hc sibling live, falling back to the base when none
exists); list base themes only, sorted by display name; widen 240->280
and ellipsize rows so 'Catppuccin Mocha' no longer wraps; swap the swatch
dot for the Phosphor palette icon; lowercase the bar label to match the
all-lowercase status bar (proper case kept in the a11y label).

New pure theme_families helpers (base/sibling/resolve), unit-tested.
Modal picker_view consistency + the status-bar right-alignment remain on
T-237.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-03 22:46:17 +02:00
co-authored by Claude Opus 4.8
parent fb29254851
commit 5fcc42bd8c
6 changed files with 214 additions and 35 deletions
@@ -140,6 +140,23 @@ void main() {
expect(find.bySemanticsLabel('forest'), findsNothing);
});
testWidgets('popover hides -hc rows; the High contrast toggle applies the sibling (T-237)', (tester) async {
final f2 = await KernelFixture.create(bundledThemes: [_def('midnight'), _def('midnight-hc')]);
addTearDown(f2.dispose);
await tester.pumpWidget(harness(f2, const ThemeSwitcherStatusItem()));
await tester.pump();
await tester.tap(find.bySemanticsLabel('Theme: midnight'));
await tester.pumpAndSettle();
// Base shown, -hc row hidden, toggle present.
expect(find.text('midnight'), findsOneWidget);
expect(find.text('midnight-hc'), findsNothing);
expect(find.text('High contrast'), findsOneWidget);
// Toggling high contrast applies the -hc sibling live.
await tester.tap(find.bySemanticsLabel('High contrast'));
await tester.pumpAndSettle();
expect(f2.services.theme.currentName, 'midnight-hc');
});
testWidgets('Esc dismisses the popover without changing the theme (T-234)', (tester) async {
await tester.pumpWidget(harness(f, const ThemeSwitcherStatusItem()));
await tester.pump();