59 lines
1.4 KiB
TypeScript
59 lines
1.4 KiB
TypeScript
|
|
import {
|
||
|
|
themes,
|
||
|
|
type AccentColor,
|
||
|
|
type BaseColor,
|
||
|
|
type ThemeColorConfig,
|
||
|
|
type ThemeScheme,
|
||
|
|
} from "./themes"
|
||
|
|
|
||
|
|
export {
|
||
|
|
accentColors,
|
||
|
|
baseColors,
|
||
|
|
themes,
|
||
|
|
type AccentColor,
|
||
|
|
type BaseColor,
|
||
|
|
type Theme,
|
||
|
|
type ThemeColorConfig,
|
||
|
|
type ThemeScheme,
|
||
|
|
} from "./themes"
|
||
|
|
|
||
|
|
export const THEME_STYLE_ELEMENT_ID = "ui-theme-variables"
|
||
|
|
|
||
|
|
export const getTheme = (name: BaseColor | AccentColor) =>
|
||
|
|
themes.find((theme) => theme.name === name)
|
||
|
|
|
||
|
|
export function getThemeCssVariables(
|
||
|
|
scheme: ThemeScheme,
|
||
|
|
config: ThemeColorConfig
|
||
|
|
) {
|
||
|
|
const base = getTheme(config.baseColor) ?? getTheme("neutral")!
|
||
|
|
const accent = getTheme(config.accentColor) ?? getTheme("blue")!
|
||
|
|
|
||
|
|
return {
|
||
|
|
...base.cssVars[scheme],
|
||
|
|
...accent.cssVars[scheme],
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function serializeThemeVariables(theme: Record<string, string>): string {
|
||
|
|
return Object.entries(theme)
|
||
|
|
.map(([key, value]) => `--${key}:${value}`)
|
||
|
|
.join(";")
|
||
|
|
}
|
||
|
|
|
||
|
|
export function buildThemeStyleSheet(
|
||
|
|
lightConfig: ThemeColorConfig,
|
||
|
|
darkConfig: ThemeColorConfig
|
||
|
|
) {
|
||
|
|
const light = serializeThemeVariables(
|
||
|
|
getThemeCssVariables("light", lightConfig)
|
||
|
|
)
|
||
|
|
const dark = serializeThemeVariables(getThemeCssVariables("dark", darkConfig))
|
||
|
|
|
||
|
|
return [
|
||
|
|
`:root,.ui\\:light{${light}}`,
|
||
|
|
`.ui\\:dark{${dark}}`,
|
||
|
|
`@media (prefers-color-scheme:dark){:root:not(.ui\\:light):not(.ui\\:dark){${dark}}}`,
|
||
|
|
].join("")
|
||
|
|
}
|