diff --git a/package.json b/package.json index 37b5c01ac6..63eddfc9a6 100644 --- a/package.json +++ b/package.json @@ -112,6 +112,7 @@ "axe-core": "^4.6.3", "cheerio": "^1.0.0-rc.12", "chokidar-cli": "^3.0.0", + "chroma-js": "^2.4.2", "cssnano": "^6.0.0", "dotenv-cli": "^7.0.0", "eleventy-plugin-toc": "^1.1.5", diff --git a/scripts/applyDesignTokens.ts b/scripts/applyDesignTokens.ts index 58f5596c6b..c4c8d14d15 100644 --- a/scripts/applyDesignTokens.ts +++ b/scripts/applyDesignTokens.ts @@ -3,6 +3,7 @@ const https = require('https') const { existsSync } = require('fs') const { mkdir, writeFile } = require('fs').promises const { join, dirname } = require('path') +const chroma = require('chroma-js') const isBin = __filename.endsWith('.cjs') const stylesDir = isBin ? './liquid_tmp/styles' : './src/liquid/global/styles' @@ -27,35 +28,94 @@ function pxToRem(px: string | number) { return val + 'rem' } -function getColorTokenValue(variant, styles) { +function getShortName(baseColorName: string) { + return ( + baseColorName === 'Neutral' + ? baseColorName + : baseColorName['replaceAll'](/[a-z]/g, '') + ).toLowerCase() +} + +function getColorTokenValue( + variant, + styles, + modifier?: 'hover' | 'active' | 'focus', + isDark = false +) { + function darken(colKey: string, times: 1 | 2 | -2) { + // const colNum = isDark ? 1100 - parseInt(colKey) : parseInt(colKey) + const colNum = parseInt(colKey) + if (isDark) { + if (colNum === 200) { + if (times === 2) return '050' + } + if (colNum === 100) { + if (times === 1) return '050' + if (times === 2) return '010' + } + if (times === -2) { + if (colNum === 10) return '100' + if (colNum === 50) return '200' + } + return String(colNum - times * 100) + } + + if (colNum === 10) { + if (times === 1) return '050' + if (times === 2) return '100' + } + if (colNum === 50) { + if (times === 1) return '100' + if (times === 2) return '200' + } + if (times === -2) { + if (colNum === 100) return '010' + if (colNum === 200) return '050' + } + return String(colNum + times * 100) + } + if (variant.styles?.fill) { const style = styles[variant.styles.fill] const { name, description } = style const variants = description.split(', ') const [baseColorName, ...rest] = name.split('/')[1].split('-') + const shortName = getShortName(baseColorName) const referenceName = - (baseColorName === 'Neutral' - ? baseColorName - : baseColorName.replaceAll(/[a-z]/g, '') - ).toLowerCase() + + shortName + (variants.includes('Default') ? '' : rest.length ? '-' + rest.join('-') : '') - return referenceName - } else { - return relRGBToAbsRGB(variant.fills[0]) - } -} -function relRGBToAbsRGB(fill) { - const r = Math.round(fill.color.r * 255) - const g = Math.round(fill.color.g * 255) - const b = Math.round(fill.color.b * 255) - const a = Math.round((fill.opacity ?? 1) * 100) / 100 + switch (modifier) { + case 'hover': + return `${referenceName}-${darken( + getDefaultKeyFromCache(shortName), + 1 + )}` + case 'active': + return `${referenceName}-${darken( + getDefaultKeyFromCache(shortName), + 2 + )}` + case 'focus': + return `${referenceName}-${darken( + getDefaultKeyFromCache(shortName), + -2 + )}` + default: + return referenceName + } + } else { + const { r, g, b, a } = variant.fills[0] + const color = chroma({ r, g, b, a }) - return a === 1 ? `rgb(${r}, ${g}, ${b})` : `rgba(${r}, ${g}, ${b}, ${a})` + return `hsl(${color.get('hsl.h')}deg ${color.get('hsl.s') * 100}% ${ + color.get('hsl.l') * 100 + }%${a === 1 ? '' : ' / ' + a})` + } } function parseThemes(items, styles) { @@ -73,23 +133,66 @@ function parseThemes(items, styles) { if (variants) { variants.forEach((variant) => { const variantName = variant.name.toLowerCase().replace(/ /g, '-') + + // Ignore hover, active, focus variants - we do not fetch these from Figma; + // instead we set them programmatically for light and dark mode based on the default variant. + if (['hover', 'active', 'focus'].includes(variantName)) { + return + } + const subVariants = variant.children - if (variant.children) { - if (subVariants) { - subVariants.forEach((subVariant) => { - const subVariantName = subVariant.name - .toLowerCase() - .replace(/ /g, '-') - const colorName = `${groupName}-${variantName}-${subVariantName}` - theme[colorName] = getColorTokenValue(subVariant, styles) - }) - } + if (subVariants) { + subVariants.forEach((subVariant) => { + const subVariantName = subVariant.name + .toLowerCase() + .replace(/ /g, '-') + const colorName = `${groupName}-${variantName}-${subVariantName}` + theme[colorName] = getColorTokenValue(subVariant, styles) + }) } else { const colorName = `${groupName}${ variantName === 'default' ? '' : `-${variantName}` }` theme[colorName] = getColorTokenValue(variant, styles) + + if (variantName === 'default') { + // Derive hover, active, focus variants from default variant for light and dark mode. + theme[`${colorName}-hover`] = getColorTokenValue( + variant, + styles, + 'hover' + ) + theme[`${colorName}-active`] = getColorTokenValue( + variant, + styles, + 'active' + ) + theme[`${colorName}-focus`] = getColorTokenValue( + variant, + styles, + 'focus' + ) + + theme[`${colorName}-hover-dark`] = getColorTokenValue( + variant, + styles, + 'hover', + true + ) + theme[`${colorName}-active-dark`] = getColorTokenValue( + variant, + styles, + 'active', + true + ) + theme[`${colorName}-focus-dark`] = getColorTokenValue( + variant, + styles, + 'focus', + true + ) + } } }) } @@ -139,6 +242,49 @@ function parseShadows(items) { return shadows } +const defaultColorKeysCache = new Map() +function getDefaultKeyFromCache(colorShortName: string) { + return defaultColorKeysCache.get(colorShortName) +} + +function getDefaultKey( + colorShortName: string, + defaultColor: { hex(mode?: 'auto' | 'rgb' | 'rgba'): string }, + oklchH: number, + scale: { + key: `${number}${number}${number}` + chroma: number + lightness: number + }[] +) { + const defaultKey = scale.reduce((key, setting) => { + const settingColor = chroma.oklch(setting.lightness, setting.chroma, oklchH) + if (!key) { + return setting.key + } + const keyColorSetting = scale.find((setting) => setting.key === key) + const keyColor = chroma.oklch( + keyColorSetting.lightness, + keyColorSetting.chroma, + oklchH + ) + const distanceToSettingColor = chroma.deltaE( + settingColor.hex(), + defaultColor.hex() + ) + const distanceToKeyColor = chroma.deltaE(keyColor.hex(), defaultColor.hex()) + if (distanceToSettingColor < distanceToKeyColor) { + return setting.key + } + return key + }, '') as `${number}${number}${number}` + + // HACK: intended side effect + defaultColorKeysCache.set(colorShortName, defaultKey) + + return defaultKey +} + function parseColors(items, styles: { name: string; description: string }[]) { const colors = {} @@ -152,22 +298,123 @@ function parseColors(items, styles: { name: string; description: string }[]) { } else if (item.fills?.length && item.styles?.fill) { const style = styles[item.styles.fill] const { name, description } = style - const variants = description.split(', ') const pathParts = name.split('/') const [baseColorName, ...rest] = pathParts[pathParts.length > 1 ? pathParts.length - 1 : 0].split('-') - const defaultOnly = rest.length === 0 - const colorShortName = ['Neutral', 'White'].includes(baseColorName) - ? baseColorName === 'White' - ? 'wht' - : baseColorName.toLowerCase() - : baseColorName.replace(/[a-z]/g, '').toLowerCase() - const colorName = - colorShortName + - (defaultOnly ? '' : '-' + rest.join('-')) + - (variants.includes('Default') ? '/default' : '') - const colorValue = relRGBToAbsRGB(item.fills[0]) - colors[colorName] = colorValue + + const isDefault = description === 'Default' + const isNeutral = name.includes('/Neutral-900') + const isWhite = name.includes('/White') && !rest.length + + if (!isDefault && !isNeutral && !isWhite) continue + + let colorShortName: string + if (isNeutral) { + colorShortName = 'neutral' + } else if (isWhite) { + colorShortName = 'wht' + } else { + colorShortName = baseColorName.replace(/[a-z]/g, '').toLowerCase() + } + + const r = parseFloat((item.fills[0].color.r * 255).toFixed(2)) + const g = parseFloat((item.fills[0].color.g * 255).toFixed(2)) + const b = parseFloat((item.fills[0].color.b * 255).toFixed(2)) + + const defaultColor = chroma({ r, g, b }) + const hslH = defaultColor.get('hsl.h') || 0 + const hslS = defaultColor.get('hsl.s') + const hslL = defaultColor.get('hsl.l') + const oklchH = defaultColor.get('oklch.h') || 0 + + if (isWhite) { + colors[colorShortName] = `hsl(${hslH.toFixed(2)}deg ${( + hslS * 100 + ).toFixed(2)}% ${(hslL * 100).toFixed(2)}%)` + const whiteGradients = [ + { + modifier: 'alpha-highest', + alpha: 0.8, + }, + { + modifier: 'alpha-high', + alpha: 0.7, + }, + { + modifier: 'alpha-medium', + alpha: 0.5, + }, + { + modifier: 'alpha-low', + alpha: 0.2, + }, + { + modifier: 'alpha-lowest', + alpha: 0.1, + }, + ] + for (const gradient of whiteGradients) { + colors[ + `${colorShortName}-${gradient.modifier}` + ] = `hsl(${hslH.toFixed(2)}deg ${(hslS * 100).toFixed(2)}% ${( + hslL * 100 + ).toFixed(2)}% / ${gradient.alpha})` + } + continue + } + + const scale = [ + { key: '010', chroma: isNeutral ? 0.002 : 0.02, lightness: 0.98 }, + { key: '050', chroma: isNeutral ? 0.005 : 0.04, lightness: 0.96 }, + { key: '100', chroma: isNeutral ? 0.005 : 0.07, lightness: 0.91 }, + { key: '200', chroma: isNeutral ? 0.01 : 0.14, lightness: 0.8 }, + { key: '300', chroma: isNeutral ? 0.01 : 0.15, lightness: 0.74 }, + { key: '400', chroma: isNeutral ? 0.01 : 0.14, lightness: 0.64 }, + { key: '500', chroma: isNeutral ? 0.005 : 0.13, lightness: 0.55 }, + { key: '600', chroma: isNeutral ? 0.01 : 0.11, lightness: 0.5 }, + { key: '700', chroma: isNeutral ? 0.015 : 0.1, lightness: 0.4 }, + { key: '800', chroma: isNeutral ? 0.02 : 0.08, lightness: 0.35 }, + { key: '900', chroma: 0.06, lightness: 0.24 }, + ] as { + key: `${number}${number}${number}` + chroma: number + lightness: number + }[] + + scale.forEach((setting) => { + const color = chroma.oklch(setting.lightness, setting.chroma, oklchH) + colors[`${colorShortName}-${setting.key}`] = `hsl(${color + .get('hsl.h') + .toFixed(2)}deg ${(color.get('hsl.s') * 100).toFixed(2)}% ${( + color.get('hsl.l') * 100 + ).toFixed(2)}%)` + }) + + // Find color in scale with the smallest distance to the default color + // and replace it with the default color. Note that interactivity variants, + // such as hover and focus, need to be assigned according to the new default + // color key. + const defaultKey = getDefaultKey( + getShortName(baseColorName), + defaultColor, + oklchH, + scale + ) + colors[`${colorShortName}-${defaultKey}`] = `hsl(${hslH.toFixed(2)}deg ${( + hslS * 100 + ).toFixed(2)}% ${(hslL * 100).toFixed(2)}%)` + colors[`${colorShortName}-${defaultKey}/default`] = `hsl(${hslH.toFixed( + 2 + )}deg ${(hslS * 100).toFixed(2)}% ${(hslL * 100).toFixed(2)}%)` + + // TODO check if it is wiser to pick a color from the middle of the range + // alpha + colors[`${colorShortName}-alpha-low`] = `hsl(${hslH.toFixed(2)}deg ${( + hslS * 100 + ).toFixed(2)}% ${(hslL * 100).toFixed(2)}% / 0.2)` + colors[`${colorShortName}-alpha-lowest`] = `hsl(${hslH.toFixed(2)}deg ${( + hslS * 100 + ).toFixed(2)}% ${(hslL * 100).toFixed(2)}% / 0.1)` } } @@ -217,6 +464,34 @@ function parseSpacings(items) { return spacings } +function invertColors(colors) { + const inverted = JSON.parse( + JSON.stringify(colors) + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + .replaceAll(/(-\d\d\d)/g, '$1_') + .replaceAll('900_', '010') + .replaceAll('800_', '050') + .replaceAll('700_', '100') + .replaceAll('600_', '200') + .replaceAll('500_', '300') + .replaceAll('400_', '400') + .replaceAll('300_', '500') + .replaceAll('200_', '600') + .replaceAll('100_', '700') + .replaceAll('050_', '800') + .replaceAll('010_', '900') + .replaceAll('/default', '') + ) + Object.keys(colors).forEach((key) => { + if (key.includes('/default')) { + inverted[key] = inverted[key.split('/default')[0]] + delete inverted[key.split('/default')[0]] + } + }) + return inverted +} + async function getTokensFromFigma(figmaFileURL: string) { let figmaId let nodeId @@ -263,6 +538,10 @@ async function getTokensFromFigma(figmaFileURL: string) { const { document, styles } = (result as { nodes }).nodes[nodeId] const { children: figmaData } = document + const colors = parseColors( + figmaData.find((child) => child.name === 'Colors').children, + styles + ) const tokens = { themes: parseThemes( figmaData.find(({ name }) => name === 'Themes').children, @@ -275,10 +554,10 @@ async function getTokensFromFigma(figmaFileURL: string) { figmaData.find((child) => child.name === 'Spacings').children ), colors: { - ...parseColors( - figmaData.find((child) => child.name === 'Colors').children, - styles - ), + ...colors, + }, + colorsDark: { + ...invertColors(colors), }, typography: parseTypography( [ @@ -310,7 +589,7 @@ function boxShadowToDropShadow(boxShadow: string): string { function generateShadows(tokens) { return ensureWriteFile( join(stylesDir, 'shadows/shadows.css'), - '/* autogenerated */\n/* prettier-ignore */\n:root {\n' + + '/* autogenerated */ /* prettier-ignore */\n/* prettier-ignore */\n:root {\n' + Object.keys(tokens) .sort() .map((key) => ` --ld-shadow-${key}: ${tokens[key]};`) @@ -328,35 +607,49 @@ function generateShadows(tokens) { ) } -function generateColors(colorTokens) { - const colorVariables = [] +function generateColors(colors, isDark = false) { + const colorVariables = new Map() - // Basic colors - Object.keys(colorTokens).forEach((key) => { - const val = colorTokens[key] + // Defaults + const defaults = {} + Object.keys(colors).forEach((key) => { if (key.includes('/default')) { const colorKey = key.split('/default')[0] const colorBaseName = key .replace(/\d/g, '') .replace('/default', '') .replace(/-$/, '') + defaults[colorBaseName] = colorKey.match(/\d+/g)?.at(0) + } + }) - colorVariables.push(` --ld-col-${colorKey}: ${val};`) - - // prevents duplicate custom properties in cases like "sp/default" - if (colorBaseName !== colorKey) { - colorVariables.push(` --ld-col-${colorBaseName}: ${val};`) - } + // Basic colors + Object.keys(colors).forEach((key) => { + const val = colors[key] + if (key.includes('/default')) { + const colorKey = key.split('/default')[0] + const colorBaseName = key + .replace(/\d/g, '') + .replace('/default', '') + .replace(/-$/, '') + colorVariables.set(`--ld-col-${colorKey}`, val) + colorVariables.set(`--ld-col-${colorBaseName}`, val) } else { - colorVariables.push(` --ld-col-${key}: ${val};`) + colorVariables.set(`--ld-col-${key}`, val) } }) return ensureWriteFile( - join(stylesDir, 'colors/colors.css'), - ['/* autogenerated */', ':root {', ...colorVariables.sort(), '}', ''].join( - '\n' - ), + join(stylesDir, isDark ? 'colors/colors-dark.css' : 'colors/colors.css'), + [ + '/* autogenerated */', + isDark ? ':root:is(.ld-dark) {' : ':root:not(.ld-dark) {', + ...Array.from(colorVariables.entries()) + .map((entry) => ` ${entry[0]}: ${entry[1]};`) + .sort(), + '}', + '', + ].join('\n'), 'utf8' ) } @@ -364,7 +657,7 @@ function generateColors(colorTokens) { function generateSpacings(tokens) { return ensureWriteFile( join(stylesDir, 'spacings/spacings.css'), - '/* autogenerated */\n/* prettier-ignore */\n:root {\n' + + '/* autogenerated */ /* prettier-ignore */\n/* prettier-ignore */\n:root {\n' + Object.keys(tokens) .sort((key) => parseInt(key)) .map((key) => ` --ld-sp-${key}: ${tokens[key]};`) @@ -410,17 +703,37 @@ function generateTheming(themes) { }) themeSelectors.push(`.ld-theme-${themeName} {`) - themeSelectors.push(...currentThemeColorVariables.sort()) - themeSelectors.push(`}`) + themeSelectors.push( + ...currentThemeColorVariables.filter((v) => !v.includes('-dark:')).sort() + ) + // themeSelectors.push('\n &.ld-dark {') + // themeSelectors.push( + // ...currentThemeColorVariables + // .filter((v) => v.includes('-dark:')) + // .map((v) => ' ' + v.replace('-dark:', ':')) + // .sort() + // ) + // themeSelectors.push(' }') + themeSelectors.push('}') }) return ensureWriteFile( join(stylesDir, 'theming/theming.css'), [ - '/* autogenerated */', + '/* autogenerated */ /* prettier-ignore */', ':root {', - ...themeColorVariables.sort(), - ...defaultThemeColorVariables.sort(), + ...themeColorVariables.filter((v) => !v.includes('-dark:')).sort(), + ...defaultThemeColorVariables.filter((v) => !v.includes('-dark:')).sort(), + '\n &.ld-dark {', + ...themeColorVariables + .filter((v) => v.includes('-dark:')) + .map((v) => ' ' + v.replace('-dark:', ':')) + .sort(), + ...defaultThemeColorVariables + .filter((v) => v.includes('-dark:')) + .map((v) => ' ' + v.replace('-dark:', ':')) + .sort(), + ' }', '}', ...themeSelectors, '', @@ -444,7 +757,7 @@ function generateTypography(tokens: TypoToken[]) { } return ensureWriteFile( join(stylesDir, 'typography/typography.css'), - '/* autogenerated */\n/* prettier-ignore */\n:root {\n' + + '/* autogenerated */ /* prettier-ignore */\n/* prettier-ignore */\n:root {\n' + // This expects to have at least one headline and one paragraph typo defined ` --ld-font-body: ${bodyFontFamily};\n` + (nonBodyTypoEntry !== undefined @@ -469,7 +782,7 @@ function generateTypography(tokens: TypoToken[]) { function generateBorderRadii(tokens) { return ensureWriteFile( join(stylesDir, 'border-radius/border-radius.css'), - '/* autogenerated */\n/* prettier-ignore */\n:root {\n' + + '/* autogenerated */ /* prettier-ignore */\n/* prettier-ignore */\n:root {\n' + Object.keys(tokens) .sort((key) => parseInt(key)) .map((key) => ` --ld-br-${key}: ${tokens[key]};`) @@ -483,6 +796,7 @@ function generateCSSTokenFiles(tokenCollection) { return Promise.all([ generateShadows(tokenCollection.shadows), generateColors(tokenCollection.colors), + generateColors(tokenCollection.colorsDark, true), generateSpacings(tokenCollection.spacings), generateTheming(tokenCollection.themes), generateTypography(tokenCollection.typography), diff --git a/src/docs/components/docs-border-radius/docs-border-radius.css b/src/docs/components/docs-border-radius/docs-border-radius.css index 44b66dfc49..7d57c6f996 100644 --- a/src/docs/components/docs-border-radius/docs-border-radius.css +++ b/src/docs/components/docs-border-radius/docs-border-radius.css @@ -1,27 +1,5 @@ -@define-mixin docs-border-radius-ui-light { - .docs-border-radius { - border-color: var(--ld-col-neutral-100); - } -} -@define-mixin docs-border-radius-ui-dark { - .docs-border-radius { - border-color: var(--ld-col-neutral-600); - } -} - -@mixin docs-border-radius-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-border-radius-ui-dark; -} -.docs-ui-dark { - @mixin docs-border-radius-ui-dark; -} -.docs-ui-light { - @mixin docs-border-radius-ui-light; -} - .docs-border-radius { + border-color: var(--ld-col-neutral-100); display: flex; width: 100%; align-items: center; diff --git a/src/docs/components/docs-btn-search/docs-btn-search.css b/src/docs/components/docs-btn-search/docs-btn-search.css index 1867b79308..d3dc8ef776 100644 --- a/src/docs/components/docs-btn-search/docs-btn-search.css +++ b/src/docs/components/docs-btn-search/docs-btn-search.css @@ -1,32 +1,3 @@ -@define-mixin docs-btn-search-ui-light { - .docs-btn-search__magnifier { - stroke: var(--ld-col-neutral-900); - } - .docs-btn-search__shortcut { - fill: var(--ld-col-neutral-900); - } -} -@define-mixin docs-btn-search-ui-dark { - .docs-btn-search__magnifier { - stroke: var(--ld-col-wht); - } - .docs-btn-search__shortcut { - fill: var(--ld-col-wht); - } -} - -@mixin docs-btn-search-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-btn-search-ui-dark; -} -.docs-ui-dark { - @mixin docs-btn-search-ui-dark; -} -.docs-ui-light { - @mixin docs-btn-search-ui-light; -} - .docs-btn-search__btn { display: flex; align-items: center; @@ -43,8 +14,10 @@ .docs-btn-search__magnifier { margin-right: var(--ld-sp-6); + stroke: var(--ld-col-neutral-900); } .docs-btn-search__shortcut { + fill: var(--ld-col-neutral-900); margin-left: auto; } diff --git a/src/docs/components/docs-color/docs-color.css b/src/docs/components/docs-color/docs-color.css index df90989fa2..85338a41ea 100644 --- a/src/docs/components/docs-color/docs-color.css +++ b/src/docs/components/docs-color/docs-color.css @@ -1,29 +1,7 @@ -@define-mixin docs-color-ui-light { - .docs-color { - border-color: var(--ld-col-neutral-100); - } -} -@define-mixin docs-color-ui-dark { - .docs-color { - border-color: var(--ld-col-neutral-600); - } -} - -@mixin docs-color-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-color-ui-dark; -} -.docs-ui-dark { - @mixin docs-color-ui-dark; -} -.docs-ui-light { - @mixin docs-color-ui-light; -} - .docs-color { - background: #090909 - url('data:image/svg+xml;utf8,'); + background: var(--ld-layer) + url('data:image/svg+xml;utf8,'); + border-color: var(--ld-col-neutral-100); display: flex; width: 100%; height: var(--ld-sp-40); @@ -51,22 +29,10 @@ } } -.docs-color--transparent { - color: var(--ld-col-wht); - - &.docs-color--dark { - color: var(--ld-col-neutral-900); - } - - .docs-copy-to-cb { - filter: invert(1) hue-rotate(180deg); - } -} - .docs-color--dark { - color: var(--ld-col-wht); - background: #f1f1f1 - url('data:image/svg+xml;utf8,'); + color: var(--ld-col-neutral-010); + background: var(--ld-layer) + url('data:image/svg+xml;utf8,'); .docs-copy-to-cb { filter: invert(1) hue-rotate(180deg); diff --git a/src/docs/components/docs-color/docs-color.tsx b/src/docs/components/docs-color/docs-color.tsx index 336f480b88..b16b92eb4c 100644 --- a/src/docs/components/docs-color/docs-color.tsx +++ b/src/docs/components/docs-color/docs-color.tsx @@ -1,4 +1,5 @@ import { Component, Prop, h, Host, Element, State } from '@stencil/core' +import chroma from 'chroma-js' /** @internal **/ @Component({ @@ -9,6 +10,7 @@ import { Component, Prop, h, Host, Element, State } from '@stencil/core' export class MyComponent { @Element() el: HTMLElement private bgRef: HTMLSpanElement + private observer: MutationObserver /** CSS variable name */ @Prop() var: string @@ -19,28 +21,58 @@ export class MyComponent { @State() val: string @State() dark: boolean + private getAlpha(color) { + return parseFloat((color.rgba()[3] || 1).toFixed(2)) + } + private isDark(color) { - color = color.match( - /^rgba?\((\d+),\s*(\d+),\s*(\d+)(?:,\s*(\d+(?:\.\d+)?))?\)$/ + const isDarkMode = document.documentElement.classList.contains('ld-dark') + const a = this.getAlpha(color) + const lightness = color.get('hsl.l') + const isDark = isDarkMode ? lightness <= 0.4 : lightness > 0.4 + console.info('a === 1 ? !isDark : false', a === 1 ? !isDark : false) + return a === 1 ? !isDark : false + } + + getHSLAFromColor(color) { + const h = parseFloat(((color.get('hsl.h') || 0) * 1).toFixed(2)) + const s = parseFloat((color.get('hsl.s') * 100).toFixed(2)) + const l = parseFloat((color.get('hsl.l') * 100).toFixed(2)) + const a = this.getAlpha(color) + return { h, s, l, a } + } + + updateState() { + if (!this.bgRef) return + const color = chroma( + getComputedStyle(this.bgRef).getPropertyValue('background-color') ) - const r = color[1] - const g = color[2] - const b = color[3] - const a = color[4] - const hsp = Math.sqrt(0.299 * (r * r) + 0.587 * (g * g) + 0.114 * (b * b)) - return hsp <= 127.5 * (a || 1) + const { h, s, l, a } = this.getHSLAFromColor(color) + this.val = `hsl(${h}deg ${s}% ${l}%${a === 1 ? '' : ' / ' + a})` + this.dark = this.isDark(color) + } + + componentWillLoad() { + this.observer = new MutationObserver(this.updateState.bind(this)) + this.observer.observe(document.documentElement, { + subtree: false, + childList: false, + attributes: true, + }) + + this.updateState() } componentDidLoad() { - const color = getComputedStyle(this.bgRef).getPropertyValue( - 'background-color' - ) setTimeout(() => { - this.val = color - this.dark = this.isDark(color) + this.updateState() }) } + disconnectedCallback() { + if (this.observer) this.observer.disconnect() + } + render() { let cl = 'docs-color' if (this.dark) cl += ' docs-color--dark' diff --git a/src/docs/components/docs-contributors/docs-contributors.css b/src/docs/components/docs-contributors/docs-contributors.css index 998b775980..edf9215136 100644 --- a/src/docs/components/docs-contributors/docs-contributors.css +++ b/src/docs/components/docs-contributors/docs-contributors.css @@ -1,26 +1,3 @@ -@define-mixin docs-contributors-ui-light { - .docs-contributors__img { - border-color: var(--ld-col-wht); - } -} -@define-mixin docs-contributors-ui-dark { - .docs-contributors__img { - border-color: var(--ld-col-neutral-800); - } -} - -@mixin docs-contributors-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-contributors-ui-dark; -} -.docs-ui-light { - @mixin docs-contributors-ui-light; -} -.docs-ui-dark { - @mixin docs-contributors-ui-dark; -} - .docs-contributors { margin: var(--ld-sp-40) 0; display: block; @@ -57,7 +34,6 @@ display: inline-flex; text-align: center; text-decoration: none; - color: var(--color-dodger-blue); border: 0; &:hover { @@ -74,5 +50,5 @@ .docs-contributors__img { border-radius: var(--ld-br-full); - border: var(--ld-sp-2) solid; + border: var(--ld-sp-1) solid var(--ld-col-neutral-800); } diff --git a/src/docs/components/docs-edit-on-github/docs-edit-on-github.css b/src/docs/components/docs-edit-on-github/docs-edit-on-github.css index b125ff5f8c..0dee118d23 100644 --- a/src/docs/components/docs-edit-on-github/docs-edit-on-github.css +++ b/src/docs/components/docs-edit-on-github/docs-edit-on-github.css @@ -1,8 +1,18 @@ -@define-mixin docs-edit-on-github-ui-light { - .docs-edit-on-github .ld-button { - background-color: var(--ld-col-wht); +.docs-edit-on-github { + display: block; + + .ld-button { + --ld-button-border-top-left-radius: calc(var(--ld-br-m) + var(--ld-sp-2)); + --ld-button-border-top-right-radius: calc(var(--ld-br-m) + var(--ld-sp-2)); + --ld-button-border-bottom-right-radius: calc( + var(--ld-br-m) + var(--ld-sp-2) + ); + --ld-button-border-bottom-left-radius: calc( + var(--ld-br-m) + var(--ld-sp-2) + ); + background-color: var(--ld-layer); color: var(--ld-col-neutral-900); - box-shadow: inset 0 0 0 2px var(--ld-col-neutral-100); + box-shadow: inset 0 0 0 2px var(--ld-layer); &:focus:focus-visible { color: var(--ld-col-neutral-900); @@ -24,46 +34,3 @@ } } } -@define-mixin docs-edit-on-github-ui-dark { - .docs-edit-on-github .ld-button { - background-color: var(--ld-col-neutral-800); - color: var(--ld-col-wht); - box-shadow: inset 0 0 0 2px var(--ld-col-neutral-600); - - &:focus:focus-visible { - color: var(--ld-col-wht); - background-color: var(--ld-col-neutral-600); - box-shadow: inset 0 0 0 2px var(--ld-col-wht); - } - - @media (hover: hover) { - &:hover { - background-color: var(--ld-col-neutral-800); - box-shadow: inset 0 0 0 2px var(--ld-col-wht); - } - } - - &:active, - &:active:focus-visible { - background-color: var(--ld-col-neutral-300); - color: var(--ld-col-neutral-900); - box-shadow: inset 0 0 0 2px var(--ld-col-neutral-300); - } - } -} - -@mixin docs-edit-on-github-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-edit-on-github-ui-dark; -} -.docs-ui-dark { - @mixin docs-edit-on-github-ui-dark; -} -.docs-ui-light { - @mixin docs-edit-on-github-ui-light; -} - -.docs-edit-on-github { - display: block; -} diff --git a/src/docs/components/docs-example/docs-example.css b/src/docs/components/docs-example/docs-example.css index 1e04d76251..5ff9963eeb 100644 --- a/src/docs/components/docs-example/docs-example.css +++ b/src/docs/components/docs-example/docs-example.css @@ -1,65 +1,9 @@ -@define-mixin docs-example-ui-light { - .docs-example__code { - background-color: var(--ld-col-neutral-010); - } - - .docs-example__tools-scroll-container { - background-color: var(--ld-col-neutral-050); - border-color: var(--ld-col-neutral-100); - } - - .docs-example__tools { - stroke: var(--ld-col-neutral-900); - } - - .docs-example__tool-buttons, - .docs-example__tool-switch, - .docs-example__copy-to-clipboard { - filter: none; - } -} -@define-mixin docs-example-ui-dark { - .docs-example__code { - background-color: var(--ld-col-neutral-900); - } - - .docs-example__tools-scroll-container { - background-color: var(--ld-col-neutral-700); - border-color: var(--ld-col-neutral-700); - } - - .docs-example__tools { - stroke: var(--ld-col-wht); - } - - .docs-example__tool-buttons, - .docs-example__tool-switch, - .docs-example__copy-to-clipboard { - filter: invert(1) hue-rotate(180deg); - } - - .docs-example--has-border .docs-example__show { - border-color: transparent; - } -} - -@mixin docs-example-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-example-ui-dark; -} -.docs-ui-light { - @mixin docs-example-ui-light; -} -.docs-ui-dark { - @mixin docs-example-ui-dark; -} - .docs-example { display: block; } .docs-example__code { + background-color: var(--ld-layer); overflow: hidden; display: none; border-bottom-left-radius: var(--ld-br-l); @@ -77,8 +21,7 @@ overflow: auto; display: flex; width: 100%; - border-style: solid; - border-width: var(--ld-sp-1); + background-color: var(--ld-layer); border-bottom-left-radius: var(--ld-br-l); border-bottom-right-radius: var(--ld-br-l); } @@ -90,6 +33,8 @@ align-items: center; flex-grow: 1; line-height: 0; /* Firefox fix */ + stroke: var(--ld-col-neutral-900); + border-inline: var(--ld-sp-1) solid transparent; } .docs-example__tool-switch { @@ -109,20 +54,14 @@ } .docs-example__show { - background-color: var(--ld-col-neutral-010); + background-color: var(--ld-layer); color: var(--ld-col-neutral-900); - border-bottom-width: 0; border-top-left-radius: var(--ld-br-l); border-top-right-radius: var(--ld-br-l); overflow: hidden; will-change: transform; /* Fixes overflow in Safari */ color-scheme: light; /* stylelint-disable-line scale-unlimited/declaration-strict-value */ - .docs-example--has-border & { - border: var(--ld-sp-1) solid var(--ld-col-neutral-100); - border-bottom: 0; - } - .docs-example--has-padding & { padding: 0 var(--ld-sp-8) var(--ld-sp-24); @@ -161,8 +100,6 @@ } .docs-example__show--brand { - border-color: transparent; - &.ld-theme-ocean { background-color: var(--ld-thm-ocean-primary); } @@ -177,7 +114,7 @@ } .docs-example__show--light { - background-color: var(--ld-col-wht); + background-color: var(--ld-layer); } .docs-example--code-visible { diff --git a/src/docs/components/docs-example/docs-example.tsx b/src/docs/components/docs-example/docs-example.tsx index 9c34089069..de88eded13 100644 --- a/src/docs/components/docs-example/docs-example.tsx +++ b/src/docs/components/docs-example/docs-example.tsx @@ -35,9 +35,6 @@ export class DocsExample { /** React component markup encoded as URI component. */ @Prop() codeReactComponent: string - /** Adds a thin border to the container. */ - @Prop() hasBorder = false - /** Puts some space between content and container. */ @Prop() hasPadding = false @@ -131,14 +128,13 @@ export class DocsExample { const cl = [ 'docs-example', this.isCodeVisible && 'docs-example--code-visible', - this.hasBorder && 'docs-example--has-border', this.hasPadding && 'docs-example--has-padding', this.codeType === 'wc' && 'docs-example--web-component', this.codeType === 'css' && 'docs-example--css-component', this.codeType === 'react' && 'docs-example--react-component', ] - let clShow = 'docs-example__show' + let clShow = 'docs-example__show ld-layer-0' if (this.themable && this.currentTheme) { clShow += ' ld-theme-' + this.currentTheme.toLowerCase() } @@ -192,7 +188,7 @@ export class DocsExample { viewBox="-11.5 -10.2 23 20.5" style={{ transform: 'scale(1.1)' }} > - + diff --git a/src/docs/components/docs-icon/docs-icon.css b/src/docs/components/docs-icon/docs-icon.css index 673e3364f0..33b9ff872a 100644 --- a/src/docs/components/docs-icon/docs-icon.css +++ b/src/docs/components/docs-icon/docs-icon.css @@ -1,38 +1,8 @@ -@define-mixin docs-icon-ui-light { - .docs-icon { - color: var(--ld-col-neutral-900); - - &__player { - filter: none; - } - } -} -@define-mixin docs-icon-ui-dark { - .docs-icon { - color: var(--ld-col-wht); - - &__player { - filter: invert(1) hue-rotate(180deg); - } - } -} - -@mixin docs-icon-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-icon-ui-dark; -} -.docs-ui-dark { - @mixin docs-icon-ui-dark; -} -.docs-ui-light { - @mixin docs-icon-ui-light; -} - .docs-icon { align-items: center; border-radius: var(--ld-br-l); border: none; + color: var(--ld-col-neutral-900); cursor: pointer; display: flex; flex-direction: column; @@ -44,7 +14,7 @@ width: 100%; &:hover { - background: var(--ld-col-neutral-010); + background: var(--ld-layer); color: var(--ld-col-neutral-900); height: calc(100% + var(--ld-sp-16)); margin: calc(var(--ld-sp-8) * -1); @@ -68,6 +38,7 @@ } &__player { + filter: none; flex: 0; margin: calc(var(--ld-sp-16) * -1) 0 calc(var(--ld-sp-8) * -1); width: 3rem; diff --git a/src/docs/components/docs-main/docs-main.css b/src/docs/components/docs-main/docs-main.css index 86f4afce46..cbdfe737be 100644 --- a/src/docs/components/docs-main/docs-main.css +++ b/src/docs/components/docs-main/docs-main.css @@ -1,223 +1,70 @@ -@define-mixin docs-main-ui-light { - .docs-main { - hr { - background-color: var(--ld-col-neutral-100); - } - - main { - > header { - ld-breadcrumbs { - filter: none; - } - } - - > p, - > ol, - > ul, - > ld-notice, - > [id^='css-variables'] + table, - > [id^='properties'] + table, - > [id^='events'] + table, - > [id^='slots'] + table, - > [id^='methods'] ~ h3 { - code { - box-shadow: inset 0 0 0 var(--ld-sp-1) var(--ld-col-neutral-100); - background-color: var(--ld-col-neutral-010); - } - } - - [id^='css-variables'] + table td, - [id^='properties'] + table td { - &:first-of-type, - &:nth-of-type(2), - &:nth-of-type(4) { - code { - &:not(:last-child) { - color: var(--ld-col-rb-010); - background-color: var(--ld-thm-ocean-primary); - box-shadow: inset 0 0 0 var(--ld-sp-1) var(--ld-col-rb-800); - } - } - } - } - - > p > a, - > ul a, - > ol a, - > table a { - color: var(--ld-col-vc-600); - - @media (hover: hover) { - &:hover { - color: var(--ld-thm-secondary); - } - } - - &:active, - &:active:focus-visible { - color: var(--ld-col-vc-700); - } - } - - > blockquote { - color: var(--ld-col-neutral-900); - background-color: var(--ld-thm-warning-focus); - border-left: solid var(--ld-sp-6) var(--ld-thm-warning); - font: var(--ld-typo-body-m); - - code { - background-color: var(--ld-thm-warning); - } - } - - > pre { - border-color: var(--ld-col-neutral-100); +.docs-main { + --ld-typo-code-s: 0.875rem / 176% 'Source Code Pro', Consolas, Monaco, + 'Ubuntu Mono', monospace; + --ld-typo-code-m: 1rem / 160% 'Source Code Pro', Consolas, Monaco, + 'Ubuntu Mono', monospace; + --docs-main-padding-x: var(--ld-sp-40); + padding: var(--ld-sp-24) var(--docs-main-padding-x) var(--ld-sp-40); + max-width: 54rem; + min-width: 20rem; - > docs-copy-to-cb { - filter: none; - } - } + @media (width <= 75rem) { + --docs-main-padding-x: var(--ld-sp-24); + } - > table { - thead tr { - border-bottom: solid var(--ld-sp-1) var(--ld-col-neutral-300); - } - tbody tr { - border-bottom: solid var(--ld-sp-1) var(--ld-col-neutral-100); - } - } - } + hr { + background-color: var(--ld-col-neutral-300); } -} -@define-mixin docs-main-ui-dark { - .docs-main { - hr { - background-color: var(--ld-col-neutral-600); - } - main { - > header { - ld-breadcrumbs { - filter: invert(1) hue-rotate(180deg); - } + main { + > p, + > ol, + > ul, + > ld-notice, + > [id^='css-variables'] + table, + > [id^='properties'] + table, + > [id^='events'] + table, + > [id^='slots'] + table, + > [id^='methods'] ~ h3 { + code { + box-shadow: inset 0 0 0 var(--ld-sp-1) var(--ld-col-neutral-100); + background-color: var(--ld-layer); } + } - > p, - > ol, - > ul, - > [id^='css-variables'] + table, - > [id^='properties'] + table, - > [id^='events'] + table, - > [id^='slots'] + table, - > [id^='methods'] ~ h3 { + [id^='css-variables'] + table td, + [id^='properties'] + table td { + &:first-of-type, + &:nth-of-type(2), + &:nth-of-type(4) { code { - box-shadow: inset 0 0 0 var(--ld-sp-1) var(--ld-col-neutral-400); - background-color: var(--ld-col-neutral-600); - } - } - - [id^='properties'] + table td { - &:first-of-type, - &:nth-of-type(2), - &:nth-of-type(4) { - code { - &:not(:last-child) { - color: var(--ld-col-rb-010); - background-color: var(--ld-thm-ocean-primary); - box-shadow: inset 0 0 0 var(--ld-sp-1) var(--ld-col-rb-400); - } - } - } - } - - [id^='css-variables'] + table td { - &:first-of-type, - &:nth-of-type(3) { - code { - &:not(:last-child) { - color: var(--ld-col-rb-010); - background-color: var(--ld-thm-ocean-primary); - box-shadow: inset 0 0 0 var(--ld-sp-1) var(--ld-col-rb-400); - } - } - } - } - - > p > a, - > ol a, - > ul a, - > table a { - color: var(--ld-col-vc-200); - - @media (hover: hover) { - &:hover { - color: var(--ld-col-vc); + &:not(:last-child) { + color: var(--ld-col-rb-010); + background-color: var(--ld-thm-ocean-primary); + box-shadow: inset 0 0 0 var(--ld-sp-1) var(--ld-col-rb-800); } } - - &:active, - &:active:focus-visible { - color: var(--ld-col-vc-600); - } - } - - > blockquote { - color: var(--ld-col-neutral-900); - background-color: var(--ld-thm-warning); - border-left: solid var(--ld-sp-6) var(--ld-thm-warning-hover); - - code { - background-color: var(--ld-thm-warning); - } } + } - > pre { - border-color: var(--ld-col-neutral-900); + > p > a, + > ul a, + > ol a, + > table a { + color: var(--ld-col-vc-600); - > docs-copy-to-cb { - filter: invert(1) hue-rotate(180deg); + @media (hover: hover) { + &:hover { + color: var(--ld-thm-secondary); } } - > table { - thead tr { - border-bottom: solid var(--ld-sp-1) var(--ld-col-wht); - } - tbody tr { - border-bottom: solid var(--ld-sp-1) var(--ld-col-neutral-700); - } + &:active, + &:active:focus-visible { + color: var(--ld-col-vc-700); } } - } -} - -@mixin docs-main-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-main-ui-dark; -} -.docs-ui-dark { - @mixin docs-main-ui-dark; -} -.docs-ui-light { - @mixin docs-main-ui-light; -} - -.docs-main { - --ld-typo-code-s: 0.875rem / 176% 'Source Code Pro', Consolas, Monaco, - 'Ubuntu Mono', monospace; - --ld-typo-code-m: 1rem / 160% 'Source Code Pro', Consolas, Monaco, - 'Ubuntu Mono', monospace; - --docs-main-padding-x: var(--ld-sp-40); - padding: var(--ld-sp-24) var(--docs-main-padding-x) var(--ld-sp-40); - max-width: 54rem; - min-width: 20rem; - @media (width <= 75rem) { - --docs-main-padding-x: var(--ld-sp-24); - } - - main { > header, > footer { display: flex; @@ -247,7 +94,7 @@ code { display: inline-flex; padding: 0 var(--ld-sp-4); - border-radius: var(--ld-br-s); + border-radius: var(--ld-br-m); } } @@ -365,16 +212,15 @@ display: block; padding-bottom: var(--ld-sp-24); - tr { + tbody tr { + border-bottom: solid var(--ld-sp-1) var(--ld-col-neutral-300); margin-top: var(--ld-sp-16); } - tbody tr:nth-child(odd) { - background-color: var(--sensitive-grey-dark); - } thead { tr { margin-top: 0; + border-bottom: solid var(--ld-sp-1) var(--ld-col-neutral-300); } th { padding-top: 0; @@ -469,7 +315,7 @@ font-family: 'Source Code Pro', Consolas, Monaco, 'Ubuntu Mono', monospace; padding: var(--ld-sp-4) var(--ld-sp-6); - border-radius: var(--ld-br-s); + border-radius: var(--ld-br-m); display: inline-flex; } } @@ -483,11 +329,15 @@ code { display: inline-flex; padding: 0 var(--ld-sp-6); - border-radius: var(--ld-br-s); + border-radius: var(--ld-br-m); } } > blockquote { + color: var(--ld-col-neutral-900); + background-color: var(--ld-thm-warning-focus); + border-left: solid var(--ld-sp-6) var(--ld-thm-warning); + font: var(--ld-typo-body-m); padding: var(--ld-sp-8) var(--ld-sp-24) var(--ld-sp-12) var(--ld-sp-24); a { @@ -495,12 +345,14 @@ } code { + background-color: var(--ld-thm-warning); + border-radius: var(--ld-br-m); padding: 0 var(--ld-sp-4); - border-radius: var(--ld-br-s); } } > pre { + border-color: var(--ld-col-neutral-100); border-radius: var(--ld-br-l); border-style: solid; border-width: var(--ld-sp-1); diff --git a/src/docs/components/docs-nav/docs-nav.css b/src/docs/components/docs-nav/docs-nav.css index 8e7f359ed5..e726d3f884 100644 --- a/src/docs/components/docs-nav/docs-nav.css +++ b/src/docs/components/docs-nav/docs-nav.css @@ -1,174 +1,62 @@ -@define-mixin docs-nav-ui-light { - .docs-nav__content { - background-color: var(--ld-col-neutral-010); - box-shadow: var(--ld-sp-1) 0 0 0 var(--ld-col-neutral-100); - } - .docs-nav::before { - background-color: var(--ld-col-neutral-010); - } - .docs-nav__section { - border-bottom-color: var(--ld-col-neutral-100); - } - .docs-nav__li { - color: var(--ld-col-neutral-600); - - a:hover, - &.docs-nav__li--active { - color: var(--ld-col-neutral-900); - } - } - .docs-nav__summary--introduction, - .docs-nav__summary--introduction + ul .docs-nav__summary { - .docs-nav__arrow { - background-image: url('dist/build/assets/chevron-introduction-dark.svg'); - } - .docs-nav__summary-toggle { - background-color: var(--ld-col-rb); - } - } - .docs-nav__summary--guides, - .docs-nav__summary--guides + ul .docs-nav__summary { - .docs-nav__arrow { - background-image: url('dist/build/assets/chevron-guides-dark.svg'); - } - .docs-nav__summary-toggle { - background-color: var(--ld-col-vc-200); - } - } - .docs-nav__summary--globals, - .docs-nav__summary--globals + ul .docs-nav__summary { - .docs-nav__arrow { - background-image: url('dist/build/assets/chevron-globals-dark.svg'); - } - .docs-nav__summary-toggle { - background-color: var(--ld-col-rp); - } - } - .docs-nav__summary--components, - .docs-nav__summary--components + ul .docs-nav__summary { - .docs-nav__arrow { - background-image: url('dist/build/assets/chevron-components-dark.svg'); - } - .docs-nav__summary-toggle { - background-color: var(--ld-col-rg); - } - } - .docs-nav__summary--data-visualization, - .docs-nav__summary--data-visualization + ul .docs-nav__summary { - .docs-nav__arrow { - background-image: url('dist/build/assets/chevron-data-visualization-dark.svg'); - } - .docs-nav__summary-toggle { - background-color: var(--ld-col-vm); - } - } - .docs-nav__li--active .docs-nav__summary--introduction { +.docs-nav__summary--introduction, +.docs-nav__summary--introduction + ul .docs-nav__summary { + .docs-nav__arrow { color: var(--ld-col-rb); } - .docs-nav__li--active .docs-nav__summary--guides { - color: var(--ld-col-vc); - } - .docs-nav__li--active .docs-nav__summary--globals { - color: var(--ld-col-rp); - } - .docs-nav__li--active .docs-nav__summary--components { - color: var(--ld-col-rg); - } - .docs-nav__li--active .docs-nav__summary--data-visualization { - color: var(--ld-col-vm); + .docs-nav__summary-toggle { + background-color: var(--ld-col-rb); } } -@define-mixin docs-nav-ui-dark { - .docs-nav__content { - background-color: var(--ld-col-neutral-900); - box-shadow: none; - } - .docs-nav::before { - background-color: var(--ld-col-neutral-900); - } - .docs-nav__section { - border-bottom-color: var(--ld-col-neutral-800); - } - .docs-nav__li { - color: var(--ld-col-neutral-200); - - a:hover, - &.docs-nav__li--active { - color: var(--ld-col-wht); - } - } - .docs-nav__summary--introduction, - .docs-nav__summary--introduction + ul .docs-nav__summary { - .docs-nav__arrow { - background-image: url('dist/build/assets/chevron-introduction-light.svg'); - } - .docs-nav__summary-toggle { - background-color: var(--ld-col-rb); - } - } - .docs-nav__summary--guides, - .docs-nav__summary--guides + ul .docs-nav__summary { - .docs-nav__arrow { - background-image: url('dist/build/assets/chevron-guides-light.svg'); - } - .docs-nav__summary-toggle { - background-color: var(--ld-col-vc); - } - } - .docs-nav__summary--globals, - .docs-nav__summary--globals + ul .docs-nav__summary { - .docs-nav__arrow { - background-image: url('dist/build/assets/chevron-globals-light.svg'); - } - .docs-nav__summary-toggle { - background-color: var(--ld-col-rp); - } +.docs-nav__summary--guides, +.docs-nav__summary--guides + ul .docs-nav__summary { + .docs-nav__arrow { + color: var(--ld-col-vc); } - .docs-nav__summary--components, - .docs-nav__summary--components + ul .docs-nav__summary { - .docs-nav__arrow { - background-image: url('dist/build/assets/chevron-components-light.svg'); - } - .docs-nav__summary-toggle { - background-color: var(--ld-col-rg); - } + .docs-nav__summary-toggle { + background-color: var(--ld-col-vc-200); } - .docs-nav__summary--data-visualization, - .docs-nav__summary--data-visualization + ul .docs-nav__summary { - .docs-nav__arrow { - background-image: url('dist/build/assets/chevron-data-visualization-light.svg'); - } - .docs-nav__summary-toggle { - background-color: var(--ld-col-vm); - } +} +.docs-nav__summary--globals, +.docs-nav__summary--globals + ul .docs-nav__summary { + .docs-nav__arrow { + color: var(--ld-col-rp); } - .docs-nav__li--active .docs-nav__summary--introduction { - color: var(--ld-col-rb-400); + .docs-nav__summary-toggle { + background-color: var(--ld-col-rp); } - .docs-nav__li--active .docs-nav__summary--guides { - color: var(--ld-col-vc-400); +} +.docs-nav__summary--components, +.docs-nav__summary--components + ul .docs-nav__summary { + .docs-nav__arrow { + color: var(--ld-col-rg); } - .docs-nav__li--active .docs-nav__summary--globals { - color: var(--ld-col-rp-400); + .docs-nav__summary-toggle { + background-color: var(--ld-col-rg); } - .docs-nav__li--active .docs-nav__summary--components { - color: var(--ld-col-rg-400); +} +.docs-nav__summary--data-visualization, +.docs-nav__summary--data-visualization + ul .docs-nav__summary { + .docs-nav__arrow { + color: var(--ld-col-vm); } - .docs-nav__li--active .docs-nav__summary--data-visualization { - color: var(--ld-col-vm-400); + .docs-nav__summary-toggle { + background-color: var(--ld-col-vm); } } - -@mixin docs-nav-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-nav-ui-dark; +.docs-nav__li--active .docs-nav__summary--introduction { + color: var(--ld-col-rb); +} +.docs-nav__li--active .docs-nav__summary--guides { + color: var(--ld-col-vc); +} +.docs-nav__li--active .docs-nav__summary--globals { + color: var(--ld-col-rp); } -.docs-ui-dark { - @mixin docs-nav-ui-dark; +.docs-nav__li--active .docs-nav__summary--components { + color: var(--ld-col-rg); } -.docs-ui-light { - @mixin docs-nav-ui-light; +.docs-nav__li--active .docs-nav__summary--data-visualization { + color: var(--ld-col-vm); } .docs-nav { @@ -180,6 +68,7 @@ pointer-events: none; &::before { + background-color: var(--ld-layer); content: ''; position: fixed; height: 100%; @@ -205,6 +94,8 @@ } .docs-nav__content { + background-color: var(--ld-layer); + box-shadow: var(--ld-sp-1) 0 0 0 var(--ld-col-neutral-100); pointer-events: all; bottom: 0; overflow: hidden scroll; @@ -221,9 +112,8 @@ } .docs-nav__section { + border-bottom: var(--ld-sp-1) solid var(--ld-col-neutral-100); padding: var(--ld-sp-24) var(--ld-sp-8) var(--ld-sp-24) 0; - border-bottom-style: solid; - border-bottom-width: var(--ld-sp-1); &:first-of-type { padding-top: 0; @@ -296,6 +186,7 @@ top: calc(-1 * var(--ld-sp-1)); background-repeat: no-repeat; background-position: center; + display: flex; width: 0.8rem; height: 1rem; align-items: center; @@ -354,8 +245,14 @@ body:not(.safari) { } .docs-nav__li { + color: var(--ld-col-neutral-600); margin-top: var(--ld-sp-12); + a:hover, + &.docs-nav__li--active { + color: var(--ld-col-neutral-900); + } + ul { padding-left: var(--ld-sp-40); } diff --git a/src/docs/components/docs-page-nav/docs-page-nav.css b/src/docs/components/docs-page-nav/docs-page-nav.css index 389367b24e..a83462c54a 100644 --- a/src/docs/components/docs-page-nav/docs-page-nav.css +++ b/src/docs/components/docs-page-nav/docs-page-nav.css @@ -1,32 +1,3 @@ -@define-mixin docs-page-nav-ui-light { - .docs-page-nav__dark { - display: none; - } - .docs-page-nav__light { - display: block; - } -} -@define-mixin docs-page-nav-ui-dark { - .docs-page-nav__dark { - display: block; - } - .docs-page-nav__light { - display: none; - } -} - -@mixin docs-page-nav-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-page-nav-ui-dark; -} -.docs-ui-dark { - @mixin docs-page-nav-ui-dark; -} -.docs-ui-light { - @mixin docs-page-nav-ui-light; -} - .docs-page-nav { display: flex; flex-wrap: wrap; diff --git a/src/docs/components/docs-page-nav/docs-page-nav.tsx b/src/docs/components/docs-page-nav/docs-page-nav.tsx index 68a07c6f0a..48a2de36a7 100644 --- a/src/docs/components/docs-page-nav/docs-page-nav.tsx +++ b/src/docs/components/docs-page-nav/docs-page-nav.tsx @@ -35,34 +35,7 @@ export class DocsPageNav { 'docs-page-nav--has-slot': this.hasSlot, }} > -
-
- {this.prevHref ? ( - - {this.prevTitle} - - ) : ( - '' - )} - {this.nextHref ? ( - - {this.nextTitle} - - ) : ( - '' - )} -
-
-
+
{this.prevHref ? ( - Liquid Oxygen on GitHub + > + +
diff --git a/src/docs/components/docs-typography/docs-typography.css b/src/docs/components/docs-typography/docs-typography.css index 247e897cdb..f045e56db8 100644 --- a/src/docs/components/docs-typography/docs-typography.css +++ b/src/docs/components/docs-typography/docs-typography.css @@ -1,27 +1,5 @@ -@define-mixin docs-typography-ui-light { - .docs-typography { - border-color: var(--ld-col-neutral-100); - } -} -@define-mixin docs-typography-ui-dark { - .docs-typography { - border-color: var(--ld-col-neutral-600); - } -} - -@mixin docs-typography-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-typography-ui-dark; -} -.docs-ui-dark { - @mixin docs-typography-ui-dark; -} -.docs-ui-light { - @mixin docs-typography-ui-light; -} - .docs-typography { + border-color: var(--ld-col-neutral-100); display: block; width: 100%; align-items: center; diff --git a/src/docs/components/docs-view-on-figma/docs-view-on-figma.css b/src/docs/components/docs-view-on-figma/docs-view-on-figma.css index 31b6675bc9..cff6ec718f 100644 --- a/src/docs/components/docs-view-on-figma/docs-view-on-figma.css +++ b/src/docs/components/docs-view-on-figma/docs-view-on-figma.css @@ -1,5 +1,8 @@ -@define-mixin docs-view-on-figma-ui-light { - .docs-view-on-figma ld-button::part(button) { +.docs-view-on-figma { + flex-shrink: 0; + display: block; + + ld-button::part(button) { background-color: var(--ld-col-neutral-800); color: var(--ld-col-wht); box-shadow: inset 0 0 0 2px var(--ld-col-neutral-800); @@ -25,48 +28,3 @@ } } } - -@define-mixin docs-view-on-figma-ui-dark { - .docs-view-on-figma ld-button::part(button) { - background-color: var(--ld-col-wht); - color: var(--ld-col-neutral-900); - box-shadow: inset 0 0 0 2px var(--ld-col-wht); - - &:focus:focus-visible { - color: var(--ld-col-neutral-900); - background-color: var(--ld-col-neutral-050); - box-shadow: inset 0 0 0 2px var(--ld-col-neutral-050); - } - - @media (hover: hover) { - &:hover { - background-color: var(--ld-col-neutral-200); - box-shadow: inset 0 0 0 2px var(--ld-col-neutral-200); - } - } - - &:active, - &:active:focus-visible { - background-color: var(--ld-col-neutral-800); - color: var(--ld-col-wht); - box-shadow: inset 0 0 0 2px var(--ld-col-neutral-800); - } - } -} - -@mixin docs-view-on-figma-ui-light; - -@media (prefers-color-scheme: dark) { - @mixin docs-view-on-figma-ui-dark; -} -.docs-ui-dark { - @mixin docs-view-on-figma-ui-dark; -} -.docs-ui-light { - @mixin docs-view-on-figma-ui-light; -} - -.docs-view-on-figma { - flex-shrink: 0; - display: block; -} diff --git a/src/docs/global/styles/code.css b/src/docs/global/styles/code.css index 9deed68840..db4bf2f957 100644 --- a/src/docs/global/styles/code.css +++ b/src/docs/global/styles/code.css @@ -64,160 +64,53 @@ code .highlight-line::before { /* ------------------------------------- Colors ------------------------------------- */ -@define-mixin docs-code-ui-light { - code[class*='language-'], - pre[class*='language-'] { - color: var(--ld-col-neutral-900); - } - :not(pre) > code[class*='language-'], - pre[class*='language-'] { - background-color: var(--ld-col-neutral-010); - } - .token.comment, - .token.prolog, - .token.doctype, - .token.cdata, - .token.punctuation { - color: var(--ld-col-neutral-600); - } - .token.property, - .token.tag, - .token.constant, - .token.symbol, - .token.boolean, - .token.deleted { - color: var(--ld-col-vm-600); - } - .token.number, - .token.selector, - .token.attr-name, - .token.string, - .token.char, - .token.builtin, - .token.inserted { - color: var(--ld-col-rg); - } - .token.atrule, - .token.attr-value, - .token.function, - .token.class-name { - color: var(--ld-col-vc-600); - } - .token.keyword, - .token.regex, - .token.important { - color: var(--ld-col-rp-600); - } - code .highlight-line::before { - border-right: var(--ld-sp-1) solid var(--ld-col-neutral-100); - color: var(--ld-col-neutral-300); - } - .highlight-line.highlight-line-active { - background-color: var(--ld-col-vy-100); - } +code[class*='language-'], +pre[class*='language-'] { + color: var(--ld-col-neutral-900); } - -@define-mixin docs-code-ui-dark { - code[class*='language-'], - pre[class*='language-'] { - color: var(--ld-col-wht); - } - :not(pre) > code[class*='language-'], - pre[class*='language-'] { - background: var(--ld-col-neutral-900); - } - .token.comment, - .token.prolog, - .token.doctype, - .token.cdata, - .token.punctuation { - color: var(--ld-col-neutral-300); - } - .token.property, - .token.tag, - .token.constant, - .token.symbol, - .token.boolean, - .token.deleted { - color: var(--ld-col-vm); - } - .token.number, - .token.selector, - .token.attr-name, - .token.string, - .token.char, - .token.builtin, - .token.inserted { - color: var(--ld-col-vg); - } - .token.atrule, - .token.attr-value, - .token.function, - .token.class-name { - color: var(--ld-col-vc); - } - .token.keyword, - .token.regex, - .token.important { - color: var(--ld-col-rp-300); - } - code .highlight-line::before { - border-right: var(--ld-sp-1) solid var(--ld-col-neutral-800); - color: var(--ld-col-neutral-600); - } - .highlight-line.highlight-line-active { - background-color: var(--ld-col-vy-100); - color: var(--ld-col-neutral-900); - - .token.comment, - .token.prolog, - .token.doctype, - .token.cdata, - .token.punctuation { - color: var(--ld-col-neutral-600); - } - .token.property, - .token.tag, - .token.constant, - .token.symbol, - .token.boolean, - .token.deleted { - color: var(--ld-col-vm-600); - } - .token.number, - .token.selector, - .token.attr-name, - .token.string, - .token.char, - .token.builtin, - .token.inserted { - color: var(--ld-col-rg); - } - .token.atrule, - .token.attr-value, - .token.function, - .token.class-name { - color: var(--ld-col-vc-600); - } - .token.keyword, - .token.regex, - .token.important { - color: var(--ld-col-rp-600); - } - code .highlight-line::before { - border-right: var(--ld-sp-1) solid var(--ld-col-neutral-100); - color: var(--ld-col-neutral-300); - } - } +:not(pre) > code[class*='language-'], +pre[class*='language-'] { + background-color: var(--ld-col-neutral-010); } - -@mixin docs-code-ui-light; -@media (prefers-color-scheme: dark) { - @mixin docs-code-ui-dark; +.token.comment, +.token.prolog, +.token.doctype, +.token.cdata, +.token.punctuation { + color: var(--ld-col-neutral-600); } -.docs-ui-light { - @mixin docs-code-ui-light; +.token.property, +.token.tag, +.token.constant, +.token.symbol, +.token.boolean, +.token.deleted { + color: var(--ld-col-vm-600); } -.docs-ui-dark { - @mixin docs-code-ui-dark; +.token.number, +.token.selector, +.token.attr-name, +.token.string, +.token.char, +.token.builtin, +.token.inserted { + color: var(--ld-col-rg); +} +.token.atrule, +.token.attr-value, +.token.function, +.token.class-name { + color: var(--ld-col-vc-600); +} +.token.keyword, +.token.regex, +.token.important { + color: var(--ld-col-rp-600); +} +code .highlight-line::before { + border-right: var(--ld-sp-1) solid var(--ld-col-neutral-100); + color: var(--ld-col-neutral-300); +} +.highlight-line.highlight-line-active { + background-color: var(--ld-col-vy-100); } diff --git a/src/docs/global/styles/global.css b/src/docs/global/styles/global.css index f4b3fc5f63..5f54a269ed 100644 --- a/src/docs/global/styles/global.css +++ b/src/docs/global/styles/global.css @@ -2,19 +2,19 @@ @import 'code.css'; @define-mixin docs-ui-light { - background-color: var(--ld-col-wht); + background-color: var(--ld-layer); color: var(--ld-col-neutral-900); body::before { - background-color: var(--ld-col-wht); + background-color: var(--ld-layer); } } @define-mixin docs-ui-dark { - background-color: var(--ld-col-neutral-800); - color: var(--ld-col-wht); + background-color: var(--ld-layer); + color: var(--ld-col-neutral-900); body::before { - background-color: var(--ld-col-neutral-800); + background-color: var(--ld-layer); } } diff --git a/src/docs/includes/layout.njk b/src/docs/includes/layout.njk index ed988684b7..01b2f6df1e 100644 --- a/src/docs/includes/layout.njk +++ b/src/docs/includes/layout.njk @@ -3,7 +3,7 @@ title: Introduction --- - + @@ -55,18 +55,16 @@ title: Introduction - +