summaryrefslogtreecommitdiffstats
path: root/src/components/searcher/Searcher.vue
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/searcher/Searcher.vue')
-rw-r--r--src/components/searcher/Searcher.vue157
1 files changed, 157 insertions, 0 deletions
diff --git a/src/components/searcher/Searcher.vue b/src/components/searcher/Searcher.vue
new file mode 100644
index 0000000..f8dd51f
--- /dev/null
+++ b/src/components/searcher/Searcher.vue
@@ -0,0 +1,157 @@
1<template>
2 <div id="searcher">
3 <input
4 type="text"
5 v-model='search'
6 ref='input'
7 @keydown="hotkeys"
8 @blur="close()"
9 placeholder="Search!"
10 />
11
12 <Sugestion
13 v-for="sugestion in sugestions"
14 :key="sugestion[0]"
15 :sugestion="sugestion"
16 :class="{selected: sugestion[0] === current[0]}"
17 />
18 </div>
19</template>
20
21<script>
22import CommandsService from '@/services/CommandsService'
23import Sugestion from '@/components/searcher/Sugestion.vue'
24
25export default {
26 data() {
27 return {
28 commands: CommandsService,
29 search: '',
30 sugestions: [],
31 current: []
32 }
33 },
34
35 methods: {
36 set_sugestions() {
37 const sugestions = []
38 let is_current_set = false
39
40 Object.entries(this.commands).forEach((element) => {
41 if(element[0].startsWith(this.search) && element[1] instanceof Function) {
42 sugestions.push(element)
43 if(!is_current_set){
44 this.current = element
45 is_current_set = true;
46 }
47 }
48 });
49 this.sugestions = sugestions
50 },
51
52 close() {
53 this.$emit('close')
54 },
55
56 change_current(a=1) {
57 let index = this.sugestions.findIndex(element => element===this.current)
58 let new_current = this.sugestions[index+a]
59
60 if (new_current) this.current = new_current
61 else this.current = this.sugestions[0]
62 },
63
64 async execute_current() {
65 let out = await this.current[1](this)
66
67 if(out instanceof Object) {
68 this.search = ''
69 this.commands = out
70 }
71 },
72
73 hotkeys(e) {
74 switch(e.code) {
75 case 'Escape':
76 e.preventDefault()
77 this.close()
78 break
79 case 'ArrowDown':
80 e.preventDefault()
81 this.change_current(1)
82 break
83 case 'ArrowUp':
84 e.preventDefault()
85 this.change_current(-1)
86 break
87 case 'Tab':
88 e.preventDefault()
89 this.change_current(1)
90 break
91 case 'Enter':
92 e.preventDefault()
93 this.execute_current()
94 break
95 case 'ShiftLeft':
96 e.preventDefault()
97 this.commands = CommandsService
98 break
99 }
100 },
101 },
102
103 watch: {
104 search() {
105 this.set_sugestions()
106 },
107
108 commands() {
109 this.set_sugestions()
110 }
111 },
112
113 computed: {
114
115 },
116
117 components: {
118 Sugestion
119 },
120
121 created() {
122 this.set_sugestions()
123
124 this.$nextTick(function () {
125 this.$refs.input.focus()
126 })
127 }
128}
129</script>
130
131<style scoped>
132 #searcher {
133 position: absolute;
134 width: 30%;
135 height: 80%;
136 top: 50%;
137 left: 50%;
138 background-color: #202020;
139 padding: 20px;
140 border-radius: 10px;
141 transform: translate(-50%, -50%);
142 }
143
144 #searcher input {
145 width: 100%;
146 margin-bottom: 20px;
147 padding: 10px;
148 padding-right: 0px;
149 height: 20px;
150 border: none;
151 background-color: #303030;
152 }
153
154 .selected {
155 background-color: #505050;
156 }
157</style>