Skip to content

Commit

Permalink
Merge pull request #80 from ant-design/alpha
Browse files Browse the repository at this point in the history
✨ feat: 撤销重做中间件
  • Loading branch information
ONLY-yours authored Nov 24, 2023
2 parents c9c1431 + 4636b92 commit 25d782e
Show file tree
Hide file tree
Showing 32 changed files with 1,406 additions and 14 deletions.
5 changes: 0 additions & 5 deletions .dumirc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,6 @@ const isProd = process.env.NODE_ENV === 'production';
export default defineConfig({
outputPath: 'docs-dist',
mfsu: false,
// apiParser: {},
// resolve: {
// // 配置入口文件路径,API 解析将从这里开始
// entryFile: './src/index.ts',
// },
favicons: ['https://gw.alipayobjects.com/zos/antfincdn/upvrAjAPQX/Logo_Tech%252520UI.svg'],
// @ts-ignore
ssr: false,
Expand Down
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# Changelog

## [Version 0.28.0-alpha.1](https://github.com/ant-design/pro-editor/compare/v0.27.0...v0.28.0-alpha.1)

<sup>Released on **2023-11-24**</sup>

#### ✨ 新特性

- Undo/redo Middleware.

#### 🐛 修复

- Fix compatible with subscribeWithSelector middleware.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### What's improved

- Undo/redo Middleware, closes [#74](https://github.com/ant-design/pro-editor/issues/74) ([44551aa](https://github.com/ant-design/pro-editor/commit/44551aa))

#### What's fixed

- Fix compatible with subscribeWithSelector middleware, closes [#89](https://github.com/ant-design/pro-editor/issues/89) ([b11cb36](https://github.com/ant-design/pro-editor/commit/b11cb36))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>

## [Version&nbsp;0.27.0](https://github.com/ant-design/pro-editor/compare/v0.26.0...v0.27.0)

<sup>Released on **2023-11-24**</sup>
Expand Down
4 changes: 2 additions & 2 deletions docs/guide/data-management.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
---
title: 数据流最佳实践
title: 编辑器数据流最佳实践
group:
title: 状态管理研发
order: 10
---

## 数据流最佳实践

编辑器场景不同于网页,存在大量的富交互能力如何设计一个易于开发与易于维护的数据流架构非常重要。
编辑器场景不同于 CRUD 的网页,存在大量的富交互能力如何设计一个易于开发与易于维护的数据流架构非常重要。

## 概念要素

Expand Down
43 changes: 43 additions & 0 deletions docs/guide/demos/Redo/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { Button, Card, Divider, Tabs } from 'antd';
import { useTheme } from 'antd-style';
import { Flexbox } from 'react-layout-kit';

import Toolbar from './Toolbar';
import { useStore } from './store';

const App = () => {
const { data, plus, tabs, switchTabs, plusWithoutHistory } = useStore();

const theme = useTheme();

return (
<Flexbox padding={16} style={{ background: theme.colorBgLayout }}>
<Toolbar />
<Divider />
<Flexbox gap={12}>
<Card title={'历史记录里的数据'}>
<Button onClick={plus}>+1</Button>

<div>data: {data}</div>
</Card>
<Card title={'不在历史记录里的数据'}>
<div>
<Tabs
activeKey={tabs}
onChange={switchTabs}
items={[
{ key: '1', label: '数据' },
{ key: '2', label: '配置' },
]}
/>

<div>下面的 +2 可使得 在历史记录外添加让 data +2 </div>
<Button onClick={plusWithoutHistory}>+2</Button>
</div>
</Card>
</Flexbox>
</Flexbox>
);
};

export default App;
45 changes: 45 additions & 0 deletions docs/guide/demos/Redo/Toolbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { RedoOutlined, UndoOutlined } from '@ant-design/icons';
import { useProEditor } from '@ant-design/pro-editor';
import { Badge, Button } from 'antd';
import { Flexbox } from 'react-layout-kit';

const Toolbar = () => {
const { undo, redo, undoStack, redoStack } = useProEditor();

const undoStackList = undoStack();
const redoStackList = redoStack();

const lastAction = undoStackList.at(-1);

return (
<Flexbox padding={12} gap={8}>
<Flexbox horizontal gap={8}>
<Badge count={undoStackList.length}>
<Button icon={<UndoOutlined />} onClick={undo} disabled={undoStackList.length === 0}>
撤销
</Button>
</Badge>

<Badge count={redoStackList.length}>
<Button icon={<RedoOutlined />} onClick={redo} disabled={redoStackList.length === 0}>
重做
</Button>
</Badge>
</Flexbox>
<Flexbox>
上次操作时间:
{lastAction ? new Date(lastAction.timestamp).toLocaleTimeString() : '-'}
</Flexbox>
<Flexbox>
上次操作名称:
{lastAction?.name ?? '-'}
</Flexbox>{' '}
<Flexbox>
上次操作类型:
{lastAction?.type ?? '-'}
</Flexbox>
</Flexbox>
);
};

export default Toolbar;
15 changes: 15 additions & 0 deletions docs/guide/demos/Redo/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/**
* compact: true
*/
import { ProEditorProvider } from '@ant-design/pro-editor';
import App from './App';

import { useStore } from './store';

export default () => {
return (
<ProEditorProvider devtoolOptions={{ name: 'redo-pro-editor-store' }} store={[useStore]}>
<App />
</ProEditorProvider>
);
};
57 changes: 57 additions & 0 deletions docs/guide/demos/Redo/store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { proEditorMiddleware, ProEditorOptions } from '@ant-design/pro-editor';
import { create, StateCreator } from 'zustand';
import { devtools, subscribeWithSelector } from 'zustand/middleware';

interface Store {
tabs: string;
plus: () => void;
plusWithoutHistory: () => void;
data: number;
switchTabs: (key: string) => void;
}

const createStore: StateCreator<Store, [['zustand/devtools', never], ['pro-editor', never]]> = (
set,
get,
) => ({
tabs: '1',
switchTabs: (key) => {
set({ tabs: key });
},
plusWithoutHistory: () => {
set((s) => ({ ...s, data: s.data + 2 }), false, {
type: 'plusWithoutHistory',
recordHistory: false,
});
},

plus: () => {
const nextData = get().data + 1;

set({ data: nextData }, false, {
type: 'plus',
payload: nextData,
name: '+1',
});
},
data: 3,
});

interface ProEditorStore {
data: number;
}

const storeName = 'redo-demo-app';

const proEditorOptions: ProEditorOptions<Store, ProEditorStore> = {
name: storeName,
partialize: (s) => ({ data: s.data }),
};

export const useStore = create<Store>()(
devtools(proEditorMiddleware(subscribeWithSelector(createStore), proEditorOptions), {
name: storeName,
}),
);

useStore.subscribe((s) => s.data, console.log);
113 changes: 113 additions & 0 deletions docs/guide/redo-undo.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
---
title: 撤销重做
group: 状态管理研发
order: 2
---

# 撤销重做

撤销重做是编辑器场景保障用户体验的一个重要特性。ProEditor 作为编辑器框架,为上层的应用编辑器提供了撤销重做的原子化能力。

## 立即上手

<code src="./demos/Redo/index.tsx" ></code>

## 使用方式

### 初始化

1. 外层包裹 ProEditorProvider,传入相应的 zustand store

```tsx | pure
import { ProEditorProvider } from '@ant-design/pro-editor';

import { useStore } from './store';

export default () => {
return (
<ProEditorProvider store={[useStore]}>
<App />
</ProEditorProvider>
);
};
```

2. zustand store 包裹 ProEditorMiddleware

```ts
import { proEditorMiddleware, ProEditorOptions } from '@ant-design/pro-editor';

interface ProEditorStore extends Partial<Store> { }


const proEditorOptions: ProEditorOptions<Store, ProEditorStore> = {
name: 'store-name', // 每个 store 需要有自己的唯一名称
partialize: (s) => ({ data: s.data }), // 支持按需接入
};

export const useStore = create<Store>()(

// createStore 是 StoreCreator 类型的对象
proEditorMiddleware(createStore, proEditorOptions)),
);
```

多个 Store 使用的方式:

```tsx | pure
import { ProEditorProvider } from '@ant-design/pro-editor';

import { useAStore } from './storeA';
import { useBStore } from './storeB';

export default () => {
return (
<ProEditorProvider store={[useAStore, useBStore]}>
<App />
</ProEditorProvider>
);
};
```

多 Store 撤销重做互相隔离

```tsx | pure
<div>
<ProEditorProvider store={[cStore]}>
<A />
</ProEditorProvider>

<ProEditorProvider store={[dStore]}>
<B />
</ProEditorProvider>
</div>
```

### 设定历史记录

```ts
const createStore: StateCreator<Store, [['zustand/devtools', never], ['pro-editor', never]]> = (
set,
get,
) => ({
tabs: '1',
switchTabs: (key) => {
set({ tabs: key });
},
plusWithoutHistory: () => {
set((s) => ({ ...s, data: s.data + 2 }), false, {
type: 'plusWithoutHistory',
// 不进入历史记录
recordHistory: false,
});
},

plus: () => {
const nextData = get().data + 1;

// 默认进入历史记录
set({ data: nextData }, false, { type: 'plus' });
},
data: 3,
});
```
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ant-design/pro-editor",
"version": "0.27.0",
"version": "0.28.0-alpha.1",
"description": "🌟 Lightweight Editor UI Framework",
"homepage": "https://github.com/ant-design/pro-editor",
"bugs": {
Expand Down Expand Up @@ -121,7 +121,7 @@
},
"devDependencies": {
"@emotion/jest": "^11.11.0",
"@testing-library/jest-dom": "^5.17.0",
"@testing-library/jest-dom": "^6.1.3",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^14.5.1",
"@types/color": "^3.0.4",
Expand Down Expand Up @@ -153,7 +153,7 @@
"semantic-release": "^21.1.2",
"semantic-release-config-gitmoji": "^1.5.3",
"stylelint": "^15.10.3",
"typescript": "~5.1.6",
"typescript": "^5.2.2",
"vitest": "latest",
"wait-on": "^6.0.1",
"y-protocols": "^1.0.5",
Expand Down
4 changes: 2 additions & 2 deletions src/ConfigProvider/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
title: ConfigProvider 全局容器
atomId: ConfigProvider
group:
title: 基础组件
order: 0
title: 其他
order: 1000
---

# ConfigProvider 全局容器
1 change: 0 additions & 1 deletion src/IconPicker/features/PickerPanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ const PickerPanel = () => {
</Flexbox>
) : undefined}
<Segmented
size={'small'}
options={[
{ label: 'Ant Design', value: 'antd', icon: <AntDesignOutlined /> },
{ label: 'Iconfont', value: 'iconfont' },
Expand Down
Loading

0 comments on commit 25d782e

Please sign in to comment.