feat(theme): expand color settings to 8-token CI palette + alt button
This commit is contained in:
@@ -1,34 +1,77 @@
|
||||
import type { ThemeConfig, HeaderStyleType, HeroDividerStyle, GalleryLayoutType } from '../types/theme.types';
|
||||
|
||||
/**
|
||||
* Migrates legacy theme configurations that used 'hero' as a galleryLayout
|
||||
* to the new decoupled headerStyle + galleryLayout system.
|
||||
* Fills in any missing 8-token CI palette fields on legacy themes that were
|
||||
* saved before the palette expanded from 4 → 8 explicit tokens.
|
||||
*
|
||||
* This ensures backward compatibility with existing events that have
|
||||
* 'hero' set as their galleryLayout.
|
||||
* The visible look of an existing instance must not change just because the
|
||||
* type system grew (per project memory: migrations preserve visual state).
|
||||
* For each missing token we fall back to the value the renderer was already
|
||||
* deriving implicitly:
|
||||
* - accentDarkColor ← primaryColor (legacy primary was used as CTA fill)
|
||||
* - elevatedColor ← surfaceColor (or a slight shift for light themes)
|
||||
* - surfaceColor ← '#ffffff' / '#1a1a1a' depending on colorMode
|
||||
* - surfaceBorderColor← '#e5e5e5' / '#2e2e2e'
|
||||
* - mutedTextColor ← '#737373' / '#a3a3a3'
|
||||
*/
|
||||
function fillMissingPaletteTokens(theme: ThemeConfig): ThemeConfig {
|
||||
const isDark = theme.colorMode === 'dark';
|
||||
const filled: ThemeConfig = { ...theme };
|
||||
|
||||
if (!filled.surfaceColor) {
|
||||
filled.surfaceColor = isDark ? '#1a1a1a' : '#ffffff';
|
||||
}
|
||||
if (!filled.elevatedColor) {
|
||||
// For dark themes raise slightly above surface; for light, drop slightly below.
|
||||
filled.elevatedColor = isDark ? '#242424' : '#f5f5f5';
|
||||
}
|
||||
if (!filled.surfaceBorderColor) {
|
||||
filled.surfaceBorderColor = isDark ? '#2e2e2e' : '#e5e5e5';
|
||||
}
|
||||
if (!filled.mutedTextColor) {
|
||||
filled.mutedTextColor = isDark ? '#a3a3a3' : '#737373';
|
||||
}
|
||||
if (!filled.accentDarkColor) {
|
||||
// Legacy themes used primaryColor as the CTA fill — preserve that.
|
||||
filled.accentDarkColor = filled.primaryColor;
|
||||
}
|
||||
|
||||
return filled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrates legacy theme configurations:
|
||||
* - 'hero' galleryLayout → decoupled headerStyle + galleryLayout
|
||||
* - missing 8-token CI palette fields → derived from legacy 4-color set
|
||||
*
|
||||
* This ensures backward compatibility with existing events.
|
||||
*/
|
||||
export function migrateThemeConfig(theme: ThemeConfig): ThemeConfig {
|
||||
if (!theme) return theme;
|
||||
|
||||
let migrated = theme;
|
||||
|
||||
// Check if this theme uses the legacy 'hero' layout
|
||||
if ((theme.galleryLayout as string) === 'hero') {
|
||||
return {
|
||||
...theme,
|
||||
if ((migrated.galleryLayout as string) === 'hero') {
|
||||
migrated = {
|
||||
...migrated,
|
||||
headerStyle: 'hero' as HeaderStyleType,
|
||||
galleryLayout: 'grid' as GalleryLayoutType,
|
||||
heroDividerStyle: (theme.heroDividerStyle || 'wave') as HeroDividerStyle,
|
||||
heroDividerStyle: (migrated.heroDividerStyle || 'wave') as HeroDividerStyle,
|
||||
};
|
||||
}
|
||||
|
||||
// If headerStyle is not set but galleryLayout is valid, default to 'standard'
|
||||
if (!theme.headerStyle && theme.galleryLayout) {
|
||||
return {
|
||||
...theme,
|
||||
if (!migrated.headerStyle && migrated.galleryLayout) {
|
||||
migrated = {
|
||||
...migrated,
|
||||
headerStyle: 'standard' as HeaderStyleType,
|
||||
};
|
||||
}
|
||||
|
||||
return theme;
|
||||
// Fill any missing 8-token palette fields so the renderer never has to
|
||||
// fall back to hard-coded defaults that diverge from the original look.
|
||||
return fillMissingPaletteTokens(migrated);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user