feat: search-bar
This commit is contained in:
		
							parent
							
								
									bab92ef84f
								
							
						
					
					
						commit
						e8594de7b4
					
				
							
								
								
									
										1
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -13,6 +13,7 @@ | |||||||
|         "@vueuse/core": "^8.2.1", |         "@vueuse/core": "^8.2.1", | ||||||
|         "@vueuse/head": "^0.7.5", |         "@vueuse/head": "^0.7.5", | ||||||
|         "crypto-js": "^4.1.1", |         "crypto-js": "^4.1.1", | ||||||
|  |         "lodash": "^4.17.21", | ||||||
|         "naive-ui": "^2.27.0", |         "naive-ui": "^2.27.0", | ||||||
|         "pinia": "^2.0.11", |         "pinia": "^2.0.11", | ||||||
|         "randombytes": "^2.1.0", |         "randombytes": "^2.1.0", | ||||||
|  | |||||||
| @ -19,6 +19,7 @@ | |||||||
|     "@vueuse/core": "^8.2.1", |     "@vueuse/core": "^8.2.1", | ||||||
|     "@vueuse/head": "^0.7.5", |     "@vueuse/head": "^0.7.5", | ||||||
|     "crypto-js": "^4.1.1", |     "crypto-js": "^4.1.1", | ||||||
|  |     "lodash": "^4.17.21", | ||||||
|     "naive-ui": "^2.27.0", |     "naive-ui": "^2.27.0", | ||||||
|     "pinia": "^2.0.11", |     "pinia": "^2.0.11", | ||||||
|     "randombytes": "^2.1.0", |     "randombytes": "^2.1.0", | ||||||
|  | |||||||
							
								
								
									
										57
									
								
								src/components/SearchBar.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/components/SearchBar.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,57 @@ | |||||||
|  | <script lang="ts" setup> | ||||||
|  | import { SearchRound } from '@vicons/material' | ||||||
|  | import { computed, ref } from 'vue'; | ||||||
|  | import { deburr } from 'lodash' | ||||||
|  | import { tools } from '@/tools'; | ||||||
|  | import { useRouter } from 'vue-router'; | ||||||
|  | 
 | ||||||
|  | const router = useRouter() | ||||||
|  | const queryString = ref('') | ||||||
|  | 
 | ||||||
|  | const cleanString = (s: string) => deburr(s.trim().toLowerCase()) | ||||||
|  | 
 | ||||||
|  | const searchableTools = tools.map(({ name, description, keywords, path }) => ({ | ||||||
|  |     searchableText: [name, description, ...keywords].map(cleanString).join(' '), | ||||||
|  |     path, | ||||||
|  |     name | ||||||
|  | })) | ||||||
|  | 
 | ||||||
|  | const options = computed(() => { | ||||||
|  |     const query = cleanString(queryString.value) | ||||||
|  | 
 | ||||||
|  |     return searchableTools | ||||||
|  |         .filter(({ searchableText }) => searchableText.includes(query)) | ||||||
|  |         .map(({ name, path }) => ({ label: name, value: path })) | ||||||
|  | }) | ||||||
|  | 
 | ||||||
|  | function onSelect(path: string) { | ||||||
|  |     router.push(path) | ||||||
|  |     queryString.value = '' | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |     <div> | ||||||
|  |         <n-auto-complete | ||||||
|  |             placeholder="Search a tool..." | ||||||
|  |             :options="options" | ||||||
|  |             v-model:value="queryString" | ||||||
|  |             :input-props="{ autocomplete: 'disabled' }" | ||||||
|  |             :on-select="onSelect" | ||||||
|  |         > | ||||||
|  |             <template #prefix> | ||||||
|  |                 <n-icon> | ||||||
|  |                     <search-round /> | ||||||
|  |                 </n-icon> | ||||||
|  |             </template> | ||||||
|  |         </n-auto-complete> | ||||||
|  |     </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | <style lang="less" scoped> | ||||||
|  | // ::v-deep(.n-input__border) { | ||||||
|  | //     border: none; | ||||||
|  | // } | ||||||
|  | </style> | ||||||
| @ -4,6 +4,7 @@ import { h, ref, type Component } from 'vue'; | |||||||
| import { RouterLink, useRoute } from 'vue-router'; | import { RouterLink, useRoute } from 'vue-router'; | ||||||
| import { User } from '@vicons/tabler' | import { User } from '@vicons/tabler' | ||||||
| import { tools } from '@/tools'; | import { tools } from '@/tools'; | ||||||
|  | import SearchBar from '../components/SearchBar.vue'; | ||||||
| 
 | 
 | ||||||
| const collapsed = ref(false) | const collapsed = ref(false) | ||||||
| const activeKey = ref(null) | const activeKey = ref(null) | ||||||
| @ -50,7 +51,8 @@ const menuOptions = tools.map(({ name, path, icon }) => ({ | |||||||
|         </n-layout-sider> |         </n-layout-sider> | ||||||
|         <n-layout class="content"> |         <n-layout class="content"> | ||||||
|             <div class="bar-wrapper"> |             <div class="bar-wrapper"> | ||||||
|                 <n-input /> |                 <search-bar /> | ||||||
|  | 
 | ||||||
|                 <n-button secondary circle> |                 <n-button secondary circle> | ||||||
|                     <n-icon size="large"> |                     <n-icon size="large"> | ||||||
|                         <user /> |                         <user /> | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user