theme-vir
Version:
Create an entire web theme.
89 lines (88 loc) • 2.93 kB
JavaScript
import { camelCaseToKebabCase, getObjectTypedValues, typedObjectFromEntries, } from '@augment-vir/common';
import { applyCssVarsViaStyleElement, setCssVarValue } from 'lit-css-vars';
/**
* Create the `<style>` id used to apply color themes globally by
* {@link applyColorThemeViaStyleElement}.
*
* @category Internal
*/
export function createGlobalThemeStyleId(colorTheme) {
return [
camelCaseToKebabCase(colorTheme.prefix),
'theme-vir-style',
].join('-');
}
/**
* Sets all of a color theme's CSS vars in a global style element. If no override is given, the
* theme color default values are assigned.
*
* Uses `applyCssVarsViaStyleElement` from `lit-css-vars`.
*
* @category Color Theme
*/
export function applyColorThemeViaStyleElement(colorTheme, themeOverride,
/**
* The context to apply the color theme to.
*
* @default document.head
*/
context) {
const cssVarValues = typedObjectFromEntries(getObjectTypedValues(colorTheme.colors).flatMap((themeColor) => {
return [
buildCssVarDeclaration({
layerKey: 'background',
themeColor,
themeOverride,
}),
buildCssVarDeclaration({
layerKey: 'foreground',
themeColor,
themeOverride,
}),
];
}));
return applyCssVarsViaStyleElement(cssVarValues, createGlobalThemeStyleId(colorTheme), context);
}
/**
* A very inefficient way of setting all of a color theme's CSS vars on a given element. If no
* override is given, the theme color default values are assigned.
*
* @deprecated Use {@link applyColorThemeViaStyleElement} instead whenever possible.
* @category Internal
*/
export function applyColorTheme(
/** This should usually be the top-level `html` element. */
element, fullTheme, themeOverride) {
getObjectTypedValues(fullTheme.colors).forEach((themeColor) => {
applyIndividualThemeColorValue({
element,
layerKey: 'background',
themeColor,
themeOverride,
});
applyIndividualThemeColorValue({
element,
layerKey: 'foreground',
themeColor,
themeOverride,
});
});
}
function buildCssVarDeclaration({ layerKey, themeOverride, themeColor, }) {
const cssVarName = String(themeColor[layerKey].name);
const override = themeOverride?.overrides[cssVarName];
const value = override || themeColor[layerKey].default;
return [
cssVarName,
value,
];
}
function applyIndividualThemeColorValue({ element, layerKey, themeOverride, themeColor, }) {
const override = themeOverride?.overrides[String(themeColor[layerKey].name)];
const value = override || themeColor[layerKey].default;
setCssVarValue({
forCssVar: themeColor[layerKey],
onElement: element,
toValue: value,
});
}