Skip to content

Commit

Permalink
feat: enabling css variables v1 via tailwind
Browse files Browse the repository at this point in the history
  • Loading branch information
yue4u committed Dec 19, 2024
1 parent f6f3b6e commit 518be75
Show file tree
Hide file tree
Showing 6 changed files with 204 additions and 10 deletions.
1 change: 1 addition & 0 deletions .storybook/tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module.exports = {
':root': light,
'[data-dark="true"]': dark,
},
cssVariablesV1: false,
unstableTokenV2: true,
}),
],
Expand Down
81 changes: 81 additions & 0 deletions packages/tailwind-config/src/__snapshots__/index.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -4641,6 +4641,87 @@ exports[`tailwind.config.js > list of css variables 1`] = `
"--tailwind-color-border--hover",
"--tailwind-color-border--press",
"--tailwind-color-border--outline",
"--charcoal-transparent",
"--charcoal-transparent-hover",
"--charcoal-transparent-press",
"--charcoal-background1",
"--charcoal-background1-hover",
"--charcoal-background1-press",
"--charcoal-background2",
"--charcoal-background2-hover",
"--charcoal-background2-press",
"--charcoal-icon6",
"--charcoal-icon6-hover",
"--charcoal-icon6-press",
"--charcoal-link1",
"--charcoal-link1-hover",
"--charcoal-link1-press",
"--charcoal-link2",
"--charcoal-link2-hover",
"--charcoal-link2-press",
"--charcoal-surface1",
"--charcoal-surface1-hover",
"--charcoal-surface1-press",
"--charcoal-surface2",
"--charcoal-surface2-hover",
"--charcoal-surface2-press",
"--charcoal-surface3",
"--charcoal-surface3-hover",
"--charcoal-surface3-press",
"--charcoal-surface4",
"--charcoal-surface4-hover",
"--charcoal-surface4-press",
"--charcoal-surface6",
"--charcoal-surface6-hover",
"--charcoal-surface6-press",
"--charcoal-surface7",
"--charcoal-surface7-hover",
"--charcoal-surface7-press",
"--charcoal-surface8",
"--charcoal-surface8-hover",
"--charcoal-surface8-press",
"--charcoal-surface9",
"--charcoal-surface9-hover",
"--charcoal-surface9-press",
"--charcoal-surface10",
"--charcoal-surface10-hover",
"--charcoal-surface10-press",
"--charcoal-text1",
"--charcoal-text1-hover",
"--charcoal-text1-press",
"--charcoal-text2",
"--charcoal-text2-hover",
"--charcoal-text2-press",
"--charcoal-text3",
"--charcoal-text3-hover",
"--charcoal-text3-press",
"--charcoal-text4",
"--charcoal-text4-hover",
"--charcoal-text4-press",
"--charcoal-text5",
"--charcoal-text5-hover",
"--charcoal-text5-press",
"--charcoal-brand",
"--charcoal-brand-hover",
"--charcoal-brand-press",
"--charcoal-assertive",
"--charcoal-assertive-hover",
"--charcoal-assertive-press",
"--charcoal-warning",
"--charcoal-warning-hover",
"--charcoal-warning-press",
"--charcoal-success",
"--charcoal-success-hover",
"--charcoal-success-press",
"--charcoal-updatedItem",
"--charcoal-updatedItem-hover",
"--charcoal-updatedItem-press",
"--charcoal-border",
"--charcoal-border-hover",
"--charcoal-border-press",
"--charcoal-border-default",
"--charcoal-border-default-hover",
"--charcoal-border-default-press",
"--tailwind-gradient-surface5-top",
"--tailwind-gradient-surface5-top-disabled",
"--tailwind-gradient-surface5-top-hover",
Expand Down
6 changes: 3 additions & 3 deletions packages/tailwind-config/src/_lib/TailwindBuild.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ export class TailwindBuild {
const cssVariables = new Set<string>()

/**
* 独自に生成する CSS 変数は必ず --tailwind で始まるはず
* 独自に生成する CSS 変数は必ず --(tailwind|charcoal) で始まるはず
*/
this.result.root.walkDecls(/^--tailwind/u, (decl) => {
this.result.root.walkDecls(/^--(tailwind|charcoal)/u, (decl) => {
cssVariables.add(decl.prop)
})

Expand All @@ -101,7 +101,7 @@ export class TailwindBuild {
getCssVariable(varName: `--${string}`) {
const values: string[] = []

this.result.root.walkDecls(/^--tailwind/u, (decl) => {
this.result.root.walkDecls(/^--(tailwind|charcoal)/u, (decl) => {
if (decl.prop === varName) {
values.push(decl.value)
}
Expand Down
23 changes: 17 additions & 6 deletions packages/tailwind-config/src/colors/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,30 @@ import plugin, { TailwindPlugin } from 'tailwindcss/plugin'
import { mergeEffect } from '../foundation'
import { CSSVariableName, CSSVariables, Definition, ThemeMap } from '../types'
import { COLOR_PREFIX, isSingleColor } from './utils'
import { defineCssVariablesV1 } from './pluginTokenV1'

/**
* `:root` 以外のケースで各 CSS Variable がどういう値を取るかを定義する
* --tailwind-* また --charcoal-* を生成する
* TODO: --tailwindをやめる
*/
export default function cssVariableColorPlugin({
':root': _defaultTheme,
...themes
}: ThemeMap): TailwindPlugin {
const definitions = defineCssVariables(themes)
export default function cssVariableColorPlugin(
themeMap: ThemeMap,
cssVariablesV1: boolean
): TailwindPlugin {
// `:root` 以外のケースで各 CSS Variable がどういう値を取るかを定義する
const { ':root': _defaultTheme, ...otherThemes } = themeMap
const definitions = defineCssVariables(otherThemes)

return plugin(({ addBase }) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
addBase(definitions)

// styledのTokenInjector移植(background処理除く)
if (cssVariablesV1) {
const cssVariablesV1 = defineCssVariablesV1(themeMap)
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
addBase(cssVariablesV1)
}
})
}

Expand Down
99 changes: 99 additions & 0 deletions packages/tailwind-config/src/colors/pluginTokenV1.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import {
applyEffect,
customPropertyToken,
filterObject,
flatMapObject,
mapObject,
} from '@charcoal-ui/utils'
import { ThemeMap } from '../types'
import {
CharcoalAbstractTheme,
EffectType,
Key,
CharcoalTheme as Theme,
} from '@charcoal-ui/theme'

export function defineCssVariablesV1(themeMap: ThemeMap) {
// @ts-expect-error FIXME
return mapObject(themeMap, (key, theme) => {
if (key.startsWith('@media')) {
return [
key,
{
':root': defineColorVariableCSS(theme),
},
]
} else {
return [key, defineColorVariableCSS(theme)]
}
})
}

export const defineColorVariableCSS = (theme: Theme) => {
const borders = mapObject(theme.border, (name, { color }) => [
// REVIEW: もしtheme.colorにたまたまborder-〇〇で始まる色名がいたら被りうる
withPrefixes('border', name),
color,
])

const colors = defineThemeVariables({ ...theme.color, ...borders })({ theme })
return colors
}

/**
* Check whether a value is non-null and non-undefined
*
* @param value nullable
*/
export const isPresent = <T>(value: T): value is NonNullable<T> => value != null

/**
* 子孫要素で使われるカラーテーマの CSS Variables を上書きする
*
* @params colorParams - 上書きしたい色の定義( `theme.color` の一部だけ書けば良い )
* @params effectParams - effect の定義を上書きしたい場合は渡す(必須ではない)
*
* @example
* ```tsx
* const LocalTheme = styled.div`
* ${defineThemeVariables({ text1: '#ff0000' })}
* // `text1` is now defined as red
* ${theme((o) => [o.font.text1])}
* `
* ```
*/
export function defineThemeVariables(
colorParams: Partial<CharcoalAbstractTheme['color']>,
effectParams?: Partial<CharcoalAbstractTheme['effect']>
) {
return function toCssObject(props: {
theme: Pick<CharcoalAbstractTheme, 'effect'>
}) {
const colors = filterObject(colorParams, isPresent)

// flatMapObject の中で毎回 Object.entries を呼ぶのは無駄なので外で呼ぶ
const effects = Object.entries({
...props.theme.effect,
...effectParams,
})

return flatMapObject(colors, (colorKey, color) => [
[customPropertyToken(colorKey), color],

...effects.map<[string, string]>(([effectKey, effect]) => [
customPropertyToken(colorKey, [effectKey]),
applyEffect(color, [effect]),
]),
])
}
}

export function isSupportedEffect(effect: Key): effect is EffectType {
return ['hover', 'press', 'disabled'].includes(effect as string)
}

export const variable = (value: string) => `var(${value})`

export function withPrefixes(...parts: string[]) {
return parts.join('-')
}
4 changes: 3 additions & 1 deletion packages/tailwind-config/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,14 @@ export { unstable_createTailwindConfigTokenV2 }
interface Options {
version?: TailwindVersion
theme?: ThemeMap
cssVariablesV1?: boolean
unstableTokenV2?: boolean
}

export function createTailwindConfig({
theme = { ':root': light },
version = 'v3',
cssVariablesV1 = true,
unstableTokenV2 = false,
}: Options): TailwindConfig {
assertAllThemeHaveSameKeys(theme)
Expand Down Expand Up @@ -151,7 +153,7 @@ export function createTailwindConfig({
},
plugins: [
typographyPlugin,
cssVariableColorPlugin(theme),
cssVariableColorPlugin(theme, Boolean(cssVariablesV1)),

...Object.entries(theme).map(([selectorOrMediaQuery, theme]) =>
cssVariableGradientPlugin(
Expand Down

0 comments on commit 518be75

Please sign in to comment.