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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 123 additions & 26 deletions
Large diffs are not rendered by default.

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

Lines changed: 137 additions & 93 deletions
Large diffs are not rendered by default.

components/cascader/__tests__/index.test.js

Lines changed: 28 additions & 12 deletions
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

Lines changed: 2 additions & 6 deletions
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

Lines changed: 8 additions & 7 deletions
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

Lines changed: 9 additions & 10 deletions
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

Lines changed: 9 additions & 10 deletions
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

0 commit comments

Comments
 (0)