diff --git a/src/table/__tests__/table.test.tsx b/src/table/__tests__/table.test.tsx
index 2f125069c..465dea851 100644
--- a/src/table/__tests__/table.test.tsx
+++ b/src/table/__tests__/table.test.tsx
@@ -1,6 +1,7 @@
import React from 'react';
import { act } from 'react-dom/test-utils';
import { fireEvent, render } from '@testing-library/react';
+import { Table as AntdTable } from 'antd';
import '@testing-library/jest-dom/extend-expect';
import Table from '../index';
@@ -21,6 +22,18 @@ const dataSource = [
];
describe('test Table', () => {
+ test('should preserve antd Table static members', () => {
+ expect(Table.defaultProps).toBe(AntdTable.defaultProps);
+ expect(Table.SELECTION_COLUMN).toBe(AntdTable.SELECTION_COLUMN);
+ expect(Table.EXPAND_COLUMN).toBe(AntdTable.EXPAND_COLUMN);
+ expect(Table.SELECTION_ALL).toBe(AntdTable.SELECTION_ALL);
+ expect(Table.SELECTION_INVERT).toBe(AntdTable.SELECTION_INVERT);
+ expect(Table.SELECTION_NONE).toBe(AntdTable.SELECTION_NONE);
+ expect(Table.Column).toBe(AntdTable.Column);
+ expect(Table.ColumnGroup).toBe(AntdTable.ColumnGroup);
+ expect(Table.Summary).toBe(AntdTable.Summary);
+ });
+
test('should support tooltip column attribute', async () => {
jest.useFakeTimers();
const { container } = render(
@@ -38,4 +51,46 @@ describe('test Table', () => {
container.parentElement?.querySelector('.ant-tooltip:not(.ant-tooltip-hidden)')
).toBeInTheDocument();
});
+
+ test('should support declarative Table.Column', () => {
+ const { getByText } = render(
+
+ );
+
+ expect(getByText('Name')).toBeInTheDocument();
+ expect(getByText('ZhangSan')).toBeInTheDocument();
+ });
+
+ test('should preserve function column title', () => {
+ const title = jest.fn(() => 'Dynamic Name');
+ const { getByText } = render(
+
+ );
+
+ expect(title).toHaveBeenCalled();
+ expect(getByText('Dynamic Name')).toBeInTheDocument();
+ });
+
+ test('should support tooltip in nested columns', () => {
+ const columns = [
+ {
+ title: 'Information',
+ children: [
+ {
+ dataIndex: 'name',
+ title: 'Name',
+ tooltip: 'This is Name!',
+ },
+ ],
+ },
+ ];
+ const { container } = render(
+
+ );
+
+ expect(container.querySelectorAll('.dtc-table__tooltip')).toHaveLength(1);
+ });
});
diff --git a/src/table/demos/declarative.tsx b/src/table/demos/declarative.tsx
new file mode 100644
index 000000000..a0ea9ad27
--- /dev/null
+++ b/src/table/demos/declarative.tsx
@@ -0,0 +1,23 @@
+import React from 'react';
+import { Table } from 'dt-react-component';
+
+interface DataType {
+ id: number;
+ name: string;
+ age: number;
+ address: string;
+}
+
+const dataSource: DataType[] = [
+ { id: 1, name: 'ZhangSan', age: 17, address: 'New York No. 1 Lake Park' },
+ { id: 2, name: 'LiSi', age: 20, address: 'Bei Jing No. 1 Lake Park' },
+ { id: 3, name: 'WangWu', age: 23, address: 'Zhe Jiang No. 1 Lake Park' },
+];
+
+export default () => (
+ rowKey="id" dataSource={dataSource} pagination={false}>
+ title="Name" dataIndex="name" />
+ title="Age" dataIndex="age" />
+ title="Address" dataIndex="address" />
+
+);
diff --git a/src/table/demos/dynamicTitle.tsx b/src/table/demos/dynamicTitle.tsx
new file mode 100644
index 000000000..088248669
--- /dev/null
+++ b/src/table/demos/dynamicTitle.tsx
@@ -0,0 +1,37 @@
+import React from 'react';
+import { Table } from 'dt-react-component';
+
+import type { ColumnsType } from '..';
+
+interface DataType {
+ id: number;
+ name: string;
+ age: number;
+}
+
+const columns: ColumnsType = [
+ {
+ title: 'Name',
+ dataIndex: 'name',
+ },
+ {
+ title: ({ sortColumns }) => {
+ const sortOrder = sortColumns?.find(({ column }) => column.dataIndex === 'age')?.order;
+ const sortText = sortOrder === 'ascend' ? 'ascending' : 'descending';
+ return sortOrder ? `Age (${sortText})` : 'Age';
+ },
+ dataIndex: 'age',
+ sorter: (previous, next) => previous.age - next.age,
+ tooltip: 'Click the sorter to see the title update',
+ },
+];
+
+const dataSource: DataType[] = [
+ { id: 1, name: 'ZhangSan', age: 23 },
+ { id: 2, name: 'LiSi', age: 17 },
+ { id: 3, name: 'WangWu', age: 20 },
+];
+
+export default () => (
+ rowKey="id" columns={columns} dataSource={dataSource} pagination={false} />
+);
diff --git a/src/table/demos/group.tsx b/src/table/demos/group.tsx
new file mode 100644
index 000000000..4ac2dd79d
--- /dev/null
+++ b/src/table/demos/group.tsx
@@ -0,0 +1,65 @@
+import React from 'react';
+import { Table } from 'dt-react-component';
+
+import type { ColumnsType } from '..';
+
+interface DataType {
+ id: number;
+ name: string;
+ age: number;
+ city: string;
+ address: string;
+}
+
+const columns: ColumnsType = [
+ {
+ title: 'Basic Information',
+ tooltip: 'Personal information',
+ children: [
+ {
+ title: 'Name',
+ dataIndex: 'name',
+ tooltip: 'User name',
+ },
+ {
+ title: 'Age',
+ dataIndex: 'age',
+ },
+ ],
+ },
+ {
+ title: 'Contact Address',
+ children: [
+ {
+ title: 'City',
+ dataIndex: 'city',
+ },
+ {
+ title: 'Address',
+ dataIndex: 'address',
+ tooltip: 'Detailed contact address',
+ },
+ ],
+ },
+];
+
+const dataSource: DataType[] = [
+ {
+ id: 1,
+ name: 'ZhangSan',
+ age: 17,
+ city: 'New York',
+ address: 'No. 1 Lake Park',
+ },
+ {
+ id: 2,
+ name: 'LiSi',
+ age: 20,
+ city: 'Beijing',
+ address: 'No. 1 Lake Park',
+ },
+];
+
+export default () => (
+ rowKey="id" columns={columns} dataSource={dataSource} pagination={false} />
+);
diff --git a/src/table/index.md b/src/table/index.md
index 31f6379e7..4cad473e0 100644
--- a/src/table/index.md
+++ b/src/table/index.md
@@ -14,7 +14,13 @@ demo:
## 示例
-基础使用
+
+
+
+
+
+
+
## API
diff --git a/src/table/index.tsx b/src/table/index.tsx
index 1d98220b6..ba5fb5fd5 100644
--- a/src/table/index.tsx
+++ b/src/table/index.tsx
@@ -2,7 +2,12 @@ import React, { forwardRef, useMemo } from 'react';
import { QuestionOutlined } from '@dtinsight/react-icons';
import { Table as InternalTable, Tooltip } from 'antd';
import type { LabelTooltipType, WrapperTooltipProps } from 'antd/lib/form/FormItemLabel';
-import type { ColumnType as PrimitiveColumnType, TableProps } from 'antd/lib/table';
+import type {
+ ColumnGroupType as PrimitiveColumnGroupType,
+ ColumnsType as PrimitiveColumnsType,
+ ColumnType as PrimitiveColumnType,
+ TableProps,
+} from 'antd/lib/table';
import classNames from 'classnames';
import './index.scss';
@@ -21,12 +26,19 @@ export interface ColumnType extends PrimitiveColumnType {
tooltip?: LabelTooltipType;
}
-export interface ITableProps extends TableProps {
- columns?: ColumnType[];
+export interface ColumnGroupType extends Omit, 'children'> {
+ tooltip?: LabelTooltipType;
+ children: ColumnsType;
+}
+
+export type ColumnsType = (ColumnGroupType | ColumnType)[];
+
+export interface ITableProps extends Omit, 'columns'> {
+ columns?: ColumnsType;
}
export type RefTable = (
- props: React.PropsWithChildren> & { ref?: React.Ref }
+ props: React.PropsWithChildren> & { ref?: React.Ref }
) => React.ReactElement;
function toTooltipProps(tooltip: LabelTooltipType): WrapperTooltipProps | null {
@@ -43,10 +55,11 @@ function toTooltipProps(tooltip: LabelTooltipType): WrapperTooltipProps | null {
};
}
-function convertColumns(columns?: ColumnType[]): PrimitiveColumnType[] {
- if (!columns?.length) return [];
+function convertColumns(columns?: ColumnsType): PrimitiveColumnsType | undefined {
+ if (!columns) return undefined;
+
return columns.map((col) => {
- const { tooltip, title } = col;
+ const { tooltip, title, ...restColumn } = col;
const tooltipProps = toTooltipProps(tooltip);
let tooltipNode: React.ReactNode | null = null;
@@ -61,24 +74,40 @@ function convertColumns(columns?: ColumnType[]): PrimitiveColumnType[] {
);
}
- const titleNode = (
- <>
- {title}
- {tooltipNode}
- >
+ const convertedTitle = tooltipNode ? (
+ typeof title === 'function' ? (
+ (...args: Parameters) => (
+ <>
+ {title(...args)}
+ {tooltipNode}
+ >
+ )
+ ) : (
+ <>
+ {title}
+ {tooltipNode}
+ >
+ )
+ ) : (
+ title
);
+ if ('children' in col) {
+ return {
+ ...restColumn,
+ title: convertedTitle,
+ children: convertColumns(col.children) || [],
+ } as PrimitiveColumnGroupType;
+ }
+
return {
- ...col,
- title: titleNode,
- };
+ ...restColumn,
+ title: convertedTitle,
+ } as PrimitiveColumnType;
});
}
-function Table = any>(
- props: ITableProps,
- ref: React.Ref
-) {
+function Table(props: ITableProps, ref: React.Ref) {
const { columns, className, ...reset } = props;
const cols = useMemo(() => convertColumns(columns), [columns]);
@@ -93,6 +122,7 @@ function Table = any>(
}
const ForwardTable = forwardRef(Table) as unknown as RefTable & {
+ defaultProps?: Partial>;
SELECTION_COLUMN: typeof SELECTION_COLUMN;
EXPAND_COLUMN: typeof EXPAND_COLUMN;
SELECTION_ALL: typeof SELECTION_ALL;
@@ -104,6 +134,7 @@ const ForwardTable = forwardRef(Table) as unknown as RefTable & {
Summary: typeof InternalTable.Summary;
};
+ForwardTable.defaultProps = InternalTable.defaultProps as Partial>;
ForwardTable.SELECTION_COLUMN = SELECTION_COLUMN;
ForwardTable.EXPAND_COLUMN = EXPAND_COLUMN;
ForwardTable.SELECTION_ALL = SELECTION_ALL;