Skip to content

Commit f0385d7

Browse files
authored
Refactor cascader (#5192)
* feat: tree * refactor: select * refactor: select * refactor: select * refactor: vc-tree-select * refactor: tree-select * refactor: tree-select * feat: add showLeafIcon * refactor: remove lod vc-tree-select * feat: tree-select add tag-render * refactor: cascader * refactor: cascader * refactor: cascader * refactor: cascader * fix: maxTagmaxTagPlaceholder not work
1 parent 7624d80 commit f0385d7

File tree

151 files changed

+6875
-6821
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

151 files changed

+6875
-6821
lines changed

components/auto-complete/OptGroup.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { FunctionalComponent } from 'vue';
2-
import type { OptionGroupData } from '../vc-select/interface';
2+
import type { DefaultOptionType } from '../select';
33

4-
export type OptGroupProps = Omit<OptionGroupData, 'options'>;
4+
export type OptGroupProps = Omit<DefaultOptionType, 'options'>;
55

66
export interface OptionGroupFC extends FunctionalComponent<OptGroupProps> {
77
/** Legacy for check if is a Option Group */

components/auto-complete/Option.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { FunctionalComponent } from 'vue';
2-
import type { OptionCoreData } from '../vc-select/interface';
2+
import type { DefaultOptionType } from '../vc-select/Select';
33

4-
export interface OptionProps extends Omit<OptionCoreData, 'label'> {
4+
export interface OptionProps extends Omit<DefaultOptionType, 'label'> {
55
/** Save for customize data */
66
[prop: string]: any; // eslint-disable-line @typescript-eslint/no-explicit-any
77
}

components/calendar/Header.tsx

+2-2
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ function YearSelect<DateType>(props: SharedProps<DateType>) {
4545
options={options}
4646
value={year}
4747
class={`${prefixCls}-year-select`}
48-
onChange={numYear => {
48+
onChange={(numYear: number) => {
4949
let newDate = generateConfig.setYear(value, numYear);
5050

5151
if (validRange) {
@@ -108,7 +108,7 @@ function MonthSelect<DateType>(props: SharedProps<DateType>) {
108108
class={`${prefixCls}-month-select`}
109109
value={month}
110110
options={options}
111-
onChange={newMonth => {
111+
onChange={(newMonth: number) => {
112112
onChange(generateConfig.setMonth(value, newMonth));
113113
}}
114114
getPopupContainer={() => divRef!.value!}

components/cascader/__tests__/__snapshots__/demo.test.js.snap

+123-26
Large diffs are not rendered by default.

components/cascader/__tests__/__snapshots__/index.test.js.snap

+137-93
Large diffs are not rendered by default.

components/cascader/__tests__/index.test.js

+28-12
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@ function filter(inputValue, path) {
4646
return path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
4747
}
4848

49+
function toggleOpen(wrapper) {
50+
wrapper.find('.ant-select-selector').trigger('mousedown');
51+
}
52+
53+
function isOpen(wrapper) {
54+
return !!wrapper.findComponent({ name: 'Trigger' }).props().popupVisible;
55+
}
56+
4957
describe('Cascader', () => {
5058
focusTest(Cascader);
5159
beforeEach(() => {
@@ -65,7 +73,7 @@ describe('Cascader', () => {
6573
it('popup correctly when panel is open', async () => {
6674
const wrapper = mount(Cascader, { props: { options }, sync: false, attachTo: 'body' });
6775
await asyncExpect(() => {
68-
wrapper.find('input').trigger('click');
76+
toggleOpen(wrapper);
6977
});
7078
expect($$('.ant-cascader-menus').length).toBe(1);
7179
await asyncExpect(() => {
@@ -95,7 +103,7 @@ describe('Cascader', () => {
95103
});
96104

97105
await asyncExpect(() => {
98-
wrapper.find('input').trigger('click');
106+
toggleOpen(wrapper);
99107
});
100108
expect($$('.ant-cascader-menus').length).toBe(1);
101109
await asyncExpect(() => {
@@ -106,9 +114,8 @@ describe('Cascader', () => {
106114
it('can be selected', async () => {
107115
const wrapper = mount(Cascader, { props: { options }, sync: false });
108116
await asyncExpect(() => {
109-
wrapper.find('input').trigger('click');
117+
toggleOpen(wrapper);
110118
});
111-
112119
await asyncExpect(() => {
113120
$$('.ant-cascader-menu')[0].querySelectorAll('.ant-cascader-menu-item')[0].click();
114121
});
@@ -134,23 +141,36 @@ describe('Cascader', () => {
134141
});
135142
});
136143

137-
it('backspace should work with `Cascader[showSearch]`', async () => {
144+
fit('backspace should work with `Cascader[showSearch]`', async () => {
138145
const wrapper = mount(Cascader, { props: { options, showSearch: true }, sync: false });
139146
await asyncExpect(() => {
140147
wrapper.find('input').element.value = '123';
141148
wrapper.find('input').trigger('input');
142149
});
143150
await asyncExpect(() => {
144-
expect(wrapper.vm.inputValue).toBe('123');
151+
expect(isOpen(wrapper)).toBeTruthy();
145152
});
146153
await asyncExpect(() => {
147154
wrapper.find('input').element.keyCode = KeyCode.BACKSPACE;
148155
wrapper.find('input').trigger('keydown');
149156
});
150157
await asyncExpect(() => {
151-
// trigger onKeyDown will not trigger onChange by default, so the value is still '123'
152-
expect(wrapper.vm.inputValue).toBe('123');
158+
expect(isOpen(wrapper)).toBeTruthy();
159+
});
160+
await asyncExpect(() => {
161+
wrapper.find('input').element.value = '';
162+
wrapper.find('input').trigger('input');
163+
});
164+
await asyncExpect(() => {
165+
expect(isOpen(wrapper)).toBeTruthy();
153166
});
167+
// await asyncExpect(() => {
168+
// wrapper.find('input').element.keyCode = KeyCode.BACKSPACE;
169+
// wrapper.find('input').trigger('keydown');
170+
// });
171+
// await asyncExpect(() => {
172+
// expect(isOpen(wrapper)).toBeFalsy();
173+
// }, 0);
154174
});
155175

156176
describe('limit filtered item count', () => {
@@ -191,7 +211,6 @@ describe('Cascader', () => {
191211
});
192212

193213
it('negative limit', async () => {
194-
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
195214
const wrapper = mount(Cascader, {
196215
props: { options, showSearch: { filter, limit: -1 } },
197216
sync: false,
@@ -203,9 +222,6 @@ describe('Cascader', () => {
203222
await asyncExpect(() => {
204223
expect($$('.ant-cascader-menu-item').length).toBe(2);
205224
}, 0);
206-
expect(errorSpy).toBeCalledWith(
207-
"Warning: [antdv: Cascader] 'limit' of showSearch in Cascader should be positive number or false.",
208-
);
209225
});
210226
});
211227
});

components/cascader/demo/basic.vue

+2-6
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,8 @@ Cascade selection box for selecting province/city/district.
2020
</template>
2121
<script lang="ts">
2222
import { defineComponent, ref } from 'vue';
23-
interface Option {
24-
value: string;
25-
label: string;
26-
children?: Option[];
27-
}
28-
const options: Option[] = [
23+
import type { CascaderProps } from 'ant-design-vue';
24+
const options: CascaderProps['options'] = [
2925
{
3026
value: 'zhejiang',
3127
label: 'Zhejiang',

components/cascader/demo/change-on-select.vue

+8-7
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,17 @@ Allow only select parent options.
1616

1717
</docs>
1818
<template>
19-
<a-cascader v-model:value="value" :options="options" change-on-select />
19+
<a-cascader
20+
v-model:value="value"
21+
:options="options"
22+
placeholder="Please select"
23+
change-on-select
24+
/>
2025
</template>
2126
<script lang="ts">
2227
import { defineComponent, ref } from 'vue';
23-
interface Option {
24-
value: string;
25-
label: string;
26-
children?: Option[];
27-
}
28-
const options: Option[] = [
28+
import type { CascaderProps } from 'ant-design-vue';
29+
const options: CascaderProps['options'] = [
2930
{
3031
value: 'zhejiang',
3132
label: 'Zhejiang',

components/cascader/demo/custom-render.vue

+9-10
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@ For instance, add an external link after the selected value.
1616

1717
</docs>
1818
<template>
19-
<a-cascader v-model:value="value" :options="options" style="width: 100%">
19+
<a-cascader
20+
v-model:value="value"
21+
placeholder="Please select"
22+
:options="options"
23+
style="width: 100%"
24+
>
2025
<template #displayRender="{ labels, selectedOptions }">
2126
<span v-for="(label, index) in labels" :key="selectedOptions[index].value">
2227
<span v-if="index === labels.length - 1">
@@ -33,14 +38,8 @@ For instance, add an external link after the selected value.
3338
</template>
3439
<script lang="ts">
3540
import { defineComponent, ref } from 'vue';
36-
interface Option {
37-
value: string;
38-
label: string;
39-
children?: Option[];
40-
code?: number;
41-
[key: string]: any;
42-
}
43-
const options: Option[] = [
41+
import type { CascaderProps } from 'ant-design-vue';
42+
const options: CascaderProps['options'] = [
4443
{
4544
value: 'zhejiang',
4645
label: 'Zhejiang',
@@ -78,7 +77,7 @@ const options: Option[] = [
7877
];
7978
export default defineComponent({
8079
setup() {
81-
const handleAreaClick = (e: Event, label: string, option: Option) => {
80+
const handleAreaClick = (e: Event, label: string, option: CascaderProps['options'][number]) => {
8281
e.stopPropagation();
8382
console.log('clicked', label, option);
8483
};

components/cascader/demo/custom-trigger.vue

+9-10
Original file line numberDiff line numberDiff line change
@@ -18,21 +18,20 @@ Separate trigger button and result.
1818
<template>
1919
<span>
2020
{{ text }} &nbsp;
21-
<a-cascader v-model:value="value" :options="options" @change="onChange">
21+
<a-cascader
22+
v-model:value="value"
23+
placeholder="Please select"
24+
:options="options"
25+
@change="onChange"
26+
>
2227
<a href="#">Change city</a>
2328
</a-cascader>
2429
</span>
2530
</template>
2631
<script lang="ts">
2732
import { defineComponent, ref } from 'vue';
28-
interface Option {
29-
value: string;
30-
label: string;
31-
children?: Option[];
32-
code?: number;
33-
[key: string]: any;
34-
}
35-
const options: Option[] = [
33+
import type { CascaderProps } from 'ant-design-vue';
34+
const options: CascaderProps['options'] = [
3635
{
3736
value: 'zhejiang',
3837
label: 'Zhejiang',
@@ -72,7 +71,7 @@ export default defineComponent({
7271
const value = ref<string[]>([]);
7372
const text = ref<string>('Unselect');
7473
75-
const onChange = (_value: string, selectedOptions: Option[]) => {
74+
const onChange: CascaderProps['onChange'] = (_value, selectedOptions) => {
7675
text.value = selectedOptions.map(o => o.label).join(', ');
7776
};
7877

components/cascader/demo/disabled-option.vue

+3-10
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,12 @@ Disable option by specifying the `disabled` property in `options`.
1616

1717
</docs>
1818
<template>
19-
<a-cascader v-model:value="value" :options="options" />
19+
<a-cascader v-model:value="value" placeholder="Please select" :options="options" />
2020
</template>
2121
<script lang="ts">
2222
import { defineComponent, ref } from 'vue';
23-
interface Option {
24-
value: string;
25-
label: string;
26-
disabled?: boolean;
27-
children?: Option[];
28-
code?: number;
29-
[key: string]: any;
30-
}
31-
const options: Option[] = [
23+
import type { CascaderProps } from 'ant-design-vue';
24+
const options: CascaderProps['options'] = [
3225
{
3326
value: 'zhejiang',
3427
label: 'Zhejiang',

components/cascader/demo/fields-name.vue

+2-8
Original file line numberDiff line numberDiff line change
@@ -25,14 +25,8 @@ Custom Field Names
2525
</template>
2626
<script lang="ts">
2727
import { defineComponent, ref } from 'vue';
28-
interface Option {
29-
code: string;
30-
name: string;
31-
disabled?: boolean;
32-
items?: Option[];
33-
[key: string]: any;
34-
}
35-
const options: Option[] = [
28+
import type { CascaderProps } from 'ant-design-vue';
29+
const options: CascaderProps['options'] = [
3630
{
3731
code: 'zhejiang',
3832
name: 'Zhejiang',

components/cascader/demo/hover.vue

+2-12
Original file line numberDiff line numberDiff line change
@@ -19,19 +19,14 @@ Hover to expand sub menu, click to select option.
1919
<a-cascader
2020
v-model:value="value"
2121
:options="options"
22-
:display-render="displayRender"
2322
expand-trigger="hover"
2423
placeholder="Please select"
2524
/>
2625
</template>
2726
<script lang="ts">
2827
import { defineComponent, ref } from 'vue';
29-
interface Option {
30-
value: string;
31-
label: string;
32-
children?: Option[];
33-
}
34-
const options: Option[] = [
28+
import type { CascaderProps } from 'ant-design-vue';
29+
const options: CascaderProps['options'] = [
3530
{
3631
value: 'zhejiang',
3732
label: 'Zhejiang',
@@ -67,14 +62,9 @@ const options: Option[] = [
6762
];
6863
export default defineComponent({
6964
setup() {
70-
const displayRender = ({ labels }: { labels: string[] }) => {
71-
return labels[labels.length - 1];
72-
};
73-
7465
return {
7566
value: ref<string[]>([]),
7667
options,
77-
displayRender,
7868
};
7969
},
8070
});

components/cascader/demo/index.vue

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
<lazy />
1212
<fields-name />
1313
<suffix />
14+
<multipleVue />
1415
</demo-sort>
1516
</template>
1617
<script>
@@ -25,6 +26,7 @@ import Search from './search.vue';
2526
import Size from './size.vue';
2627
import FieldsName from './fields-name.vue';
2728
import Suffix from './suffix.vue';
29+
import multipleVue from './multiple.vue';
2830
2931
import CN from '../index.zh-CN.md';
3032
import US from '../index.en-US.md';
@@ -44,6 +46,7 @@ export default defineComponent({
4446
Size,
4547
FieldsName,
4648
Suffix,
49+
multipleVue,
4750
},
4851
});
4952
</script>

components/cascader/demo/lazy.vue

+4-9
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,11 @@ Load options lazily with `loadData`.
2828
</template>
2929
<script lang="ts">
3030
import { defineComponent, ref } from 'vue';
31-
interface Option {
32-
value: string;
33-
label: string;
34-
loading?: boolean;
35-
isLeaf?: boolean;
36-
children?: Option[];
37-
}
31+
import type { CascaderProps } from 'ant-design-vue';
32+
3833
export default defineComponent({
3934
setup() {
40-
const options = ref<Option[]>([
35+
const options = ref<CascaderProps['options']>([
4136
{
4237
value: 'zhejiang',
4338
label: 'Zhejiang',
@@ -50,7 +45,7 @@ export default defineComponent({
5045
},
5146
]);
5247
53-
const loadData = (selectedOptions: Option[]) => {
48+
const loadData: CascaderProps['loadData'] = selectedOptions => {
5449
const targetOption = selectedOptions[selectedOptions.length - 1];
5550
targetOption.loading = true;
5651

0 commit comments

Comments
 (0)