( baseTheme: ChatTheme, mode: 'dark' | 'light', customColors?: Partial<ChatTheme>, plugins?: ThemePlugin[], )
| 112 | * @returns Complete theme with all customizations applied |
| 113 | */ |
| 114 | export const buildTheme = ( |
| 115 | baseTheme: ChatTheme, |
| 116 | mode: 'dark' | 'light', |
| 117 | customColors?: Partial<ChatTheme>, |
| 118 | plugins?: ThemePlugin[], |
| 119 | ): ChatTheme => { |
| 120 | // Start with cloned base theme (cloning handled by caller) |
| 121 | const theme = { ...baseTheme } |
| 122 | |
| 123 | // Layer 1: Apply global custom colors |
| 124 | if (customColors) { |
| 125 | Object.assign(theme, customColors) |
| 126 | } |
| 127 | |
| 128 | // Layer 2: Apply plugins |
| 129 | if (plugins) { |
| 130 | for (const plugin of plugins) { |
| 131 | const pluginOverrides = plugin.apply(theme, mode) |
| 132 | Object.assign(theme, pluginOverrides) |
| 133 | } |
| 134 | } |
| 135 | |
| 136 | // Final step: Resolve all 'default' values to actual colors |
| 137 | resolveThemeColors(theme, mode) |
| 138 | theme.name = mode |
| 139 | |
| 140 | return theme |
| 141 | } |
no test coverage detected