From f054380db7cec0715e5a4eba96ff57e69fab3b56 Mon Sep 17 00:00:00 2001 From: Arvin Xu Date: Sun, 2 Jul 2023 00:19:44 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20feat:=20=E4=BC=98=E5=8C=96=20Babel?= =?UTF-8?q?=20=E6=8F=92=E4=BB=B6=20(#77)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * :sparkles: feat: Babel 插件支持显示样式 key * 🐛 fix: 修正 部分场景下 Babel 插件会导致样式失效的问题 --------- Co-authored-by: semantic-release-bot --- CHANGELOG.md | 6 ++++++ package.json | 2 +- src/core/createCSS.ts | 11 +++++----- src/core/insertStyles.ts | 27 +++--------------------- src/factories/createStyles/index.ts | 32 ++++++++++++++++++++++------- 5 files changed, 40 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04966cc4..ba0bc3f7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +# [3.4.0-alpha.1](https://github.com/ant-design/antd-style/compare/v3.3.0...v3.4.0-alpha.1) (2023-07-01) + +### ✨ Features + +- Babel 插件支持显示 key 前缀 ([87ae9c4](https://github.com/ant-design/antd-style/commit/87ae9c4)) + # [3.3.0](https://github.com/ant-design/antd-style/compare/v3.2.3...v3.3.0) (2023-06-05) ### ✨ Features diff --git a/package.json b/package.json index f49bcf18..bdedd484 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "antd-style", - "version": "3.3.0", + "version": "3.4.0-alpha.1", "description": "a css-in-js solution for application combine with antd v5 token system and emotion", "keywords": [ "antd", diff --git a/src/core/createCSS.ts b/src/core/createCSS.ts index ca3344b6..cb8f6465 100644 --- a/src/core/createCSS.ts +++ b/src/core/createCSS.ts @@ -1,17 +1,17 @@ -import { createHashStyleName, insertStyles, InternalClassNameOption } from '@/core/insertStyles'; -import { ClassNameGenerator, ClassNamesUtil } from '@/types'; +import { createHashStyleName, insertStyles } from '@/core/insertStyles'; +import { ClassNameGenerator, ClassNameGeneratorOption, ClassNamesUtil } from '@/types'; import { classnames, isReactCssResult, mergeCSS } from '@/utils'; import { EmotionCache } from '@emotion/css/create-instance'; import { serializeStyles } from '@emotion/serialize'; const createClassNameGenerator = - (cache: EmotionCache, options: InternalClassNameOption): ClassNameGenerator => + (cache: EmotionCache, options: ClassNameGeneratorOption): ClassNameGenerator => (...args) => { const serialized = serializeStyles(args, cache.registered, undefined); insertStyles(cache, serialized, false, options); - return createHashStyleName(cache.key, serialized.name, options); + return createHashStyleName(cache.key, serialized.name); }; const createCX = @@ -29,11 +29,10 @@ const createCX = * @param cache * @param options */ -export const createCSS = (cache: EmotionCache, options: InternalClassNameOption) => { +export const createCSS = (cache: EmotionCache, options: ClassNameGeneratorOption) => { const css = createClassNameGenerator(cache, { hashPriority: options.hashPriority || 'high', label: options.label, - __BABEL_FILE_NAME__: options.__BABEL_FILE_NAME__, }); const cx = createCX(cache, css); diff --git a/src/core/insertStyles.ts b/src/core/insertStyles.ts index 08227711..f28ae233 100644 --- a/src/core/insertStyles.ts +++ b/src/core/insertStyles.ts @@ -6,28 +6,7 @@ import { registerStyles } from '@emotion/utils'; const isBrowser = typeof document !== 'undefined'; -export interface InternalClassNameOption extends ClassNameGeneratorOption { - /** - * 用于生成 className 的文件名,用于 babel 插件使用,不对用户透出 - */ - __BABEL_FILE_NAME__?: string; -} - -export const createHashStyleName = ( - cacheKey: string, - hash: string, - options?: InternalClassNameOption, -) => { - const fileName = options?.__BABEL_FILE_NAME__; - const label = options?.label; - - const babelSuffix = fileName ? `__${fileName}` : ''; - const labelSuffix = label ? `__${label}` : ''; - - const prefix = `${cacheKey}-${hash}`; - - return prefix + labelSuffix + babelSuffix; -}; +export const createHashStyleName = (cacheKey: string, hash: string) => `${cacheKey}-${hash}`; /** * 向浏览器插入样式表 @@ -40,12 +19,12 @@ export const insertStyles = ( cache: EmotionCache, serialized: SerializedStyles, isStringTag: boolean, - options: InternalClassNameOption, + options: ClassNameGeneratorOption, ) => { const hashPriority = options.hashPriority || 'high'; registerStyles(cache, serialized, isStringTag); - const hashClassName = `.${createHashStyleName(cache.key, serialized.name, options)}`; + const hashClassName = `.${createHashStyleName(cache.key, serialized.name)}`; const hashSelector = hashPriority === 'low' ? `:where(${hashClassName})` : hashClassName; diff --git a/src/factories/createStyles/index.ts b/src/factories/createStyles/index.ts index 33b8669c..baba29ad 100644 --- a/src/factories/createStyles/index.ts +++ b/src/factories/createStyles/index.ts @@ -3,7 +3,6 @@ import { Context, useContext, useMemo } from 'react'; import { Emotion, createCSS, serializeCSS } from '@/core'; import type { BaseReturnType, - CSSObject, ClassNameGeneratorOption, HashPriority, ResponsiveUtil, @@ -11,7 +10,6 @@ import type { } from '@/types'; import { isReactCssResult } from '@/utils'; -import { InternalClassNameOption } from '@/core/insertStyles'; import { convertResponsiveStyleToString, useMediaQueryMap } from './response'; import { ReturnStyles, StyleOrGetStyleFn } from './types'; @@ -21,6 +19,13 @@ interface CreateStylesFactory { useTheme: () => any; } +interface InternalClassNameOption { + /** + * 用于生成 className 的文件名,用于 babel 插件使用,不对用户透出 + */ + __BABEL_FILE_NAME__?: string; +} + /** * 创建样式基础写法 */ @@ -30,6 +35,11 @@ export const createStylesFactory = styleOrGetStyle: StyleOrGetStyleFn, options?: ClassNameGeneratorOption, ) => { + // 从该字段可以获得当前文件的文件名 + const styleFileName = (options as InternalClassNameOption)?.__BABEL_FILE_NAME__; + // 判断是否使用 babel 插件,如果有在用 babel 插件,则有一个特殊的内部字段 + const usingBabel = !!styleFileName; + // 返回 useStyles 方法,作为 hooks 使用 return (props?: Props): ReturnStyles => { const theme = useTheme(); @@ -38,7 +48,6 @@ export const createStylesFactory = const { cx, css: toClassName } = createCSS(cache, { hashPriority: options?.hashPriority || hashPriority, label: options?.label, - __BABEL_FILE_NAME__: (options as InternalClassNameOption)?.__BABEL_FILE_NAME__, }); const responsiveMap = useMediaQueryMap(); @@ -86,13 +95,22 @@ export const createStylesFactory = // 不是的话就是直接是 复合的 css object tempStyles = Object.fromEntries( Object.entries(tempStyles).map(([key, value]) => { - // 这里有可能是 x:{ color:red } 也可能是 c:reactCss`color:red`; - // 但无论哪种,都可以直接用 css 包一下转换成 className + // 这里做两道转换: + // 1. 如果是用 babel 插件,则将样式的 label 设置为当前文件名 + key + // 2. 如果是 SerializedStyles ,将其用 cx 包一下转换成 className + + const label = usingBabel ? `${styleFileName}-${key}` : undefined; + + // 这里有可能是 { a : css` color:red ` } 也可能是 { b: { color:"blue" } } 这样的写法 if (typeof value === 'object') { - return [key, toClassName(value as CSSObject)]; + if (usingBabel) { + return [key, toClassName(value, `label:${label}`) as any]; + } + + return [key, toClassName(value) as any]; } - // 这里只可能是 c: css`color:red`; css 直接来自 antd-style,因此啥也不用处理 + // 这里只可能是 { c: cx(css`color:red`) } , 或者 d: 'abcd' 这样的写法 return [key, value]; }), ) as any;