chore(table): optimize select all checkbox display logic (#30811)

This commit is contained in:
Kermit 2021-06-02 12:15:00 +08:00 committed by GitHub
parent 023a1e0f88
commit f6b09a79b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 96 additions and 12 deletions

View File

@ -865,6 +865,74 @@ describe('Table.rowSelection', () => {
expect(wrapper.find('thead .ant-checkbox-input').props().checked).toBeFalsy();
});
it('should make select all checked when each item is checked and disabled', () => {
const wrapper = mount(
createTable({
rowSelection: {
selectedRowKeys: [0, 1, 2, 3],
getCheckboxProps: () => ({
disabled: true,
}),
},
}),
);
expect(wrapper.find('thead .ant-checkbox-input').props().disabled).toBeTruthy();
expect(wrapper.find('thead .ant-checkbox-input').props().checked).toBeTruthy();
});
it('should make select all indeterminated when each item is disabled and some item is checked', () => {
const wrapper = mount(
createTable({
rowSelection: {
selectedRowKeys: [0],
getCheckboxProps: () => ({
disabled: true,
}),
},
}),
);
expect(wrapper.find('thead .ant-checkbox-input').props().disabled).toBeTruthy();
expect(wrapper.find('thead .ant-checkbox-input').props().checked).toBeFalsy();
expect(
wrapper.find('thead .ant-checkbox-indeterminate.ant-checkbox-disabled').exists(),
).toBeTruthy();
});
it('should make select all checked when each item is checked and some item is disabled', () => {
const wrapper = mount(
createTable({
rowSelection: {
selectedRowKeys: [0, 1, 2, 3],
getCheckboxProps: record => ({
disabled: record.key === 0,
}),
},
}),
);
expect(wrapper.find('thead .ant-checkbox-input').props().disabled).toBeFalsy();
expect(wrapper.find('thead .ant-checkbox-input').props().checked).toBeTruthy();
});
it('should not make select all checked when some item is checked and disabled', () => {
const wrapper = mount(
createTable({
rowSelection: {
selectedRowKeys: [1],
getCheckboxProps: record => ({
disabled: record.key === 0,
}),
},
}),
);
expect(wrapper.find('thead .ant-checkbox-input').props().disabled).toBeFalsy();
expect(wrapper.find('thead .ant-checkbox-input').props().checked).toBeFalsy();
expect(wrapper.find('thead .ant-checkbox-indeterminate').exists()).toBeTruthy();
});
it('should onRowClick not called when checkbox clicked', () => {
const onRowClick = jest.fn();

View File

@ -124,7 +124,7 @@ export default function useSelection<RecordType>(
() =>
checkStrictly
? { keyEntities: null }
: convertDataToEntities((data as unknown) as DataNode[], {
: convertDataToEntities(data as unknown as DataNode[], {
externalGetKey: getRowKey as any,
childrenPropName: childrenColumnName,
}),
@ -132,10 +132,10 @@ export default function useSelection<RecordType>(
);
// Get flatten data
const flattedData = useMemo(() => flattenData(pageData, childrenColumnName), [
pageData,
childrenColumnName,
]);
const flattedData = useMemo(
() => flattenData(pageData, childrenColumnName),
[pageData, childrenColumnName],
);
// Get all checkbox props
const checkboxPropsMap = useMemo(() => {
@ -395,17 +395,33 @@ export default function useSelection<RecordType>(
);
}
const allDisabled = flattedData.every((record, index) => {
const key = getRowKey(record, index);
const checkboxProps = checkboxPropsMap.get(key) || {};
return checkboxProps.disabled;
});
const allDisabledData = flattedData
.map((record, index) => {
const key = getRowKey(record, index);
const checkboxProps = checkboxPropsMap.get(key) || {};
return { checked: keySet.has(key), ...checkboxProps };
})
.filter(({ disabled }) => disabled);
const allDisabled =
!!allDisabledData.length && allDisabledData.length === flattedData.length;
const allDisabledAndChecked =
allDisabled && allDisabledData.every(({ checked }) => checked);
const allDisabledSomeChecked =
allDisabled && allDisabledData.some(({ checked }) => checked);
title = !hideSelectAll && (
<div className={`${prefixCls}-selection`}>
<Checkbox
checked={!allDisabled && !!flattedData.length && checkedCurrentAll}
indeterminate={!checkedCurrentAll && checkedCurrentSome}
checked={
!allDisabled ? !!flattedData.length && checkedCurrentAll : allDisabledAndChecked
}
indeterminate={
!allDisabled
? !checkedCurrentAll && checkedCurrentSome
: !allDisabledAndChecked && allDisabledSomeChecked
}
onChange={onSelectAllChange}
disabled={flattedData.length === 0 || allDisabled}
skipGroup