diff --git a/packages/core/src/theme/themeRegistry.ts b/packages/core/src/theme/themeRegistry.ts new file mode 100644 index 000000000..95ac04d15 --- /dev/null +++ b/packages/core/src/theme/themeRegistry.ts @@ -0,0 +1,66 @@ +export interface ColorPalette { + primary: string; + secondary: string; + background: string; + text: string; + border?: string; + accent?: string; +} + +export interface ThemeDefinition { + name: string; + palette: ColorPalette; +} + +/** + * ThemeRegistryManager - Extensible Color Palette & Dynamic Theme Registry Subsystem (#3334). + */ +export class ThemeRegistryManager { + private themes: Map = new Map(); + private activeThemeName: string = 'default'; + + constructor() { + this.registerTheme({ + name: 'default', + palette: { + primary: '#3b82f6', + secondary: '#64748b', + background: '#0f172a', + text: '#f8fafc', + border: '#334155', + accent: '#eab308', + }, + }); + } + + registerTheme(theme: ThemeDefinition): void { + if (!theme || !theme.name) return; + this.themes.set(theme.name, theme); + } + + setActiveTheme(name: string): boolean { + if (this.themes.has(name)) { + this.activeThemeName = name; + return true; + } + return false; + } + + getActiveTheme(): ThemeDefinition { + return this.themes.get(this.activeThemeName) || Array.from(this.themes.values())[0]; + } + + extendPalette(themeName: string, customPalette: Partial): void { + const existing = this.themes.get(themeName); + if (existing) { + existing.palette = { + ...existing.palette, + ...customPalette, + }; + } + } + + listThemes(): string[] { + return Array.from(this.themes.keys()); + } +} diff --git a/packages/core/test/themeRegistry.test.ts b/packages/core/test/themeRegistry.test.ts new file mode 100644 index 000000000..daab9ff80 --- /dev/null +++ b/packages/core/test/themeRegistry.test.ts @@ -0,0 +1,38 @@ +import { describe, it, expect, beforeEach } from 'bun:test'; +import { ThemeRegistryManager } from '../src/theme/themeRegistry'; + +describe('ThemeRegistryManager Unit Tests', () => { + let registry: ThemeRegistryManager; + + beforeEach(() => { + registry = new ThemeRegistryManager(); + }); + + it('should initialize with default theme', () => { + const active = registry.getActiveTheme(); + expect(active.name).toBe('default'); + expect(active.palette.primary).toBe('#3b82f6'); + }); + + it('should register and switch to custom themes dynamically', () => { + registry.registerTheme({ + name: 'dracula', + palette: { + primary: '#bd93f9', + secondary: '#6272a4', + background: '#282a36', + text: '#f8f8f2', + }, + }); + + expect(registry.listThemes()).toContain('dracula'); + const switched = registry.setActiveTheme('dracula'); + expect(switched).toBe(true); + expect(registry.getActiveTheme().palette.primary).toBe('#bd93f9'); + }); + + it('should allow extending existing palette colors', () => { + registry.extendPalette('default', { primary: '#ff0000' }); + expect(registry.getActiveTheme().palette.primary).toBe('#ff0000'); + }); +});