diff --git a/examples/multiple.tsx b/examples/multiple.tsx index dc52dc95..428b80e7 100644 --- a/examples/multiple.tsx +++ b/examples/multiple.tsx @@ -9,11 +9,13 @@ const optionLists = [ value: 'zhejiang', label: 'Zhejiang', isLeaf: false, + disableCheckbox: true, }, { value: 'jiangsu', label: 'Jiangsu', isLeaf: false, + disableCheckbox: false }, ]; @@ -35,10 +37,12 @@ const Demo = () => { { label: `${targetOption.label} Dynamic 1`, value: 'dynamic1', + disableCheckbox: false, }, { label: `${targetOption.label} Dynamic 2`, value: 'dynamic2', + disableCheckbox: true, }, ]; setOptions([...options]); diff --git a/src/Cascader.tsx b/src/Cascader.tsx index 0cb8cbd7..284b1f96 100644 --- a/src/Cascader.tsx +++ b/src/Cascader.tsx @@ -54,6 +54,7 @@ export interface DefaultOptionType extends BaseOptionType { label: React.ReactNode; value?: string | number | null; children?: DefaultOptionType[]; + disableCheckbox?: boolean; } interface BaseCascaderProps diff --git a/src/OptionList/Checkbox.tsx b/src/OptionList/Checkbox.tsx index 430f9c75..f01a639b 100644 --- a/src/OptionList/Checkbox.tsx +++ b/src/OptionList/Checkbox.tsx @@ -8,6 +8,7 @@ export interface CheckboxProps { halfChecked?: boolean; disabled?: boolean; onClick?: React.MouseEventHandler; + disableCheckbox: boolean; } export default function Checkbox({ @@ -16,6 +17,7 @@ export default function Checkbox({ halfChecked, disabled, onClick, + disableCheckbox, }: CheckboxProps) { const { checkable } = React.useContext(CascaderContext); @@ -26,7 +28,7 @@ export default function Checkbox({ className={classNames(`${prefixCls}`, { [`${prefixCls}-checked`]: checked, [`${prefixCls}-indeterminate`]: !checked && halfChecked, - [`${prefixCls}-disabled`]: disabled, + [`${prefixCls}-disabled`]: disabled || disableCheckbox, })} onClick={onClick} > diff --git a/src/OptionList/Column.tsx b/src/OptionList/Column.tsx index 1e45a5d2..01d9d44c 100644 --- a/src/OptionList/Column.tsx +++ b/src/OptionList/Column.tsx @@ -59,7 +59,7 @@ export default function Column({ const optionInfoList = React.useMemo( () => options.map(option => { - const { disabled } = option; + const { disabled, disableCheckbox } = option; const searchOptions = option[SEARCH_MARK]; const label = option[FIX_LABEL] ?? option[fieldNames.label]; const value = option[fieldNames.value]; @@ -89,6 +89,7 @@ export default function Column({ checked, halfChecked, option, + disableCheckbox, fullPath, fullPathKey, }; @@ -111,6 +112,7 @@ export default function Column({ option, fullPath, fullPathKey, + disableCheckbox, }) => { // >>>>> Open const triggerOpenPath = () => { @@ -182,6 +184,7 @@ export default function Column({ checked={checked} halfChecked={halfChecked} disabled={disabled} + disableCheckbox={disableCheckbox} onClick={(e: React.MouseEvent) => { e.stopPropagation(); triggerSelect(); diff --git a/tests/checkable.spec.tsx b/tests/checkable.spec.tsx index 9b77c9bc..decb10b5 100644 --- a/tests/checkable.spec.tsx +++ b/tests/checkable.spec.tsx @@ -1,9 +1,9 @@ /* eslint-disable react/jsx-no-bind */ import React from 'react'; -import { mount } from './enzyme'; import Cascader from '../src'; import { addressOptions } from './demoOptions'; +import { mount } from './enzyme'; describe('Cascader.Checkable', () => { const options = [ @@ -171,11 +171,48 @@ describe('Cascader.Checkable', () => { it('should work with custom checkable', () => { const wrapper = mount( 0} + checkable={0} open options={addressOptions} />, ); expect(wrapper.find('.my-custom-checkbox')).toHaveLength(3); }); + + it('should be correct expression with disableCheckbox', () => { + const wrapper = mount( + , + ); + + // disabled className + wrapper.find('.rc-cascader-menu-item').simulate('click'); + expect(wrapper.find('.rc-cascader-checkbox-disabled')).toHaveLength(1); + + // Check all children except disableCheckbox When the parent checkbox is checked + expect(wrapper.find('.rc-cascader-checkbox')).toHaveLength(4); + wrapper.find('.rc-cascader-checkbox').first().simulate('click'); + expect(wrapper.find('.rc-cascader-checkbox-checked')).toHaveLength(3); + }); });