- Change the private key field name from "prvkey" to "prvkey_hex" in the CHAT_INTEGRATION.md file for clarity and consistency with expected data formats. feat: Add Fuzzy Search Component and Composable - Introduce a new FuzzySearch component for Vue 3, leveraging Fuse.js for intelligent search capabilities. - Implement a useFuzzySearch composable for flexible search functionality, allowing configuration of search options. - Create demo and README files to showcase usage and features of the fuzzy search implementation. - Update package.json and package-lock.json to include @vueuse/integrations version 13.6.0 for enhanced performance.
133 lines
No EOL
3.2 KiB
Vue
133 lines
No EOL
3.2 KiB
Vue
<script setup lang="ts">
|
|
import { computed, watch } from 'vue'
|
|
import { useFuzzySearch, type FuzzySearchOptions } from '@/composables/useFuzzySearch'
|
|
import { Input } from '@/components/ui/input'
|
|
import { Button } from '@/components/ui/button'
|
|
import { Search, X } from 'lucide-vue-next'
|
|
|
|
interface Props<T = any> {
|
|
/**
|
|
* The data to search through
|
|
*/
|
|
data: T[]
|
|
/**
|
|
* Configuration options for the fuzzy search
|
|
*/
|
|
options?: FuzzySearchOptions<T>
|
|
/**
|
|
* Placeholder text for the search input
|
|
*/
|
|
placeholder?: string
|
|
/**
|
|
* Whether to show a clear button
|
|
*/
|
|
showClearButton?: boolean
|
|
/**
|
|
* Whether to show the result count
|
|
*/
|
|
showResultCount?: boolean
|
|
/**
|
|
* Custom class for the search container
|
|
*/
|
|
class?: string
|
|
/**
|
|
* Whether the search input should be disabled
|
|
*/
|
|
disabled?: boolean
|
|
}
|
|
|
|
interface Emits<T = any> {
|
|
(e: 'update:modelValue', value: string): void
|
|
(e: 'search', query: string): void
|
|
(e: 'results', results: T[]): void
|
|
(e: 'clear'): void
|
|
}
|
|
|
|
const props = withDefaults(defineProps<Props>(), {
|
|
placeholder: 'Search...',
|
|
showClearButton: true,
|
|
showResultCount: true,
|
|
disabled: false
|
|
})
|
|
|
|
const emit = defineEmits<Emits>()
|
|
|
|
// Create reactive data ref for the composable
|
|
const dataRef = computed(() => props.data)
|
|
|
|
// Use the fuzzy search composable
|
|
const {
|
|
searchQuery,
|
|
results,
|
|
filteredItems,
|
|
isSearching,
|
|
resultCount,
|
|
clearSearch,
|
|
setSearchQuery
|
|
} = useFuzzySearch(dataRef, props.options)
|
|
|
|
// Emit events when search changes
|
|
const handleSearchChange = (value: string | number) => {
|
|
const stringValue = String(value)
|
|
setSearchQuery(stringValue)
|
|
emit('update:modelValue', stringValue)
|
|
emit('search', stringValue)
|
|
emit('results', filteredItems.value)
|
|
}
|
|
|
|
const handleClear = () => {
|
|
clearSearch()
|
|
emit('update:modelValue', '')
|
|
emit('search', '')
|
|
emit('results', filteredItems.value)
|
|
emit('clear')
|
|
}
|
|
|
|
// Watch for changes in filtered items and emit results
|
|
watch(filteredItems, (items) => {
|
|
emit('results', items)
|
|
}, { immediate: true })
|
|
</script>
|
|
|
|
<template>
|
|
<div :class="['fuzzy-search', class]">
|
|
<!-- Search Input -->
|
|
<div class="relative">
|
|
<div class="absolute inset-y-0 left-0 pl-3 flex items-center pointer-events-none">
|
|
<Search class="h-4 w-4 text-muted-foreground" />
|
|
</div>
|
|
|
|
<Input
|
|
:model-value="searchQuery"
|
|
@update:model-value="handleSearchChange"
|
|
:placeholder="placeholder"
|
|
:disabled="disabled"
|
|
class="pl-10 pr-10"
|
|
/>
|
|
|
|
<!-- Clear Button -->
|
|
<div v-if="showClearButton && searchQuery" class="absolute inset-y-0 right-0 pr-3 flex items-center">
|
|
<Button
|
|
variant="ghost"
|
|
size="sm"
|
|
@click="handleClear"
|
|
class="h-6 w-6 p-0 hover:bg-muted"
|
|
>
|
|
<X class="h-3 w-3" />
|
|
<span class="sr-only">Clear search</span>
|
|
</Button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Result Count -->
|
|
<div v-if="showResultCount && isSearching" class="mt-2 text-sm text-muted-foreground">
|
|
{{ resultCount }} result{{ resultCount === 1 ? '' : 's' }} found
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.fuzzy-search {
|
|
@apply w-full;
|
|
}
|
|
</style> |