Skip to content

Commit

Permalink
♻️ feat: 使用 reactCss 替换 css 对象
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Jan 25, 2023
1 parent c994274 commit 0b42a0a
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 53 deletions.
6 changes: 3 additions & 3 deletions src/functions/createStyish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ import { createStyles, StyleOrGetStyleFn } from './createStyles';
/**
* 业务应用中创建复合通用样式的进阶
*/
export function createStylish<Props, Styles extends StyleInputType>(
export const createStylish = <Props, Styles extends StyleInputType>(
cssStyleOrGetCssStyleFn: StyleOrGetStyleFn<Styles, Props>,
) {
): ((props?: Props) => ReturnStyleToUse<Styles>) => {
const useStyles = createStyles(cssStyleOrGetCssStyleFn);

return (props?: Props): ReturnStyleToUse<Styles> => {
const { styles } = useStyles(props);

return styles;
};
}
};
34 changes: 25 additions & 9 deletions src/functions/createStyles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@ import { useMemo } from 'react';
import { useEmotion, useTheme } from '@/hooks';
import type {
CommonStyleUtils,
EmotionCX,
FullStylish,
FullToken,
ReturnStyleToUse,
StyleInputType,
Theme,
ThemeAppearance,
} from '@/types';
import { isReactCssResult } from '@/utils';

import { type CSSObject } from './css';
import { reactCss } from './react';

export interface CreateStylesTheme extends CommonStyleUtils {
token: FullToken;
Expand Down Expand Up @@ -61,8 +64,12 @@ export const createStyles =
if (styleOrGetStyleFn instanceof Function) {
const { stylish, appearance, isDarkMode, prefixCls, ...token } = theme;

// 由于使用了 reactCss 作为基础样式工具,因此在使用 cx 级联 className 时需要使用特殊处理的 cx,要将 reactCss 的产出转为 css 产物
const reactCx: EmotionCX = (...classNames) =>
cx(...classNames.map((c) => (isReactCssResult(c) ? css(c) : c)));

tempStyles = styleOrGetStyleFn(
{ token, stylish, appearance, cx, css, isDarkMode, prefixCls },
{ token, stylish, appearance, cx: reactCx, css: reactCss, isDarkMode, prefixCls },
props!,
) as any;
}
Expand All @@ -72,15 +79,24 @@ export const createStyles =
}

if (typeof tempStyles === 'object') {
tempStyles = Object.fromEntries(
Object.entries(tempStyles).map(([key, value]) => {
if (typeof value === 'object') {
return [key, css(value as CSSObject)];
}
// 判断是否是直接用 reactCSS 生成的
if (isReactCssResult(tempStyles)) {
tempStyles = css(tempStyles) as any;
} else {
// 不是的话就是直接是 css object,需要转换了
tempStyles = Object.fromEntries(
Object.entries(tempStyles).map(([key, value]) => {
// 这里有可能是 x:{ color:red } 也可能是 c:reactCss`color:red`;
// 但无论哪种,都可以直接用 css 包一下转换掉
if (typeof value === 'object') {
return [key, css(value as CSSObject)];
}

return [key, value];
}),
) as any;
// 这里只可能是 c: css`color:red`; css 直接来自 antd-style
return [key, value];
}),
) as any;
}
}

return tempStyles;
Expand Down
56 changes: 56 additions & 0 deletions src/types/function.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { ClassNamesArg } from '@emotion/css/create-instance';
import { CSSInterpolation, SerializedStyles } from '@emotion/serialize';
import { ThemeConfig } from 'antd/es/config-provider/context';

import { ThemeAppearance } from './appearance';
import type { AntdStylish, AntdToken, AppearanceState, FullToken } from './theme';

export interface EmotionReactCss {
(template: TemplateStringsArray, ...args: Array<CSSInterpolation>): SerializedStyles;
(...args: Array<CSSInterpolation>): SerializedStyles;
}
export type EmotionCX = (...classNames: ClassNamesArg[]) => string;

export interface CommonStyleUtils {
cx: EmotionCX;
css: EmotionReactCss;
}

/**
* 获取 antd theme 配置
*/
export type GetAntdThemeConfig = (appearance: ThemeAppearance) => ThemeConfig | undefined;

export interface AntdStylishParams extends AppearanceState {
token: AntdToken;
css: EmotionReactCss;
}

/**
* 创建 antd stylish 配置
*/
export type GetAntdStylish = (theme: AntdStylishParams) => {
[T in keyof AntdStylish]: SerializedStyles;
};

export interface CustomTokenParams extends AppearanceState {
token: AntdToken;
}

/**
* 创建 自定义 token
*/
export type GetCustomToken<T> = (theme: CustomTokenParams) => T;

export interface CustomStylishParams extends AppearanceState {
token: FullToken;
stylish: AntdStylish;
css: EmotionReactCss;
}

/**
* 创建 自定义 stylish
*/
export type GetCustomStylish<S> = (theme: CustomStylishParams) => {
[T in keyof S]: SerializedStyles;
};
1 change: 1 addition & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from './appearance';
export * from './css';
export * from './function';
export * from './genericUtils';
export * from './styled';
export * from './theme';
45 changes: 4 additions & 41 deletions src/types/theme.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,16 @@
import { ThemeConfig } from 'antd/es/config-provider/context';
import { AliasToken } from 'antd/es/theme/interface';

import { Emotion } from '@/functions';
import { CSSInterpolation, SerializedStyles } from '@emotion/serialize';
import { ThemeAppearance, ThemeMode } from './appearance';

export interface EmotionReactCss {
(template: TemplateStringsArray, ...args: Array<CSSInterpolation>): SerializedStyles;
(...args: Array<CSSInterpolation>): SerializedStyles;
}

export interface CommonStyleUtils {
cx: Emotion['cx'];
css: Emotion['css'];
}

export interface ThemeContextState {
appearance: ThemeAppearance;
themeMode: ThemeMode;
isDarkMode: boolean;
}

export type AppearanceState = Omit<ThemeContextState, 'themeMode'>;
export type AntdToken = AliasToken;

export interface AntdStylishParams extends AppearanceState {
token: AntdToken;
css: EmotionReactCss;
}

export type GetAntdStylish = (theme: AntdStylishParams) => {
[T in keyof AntdStylish]: SerializedStyles;
};
export type AntdToken = AliasToken;

/**
* 一组统一封装好的 antd 标准样式
Expand All @@ -43,24 +22,6 @@ export interface AntdStylish {
// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface CustomToken {}

export interface CustomTokenParams extends AppearanceState {
token: AntdToken;
}

export type GetCustomToken<T> = (theme: CustomTokenParams) => T;

export interface CustomStylishParams extends AppearanceState {
token: FullToken;
stylish: AntdStylish;
css: EmotionReactCss;
}

export type GetCustomStylish<S> = (theme: CustomStylishParams) => {
[T in keyof S]: SerializedStyles;
};

export type GetAntdThemeConfig = (appearance: ThemeAppearance) => ThemeConfig | undefined;

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface CustomStylish {}

Expand All @@ -78,6 +39,8 @@ export interface FullToken extends AntdToken, CustomToken {}

export interface Theme extends FullToken, ThemeContextState {
stylish: FullStylish;

/**
* antd 组件的 prefixCls
*/
prefixCls: string;
}
14 changes: 14 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* 判断是否是 ReactCss 的编译产物
* @param params
*/
export const isReactCssResult = (params: any) => {
return (
typeof params === 'object' &&
'styles' in params &&
'name' in params &&
'map' in params &&
'next' in params &&
'toString' in params
);
};

0 comments on commit 0b42a0a

Please sign in to comment.