(props: TableTr
>
);
}
+ if (keyName.fixed) {
+ if (keyName.fixed === 'right') {
+ objs.className = `${objs.className} ${prefixCls}-fixed-right`;
+ } else {
+ objs.className = `${objs.className} ${prefixCls}-fixed-true`;
+ }
+ }
return (
+ {objs.children}
+
+ }
key={colNum}
- // style={keyName?.style}
- className={`${objs.className || ''} ${prefixCls}-tr-children-${keyName.align || 'left'} ${
- keyName.className || ''
+ className={`${prefixCls}-tr-children-${keyName.align || 'left'} ${keyName.className || ''} ${
+ objs.className || ''
}`}
onClick={(evn) => onCell(trData, { rowNum, colNum, keyName: keyName.key! }, evn)}
/>
diff --git a/packages/react-table/src/ThComponent.tsx b/packages/react-table/src/ThComponent.tsx
new file mode 100644
index 0000000000..75bcf81a6f
--- /dev/null
+++ b/packages/react-table/src/ThComponent.tsx
@@ -0,0 +1,45 @@
+import React, { Component } from 'react';
+import ReactDOM from 'react-dom';
+import { TableColumns, TableProps, LocationWidth } from './';
+import { locationFixed } from './util';
+
+interface ThComponentProps {
+ colNum: number;
+ item: TableColumns;
+ prefixCls: string;
+ titleNode: JSX.Element;
+ onCellHead: TableProps['onCellHead'];
+ rowNum: number;
+ locationWidth: { [key: number]: LocationWidth };
+ updateLocation: (params: LocationWidth, index: number) => void;
+}
+export default class ThComponent extends Component> {
+ componentDidMount() {
+ const rect = ReactDOM.findDOMNode(this);
+ this.props.updateLocation({ width: (rect as any).getBoundingClientRect().width }, this.props.colNum);
+ }
+
+ render() {
+ const { colNum, prefixCls, item, titleNode, onCellHead, rowNum, locationWidth } = this.props;
+ const { title, key, render, children, ellipsis, fixed = false, ...thProps } = item;
+ let cls = '';
+ if (fixed) {
+ if (fixed === 'right') {
+ cls = prefixCls + '-fixed-right';
+ } else {
+ cls = prefixCls + '-fixed-true';
+ }
+ }
+ return (
+ onCellHead?.(item, colNum, rowNum!, evn)}
+ >
+ {titleNode}
+ |
+ );
+ }
+}
diff --git a/packages/react-table/src/Thead.tsx b/packages/react-table/src/Thead.tsx
index 7af3e644da..5cffc332c0 100644
--- a/packages/react-table/src/Thead.tsx
+++ b/packages/react-table/src/Thead.tsx
@@ -1,19 +1,30 @@
import React from 'react';
import { IProps, noop } from '@uiw/utils';
-import { TableProps, TableColumns } from './';
+import { TableProps, TableColumns, LocationWidth } from './';
import './style/index.less';
+import ThComponentProps from './ThComponent';
export interface TheadProps extends IProps {
data?: TableColumns[][];
onCellHead?: TableProps['onCellHead'];
align?: TableColumns['align'];
className?: TableColumns['className'];
+ locationWidth?: { [key: number]: LocationWidth };
+ updateLocation?: (params: LocationWidth, index: number) => void;
}
export default function TheadComponent(
props: TheadProps & React.HTMLAttributes = {},
) {
- const { prefixCls = 'w-table', className, data = [], onCellHead = noop, ...other } = props;
+ const {
+ prefixCls = 'w-table',
+ className,
+ data = [],
+ onCellHead = noop,
+ locationWidth,
+ updateLocation,
+ ...other
+ } = props;
return (
{data &&
@@ -21,24 +32,27 @@ export default function TheadComponent(
data.map((tds?: TableColumns[], rowNum?: number) => (
{(tds || []).map((item, colNum) => {
- const { title, key, render, children, ellipsis, ...thProps } = item;
- const titleNode: TableColumns['title'] =
- typeof title === 'function' ? title(item, colNum, rowNum!) : title;
+ const { title, key, render, children, ellipsis, fixed = false, ...thProps } = item;
+ const titleNode: TableColumns['title'] = (
+
+ {typeof title === 'function' ? title(item, colNum, rowNum!) : title}
+
+ );
if (thProps.colSpan === 0) {
return null;
}
- if (ellipsis) {
- thProps.className = `${thProps.className || ''} ${prefixCls}-ellipsis`;
- }
return (
- onCellHead(item, colNum, rowNum!, evn)}
- >
- {titleNode}
- |
+ prefixCls={prefixCls}
+ onCellHead={onCellHead}
+ rowNum={rowNum!}
+ titleNode={titleNode}
+ locationWidth={locationWidth!}
+ updateLocation={updateLocation!}
+ />
);
})}
diff --git a/packages/react-table/src/index.tsx b/packages/react-table/src/index.tsx
index 1beef63205..445e4492ce 100644
--- a/packages/react-table/src/index.tsx
+++ b/packages/react-table/src/index.tsx
@@ -1,4 +1,4 @@
-import React, { useMemo, useState, useEffect } from 'react';
+import React, { useMemo, useState, useEffect, useRef } from 'react';
import { IProps, HTMLDivProps, noop } from '@uiw/utils';
import Icon from '@uiw/react-icon';
import Thead from './Thead';
@@ -42,6 +42,7 @@ export type TableColumns = {
style?: React.CSSProperties;
align?: 'left' | 'center' | 'right';
className?: string;
+ fixed?: boolean | 'left' | 'right';
[key: string]: any;
};
@@ -69,6 +70,11 @@ export interface TableProps exten
scroll?: { x?: React.CSSProperties['width']; y?: React.CSSProperties['height'] };
}
+export interface LocationWidth {
+ left?: number;
+ right?: number;
+ width: number;
+}
export interface ICellOptions {
rowNum: number;
colNum: number;
@@ -93,6 +99,37 @@ export default function Table(props: TablePro
...other
} = props;
const [expandIndex, setExpandIndex] = useState>([]);
+ const [locationWidth, setLocationWidth] = useState<{ [key: number]: LocationWidth }>({});
+ const finalLocationWidth = useRef<{ [key: number]: LocationWidth }>({});
+ const updateLocation = (params: LocationWidth, index: number) => {
+ finalLocationWidth.current = {
+ ...finalLocationWidth.current,
+ [index]: {
+ ...finalLocationWidth.current[index],
+ ...params,
+ },
+ };
+ if (index === columns.length - 1) {
+ setLocationWidth(computed());
+ }
+ };
+ const computed = () => {
+ let left = 0,
+ right = 0;
+ for (let index = 0; index < columns.length; index++) {
+ if (finalLocationWidth.current[index]) {
+ finalLocationWidth.current[index].left = left;
+ left = finalLocationWidth.current[index].width + left;
+ }
+ }
+ for (let index = columns.length - 1; index > -1; index--) {
+ if (finalLocationWidth.current[index]) {
+ finalLocationWidth.current[index].right = right;
+ right = finalLocationWidth.current[index].width + right;
+ }
+ }
+ return finalLocationWidth.current;
+ };
useEffect(() => {
if (expandable) {
if (expandable.defaultExpandAllRows) {
@@ -215,11 +252,19 @@ export default function Table(props: TablePro
{title && {title}}
- {columns && columns.length > 0 && }
+ {columns && columns.length > 0 && (
+
+ )}
{data && data.length > 0 && (
tbody > tr {
transition: all 0.3s;
+ > td {
+ background-color: #fff;
+ position: relative;
+ z-index: 1;
+ }
&:hover,
&:hover:nth-child(2n) {
- background-color: #efefef;
+ > td {
+ background-color: #efefef;
+ }
}
&:nth-child(2n) {
- background-color: #f9f9f9;
+ > td {
+ background-color: #f9f9f9;
+ }
}
}
> thead {
> tr > th {
font-weight: normal;
padding: 8px;
+ background-color: #f6f9fb;
+ position: relative;
+ z-index: 1;
}
> tr,
tr:nth-child(2n) {
@@ -47,6 +59,7 @@
white-space: nowrap;
text-overflow: ellipsis;
word-break: keep-all;
+ display: block;
}
&-tr-children-center {
text-align: center;
@@ -57,6 +70,41 @@
&-tr-children-right {
text-align: right;
}
+ &-fixed-true {
+ position: sticky !important;
+ z-index: 2 !important;
+ // border: 0; 透风 1px
+ }
+ &-fixed-right {
+ position: sticky !important;
+ z-index: 2 !important;
+ // border: 0; 透风 1px
+ }
+ &-fixed-true::after {
+ box-shadow: inset 10px 0 8px -8px rgb(0 0 0 / 15%);
+ position: absolute;
+ top: 0;
+ right: 0;
+ bottom: -1px;
+ width: 30px;
+ transform: translateX(100%);
+ transition: box-shadow 0.3s;
+ content: '';
+ pointer-events: none;
+ }
+ &-fixed-right::after {
+ box-shadow: inset -10px 0 8px -8px rgb(0 0 0 / 15%);
+ position: absolute;
+ top: 0;
+ bottom: -1px;
+ left: 0;
+ width: 30px;
+ transform: translateX(-100%);
+ transition: box-shadow 0.3s;
+ content: '';
+ pointer-events: none;
+ border-right: 1px solid #f0f0f0;
+ }
&-bordered {
> table {
tr > th,
diff --git a/packages/react-table/src/util.ts b/packages/react-table/src/util.ts
index 68a0c8236f..5f96cf9d80 100644
--- a/packages/react-table/src/util.ts
+++ b/packages/react-table/src/util.ts
@@ -1,4 +1,5 @@
-import { TableColumns } from './';
+import { TableColumns, LocationWidth } from './';
+import React from 'react';
/**
* Get colspan number
@@ -127,3 +128,13 @@ export function getAllColumnsKeys(data: TableColumns[], keys: TableColumns
}
return keys;
}
+
+export function locationFixed(
+ fixed: boolean | 'left' | 'right',
+ location: { [key: number]: LocationWidth },
+ index: number,
+): React.CSSProperties {
+ if (!fixed) return {};
+ if (fixed === 'right') return { right: location[index]?.right };
+ return { left: location[index]?.left };
+}
From a86201ea64ebfc9fd165b173fe0bc7c57c589337 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=85=B0=E9=91=AB?= <1192065030@qq.com>
Date: Mon, 21 Mar 2022 19:54:35 +0800
Subject: [PATCH 5/7] =?UTF-8?q?feat(Table):=20Table=20=E6=96=B0=E5=A2=9E?=
=?UTF-8?q?=E5=9B=BA=E5=AE=9A=E5=88=97=E5=B1=9E=E6=80=A7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/react-table/src/ThComponent.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/packages/react-table/src/ThComponent.tsx b/packages/react-table/src/ThComponent.tsx
index 75bcf81a6f..5711369687 100644
--- a/packages/react-table/src/ThComponent.tsx
+++ b/packages/react-table/src/ThComponent.tsx
@@ -16,7 +16,7 @@ interface ThComponentProps {
export default class ThComponent extends Component> {
componentDidMount() {
const rect = ReactDOM.findDOMNode(this);
- this.props.updateLocation({ width: (rect as any).getBoundingClientRect().width }, this.props.colNum);
+ this.props.updateLocation({ width: (rect as Element).getBoundingClientRect().width }, this.props.colNum);
}
render() {
From 35816f77babcafb01a3030fff02f49bc90b53aa0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=85=B0=E9=91=AB?= <1192065030@qq.com>
Date: Mon, 21 Mar 2022 20:43:33 +0800
Subject: [PATCH 6/7] doc(Table): Update README.md
---
packages/react-table/README.md | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)
diff --git a/packages/react-table/README.md b/packages/react-table/README.md
index fa8a7d876a..0fc5d69ad8 100644
--- a/packages/react-table/README.md
+++ b/packages/react-table/README.md
@@ -954,17 +954,17 @@ ReactDOM.render(, _mount_);
列描述数据对象,是 columns 中的一项,
-| 参数 | 说明 | 类型 | 默认值 |
-|--------- |-------- |--------- |-------- |
-| title | 列头显示文字。| ReactNode | - |
-| key | 需要的 key,可以忽略这个属性,如果标题带有 `render` 函数,那么这个 `key` 为必须非常重要。| String | - |
-| width | 列宽度。| Number | - |
-| colSpan | 合并表头行。| Number | - |
-| ellipsis | 超过宽度将自动省略。`v4.8.7+`| Boolean | `false` |
-| render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前值的 `key`,行索引数据,当前行号,当前列号。| `Function(text, key, rowData, rowNumber, columnNumber)` | - |
-| align | 设置列的对齐方式 | "left"\|"center"\|"right" | - |
-| className | 列样式类名 | String | - |
-| fixed | 把选择框列固定 | Boolean \|"left"\|"right" | - |
+| 参数 | 说明 | 类型 | 默认值 | 版本 |
+|--------- |-------- |--------- |-------- |-------- |
+| title | 列头显示文字。| ReactNode | - | - |
+| key | 需要的 key,可以忽略这个属性,如果标题带有 `render` 函数,那么这个 `key` 为必须非常重要。| String | - | - |
+| width | 列宽度。| Number | - | - |
+| colSpan | 合并表头行。| Number | - | - |
+| ellipsis | 超过宽度将自动省略。`v4.8.7+`| Boolean | `false` | - |
+| render | 生成复杂数据的渲染函数,参数分别为当前行的值,当前值的 `key`,行索引数据,当前行号,当前列号。| `Function(text, key, rowData, rowNumber, columnNumber)` | - | - |
+| align | 设置列的对齐方式 | "left"\|"center"\|"right" | - | - |
+| className | 列样式类名 | String | - | - |
+| fixed | 把选择框列固定 | Boolean \|"left"\|"right" | - | 4.15.1 |
### expandable
From 68f82624299c27bfa142d9724b50bf5c2281b657 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E5=85=B0=E9=91=AB?= <1192065030@qq.com>
Date: Tue, 22 Mar 2022 16:30:34 +0800
Subject: [PATCH 7/7] =?UTF-8?q?update(Table):=20Table=20=E6=94=AF=E6=8C=81?=
=?UTF-8?q?=E6=A0=91=E5=BD=A2=E6=95=B0=E6=8D=AE=E6=98=BE=E7=A4=BA=E5=92=8C?=
=?UTF-8?q?=E5=8F=AF=E5=B1=95=E5=BC=80=E5=90=8C=E6=97=B6=E5=87=BA=E7=8E=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
packages/react-table/README.md | 8 +++-----
packages/react-table/src/TableTr.tsx | 6 ++++--
packages/react-table/src/index.tsx | 13 ++++++++++++-
3 files changed, 19 insertions(+), 8 deletions(-)
diff --git a/packages/react-table/README.md b/packages/react-table/README.md
index 0fc5d69ad8..de95f97d6c 100644
--- a/packages/react-table/README.md
+++ b/packages/react-table/README.md
@@ -729,9 +729,6 @@ ReactDOM.render(, _mount_);
可以通过设置 indentSize 以控制每一层的缩进宽度
-> ⚠️ 注意: 树形数据展示和`expandable.expandedRowRender`请不要同时出现,后续或将支持
-
-
```jsx
import ReactDOM from 'react-dom';
@@ -805,7 +802,7 @@ const Demo = () => {
)
@@ -968,7 +965,8 @@ ReactDOM.render(, _mount_);
### expandable
-注意 expandedRowKeys 与 onExpandedRowsChange 必须成对出现
+> ⚠️ 注意: expandedRowKeys 与 onExpandedRowsChange 必须同时出现或不出现
+
| 参数 | 说明 | 类型 | 默认值 |
|--------- |-------- |--------- |-------- |
diff --git a/packages/react-table/src/TableTr.tsx b/packages/react-table/src/TableTr.tsx
index ce05e5c540..2f1d2d7cff 100644
--- a/packages/react-table/src/TableTr.tsx
+++ b/packages/react-table/src/TableTr.tsx
@@ -38,9 +38,11 @@ export default function TableTr(props: TableTr
locationWidth,
} = props;
const [isOpacity, setIsOpacity] = useState(false);
+ const [childrenIndex, setChildrenIndex] = useState(0);
const [expandIndex, setExpandIndex] = useState>([]);
useEffect(() => {
setIsOpacity(!!data?.find((it) => it[childrenColumnName]));
+ setChildrenIndex(keys?.findIndex((it) => it.key === 'uiw-expanded') === -1 ? 0 : 1);
}, [data]);
const IconDom = useMemo(() => {
@@ -92,7 +94,7 @@ export default function TableTr(props: TableTr
}
}
const isHasChildren = Array.isArray(trData[childrenColumnName]);
- if (colNum === 0 && (isOpacity || hierarchy || isHasChildren)) {
+ if (colNum === childrenIndex && (isOpacity || hierarchy || isHasChildren)) {
objs.children = (
<>
{IconDom(key, isHasChildren)}
@@ -126,10 +128,10 @@ export default function TableTr(props: TableTr
);
})}
+ {isExpandedDom(trData, rowNum)}
{expandIndex.includes(key) && (
)}
- {isExpandedDom(trData, rowNum)}
);
})}
diff --git a/packages/react-table/src/index.tsx b/packages/react-table/src/index.tsx
index 445e4492ce..1a2fc640bc 100644
--- a/packages/react-table/src/index.tsx
+++ b/packages/react-table/src/index.tsx
@@ -131,9 +131,20 @@ export default function Table(props: TablePro
return finalLocationWidth.current;
};
useEffect(() => {
+ const childKey = expandable?.childrenColumnName || 'children';
+ const deep = (params: TableColumns) => {
+ const arr1: Array = [];
+ const arr = params.map((it: T, index: number) => {
+ if (Array.isArray(it[childKey])) {
+ arr1.push(...deep(it[childKey]));
+ }
+ return rowKey ? it[rowKey] : index;
+ });
+ return [...arr1, ...arr];
+ };
if (expandable) {
if (expandable.defaultExpandAllRows) {
- setExpandIndex(data.map((it, index) => (rowKey ? it[rowKey] : index)));
+ setExpandIndex(deep(data));
return;
}
if (expandable.defaultExpandedRowKeys) {
|