wire design palette through resolver with fallback chains
Surface map now tries palette keys (bgSunken, surfaceHi, textHi, etc.) first, falling back to semantic refs for legacy themes. Sidebar/panel bg differentiates from workspace bg. Buttons use accent colour with onAccent text. Four-level text gradient flows to widgets. WCAG-AA contrast fixes: clide textDim lightened, midnight onAccent darkened, paper textDim darkened. Contrast test updated to cover all four themes. Resolver tests updated for the new palette shape. Goldens regenerated. Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,41 @@ void main() {
|
||||
Palette paletteOf(Map<String, Color> colors) => Palette(colors);
|
||||
|
||||
group('ThemeResolver default fallbacks', () {
|
||||
test('palette-only summer-night shape resolves every token', () {
|
||||
test('design-shape palette resolves every token', () {
|
||||
final tokens = resolver.resolve(
|
||||
palette: paletteOf(const {
|
||||
'bg': Color(0xFF20202C),
|
||||
'bgSunken': Color(0xFF1A1A24),
|
||||
'surface': Color(0xFF242838),
|
||||
'surfaceHi': Color(0xFF2C3046),
|
||||
'border': Color(0xFF343850),
|
||||
'borderHi': Color(0xFF3C445C),
|
||||
'textHi': Color(0xFFE6E8F2),
|
||||
'text': Color(0xFFB1BBE3),
|
||||
'textDim': Color(0xFF78809C),
|
||||
'textMute': Color(0xFF545C84),
|
||||
'accent': Color(0xFF78A0F8),
|
||||
'accentPress': Color(0xFF6C90DC),
|
||||
'accentSoft': Color(0x2178A0F8),
|
||||
'onAccent': Color(0xFF0D1020),
|
||||
'ok': Color(0xFF7DD3A8),
|
||||
'warn': Color(0xFFE6C370),
|
||||
'err': Color(0xFFE87D7D),
|
||||
'info': Color(0xFF78A0F8),
|
||||
}),
|
||||
);
|
||||
expect(tokens.globalBackground, const Color(0xFF20202C));
|
||||
expect(tokens.globalForeground, const Color(0xFFE6E8F2));
|
||||
expect(tokens.panelBackground, const Color(0xFF1A1A24));
|
||||
expect(tokens.sidebarItemSelected, const Color(0xFF2C3046));
|
||||
expect(tokens.statusSuccess, const Color(0xFF7DD3A8));
|
||||
expect(tokens.statusError, const Color(0xFFE87D7D));
|
||||
expect(tokens.globalTextMuted, const Color(0xFF78809C));
|
||||
expect(tokens.buttonBackground, const Color(0xFF78A0F8));
|
||||
expect(tokens.buttonForeground, const Color(0xFF0D1020));
|
||||
});
|
||||
|
||||
test('legacy palette keys still resolve via fallback chains', () {
|
||||
final tokens = resolver.resolve(
|
||||
palette: paletteOf(const {
|
||||
'primary': Color(0xFF00A3D2),
|
||||
@@ -28,27 +62,8 @@ void main() {
|
||||
expect(tokens.globalBackground, const Color(0xFF21262F));
|
||||
expect(tokens.globalForeground, const Color(0xFFE2E8F5));
|
||||
expect(tokens.panelBackground, const Color(0xFF292E38));
|
||||
expect(tokens.sidebarItemSelected, const Color(0xFF00A3D2));
|
||||
expect(tokens.statusSuccess, const Color(0xFF00AB9A));
|
||||
expect(tokens.statusError, const Color(0xFFF06C6F));
|
||||
expect(tokens.globalTextMuted, const Color(0xFF6A7280));
|
||||
});
|
||||
|
||||
test('missing "muted" falls back to foreground', () {
|
||||
final tokens = resolver.resolve(
|
||||
palette: paletteOf(const {
|
||||
'primary': Color(0xFF111111),
|
||||
'accent': Color(0xFF222222),
|
||||
'background': Color(0xFF333333),
|
||||
'surface': Color(0xFF444444),
|
||||
'panel': Color(0xFF555555),
|
||||
'foreground': Color(0xFFEEEEEE),
|
||||
'success': Color(0xFF008800),
|
||||
'warning': Color(0xFFFF8800),
|
||||
'error': Color(0xFFFF0000),
|
||||
}),
|
||||
);
|
||||
expect(tokens.globalTextMuted, const Color(0xFFEEEEEE));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -56,15 +71,16 @@ void main() {
|
||||
test('surface override wins over default', () {
|
||||
final tokens = resolver.resolve(
|
||||
palette: paletteOf(const {
|
||||
'primary': Color(0xFF111111),
|
||||
'accent': Color(0xFF222222),
|
||||
'background': Color(0xFF333333),
|
||||
'bg': Color(0xFF333333),
|
||||
'bgSunken': Color(0xFF222222),
|
||||
'surface': Color(0xFF444444),
|
||||
'panel': Color(0xFF555555),
|
||||
'foreground': Color(0xFFFFFFFF),
|
||||
'success': Color(0xFF008800),
|
||||
'warning': Color(0xFFFF8800),
|
||||
'error': Color(0xFFFF0000),
|
||||
'border': Color(0xFF555555),
|
||||
'textHi': Color(0xFFFFFFFF),
|
||||
'accent': Color(0xFF111111),
|
||||
'ok': Color(0xFF008800),
|
||||
'warn': Color(0xFFFF8800),
|
||||
'err': Color(0xFFFF0000),
|
||||
'info': Color(0xFF111111),
|
||||
}),
|
||||
surfaceOverride: const {
|
||||
'panel.background': '#00FF00',
|
||||
@@ -73,36 +89,38 @@ void main() {
|
||||
expect(tokens.panelBackground, const Color(0xFF00FF00));
|
||||
});
|
||||
|
||||
test('semantic override propagates to surface tokens using it', () {
|
||||
test('semantic override propagates when palette key is absent', () {
|
||||
final tokens = resolver.resolve(
|
||||
palette: paletteOf(const {
|
||||
'primary': Color(0xFF111111),
|
||||
'accent': Color(0xFF222222),
|
||||
'background': Color(0xFF333333),
|
||||
'bg': Color(0xFF333333),
|
||||
'bgSunken': Color(0xFF222222),
|
||||
'surface': Color(0xFF444444),
|
||||
'panel': Color(0xFF555555),
|
||||
'foreground': Color(0xFFFFFFFF),
|
||||
'success': Color(0xFF008800),
|
||||
'warning': Color(0xFFFF8800),
|
||||
'error': Color(0xFFFF0000),
|
||||
'teal': Color(0xFF007777),
|
||||
'surfaceHi': Color(0xFF555555),
|
||||
'border': Color(0xFF666666),
|
||||
'textHi': Color(0xFFFFFFFF),
|
||||
'ok': Color(0xFF008800),
|
||||
'warn': Color(0xFFFF8800),
|
||||
'err': Color(0xFFFF0000),
|
||||
'info': Color(0xFF111111),
|
||||
}),
|
||||
semanticOverride: const SemanticRoles({
|
||||
'focus': Color(0xFF007777),
|
||||
}),
|
||||
);
|
||||
// sidebarItemSelected defaults to semantic.focus — expect override.
|
||||
expect(tokens.sidebarItemSelected, const Color(0xFF007777));
|
||||
// No 'accent' in palette, so globalFocus falls through to
|
||||
// semantic.focus which is overridden.
|
||||
expect(tokens.globalFocus, const Color(0xFF007777));
|
||||
});
|
||||
|
||||
test('extensionOverride populates extensionTokens map', () {
|
||||
final tokens = resolver.resolve(
|
||||
palette: paletteOf(const {
|
||||
'primary': Color(0xFF111111),
|
||||
'background': Color(0xFF333333),
|
||||
'bg': Color(0xFF333333),
|
||||
'bgSunken': Color(0xFF222222),
|
||||
'surface': Color(0xFF444444),
|
||||
'panel': Color(0xFF555555),
|
||||
'foreground': Color(0xFFFFFFFF),
|
||||
'border': Color(0xFF555555),
|
||||
'textHi': Color(0xFFFFFFFF),
|
||||
'accent': Color(0xFF111111),
|
||||
}),
|
||||
extensionOverride: const {
|
||||
'ext.sqlite.table.background': '#ABCDEF',
|
||||
|
||||
Reference in New Issue
Block a user