Skip to content

Commit 4b9a170

Browse files
authored
Merge pull request #81 from ant-design/fix/id-manager
feat: 支持 renderEmpty && 添加 demo 样例。
2 parents 7a8e560 + f0fd333 commit 4b9a170

13 files changed

Lines changed: 2729 additions & 1454 deletions

File tree

src/ColumnList/ColumnList.tsx

Lines changed: 29 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
SortableList,
44
SortableListProps,
55
SortableListRef,
6-
genUniqueId,
76
getPrefixCls,
87
} from '@ant-design/pro-editor';
98
import { ReactNode, forwardRef, useCallback } from 'react';
@@ -20,59 +19,36 @@ export interface ColumnListProps<T extends SortableItem = SortableItem>
2019
const ColumnList: <T extends SortableItem>(props: ColumnListProps<T>) => ReactNode = forwardRef<
2120
SortableListRef,
2221
ColumnListProps
23-
>(
24-
(
25-
{
26-
prefixCls: customPrefixCls,
27-
className,
28-
columns,
29-
actions,
30-
hideRemove,
31-
creatorButtonProps,
32-
...props
33-
},
34-
ref,
35-
) => {
36-
const prefixCls = getPrefixCls('column-list', customPrefixCls);
37-
const { cx } = useStyle(prefixCls);
22+
>(({ prefixCls: customPrefixCls, className, columns, actions, hideRemove, ...props }, ref) => {
23+
const prefixCls = getPrefixCls('column-list', customPrefixCls);
24+
const { cx } = useStyle(prefixCls);
3825

39-
const renderItem = useCallback(
40-
(item, { index, listeners }) => (
41-
<ColumnItem
42-
columns={columns}
43-
item={item}
44-
listeners={listeners}
45-
index={index}
46-
prefixCls={prefixCls}
47-
actions={typeof actions === 'function' ? actions(item, index) : actions}
48-
hideRemove={hideRemove}
49-
/>
50-
),
51-
[prefixCls, columns],
52-
);
26+
const renderItem = useCallback(
27+
(item, { index, listeners }) => (
28+
<ColumnItem
29+
columns={columns}
30+
item={item}
31+
listeners={listeners}
32+
index={index}
33+
prefixCls={prefixCls}
34+
actions={typeof actions === 'function' ? actions(item, index) : actions}
35+
hideRemove={hideRemove}
36+
/>
37+
),
38+
[prefixCls, columns],
39+
);
5340

54-
return (
55-
<>
56-
<Header prefixCls={prefixCls} columns={columns} />
57-
<SortableList
58-
ref={ref}
59-
renderItem={renderItem}
60-
className={cx(prefixCls, className)}
61-
creatorButtonProps={
62-
creatorButtonProps === false
63-
? false
64-
: {
65-
record: () => ({
66-
id: genUniqueId('column-list'),
67-
}),
68-
...creatorButtonProps,
69-
}
70-
}
71-
{...props}
72-
/>
73-
</>
74-
);
75-
},
76-
);
41+
return (
42+
<>
43+
<Header prefixCls={prefixCls} columns={columns} />
44+
<SortableList
45+
ref={ref}
46+
renderItem={renderItem}
47+
className={cx(prefixCls, className)}
48+
{...props}
49+
/>
50+
</>
51+
);
52+
});
7753

7854
export default ColumnList;

src/ColumnList/demos/actions.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ const columns: ColumnItemList<SchemaItem> = [
4444
},
4545
];
4646

