Skip to content

Commit

Permalink
fix(auto-complete): 修复eslint和单元测试问题 (#394)
Browse files Browse the repository at this point in the history
  • Loading branch information
zxlfly authored Apr 5, 2022
1 parent 70a2130 commit c8b438f
Show file tree
Hide file tree
Showing 16 changed files with 337 additions and 194 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { mount } from '@vue/test-utils';
import { nextTick, ref } from 'vue';
import DAutoComplete from '../src/auto-complete';

// delay api
const wait = (delay = 300) =>
new Promise(resolve => setTimeout(() => resolve(true), delay));
Expand All @@ -13,7 +12,7 @@ describe('auto-complete', () => {
<d-auto-complete
:source="source"
v-model="value"
:dAutoCompleteWidth="450"
:width="450"
/>
`,
setup() {
Expand Down Expand Up @@ -71,7 +70,7 @@ describe('auto-complete', () => {
:source="source"
v-model="value"
:disabled="isDisabled"
/>
/>
<button @click="toggle">{{ isDisabled ? 'Enable AutoComplete' : 'Disable AutoComplete' }}</button>
</div>
`,
Expand Down Expand Up @@ -128,8 +127,8 @@ describe('auto-complete', () => {
disabledKey="disabled"
isSearching
:formatter="formatter"
>
<template #searchingTemplate="slotProps" >
>
<template #searching="slotProps" >
<div id="devui-is-searching-template">
{{slotProps}}
</div>
Expand Down Expand Up @@ -234,13 +233,13 @@ describe('auto-complete', () => {
<d-auto-complete
:source="source"
v-model="value"
>
<template #itemTemplate="slotProps" >
>
<template #item="slotProps" >
<div>
第{{slotProps.index}}项: {{slotProps.item}}
</div>
</template>
<template #noResultItemTemplate="slotProps" >
<template #nothing="slotProps" >
<div id="noResultItemTemplate">
{{slotProps}}
</div>
Expand Down Expand Up @@ -345,13 +344,16 @@ describe('auto-complete', () => {
expect(selectValueCB).toHaveBeenCalledTimes(1);
});
it('allowEmptyValueSearch ', async () => {
const div = document.createElement('div');
div.id="app";
document.body.appendChild(div);
const wrapper = mount({
components: {'d-auto-complete': DAutoComplete },
template: `
<d-auto-complete
:source="source"
v-model="value"
:allowEmptyValueSearch="allowEmptyValueSearch"
:allow-empty-value-search="allowEmptyValueSearch"
/>
`,
setup() {
Expand All @@ -377,41 +379,38 @@ describe('auto-complete', () => {
expect(input.element.value).toBe('');
await input.trigger('focus');
await nextTick();
await input.setValue('');
await wait(300);
await nextTick();
expect(wrapper.find('ul').element.childElementCount).toBe(5);
});

it('appendToBody & appendToBodyDirections', async () => {
it('appendToBody & position', async () => {
const wrapper = mount({
components: {'d-auto-complete': DAutoComplete },
template: `
<d-auto-complete
:source="source"
v-model="value"
:appendToBodyDirections="appendToBodyDirections"
:allowEmptyValueSearch="allowEmptyValueSearch"
:append-to-body="appendToBody"
:position="position"
/>
`,
setup() {
const value = ref('');
const allowEmptyValueSearch = ref(true);
const appendToBody = ref(true);
const source = [
'CC#',
'C',
'C++',
'CPython',
'CoffeeScript',
];
const appendToBodyDirections = ref({
originX: 'left',
originY: 'bottom',
overlayX: 'left',
overlayY: 'top',
});
const position = ref(['bottom']);
return {
value,
source,
allowEmptyValueSearch,
appendToBodyDirections
appendToBody,
position
};
}
});
Expand All @@ -424,10 +423,20 @@ describe('auto-complete', () => {
await nextTick();
await wait(300);
await nextTick();
expect(wrapper.find('ul').element.childElementCount).toBe(5);
expect(wrapper.find('.selected').element.innerHTML).toBe('CC#');
expect(wrapper.find('.devui-select-open').exists()).toBe(true);
const ul = document.querySelector('.devui-list-unstyled');
let lis = 0;
if(ul&&ul.getElementsByTagName('li')){
lis=ul.getElementsByTagName('li').length;
}
expect(lis).toBe(5);
const li_ed = document.querySelector('.selected');
let li_text = '';
if(li_ed&&li_ed.getElementsByTagName('li')){
li_text=li_ed.innerHTML;
}
expect(li_text).toBe('CC#');
});

it('latestSource',async () => {
const wrapper = mount({
components: {'d-auto-complete': DAutoComplete },
Expand Down Expand Up @@ -530,6 +539,7 @@ describe('auto-complete', () => {
expect(wrapper.find('.devui-auto-complete').exists()).toBe(true);
const input = wrapper.find('input');
expect(input.element.value).toBe('');
await input.trigger('click');
await input.setValue('c');
await nextTick();
expect(wrapper.find('.devui-dropdown-menu').exists()).toBe(true);
Expand Down
6 changes: 2 additions & 4 deletions packages/devui-vue/devui/auto-complete/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
import type { App } from 'vue';
import AutoComplete from './src/auto-complete';

AutoComplete.install = function(app: App): void {
app.component(AutoComplete.name, AutoComplete);
};
export * from './src/auto-complete-types';

export { AutoComplete };

Expand All @@ -12,6 +10,6 @@ export default {
category: '数据录入',
status: '100%',
install(app: App): void {
app.use(AutoComplete as any);
app.component(AutoComplete.name, AutoComplete);
}
};
158 changes: 89 additions & 69 deletions packages/devui-vue/devui/auto-complete/src/auto-complete-types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
import type { PropType, ExtractPropTypes, InjectionKey, SetupContext, Ref } from 'vue';
const defaultFormatter = (item: any) => (item ? item.label || item.toString() : '');
const defaultValueParse = (item: any) => item;
export interface SourceItemObj {
label: string;
disabled: boolean;
[propName: string]: unknown;
}
const defaultFormatter = (item: string | SourceItemObj) => {
if(typeof item === 'string'){
return item;
}
return item!==null ? item.label || item.toString() : '';
};
const defaultValueParse = (item: string | SourceItemObj) => item;
export type Placement =
| 'top'
| 'right'
Expand All @@ -14,122 +24,132 @@ export type Placement =
| 'bottom-end'
| 'left-start'
| 'left-end';


export type SourceType = Array<string>| Array<SourceItemObj>;

export const autoCompleteProps = {
modelValue: {
type: String,
default:''
default: ''
},
source:{
type :Array,
default:null
source: {
type : Array as PropType<SourceType>,
default: null
},
allowEmptyValueSearch:{
type:Boolean,
default:false
allowEmptyValueSearch: {
type: Boolean,
default: false
},
position :{
appendToBody:{
type: Boolean,
default: false
},
position : {
type: Array as PropType<Array<Placement>>,
default: ['bottom-end'],
},
disabled:{
type:Boolean,
default:false
disabled: {
type: Boolean,
default: false
},
delay:{
type:Number,
default:300
delay: {
type: Number,
default: 300
},
disabledKey:{
type:String,
default:null
disabledKey: {
type: String,
default: null
},
formatter: {
type:Function as PropType<(item: any) => string>,
default:defaultFormatter
type: Function as PropType<(item: string | SourceItemObj) => string>,
default: defaultFormatter
},
isSearching: {
type:Boolean,
default:false
type: Boolean,
default: false
},
sceneType:{
type:String,
default:null
sceneType: {
type: String,
default: null
},
searchFn:{
type:Function as PropType<(term: string) => Array<any>>,
default:null
searchFn: {
type: Function as PropType<(term: string) => SourceType>,
default: null
},
tipsText:{
type:String,
tipsText: {
type: String,
default:'最近输入'
},
latestSource:{
type:Array,
default:null
latestSource: {
type: Array,
default: null
},
valueParser:{
type:Function as PropType<(item: any) => any>,
default:defaultValueParse
valueParser: {
type: Function as PropType<(item: string | SourceItemObj) => string>,
default: defaultValueParse
},
enableLazyLoad: {
type:Boolean,
default:false
type: Boolean,
default: false
},
width:{
width: {
type: Number,
default:400
default: 400
},
showAnimation:{
type:Boolean,
default:true
showAnimation: {
type: Boolean,
default: true
},
maxHeight:{
type:Number,
default:300
maxHeight: {
type: Number,
default: 300
},
transInputFocusEmit:{
type:Function as PropType<() => void>,
default:null
transInputFocusEmit: {
type: Function as PropType<() => void>,
default: null
},
selectValue:{
type:Function as PropType<(val: any) => any>,
default:null
type: Function as PropType<(val: string) => string>,
default: null
},
loadMore:{
type:Function as PropType<() => void>,
default:null
loadMore: {
type: Function as PropType<() => void>,
default: null
}
} as const;

export type AutoCompleteProps = ExtractPropTypes<typeof autoCompleteProps>;

export interface AutoCompleteRootType {
ctx: SetupContext<any>;
ctx: SetupContext;
props: AutoCompleteProps;
}
export type SearchFnType = (term: string) => Array<any>;
export type FormatterType = (item: any) => string;
export type DefaultFuncType = (arg?: any) => any;
export type HandleSearch = (term?: string | string,enableLazyLoad?: boolean) => void;
export type RecentlyFocus = (latestSource: Array<any>) => void;
export type InputDebounceCb = (...rest: any) => Promise<void>;
export type TransInputFocusEmit = (any?: any) => void;
export type SelectOptionClick = (any?: any) => void;
export type SearchFnType = (term: string) => SourceType;
export type FormatterType = (item: string | SourceItemObj) => string;
export type DefaultFuncType = () => void;
export type HandleSearch = (term: string,enableLazyLoad?: boolean) => void;
export type RecentlyFocus = (latestSource: SourceType) => void;
export type InputDebounceCb = (value: string) => void;
export type TransInputFocusEmit = () => unknown;
export type SelectOptionClick = (item: string | SourceItemObj) => void;
export type SelectValueType = (value: string) => unknown;
// 弹出选择框参数
export type DropdownProps = {
props: AutoCompleteProps;
searchList: Ref<any[]>;
searchList: Ref<SourceType>;
searchStatus?: Ref<boolean>;
showNoResultItemTemplate: Ref<boolean>;
term?: string;
visible: Ref<boolean>;
selectedIndex: Ref<number>;
selectOptionClick: HandleSearch;
dropDownRef: Ref<HTMLUListElement>;
selectOptionClick: SelectOptionClick;
dropDownRef: Ref;
showLoading: Ref<boolean>;
loadMore: (arg?: any) => void;
latestSource: Ref<any[]>;
loadMore: () => void;
latestSource: Ref<Array<SourceItemObj>>;
modelValue: Ref<string>;
hoverIndex: Ref<number>;
valueParser: () => void;
};
export const DropdownPropsKey: InjectionKey<DropdownProps>=Symbol('DropdownPropsKey');
Loading

0 comments on commit c8b438f

Please sign in to comment.