From 38d75cdfad9a2f94e9a846cc31d1bf09484957f1 Mon Sep 17 00:00:00 2001 From: lijianan <574980606@qq.com> Date: Sun, 29 Sep 2024 11:39:01 +0800 Subject: [PATCH] feat: expandedRowClassName support receive a string (#1195) --- README.md | 2 +- docs/examples/virtual.tsx | 34 +++++++++------------------------- src/Body/BodyRow.tsx | 15 +++++++-------- src/VirtualTable/BodyLine.tsx | 6 ++++-- src/context/TableContext.tsx | 2 +- src/interface.ts | 2 +- src/utils/expandUtil.tsx | 17 ++++++++++++++++- tests/ExpandRow.spec.jsx | 15 +++++++++++++++ tests/Virtual.spec.tsx | 23 +++++++++++++---------- 9 files changed, 67 insertions(+), 49 deletions(-) diff --git a/README.md b/README.md index 5adb71f89..8d23a487f 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,7 @@ React.render(, mountNode); | expandable.defaultExpandedRowKeys | String[] | [] | initial expanded rows keys | | expandable.expandedRowKeys | String[] | | current expanded rows keys | | expandable.expandedRowRender | Function(recode, index, indent, expanded):ReactNode | | Content render to expanded row | -| expandable.expandedRowClassName | Function(recode, index, indent):string | | get expanded row's className | +| expandable.expandedRowClassName | `string` \| `(recode, index, indent) => string` | | get expanded row's className | | expandable.expandRowByClick | boolean | | Support expand by click row | | expandable.expandIconColumnIndex | Number | 0 | The index of expandIcon which column will be inserted when expandIconAsCell is false | | expandable.expandIcon | props => ReactNode | | Customize expand icon | diff --git a/docs/examples/virtual.tsx b/docs/examples/virtual.tsx index bcb1a59fe..3371ebd73 100644 --- a/docs/examples/virtual.tsx +++ b/docs/examples/virtual.tsx @@ -188,32 +188,20 @@ const data: RecordType[] = new Array(4 * 10000).fill(null).map((_, index) => ({ // ], })); -const Demo = () => { - const tblRef = React.useRef(); - +const Demo: React.FC = () => { + const tableRef = React.useRef(); return (
- - - + - b || c} scroll={{ x: 1300, y: 200 }} @@ -229,14 +217,10 @@ const Demo = () => { rowClassName="nice-try" getContainerWidth={(ele, width) => { // Minus border - const borderWidth = getComputedStyle( - ele.querySelector('.rc-table-tbody'), - ).borderInlineStartWidth; - const mergedWidth = width - parseInt(borderWidth, 10); - + const { borderInlineStartWidth } = getComputedStyle(ele.querySelector('.rc-table-tbody')); + const mergedWidth = width - parseInt(borderInlineStartWidth, 10); return mergedWidth; }} - ref={tblRef} />
); diff --git a/src/Body/BodyRow.tsx b/src/Body/BodyRow.tsx index 8cee145bf..d33cf38dc 100644 --- a/src/Body/BodyRow.tsx +++ b/src/Body/BodyRow.tsx @@ -6,6 +6,7 @@ import devRenderTimes from '../hooks/useRenderTimes'; import useRowInfo from '../hooks/useRowInfo'; import type { ColumnType, CustomizeComponent, GetRowKey } from '../interface'; import ExpandedRow from './ExpandedRow'; +import { computedExpandedClassName } from '../utils/expandUtil'; export interface BodyRowProps { record: RecordType; @@ -126,8 +127,7 @@ function BodyRow( // 若没有 expandedRowRender 参数, 将使用 baseRowNode 渲染 Children // 此时如果 level > 1 则说明是 expandedRow, 一样需要附加 computedExpandedRowClassName - const computedExpandedRowClassName = - expandedRowClassName && expandedRowClassName(record, index, indent); + const expandedClsName = computedExpandedClassName(expandedRowClassName, record, index, indent); // ======================== Base tr row ======================== const baseRowNode = ( @@ -139,12 +139,11 @@ function BodyRow( `${prefixCls}-row`, `${prefixCls}-row-level-${indent}`, rowProps?.className, - indent >= 1 ? computedExpandedRowClassName : '', + { + [expandedClsName]: indent >= 1, + }, )} - style={{ - ...style, - ...rowProps?.style, - }} + style={{ ...style, ...rowProps?.style }} > {flattenColumns.map((column: ColumnType, colIndex) => { const { render, dataIndex, className: columnClassName } = column; @@ -192,7 +191,7 @@ function BodyRow( className={classNames( `${prefixCls}-expanded-row`, `${prefixCls}-expanded-row-level-${indent + 1}`, - computedExpandedRowClassName, + expandedClsName, )} prefixCls={prefixCls} component={RowComponent} diff --git a/src/VirtualTable/BodyLine.tsx b/src/VirtualTable/BodyLine.tsx index 4be634457..a02d195a3 100644 --- a/src/VirtualTable/BodyLine.tsx +++ b/src/VirtualTable/BodyLine.tsx @@ -7,6 +7,7 @@ import type { FlattenData } from '../hooks/useFlattenRecords'; import useRowInfo from '../hooks/useRowInfo'; import VirtualCell from './VirtualCell'; import { StaticContext } from './context'; +import { computedExpandedClassName } from '../utils/expandUtil'; export interface BodyLineProps { data: FlattenData; @@ -41,7 +42,8 @@ const BodyLine = React.forwardRef((props, ref) => let expandRowNode: React.ReactElement; if (rowSupportExpand && expanded) { const expandContent = expandedRowRender(record, index, indent + 1, expanded); - const computedExpandedRowClassName = expandedRowClassName?.(record, index, indent); + + const expandedClsName = computedExpandedClassName(expandedRowClassName, record, index, indent); let additionalProps: React.TdHTMLAttributes = {}; if (fixColumn) { @@ -59,7 +61,7 @@ const BodyLine = React.forwardRef((props, ref) => className={classNames( `${prefixCls}-expanded-row`, `${prefixCls}-expanded-row-level-${indent + 1}`, - computedExpandedRowClassName, + expandedClsName, )} > { // Body rowClassName: string | RowClassName; - expandedRowClassName: RowClassName; + expandedRowClassName: string | RowClassName; onRow?: GetComponentProps; emptyNode?: React.ReactNode; diff --git a/src/interface.ts b/src/interface.ts index 051ac57ae..e645b2145 100644 --- a/src/interface.ts +++ b/src/interface.ts @@ -247,7 +247,7 @@ export interface ExpandableConfig { /** @deprecated Please use `EXPAND_COLUMN` in `columns` directly */ expandIconColumnIndex?: number; showExpandColumn?: boolean; - expandedRowClassName?: RowClassName; + expandedRowClassName?: string | RowClassName; childrenColumnName?: string; rowExpandable?: (record: RecordType) => boolean; columnWidth?: number | string; diff --git a/src/utils/expandUtil.tsx b/src/utils/expandUtil.tsx index 8560649e5..df6395c78 100644 --- a/src/utils/expandUtil.tsx +++ b/src/utils/expandUtil.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import classNames from 'classnames'; -import type { RenderExpandIconProps, Key, GetRowKey } from '../interface'; +import type { RenderExpandIconProps, Key, GetRowKey, ExpandableConfig } from '../interface'; export function renderExpandIcon({ prefixCls, @@ -50,3 +50,18 @@ export function findAllChildrenKeys( return keys; } + +export function computedExpandedClassName( + cls: ExpandableConfig['expandedRowClassName'], + record: RecordType, + index: number, + indent: number, +) { + if (typeof cls === 'string') { + return cls; + } + if (typeof cls === 'function') { + return cls(record, index, indent); + } + return ''; +} diff --git a/tests/ExpandRow.spec.jsx b/tests/ExpandRow.spec.jsx index d06746cd3..93c0bed35 100644 --- a/tests/ExpandRow.spec.jsx +++ b/tests/ExpandRow.spec.jsx @@ -415,6 +415,21 @@ describe('Table.Expand', () => { expect(wrapper.find('tbody tr').at(1).hasClass('expand-row-test-class-name')).toBeTruthy(); }); + it("renders expend row class correctly when it's string", () => { + const expandedRowClassName = 'expand-row-test-str-class-name'; + const wrapper = mount( + createTable({ + expandable: { + expandedRowRender, + expandedRowKeys: [0], + expandedRowClassName, + }, + }), + ); + + expect(wrapper.find('tbody tr').at(1).hasClass(expandedRowClassName)).toBeTruthy(); + }); + it('renders expend row class correctly using children without expandedRowRender', () => { const expandedRowClassName = vi.fn().mockReturnValue('expand-row-test-class-name'); diff --git a/tests/Virtual.spec.tsx b/tests/Virtual.spec.tsx index db6946deb..f9170c7d5 100644 --- a/tests/Virtual.spec.tsx +++ b/tests/Virtual.spec.tsx @@ -159,17 +159,20 @@ describe('Table.Virtual', () => { describe('expandable', () => { it('basic', () => { - const { container } = getTable({ - expandable: { - expandedRowKeys: ['name0', 'name3'], - expandedRowRender: record => record.name, - }, + (['bamboo', () => 'bamboo'] as const).forEach(cls => { + const { container } = getTable({ + expandable: { + expandedRowKeys: ['name0', 'name3'], + expandedRowRender: record => record.name, + expandedRowClassName: cls, + }, + }); + const expandedCells = container.querySelectorAll('.rc-table-expanded-row-cell'); + expect(expandedCells).toHaveLength(2); + expect(expandedCells[0].textContent).toBe('name0'); + expect(expandedCells[1].textContent).toBe('name3'); + expect(container.querySelector('.rc-table-expanded-row')).toHaveClass('bamboo'); }); - - const expandedCells = container.querySelectorAll('.rc-table-expanded-row-cell'); - expect(expandedCells).toHaveLength(2); - expect(expandedCells[0].textContent).toBe('name0'); - expect(expandedCells[1].textContent).toBe('name3'); }); it('fixed', () => {