Skip to content

Commit

Permalink
Merge pull request #8 from ant-design/feat/column-list
Browse files Browse the repository at this point in the history
feat: 新增 ColumnList 组件
  • Loading branch information
rdmclin2 committed May 25, 2023
2 parents 100a489 + d112bdc commit 992257b
Show file tree
Hide file tree
Showing 21 changed files with 9,874 additions and 157 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,11 +111,11 @@
"@types/react-dom": "^18.0.0",
"@umijs/lint": "^4.0.0",
"@vitest/coverage-c8": "latest",
"dumi": "^2",
"dumi-theme-antd-style": "latest",
"antd": "^5",
"commitlint": "^17",
"commitlint-config-gitmoji": "^2",
"dumi": "^2.1.22",
"dumi-theme-antd-style": "^0.25.0",
"eslint": "^8.23.0",
"father": "^4.1.0",
"glob": "^10.2.6",
Expand All @@ -127,6 +127,7 @@
"prettier-plugin-packagejson": "^2.2.18",
"react": "^18.0.0",
"react-dom": "^18.0.0",
"react-lazy-load": "^4",
"rxjs-spy": "^8",
"stylelint": "^15",
"typescript": "^5.0.4",
Expand Down
80 changes: 80 additions & 0 deletions src/ColumnList/ColumnItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { ColumnItemList, useSortableList } from '@ant-design/pro-editor';
import { createStyles } from 'antd-style';
import { memo } from 'react';
import { Flexbox } from 'react-layout-kit';
import ControlInput from './renderItem/Input';
import ControlSelect from './renderItem/Select';

const useStyle = createStyles(({ css, cx }, prefixCls) => {
const prefix = `${prefixCls}-content`;
return {
content: cx(
prefix,
css`
flex: 1;
height: 24px;
font-size: 12px;
border-radius: 2px;
min-width: 48px;
`,
),
};
});

interface ItemRenderProps<T = any> {
columns: ColumnItemList<T>;
item: T;
index: number;
prefixCls: string;
}

const ColumnItem = memo<ItemRenderProps>(({ item, index, prefixCls, columns }) => {
const { styles } = useStyle(prefixCls);
const instance = useSortableList();

return (
<Flexbox horizontal gap={4} width={'100%'} className={styles.content}>
{columns.map((col, colIndex) => {
const style = { flex: 1, maxWidth: `${100 / columns.length}%` };
const props = {
dataIndex: col.dataIndex,
value: item[col.dataIndex],
index,
prefixCls,
style,
placeholder: col.placeholder,
};
switch (col.type) {
default:
case 'input':
return <ControlInput key={`${item?.dataIndex}-${colIndex}`} {...props} />;

case 'select':
return (
<ControlSelect
key={`${item?.dataIndex}-${colIndex}`}
options={col.options}
{...props}
/>
);
case 'custom':
const Custom = col.render;
return Custom ? (
<Custom
item={item}
column={col}
onChange={(value) => {
instance.updateItem({ [col.dataIndex]: value }, index);
}}
{...props}
/>
) : (
'暂无实现'
);
}
})}
</Flexbox>
);
});

export default ColumnItem;
43 changes: 43 additions & 0 deletions src/ColumnList/ColumnList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { getPrefixCls, SortableList } from '@ant-design/pro-editor';
import { forwardRef, useCallback } from 'react';

import { cx } from 'antd-style';
import { SortableListProps, SortableListRef } from '../SortableList';
import ColumnItem from './ColumnItem';
import { Header } from './Header';
import { ColumnItemList } from './types';

export interface ColumnListProps<T = any> extends SortableListProps<T> {
columns: ColumnItemList<T>;
}

const ColumnList: <T = any>(props: ColumnListProps<T>) => JSX.Element = forwardRef<
SortableListRef<any>,
ColumnListProps
>(({ prefixCls: customPrefixCls, className, columns, ...props }, ref) => {
const prefixCls = getPrefixCls('column-list', customPrefixCls);

const renderHeader = useCallback(
() => <Header prefixCls={prefixCls} columns={columns} />,
[columns],
);
const renderContent = useCallback(
(item, index) => (
<ColumnItem columns={columns} item={item} index={index} prefixCls={prefixCls} />
),
[prefixCls, columns],
);

return (
<SortableList<any>
ref={ref}
compact
renderContent={renderContent}
renderHeader={renderHeader}
className={cx(prefixCls, className)}
{...props}
/>
);
});

export default ColumnList;
45 changes: 45 additions & 0 deletions src/ColumnList/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { ColumnItemList } from '@ant-design/pro-editor';
import { createStyles } from 'antd-style';
import { memo } from 'react';
import { Flexbox } from 'react-layout-kit';

const useStyle = createStyles(({ token, css, cx }, prefixCls) => {
return {
content: cx(
`${prefixCls}-content`,
css`
flex: 1;
width: 100%;
height: 24px;
font-size: 12px;
border-radius: 2px;
min-width: 48px;
`,
),
header: cx(
`${prefixCls}-header`,
css`
color: ${token.colorTextTertiary};
padding-left: 8px;
`,
),
};
});

