Skip to content

Commit

Permalink
🏷️ feat: 优化类型定义使用
Browse files Browse the repository at this point in the history
  • Loading branch information
arvinxx committed Feb 4, 2023
1 parent 478bf33 commit d4a57ae
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 37 deletions.
4 changes: 2 additions & 2 deletions .dumi/theme/components/GithubButton/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { memo, type FC } from 'react';

import { GithubFilled } from '@ant-design/icons';
import { Button, Tooltip } from 'antd';
import { memo, type FC } from 'react';

import { useSiteStore } from '../../store/useSiteStore';

const GithubButton: FC = () => {
Expand Down
1 change: 0 additions & 1 deletion src/containers/StyleProvider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { EmotionContext } from '@/context/EmotionContext';
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 {
Expand Down
3 changes: 1 addition & 2 deletions src/containers/ThemeProvider/TokenContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import { SerializedStyles } from '@emotion/serialize';
import { ReactElement, useMemo } from 'react';

import { useAntdTheme, useThemeMode } from '@/hooks';
import { PedestalProvider, reactCss } from '@/pedestal';
import { SerializedStyles, Theme } from '@/types';
import { convertStylishToString } from '@/utils/convertStylish';

import { Theme } from '@/types';
import type { ThemeProviderProps } from './type';

type TokenContainerProps<T, S = Record<string, string>> = Pick<
Expand Down
23 changes: 13 additions & 10 deletions src/functions/createStyles/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import { useEmotion, useTheme } from '@/hooks';
import { reactCss } from '@/pedestal';
import type {
BaseReturnType,
ClassNamesUtil,
CommonStyleUtils,
CSSObject,
EmotionCX,
FullStylish,
FullToken,
ResponsiveStyleUtil,
ResponsiveUtil,
ReturnStyleToUse,
Theme,
ThemeAppearance,
Expand All @@ -19,9 +19,12 @@ import { isReactCssResult } from '@/utils';
import { convertResponsiveStyleToString, useMediaQueryMap } from './response';

/**
* 用户书写样式时使用的第一个参数
* 书写样式时使用的第一个参数
*/
export interface CreateStylesTheme extends CommonStyleUtils {
/**
* 包含 antd 的 token 和所有自定义 token
*/
token: FullToken;
stylish: FullStylish;
/**
Expand Down Expand Up @@ -76,20 +79,21 @@ export const createStyles =
const responsiveMap = useMediaQueryMap();
const { css, cx } = useEmotion();

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

const styles = useMemo(() => {
let tempStyles: ReturnStyleToUse<Input>;

// 函数场景
if (styleOrGetStyle 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)));

// 创建响应式断点选择器的工具函数
// @ts-ignore
const responsive: ResponsiveStyleUtil = (styles) =>
const responsive: ResponsiveUtil = (styles) =>
convertResponsiveStyleToString(styles, responsiveMap);
// 并赋予其相应的断点工具
Object.assign(responsive, responsiveMap);
Expand All @@ -109,7 +113,6 @@ export const createStyles =
props!,
) as any;
}

// 没有函数时直接就是 object 或者 string
else {
tempStyles = styleOrGetStyle as any;
Expand Down Expand Up @@ -142,6 +145,6 @@ export const createStyles =

return useMemo(() => {
const { prefixCls, ...res } = theme;
return { styles, cx, theme: res, prefixCls };
return { styles, cx: reactCx, theme: res, prefixCls };
}, [styles, theme]);
};
11 changes: 8 additions & 3 deletions src/functions/createStyles/response.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { useAntdToken } from '@/hooks';
import { reactCss } from '@/pedestal';
import type { Breakpoint, BreakpointMapParams, CSSObject, ResponsiveMap } from '@/types';
import type {
Breakpoint,
BreakpointMapParams,
CSSObject,
ResponsiveMap,
SerializedStyles,
} from '@/types';
import { isReactCssResult } from '@/utils';
import { convertBreakpointToResponsive } from '@/utils/responsive';
import type { SerializedStyles } from '@emotion/serialize';
import { useMemo } from 'react';

export const useMediaQueryMap = (): ResponsiveMap => {
Expand All @@ -22,7 +27,7 @@ export const useMediaQueryMap = (): ResponsiveMap => {
};

/**
* 将响应式对象转换为
* 将响应式对象转换为字符串
* @param obj
* @param map
*/
Expand Down
23 changes: 23 additions & 0 deletions src/types/css.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
import { Theme } from '@/types/theme';
import { ArrayClassNamesArg } from '@emotion/css/create-instance';
import { CSSInterpolation, SerializedStyles } from '@emotion/serialize';
import { Interpolation } from '@emotion/styled';

export type CSSStyle<T = Theme> = Array<TemplateStringsArray | Interpolation<T>>;

export { type CSSObject } from '@emotion/css';
export type { SerializedStyles } from '@emotion/serialize';

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

export type ClassNamesArg =
| undefined
| null
| string
| boolean
| { [className: string]: boolean | null | undefined }
| ArrayClassNamesArg
| SerializedStyles;

/**
* 可以传入多个 css 对象 或者 className 字符串,最终会合并成一个 className 字符串
* 支持入参:{SerializedStyles} | string
*/
export type ClassNamesUtil = (...classNames: ClassNamesArg[]) => string;
35 changes: 17 additions & 18 deletions src/types/function.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,31 @@
import { ClassNamesArg } from '@emotion/css/create-instance';
import { CSSInterpolation, SerializedStyles } from '@emotion/serialize';
import { ThemeConfig } from 'antd/es/config-provider/context';

import { AtomInputType } from 'antd-style/src';
import { ThemeAppearance } from './appearance';
import { ClassNamesUtil, CssUtil, SerializedStyles } from './css';
import { AtomInputType } from './genericUtils';
import { ResponsiveKey } from './response';
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 type BreakpointMapParams = Partial<Record<ResponsiveKey, AtomInputType>>;

export interface ResponsiveStyleUtil extends Record<ResponsiveKey, string> {
(breakpoints: BreakpointMapParams): any;
/**
* 响应式断点工具函数
*/
export interface ResponsiveUtil extends Record<ResponsiveKey, string> {
/**
* 支持使用函数表达式
* @param breakpoints
*/
(breakpoints: BreakpointMapParams): SerializedStyles;
}

export interface CommonStyleUtils {
cx: EmotionCX;
css: EmotionReactCss;
cx: ClassNamesUtil;
css: CssUtil;
/**
* 可以快速创建响应式样式的工具函数
* 可以快速创建响应式媒体查询的工具函数
*/
responsive: ResponsiveStyleUtil;
responsive: ResponsiveUtil;
}

/**
Expand All @@ -36,7 +35,7 @@ export type GetAntdThemeConfig = (appearance: ThemeAppearance) => ThemeConfig |

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

/**
Expand All @@ -58,7 +57,7 @@ export type GetCustomToken<T> = (theme: CustomTokenParams) => T;
export interface CustomStylishParams extends AppearanceState {
token: FullToken;
stylish: AntdStylish;
css: EmotionReactCss;
css: CssUtil;
}

/**
Expand Down
4 changes: 3 additions & 1 deletion src/types/response.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { SerializedStyles } from './css';

export type Breakpoint =
| 'xxl'
| 'xl'
Expand All @@ -14,6 +16,6 @@ export type DeviceScreen = 'mobile' | 'tablet' | 'laptop' | 'desktop';
export type ResponsiveKey = Breakpoint | DeviceScreen;

// eslint-disable-next-line @typescript-eslint/no-empty-interface
export interface ResponsiveMap extends Record<ResponsiveKey, string> {
export interface ResponsiveMap extends Record<ResponsiveKey, SerializedStyles> {
// 在此处扩展响应式映射表
}

0 comments on commit d4a57ae

Please sign in to comment.