From 7a69faee35ab92e4faccdc3d67f5e9aa72cb705e Mon Sep 17 00:00:00 2001 From: MadCcc Date: Fri, 7 Feb 2025 20:01:59 +0800 Subject: [PATCH] feat: css var support layer --- src/hooks/useCSSVarRegister.ts | 9 ++++++--- src/hooks/useStyleRegister.tsx | 7 +------ src/interface.ts | 4 ++++ src/util/css-variables.ts | 24 +++++++++++++++++++++--- 4 files changed, 32 insertions(+), 12 deletions(-) create mode 100644 src/interface.ts diff --git a/src/hooks/useCSSVarRegister.ts b/src/hooks/useCSSVarRegister.ts index b02f1f4..7cc01c7 100644 --- a/src/hooks/useCSSVarRegister.ts +++ b/src/hooks/useCSSVarRegister.ts @@ -10,7 +10,7 @@ import type { TokenWithCSSVar } from '../util/css-variables'; import { transformToken } from '../util/css-variables'; import type { ExtractStyle } from './useGlobalCache'; import useGlobalCache from './useGlobalCache'; -import { uniqueHash } from './useStyleRegister'; +import { LayerConfig, uniqueHash } from './useStyleRegister'; export const CSS_VAR_PREFIX = 'cssVar'; @@ -30,17 +30,19 @@ const useCSSVarRegister = >( ignore?: Record; scope?: string; token: any; + layer?: LayerConfig; }, fn: () => T, ) => { - const { key, prefix, unitless, ignore, token, scope = '' } = config; + const { key, prefix, unitless, ignore, token, scope = '', layer } = config; const { cache: { instanceId }, container, + layer: enableLayer, } = useContext(StyleContext); const { _tokenKey: tokenKey } = token; - const stylePath = [...config.path, key, scope, tokenKey]; + const stylePath = [...config.path, key, scope, tokenKey, enableLayer]; const cache = useGlobalCache>( CSS_VAR_PREFIX, @@ -52,6 +54,7 @@ const useCSSVarRegister = >( unitless, ignore, scope, + layer, }); const styleId = uniqueHash(stylePath, cssVarsStr); return [mergedToken, cssVarsStr, styleId, key]; diff --git a/src/hooks/useStyleRegister.tsx b/src/hooks/useStyleRegister.tsx index 529d29d..ce2a3b3 100644 --- a/src/hooks/useStyleRegister.tsx +++ b/src/hooks/useStyleRegister.tsx @@ -6,6 +6,7 @@ import * as React from 'react'; import unitless from '@emotion/unitless'; import { compile, serialize, stringify } from 'stylis'; import type { Theme, Transformer } from '..'; +import type { LayerConfig } from '../interface'; import type Keyframes from '../Keyframes'; import type { Linter } from '../linters'; import { contentQuotesLinter, hashedAnimationLinter } from '../linters'; @@ -28,11 +29,6 @@ import useGlobalCache from './useGlobalCache'; const SKIP_CHECK = '_skip_check_'; const MULTI_VALUE = '_multi_value_'; -export interface LayerConfig { - name: string; - dependencies?: string[]; -} - export type CSSProperties = Omit< CSS.PropertiesFallback, 'animationName' @@ -333,7 +329,6 @@ export const parseStyle = ( if (!root) { styleStr = `{${styleStr}}`; } else if (layer) { - // fixme: https://github.com/thysultan/stylis/pull/339 if (styleStr) { styleStr = `@layer ${layer.name} {${styleStr}}`; diff --git a/src/interface.ts b/src/interface.ts new file mode 100644 index 0000000..0d2446b --- /dev/null +++ b/src/interface.ts @@ -0,0 +1,4 @@ +export interface LayerConfig { + name: string; + dependencies?: string[]; +} diff --git a/src/util/css-variables.ts b/src/util/css-variables.ts index 6f77ad6..c7095fb 100644 --- a/src/util/css-variables.ts +++ b/src/util/css-variables.ts @@ -1,3 +1,5 @@ +import type { LayerConfig } from '../interface'; + export const token2CSSVar = (token: string, prefix = '') => { return `--${prefix ? `${prefix}-` : ''}${token}` .replace(/([a-z0-9])([A-Z])/g, '$1-$2') @@ -8,19 +10,28 @@ export const token2CSSVar = (token: string, prefix = '') => { export const serializeCSSVar = >( cssVars: T, - hashId: string, + cssVarKey: string, options?: { scope?: string; + layer?: LayerConfig; }, ) => { if (!Object.keys(cssVars).length) { return ''; } - return `.${hashId}${ + + const { layer } = options || {}; + + let cssVarStr = `.${cssVarKey}${ options?.scope ? `.${options.scope}` : '' }{${Object.entries(cssVars) .map(([key, value]) => `${key}:${value};`) .join('')}}`; + + if (layer) { + cssVarStr = `@layer ${layer.name} {${cssVarStr}}`; + } + return cssVarStr; }; export type TokenWithCSSVar< @@ -48,6 +59,7 @@ export const transformToken = < [key in keyof T]?: boolean; }; scope?: string; + layer?: LayerConfig; }, ): [TokenWithCSSVar, string] => { const cssVars: Record = {}; @@ -67,5 +79,11 @@ export const transformToken = < result[key as keyof T] = `var(${cssVar})`; } }); - return [result, serializeCSSVar(cssVars, themeKey, { scope: config?.scope })]; + return [ + result, + serializeCSSVar(cssVars, themeKey, { + scope: config?.scope, + layer: config?.layer, + }), + ]; };