Skip to content

Commit

Permalink
⚡ feat: ProEditor ConvigProvider 优化改造,Prefix 动态获取 (#120)
Browse files Browse the repository at this point in the history
* ⚡ feat: 更新所有组件的Prefix

* ⚡ feat: 支持全组件暗黑模式切换
  • Loading branch information
ONLY-yours authored Jan 2, 2024
1 parent b521db3 commit 54f265f
Show file tree
Hide file tree
Showing 105 changed files with 3,473 additions and 3,994 deletions.
16 changes: 8 additions & 8 deletions docs/guide/data-management.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ group:

## 概念要素

| 概念名词 | 解释 |
| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| store | 状态库 (store),包含存储应用的状态、动作。允许在应用渲染中访问和修改状态。 |
| state | 状态 (state) 是指应用程序的数据,存储了应用程序的当前状态,状态的变化**一定会触发应用的重新渲染**,以反映新的状态。 |
| action | 动作 (action) 是一个操作函数,它描述了应用程序中发生的交互事件。动作通常是由用户交互、网络请求或定时器等触发。 action 可以是**同步**的,也可以是**异步**的。 |
| reducer | 归约器 (reducer) 是一个纯函数,它接收当前状态和动作作为参数,并返回一个新的状态。它用于根据动作类型来更新应用程序的状态。Reducer 是一个纯函数,不存在副作用,因此一定是 **同步** 函数。 |
| 概念名词 | 解释 |
| -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| store | 状态库 (store),包含存储应用的状态、动作。允许在应用渲染中访问和修改状态。 |
| state | 状态 (state) 是指应用程序的数据,存储了应用程序的当前状态,状态的变化**一定会触发应用的重新渲染**,以反映新的状态。 |
| action | 动作 (action) 是一个操作函数,它描述了应用程序中发生的交互事件。动作通常是由用户交互、网络请求或定时器等触发。 action 可以是**同步**的,也可以是**异步**的。 |
| reducer | 归约器 (reducer) 是一个纯函数,它接收当前状态和动作作为参数,并返回一个新的状态。它用于根据动作类型来更新应用程序的状态。Reducer 是一个纯函数,不存在副作用,因此一定是 **同步** 函数。 |
| selector | 选择器 (selector) 是一个函数,用于从应用程序的状态中获取特定的数据。它接收应用程序的状态作为参数,并返回经过计算或转换后的数据。Selector 可以将状态的一部分或多个状态组合起来,以生成派生的数据。Selector 通常用于将应用程序的状态映射到组件的 props,以供组件使用。 |
| slice | 切片 (slice) 是一个概念,用于表达数据模型状态的一部分。它指定了一个状态切片(slice),以及与该切片相关的 state、action、reducer 和 selector。使用 Slice 可以将大型的 Store 拆分为更小的、可维护的子类型。 |
| slice | 切片 (slice) 是一个概念,用于表达数据模型状态的一部分。它指定了一个状态切片(slice),以及与该切片相关的 state、action、reducer 和 selector。使用 Slice 可以将大型的 Store 拆分为更小的、可维护的子类型。 |

## 结构分层

Expand Down Expand Up @@ -295,7 +295,7 @@ const crudSlice = (set, get) => ({

此外,将数据变更逻辑下沉为 reducer 后, reducer 层面也会带来相应的好处。由于 reducer 只是一个纯函数,因此可以非常方便地实现相应的单元测试。而结合 AI ,我们可以实现一句话需求的 reducer 实现,同时也可以实现一键产出测试代码。在 reducer 上的研发与维护成本将会大大降低。

| 功能实现 | 单元测试 |
| 功能实现 | 单元测试 |
| ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------- |
| ![](https://gw.alipayobjects.com/zos/kitchen/qcmFMlllP/f588a003-6317-4ef2-9728-491c9bda3c05.png) | ![](https://github-production-user-asset-6210df.s3.amazonaws.com/28616219/261315145-01f8542f-e748-4334-b8fa-67b929fa1795.png) |

Expand Down
15 changes: 11 additions & 4 deletions src/ActionGroup/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
RedoOutlined,
UndoOutlined,
} from '@ant-design/icons';
import { ActionIcon, ActionIconProps, getPrefixCls } from '@ant-design/pro-editor';
import { ActionIcon, ActionIconProps, ConfigProvider } from '@ant-design/pro-editor';
import { Divider, Dropdown, DropdownProps } from 'antd';
import { useStyle } from './style';

Expand Down Expand Up @@ -123,8 +123,7 @@ const ActionGroup = (props: ActionGroupProps) => {
dropdownProps,
dropdownMenuTrigger,
} = props;
const prefixCls = getPrefixCls('action-group');
const { styles, cx } = useStyle({ prefixCls, direction, type });
const { styles, cx } = useStyle({ direction, type });

const DefalutItemConfig = [
{ icon: <FullscreenOutlined />, onClick: onFullScreenClick },
Expand Down Expand Up @@ -200,4 +199,12 @@ const ActionGroup = (props: ActionGroupProps) => {
);
};

export { ActionGroup };
const WrapperActionGroup = (props: ActionGroupProps) => {
return (
<ConfigProvider>
<ActionGroup {...props} />
</ConfigProvider>
);
};

export { WrapperActionGroup as ActionGroup };
40 changes: 20 additions & 20 deletions src/ActionGroup/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,29 @@ demo:

## API

| 属性名 | 类型 | 描述 |
| ------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| className | `string` | 自定义的 classname |
| style | `React.CSSProperties` | 自定义 style |
| items | `[]<ActionIconItem>` | 生成按钮的配置 config |
| dropdownMenu | `[]<ActionGroupItem>` | 生成 drowDownMenuList 内容的 config |
| 属性名 | 类型 | 描述 |
| ------------------- | ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| className | `string` | 自定义的 classname |
| style | `React.CSSProperties` | 自定义 style |
| items | `[]<ActionIconItem>` | 生成按钮的配置 config |
| dropdownMenu | `[]<ActionGroupItem>` | 生成 drowDownMenuList 内容的 config |
| dropdownProps | `[]<ActionGroupItem \| { type: 'divider' }>` | 给 dropdownMenu 设置的自定义 Props,支持除了 Menu 外其余所有 antd dropdown Props 的设置 |
| dropdownMenuTrigger | `React.ReactNode` | 用于自定义 dropdownMenu 下拉的触发 Dom,默认为 DashOutlined 的 Icon |
| render | `(defalutDom: React.ReactNode, config: Array<ButtonConfig>) => React.ReactNode` | 用于渲染自定义能力的 render 方法 |
| onFullScreenClick | `() => void` | 全屏按钮点击的回调 |
| onUndoClick | `() => void` | 撤销按钮点击的回调 |
| onRedoClick | `() => void` | 重做按钮点击的回调 |
| onDeleteClick | `() => void` | 删除按钮点击的回调 |
| type | `'ghost' \| 'block' \| 'pure'` | 整体的样式 |
| direction | `'row' \| 'column'` | 图标排列时候的方向 |
| size | `'default' \| 'large' \| number` | 图标尺寸 |
| dropdownMenuTrigger | `React.ReactNode` | 用于自定义 dropdownMenu 下拉的触发 Dom,默认为 DashOutlined 的 Icon |
| render | `(defalutDom: React.ReactNode, config: Array<ButtonConfig>) => React.ReactNode` | 用于渲染自定义能力的 render 方法 |
| onFullScreenClick | `() => void` | 全屏按钮点击的回调 |
| onUndoClick | `() => void` | 撤销按钮点击的回调 |
| onRedoClick | `() => void` | 重做按钮点击的回调 |
| onDeleteClick | `() => void` | 删除按钮点击的回调 |
| type | `'ghost' \| 'block' \| 'pure'` | 整体的样式 |
| direction | `'row' \| 'column'` | 图标排列时候的方向 |
| size | `'default' \| 'large' \| number` | 图标尺寸 |

### ActionGroupItem

| 属性名 | 类型 | 描述 |
| ------- | --------------------- | ----------- |
| icon | `React.ReactNode` | 展示的 icon |
| 属性名 | 类型 | 描述 |
| ------- | --------------------- | ---------------------- |
| icon | `React.ReactNode` | 展示的 icon |
| style | `React.CSSProperties` | 每个配置按钮的单独样式 |
| key | `key` | 每个按钮单独的 key |
| onClick | `() => void` | 按钮点击事件的回调 |
| key | `key` | 每个按钮单独的 key |
| onClick | `() => void` | 按钮点击事件的回调 |
| label | `string` | 用于展示按钮的提示文案 |
8 changes: 5 additions & 3 deletions src/ActionGroup/style.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { createStyles } from '../theme';

export const useStyle = createStyles(({ token, css, cx }, { prefixCls, type, direction }) => {
export const useStyle = createStyles(({ token, css, cx, prefixCls }, { type, direction }) => {
const typeStylish = css`
background-color: ${type === 'block' ? token.colorFillTertiary : token.colorFillQuaternary};
border: 1px solid ${type === 'block' ? 'transparent' : token.colorBorder};
`;

const prefix = `${prefixCls}-${token.editorPrefix}-action-group`;

return {
content: cx(
`${prefixCls}-content`,
`${prefix}-content`,
css`
${type !== 'pure' && typeStylish};
width: fit-content;
Expand All @@ -20,7 +22,7 @@ export const useStyle = createStyles(({ token, css, cx }, { prefixCls, type, dir
`,
),
button: cx(
`${prefixCls}-action-btn`,
`${prefix}-action-btn`,
css`
box-shadow: none;
border: none;
Expand Down
3 changes: 2 additions & 1 deletion src/ActionIcon/ActionIcon.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ describe('ActionIcon', () => {
);
expect(container).toMatchSnapshot();
const icon = await findByTestId('smile');
expect(icon.className.includes('studio-btn-icon')).toBeTruthy();
expect(icon.className.includes('ant-btn-icon')).toBeTruthy();
expect(icon.className.includes('ant-editor-icon')).toBeTruthy();
});
});
38 changes: 23 additions & 15 deletions src/ActionIcon/ActionIcon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type { ButtonProps, TooltipProps } from 'antd';
import { Button, Tooltip } from 'antd';
import type { CSSProperties, FC } from 'react';
import { ConfigProvider } from '../ConfigProvider';
import { getPrefixCls } from '../theme';
import { useStyles } from './style';

/**
Expand Down Expand Up @@ -46,7 +45,7 @@ export interface ActionIconProps extends Omit<ButtonProps, 'title' | 'size'> {
arrow?: boolean;
}

const ActionIcon: FC<ActionIconProps> = ({
const BaseActionIcon: FC<ActionIconProps> = ({
placement,
title,
icon,
Expand All @@ -56,11 +55,9 @@ const ActionIcon: FC<ActionIconProps> = ({
arrow = false,
size = 'default',
tooltipDelay = 0.5,
prefixCls: customPrefixCls,
...restProps
}) => {
const prefixCls = getPrefixCls('actionicon', customPrefixCls);
const { styles, theme: token, cx } = useStyles({ size, prefixCls });
const { styles, cx } = useStyles({ size });

const Icon = (
<Button
Expand All @@ -75,16 +72,7 @@ const ActionIcon: FC<ActionIconProps> = ({
);

return (
<ConfigProvider
componentToken={{
Button: {
colorText: token.colorTextTertiary,
// TODO: Token 的提供不太合理,需要改造
colorBgTextHover: token.colorFillSecondary,
colorBgTextActive: token.colorFill,
},
}}
>
<>
{!title ? (
Icon
) : (
Expand All @@ -98,6 +86,26 @@ const ActionIcon: FC<ActionIconProps> = ({
{Icon}
</Tooltip>
)}
</>
);
};

const ActionIcon = (props: ActionIconProps) => {
const { size } = props || {};
const { theme: token } = useStyles({ size });

return (
<ConfigProvider
componentToken={{
Button: {
colorText: token.colorTextTertiary,
// TODO: Token 的提供不太合理,需要改造
colorBgTextHover: token.colorFillSecondary,
colorBgTextActive: token.colorFill,
},
}}
>
<BaseActionIcon {...props} />
</ConfigProvider>
);
};
Expand Down
8 changes: 4 additions & 4 deletions src/ActionIcon/__snapshots__/ActionIcon.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ exports[`ActionIcon > 可正常渲染 1`] = `
<div>
<button
class="studio-btn studio-btn-text studio-btn-icon-only studio-actionicon emotion-0"
class="ant-btn ant-btn-text ant-btn-icon-only ant-editor-icon emotion-0"
type="button"
>
<span
class="studio-btn-icon"
class="ant-btn-icon"
>
<span
aria-label="smile"
Expand Down Expand Up @@ -88,12 +88,12 @@ exports[`ActionIcon > 带有标题 1`] = `
<div>
<button
class="studio-btn studio-btn-text studio-btn-icon-only studio-actionicon emotion-0"
class="ant-btn ant-btn-text ant-btn-icon-only ant-editor-icon emotion-0"
data-testid="smile"
type="button"
>
<span
class="studio-btn-icon"
class="ant-btn-icon"
>
<span
aria-label="smile"
Expand Down
16 changes: 8 additions & 8 deletions src/ActionIcon/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,13 @@ demo:

## API

| 参数 | 说明 | 类型 | 默认值 |
| :-------- | :--- | :----------------------------------------- | :---- |
| cursor | 鼠标类型 | `CSSProperties['cursor']` | - |
| title | 动作提示 | `TooltipProps['title']` | - |
| placement | 提示位置 | `TooltipProps['placement']` | - |
| icon | 图标 | `ButtonProps['icon']` | - |
| onClick | 点击回调 | `ButtonProps['onClick']` | - |
| size | 图标尺寸 | `'default' \| 'large' \|'small' \| number` | small |
| 参数 | 说明 | 类型 | 默认值 |
| :-------- | :------- | :----------------------------------------- | :----- |
| cursor | 鼠标类型 | `CSSProperties['cursor']` | - |
| title | 动作提示 | `TooltipProps['title']` | - |
| placement | 提示位置 | `TooltipProps['placement']` | - |
| icon | 图标 | `ButtonProps['icon']` | - |
| onClick | 点击回调 | `ButtonProps['onClick']` | - |
| size | 图标尺寸 | `'default' \| 'large' \|'small' \| number` | small |

其他 API 参考 antd Button Props .
5 changes: 3 additions & 2 deletions src/ActionIcon/style.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createStyles } from '../theme';

export const useStyles = createStyles(({ token, css, cx }, { size, className, prefixCls }) => {
export const useStyles = createStyles(({ token, css, cx, prefixCls }, { size, className }) => {
const prefix = `${prefixCls}-${token.editorPrefix}-icon`;
const sizeBoundary =
typeof size === 'number'
? css`
Expand Down Expand Up @@ -28,7 +29,7 @@ export const useStyles = createStyles(({ token, css, cx }, { size, className, pr
`;

return {
container: cx(prefixCls, button, sizeBoundary, className),
container: cx(prefix, button, sizeBoundary, className),
tooltip: css`
pointer-events: none;
`,
Expand Down
Loading

0 comments on commit 54f265f

Please sign in to comment.