interface HeaderProps {
prefixCls: string;
columns: ColumnItemList<any>;
}
export const Header = memo<HeaderProps>(({ prefixCls, columns }) => {
const { styles, cx } = useStyle(prefixCls);

return (
<Flexbox horizontal align={'center'} gap={4}>
{columns.map((item, index) => (
<div key={`${item.dataIndex}-${index}`} className={cx(styles.content, styles.header)}>
{item.title}
</div>
))}
</Flexbox>
);
});
58 changes: 58 additions & 0 deletions src/ColumnList/demos/actions.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { EditFilled } from '@ant-design/icons';
import type { ColumnItemList } from '@ant-design/pro-editor';
import { ActionIcon, ColumnList } from '@ant-design/pro-editor';
import { message } from 'antd';
import { tableColumnValueOptions } from './mock_data/options';

type SchemaItem = {
title: string;
valueType: string;
dataIndex: string;
};

const initialValues = [
{ title: '序号', valueType: 'indexBorder', dataIndex: 'index' },
{
title: '授权企业名称',
valueType: 'text',
dataIndex: 'name',
},
{ title: '被授权企业', valueType: 'text', dataIndex: 'authCompany' },
];

const columns: ColumnItemList<SchemaItem> = [
{
title: '列标题',
dataIndex: 'title',
type: 'input',
},
{
title: '值类型',
dataIndex: 'valueType',
type: 'select',
options: tableColumnValueOptions,
},
{
title: '字段',
dataIndex: 'dataIndex',
type: 'select',
},
];

export default () => (
<ColumnList<SchemaItem>
columns={columns}
initialValues={initialValues}
actions={(field) => [
<ActionIcon
icon={<EditFilled />}
key={'edit'}
tabIndex={-1}
onClick={() => message.info(field.dataIndex)}
/>,
]}
onChange={(values) => {
console.log('onChange', values);
}}
/>
);
52 changes: 52 additions & 0 deletions src/ColumnList/demos/column.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import type { ColumnItemList } from '@ant-design/pro-editor';
import { ColumnList } from '@ant-design/pro-editor';

import { tableColumnValueOptions } from './mock_data/options';

type SchemaItem = {
title: string;
valueType: string;
dataIndex: string;
};

const initialValues = [
{ dataIndex: 'orderId', valueType: 'text', title: '订单id', valueEnum: undefined },
{ dataIndex: 'orderNumber', valueType: 'text', title: '订单号', valueEnum: undefined },
{ dataIndex: 'orderMoney', valueType: 'text', title: '订单金额', valueEnum: undefined },
{ dataIndex: 'productName', valueType: 'text', title: '产品名称', valueEnum: undefined },
{ dataIndex: 'productComment', valueType: 'text', title: '产品介绍', valueEnum: undefined },
{ dataIndex: 'orderStatus', valueType: 'text', title: '订单状态', valueEnum: undefined },
{ dataIndex: 'orderCreated', valueType: 'date', title: '订单创建时间', valueEnum: undefined },
{ dataIndex: 'detailPic', valueType: 'text', title: '产品详情图', valueEnum: undefined },
{ dataIndex: 'closeReason', valueType: 'text', title: '订单关闭原因', valueEnum: undefined },
{ dataIndex: 'closeType', valueType: 'text', title: '订单关闭类型', valueEnum: undefined },
];

const columns: ColumnItemList<SchemaItem> = [
{
title: '列标题',
dataIndex: 'title',
type: 'input',
},
{
title: '值类型',
dataIndex: 'valueType',
type: 'select',
options: tableColumnValueOptions,
},
{
title: '字段',
dataIndex: 'dataIndex',
type: 'select',
},
];

export default () => (
<ColumnList<SchemaItem>
columns={columns}
initialValues={initialValues}
onChange={(values) => {
console.log('onChange', values);
}}
/>
);
55 changes: 55 additions & 0 deletions src/ColumnList/demos/controlled.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { ColumnItemList } from '@ant-design/pro-editor';
import { ColumnList } from '@ant-design/pro-editor';
import { useState } from 'react';

import { tableColumnValueOptions } from './mock_data/options';

type SchemaItem = {
title: string;
valueType: string;
dataIndex: string;
};

const INIT_VALUES = [
{ title: '序号', valueType: 'indexBorder', dataIndex: 'index' },
{
title: '授权企业名称',
valueType: 'text',
dataIndex: 'name',
},
{ title: '被授权企业', valueType: 'text', dataIndex: 'authCompany' },
];

const columns: ColumnItemList<SchemaItem> = [
{
title: '列标题',
dataIndex: 'title',
type: 'input',
},
{
title: '值类型',
dataIndex: 'valueType',
type: 'select',
options: tableColumnValueOptions,
},
{
title: '字段',
dataIndex: 'dataIndex',
type: 'select',
},
];

export default () => {
const [value, setValue] = useState(INIT_VALUES);

return (
<ColumnList
columns={columns}
value={value}
onChange={(values) => {
setValue(values);
console.log('onChange', values);
}}
/>
);
};
Loading

0 comments on commit 992257b

Please sign in to comment.