Skip to content

Commit

Permalink
🐛 fix: 修正使用 styled ThemeProvider 后 useTheme 方法不响应自定义 token 的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Mar 1, 2023
1 parent ed12778 commit 35d87a9
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 46 deletions.
72 changes: 40 additions & 32 deletions src/factories/createThemeProvider/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { Context, memo, ReactElement } from 'react';
import { Context, memo, ReactElement, useContext } from 'react';

import { createUseTheme } from '@/factories/createUseTheme';
import { DEFAULT_THEME_CONTEXT, DEFAULT_THEME_PROVIDER } from '@/functions/setupStyled';
import { StyledConfig } from '@/types';
import { StyledConfig, StyleEngine, UseTheme } from '@/types';

import { createStyledThemeProvider } from '@/factories/createStyledThemeProvider';
import AntdProvider from './AntdProvider';
Expand All @@ -14,9 +13,8 @@ export * from './type';

interface CreateThemeProviderOptions {
styledConfig?: StyledConfig;
CustomThemeContext: Context<any>;
prefixCls?: string;
customToken: ThemeProviderProps<any>['customToken'];
StyleEngineContext: Context<StyleEngine>;
useTheme: UseTheme;
}

export const createThemeProvider = (
Expand All @@ -27,6 +25,8 @@ export const createThemeProvider = (
? createStyledThemeProvider(option.styledConfig)
: undefined;

const { StyleEngineContext } = option;

return memo(
({
children,
Expand All @@ -45,42 +45,50 @@ export const createThemeProvider = (
themeMode,
styled,
}) => {
const useTheme = createUseTheme({
prefixCls: prefixCls || option.prefixCls,
styledThemeContext:
styled?.ThemeContext || option.styledConfig?.ThemeContext || DEFAULT_THEME_CONTEXT,
CustomThemeContext: option.CustomThemeContext,
});
const {
prefixCls: defaultPrefixCls,
StyledThemeContext,
CustomThemeContext,
} = useContext(StyleEngineContext);
const defaultCustomToken = useContext(CustomThemeContext);

const StyledThemeProvider = styled
? createStyledThemeProvider(styled)
: DefaultStyledThemeProvider || DEFAULT_THEME_PROVIDER;

return (
<ThemeSwitcher
themeMode={themeMode}
defaultAppearance={defaultAppearance}
appearance={appearance}
onAppearanceChange={onAppearanceChange}
useTheme={useTheme}
<StyleEngineContext.Provider
value={{
prefixCls: prefixCls || defaultPrefixCls,
StyledThemeContext: styled?.ThemeContext || StyledThemeContext || DEFAULT_THEME_CONTEXT,
CustomThemeContext,
}}
>
<AntdProvider
prefixCls={prefixCls}
staticInstanceConfig={staticInstanceConfig}
theme={theme}
getStaticInstance={getStaticInstance}
<ThemeSwitcher
themeMode={themeMode}
defaultAppearance={defaultAppearance}
appearance={appearance}
onAppearanceChange={onAppearanceChange}
useTheme={option.useTheme}
>
<TokenContainer
<AntdProvider
prefixCls={prefixCls}
customToken={customToken}
defaultCustomToken={option.customToken}
customStylish={customStylish}
StyledThemeProvider={StyledThemeProvider}
staticInstanceConfig={staticInstanceConfig}
theme={theme}
getStaticInstance={getStaticInstance}
>
{children}
</TokenContainer>
</AntdProvider>
</ThemeSwitcher>
<TokenContainer
prefixCls={prefixCls}
customToken={customToken}
defaultCustomToken={defaultCustomToken}
customStylish={customStylish}
StyledThemeProvider={StyledThemeProvider}
>
{children}
</TokenContainer>
</AntdProvider>
</ThemeSwitcher>
</StyleEngineContext.Provider>
);
},
);
Expand Down
13 changes: 6 additions & 7 deletions src/factories/createUseTheme.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import { Theme } from '@/types';
import { StyleEngine, Theme } from '@/types';
import { Context, useContext, useMemo } from 'react';

import { DEFAULT_THEME_CONTEXT } from '@/functions/setupStyled';
import { useAntdTheme } from '@/hooks/useAntdTheme';
import { useThemeMode } from '@/hooks/useThemeMode';

interface CreateUseThemeOptions {
prefixCls?: string;
CustomThemeContext: Context<any>;
styledThemeContext?: Context<any>;
StyleEngineContext: Context<StyleEngine>;
}

export const createUseTheme = (options: CreateUseThemeOptions) => (): Theme => {
const { prefixCls, styledThemeContext, CustomThemeContext } = options;
const { StyleEngineContext } = options;
const { StyledThemeContext, CustomThemeContext, prefixCls } = useContext(StyleEngineContext);

const antdTheme = useAntdTheme();
const themeState = useThemeMode();

const defaultCustomTheme = useContext(CustomThemeContext);

const styledTheme = useContext(styledThemeContext ?? DEFAULT_THEME_CONTEXT) || {};
const styledTheme = useContext(StyledThemeContext ?? DEFAULT_THEME_CONTEXT) || {};

const initTheme = useMemo<Theme>(
() => ({
Expand Down
16 changes: 9 additions & 7 deletions src/functions/createInstance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { createStylesFactory } from '@/factories/createStyles';
import { createThemeProvider, ThemeProviderProps } from '@/factories/createThemeProvider';
import { createUseTheme } from '@/factories/createUseTheme';

import { HashPriority, StyledConfig, StyleManager } from '@/types';
import { HashPriority, StyledConfig, StyleEngine, StyleManager } from '@/types';

// 为 SSR 添加一个全局的 cacheManager,用于统一抽取 ssr 样式
declare global {
Expand Down Expand Up @@ -72,26 +72,28 @@ export const createInstance = <T = any>(options: CreateOptions<T>) => {

const styledThemeContext = options.styled?.ThemeContext;

const useTheme = createUseTheme({
prefixCls: options?.prefixCls,
const StyleEngineContext = createContext<StyleEngine>({
CustomThemeContext,
styledThemeContext,
StyledThemeContext: styledThemeContext,
prefixCls: options?.prefixCls,
});

const useTheme = createUseTheme({ StyleEngineContext });

const createStyles = createStylesFactory({
cache,
hashPriority: options.hashPriority,
useTheme,
});

const createGlobalStyle = createGlobalStyleFactory(useTheme);

const createStylish = createStylishFactory(createStyles);

const ThemeProvider = createThemeProvider({
styledConfig: options.styled,
CustomThemeContext,
prefixCls: options.prefixCls,
customToken: options.customToken,
StyleEngineContext,
useTheme,
});

// ******** 上面这些都和主题相关,如果做了任何改动,都需要排查一遍 ************ //
Expand Down
6 changes: 6 additions & 0 deletions src/types/styled.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,9 @@ export interface StyledConfig {
}

export type StyledThemeProvider = FC<{ theme: Theme; children: ReactNode }>;

export interface StyleEngine {
CustomThemeContext: Context<any>;
StyledThemeContext?: Context<any>;
prefixCls?: string;
}

0 comments on commit 35d87a9

Please sign in to comment.