UNPKG

element-book

Version:

An [`element-vir`](https://npmjs.com/package/element-vir) drop-in element for building, testing, and demonstrating a collection of elements (or, in other words, a design system).

94 lines (93 loc) 3.16 kB
import { mapObjectValues } from '@augment-vir/common'; import Color from 'colorjs.io'; import { unsafeCSS } from 'element-vir'; function colorsObjectToCssResult(colors) { return mapObjectValues(colors, (key, value) => { if (value instanceof Color) { return unsafeCSS(value.toString({ format: 'hex' })); } else { return colorsObjectToCssResult(value); } }); } /** * The default theme color. * * @category Internal */ export const defaultThemeStartColor = 'dodgerblue'; function calculateTextColorString(color) { const onWhite = Math.abs(color.contrast('white', 'APCA')); const onBlack = Math.abs(color.contrast('black', 'APCA')); const textColorString = onWhite > onBlack ? 'white' : 'black'; return textColorString; } function createColorPair({ background, foreground, }) { return { background: background ?? new Color(calculateTextColorString(foreground)), foreground: foreground ?? new Color(calculateTextColorString(background)), }; } /** * Theme style options for the element-book app. * * @category Internal */ export var ThemeStyle; (function (ThemeStyle) { ThemeStyle["Dark"] = "dark"; ThemeStyle["Light"] = "light"; })(ThemeStyle || (ThemeStyle = {})); function flipBackForeground(input) { return input === 'black' ? 'white' : 'black'; } const faintForegroundColors = { black: { foregroundFaint1: new Color('#ccc'), foregroundFaint2: new Color('#eee'), }, white: { foregroundFaint1: new Color('#ccc'), foregroundFaint2: new Color('#eee'), }, }; const faintBackgroundColors = { black: { backgroundFaint1: new Color('#666'), backgroundFaint2: new Color('#444'), }, white: { backgroundFaint1: new Color('#ccc'), backgroundFaint2: new Color('#fafafa'), }, }; /** * Creates a theme from the given theme configuration. * * @category Internal */ export function createTheme({ themeColor: inputThemeColor = defaultThemeStartColor, themeStyle = ThemeStyle.Light, } = {}) { const themeColor = new Color(inputThemeColor); const backgroundColor = new Color(themeStyle === ThemeStyle.Dark ? 'black' : 'white'); const foregroundColorString = calculateTextColorString(backgroundColor); const foregroundColor = new Color(foregroundColorString); const colors = { nav: { hover: createColorPair({ background: themeColor.clone().set({ 'hsl.l': 93 }) }), active: createColorPair({ background: themeColor.clone().set({ 'hsl.l': 90 }) }), selected: createColorPair({ background: themeColor.clone().set({ 'hsl.l': 85 }) }), }, accent: { icon: themeColor.clone().set({ 'hsl.l': 40 }), }, page: { background: backgroundColor, ...faintBackgroundColors[flipBackForeground(foregroundColorString)], foreground: foregroundColor, ...faintForegroundColors[foregroundColorString], }, }; const convertedToCssResults = colorsObjectToCssResult(colors); return convertedToCssResults; }