47+
/**
48+
* 创建一个随机的索引标记符,请勿在生产环境使用
49+
*/
50+
export const randomIndex = () => Math.random() * 10000;
51+
4752
export default () => (
4853
<ColumnList<SchemaItem>
4954
columns={columns}
@@ -56,6 +61,13 @@ export default () => (
5661
onClick={() => message.info(field.dataIndex)}
5762
/>,
5863
]}
64+
creatorButtonProps={{
65+
record: () => ({
66+
id: randomIndex(),
67+
valueType: 'text',
68+
title: '示例标题',
69+
}),
70+
}}
5971
onChange={(values) => {
6072
console.log('onChange', values);
6173
}}
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/**
2+
* title: 自定义创建逻辑
3+
* description: 你可以设置 `creatorButtonProps={false}` 来关闭默认的创建效果,然后自定义创建逻辑
4+
*/
5+
import { PlusCircleTwoTone } from '@ant-design/icons';
6+
import type { ColumnItemList, SortableItem, SortableListRef } from '@ant-design/pro-editor';
7+
import { ActionIcon, ColumnList } from '@ant-design/pro-editor';
8+
import { Button, Empty } from 'antd';
9+
import { useRef } from 'react';
10+
import { Flexbox } from 'react-layout-kit';
11+
12+
import { tableColumnValueOptions } from './mock_data/options';
13+
14+
type SchemaItem = {
15+
title: string;
16+
valueType?: string;
17+
dataIndex: string;
18+
} & SortableItem;
19+
20+
const INIT_VALUES = [
21+
{ id: 'orderId', dataIndex: 'orderId', valueType: 'text', title: '订单id', color: undefined },
22+
{
23+
id: 'orderNumber',
24+
dataIndex: 'orderNumber',
25+
valueType: 'text',
26+
title: '订单号',
27+
color: undefined,
28+
},
29+
{
30+
id: 'orderMoney',
31+
dataIndex: 'orderMoney',
32+
valueType: 'text',
33+
title: '订单金额',
34+
color: undefined,
35+
},
36+
];
37+
38+
/**
39+
* 创建一个随机的索引标记符,请勿在生产环境使用
40+
*/
41+
export const randomIndex = () => Math.random() * 10000;
42+
43+
const columns: ColumnItemList<SchemaItem> = [
44+
{
45+
title: '列标题',
46+
dataIndex: 'title',
47+
type: 'input',
48+
},
49+
{
50+
title: '值类型',
51+
dataIndex: 'valueType',
52+
type: 'select',
53+
options: tableColumnValueOptions,
54+
},
55+
{
56+
title: '字段',
57+
dataIndex: 'dataIndex',
58+
type: 'select',
59+
},
60+
];
61+
62+
export default () => {
63+
const ref = useRef<SortableListRef<SchemaItem>>(null);
64+
65+
const handleCreate = () => {
66+
const id = `id-${randomIndex()}}`;
67+
ref.current.addItem({ id, title: `new-${id}`, dataIndex: 'text' });
68+
};
69+
return (
70+
<>
71+
<Flexbox
72+
horizontal
73+
align={'center'}
74+
distribution={'space-between'}
75+
style={{ marginBottom: 16 }}
76+
>
77+
<div>列配置项</div>
78+
<ActionIcon
79+
icon={<PlusCircleTwoTone />}
80+
key={'edit'}
81+
tabIndex={-1}
82+
onClick={handleCreate}
83+
/>
84+
</Flexbox>
85+
<ColumnList<SchemaItem>
86+
ref={ref}
87+
columns={columns}
88+
renderEmpty={() => (
89+
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无数据">
90+
<Button type="primary" onClick={handleCreate}>
91+
创建自定义数据
92+
</Button>
93+
</Empty>
94+
)}
95+
initialValues={INIT_VALUES}
96+
onChange={(values) => {
97+
console.log('onChange', values);
98+
}}
99+
creatorButtonProps={false}
100+
/>
101+
</>
102+
);
103+
};

src/ColumnList/demos/normal.tsx

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,24 @@ const columns: ColumnItemList<SchemaItem> = [
3434
},
3535
];
3636

37+
/**
38+
* 创建一个随机的索引标记符,请勿在生产环境使用
39+
*/
40+
export const randomIndex = () => Math.random() * 10000;
41+
3742
export default () => (
3843
<ColumnList<SchemaItem>
3944
columns={columns}
4045
initialValues={initialValues}
4146
onChange={(values) => {
4247
console.log('onChange', values);
4348
}}
49+
creatorButtonProps={{
50+
record: () => ({
51+
id: randomIndex(),
52+
valueType: 'text',
53+
title: '示例标题',
54+
}),
55+
}}
4456
/>
4557
);

