From 5968c0518d88925e8e034ba491cce2fb7d731376 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=9F=E8=B4=A4?= Date: Mon, 5 Jun 2023 13:32:23 +0800 Subject: [PATCH 1/5] feat: support gen className by filename --- src/core/createCSS.ts | 20 ++++++++++++++++---- src/factories/createStyles/index.ts | 8 ++++++-- src/functions/createInstance.ts | 1 - src/types/index.ts | 2 +- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/core/createCSS.ts b/src/core/createCSS.ts index 32996a88..ff2d3f4d 100644 --- a/src/core/createCSS.ts +++ b/src/core/createCSS.ts @@ -4,12 +4,20 @@ import { classnames, isReactCssResult, mergeCSS } from '@/utils'; import { EmotionCache } from '@emotion/css/create-instance'; import { serializeStyles } from '@emotion/serialize'; +type ClassNameGeneratorOption = { + fileName?: string; +}; + const createClassNameGenerator = - (cache: EmotionCache, hashPriority: HashPriority): ClassNameGenerator => + ( + cache: EmotionCache, + hashPriority: HashPriority, + options?: ClassNameGeneratorOption, + ): ClassNameGenerator => (...args) => { const serialized = serializeStyles(args, cache.registered, undefined); insertStyles(cache, serialized, false, hashPriority); - return `${cache.key}-${serialized.name}`; + return `${cache.key}${options?.fileName ? `-${options?.fileName}` : ''}-${serialized.name}`; }; const createCX = @@ -27,8 +35,12 @@ const createCX = * @param cache * @param hashPriority */ -export const createCSS = (cache: EmotionCache, hashPriority: HashPriority = 'high') => { - const css = createClassNameGenerator(cache, hashPriority); +export const createCSS = ( + cache: EmotionCache, + hashPriority: HashPriority = 'high', + options?: ClassNameGeneratorOption, +) => { + const css = createClassNameGenerator(cache, hashPriority, options); const cx = createCX(cache, css); return { css, cx }; diff --git a/src/factories/createStyles/index.ts b/src/factories/createStyles/index.ts index d9b72109..0711a0ea 100644 --- a/src/factories/createStyles/index.ts +++ b/src/factories/createStyles/index.ts @@ -21,6 +21,7 @@ interface CreateStylesFactory { export interface CreateStyleOptions { hashPriority?: HashPriority; + fileName?: string; } /** @@ -35,10 +36,13 @@ export const createStylesFactory = // 返回 useStyles 方法,作为 hooks 使用 return (props?: Props): ReturnStyles => { const theme = useTheme(); - const { cache } = useContext(EmotionContext); // 由于 toClassName 方法依赖了用户给 createStyle 传递的 hashPriority,所以需要在这里重新生成 cx 和 toClassName 方法 - const { cx, css: toClassName } = createCSS(cache, options?.hashPriority || hashPriority); + const { cx, css: toClassName } = createCSS( + cache, + options?.hashPriority || hashPriority, + options, + ); const responsiveMap = useMediaQueryMap(); diff --git a/src/functions/createInstance.ts b/src/functions/createInstance.ts index 64d6313c..dc1aa68f 100644 --- a/src/functions/createInstance.ts +++ b/src/functions/createInstance.ts @@ -68,7 +68,6 @@ export const createInstance = (options: CreateOptions) => { speedy: internalOptions.speedy, container: internalOptions.container, }); - const EmotionContext = createEmotionContext(emotion); const StyleProvider = createStyleProvider(EmotionContext); diff --git a/src/types/index.ts b/src/types/index.ts index d199708b..399d9a4e 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -3,6 +3,6 @@ export * from './css'; export * from './function'; export * from './genericUtils'; export * from './response'; -export * from './styled'; export * from './styleManager'; +export * from './styled'; export * from './theme'; From c05c2c75233cbdc55e328faf7e2f56e5d381834f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9C=9F=E8=B4=A4?= Date: Mon, 5 Jun 2023 14:02:00 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/factories/createStyles/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/factories/createStyles/index.ts b/src/factories/createStyles/index.ts index 0711a0ea..98ba3067 100644 --- a/src/factories/createStyles/index.ts +++ b/src/factories/createStyles/index.ts @@ -21,6 +21,7 @@ interface CreateStylesFactory { export interface CreateStyleOptions { hashPriority?: HashPriority; + // 用于生成 className 的文件名,用于 babel 插件使用,不建议用户使用 fileName?: string; } From 91264110c1592232953c99d282cb991e414d8e6b Mon Sep 17 00:00:00 2001 From: arvinxx Date: Mon, 5 Jun 2023 14:36:18 +0800 Subject: [PATCH 3/5] =?UTF-8?q?:recycle:=20refactor:=20=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=20className=20options?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/createCSS.ts | 34 ++++++++++++----------------- src/core/insertStyles.ts | 13 +++++++---- src/factories/createStyles/index.ts | 18 +++++---------- src/functions/createInstance.ts | 2 +- src/types/css.ts | 8 +++++++ 5 files changed, 38 insertions(+), 37 deletions(-) diff --git a/src/core/createCSS.ts b/src/core/createCSS.ts index ff2d3f4d..bd19b745 100644 --- a/src/core/createCSS.ts +++ b/src/core/createCSS.ts @@ -1,23 +1,17 @@ -import { insertStyles } from '@/core/insertStyles'; -import { ClassNameGenerator, ClassNamesUtil, HashPriority } 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'; -type ClassNameGeneratorOption = { - fileName?: string; -}; - const createClassNameGenerator = - ( - cache: EmotionCache, - hashPriority: HashPriority, - options?: ClassNameGeneratorOption, - ): ClassNameGenerator => + (cache: EmotionCache, options: ClassNameGeneratorOption): ClassNameGenerator => (...args) => { const serialized = serializeStyles(args, cache.registered, undefined); - insertStyles(cache, serialized, false, hashPriority); - return `${cache.key}${options?.fileName ? `-${options?.fileName}` : ''}-${serialized.name}`; + + insertStyles(cache, serialized, false, options); + + return createHashStyleName(cache.key, serialized.name, options.fileName); }; const createCX = @@ -33,14 +27,14 @@ const createCX = /** * CSS相关方法生成器 用于序列化的样式转换生成 className * @param cache - * @param hashPriority + * @param options */ -export const createCSS = ( - cache: EmotionCache, - hashPriority: HashPriority = 'high', - options?: ClassNameGeneratorOption, -) => { - const css = createClassNameGenerator(cache, hashPriority, options); +export const createCSS = (cache: EmotionCache, options: ClassNameGeneratorOption) => { + const css = createClassNameGenerator(cache, { + hashPriority: options.hashPriority || 'high', + fileName: options.fileName, + }); + const cx = createCX(cache, css); return { css, cx }; diff --git a/src/core/insertStyles.ts b/src/core/insertStyles.ts index ae72412c..6352e673 100644 --- a/src/core/insertStyles.ts +++ b/src/core/insertStyles.ts @@ -1,27 +1,32 @@ // copied from https://github.com/emotion-js/emotion/blob/main/packages/utils/src/index.js -import type { HashPriority } from '@/types'; +import { ClassNameGeneratorOption } from '@/types'; import type { EmotionCache } from '@emotion/css/create-instance'; import type { SerializedStyles } from '@emotion/serialize'; import { registerStyles } from '@emotion/utils'; const isBrowser = typeof document !== 'undefined'; +export const createHashStyleName = (cacheKey: string, hash: string, fileName?: string) => { + return `${cacheKey}-${hash}${fileName ? `__${fileName}` : ''}`; +}; + /** * 向浏览器插入样式表 * @param cache * @param serialized * @param isStringTag - * @param hashPriority + * @param options */ export const insertStyles = ( cache: EmotionCache, serialized: SerializedStyles, isStringTag: boolean, - hashPriority: HashPriority = 'high', + options: ClassNameGeneratorOption, ) => { + const hashPriority = options.hashPriority || 'high'; registerStyles(cache, serialized, isStringTag); - const hashClassName = `.${cache.key}-${serialized.name}`; + const hashClassName = `.${createHashStyleName(cache.key, serialized.name, options.fileName)}`; const hashSelector = hashPriority === 'low' ? `:where(${hashClassName})` : hashClassName; diff --git a/src/factories/createStyles/index.ts b/src/factories/createStyles/index.ts index 98ba3067..1fe4848c 100644 --- a/src/factories/createStyles/index.ts +++ b/src/factories/createStyles/index.ts @@ -4,6 +4,7 @@ import { Emotion, createCSS, serializeCSS } from '@/core'; import type { BaseReturnType, CSSObject, + ClassNameGeneratorOption, HashPriority, ResponsiveUtil, ReturnStyleToUse, @@ -19,12 +20,6 @@ interface CreateStylesFactory { useTheme: () => any; } -export interface CreateStyleOptions { - hashPriority?: HashPriority; - // 用于生成 className 的文件名,用于 babel 插件使用,不建议用户使用 - fileName?: string; -} - /** * 创建样式基础写法 */ @@ -32,18 +27,17 @@ export const createStylesFactory = ({ hashPriority, useTheme, EmotionContext }: CreateStylesFactory) => ( styleOrGetStyle: StyleOrGetStyleFn, - options?: CreateStyleOptions, + options?: ClassNameGeneratorOption, ) => { // 返回 useStyles 方法,作为 hooks 使用 return (props?: Props): ReturnStyles => { const theme = useTheme(); const { cache } = useContext(EmotionContext); // 由于 toClassName 方法依赖了用户给 createStyle 传递的 hashPriority,所以需要在这里重新生成 cx 和 toClassName 方法 - const { cx, css: toClassName } = createCSS( - cache, - options?.hashPriority || hashPriority, - options, - ); + const { cx, css: toClassName } = createCSS(cache, { + hashPriority: options?.hashPriority || hashPriority, + fileName: options?.fileName, + }); const responsiveMap = useMediaQueryMap(); diff --git a/src/functions/createInstance.ts b/src/functions/createInstance.ts index dc1aa68f..484b91d2 100644 --- a/src/functions/createInstance.ts +++ b/src/functions/createInstance.ts @@ -108,7 +108,7 @@ export const createInstance = (options: CreateOptions) => { }); // ******** 上面这些都和主题相关,如果做了任何改动,都需要排查一遍 ************ // - const { cx } = createCSS(emotion.cache, internalOptions.hashPriority); + const { cx } = createCSS(emotion.cache, { hashPriority: internalOptions.hashPriority }); const { injectGlobal, keyframes } = emotion; return { diff --git a/src/types/css.ts b/src/types/css.ts index 5c875adb..c5233899 100644 --- a/src/types/css.ts +++ b/src/types/css.ts @@ -9,6 +9,14 @@ export type { SerializedStyles } from '@emotion/serialize'; export type ClassNameGenerator = Emotion['css']; +export type ClassNameGeneratorOption = { + /** + * 用于生成 className 的文件名,用于 babel 插件使用,不建议用户使用 + */ + fileName?: string; + hashPriority?: HashPriority; +}; + /** * @title CSS 工具函数 * @param template - 模板字符串数组 From 6a9a60f3ebe4525466dcaa2811bb10cd5ed32228 Mon Sep 17 00:00:00 2001 From: arvinxx Date: Mon, 5 Jun 2023 18:09:29 +0800 Subject: [PATCH 4/5] =?UTF-8?q?:recycle:=20refactor:=20filename=20?= =?UTF-8?q?=E9=87=8D=E6=9E=84=E4=B8=BA=20=5F=5FBABEL=5FFILE=5FNAME=5F=5F?= =?UTF-8?q?=20=EF=BC=8C=E4=BD=9C=E4=B8=BA=E5=86=85=E9=83=A8=20api?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/core/createCSS.ts | 5 +++-- src/core/insertStyles.ts | 10 ++++++++-- src/factories/createStyles/index.ts | 3 ++- src/types/css.ts | 6 ++++-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/core/createCSS.ts b/src/core/createCSS.ts index bd19b745..366432df 100644 --- a/src/core/createCSS.ts +++ b/src/core/createCSS.ts @@ -11,7 +11,7 @@ const createClassNameGenerator = insertStyles(cache, serialized, false, options); - return createHashStyleName(cache.key, serialized.name, options.fileName); + return createHashStyleName(cache.key, serialized.name, options); }; const createCX = @@ -32,7 +32,8 @@ const createCX = export const createCSS = (cache: EmotionCache, options: ClassNameGeneratorOption) => { const css = createClassNameGenerator(cache, { hashPriority: options.hashPriority || 'high', - fileName: options.fileName, + 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 6352e673..06376e69 100644 --- a/src/core/insertStyles.ts +++ b/src/core/insertStyles.ts @@ -6,7 +6,13 @@ import { registerStyles } from '@emotion/utils'; const isBrowser = typeof document !== 'undefined'; -export const createHashStyleName = (cacheKey: string, hash: string, fileName?: string) => { +export const createHashStyleName = ( + cacheKey: string, + hash: string, + options?: ClassNameGeneratorOption, +) => { + const fileName = options?.__BABEL_FILE_NAME__; + return `${cacheKey}-${hash}${fileName ? `__${fileName}` : ''}`; }; @@ -26,7 +32,7 @@ export const insertStyles = ( const hashPriority = options.hashPriority || 'high'; registerStyles(cache, serialized, isStringTag); - const hashClassName = `.${createHashStyleName(cache.key, serialized.name, options.fileName)}`; + const hashClassName = `.${createHashStyleName(cache.key, serialized.name, options)}`; const hashSelector = hashPriority === 'low' ? `:where(${hashClassName})` : hashClassName; diff --git a/src/factories/createStyles/index.ts b/src/factories/createStyles/index.ts index 1fe4848c..d5cc10f0 100644 --- a/src/factories/createStyles/index.ts +++ b/src/factories/createStyles/index.ts @@ -36,7 +36,8 @@ export const createStylesFactory = // 由于 toClassName 方法依赖了用户给 createStyle 传递的 hashPriority,所以需要在这里重新生成 cx 和 toClassName 方法 const { cx, css: toClassName } = createCSS(cache, { hashPriority: options?.hashPriority || hashPriority, - fileName: options?.fileName, + label: options?.label, + __BABEL_FILE_NAME__: options?.__BABEL_FILE_NAME__, }); const responsiveMap = useMediaQueryMap(); diff --git a/src/types/css.ts b/src/types/css.ts index c5233899..a162c44e 100644 --- a/src/types/css.ts +++ b/src/types/css.ts @@ -10,11 +10,13 @@ export type { SerializedStyles } from '@emotion/serialize'; export type ClassNameGenerator = Emotion['css']; export type ClassNameGeneratorOption = { + label?: string; + hashPriority?: HashPriority; /** * 用于生成 className 的文件名,用于 babel 插件使用,不建议用户使用 + * @private */ - fileName?: string; - hashPriority?: HashPriority; + __BABEL_FILE_NAME__?: string; }; /** From b5c99fa5d037f831b9ec517ede0bc58616470f6a Mon Sep 17 00:00:00 2001 From: arvinxx Date: Mon, 5 Jun 2023 18:27:13 +0800 Subject: [PATCH 5/5] :sparkles: feat: support label --- docs/api/create-styles.md | 9 +++++++++ docs/demos/api/createStyles/label.tsx | 15 +++++++++++++++ src/core/createCSS.ts | 8 ++++---- src/core/insertStyles.ts | 19 ++++++++++++++++--- src/factories/createStyles/index.ts | 3 ++- src/types/css.ts | 9 ++------- 6 files changed, 48 insertions(+), 15 deletions(-) create mode 100644 docs/demos/api/createStyles/label.tsx diff --git a/docs/api/create-styles.md b/docs/api/create-styles.md index b4aa5653..956a8583 100644 --- a/docs/api/create-styles.md +++ b/docs/api/create-styles.md @@ -214,6 +214,7 @@ createStyles 的第二个参数可以对生成的 className 做额外的控制 | 属性名 | 类型 | 描述 | | ------------ | -------------- | ------------------------------ | | hashPriority | `HashPriority` | 生成的 hash className 样式权重 | +| label | `string` | 添加后缀 | ### hashPriority @@ -222,3 +223,11 @@ createStyles 的第二个参数可以对生成的 className 做额外的控制 控制生成的 className 的权重,默认为 `high`。 如果设为 `low`,生成 hash 的样式选择器会包裹 :where 选择器,以降低权重。一般来说在组件库的使用场景中可以用到,其他场景不建议使用。 + +### label + +类型:`string` + +类似 emotion 的 label。添加 label 后,将会在把 label 添加到后缀中。一般来说无需使用。 + + diff --git a/docs/demos/api/createStyles/label.tsx b/docs/demos/api/createStyles/label.tsx new file mode 100644 index 00000000..516bed54 --- /dev/null +++ b/docs/demos/api/createStyles/label.tsx @@ -0,0 +1,15 @@ +import { createStyles } from 'antd-style'; + +const useStyles = createStyles( + ({ css }) => ({ + text: css` + color: blue; + `, + }), + { label: 'with-label' }, +); + +export default () => { + const { styles } = useStyles(); + return
赋予 with-label 标签
; +}; diff --git a/src/core/createCSS.ts b/src/core/createCSS.ts index 366432df..ca3344b6 100644 --- a/src/core/createCSS.ts +++ b/src/core/createCSS.ts @@ -1,11 +1,11 @@ -import { createHashStyleName, insertStyles } from '@/core/insertStyles'; -import { ClassNameGenerator, ClassNameGeneratorOption, ClassNamesUtil } from '@/types'; +import { createHashStyleName, insertStyles, InternalClassNameOption } from '@/core/insertStyles'; +import { ClassNameGenerator, 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: ClassNameGeneratorOption): ClassNameGenerator => + (cache: EmotionCache, options: InternalClassNameOption): ClassNameGenerator => (...args) => { const serialized = serializeStyles(args, cache.registered, undefined); @@ -29,7 +29,7 @@ const createCX = * @param cache * @param options */ -export const createCSS = (cache: EmotionCache, options: ClassNameGeneratorOption) => { +export const createCSS = (cache: EmotionCache, options: InternalClassNameOption) => { const css = createClassNameGenerator(cache, { hashPriority: options.hashPriority || 'high', label: options.label, diff --git a/src/core/insertStyles.ts b/src/core/insertStyles.ts index 06376e69..08227711 100644 --- a/src/core/insertStyles.ts +++ b/src/core/insertStyles.ts @@ -6,14 +6,27 @@ 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?: ClassNameGeneratorOption, + 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 `${cacheKey}-${hash}${fileName ? `__${fileName}` : ''}`; + return prefix + labelSuffix + babelSuffix; }; /** @@ -27,7 +40,7 @@ export const insertStyles = ( cache: EmotionCache, serialized: SerializedStyles, isStringTag: boolean, - options: ClassNameGeneratorOption, + options: InternalClassNameOption, ) => { const hashPriority = options.hashPriority || 'high'; registerStyles(cache, serialized, isStringTag); diff --git a/src/factories/createStyles/index.ts b/src/factories/createStyles/index.ts index d5cc10f0..33b8669c 100644 --- a/src/factories/createStyles/index.ts +++ b/src/factories/createStyles/index.ts @@ -11,6 +11,7 @@ import type { } from '@/types'; import { isReactCssResult } from '@/utils'; +import { InternalClassNameOption } from '@/core/insertStyles'; import { convertResponsiveStyleToString, useMediaQueryMap } from './response'; import { ReturnStyles, StyleOrGetStyleFn } from './types'; @@ -37,7 +38,7 @@ export const createStylesFactory = const { cx, css: toClassName } = createCSS(cache, { hashPriority: options?.hashPriority || hashPriority, label: options?.label, - __BABEL_FILE_NAME__: options?.__BABEL_FILE_NAME__, + __BABEL_FILE_NAME__: (options as InternalClassNameOption)?.__BABEL_FILE_NAME__, }); const responsiveMap = useMediaQueryMap(); diff --git a/src/types/css.ts b/src/types/css.ts index a162c44e..bbe45ab9 100644 --- a/src/types/css.ts +++ b/src/types/css.ts @@ -9,15 +9,10 @@ export type { SerializedStyles } from '@emotion/serialize'; export type ClassNameGenerator = Emotion['css']; -export type ClassNameGeneratorOption = { +export interface ClassNameGeneratorOption { label?: string; hashPriority?: HashPriority; - /** - * 用于生成 className 的文件名,用于 babel 插件使用,不建议用户使用 - * @private - */ - __BABEL_FILE_NAME__?: string; -}; +} /** * @title CSS 工具函数