Files
clide/lib/kernel/src/settings_control_registry.dart
T
jpmschweitzerandClaude Opus 4.8 757d6f71fa feat(settings): Appearance category + custom-control escape hatch (T-452)
Add the one bespoke control the schema engine defers to. New
SettingsControlContribution routes a WidgetBuilder into a kernel
SettingsControlRegistry under a customId; a SettingsFieldKind.custom field
names that id, and the renderer draws the registered widget full-width
(label on top, no scope tag — the control owns its own apply + scope).

The theme-picker extension uses it: an Appearance category whose theme field
is custom, backed by AppearanceThemeControl — base-theme chips + a
high-contrast toggle that apply live through ThemeController (persisted by
theme_persistence). Reuses the shared theme_families helpers.

Tests: control registry (register/dup/unregister), the renderer's custom-field
path, and the Appearance contribution + live theme apply.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 13:04:52 +02:00

27 lines
1.1 KiB
Dart

import 'package:flutter/widgets.dart';
/// Holds the bespoke widgets that draw [SettingsFieldKind.custom] fields
/// (T-452). A subsystem registers a builder under a `customId` (via
/// `SettingsControlContribution`, routed by the extension manager); the
/// settings renderer looks it up when it meets a custom field.
///
/// Controls register at activation, before any settings modal opens, so this
/// is a plain registry — no change notification needed.
class SettingsControlRegistry {
final Map<String, WidgetBuilder> _byId = <String, WidgetBuilder>{};
/// Register the [builder] for [customId]. Throws on a duplicate id so a
/// collision rolls the contributing extension's activation back.
void register(String customId, WidgetBuilder builder) {
if (_byId.containsKey(customId)) {
throw StateError('duplicate settings control id: $customId');
}
_byId[customId] = builder;
}
void unregister(String customId) => _byId.remove(customId);
/// The builder for [customId], or null when none is registered.
WidgetBuilder? builderFor(String customId) => _byId[customId];
}