50 lines
2.1 KiB
TypeScript
50 lines
2.1 KiB
TypeScript
import { jadeScrollTheme } from './jadeScroll'
|
|
import { moonlitWaterTheme } from './moonlitWater'
|
|
import type { OverlayThemeDefinition, OverlayThemeId } from './types'
|
|
|
|
export type { OverlayThemeDefinition, OverlayThemeId, ThemeParticle } from './types'
|
|
|
|
/** Ordered registry used by both the control select and OBS renderer. */
|
|
export const overlayThemes: readonly OverlayThemeDefinition[] = [jadeScrollTheme, moonlitWaterTheme]
|
|
|
|
const themesById = new Map(overlayThemes.map(theme => [theme.id, theme]))
|
|
|
|
/**
|
|
* Resolve untrusted snapshots defensively. The Rust API rejects unknown IDs,
|
|
* while this fallback keeps older or cached OBS pages renderable during deploys.
|
|
*/
|
|
export function getOverlayTheme(id: unknown): OverlayThemeDefinition {
|
|
return themesById.get(id as OverlayThemeId) ?? jadeScrollTheme
|
|
}
|
|
|
|
export function normalizeThemeId(id: unknown): OverlayThemeId {
|
|
return getOverlayTheme(id).id
|
|
}
|
|
|
|
/** Translate semantic theme fields into the renderer's CSS contract. */
|
|
export function themeCssVariables(
|
|
theme: OverlayThemeDefinition,
|
|
): Readonly<Record<`--theme-${string}`, string>> {
|
|
return {
|
|
'--theme-text': theme.palette.text,
|
|
'--theme-user': theme.palette.user,
|
|
'--theme-compact-user': theme.palette.compactUser,
|
|
'--theme-accent': theme.palette.accent,
|
|
'--theme-price': theme.palette.price,
|
|
'--theme-card-border': theme.surfaces.cardBorder,
|
|
'--theme-card-background': theme.surfaces.cardBackground,
|
|
'--theme-pattern-divider': `url("${theme.ornaments.patterns.divider}")`,
|
|
'--theme-pattern-cluster': `url("${theme.ornaments.patterns.cluster}")`,
|
|
'--theme-pattern-vine': `url("${theme.ornaments.patterns.vine}")`,
|
|
'--theme-pattern-edge': `url("${theme.ornaments.patterns.edge}")`,
|
|
'--theme-pattern-lotus': `url("${theme.ornaments.patterns.lotus}")`,
|
|
'--theme-motion-arrive': theme.motion.arrive,
|
|
'--theme-motion-sheen': theme.motion.sheen,
|
|
'--theme-motion-featured': theme.motion.featured,
|
|
'--theme-motion-float': theme.motion.float,
|
|
'--theme-motion-sparkle': theme.motion.sparkle,
|
|
'--theme-motion-unfurl': theme.motion.unfurl,
|
|
'--theme-motion-rails-open': theme.motion.railsOpen,
|
|
}
|
|
}
|