1
1
<template >
2
2
<div style =" display : inline-flex ;" >
3
- <Input size =" small" :width =" 150" :placeholder =" $t(`main_search_placeholder`)" v-model =" input" @load =" load" >
3
+ <Input
4
+ size =" small"
5
+ :width =" 150"
6
+ :placeholder =" $t(`main_search_placeholder`)"
7
+ v-model =" input"
8
+ @load =" load"
9
+ @keyup.enter =" keyupEnter"
10
+ @keyup.up =" keyupUp"
11
+ @keyup.down =" keyupDown"
12
+ @keyup.esc =" close"
13
+ >
4
14
<template #suffix >
5
15
<Icon name =" search" :size =" 12" />
6
16
</template >
7
17
</Input >
8
18
<ul class =" ctool-search-block" v-if =" isInput" ref =" container" >
9
- <li v-for =" item in items" @click =" click(item.tool,item.feature)" :key =" `${item.tool}-${item.feature}`" >{{ item.label }}</li >
19
+ <li
20
+ v-for =" (item,index) in items"
21
+ :class =" index === selectIndex ? `ctool-search-active` : ''"
22
+ @click =" select(index)"
23
+ :key =" `${item.tool}-${item.feature}`"
24
+ @mouseover =" selectIndex = index"
25
+ >{{ item.label }}
26
+ </li >
10
27
</ul >
11
28
</div >
12
29
</template >
@@ -15,40 +32,15 @@ import {toolKeywords} from "@/buildDataTemp";
15
32
import {getTool , FeatureInterface } from " @/config" ;
16
33
import useOperate from " @/store/operate" ;
17
34
import useSetting from " @/store/setting" ;
35
+ import {watch } from " vue" ;
18
36
19
37
const setting = useSetting ()
20
38
const operate = useOperate ()
21
39
let container = $ref <HTMLElement | null >(null );
22
40
let input = $ref (" " )
23
41
let inputElement = $ref <HTMLInputElement | null >(null );
24
42
let isInput = $ref (false );
25
-
26
- const load = (element : HTMLInputElement ) => {
27
- inputElement = element
28
- element .addEventListener (" focus" , () => {
29
- isInput = true
30
- });
31
- document .addEventListener (" click" , (e : MouseEvent ) => {
32
- if (
33
- element .contains (e .target as any )
34
- || container ?.contains (e .target as any )
35
- ) {
36
- return ;
37
- }
38
- isInput = false
39
- });
40
- }
41
-
42
- const click = (tool , feature ) => {
43
- const keyword = input
44
- input = " "
45
- if (tool === " " ) {
46
- return ;
47
- }
48
- operate .redirectTool (tool , feature ,' ' ,' ' ,keyword )
49
- inputElement ?.blur ()
50
- isInput = false
51
- }
43
+ let selectIndex = $ref (0 )
52
44
53
45
const items = $computed (() => {
54
46
let lists: FeatureInterface []
@@ -63,7 +55,7 @@ const items = $computed(() => {
63
55
]
64
56
)
65
57
)
66
- ]. slice ( 0 , 10 )
58
+ ]
67
59
} else {
68
60
lists = toolKeywords .filter ((item ) => item .search .join (" ," ).includes (input .toLowerCase ())).map (item => {
69
61
return getTool (item .name ).getFeature (item .feature )
@@ -72,7 +64,7 @@ const items = $computed(() => {
72
64
if (lists .length === 0 ) {
73
65
return [{label: $t (` main_ui_null ` ), tool: " " , feature: " " }]
74
66
}
75
- return lists .map (feature => {
67
+ return lists .slice ( 0 , 15 ). map (feature => {
76
68
const tool = feature .tool
77
69
return {
78
70
label: ` ${$t (` tool_${tool .name } ` )}${tool .isSimple () ? ` ` : ` - ${$t (` tool_${tool .name }_${feature .name } ` )} ` } ` ,
@@ -81,6 +73,62 @@ const items = $computed(() => {
81
73
}
82
74
})
83
75
})
76
+
77
+ const open = () => {
78
+ isInput = true
79
+ selectIndex = 0
80
+ }
81
+
82
+ const close = () => {
83
+ input = " "
84
+ isInput = false
85
+ selectIndex = 0
86
+ }
87
+
88
+ const load = (element : HTMLInputElement ) => {
89
+ inputElement = element
90
+ element .addEventListener (" focus" , () => open ());
91
+ document .addEventListener (" click" , (e : MouseEvent ) => {
92
+ if (
93
+ element .contains (e .target as any )
94
+ || container ?.contains (e .target as any )
95
+ ) {
96
+ return ;
97
+ }
98
+ close ()
99
+ });
100
+ }
101
+
102
+ const select = (index : number ) => {
103
+ if (items .length === 0 || items .length - 1 < index ) {
104
+ return ;
105
+ }
106
+ const {tool, feature} = items [index ]
107
+ const keyword = input
108
+ if (tool !== " " ) {
109
+ operate .redirectTool (tool , feature , ' ' , ' ' , keyword )
110
+ }
111
+ inputElement ?.blur ();
112
+ close ();
113
+ }
114
+
115
+ const keyupEnter = () => {
116
+ select (selectIndex )
117
+ }
118
+ const keyupUp = () => {
119
+ if (items .length === 0 ) {
120
+ return ;
121
+ }
122
+ selectIndex = selectIndex === 0 ? items .length - 1 : selectIndex - 1
123
+ }
124
+ const keyupDown = () => {
125
+ if (items .length === 0 ) {
126
+ return ;
127
+ }
128
+ selectIndex = selectIndex === items .length - 1 ? 0 : selectIndex + 1
129
+ }
130
+
131
+ watch (() => input , () => selectIndex = 0 , {immediate: true })
84
132
</script >
85
133
86
134
<style >
@@ -90,8 +138,6 @@ const items = $computed(() => {
90
138
top : 28px ;
91
139
font-size : .875rem ;
92
140
width : 165px ;
93
- max-height : 15rem ;;
94
- overflow-y : auto ;
95
141
display : flex ;
96
142
flex-direction : column ;
97
143
border : var (--border-width ) solid var (--dropdown-border-color );
@@ -101,19 +147,21 @@ const items = $computed(() => {
101
147
color : var (--dropdown-color );
102
148
white-space : nowrap ;
103
149
font-style : normal ;
150
+ margin-bottom : 0px ;
104
151
padding : 5px 0 0 ;
105
152
}
106
153
107
154
.ctool-search-block li {
108
155
cursor : pointer ;
156
+ list-style : none ;
109
157
width : 100% ;
110
158
color : var (--dropdown-color );
111
159
padding-left : 10px ;
112
- line-height : 2 rem ;
160
+ line-height : 1.9 rem ;
113
161
margin-bottom : 0 ;
114
162
}
115
163
116
- .ctool-search-block li :hover {
164
+ .ctool-search-block li .ctool-search-active {
117
165
background-color : var (--dropdown-hover-background-color );
118
166
}
119
167
</style >
0 commit comments