Skip to content

Refactor cascader #5192

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 17 commits into from
Jan 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions components/auto-complete/OptGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { FunctionalComponent } from 'vue';
import type { OptionGroupData } from '../vc-select/interface';
import type { DefaultOptionType } from '../select';

export type OptGroupProps = Omit<OptionGroupData, 'options'>;
export type OptGroupProps = Omit<DefaultOptionType, 'options'>;

export interface OptionGroupFC extends FunctionalComponent<OptGroupProps> {
/** Legacy for check if is a Option Group */
Expand Down
4 changes: 2 additions & 2 deletions components/auto-complete/Option.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { FunctionalComponent } from 'vue';
import type { OptionCoreData } from '../vc-select/interface';
import type { DefaultOptionType } from '../vc-select/Select';

export interface OptionProps extends Omit<OptionCoreData, 'label'> {
export interface OptionProps extends Omit<DefaultOptionType, 'label'> {
/** Save for customize data */
[prop: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
}
Expand Down
4 changes: 2 additions & 2 deletions components/calendar/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ function YearSelect<DateType>(props: SharedProps<DateType>) {
options={options}
value={year}
class={`${prefixCls}-year-select`}
onChange={numYear => {
onChange={(numYear: number) => {
let newDate = generateConfig.setYear(value, numYear);

if (validRange) {
Expand Down Expand Up @@ -108,7 +108,7 @@ function MonthSelect<DateType>(props: SharedProps<DateType>) {
class={`${prefixCls}-month-select`}
value={month}
options={options}
onChange={newMonth => {
onChange={(newMonth: number) => {
onChange(generateConfig.setMonth(value, newMonth));
}}
getPopupContainer={() => divRef!.value!}
Expand Down
149 changes: 123 additions & 26 deletions components/cascader/__tests__/__snapshots__/demo.test.js.snap

Large diffs are not rendered by default.

230 changes: 137 additions & 93 deletions components/cascader/__tests__/__snapshots__/index.test.js.snap

Large diffs are not rendered by default.

40 changes: 28 additions & 12 deletions components/cascader/__tests__/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,14 @@ function filter(inputValue, path) {
return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
}

function toggleOpen(wrapper) {
wrapper.find('.ant-select-selector').trigger('mousedown');
}

function isOpen(wrapper) {
return !!wrapper.findComponent({ name: 'Trigger' }).props().popupVisible;
}

describe('Cascader', () => {
focusTest(Cascader);
beforeEach(() => {
Expand All @@ -65,7 +73,7 @@ describe('Cascader', () => {
it('popup correctly when panel is open', async () => {
const wrapper = mount(Cascader, { props: { options }, sync: false, attachTo: 'body' });
await asyncExpect(() => {
wrapper.find('input').trigger('click');
toggleOpen(wrapper);
});
expect($$('.ant-cascader-menus').length).toBe(1);
await asyncExpect(() => {
Expand Down Expand Up @@ -95,7 +103,7 @@ describe('Cascader', () => {
});

await asyncExpect(() => {
wrapper.find('input').trigger('click');
toggleOpen(wrapper);
});
expect($$('.ant-cascader-menus').length).toBe(1);
await asyncExpect(() => {
Expand All @@ -106,9 +114,8 @@ describe('Cascader', () => {
it('can be selected', async () => {
const wrapper = mount(Cascader, { props: { options }, sync: false });
await asyncExpect(() => {
wrapper.find('input').trigger('click');
toggleOpen(wrapper);
});

await asyncExpect(() => {
$$('.ant-cascader-menu')[0].querySelectorAll('.ant-cascader-menu-item')[0].click();
});
Expand All @@ -134,23 +141,36 @@ describe('Cascader', () => {
});
});

it('backspace should work with `Cascader[showSearch]`', async () => {
fit('backspace should work with `Cascader[showSearch]`', async () => {
const wrapper = mount(Cascader, { props: { options, showSearch: true }, sync: false });
await asyncExpect(() => {
wrapper.find('input').element.value = '123';
wrapper.find('input').trigger('input');
});
await asyncExpect(() => {
expect(wrapper.vm.inputValue).toBe('123');
expect(isOpen(wrapper)).toBeTruthy();
});
await asyncExpect(() => {
wrapper.find('input').element.keyCode = KeyCode.BACKSPACE;
wrapper.find('input').trigger('keydown');
});
await asyncExpect(() => {
// trigger onKeyDown will not trigger onChange by default, so the value is still '123'
expect(wrapper.vm.inputValue).toBe('123');
expect(isOpen(wrapper)).toBeTruthy();
});
await asyncExpect(() => {
wrapper.find('input').element.value = '';
wrapper.find('input').trigger('input');
});
await asyncExpect(() => {
expect(isOpen(wrapper)).toBeTruthy();
});
// await asyncExpect(() => {
// wrapper.find('input').element.keyCode = KeyCode.BACKSPACE;
// wrapper.find('input').trigger('keydown');
// });
// await asyncExpect(() => {
// expect(isOpen(wrapper)).toBeFalsy();
// }, 0);
});

describe('limit filtered item count', () => {
Expand Down Expand Up @@ -191,7 +211,6 @@ describe('Cascader', () => {
});

it('negative limit', async () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
const wrapper = mount(Cascader, {
props: { options, showSearch: { filter, limit: -1 } },
sync: false,
Expand All @@ -203,9 +222,6 @@ describe('Cascader', () => {
await asyncExpect(() => {
expect($$('.ant-cascader-menu-item').length).toBe(2);
}, 0);
expect(errorSpy).toBeCalledWith(
"Warning: [antdv: Cascader] 'limit' of showSearch in Cascader should be positive number or false.",
);
});
});
});
8 changes: 2 additions & 6 deletions components/cascader/demo/basic.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,8 @@ Cascade selection box for selecting province/city/district.
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
import type { CascaderProps } from 'ant-design-vue';
const options: CascaderProps['options'] = [
{
value: 'zhejiang',
label: 'Zhejiang',
Expand Down
15 changes: 8 additions & 7 deletions components/cascader/demo/change-on-select.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ Allow only select parent options.

</docs>
<template>
<a-cascader v-model:value="value" :options="options" change-on-select />
<a-cascader
v-model:value="value"
:options="options"
placeholder="Please select"
change-on-select
/>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
import type { CascaderProps } from 'ant-design-vue';
const options: CascaderProps['options'] = [
{
value: 'zhejiang',
label: 'Zhejiang',
Expand Down
19 changes: 9 additions & 10 deletions components/cascader/demo/custom-render.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@ For instance, add an external link after the selected value.

</docs>
<template>
<a-cascader v-model:value="value" :options="options" style="width: 100%">
<a-cascader
v-model:value="value"
placeholder="Please select"
:options="options"
style="width: 100%"
>
<template #displayRender="{ labels, selectedOptions }">
<span v-for="(label, index) in labels" :key="selectedOptions[index].value">
<span v-if="index === labels.length - 1">
Expand All @@ -33,14 +38,8 @@ For instance, add an external link after the selected value.
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
interface Option {
value: string;
label: string;
children?: Option[];
code?: number;
[key: string]: any;
}
const options: Option[] = [
import type { CascaderProps } from 'ant-design-vue';
const options: CascaderProps['options'] = [
{
value: 'zhejiang',
label: 'Zhejiang',
Expand Down Expand Up @@ -78,7 +77,7 @@ const options: Option[] = [
];
export default defineComponent({
setup() {
const handleAreaClick = (e: Event, label: string, option: Option) => {
const handleAreaClick = (e: Event, label: string, option: CascaderProps['options'][number]) => {
e.stopPropagation();
console.log('clicked', label, option);
};
Expand Down
19 changes: 9 additions & 10 deletions components/cascader/demo/custom-trigger.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,20 @@ Separate trigger button and result.
<template>
<span>
{{ text }} &nbsp;
<a-cascader v-model:value="value" :options="options" @change="onChange">
<a-cascader
v-model:value="value"
placeholder="Please select"
:options="options"
@change="onChange"
>
<a href="#">Change city</a>
</a-cascader>
</span>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
interface Option {
value: string;
label: string;
children?: Option[];
code?: number;
[key: string]: any;
}
const options: Option[] = [
import type { CascaderProps } from 'ant-design-vue';
const options: CascaderProps['options'] = [
{
value: 'zhejiang',
label: 'Zhejiang',
Expand Down Expand Up @@ -72,7 +71,7 @@ export default defineComponent({
const value = ref<string[]>([]);
const text = ref<string>('Unselect');

const onChange = (_value: string, selectedOptions: Option[]) => {
const onChange: CascaderProps['onChange'] = (_value, selectedOptions) => {
text.value = selectedOptions.map(o => o.label).join(', ');
};

Expand Down
13 changes: 3 additions & 10 deletions components/cascader/demo/disabled-option.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,12 @@ Disable option by specifying the `disabled` property in `options`.

</docs>
<template>
<a-cascader v-model:value="value" :options="options" />
<a-cascader v-model:value="value" placeholder="Please select" :options="options" />
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
interface Option {
value: string;
label: string;
disabled?: boolean;
children?: Option[];
code?: number;
[key: string]: any;
}
const options: Option[] = [
import type { CascaderProps } from 'ant-design-vue';
const options: CascaderProps['options'] = [
{
value: 'zhejiang',
label: 'Zhejiang',
Expand Down
10 changes: 2 additions & 8 deletions components/cascader/demo/fields-name.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,8 @@ Custom Field Names
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
interface Option {
code: string;
name: string;
disabled?: boolean;
items?: Option[];
[key: string]: any;
}
const options: Option[] = [
import type { CascaderProps } from 'ant-design-vue';
const options: CascaderProps['options'] = [
{
code: 'zhejiang',
name: 'Zhejiang',
Expand Down
14 changes: 2 additions & 12 deletions components/cascader/demo/hover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,14 @@ Hover to expand sub menu, click to select option.
<a-cascader
v-model:value="value"
:options="options"
:display-render="displayRender"
expand-trigger="hover"
placeholder="Please select"
/>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
interface Option {
value: string;
label: string;
children?: Option[];
}
const options: Option[] = [
import type { CascaderProps } from 'ant-design-vue';
const options: CascaderProps['options'] = [
{
value: 'zhejiang',
label: 'Zhejiang',
Expand Down Expand Up @@ -67,14 +62,9 @@ const options: Option[] = [
];
export default defineComponent({
setup() {
const displayRender = ({ labels }: { labels: string[] }) => {
return labels[labels.length - 1];
};

return {
value: ref<string[]>([]),
options,
displayRender,
};
},
});
Expand Down
3 changes: 3 additions & 0 deletions components/cascader/demo/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
<lazy />
<fields-name />
<suffix />
<multipleVue />
</demo-sort>
</template>
<script>
Expand All @@ -25,6 +26,7 @@ import Search from './search.vue';
import Size from './size.vue';
import FieldsName from './fields-name.vue';
import Suffix from './suffix.vue';
import multipleVue from './multiple.vue';

import CN from '../index.zh-CN.md';
import US from '../index.en-US.md';
Expand All @@ -44,6 +46,7 @@ export default defineComponent({
Size,
FieldsName,
Suffix,
multipleVue,
},
});
</script>
Expand Down
13 changes: 4 additions & 9 deletions components/cascader/demo/lazy.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,11 @@ Load options lazily with `loadData`.
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
interface Option {
value: string;
label: string;
loading?: boolean;
isLeaf?: boolean;
children?: Option[];
}
import type { CascaderProps } from 'ant-design-vue';

export default defineComponent({
setup() {
const options = ref<Option[]>([
const options = ref<CascaderProps['options']>([
{
value: 'zhejiang',
label: 'Zhejiang',
Expand All @@ -50,7 +45,7 @@ export default defineComponent({
},
]);

const loadData = (selectedOptions: Option[]) => {
const loadData: CascaderProps['loadData'] = selectedOptions => {
const targetOption = selectedOptions[selectedOptions.length - 1];
targetOption.loading = true;

Expand Down
Loading