Skip to content

Commit

Permalink
feat(Table): Table 新增树形数据结构展示功能 #539 (#686)
Browse files Browse the repository at this point in the history
  • Loading branch information
cuilanxin committed Mar 17, 2022
1 parent dacf2a8 commit 369fa95
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 20 deletions.
13 changes: 12 additions & 1 deletion packages/react-table/README.md
Expand Up @@ -773,7 +773,16 @@ const dataSource = [
age: '10',
id: '1-1',
children: [
{ name: '邓紫棋-0-1-1', age: '10', id: '1-1-1',},
{
name: '邓紫棋-0-1-1',
age: '10',
id: '1-1-1',
children: [
{name: '邓紫棋-0-1-1-1', age: '10', id: '-0-1-1-1'},
{name: '邓紫棋-0-1-1-2', age: '10', id: '-0-1-1-2'},
{name: '邓紫棋-0-1-1-3', age: '10', id: '-0-1-1-3'},
]
},
{ name: '邓紫棋-0-1-2', age: '10', id: '1-1-2',}
]
},
Expand Down Expand Up @@ -834,6 +843,8 @@ ReactDOM.render(<Demo />, _mount_);
| colSpan | 合并表头行。| Number | - |
| ellipsis | 超过宽度将自动省略。`v4.8.7+`| Boolean | `false` |
| render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前值的 `key`,行索引数据,当前行号,当前列号。| `Function(text, key, rowData, rowNumber, columnNumber)` | - |
| align | 设置列的对齐方式 | "left"|"center"|"right" | - |
| className | 列样式类名 | string | - |

### expandable

