diff --git a/packages/components/cascader/__tests__/cascader.spec.ts b/packages/components/cascader/__tests__/cascader.spec.ts index b634b038d..0bb3863cc 100644 --- a/packages/components/cascader/__tests__/cascader.spec.ts +++ b/packages/components/cascader/__tests__/cascader.spec.ts @@ -1,4 +1,4 @@ -import { MountingOptions, mount } from '@vue/test-utils' +import { MountingOptions, VueWrapper, mount } from '@vue/test-utils' import { renderWork } from '@tests' @@ -125,6 +125,9 @@ const defaultMultipleValue = [ ] const defaultExpandedKeys = ['components', 'general'] +const getAllOptionGroup = (wrapper: VueWrapper) => + wrapper.findComponent(OverlayContent).findAll('.ix-cascader-option-group') + describe('Cascader', () => { describe('single work', () => { const CascaderMount = (options?: MountingOptions>) => { @@ -168,19 +171,47 @@ describe('Cascader', () => { expect(wrapper.find('.ix-selector-item').exists()).toBe(false) - const allGroups = wrapper.findComponent(OverlayContent).findAll('.ix-cascader-option-group') - - await allGroups[2].find('.ix-cascader-option').trigger('click') + await getAllOptionGroup(wrapper)[2].find('.ix-cascader-option').trigger('click') // expect(onUpdateValue).toBeCalledWith(['components', 'general', 'button']) // expect(onChange).toBeCalledWith(['components', 'general', 'button'], undefined) await wrapper.setProps({ value: ['components', 'general', 'button'] }) - await allGroups[2].find('.ix-cascader-option').trigger('click') + await getAllOptionGroup(wrapper)[2].find('.ix-cascader-option').trigger('click') // expect(onUpdateValue).toBeCalledWith(['pro', 'pro-layout']) // expect(onChange).toBeCalledWith(['pro', 'pro-layout'], ['components', 'general', 'button']) }) + + test('v-model:expandedKeys work', async () => { + const onUpdateExpandedKeys = vi.fn() + const wrapper = CascaderMount({ + props: { + open: true, + expandedKeys: defaultExpandedKeys, + 'onUpdate:expandedKeys': onUpdateExpandedKeys, + }, + }) + + expect(getAllOptionGroup(wrapper).length).toBe(3) + + await wrapper.setProps({ expandedKeys: ['components'] }) + + expect(getAllOptionGroup(wrapper).length).toBe(2) + + await wrapper + .findComponent(OverlayContent) + .findAll('.ix-cascader-option-group')[1] + .find('.ix-cascader-option') + .trigger('click') + + expect(onUpdateExpandedKeys).toBeCalledWith(['components', 'general']) + + // see https://github.com/IDuxFE/idux/issues/1192 + await wrapper.setProps({ expandedKeys: undefined }) + + expect(getAllOptionGroup(wrapper).length).toBe(3) + }) }) describe('multiple work', () => { @@ -221,9 +252,7 @@ describe('Cascader', () => { expect(wrapper.findAll('.ix-selector-item').length).toBe(1) - const allGroups = wrapper.findComponent(OverlayContent).findAll('.ix-cascader-option-group') - - await allGroups[2].find('.ix-cascader-option').trigger('click') + await getAllOptionGroup(wrapper)[2].find('.ix-cascader-option').trigger('click') // expect(onUpdateValue).toBeCalledWith([ // ['components', 'general', 'button'], diff --git a/packages/components/cascader/src/Cascader.tsx b/packages/components/cascader/src/Cascader.tsx index 468985479..7d784daeb 100644 --- a/packages/components/cascader/src/Cascader.tsx +++ b/packages/components/cascader/src/Cascader.tsx @@ -78,6 +78,7 @@ export default defineComponent({ mergedLabelKey, mergedFullPath, mergedDataMap, + selectedStateContext.selectedKeys, ) watch(overlayOpened, opened => { diff --git a/packages/components/cascader/src/composables/useExpandable.ts b/packages/components/cascader/src/composables/useExpandable.ts index 06e4cf8b2..0e903cb80 100644 --- a/packages/components/cascader/src/composables/useExpandable.ts +++ b/packages/components/cascader/src/composables/useExpandable.ts @@ -7,6 +7,8 @@ import { type ComputedRef, type Ref, type WritableComputedRef, ref } from 'vue' +import { isNil } from 'lodash-es' + import { type VKey, callEmit, useControlledProp } from '@idux/cdk/utils' import { type GetKeyFn } from '@idux/components/utils' @@ -27,8 +29,19 @@ export function useExpandable( mergedLabelKey: ComputedRef, mergedFullPath: ComputedRef, mergedDataMap: ComputedRef>, + selectedKeys: ComputedRef, ): ExpandableContext { - const [expandedKeys, setExpandedKeys] = useControlledProp(props, 'expandedKeys', () => []) + const getDefaultExpandedKeys = (firstSelectedKey: VKey) => { + if (isNil(firstSelectedKey)) { + return [] + } + const dataMap = mergedDataMap.value + const currData = dataMap.get(firstSelectedKey) + return getParentKeys(dataMap, currData, false) + } + const [expandedKeys, setExpandedKeys] = useControlledProp(props, 'expandedKeys', () => + getDefaultExpandedKeys(selectedKeys.value[0]), + ) const [loadedKeys, setLoadedKeys] = useControlledProp(props, 'loadedKeys', () => []) const loadingKeys = ref([])