From a29a0796ae29c76941ed8fc460531826d1dafed6 Mon Sep 17 00:00:00 2001 From: Zhou Bill <735051883@qq.com> Date: Tue, 24 Oct 2023 16:05:29 +0800 Subject: [PATCH] feat: columnTitle render props (#41937) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: columnTitle render props * feat: 添加测试 * docs: 修改table rowSelection interface --------- Signed-off-by: afc163 Co-authored-by: afc163 --- .../__tests__/Table.rowSelection.test.tsx | 27 +++++++++++ components/table/hooks/useSelection.tsx | 45 ++++++++++++------- components/table/index.en-US.md | 2 +- components/table/index.zh-CN.md | 2 +- components/table/interface.ts | 2 +- 5 files changed, 60 insertions(+), 18 deletions(-) diff --git a/components/table/__tests__/Table.rowSelection.test.tsx b/components/table/__tests__/Table.rowSelection.test.tsx index 19abf4e2a537..e3f2f04cb453 100644 --- a/components/table/__tests__/Table.rowSelection.test.tsx +++ b/components/table/__tests__/Table.rowSelection.test.tsx @@ -860,6 +860,33 @@ describe('Table.rowSelection', () => { expect(container.querySelector('thead tr th')?.textContent).toBe('单选'); }); + it('columnTitle for rowSelection to be renderProps', () => { + const { container } = render( + + React.cloneElement(originalNode as any, { + 'data-testid': 'selection-checkbox', + children: '多选', + }), + }} + />, + ); + + expect(container.querySelector('thead tr th')?.textContent).toBe('多选'); + expect(container.querySelector('thead tr th input')?.getAttribute('data-testid')).toBe( + 'selection-checkbox', + ); + + fireEvent.click(container.querySelector('thead tr th input')!); + container.querySelectorAll('.ant-checkbox').forEach((checkbox) => { + expect(checkbox.querySelector('input')?.checked).toBe(true); + expect(checkbox.className.includes('ant-checkbox-indeterminate')).toBe(false); + }); + }); + // https://github.com/ant-design/ant-design/issues/11384 it('should keep item even if in filter', () => { const filterColumns = [ diff --git a/components/table/hooks/useSelection.tsx b/components/table/hooks/useSelection.tsx index bc7630b61cb5..1fae14c8f2d8 100644 --- a/components/table/hooks/useSelection.tsx +++ b/components/table/hooks/useSelection.tsx @@ -412,6 +412,7 @@ const useSelection = ( // ===================== Render ===================== // Title Cell let title: React.ReactNode; + let columnTitleCheckbox: React.ReactNode; if (selectionType !== 'radio') { let customizeSelections: React.ReactNode; if (mergedSelections) { @@ -456,22 +457,26 @@ const useSelection = ( const allDisabledSomeChecked = allDisabled && allDisabledData.some(({ checked }) => checked); + columnTitleCheckbox = ( + + ); + title = !hideSelectAll && (
- + {columnTitleCheckbox} {customizeSelections}
); @@ -699,6 +704,16 @@ const useSelection = ( [`${prefixCls}-selection-col-with-dropdown`]: selections && selectionType === 'checkbox', }); + const renderColumnTitle = () => { + if (!rowSelection?.columnTitle) { + return title; + } + if (typeof rowSelection.columnTitle === 'function') { + return rowSelection.columnTitle(columnTitleCheckbox); + } + return rowSelection.columnTitle; + }; + // Replace with real selection column const selectionColumn: ColumnsType[0] & { RC_TABLE_INTERNAL_COL_DEFINE: Record; @@ -706,7 +721,7 @@ const useSelection = ( fixed: mergedFixed, width: selectionColWidth, className: `${prefixCls}-selection-column`, - title: rowSelection.columnTitle || title, + title: renderColumnTitle(), render: renderSelectionCell, onCell: rowSelection.onCell, [INTERNAL_COL_DEFINE]: { className: columnCls }, diff --git a/components/table/index.en-US.md b/components/table/index.en-US.md index ae6eab6e68ad..7d8533fdcd42 100644 --- a/components/table/index.en-US.md +++ b/components/table/index.en-US.md @@ -259,7 +259,7 @@ Properties for row selection. | Property | Description | Type | Default | Version | | --- | --- | --- | --- | --- | | checkStrictly | Check table row precisely; parent row and children rows are not associated | boolean | true | 4.4.0 | -| columnTitle | Set the title of the selection column | ReactNode | - | | +| columnTitle | Set the title of the selection column | ReactNode \| (originalNode: ReactNode) => ReactNode | - | | | columnWidth | Set the width of the selection column | string \| number | `32px` | | | fixed | Fixed selection column on the left | boolean | - | | | getCheckboxProps | Get Checkbox or Radio props | function(record) | - | | diff --git a/components/table/index.zh-CN.md b/components/table/index.zh-CN.md index 77a1070568b1..917b8055d138 100644 --- a/components/table/index.zh-CN.md +++ b/components/table/index.zh-CN.md @@ -260,7 +260,7 @@ const columns = [ | 参数 | 说明 | 类型 | 默认值 | 版本 | | --- | --- | --- | --- | --- | | checkStrictly | checkable 状态下节点选择完全受控(父子数据选中状态不再关联) | boolean | true | 4.4.0 | -| columnTitle | 自定义列表选择框标题 | ReactNode | - | | +| columnTitle | 自定义列表选择框标题 | ReactNode \| (originalNode: ReactNode) => ReactNode | - | | | columnWidth | 自定义列表选择框宽度 | string \| number | `32px` | | | fixed | 把选择框列固定在左边 | boolean | - | | | getCheckboxProps | 选择框的默认属性配置 | function(record) | - | | diff --git a/components/table/interface.ts b/components/table/interface.ts index 9448b7cd775b..cece5808392a 100644 --- a/components/table/interface.ts +++ b/components/table/interface.ts @@ -197,7 +197,7 @@ export interface TableRowSelection { hideSelectAll?: boolean; fixed?: FixedType; columnWidth?: string | number; - columnTitle?: string | React.ReactNode; + columnTitle?: React.ReactNode | ((checkboxNode: React.ReactNode) => React.ReactNode); checkStrictly?: boolean; renderCell?: ( value: boolean,