diff --git a/examples/debug.tsx b/examples/debug.tsx index 670f2b98..74261d58 100644 --- a/examples/debug.tsx +++ b/examples/debug.tsx @@ -120,7 +120,8 @@ const Demo = () => { allowClear // defaultValue={multiple ? [defaultValue] : defaultValue} // defaultValue={[['not', 'yet'], ['exist']]} - defaultValue={[['empty']]} + // defaultValue={[['empty']]} + defaultValue={[['fj', 'fuzhou']]} showSearch // showSearch={{ limit: 1 }} open diff --git a/src/Cascader.tsx b/src/Cascader.tsx index e62a634c..7eded636 100644 --- a/src/Cascader.tsx +++ b/src/Cascader.tsx @@ -306,6 +306,7 @@ const Cascader = React.forwardRef((props, re deDuplicatedValues, mergedOptions, mergedFieldNames, + multiple, displayRender, ); diff --git a/src/hooks/useDisplayValues.ts b/src/hooks/useDisplayValues.ts index cb075044..64ed1ead 100644 --- a/src/hooks/useDisplayValues.ts +++ b/src/hooks/useDisplayValues.ts @@ -12,32 +12,39 @@ export default ( rawValues: SingleValueType[], options: DefaultOptionType[], fieldNames: InternalFieldNames, - displayRender: CascaderProps['displayRender'] = labels => { - const SPLIT = ' / '; - - if (labels.every(label => ['string', 'number'].includes(typeof label))) { - return labels.join(SPLIT); - } - - // If exist non-string value, use ReactNode instead - return labels.reduce((list, label, index) => { - const keyedLabel = React.isValidElement(label) - ? React.cloneElement(label, { key: index }) - : label; - - if (index === 0) { - return [keyedLabel]; - } - - return [...list, SPLIT, keyedLabel]; - }, []); - }, + multiple: boolean, + displayRender: CascaderProps['displayRender'], ) => { return React.useMemo(() => { + const mergedDisplayRender = + displayRender || + // Default displayRender + (labels => { + const mergedLabels = multiple ? labels.slice(-1) : labels; + const SPLIT = ' / '; + + if (mergedLabels.every(label => ['string', 'number'].includes(typeof label))) { + return mergedLabels.join(SPLIT); + } + + // If exist non-string value, use ReactNode instead + return mergedLabels.reduce((list, label, index) => { + const keyedLabel = React.isValidElement(label) + ? React.cloneElement(label, { key: index }) + : label; + + if (index === 0) { + return [keyedLabel]; + } + + return [...list, SPLIT, keyedLabel]; + }, []); + }); + return rawValues.map(valueCells => { const valueOptions = toPathOptions(valueCells, options, fieldNames); - const label = displayRender( + const label = mergedDisplayRender( valueOptions.map(({ option, value }) => option?.[fieldNames.label] ?? value), valueOptions.map(({ option }) => option), ); @@ -48,5 +55,5 @@ export default ( valueCells, }; }); - }, [rawValues, options, fieldNames, displayRender]); + }, [rawValues, options, fieldNames, displayRender, multiple]); }; diff --git a/tests/index.spec.tsx b/tests/index.spec.tsx index ce776b26..74298da3 100644 --- a/tests/index.spec.tsx +++ b/tests/index.spec.tsx @@ -711,34 +711,60 @@ describe('Cascader.Basic', () => { expect(wrapper.find('ul.rc-cascader-menu')).toHaveLength(1); }); - it('ReactNode label should not be [object]', () => { - const wrapper = mount( - Parent, value: 'parent' }, - { - label: 'Normal', - value: 'normal', - children: [ - { - label: Child, - value: 'child', - }, - { - label: 'Child2', - value: 'child2', - }, - ], - }, - ]} - value={[['parent'], ['normal', 'child']]} - checkable - />, - ); + describe('ReactNode label should not be [object]', () => { + it('single', () => { + const wrapper = mount( + Child, + value: 'child', + }, + { + label: 'Child2', + value: 'child2', + }, + ], + }, + ]} + value={['normal', 'child']} + />, + ); - expect(wrapper.find('.rc-cascader-selection-item-content').first().text()).toEqual('Parent'); - expect(wrapper.find('.rc-cascader-selection-item-content').last().text()).toEqual( - 'Normal / Child', - ); + expect(wrapper.find('.rc-cascader-selection-item').text()).toEqual('Normal / Child'); + }); + + it('multiple', () => { + const wrapper = mount( + Parent, value: 'parent' }, + { + label: 'Normal', + value: 'normal', + children: [ + { + label: Child, + value: 'child', + }, + { + label: 'Child2', + value: 'child2', + }, + ], + }, + ]} + value={[['parent'], ['normal', 'child']]} + checkable + />, + ); + + expect(wrapper.find('.rc-cascader-selection-item-content').first().text()).toEqual('Parent'); + expect(wrapper.find('.rc-cascader-selection-item-content').last().text()).toEqual('Child'); + }); }); });