Expand Down
41 changes: 29 additions & 12 deletions packages/react-table/src/TableTr.tsx
@@ -1,4 +1,4 @@
import React, { useMemo, useState } from 'react';
import React, { useMemo, useState, useEffect } from 'react';
import Icon from '@uiw/react-icon';
import { TableProps } from './';
import './style/index.less';
Expand All @@ -7,7 +7,7 @@ import { noop } from '@uiw/utils';
interface TableTrProps<T> {
rowKey?: keyof T;
data: T[];
keys: string[];
keys: TableProps['columns'];
render: { [key: string]: any };
ellipsis?: Record<string, boolean>;
prefixCls: string;
Expand All @@ -34,16 +34,25 @@ export default function TableTr<T extends { [key: string]: any }>(props: TableTr
indentSize,
childrenColumnName,
} = props;

const [isOpacity, setIsOpacity] = useState(false);
const [expandIndex, setExpandIndex] = useState<Array<T[keyof T] | number>>([]);
useEffect(() => {
setIsOpacity(!!data?.find((it) => it[childrenColumnName]));
}, [data]);

const IconDom = useMemo(() => {
return (key: T[keyof T] | number, isOpacity: boolean) => {
const flag = expandIndex.includes(key);
return (
<Icon
type={flag ? 'minus-square-o' : 'plus-square-o'}
style={{ marginRight: 10, opacity: isOpacity ? 1 : 0, marginLeft: hierarchy * indentSize }}
style={{
marginRight: 10,
opacity: isOpacity ? 1 : 0,
marginLeft: hierarchy * indentSize,
float: 'left',
marginTop: 3.24,
}}
onClick={() => {
setExpandIndex(flag ? expandIndex.filter((it) => it !== key) : [...expandIndex, key]);
}}
Expand All @@ -61,12 +70,12 @@ export default function TableTr<T extends { [key: string]: any }>(props: TableTr
return (
<React.Fragment key={rowNum}>
<tr key={key}>
{keys.map((keyName, colNum) => {
{keys!.map((keyName, colNum) => {
let objs: React.TdHTMLAttributes<HTMLTableDataCellElement> = {
children: trData[keyName],
children: trData[keyName.key!],
};
if (render[keyName]) {
const child = render[keyName](trData[keyName], keyName, trData, rowNum, colNum);
if (render[keyName.key!]) {
const child = render[keyName.key!](trData[keyName.key!], keyName.key!, trData, rowNum, colNum);
if (React.isValidElement(child)) {
objs.children = child;
} else {
Expand All @@ -79,21 +88,29 @@ export default function TableTr<T extends { [key: string]: any }>(props: TableTr
}
}
}
if (ellipsis && ellipsis[keyName]) {
if (ellipsis && ellipsis[keyName.key!]) {
objs.className = `${prefixCls}-ellipsis`;
}
const isHasChildren = Array.isArray(trData[childrenColumnName]);
if (colNum === 0 && (hierarchy || isHasChildren)) {
objs.className = `${objs.className} ${prefixCls}-has-children`;
if (colNum === 0 && (isOpacity || hierarchy || isHasChildren)) {
objs.children = (
<>
{IconDom(key, isHasChildren)}
<span style={{ paddingLeft: hierarchy * indentSize }}></span>
{objs.children}
</>
);
}
return (
<td {...objs} key={colNum} onClick={(evn) => onCell(trData, { rowNum, colNum, keyName }, evn)} />
<td
{...objs}
key={colNum}
// style={keyName?.style}
className={`${objs.className} ${prefixCls}-tr-children-${keyName?.align || 'left'} ${
keyName.className || ''
}`}
onClick={(evn) => onCell(trData, { rowNum, colNum, keyName: keyName.key! }, evn)}
/>
);
})}
</tr>
Expand Down
9 changes: 8 additions & 1 deletion packages/react-table/src/Thead.tsx
Expand Up @@ -6,6 +6,8 @@ import './style/index.less';
export interface TheadProps<T extends { [key: string]: V }, V = any> extends IProps {
data?: TableColumns<T>[][];
onCellHead?: TableProps<T, V>['onCellHead'];
align?: TableColumns['align'];
className?: TableColumns['className'];
}

export default function TheadComponent<T extends { [key: string]: V }, V>(
Expand All @@ -29,7 +31,12 @@ export default function TheadComponent<T extends { [key: string]: V }, V>(
thProps.className = `${thProps.className || ''} ${prefixCls}-ellipsis`;
}
return (
<th key={colNum} onClick={(evn) => onCellHead(item, colNum, rowNum!, evn)} {...thProps}>
<th
key={colNum}
{...thProps}
className={`${prefixCls}-tr-children-${item?.align || 'left'} ${className || ''}`}
onClick={(evn) => onCellHead(item, colNum, rowNum!, evn)}
>
{titleNode}
</th>
);
Expand Down
4 changes: 3 additions & 1 deletion packages/react-table/src/index.tsx
Expand Up @@ -40,6 +40,8 @@ export type TableColumns<T = any> = {
ellipsis?: boolean;
render?: (text: string, keyName: string, rowData: T, rowNumber: number, columnNumber: number) => React.ReactNode;
style?: React.CSSProperties;
align?: 'left' | 'center' | 'right';
className?: string;
[key: string]: any;
};

Expand Down Expand Up @@ -137,7 +139,7 @@ export default function Table<T extends { [key: string]: V }, V>(props: TablePro
let keys = getAllColumnsKeys<T>(columns);
let selfColumns: TableColumns<T>[] = [];
if (expandable?.expandedRowRender) {
keys = ['uiw-expanded', ...keys];
keys = [{ key: 'uiw-expanded', align: 'center' }, ...keys];
selfColumns = [
{
title: '',
Expand Down
11 changes: 8 additions & 3 deletions packages/react-table/src/style/index.less
Expand Up @@ -48,9 +48,14 @@
text-overflow: ellipsis;
word-break: keep-all;
}
&-has-children {
display: flex;
align-items: center;
&-tr-children-center {
text-align: center;
}
&-tr-children-left {
text-align: left;
}
&-tr-children-right {
text-align: right;
}
&-bordered {
> table {
Expand Down
4 changes: 2 additions & 2 deletions packages/react-table/src/util.ts
Expand Up @@ -117,12 +117,12 @@ export function getLevelItems<T>(data: TableColumns<T>[], result?: ILevelItems<T
* Get all columns keys
* @param {Array} data
*/
export function getAllColumnsKeys<T>(data: TableColumns<T>[], keys: any[] = []): string[] {
export function getAllColumnsKeys<T>(data: TableColumns<T>[], keys: TableColumns<T>[] = []): TableColumns<T>[] {
for (let i = 0; i < data.length; i += 1) {
if (data[i].children) {
keys = keys.concat(getAllColumnsKeys(data[i].children || []));
} else if (data[i].key) {
keys.push(data[i].key);
keys.push(data[i]);
}
}
return keys;
Expand Down

0 comments on commit 369fa95

Please sign in to comment.