mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-24 11:10:01 +08:00
feat: table row check strictly (#24931)
* feat: add checkStrictly on Table.rowSelection * fix: LGTM warnings * test: table rowSelection.checkStrictly * test: add cov [wip] * refactor: tree.rowSelection.checkStrictly [wip] * test: table.rowSelection.checkStrictly basic case * feat: support rowKey on checkStrictly table * feat: Table checkStrictly support getCheckboxProps * docs: Table checkStrictly * chore: typo * chore: remove useless comment * chore: update snapshot * chore: update snapshot * fix: fire selectAll on selection dropdown menu & changeRows incorrect in selectAll callback * docs: typo * chore * chore * fix: expand buttons of leaf rows in tree data are not hidden * feat: Table warning about rowKey index parameter * perf: only generate keyEntities when not checkStrictly * refactor: remove useless parseCheckedKeys * refactor: get derived selected & half selected keys from selectedRowKeys * chore: remove env condition stmt * chore: revert index usage & code formatting * chore: rerun ci * docs: table tree-data checkstrictly * test: update snapshots * refactor: use useMergedState hook * chore: rerun ci * chore: rerun ci 2 * chore: revert selection select all behavior * refactor: refactor code based on feature * chore: revert table code format * chore: revert table code format * fix: useMemo deps * fix: useMemo deps * fix: useMemo deps
This commit is contained in:
parent
3dbb9be339
commit
50ae190b57
@ -124,6 +124,12 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
|
||||
showSorterTooltip = true,
|
||||
} = props;
|
||||
|
||||
devWarning(
|
||||
!(typeof rowKey === 'function' && rowKey.length > 1),
|
||||
'Table',
|
||||
'`index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected.',
|
||||
);
|
||||
|
||||
const screens = useBreakpoint();
|
||||
const mergedColumns = React.useMemo(() => {
|
||||
const matched = new Set(Object.keys(screens).filter((m: Breakpoint) => screens[m]));
|
||||
|
@ -43,7 +43,21 @@ describe('Table.rowSelection', () => {
|
||||
.find('BodyRow')
|
||||
.map(row => {
|
||||
const { key } = row.props().record;
|
||||
if (!row.find('input').props().checked) {
|
||||
if (!row.find('input').at(0).props().checked) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return key;
|
||||
})
|
||||
.filter(key => key !== null);
|
||||
}
|
||||
|
||||
function getIndeterminateSelection(wrapper) {
|
||||
return wrapper
|
||||
.find('BodyRow')
|
||||
.map(row => {
|
||||
const { key } = row.props().record;
|
||||
if (!row.find('Checkbox').at(0).props().indeterminate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@ -229,6 +243,19 @@ describe('Table.rowSelection', () => {
|
||||
expect(handleSelectAll).toHaveBeenCalledWith(false, [], data);
|
||||
});
|
||||
|
||||
it('works with selectAll option inside selection menu', () => {
|
||||
const handleChange = jest.fn();
|
||||
const rowSelection = {
|
||||
onChange: handleChange,
|
||||
selections: true,
|
||||
};
|
||||
const wrapper = mount(createTable({ rowSelection }));
|
||||
|
||||
const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
|
||||
dropdownWrapper.find('.ant-dropdown-menu-item').first().simulate('click');
|
||||
expect(handleChange.mock.calls[0][0]).toEqual([0, 1, 2, 3]);
|
||||
});
|
||||
|
||||
it('render with default selection correctly', () => {
|
||||
const rowSelection = {
|
||||
selections: true,
|
||||
@ -787,6 +814,246 @@ describe('Table.rowSelection', () => {
|
||||
expect(onChange.mock.calls[0][1]).toEqual([expect.objectContaining({ name: 'bamboo' })]);
|
||||
});
|
||||
|
||||
describe('supports children', () => {
|
||||
const dataWithChildren = [
|
||||
{ key: 0, name: 'Jack' },
|
||||
{ key: 1, name: 'Lucy' },
|
||||
{ key: 2, name: 'Tom' },
|
||||
{
|
||||
key: 3,
|
||||
name: 'Jerry',
|
||||
children: [
|
||||
{
|
||||
key: 4,
|
||||
name: 'Jerry Jack',
|
||||
},
|
||||
{
|
||||
key: 5,
|
||||
name: 'Jerry Lucy',
|
||||
},
|
||||
{
|
||||
key: 6,
|
||||
name: 'Jerry Tom',
|
||||
children: [
|
||||
{
|
||||
key: 7,
|
||||
name: 'Jerry Tom Jack',
|
||||
},
|
||||
{
|
||||
key: 8,
|
||||
name: 'Jerry Tom Lucy',
|
||||
},
|
||||
{
|
||||
key: 9,
|
||||
name: 'Jerry Tom Tom',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
describe('supports checkStrictly', () => {
|
||||
it('use data entity key', () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
const table = createTable({
|
||||
dataSource: dataWithChildren,
|
||||
defaultExpandAllRows: true,
|
||||
rowSelection: {
|
||||
checkStrictly: false,
|
||||
onChange,
|
||||
},
|
||||
});
|
||||
const wrapper = mount(table);
|
||||
const checkboxes = wrapper.find('input');
|
||||
|
||||
checkboxes.at(4).simulate('change', { target: { checked: true } });
|
||||
expect(getSelections(wrapper)).toEqual([3, 4, 5, 6, 7, 8, 9]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([]);
|
||||
expect(onChange.mock.calls[0][0]).toEqual([3, 4, 5, 6, 7, 8, 9]);
|
||||
checkboxes.at(7).simulate('change', { target: { checked: true } });
|
||||
expect(getSelections(wrapper)).toEqual([4, 5]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([3]);
|
||||
expect(onChange.mock.calls[1][0]).toEqual([4, 5]);
|
||||
});
|
||||
it('use function rowkey', () => {
|
||||
const onChange = jest.fn();
|
||||
const table = createTable({
|
||||
dataSource: dataWithChildren,
|
||||
defaultExpandAllRows: true,
|
||||
rowSelection: {
|
||||
checkStrictly: false,
|
||||
onChange,
|
||||
},
|
||||
rowKey: entity => entity.name,
|
||||
});
|
||||
const wrapper = mount(table);
|
||||
const checkboxes = wrapper.find('input');
|
||||
|
||||
checkboxes.at(4).simulate('change', { target: { checked: true } });
|
||||
expect(getSelections(wrapper)).toEqual([3, 4, 5, 6, 7, 8, 9]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([]);
|
||||
expect(onChange.mock.calls[0][0]).toEqual([
|
||||
'Jerry',
|
||||
'Jerry Jack',
|
||||
'Jerry Lucy',
|
||||
'Jerry Tom',
|
||||
'Jerry Tom Jack',
|
||||
'Jerry Tom Lucy',
|
||||
'Jerry Tom Tom',
|
||||
]);
|
||||
checkboxes.at(7).simulate('change', { target: { checked: true } });
|
||||
expect(getSelections(wrapper)).toEqual([4, 5]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([3]);
|
||||
expect(onChange.mock.calls[1][0]).toEqual(['Jerry Jack', 'Jerry Lucy']);
|
||||
});
|
||||
it('use string rowkey', () => {
|
||||
const onChange = jest.fn();
|
||||
const table = createTable({
|
||||
dataSource: dataWithChildren,
|
||||
defaultExpandAllRows: true,
|
||||
rowSelection: {
|
||||
checkStrictly: false,
|
||||
onChange,
|
||||
},
|
||||
rowKey: 'name',
|
||||
});
|
||||
const wrapper = mount(table);
|
||||
const checkboxes = wrapper.find('input');
|
||||
|
||||
checkboxes.at(4).simulate('change', { target: { checked: true } });
|
||||
expect(getSelections(wrapper)).toEqual([3, 4, 5, 6, 7, 8, 9]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([]);
|
||||
expect(onChange.mock.calls[0][0]).toEqual([
|
||||
'Jerry',
|
||||
'Jerry Jack',
|
||||
'Jerry Lucy',
|
||||
'Jerry Tom',
|
||||
'Jerry Tom Jack',
|
||||
'Jerry Tom Lucy',
|
||||
'Jerry Tom Tom',
|
||||
]);
|
||||
checkboxes.at(7).simulate('change', { target: { checked: true } });
|
||||
expect(getSelections(wrapper)).toEqual([4, 5]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([3]);
|
||||
expect(onChange.mock.calls[1][0]).toEqual(['Jerry Jack', 'Jerry Lucy']);
|
||||
});
|
||||
it('initialized correctly', () => {
|
||||
const table = createTable({
|
||||
dataSource: dataWithChildren,
|
||||
defaultExpandAllRows: true,
|
||||
rowSelection: {
|
||||
checkStrictly: false,
|
||||
selectedRowKeys: [7, 8, 9],
|
||||
},
|
||||
rowKey: 'key',
|
||||
});
|
||||
const wrapper = mount(table);
|
||||
expect(getSelections(wrapper)).toEqual([6, 7, 8, 9]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([3]);
|
||||
});
|
||||
it('works with disabled checkbox', () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
const table = createTable({
|
||||
dataSource: dataWithChildren,
|
||||
defaultExpandAllRows: true,
|
||||
rowSelection: {
|
||||
checkStrictly: false,
|
||||
onChange,
|
||||
getCheckboxProps(record) {
|
||||
return {
|
||||
disabled: record.name === 'Jerry Tom',
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
const wrapper = mount(table);
|
||||
const checkboxes = wrapper.find('input');
|
||||
|
||||
checkboxes.at(10).simulate('change', { target: { checked: true } });
|
||||
checkboxes.at(4).simulate('change', { target: { checked: true } });
|
||||
expect(getSelections(wrapper).sort()).toEqual([3, 4, 5, 9]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([]);
|
||||
expect(Array.from(onChange.mock.calls[1][0]).sort()).toEqual([3, 4, 5, 9]);
|
||||
checkboxes.at(4).simulate('change', { target: { checked: false } });
|
||||
expect(getSelections(wrapper)).toEqual([9]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([]);
|
||||
expect(onChange.mock.calls[2][0]).toEqual([9]);
|
||||
});
|
||||
it('works with disabled checkbox and function rowkey', () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
const table = createTable({
|
||||
dataSource: dataWithChildren,
|
||||
defaultExpandAllRows: true,
|
||||
rowSelection: {
|
||||
checkStrictly: false,
|
||||
onChange,
|
||||
getCheckboxProps(record) {
|
||||
return {
|
||||
disabled: record.name === 'Jerry Tom',
|
||||
};
|
||||
},
|
||||
},
|
||||
rowKey: entity => entity.name,
|
||||
});
|
||||
const wrapper = mount(table);
|
||||
const checkboxes = wrapper.find('input');
|
||||
|
||||
checkboxes.at(10).simulate('change', { target: { checked: true } });
|
||||
checkboxes.at(4).simulate('change', { target: { checked: true } });
|
||||
expect(getSelections(wrapper).sort()).toEqual([3, 4, 5, 9]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([]);
|
||||
expect(Array.from(onChange.mock.calls[1][0]).sort()).toEqual([
|
||||
'Jerry',
|
||||
'Jerry Jack',
|
||||
'Jerry Lucy',
|
||||
'Jerry Tom Tom',
|
||||
]);
|
||||
checkboxes.at(4).simulate('change', { target: { checked: false } });
|
||||
expect(getSelections(wrapper)).toEqual([9]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([]);
|
||||
expect(onChange.mock.calls[2][0]).toEqual(['Jerry Tom Tom']);
|
||||
});
|
||||
it('works with disabled checkbox and string rowkey', () => {
|
||||
const onChange = jest.fn();
|
||||
|
||||
const table = createTable({
|
||||
dataSource: dataWithChildren,
|
||||
defaultExpandAllRows: true,
|
||||
rowSelection: {
|
||||
checkStrictly: false,
|
||||
onChange,
|
||||
getCheckboxProps(record) {
|
||||
return {
|
||||
disabled: record.name === 'Jerry Tom',
|
||||
};
|
||||
},
|
||||
},
|
||||
rowKey: 'name',
|
||||
});
|
||||
const wrapper = mount(table);
|
||||
const checkboxes = wrapper.find('input');
|
||||
|
||||
checkboxes.at(10).simulate('change', { target: { checked: true } });
|
||||
checkboxes.at(4).simulate('change', { target: { checked: true } });
|
||||
expect(getSelections(wrapper).sort()).toEqual([3, 4, 5, 9]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([]);
|
||||
expect(Array.from(onChange.mock.calls[1][0]).sort()).toEqual([
|
||||
'Jerry',
|
||||
'Jerry Jack',
|
||||
'Jerry Lucy',
|
||||
'Jerry Tom Tom',
|
||||
]);
|
||||
checkboxes.at(4).simulate('change', { target: { checked: false } });
|
||||
expect(getSelections(wrapper)).toEqual([9]);
|
||||
expect(getIndeterminateSelection(wrapper)).toEqual([]);
|
||||
expect(onChange.mock.calls[2][0]).toEqual(['Jerry Tom Tom']);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('cache with selected keys', () => {
|
||||
it('default not cache', () => {
|
||||
const onChange = jest.fn();
|
||||
|
@ -221,4 +221,31 @@ describe('Table', () => {
|
||||
expect(td.getDOMNode().attributes.getNamedItem('title')).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
it('warn about rowKey when using index parameter', () => {
|
||||
warnSpy.mockReset();
|
||||
const columns = [
|
||||
{
|
||||
title: 'Name',
|
||||
key: 'name',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
];
|
||||
mount(<Table columns={columns} rowKey={(record, index) => record + index} />);
|
||||
expect(warnSpy).toBeCalledWith(
|
||||
'Warning: [antd: Table] `index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected.',
|
||||
);
|
||||
});
|
||||
it('not warn about rowKey', () => {
|
||||
warnSpy.mockReset();
|
||||
const columns = [
|
||||
{
|
||||
title: 'Name',
|
||||
key: 'name',
|
||||
dataIndex: 'name',
|
||||
},
|
||||
];
|
||||
mount(<Table columns={columns} rowKey={record => record.key} />);
|
||||
expect(warnSpy).not.toBeCalled();
|
||||
});
|
||||
});
|
||||
|
@ -5462,48 +5462,121 @@ exports[`renders ./components/table/demo/expand.md correctly 1`] = `
|
||||
`;
|
||||
|
||||
exports[`renders ./components/table/demo/expand-children.md correctly 1`] = `
|
||||
<div
|
||||
class="ant-table-wrapper"
|
||||
>
|
||||
Array [
|
||||
<div
|
||||
class="ant-spin-nested-loading"
|
||||
class="ant-space ant-space-horizontal ant-space-align-center"
|
||||
style="margin-bottom:16px"
|
||||
>
|
||||
<div
|
||||
class="ant-spin-container"
|
||||
class="ant-space-item"
|
||||
style="margin-right:8px"
|
||||
>
|
||||
<div
|
||||
class="ant-table"
|
||||
CheckStrictly:
|
||||
</div>
|
||||
<div
|
||||
class="ant-space-item"
|
||||
>
|
||||
<button
|
||||
aria-checked="false"
|
||||
class="ant-switch"
|
||||
role="switch"
|
||||
type="button"
|
||||
>
|
||||
<div
|
||||
class="ant-table-container"
|
||||
class="ant-switch-handle"
|
||||
/>
|
||||
<span
|
||||
class="ant-switch-inner"
|
||||
/>
|
||||
</button>
|
||||
</div>
|
||||
</div>,
|
||||
<div
|
||||
class="ant-table-wrapper"
|
||||
>
|
||||
<div
|
||||
class="ant-spin-nested-loading"
|
||||
>
|
||||
<div
|
||||
class="ant-spin-container"
|
||||
>
|
||||
<div
|
||||
class="ant-table"
|
||||
>
|
||||
<div
|
||||
class="ant-table-content"
|
||||
class="ant-table-container"
|
||||
>
|
||||
<table
|
||||
style="table-layout:auto"
|
||||
<div
|
||||
class="ant-table-content"
|
||||
>
|
||||
<colgroup>
|
||||
<col
|
||||
class="ant-table-selection-col"
|
||||
/>
|
||||
<col />
|
||||
<col
|
||||
style="width:12%;min-width:12%"
|
||||
/>
|
||||
<col
|
||||
style="width:30%;min-width:30%"
|
||||
/>
|
||||
</colgroup>
|
||||
<thead
|
||||
class="ant-table-thead"
|
||||
<table
|
||||
style="table-layout:auto"
|
||||
>
|
||||
<tr>
|
||||
<th
|
||||
class="ant-table-cell ant-table-selection-column"
|
||||
<colgroup>
|
||||
<col
|
||||
class="ant-table-selection-col"
|
||||
/>
|
||||
<col />
|
||||
<col
|
||||
style="width:12%;min-width:12%"
|
||||
/>
|
||||
<col
|
||||
style="width:30%;min-width:30%"
|
||||
/>
|
||||
</colgroup>
|
||||
<thead
|
||||
class="ant-table-thead"
|
||||
>
|
||||
<tr>
|
||||
<th
|
||||
class="ant-table-cell ant-table-selection-column"
|
||||
>
|
||||
<div
|
||||
class="ant-table-selection"
|
||||
>
|
||||
<label
|
||||
class="ant-checkbox-wrapper"
|
||||
>
|
||||
<span
|
||||
class="ant-checkbox"
|
||||
>
|
||||
<input
|
||||
class="ant-checkbox-input"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
class="ant-checkbox-inner"
|
||||
/>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</th>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Name
|
||||
</th>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Age
|
||||
</th>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Address
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody
|
||||
class="ant-table-tbody"
|
||||
>
|
||||
<tr
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="1"
|
||||
>
|
||||
<div
|
||||
class="ant-table-selection"
|
||||
<td
|
||||
class="ant-table-cell ant-table-selection-column"
|
||||
>
|
||||
<label
|
||||
class="ant-checkbox-wrapper"
|
||||
@ -5520,212 +5593,169 @@ exports[`renders ./components/table/demo/expand-children.md correctly 1`] = `
|
||||
/>
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</th>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Name
|
||||
</th>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Age
|
||||
</th>
|
||||
<th
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Address
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody
|
||||
class="ant-table-tbody"
|
||||
>
|
||||
<tr
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="1"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell ant-table-selection-column"
|
||||
>
|
||||
<label
|
||||
class="ant-checkbox-wrapper"
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell ant-table-cell-with-append"
|
||||
>
|
||||
<span
|
||||
class="ant-checkbox"
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
/>
|
||||
John Brown sr.
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
60
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
New York No. 1 Lake Park
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="2"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell ant-table-selection-column"
|
||||
>
|
||||
<label
|
||||
class="ant-checkbox-wrapper"
|
||||
>
|
||||
<input
|
||||
class="ant-checkbox-input"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
class="ant-checkbox-inner"
|
||||
/>
|
||||
</span>
|
||||
</label>
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell ant-table-cell-with-append"
|
||||
>
|
||||
<span
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-collapsed"
|
||||
type="button"
|
||||
/>
|
||||
John Brown sr.
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
60
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
New York No. 1 Lake Park
|
||||
</td>
|
||||
</tr>
|
||||
<tr
|
||||
class="ant-table-row ant-table-row-level-0"
|
||||
data-row-key="2"
|
||||
>
|
||||
<td
|
||||
class="ant-table-cell ant-table-selection-column"
|
||||
>
|
||||
<label
|
||||
class="ant-checkbox-wrapper"
|
||||
class="ant-checkbox"
|
||||
>
|
||||
<input
|
||||
class="ant-checkbox-input"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
class="ant-checkbox-inner"
|
||||
/>
|
||||
</span>
|
||||
</label>
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell ant-table-cell-with-append"
|
||||
>
|
||||
<span
|
||||
class="ant-checkbox"
|
||||
>
|
||||
<input
|
||||
class="ant-checkbox-input"
|
||||
type="checkbox"
|
||||
/>
|
||||
<span
|
||||
class="ant-checkbox-inner"
|
||||
/>
|
||||
</span>
|
||||
</label>
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell ant-table-cell-with-append"
|
||||
>
|
||||
<span
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
/>
|
||||
Joe Black
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Sidney No. 1 Lake Park
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
class="ant-table-row-indent indent-level-0"
|
||||
style="padding-left:0px"
|
||||
/>
|
||||
<button
|
||||
aria-label="Expand row"
|
||||
class="ant-table-row-expand-icon ant-table-row-expand-icon-spaced"
|
||||
type="button"
|
||||
/>
|
||||
Joe Black
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
32
|
||||
</td>
|
||||
<td
|
||||
class="ant-table-cell"
|
||||
>
|
||||
Sidney No. 1 Lake Park
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<ul
|
||||
class="ant-pagination ant-table-pagination ant-table-pagination-right"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-pagination-prev ant-pagination-disabled"
|
||||
title="Previous Page"
|
||||
>
|
||||
<button
|
||||
class="ant-pagination-item-link"
|
||||
disabled=""
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="left"
|
||||
class="anticon anticon-left"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="left"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-1 ant-pagination-item-active"
|
||||
tabindex="0"
|
||||
title="1"
|
||||
>
|
||||
<a>
|
||||
1
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-pagination-next ant-pagination-disabled"
|
||||
title="Next Page"
|
||||
>
|
||||
<button
|
||||
class="ant-pagination-item-link"
|
||||
disabled=""
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="right"
|
||||
class="anticon anticon-right"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="right"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul
|
||||
class="ant-pagination ant-table-pagination ant-table-pagination-right"
|
||||
unselectable="unselectable"
|
||||
>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-pagination-prev ant-pagination-disabled"
|
||||
title="Previous Page"
|
||||
>
|
||||
<button
|
||||
class="ant-pagination-item-link"
|
||||
disabled=""
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="left"
|
||||
class="anticon anticon-left"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="left"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
class="ant-pagination-item ant-pagination-item-1 ant-pagination-item-active"
|
||||
tabindex="0"
|
||||
title="1"
|
||||
>
|
||||
<a>
|
||||
1
|
||||
</a>
|
||||
</li>
|
||||
<li
|
||||
aria-disabled="true"
|
||||
class="ant-pagination-next ant-pagination-disabled"
|
||||
title="Next Page"
|
||||
>
|
||||
<button
|
||||
class="ant-pagination-item-link"
|
||||
disabled=""
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
<span
|
||||
aria-label="right"
|
||||
class="anticon anticon-right"
|
||||
role="img"
|
||||
>
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
class=""
|
||||
data-icon="right"
|
||||
fill="currentColor"
|
||||
focusable="false"
|
||||
height="1em"
|
||||
viewBox="64 64 896 896"
|
||||
width="1em"
|
||||
>
|
||||
<path
|
||||
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
|
||||
/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>,
|
||||
]
|
||||
`;
|
||||
|
||||
exports[`renders ./components/table/demo/fixed-columns.md correctly 1`] = `
|
||||
|
@ -11,18 +11,14 @@ title:
|
||||
|
||||
可以通过设置 `indentSize` 以控制每一层的缩进宽度。
|
||||
|
||||
> 注:暂不支持父子数据递归关联选择。
|
||||
|
||||
## en-US
|
||||
|
||||
Display tree structure data in Table when there is field key `children` in dataSource, try to customize `childrenColumnName` property to avoid tree table structure.
|
||||
|
||||
You can control the indent width by setting `indentSize`.
|
||||
|
||||
> Note, no support for recursive selection of tree structure data table yet.
|
||||
|
||||
```jsx
|
||||
import { Table } from 'antd';
|
||||
import { Table, Switch, Space } from 'antd';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
@ -122,8 +118,21 @@ const rowSelection = {
|
||||
},
|
||||
};
|
||||
|
||||
ReactDOM.render(
|
||||
<Table columns={columns} rowSelection={rowSelection} dataSource={data} />,
|
||||
mountNode,
|
||||
);
|
||||
function TreeData() {
|
||||
const [checkStrictly, setCheckStrictly] = React.useState(false);
|
||||
return (
|
||||
<>
|
||||
<Space align="center" style={{ marginBottom: 16 }}>
|
||||
CheckStrictly: <Switch checked={checkStrictly} onChange={setCheckStrictly} />
|
||||
</Space>
|
||||
<Table
|
||||
columns={columns}
|
||||
rowSelection={{ ...rowSelection, checkStrictly }}
|
||||
dataSource={data}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
ReactDOM.render(<TreeData />, mountNode);
|
||||
```
|
||||
|
@ -1,8 +1,13 @@
|
||||
import * as React from 'react';
|
||||
import { useState, useCallback, useMemo } from 'react';
|
||||
import DownOutlined from '@ant-design/icons/DownOutlined';
|
||||
import { convertDataToEntities } from 'rc-tree/lib/utils/treeUtil';
|
||||
import { conductCheck } from 'rc-tree/lib/utils/conductUtil';
|
||||
import { arrAdd, arrDel } from 'rc-tree/lib/util';
|
||||
import { DataNode, GetCheckDisabled } from 'rc-tree/lib/interface';
|
||||
import { INTERNAL_COL_DEFINE } from 'rc-table';
|
||||
import { FixedType } from 'rc-table/lib/interface';
|
||||
import useMergedState from 'rc-util/lib/hooks/useMergedState';
|
||||
import Checkbox, { CheckboxProps } from '../../checkbox';
|
||||
import Dropdown from '../../dropdown';
|
||||
import Menu from '../../menu';
|
||||
@ -20,8 +25,6 @@ import {
|
||||
GetPopupContainer,
|
||||
} from '../interface';
|
||||
|
||||
const EMPTY_LIST: any[] = [];
|
||||
|
||||
// TODO: warning if use ajax!!!
|
||||
export const SELECTION_ALL = 'SELECT_ALL' as const;
|
||||
export const SELECTION_INVERT = 'SELECT_INVERT' as const;
|
||||
@ -86,6 +89,7 @@ export default function useSelection<RecordType>(
|
||||
fixed,
|
||||
renderCell: customizeRenderCell,
|
||||
hideSelectAll,
|
||||
checkStrictly = true,
|
||||
} = rowSelection || {};
|
||||
|
||||
const {
|
||||
@ -105,12 +109,73 @@ export default function useSelection<RecordType>(
|
||||
const preserveRecordsRef = React.useRef(new Map<Key, RecordType>());
|
||||
|
||||
// ========================= Keys =========================
|
||||
const [innerSelectedKeys, setInnerSelectedKeys] = useState<Key[]>();
|
||||
const mergedSelectedKeys = selectedRowKeys || innerSelectedKeys || EMPTY_LIST;
|
||||
const mergedSelectedKeySet = useMemo(() => {
|
||||
const keys = selectionType === 'radio' ? mergedSelectedKeys.slice(0, 1) : mergedSelectedKeys;
|
||||
const [mergedSelectedKeys, setMergedSelectedKeys] = useMergedState(selectedRowKeys || [], {
|
||||
value: selectedRowKeys,
|
||||
});
|
||||
|
||||
const { keyEntities } = useMemo(
|
||||
() =>
|
||||
checkStrictly
|
||||
? { keyEntities: null }
|
||||
: convertDataToEntities((data as unknown) as DataNode[], undefined, getRowKey as any),
|
||||
[data, getRowKey, checkStrictly],
|
||||
);
|
||||
|
||||
// Get flatten data
|
||||
const flattedData = useMemo(() => flattenData(pageData, childrenColumnName), [
|
||||
pageData,
|
||||
childrenColumnName,
|
||||
]);
|
||||
|
||||
// Get all checkbox props
|
||||
const checkboxPropsMap = useMemo(() => {
|
||||
const map = new Map<Key, Partial<CheckboxProps>>();
|
||||
flattedData.forEach((record, index) => {
|
||||
const key = getRowKey(record, index);
|
||||
const checkboxProps = (getCheckboxProps ? getCheckboxProps(record) : null) || {};
|
||||
map.set(key, checkboxProps);
|
||||
|
||||
if (
|
||||
process.env.NODE_ENV !== 'production' &&
|
||||
('checked' in checkboxProps || 'defaultChecked' in checkboxProps)
|
||||
) {
|
||||
devWarning(
|
||||
false,
|
||||
'Table',
|
||||
'Do not set `checked` or `defaultChecked` in `getCheckboxProps`. Please use `selectedRowKeys` instead.',
|
||||
);
|
||||
}
|
||||
});
|
||||
return map;
|
||||
}, [flattedData, getRowKey, getCheckboxProps]);
|
||||
|
||||
const isCheckboxDisabled: GetCheckDisabled<RecordType> = useCallback(
|
||||
(r: RecordType) => {
|
||||
return !!checkboxPropsMap.get(getRowKey(r))?.disabled;
|
||||
},
|
||||
[checkboxPropsMap, getRowKey],
|
||||
);
|
||||
|
||||
const [derivedSelectedKeys, derivedHalfSelectedKeys] = useMemo(() => {
|
||||
if (checkStrictly) {
|
||||
return [mergedSelectedKeys, []];
|
||||
}
|
||||
const { checkedKeys, halfCheckedKeys } = conductCheck(
|
||||
mergedSelectedKeys,
|
||||
true,
|
||||
keyEntities as any,
|
||||
isCheckboxDisabled as any,
|
||||
);
|
||||
return [checkedKeys, halfCheckedKeys];
|
||||
}, [mergedSelectedKeys, checkStrictly, keyEntities, isCheckboxDisabled]);
|
||||
|
||||
const derivedSelectedKeySet: Set<Key> = useMemo(() => {
|
||||
const keys = selectionType === 'radio' ? derivedSelectedKeys.slice(0, 1) : derivedSelectedKeys;
|
||||
return new Set(keys);
|
||||
}, [mergedSelectedKeys, selectionType]);
|
||||
}, [derivedSelectedKeys, selectionType]);
|
||||
const derivedHalfSelectedKeySet = useMemo(() => {
|
||||
return selectionType === 'radio' ? new Set() : new Set(derivedHalfSelectedKeys);
|
||||
}, [derivedHalfSelectedKeys, selectionType]);
|
||||
|
||||
// Save last selected key to enable range selection
|
||||
const [lastSelectedKey, setLastSelectedKey] = useState<Key | null>(null);
|
||||
@ -118,7 +183,7 @@ export default function useSelection<RecordType>(
|
||||
// Reset if rowSelection reset
|
||||
React.useEffect(() => {
|
||||
if (!rowSelection) {
|
||||
setInnerSelectedKeys([]);
|
||||
setMergedSelectedKeys([]);
|
||||
}
|
||||
}, [!!rowSelection]);
|
||||
|
||||
@ -159,13 +224,13 @@ export default function useSelection<RecordType>(
|
||||
});
|
||||
}
|
||||
|
||||
setInnerSelectedKeys(availableKeys);
|
||||
setMergedSelectedKeys(availableKeys);
|
||||
|
||||
if (onSelectionChange) {
|
||||
onSelectionChange(availableKeys, records);
|
||||
}
|
||||
},
|
||||
[setInnerSelectedKeys, getRecordByKey, onSelectionChange, preserveSelectedRowKeys],
|
||||
[setMergedSelectedKeys, getRecordByKey, onSelectionChange, preserveSelectedRowKeys],
|
||||
);
|
||||
|
||||
// ====================== Selections ======================
|
||||
@ -205,7 +270,7 @@ export default function useSelection<RecordType>(
|
||||
key: 'invert',
|
||||
text: tableLocale.selectInvert,
|
||||
onSelect() {
|
||||
const keySet = new Set(mergedSelectedKeySet);
|
||||
const keySet = new Set(derivedSelectedKeySet);
|
||||
pageData.forEach((record, index) => {
|
||||
const key = getRowKey(record, index);
|
||||
|
||||
@ -231,7 +296,7 @@ export default function useSelection<RecordType>(
|
||||
}
|
||||
return selection as SelectionItem;
|
||||
});
|
||||
}, [selections, mergedSelectedKeySet, pageData, getRowKey]);
|
||||
}, [selections, derivedSelectedKeySet, pageData, getRowKey, onSelectInvert, setSelectedKeys]);
|
||||
|
||||
// ======================= Columns ========================
|
||||
const transformColumns = useCallback(
|
||||
@ -240,30 +305,8 @@ export default function useSelection<RecordType>(
|
||||
return columns;
|
||||
}
|
||||
|
||||
// Get flatten data
|
||||
const flattedData = flattenData(pageData, childrenColumnName);
|
||||
|
||||
// Support selection
|
||||
const keySet = new Set(mergedSelectedKeySet);
|
||||
|
||||
// Get all checkbox props
|
||||
const checkboxPropsMap = new Map<Key, Partial<CheckboxProps>>();
|
||||
flattedData.forEach((record, index) => {
|
||||
const key = getRowKey(record, index);
|
||||
const checkboxProps = (getCheckboxProps ? getCheckboxProps(record) : null) || {};
|
||||
checkboxPropsMap.set(key, checkboxProps);
|
||||
|
||||
if (
|
||||
process.env.NODE_ENV !== 'production' &&
|
||||
('checked' in checkboxProps || 'defaultChecked' in checkboxProps)
|
||||
) {
|
||||
devWarning(
|
||||
false,
|
||||
'Table',
|
||||
'Do not set `checked` or `defaultChecked` in `getCheckboxProps`. Please use `selectedRowKeys` instead.',
|
||||
);
|
||||
}
|
||||
});
|
||||
const keySet = new Set(derivedSelectedKeySet);
|
||||
|
||||
// Record key only need check with enabled
|
||||
const recordKeys = flattedData
|
||||
@ -282,8 +325,10 @@ export default function useSelection<RecordType>(
|
||||
});
|
||||
} else {
|
||||
recordKeys.forEach(key => {
|
||||
keySet.add(key);
|
||||
changeKeys.push(key);
|
||||
if (!keySet.has(key)) {
|
||||
keySet.add(key);
|
||||
changeKeys.push(key);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -385,6 +430,7 @@ export default function useSelection<RecordType>(
|
||||
renderCell = (_, record, index) => {
|
||||
const key = getRowKey(record, index);
|
||||
const checked = keySet.has(key);
|
||||
const indeterminate = derivedHalfSelectedKeySet.has(key);
|
||||
|
||||
// Record checked
|
||||
return {
|
||||
@ -392,6 +438,7 @@ export default function useSelection<RecordType>(
|
||||
<Checkbox
|
||||
{...checkboxPropsMap.get(key)}
|
||||
checked={checked}
|
||||
indeterminate={indeterminate}
|
||||
onClick={e => e.stopPropagation()}
|
||||
onChange={({ nativeEvent }) => {
|
||||
const { shiftKey } = nativeEvent;
|
||||
@ -400,7 +447,7 @@ export default function useSelection<RecordType>(
|
||||
let endIndex: number = -1;
|
||||
|
||||
// Get range of this
|
||||
if (shiftKey) {
|
||||
if (shiftKey && checkStrictly) {
|
||||
const pointKeys = new Set([lastSelectedKey, key]);
|
||||
|
||||
recordKeys.some((recordKey, recordIndex) => {
|
||||
@ -417,7 +464,7 @@ export default function useSelection<RecordType>(
|
||||
});
|
||||
}
|
||||
|
||||
if (endIndex !== -1 && startIndex !== endIndex) {
|
||||
if (endIndex !== -1 && startIndex !== endIndex && checkStrictly) {
|
||||
// Batch update selections
|
||||
const rangeKeys = recordKeys.slice(startIndex, endIndex + 1);
|
||||
const changedKeys: Key[] = [];
|
||||
@ -449,13 +496,37 @@ export default function useSelection<RecordType>(
|
||||
}
|
||||
} else {
|
||||
// Single record selected
|
||||
if (checked) {
|
||||
keySet.delete(key);
|
||||
const originCheckedKeys = derivedSelectedKeys;
|
||||
if (checkStrictly) {
|
||||
const checkedKeys = checked
|
||||
? arrDel(originCheckedKeys, key)
|
||||
: arrAdd(originCheckedKeys, key);
|
||||
triggerSingleSelection(key, !checked, checkedKeys, nativeEvent);
|
||||
} else {
|
||||
keySet.add(key);
|
||||
}
|
||||
// Always fill first
|
||||
const result = conductCheck(
|
||||
[...originCheckedKeys, key],
|
||||
true,
|
||||
keyEntities as any,
|
||||
isCheckboxDisabled as any,
|
||||
);
|
||||
const { checkedKeys, halfCheckedKeys } = result;
|
||||
let nextCheckedKeys = checkedKeys;
|
||||
|
||||
triggerSingleSelection(key, !checked, Array.from(keySet), nativeEvent);
|
||||
// If remove, we do it again to correction
|
||||
if (checked) {
|
||||
const tempKeySet = new Set(checkedKeys);
|
||||
tempKeySet.delete(key);
|
||||
nextCheckedKeys = conductCheck(
|
||||
Array.from(tempKeySet),
|
||||
{ checked: false, halfCheckedKeys },
|
||||
keyEntities as any,
|
||||
isCheckboxDisabled as any,
|
||||
).checkedKeys;
|
||||
}
|
||||
|
||||
triggerSingleSelection(key, !checked, nextCheckedKeys, nativeEvent);
|
||||
}
|
||||
}
|
||||
|
||||
setLastSelectedKey(key);
|
||||
@ -500,18 +571,21 @@ export default function useSelection<RecordType>(
|
||||
},
|
||||
[
|
||||
getRowKey,
|
||||
pageData,
|
||||
flattedData,
|
||||
rowSelection,
|
||||
innerSelectedKeys,
|
||||
mergedSelectedKeys,
|
||||
derivedSelectedKeys,
|
||||
derivedSelectedKeySet,
|
||||
derivedHalfSelectedKeySet,
|
||||
selectionColWidth,
|
||||
mergedSelections,
|
||||
expandType,
|
||||
lastSelectedKey,
|
||||
checkboxPropsMap,
|
||||
onSelectMultiple,
|
||||
triggerSingleSelection,
|
||||
isCheckboxDisabled,
|
||||
],
|
||||
);
|
||||
|
||||
return [transformColumns, mergedSelectedKeySet];
|
||||
return [transformColumns, derivedSelectedKeySet];
|
||||
}
|
||||
|
@ -185,11 +185,12 @@ Properties for row selection.
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| columnWidth | Set the width of the selection column | string\|number | `60px` | 4.0 |
|
||||
| columnTitle | Set the title of the selection column | string\|React.ReactNode | - | 4.0 |
|
||||
| fixed | Fixed selection column on the left | boolean | - | 4.0 |
|
||||
| getCheckboxProps | Get Checkbox or Radio props | Function(record) | - | 4.0 |
|
||||
| hideSelectAll | Hide the selectAll checkbox and custom selection | boolean | false | 4.3 |
|
||||
| checkStrictly | Check table row precisely; parent row and children rows are not associated | boolean | true | 4.4.0 |
|
||||
| columnWidth | Set the width of the selection column | string\|number | `60px` | |
|
||||
| columnTitle | Set the title of the selection column | string\|ReactNode | - | |
|
||||
| fixed | Fixed selection column on the left | boolean | - | |
|
||||
| getCheckboxProps | Get Checkbox or Radio props | Function(record) | - | |
|
||||
| hideSelectAll | Hide the selectAll checkbox and custom selection | boolean | `false` | 4.3 |
|
||||
| preserveSelectedRowKeys | Keep selection `key` even when it removed from `dataSource` | boolean | - | 4.4 |
|
||||
| renderCell | Renderer of the table cell. Same as `render` in column | Function(checked, record, index, originNode) {} | - | 4.1 |
|
||||
| selectedRowKeys | Controlled selected row keys | string\[]\|number[] | \[] | |
|
||||
|
@ -190,6 +190,7 @@ const columns = [
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| checkStrictly | checkable 状态下节点选择完全受控(父子数据选中状态不再关联) | boolean | true | 4.4.0 |
|
||||
| columnWidth | 自定义列表选择框宽度 | string\|number | `60px` | |
|
||||
| columnTitle | 自定义列表选择框标题 | string\|ReactNode | - | |
|
||||
| fixed | 把选择框列固定在左边 | boolean | - | |
|
||||
|
@ -148,6 +148,7 @@ export interface TableRowSelection<T> {
|
||||
fixed?: boolean;
|
||||
columnWidth?: string | number;
|
||||
columnTitle?: string | React.ReactNode;
|
||||
checkStrictly?: boolean;
|
||||
renderCell?: (
|
||||
value: boolean,
|
||||
record: T,
|
||||
|
@ -471,6 +471,7 @@
|
||||
}
|
||||
background: transparent;
|
||||
border: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.@{table-prefix-cls}-row-indent + & {
|
||||
|
@ -139,7 +139,7 @@
|
||||
"rc-tabs": "~11.4.1",
|
||||
"rc-textarea": "~0.2.2",
|
||||
"rc-tooltip": "~4.2.0",
|
||||
"rc-tree": "~3.3.0",
|
||||
"rc-tree": "~3.5.0",
|
||||
"rc-tree-select": "~4.0.0",
|
||||
"rc-trigger": "~4.3.0",
|
||||
"rc-upload": "~3.2.0",
|
||||
|
Loading…
Reference in New Issue
Block a user