diff --git a/.dumi/theme/components/Provider/index.tsx b/.dumi/theme/components/Provider/index.tsx index 1f624637..87860032 100644 --- a/.dumi/theme/components/Provider/index.tsx +++ b/.dumi/theme/components/Provider/index.tsx @@ -1,5 +1,5 @@ import { App } from 'antd'; -import { ThemeProvider } from 'antd-style'; +import { StyleProvider, ThemeProvider } from 'antd-style'; import { PropsWithChildren } from 'react'; import { useThemeStore } from '../../store/useThemeStore'; @@ -9,13 +9,15 @@ export default ({ children }: PropsWithChildren) => { const themeMode = useThemeStore((s) => s.themeMode); return ( - - {children} - + + + {children} + + ); }; diff --git a/package.json b/package.json index 4692ee3c..eb2ffd0d 100644 --- a/package.json +++ b/package.json @@ -64,6 +64,7 @@ }, "dependencies": { "@babel/runtime": "^7.20", + "@emotion/cache": "^11", "@emotion/css": "^11", "@emotion/react": "^11", "@emotion/serialize": "^1", diff --git a/src/containers/StyleProvider/index.tsx b/src/containers/StyleProvider/index.tsx new file mode 100644 index 00000000..93d13710 --- /dev/null +++ b/src/containers/StyleProvider/index.tsx @@ -0,0 +1,57 @@ +import { StyleUtilsContext } from '@/context/StyleUtilsContext'; +import { createEmotion } from '@/functions'; +import { StylisPlugin } from '@emotion/cache'; +import { Emotion } from '@emotion/css/create-instance'; +import * as process from 'process'; +import { FC, memo, ReactNode, useEffect, useMemo } from 'react'; + +interface StyleProviderProps { + prefix: string; + + nonce?: string; + stylisPlugins?: StylisPlugin[]; + container?: HTMLElement; + /** + * 开启极速模式,极速模式下不会插入真实的样式 style + * @default false + */ + speedy?: boolean; + insertionPoint?: HTMLElement; + + /** + * 获取到 emotion 实例 + * @param emotion + */ + getEmotionInstance?: (emotion: Emotion) => void; + children: ReactNode; +} + +export const StyleProvider: FC = memo( + ({ + children, + prefix, + speedy, + getEmotionInstance, + + ...emotionOptions + }) => { + const emotion = useMemo(() => { + const defaultSpeedy = process.env.NODE_ENV !== 'development'; + return createEmotion({ + speedy: speedy ?? defaultSpeedy, + key: prefix, + ...emotionOptions, + }); + }, [prefix, speedy, emotionOptions]); + + useEffect(() => { + getEmotionInstance?.(emotion); + }, [emotion]); + + return ( + + {children} + + ); + }, +); diff --git a/src/containers/index.ts b/src/containers/index.ts index 8abd195f..049c88b4 100644 --- a/src/containers/index.ts +++ b/src/containers/index.ts @@ -1 +1,2 @@ +export * from './StyleProvider'; export * from './ThemeProvider'; diff --git a/src/context/StyleUtilsContext.ts b/src/context/StyleUtilsContext.ts new file mode 100644 index 00000000..abda3be9 --- /dev/null +++ b/src/context/StyleUtilsContext.ts @@ -0,0 +1,13 @@ +import { createContext } from 'react'; + +import { css, cx, type Emotion } from '@/functions'; + +export interface CommonStyleUtils { + cx: Emotion['cx']; + css: Emotion['css']; +} + +export const StyleUtilsContext = createContext({ + css, + cx, +}); diff --git a/src/context/index.ts b/src/context/index.ts index 2c3a1ed7..eba1d8c7 100644 --- a/src/context/index.ts +++ b/src/context/index.ts @@ -1 +1,2 @@ +export * from './StyleUtilsContext'; export * from './ThemeModeContext'; diff --git a/src/functions/createStyles.ts b/src/functions/createStyles.ts index 2176117f..aaa59c6b 100644 --- a/src/functions/createStyles.ts +++ b/src/functions/createStyles.ts @@ -1,9 +1,9 @@ import { useMemo } from 'react'; -import { css, cx, type CSSObject, type Emotion } from './css'; +import { CommonStyleUtils } from '@/context'; import { useTheme } from '@/hooks'; +import { useStyleUtils } from '@/hooks/useStyleUtils'; import { - CommonStyleUtils, FullStylish, FullToken, ReturnStyleToUse, @@ -12,6 +12,8 @@ import { ThemeAppearance, } from '@/types'; +import { type CSSObject, type Emotion } from './css'; + export interface CreateStylesTheme extends CommonStyleUtils { token: FullToken; stylish: FullStylish; @@ -50,6 +52,7 @@ export const createStyles = ) => (props?: Props): ReturnStyles => { const theme = useTheme(); + const { css, cx } = useStyleUtils(); const styles = useMemo(() => { let tempStyles: ReturnStyleToUse; diff --git a/src/hooks/useStyleUtils.ts b/src/hooks/useStyleUtils.ts new file mode 100644 index 00000000..94436224 --- /dev/null +++ b/src/hooks/useStyleUtils.ts @@ -0,0 +1,5 @@ +import { useContext } from 'react'; + +import { StyleUtilsContext, type CommonStyleUtils } from '@/context/StyleUtilsContext'; + +export const useStyleUtils = (): CommonStyleUtils => useContext(StyleUtilsContext); diff --git a/src/types/theme.ts b/src/types/theme.ts index 4f9b1c89..ec951358 100644 --- a/src/types/theme.ts +++ b/src/types/theme.ts @@ -1,12 +1,8 @@ -import { Emotion } from '@emotion/css/create-instance'; import { ThemeConfig } from 'antd/es/config-provider/context'; import { AliasToken } from 'antd/es/theme/interface'; -import { ThemeAppearance, ThemeMode } from './appearance'; -export interface CommonStyleUtils { - cx: Emotion['cx']; - css: Emotion['css']; -} +import { CommonStyleUtils } from '@/context'; +import { ThemeAppearance, ThemeMode } from './appearance'; export interface ThemeContextState { appearance: ThemeAppearance;