src/ColumnList/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ demo:
2020
<code src="./demos/controlled.tsx" ></code>
2121
<code src="./demos/actions.tsx" ></code>
2222
<code src="./demos/creatorButtonProps.tsx" ></code>
23+
<code src="./demos/customCreate.tsx" ></code>
2324
<code src="./demos/empty.tsx" ></code>
2425

2526
## API

src/SortableList/container/StoreUpdater.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const StoreUpdater = forwardRef(
1313
onChange,
1414
renderItem,
1515
renderContent,
16+
renderEmpty,
1617
getItemStyles,
1718
getId,
1819
creatorButtonProps,
@@ -30,6 +31,7 @@ const StoreUpdater = forwardRef(
3031
useStoreUpdater('onChange', onChange);
3132
useStoreUpdater('renderItem', renderItem);
3233
useStoreUpdater('renderContent', renderContent);
34+
useStoreUpdater('renderEmpty', renderEmpty);
3335
useStoreUpdater('getItemStyles', getItemStyles);
3436
useStoreUpdater('creatorButtonProps', creatorButtonProps);
3537
useStoreUpdater('hideRemove', hideRemove);

src/SortableList/demos/controlled.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { useState } from 'react';
1010
import { Flexbox } from 'react-layout-kit';
1111

1212
const Demo = () => {
13-
const [list, setList] = useState<SortableItem[]>([]);
13+
const [list, setList] = useState<SortableItem[]>([{ id: 'hello' }, { id: 'world' }]);
1414

1515
const token = useTheme();
1616
return (
@@ -23,9 +23,11 @@ const Demo = () => {
2323
}}
2424
/>
2525
<Button
26+
type="primary"
2627
onClick={() => {
27-
setList([{ id: 'hello' }, { id: 'world' }]);
28+
setList([{ id: 'foo' }, { id: 'bar' }]);
2829
}}
30+
style={{ marginTop: 8 }}
2931
>
3032
设置数据
3133
</Button>

src/SortableList/demos/ref.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ export default () => {
3232
onClick={() => {
3333
const id = `id-${listData.length}-${randomIndex()}`;
3434
ref.current.addItem({ id, title: `new-${id}` });
35-
ref.current.addItem({ id: 'xxx', title: '111' });
3635
}}
3736
/>
3837
</Flexbox>

src/SortableList/features/SortList.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { useStyle } from '../style';
1515
const selector = (s: Store) => ({
1616
renderItem: s.renderItem,
1717
renderContent: s.renderContent,
18+
renderEmpty: s.renderEmpty,
1819
getItemStyles: s.getItemStyles,
1920
getId: s.getId,
2021
actions: s.actions,
@@ -32,6 +33,7 @@ const SortableList: FC<SortableListProps> = ({ prefixCls }) => {
3233
dispatchListData,
3334
renderItem,
3435
renderContent,
36+
renderEmpty,
3537
creatorButtonProps = false,
3638
hideRemove,
3739
getItemStyles,
@@ -63,11 +65,15 @@ const SortableList: FC<SortableListProps> = ({ prefixCls }) => {
6365
};
6466

6567
return Array.isArray(items) && items.length === 0 ? (
66-
<>
67-
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无数据">
68-
{creatorButtonProps !== false ? <CreateButton empty={true} /> : null}
69-
</Empty>
70-
</>
68+
renderEmpty ? (
69+
renderEmpty()
70+
) : (
71+
<>
72+
<Empty image={Empty.PRESENTED_IMAGE_SIMPLE} description="暂无数据">
73+
{creatorButtonProps !== false ? <CreateButton empty={true} /> : null}
74+
</Empty>
75+
</>
76+
)
7177
) : (
7278
<>
7379
{creatorButtonProps !== false && position === 'top' ? <CreateButton /> : null}

src/SortableList/type/component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ export interface SortableItemProps<T = SortableItem>
5353

5454
export type RenderContent<T = SortableItem> = (item: T, index: number) => React.ReactNode;
5555

56+
export type RenderEmpty = () => React.ReactNode;
57+
5658
export interface CreatorButtonProps {
5759
/**
5860
* 添加创建按钮的位置

0 commit comments

Comments
 (0)