From 3d53b0f6d308874efabcd4d946ff5f1fa6e60069 Mon Sep 17 00:00:00 2001 From: Jony J <1844749591@qq.com> Date: Tue, 29 Oct 2024 19:15:38 +0800 Subject: [PATCH] feat: add disabled api for panel (#543) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: add disabled api for panel * feat: add test case * docs: add demo * fix: test case fixed * feat: adjust demo position * feat: improve demo * chore: reorganize code for better readability * test: update snapshot * fix: lint fix * chore: adjust code structure * test: update snapshot * chore: code optimization --------- Co-authored-by: 小豪 --- examples/panel.tsx | 13 ++++++++++++- src/OptionList/Column.tsx | 12 ++++++++---- src/OptionList/List.tsx | 28 ++++++++++++++++++++++++---- src/Panel.tsx | 5 ++++- tests/Panel.spec.tsx | 13 +++++++++++++ 5 files changed, 61 insertions(+), 10 deletions(-) diff --git a/examples/panel.tsx b/examples/panel.tsx index 1f985476..c0c51353 100644 --- a/examples/panel.tsx +++ b/examples/panel.tsx @@ -61,6 +61,8 @@ export default () => { const [value2, setValue2] = React.useState([]); + const [disabled, setDisabled] = React.useState(false); + return ( <>

Panel

@@ -71,6 +73,13 @@ export default () => { > Set Value + { console.log('Change:', nextValue); setValue(nextValue); }} + disabled={disabled} /> { console.log('Change:', nextValue); setValue2(nextValue); }} + disabled={disabled} /> - + diff --git a/src/OptionList/Column.tsx b/src/OptionList/Column.tsx index 5805ab1c..c46cc457 100644 --- a/src/OptionList/Column.tsx +++ b/src/OptionList/Column.tsx @@ -23,6 +23,7 @@ export interface ColumnProps; loadingKeys: React.Key[]; isSelectable: (option: DefaultOptionType) => boolean; + disabled?: boolean; } export default function Column({ @@ -38,6 +39,7 @@ export default function Column) { const menuPrefixCls = `${prefixCls}-menu`; const menuItemPrefixCls = `${prefixCls}-menu-item`; @@ -54,6 +56,8 @@ export default function Column propsDisabled || disabled; + // ============================ Option ============================ const optionInfoList = React.useMemo( () => @@ -115,7 +119,7 @@ export default function Column { // >>>>> Open const triggerOpenPath = () => { - if (disabled) { + if (isOptionDisabled(disabled)) { return; } const nextValueCells = [...fullPath]; @@ -127,7 +131,7 @@ export default function Column>>>> Selection const triggerSelect = () => { - if (isSelectable(option)) { + if (isSelectable(option) && !isOptionDisabled(disabled)) { onSelect(fullPath, isMergedLeaf); } }; @@ -148,7 +152,7 @@ export default function Column) => { if (disableCheckbox) { diff --git a/src/OptionList/List.tsx b/src/OptionList/List.tsx index 0850b016..d495af23 100644 --- a/src/OptionList/List.tsx +++ b/src/OptionList/List.tsx @@ -21,11 +21,27 @@ import useKeyboard from './useKeyboard'; export type RawOptionListProps = Pick< ReturnType, - 'prefixCls' | 'multiple' | 'searchValue' | 'toggleOpen' | 'notFoundContent' | 'direction' | 'open' + | 'prefixCls' + | 'multiple' + | 'searchValue' + | 'toggleOpen' + | 'notFoundContent' + | 'direction' + | 'open' + | 'disabled' >; const RawOptionList = React.forwardRef((props, ref) => { - const { prefixCls, multiple, searchValue, toggleOpen, notFoundContent, direction, open } = props; + const { + prefixCls, + multiple, + searchValue, + toggleOpen, + notFoundContent, + direction, + open, + disabled, + } = props; const containerRef = React.useRef(null); const rtl = direction === 'rtl'; @@ -100,10 +116,14 @@ const RawOptionList = React.forwardRef(( }; const isSelectable = (option: DefaultOptionType) => { - const { disabled } = option; + if (disabled) { + return false; + } + const { disabled: optionDisabled } = option; const isMergedLeaf = isLeaf(option, fieldNames); - return !disabled && (isMergedLeaf || changeOnSelect || multiple); + + return !optionDisabled && (isMergedLeaf || changeOnSelect || multiple); }; const onPathSelect = (valuePath: SingleValueType, leaf: boolean, fromKeyboard = false) => { diff --git a/src/Panel.tsx b/src/Panel.tsx index 9fa7e6dd..15e36b83 100644 --- a/src/Panel.tsx +++ b/src/Panel.tsx @@ -35,7 +35,8 @@ export type PickType = | 'className' | 'style' | 'direction' - | 'notFoundContent'; + | 'notFoundContent' + | 'disabled'; export type PanelProps< OptionType extends DefaultOptionType = DefaultOptionType, @@ -68,6 +69,7 @@ export default function Panel< loadingIcon, direction, notFoundContent = 'Not Found', + disabled, } = props as Pick; // ======================== Multiple ======================== @@ -200,6 +202,7 @@ export default function Panel< toggleOpen={noop} open direction={direction} + disabled={disabled} /> )} diff --git a/tests/Panel.spec.tsx b/tests/Panel.spec.tsx index 452f1be4..c830a9aa 100644 --- a/tests/Panel.spec.tsx +++ b/tests/Panel.spec.tsx @@ -97,4 +97,17 @@ describe('Cascader.Panel', () => { const checkedLi = container.querySelector('[aria-checked="true"]'); expect(checkedLi?.textContent).toEqual('Little'); }); + + it('disabled', () => { + const onChange = jest.fn(); + const { container } = render( + , + ); + + expect(container.querySelector('.rc-cascader-menu-item-disabled')).toBeTruthy(); + + const selectOption = container.querySelector('.rc-cascader-menu-item')!; + fireEvent.click(selectOption); + expect(onChange).not.toHaveBeenCalled(); + }); });