-
Notifications
You must be signed in to change notification settings - Fork 290
/
Copy pathuse-input-handle.ts
95 lines (95 loc) · 2.42 KB
/
use-input-handle.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import { ref, Ref, SetupContext } from 'vue';
import {
HandleSearch,
RecentlyFocus,
InputDebounceCb,
TransInputFocusEmit,
SourceType,
SourceItemObj,
UseInputHandle,
} from '../auto-complete-types';
export default function useInputHandle(
ctx: SetupContext,
searchList: Ref<SourceType>,
showNoResultItemTemplate: Ref<boolean>,
modelValue: Ref<string>,
isDisabled: Ref<boolean>,
delay: Ref<number>,
handleSearch: HandleSearch,
transInputFocusEmit: Ref<TransInputFocusEmit>,
recentlyFocus: RecentlyFocus,
latestSource: Ref<Array<SourceItemObj>>
): UseInputHandle {
const visible = ref(false);
const inputRef = ref();
const searchStatus = ref(false);
const isFocus = ref(false);
const debounce = (cb: InputDebounceCb, time: number) => {
let timer: NodeJS.Timeout | null;
return (arg: string) => {
if (timer) {
clearTimeout(timer);
}
timer = setTimeout(async () => {
searchStatus.value = true;
await cb(arg);
searchStatus.value = false;
}, time);
};
};
const onInputCb = async (value: string) => {
await handleSearch(value);
visible.value = true;
};
const onInputDebounce = debounce(onInputCb, delay.value);
const onInput = (e: Event) => {
const inp = e.target as HTMLInputElement;
searchStatus.value = false;
showNoResultItemTemplate.value = false;
ctx.emit('update:modelValue', inp.value);
onInputDebounce(inp.value);
};
const onFocus = () => {
isFocus.value = true;
handleSearch(modelValue.value);
recentlyFocus(latestSource?.value);
transInputFocusEmit.value && transInputFocusEmit.value();
};
const onBlur = () => {
isFocus.value = false;
ctx.emit('blur');
};
const onClear = () => {
ctx.emit('update:modelValue', '');
ctx.emit('clear');
};
const handleClose = () => {
visible.value = false;
searchStatus.value = false;
showNoResultItemTemplate.value = false;
};
const toggleMenu = () => {
if (!isDisabled.value) {
if (visible.value) {
handleClose();
} else {
visible.value = true;
if (ctx.slots.noResultItemTemplate && searchList.value.length === 0 && modelValue.value.trim() !== '') {
showNoResultItemTemplate.value = true;
}
}
}
};
return {
handleClose,
toggleMenu,
onInput,
onFocus,
onBlur,
onClear,
isFocus,
inputRef,
visible,
searchStatus,
};
}