feat(settings): category rail + navigation (T-447)
The settings modal's left rail now lists the registered categories (icon + title, data-driven from the SettingsRegistry) with an accent left-stripe + surfaceHi selection per ui-design surface.md. Selecting a category drives the modal's selection state and swaps the right panel; the rail scrolls when the set exceeds the height. The cross-category search box atop the rail lands in T-450. Tests: rail lists categories and selecting one swaps the panel. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,17 @@ const _category = SettingsCategory(
|
||||
],
|
||||
);
|
||||
|
||||
const _other = SettingsCategory(
|
||||
id: 'other',
|
||||
title: 'Other',
|
||||
sections: [
|
||||
SettingsSection(
|
||||
label: 'Misc',
|
||||
fields: [SettingsField(key: 'app.other.x', kind: SettingsFieldKind.toggle, label: 'OtherFlag', defaultValue: false)],
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
/// Tiny extension that registers [_category] via the contribution.
|
||||
class _DemoSettingsExt extends ClideExtension {
|
||||
@override
|
||||
@@ -109,5 +120,21 @@ void main() {
|
||||
expect(find.text('Flag'), findsOneWidget);
|
||||
expect(find.text('No settings categories are registered yet.'), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('rail lists categories and selecting one swaps the panel', (tester) async {
|
||||
f.services.settingsRegistry.register(_category);
|
||||
f.services.settingsRegistry.register(_other);
|
||||
await tester.pumpWidget(harness(f, SettingsModal(onDismiss: () {})));
|
||||
// Rail shows both titles; first (alphabetical) category's panel is shown.
|
||||
expect(find.text('Demo'), findsOneWidget);
|
||||
expect(find.text('Other'), findsOneWidget);
|
||||
expect(find.text('Flag'), findsOneWidget);
|
||||
expect(find.text('OtherFlag'), findsNothing);
|
||||
// Selecting the second category swaps the panel.
|
||||
await tester.tap(find.text('Other'));
|
||||
await tester.pump();
|
||||
expect(find.text('OtherFlag'), findsOneWidget);
|
||||
expect(find.text('Flag'), findsNothing);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user