feat: columnTitle render props (#41937)

* feat: columnTitle render props

* feat: 添加测试

* docs: 修改table rowSelection interface

---------

Signed-off-by: afc163 <afc163@gmail.com>
Co-authored-by: afc163 <afc163@gmail.com>
This commit is contained in:
Zhou Bill 2023-10-24 16:05:29 +08:00 committed by GitHub
parent d04e9efe16
commit a29a0796ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 60 additions and 18 deletions

View File

@ -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(
<Table
columns={columns}
dataSource={data}
rowSelection={{
columnTitle: (originalNode) =>
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 = [

View File

@ -412,6 +412,7 @@ const useSelection = <RecordType extends AnyObject = AnyObject>(
// ===================== 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 = <RecordType extends AnyObject = AnyObject>(
const allDisabledSomeChecked =
allDisabled && allDisabledData.some(({ checked }) => checked);
columnTitleCheckbox = (
<Checkbox
checked={
!allDisabled ? !!flattedData.length && checkedCurrentAll : allDisabledAndChecked
}
indeterminate={
!allDisabled
? !checkedCurrentAll && checkedCurrentSome
: !allDisabledAndChecked && allDisabledSomeChecked
}
onChange={onSelectAllChange}
disabled={flattedData.length === 0 || allDisabled}
aria-label={customizeSelections ? 'Custom selection' : 'Select all'}
skipGroup
/>
);
title = !hideSelectAll && (
<div className={`${prefixCls}-selection`}>
<Checkbox
checked={
!allDisabled ? !!flattedData.length && checkedCurrentAll : allDisabledAndChecked
}
indeterminate={
!allDisabled
? !checkedCurrentAll && checkedCurrentSome
: !allDisabledAndChecked && allDisabledSomeChecked
}
onChange={onSelectAllChange}
disabled={flattedData.length === 0 || allDisabled}
aria-label={customizeSelections ? 'Custom selection' : 'Select all'}
skipGroup
/>
{columnTitleCheckbox}
{customizeSelections}
</div>
);
@ -699,6 +704,16 @@ const useSelection = <RecordType extends AnyObject = AnyObject>(
[`${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<RecordType>[0] & {
RC_TABLE_INTERNAL_COL_DEFINE: Record<string, any>;
@ -706,7 +721,7 @@ const useSelection = <RecordType extends AnyObject = AnyObject>(
fixed: mergedFixed,
width: selectionColWidth,
className: `${prefixCls}-selection-column`,
title: rowSelection.columnTitle || title,
title: renderColumnTitle(),
render: renderSelectionCell,
onCell: rowSelection.onCell,
[INTERNAL_COL_DEFINE]: { className: columnCls },

View File

@ -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) | - | |

View File

@ -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) | - | |

View File

@ -197,7 +197,7 @@ export interface TableRowSelection<T> {
hideSelectAll?: boolean;
fixed?: FixedType;
columnWidth?: string | number;
columnTitle?: string | React.ReactNode;
columnTitle?: React.ReactNode | ((checkboxNode: React.ReactNode) => React.ReactNode);
checkStrictly?: boolean;
renderCell?: (
value: boolean,