feat(settings): schema-driven settings engine (T-448)
The core of the settings panel (epic T-444). Subsystems describe a category as data — a SettingsCategory of carded SettingsSections of SettingsFields (toggle / select / text / number / opens-external-file), each bound to a SettingsStore key with help text, a default, and reset-to-default. Registration is declarative: a new SettingsCategoryContribution carries the category; the extension manager routes it into a new kernel SettingsRegistry (exposed on KernelServices), which the panel reads via ClideKernel. Adding a category is now pure data + a contribution — no widget code. SettingsCategoryView renders a category into carded sections per ui-design surface.md: panelHeader card fill, dividerColor border, inputs receding to panelBackground; select reuses the anchored-overlay menu, text/number commit on Enter or blur (numeric clamps to bounds). The modal panel now shows the selected/first registered category, falling back to the empty state. Tests: registry (sort / dedup / notify), contribution routing on activation, renderer (render + toggle/select write-through + reset), modal-with-category. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,7 @@ import 'package:clide/kernel/src/panels/registry.dart';
|
||||
import 'package:clide/kernel/src/project.dart';
|
||||
import 'package:clide/kernel/src/secrets.dart';
|
||||
import 'package:clide/kernel/src/settings.dart';
|
||||
import 'package:clide/kernel/src/settings_registry.dart';
|
||||
import 'package:clide/kernel/src/theme/controller.dart';
|
||||
import 'package:clide/kernel/src/tray.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
@@ -55,6 +56,7 @@ class ExtensionManager extends ChangeNotifier {
|
||||
required this.focus,
|
||||
required this.project,
|
||||
required this.ipc,
|
||||
required this.settingsRegistry,
|
||||
});
|
||||
|
||||
final Logger log;
|
||||
@@ -81,6 +83,7 @@ class ExtensionManager extends ChangeNotifier {
|
||||
final FocusTracker focus;
|
||||
final ProjectManager project;
|
||||
final DaemonClient ipc;
|
||||
final SettingsRegistry settingsRegistry;
|
||||
|
||||
final Map<String, ClideExtension> _known = {};
|
||||
final Set<String> _activated = {};
|
||||
@@ -256,6 +259,9 @@ class ExtensionManager extends ChangeNotifier {
|
||||
// Presets are consumed by the default-layout extension in its
|
||||
// own activate(); nothing for the kernel to do here.
|
||||
break;
|
||||
case SettingsCategoryContribution s:
|
||||
// register() throws on a duplicate id, rolling activation back.
|
||||
settingsRegistry.register(s.category);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,6 +282,8 @@ class ExtensionManager extends ChangeNotifier {
|
||||
tray.remove(t.id);
|
||||
case LayoutPresetContribution _:
|
||||
break;
|
||||
case SettingsCategoryContribution s:
|
||||
settingsRegistry.unregister(s.category.id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user