fix: Update private key field in chat integration documentation

- 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.
This commit is contained in:
padreug 2025-08-08 14:17:11 +02:00
parent 37a539bc2d
commit 3d1bc94183
8 changed files with 783 additions and 1 deletions

View file

@ -0,0 +1,133 @@
<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>