UNPKG

theme-vir

Version:
182 lines (179 loc) 6.95 kB
import { check } from '@augment-vir/assert'; import { groupArrayBy } from '@augment-vir/common'; import { VirColorPair } from '@electrovir/color'; import { BookPageControlType, defineBookPage, definePageControl, } from 'element-book'; import { css, html, listen, nothing } from 'element-vir'; import { generateThemeCode } from './color-theme-code.js'; const noneOverridesSelectionValue = 'None'; /** * Create multiple element-book pages to showcase a theme its overrides (if any). * * @category Color Theme */ export function createColorThemeBookPages({ parent, title, theme, hideInverseColors, overrides, useVerticalLayout, prefixGroupByCount = 2, hideCopyCode, }) { const themeControls = { 'Show Var Names': definePageControl({ controlType: BookPageControlType.Checkbox, initValue: false, }), 'Show Contrast Tips': definePageControl({ controlType: BookPageControlType.Checkbox, initValue: true, }), }; const defaultThemeControls = { 'Theme Override': definePageControl({ controlType: BookPageControlType.Dropdown, initValue: noneOverridesSelectionValue, options: [ noneOverridesSelectionValue, ...(overrides || []).map((override) => { if (override.name === noneOverridesSelectionValue) { throw new Error(`Cannot have theme override named '${noneOverridesSelectionValue}'`); } return override.name; }), ], }), }; const themeParentPage = defineBookPage({ parent, title, controls: themeControls, }); function buildThemeColorTemplate({ controls, theme, themeColorName, }) { const themeColor = check.isKeyOf(themeColorName, theme.colors) ? theme.colors[themeColorName] : undefined; const inverseThemeColor = check.isKeyOf(themeColorName, theme.inverse) ? theme.inverse[themeColorName] : undefined; if (!themeColor || !inverseThemeColor) { throw new Error(`No theme color found by name '${themeColorName}'`); } const normalTemplate = html ` <${VirColorPair.assign({ color: themeColor, showVarValues: true, showVarNames: controls['Show Var Names'], showContrast: controls['Show Contrast Tips'], fontWeight: 400, })}></${VirColorPair}> `; const inverseColor = hideInverseColors ? undefined : inverseThemeColor; const inverseTemplate = inverseColor ? html ` <${VirColorPair.assign({ color: inverseColor, showVarValues: false, showVarNames: controls['Show Var Names'], showContrast: controls['Show Contrast Tips'], fontWeight: 400, })}></${VirColorPair}> ` : nothing; return html ` <div class="with-inverse">${normalTemplate}${inverseTemplate}</div> `; } function createThemePageExamples(defineExample, defaultTheme, overrides) { const groups = groupArrayBy(Object.keys(defaultTheme.colors), (value) => { if (prefixGroupByCount) { return value.split('-').slice(0, prefixGroupByCount).join('-'); } else { return value; } }); Object.entries(groups).forEach(([groupName, group,]) => { if (!group) { return; } defineExample({ title: groupName, styles: css ` :host { display: flex; flex-direction: column; gap: 4px; } .theme-wrapper { display: contents; } .with-inverse { display: flex; flex-direction: column; gap: 4px; } `, render({ controls }) { const selectedOverride = ('Theme Override' in controls && controls['Theme Override'] && overrides?.find((override) => override.name === controls['Theme Override'])) || undefined; const currentTheme = selectedOverride?.asTheme || defaultTheme; return html ` <div class="theme-wrapper"> ${group.map((entry) => buildThemeColorTemplate({ controls, theme: currentTheme, themeColorName: entry, }))} </div> `; }, }); }); } const descriptionParagraphs = [ 'Click a color preview to show CSS var names and values.', ]; const defaultThemePage = defineBookPage({ parent: themeParentPage, title: 'Default', descriptionParagraphs, useVerticalExamples: useVerticalLayout, controls: { ...(hideCopyCode ? {} : { copy: definePageControl({ controlType: BookPageControlType.Custom, content: html ` <button ${listen('click', async () => { const code = generateThemeCode(theme, { paletteVarName: 'viraColorPalette', overrides, }); await navigator.clipboard.writeText(code); })} > Copy Code </button> `, }), }), ...defaultThemeControls, }, defineExamples({ defineExample }) { createThemePageExamples(defineExample, theme, overrides); }, }); const overridePages = (overrides || []).map((override) => { return defineBookPage({ parent: themeParentPage, title: override.name, useVerticalExamples: useVerticalLayout, descriptionParagraphs, defineExamples({ defineExample }) { createThemePageExamples(defineExample, override.asTheme, undefined); }, }); }); return [ themeParentPage, defaultThemePage, ...overridePages, ]; }