-
Notifications
You must be signed in to change notification settings - Fork 36
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add table component * fix: fix code review on table * fix: fix ts lint --------- Co-authored-by: jialan <jialan@dtstack.com>
- Loading branch information
1 parent
be7aacb
commit 0553e28
Showing
6 changed files
with
224 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import React from 'react'; | ||
import Table from '../index'; | ||
import { fireEvent, render } from '@testing-library/react'; | ||
import '@testing-library/jest-dom/extend-expect'; | ||
import { act } from 'react-dom/test-utils'; | ||
|
||
const columns = [ | ||
{ | ||
dataIndex: 'name', | ||
title: 'Name', | ||
tooltip: { title: 'This is Name!', mouseEnterDelay: 0, mouseLeaveDelay: 0 }, | ||
}, | ||
{ dataIndex: 'address', title: 'Address' }, | ||
]; | ||
|
||
const dataSource = [ | ||
{ id: 1, name: 'ZhangSan', age: 17, address: 'New York No. 1 Lake Park' }, | ||
{ id: 2, name: 'LiSi', age: 17, address: 'Bei Jing No. 1 Lake Park' }, | ||
{ id: 3, name: 'WangWu', age: 17, address: 'Zhe Jiang No. 1 Lake Park' }, | ||
]; | ||
|
||
describe('test Table', () => { | ||
test('should support tooltip column attribute', async () => { | ||
jest.useFakeTimers(); | ||
const { container } = render( | ||
<Table rowKey="id" columns={columns} dataSource={dataSource} /> | ||
); | ||
const iconNode = container.querySelector('.dtc-table__tooltip'); | ||
expect(iconNode).toBeInTheDocument(); | ||
|
||
act(() => { | ||
fireEvent.mouseEnter(iconNode!); | ||
jest.runAllTimers(); | ||
}); | ||
|
||
expect( | ||
container.parentElement?.querySelector('.ant-tooltip:not(.ant-tooltip-hidden)') | ||
).toBeInTheDocument(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import React from 'react'; | ||
import { Table } from 'dt-react-component'; | ||
import { ColumnType } from '..'; | ||
|
||
interface DataType { | ||
id: number; | ||
name: string; | ||
age: number; | ||
address: string; | ||
} | ||
|
||
const columns: ColumnType<DataType>[] = [ | ||
{ dataIndex: 'name', title: 'Name', tooltip: 'This is Name!' }, | ||
{ | ||
dataIndex: 'age', | ||
title: 'Age', | ||
tooltip: { icon: <span>❓</span>, title: 'This is Age!', color: 'pink' }, | ||
}, | ||
{ dataIndex: 'address', title: 'Address' }, | ||
]; | ||
|
||
const dataSource = [ | ||
{ id: 1, name: 'ZhangSan', age: 17, address: 'New York No. 1 Lake Park' }, | ||
{ id: 2, name: 'LiSi', age: 17, address: 'Bei Jing No. 1 Lake Park' }, | ||
{ id: 3, name: 'WangWu', age: 17, address: 'Zhe Jiang No. 1 Lake Park' }, | ||
]; | ||
|
||
export default () => { | ||
return <Table rowKey="id" columns={columns} dataSource={dataSource} />; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
--- | ||
title: Table 表格 | ||
group: 组件 | ||
toc: content | ||
demo: | ||
cols: 1 | ||
--- | ||
|
||
# Table 表格 | ||
|
||
## 何时使用 | ||
|
||
继承并完全兼容`antd`的`Table`,可以直接替换,并扩充了其他功能 | ||
|
||
## 示例 | ||
|
||
<code src="./demos/basic.tsx" description="为标题头添加tooltip">基础使用</code> | ||
|
||
## API | ||
|
||
### Table | ||
|
||
完全继承自`antd`的`Table`组件,参考[Table](https://4x.ant.design/components/table-cn/#API) | ||
|
||
### ColumnType | ||
|
||
除继承自`Table`组件的 ColumnType 外,还额外扩充以下属性 | ||
| 参数 | 说明 | 类型 | 默认值 | | ||
| ----------- | ---------------------------------------- | ----------------- | ------ | | ||
| tooltip | 配置表格 title 提示信息 | `React.ReactNode` \| <a href="https://4x.ant.design/components/tooltip-cn/#API" target="_blank">TooltipProps & { icon: React.ReactNode }</a> | - | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
.dtc-table { | ||
&__tooltip { | ||
margin-left: 4px; | ||
font-size: 16px; | ||
color: #B1B4C5; | ||
cursor: help; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
import React, { forwardRef, useMemo } from 'react'; | ||
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 { QuestionCircleOutlined } from '@ant-design/icons'; | ||
import classNames from 'classnames'; | ||
import './index.scss'; | ||
|
||
const { | ||
SELECTION_COLUMN, | ||
EXPAND_COLUMN, | ||
SELECTION_ALL, | ||
SELECTION_INVERT, | ||
SELECTION_NONE, | ||
Column, | ||
ColumnGroup, | ||
} = InternalTable; | ||
|
||
export interface ColumnType<R = any> extends PrimitiveColumnType<R> { | ||
tooltip?: LabelTooltipType; | ||
} | ||
|
||
export interface ITableProps<R = any> extends TableProps<R> { | ||
columns?: ColumnType<R>[]; | ||
} | ||
|
||
export type RefTable = <R extends object = any>( | ||
props: React.PropsWithChildren<TableProps<R>> & { ref?: React.Ref<HTMLDivElement | unknown> } | ||
) => React.ReactElement; | ||
|
||
function toTooltipProps(tooltip: LabelTooltipType): WrapperTooltipProps | null { | ||
if (!tooltip) { | ||
return null; | ||
} | ||
|
||
if (typeof tooltip === 'object' && !React.isValidElement(tooltip)) { | ||
return tooltip as WrapperTooltipProps; | ||
} | ||
|
||
return { | ||
title: tooltip, | ||
}; | ||
} | ||
|
||
function convertColumns(columns?: ColumnType[]): PrimitiveColumnType<any>[] { | ||
if (!columns?.length) return []; | ||
return columns.map((col) => { | ||
const { tooltip, title } = col; | ||
|
||
const tooltipProps = toTooltipProps(tooltip); | ||
let tooltipNode: React.ReactNode | null = null; | ||
if (tooltipProps) { | ||
const { icon = <QuestionCircleOutlined />, ...restTooltipProps } = tooltipProps; | ||
tooltipNode = ( | ||
<Tooltip {...restTooltipProps}> | ||
{React.cloneElement(icon, { | ||
className: `dtc-table__tooltip ${icon.props?.className || ''}`, | ||
})} | ||
</Tooltip> | ||
); | ||
} | ||
|
||
const titleNode = ( | ||
<> | ||
{title} | ||
{tooltipNode} | ||
</> | ||
); | ||
|
||
return { | ||
...col, | ||
title: titleNode, | ||
}; | ||
}); | ||
} | ||
|
||
function Table<R extends Record<any, any> = any>( | ||
props: ITableProps<R>, | ||
ref: React.Ref<HTMLDivElement> | ||
) { | ||
const { columns, className, ...reset } = props; | ||
const cols = useMemo(() => convertColumns(columns), [columns]); | ||
|
||
return ( | ||
<InternalTable<R> | ||
{...reset} | ||
className={classNames(['dtc-table', className])} | ||
columns={cols} | ||
ref={ref} | ||
/> | ||
); | ||
} | ||
|
||
const ForwardTable = forwardRef(Table) as unknown as RefTable & { | ||
SELECTION_COLUMN: typeof SELECTION_COLUMN; | ||
EXPAND_COLUMN: typeof EXPAND_COLUMN; | ||
SELECTION_ALL: typeof SELECTION_ALL; | ||
SELECTION_INVERT: typeof SELECTION_INVERT; | ||
SELECTION_NONE: typeof SELECTION_NONE; | ||
Column: typeof Column; | ||
ColumnGroup: typeof ColumnGroup; | ||
// use InternalTable.Summary because of typescript bug(TS2742) | ||
Summary: typeof InternalTable.Summary; | ||
}; | ||
|
||
ForwardTable.SELECTION_COLUMN = SELECTION_COLUMN; | ||
ForwardTable.EXPAND_COLUMN = EXPAND_COLUMN; | ||
ForwardTable.SELECTION_ALL = SELECTION_ALL; | ||
ForwardTable.SELECTION_INVERT = SELECTION_INVERT; | ||
ForwardTable.SELECTION_NONE = SELECTION_NONE; | ||
ForwardTable.Column = Column; | ||
ForwardTable.ColumnGroup = ColumnGroup; | ||
ForwardTable.Summary = InternalTable.Summary; | ||
|
||
export default ForwardTable; |