feat(search-bar): better search back result
This commit is contained in:
		
							parent
							
								
									1b5d4e72bd
								
							
						
					
					
						commit
						71e98e93e5
					
				| @ -1,10 +1,12 @@ | |||||||
| <script lang="ts" setup> | <script lang="ts" setup> | ||||||
| import { useFuzzySearch } from '@/composable/fuzzySearch'; | import { useFuzzySearch } from '@/composable/fuzzySearch'; | ||||||
| import { tools } from '@/tools'; | import { tools } from '@/tools'; | ||||||
|  | import type { ITool } from '@/tools/tool'; | ||||||
| import { SearchRound } from '@vicons/material'; | import { SearchRound } from '@vicons/material'; | ||||||
| import { useMagicKeys, whenever } from '@vueuse/core'; | import { useMagicKeys, whenever } from '@vueuse/core'; | ||||||
| import { computed, ref } from 'vue'; | import { computed, h, ref } from 'vue'; | ||||||
| import { useRouter } from 'vue-router'; | import { useRouter } from 'vue-router'; | ||||||
|  | import SearchBarItem from './SearchBarItem.vue'; | ||||||
| 
 | 
 | ||||||
| const router = useRouter(); | const router = useRouter(); | ||||||
| const queryString = ref(''); | const queryString = ref(''); | ||||||
| @ -15,7 +17,15 @@ const { searchResult } = useFuzzySearch({ | |||||||
|   options: { keys: [{ name: 'name', weight: 2 }, 'description', 'keywords'] }, |   options: { keys: [{ name: 'name', weight: 2 }, 'description', 'keywords'] }, | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| const options = computed(() => searchResult.value.map(({ name, path }) => ({ label: name, value: path }))); | const toolToOption = (tool: ITool) => ({ label: tool.name, value: tool.path, tool }); | ||||||
|  | 
 | ||||||
|  | const options = computed(() => { | ||||||
|  |   if (queryString.value === '') { | ||||||
|  |     return tools.map(toolToOption); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   return searchResult.value.map(toolToOption); | ||||||
|  | }); | ||||||
| 
 | 
 | ||||||
| function onSelect(path: string) { | function onSelect(path: string) { | ||||||
|   router.push(path); |   router.push(path); | ||||||
| @ -36,6 +46,10 @@ const keys = useMagicKeys({ | |||||||
| whenever(keys.ctrl_k, () => { | whenever(keys.ctrl_k, () => { | ||||||
|   focusTarget.value.focus(); |   focusTarget.value.focus(); | ||||||
| }); | }); | ||||||
|  | 
 | ||||||
|  | function renderOption({ tool }: { tool: ITool }) { | ||||||
|  |   return h(SearchBarItem, { tool }); | ||||||
|  | } | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <template> | <template> | ||||||
| @ -43,8 +57,10 @@ whenever(keys.ctrl_k, () => { | |||||||
|     <n-auto-complete |     <n-auto-complete | ||||||
|       v-model:value="queryString" |       v-model:value="queryString" | ||||||
|       :options="options" |       :options="options" | ||||||
|       :input-props="{ autocomplete: 'disabled' }" |  | ||||||
|       :on-select="(value) => onSelect(String(value))" |       :on-select="(value) => onSelect(String(value))" | ||||||
|  |       :render-label="renderOption" | ||||||
|  |       :default-value="'aa'" | ||||||
|  |       :get-show="() => true" | ||||||
|     > |     > | ||||||
|       <template #default="{ handleInput, handleBlur, handleFocus, value: slotValue }"> |       <template #default="{ handleInput, handleBlur, handleFocus, value: slotValue }"> | ||||||
|         <n-input |         <n-input | ||||||
| @ -53,6 +69,7 @@ whenever(keys.ctrl_k, () => { | |||||||
|           clearable |           clearable | ||||||
|           placeholder="Search a tool... [Ctrl + K]" |           placeholder="Search a tool... [Ctrl + K]" | ||||||
|           :value="slotValue" |           :value="slotValue" | ||||||
|  |           :input-props="{ autocomplete: 'disabled' }" | ||||||
|           @input="handleInput" |           @input="handleInput" | ||||||
|           @focus="handleFocus" |           @focus="handleFocus" | ||||||
|           @blur="handleBlur" |           @blur="handleBlur" | ||||||
| @ -66,8 +83,4 @@ whenever(keys.ctrl_k, () => { | |||||||
|   </div> |   </div> | ||||||
| </template> | </template> | ||||||
| 
 | 
 | ||||||
| <style lang="less" scoped> | <style lang="less" scoped></style> | ||||||
| // ::v-deep(.n-input__border) { |  | ||||||
| //     border: none; |  | ||||||
| // } |  | ||||||
| </style> |  | ||||||
|  | |||||||
							
								
								
									
										45
									
								
								src/components/SearchBarItem.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								src/components/SearchBarItem.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,45 @@ | |||||||
|  | <script lang="ts" setup> | ||||||
|  | import type { ITool } from '@/tools/tool'; | ||||||
|  | import { toRefs } from 'vue'; | ||||||
|  | 
 | ||||||
|  | const props = defineProps<{ tool: ITool }>(); | ||||||
|  | const { tool } = toRefs(props); | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |   <div class="search-bar-item"> | ||||||
|  |     <n-icon class="icon" :component="tool.icon" /> | ||||||
|  | 
 | ||||||
|  |     <div> | ||||||
|  |       <div class="name">{{ tool.name }}</div> | ||||||
|  |       <div class="description">{{ tool.description }}</div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style lang="less" scoped> | ||||||
|  | .search-bar-item { | ||||||
|  |   padding: 10px; | ||||||
|  |   display: flex; | ||||||
|  |   flex-direction: row; | ||||||
|  |   align-items: center; | ||||||
|  | 
 | ||||||
|  |   .icon { | ||||||
|  |     font-size: 30px; | ||||||
|  |     margin-right: 10px; | ||||||
|  |     opacity: 0.7; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .name { | ||||||
|  |     font-weight: bold; | ||||||
|  |     font-size: 15px; | ||||||
|  |     line-height: 1; | ||||||
|  |     margin-bottom: 5px; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   .description { | ||||||
|  |     opacity: 0.7; | ||||||
|  |     line-height: 1; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | </style> | ||||||
| @ -6,6 +6,12 @@ export const lightThemeOverrides: GlobalThemeOverrides = { | |||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   Layout: { color: '#f1f5f9' }, |   Layout: { color: '#f1f5f9' }, | ||||||
|  | 
 | ||||||
|  |   AutoComplete: { | ||||||
|  |     peers: { | ||||||
|  |       InternalSelectMenu: { height: '500px' }, | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export const darkThemeOverrides: GlobalThemeOverrides = { | export const darkThemeOverrides: GlobalThemeOverrides = { | ||||||
| @ -16,6 +22,12 @@ export const darkThemeOverrides: GlobalThemeOverrides = { | |||||||
|     primaryColorSuppl: '#36AD6AFF', |     primaryColorSuppl: '#36AD6AFF', | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|  |   AutoComplete: { | ||||||
|  |     peers: { | ||||||
|  |       InternalSelectMenu: { height: '500px', color: '#1e1e1e' }, | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|   Menu: { |   Menu: { | ||||||
|     itemHeight: '32px', |     itemHeight: '32px', | ||||||
|   }, |   }, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user