+
\ No newline at end of file
diff --git a/src/components/ui/fuzzy-search/README.md b/src/components/ui/fuzzy-search/README.md
new file mode 100644
index 0000000..112c555
--- /dev/null
+++ b/src/components/ui/fuzzy-search/README.md
@@ -0,0 +1,236 @@
+# Fuzzy Search Component
+
+A powerful fuzzy search implementation for Vue 3 using Fuse.js and VueUse integrations.
+
+## Features
+
+- 🔍 **Fuzzy Search**: Intelligent search with typo tolerance and scoring
+- ⚡ **VueUse Integration**: Built on top of `@vueuse/integrations` for optimal performance
+- 🎯 **Configurable**: Customizable search options and behavior
+- 🎨 **Vue 3 Compatible**: Built with Vue 3 Composition API and TypeScript
+- 📦 **Reusable**: Both composable and component versions available
+
+## Installation
+
+The fuzzy search functionality is already installed and available in this project. It uses:
+
+- `fuse.js` - For fuzzy search algorithms
+- `@vueuse/integrations` - For Vue 3 integration
+
+## Usage
+
+### Using the Composable
+
+```vue
+
+
+
+
+
+
Found {{ resultCount }} results
+
+
+ {{ product.name }}
+
+
+
+```
+
+### Using the Component
+
+```vue
+
+
+
+
+
+```
+
+## API Reference
+
+### `useFuzzySearch` Composable
+
+#### Parameters
+
+- `data: Ref | T[]` - The data to search through
+- `options?: FuzzySearchOptions` - Configuration options
+
+#### Returns
+
+- `searchQuery: Ref` - Current search query
+- `results: ComputedRef[]>` - Search results with scoring
+- `filteredItems: ComputedRef` - Filtered items (just the items)
+- `isSearching: ComputedRef` - Whether search is active
+- `resultCount: ComputedRef` - Number of results found
+- `clearSearch: () => void` - Clear the current search
+- `setSearchQuery: (query: string) => void` - Set the search query
+- `updateData: (data: T[]) => void` - Update the data to search through
+
+### `FuzzySearch` Component
+
+#### Props
+
+- `data: T[]` - The data to search through
+- `options?: FuzzySearchOptions` - Configuration options
+- `placeholder?: string` - Placeholder text for the search input
+- `showClearButton?: boolean` - Whether to show a clear button
+- `showResultCount?: boolean` - Whether to show the result count
+- `class?: string` - Custom class for the search container
+- `disabled?: boolean` - Whether the search input should be disabled
+
+#### Events
+
+- `update:modelValue` - Emitted when the search query changes
+- `search` - Emitted when a search is performed
+- `results` - Emitted when search results change
+- `clear` - Emitted when the search is cleared
+
+### `FuzzySearchOptions`
+
+```typescript
+interface FuzzySearchOptions {
+ /**
+ * Fuse.js options for configuring the search behavior
+ */
+ fuseOptions?: FuseOptions
+ /**
+ * Maximum number of results to return
+ */
+ resultLimit?: number
+ /**
+ * Whether to return all items when search is empty
+ */
+ matchAllWhenSearchEmpty?: boolean
+ /**
+ * Debounce delay in milliseconds for search input
+ */
+ debounceMs?: number
+ /**
+ * Minimum search length before triggering search
+ */
+ minSearchLength?: number
+}
+```
+
+## Configuration Examples
+
+### Basic Search
+
+```typescript
+const options = {
+ fuseOptions: {
+ keys: ['name', 'description'],
+ threshold: 0.3,
+ },
+}
+```
+
+### Advanced Search
+
+```typescript
+const options = {
+ fuseOptions: {
+ keys: [
+ { name: 'name', weight: 0.7 },
+ { name: 'description', weight: 0.3 },
+ { name: 'category', weight: 0.2 },
+ ],
+ threshold: 0.2,
+ distance: 100,
+ ignoreLocation: true,
+ useExtendedSearch: false,
+ minMatchCharLength: 2,
+ shouldSort: true,
+ findAllMatches: false,
+ location: 0,
+ isCaseSensitive: false,
+ },
+ resultLimit: 20,
+ matchAllWhenSearchEmpty: true,
+ minSearchLength: 2,
+}
+```
+
+### Search with Weighted Keys
+
+```typescript
+const options = {
+ fuseOptions: {
+ keys: [
+ { name: 'title', weight: 0.8 },
+ { name: 'content', weight: 0.5 },
+ { name: 'tags', weight: 0.3 },
+ ],
+ threshold: 0.4,
+ },
+}
+```
+
+## Performance Tips
+
+1. **Use `resultLimit`** to limit the number of results for better performance
+2. **Set appropriate `threshold`** values (0.0 = perfect match, 1.0 = match anything)
+3. **Use weighted keys** to prioritize certain fields
+4. **Consider `minSearchLength`** to avoid searching on very short queries
+5. **Use `ignoreLocation: true`** for better performance when location doesn't matter
+
+## Examples
+
+See `FuzzySearchDemo.vue` for a complete example of how to use the fuzzy search functionality.
\ No newline at end of file
diff --git a/src/components/ui/fuzzy-search/index.ts b/src/components/ui/fuzzy-search/index.ts
new file mode 100644
index 0000000..7e3dd40
--- /dev/null
+++ b/src/components/ui/fuzzy-search/index.ts
@@ -0,0 +1,2 @@
+export { default as FuzzySearch } from './FuzzySearch.vue'
+export { useFuzzySearch, type FuzzySearchOptions, type UseFuzzySearchReturn } from '@/composables/useFuzzySearch'
\ No newline at end of file
diff --git a/src/composables/useFuzzySearch.ts b/src/composables/useFuzzySearch.ts
new file mode 100644
index 0000000..203af5c
--- /dev/null
+++ b/src/composables/useFuzzySearch.ts
@@ -0,0 +1,183 @@
+import { ref, computed, type Ref, type ComputedRef } from 'vue'
+import { useFuse, type UseFuseOptions, type FuseOptions } from '@vueuse/integrations'
+import type { FuseResult } from 'fuse.js'
+
+export interface FuzzySearchOptions {
+ /**
+ * Fuse.js options for configuring the search behavior
+ */
+ fuseOptions?: FuseOptions
+ /**
+ * Maximum number of results to return
+ */
+ resultLimit?: number
+ /**
+ * Whether to return all items when search is empty
+ */
+ matchAllWhenSearchEmpty?: boolean
+ /**
+ * Debounce delay in milliseconds for search input
+ */
+ debounceMs?: number
+ /**
+ * Minimum search length before triggering search
+ */
+ minSearchLength?: number
+}
+
+export interface UseFuzzySearchReturn {
+ /**
+ * Current search query
+ */
+ searchQuery: Ref
+ /**
+ * Search results with Fuse.js scoring
+ */
+ results: ComputedRef[]>
+ /**
+ * Filtered items (just the items without scoring)
+ */
+ filteredItems: ComputedRef
+ /**
+ * Whether search is currently active
+ */
+ isSearching: ComputedRef
+ /**
+ * Number of results found
+ */
+ resultCount: ComputedRef
+ /**
+ * Clear the current search
+ */
+ clearSearch: () => void
+ /**
+ * Set the search query
+ */
+ setSearchQuery: (query: string) => void
+ /**
+ * Update the data to search through
+ */
+ updateData: (data: T[]) => void
+}
+
+/**
+ * Composable for fuzzy search functionality using Fuse.js
+ *
+ * @param data - The data to search through
+ * @param options - Configuration options for the fuzzy search
+ * @returns Object with search functionality and results
+ *
+ * @example
+ * ```ts
+ * // Basic usage
+ * const { searchQuery, results, filteredItems, clearSearch } = useFuzzySearch(
+ * products,
+ * {
+ * fuseOptions: {
+ * keys: ['name', 'description'],
+ * threshold: 0.3
+ * },
+ * resultLimit: 10,
+ * minSearchLength: 2
+ * }
+ * )
+ *
+ * // Integration with existing market functionality
+ * const { searchQuery, filteredItems } = useFuzzySearch(
+ * marketStore.products,
+ * {
+ * fuseOptions: {
+ * keys: [
+ * { name: 'name', weight: 0.7 },
+ * { name: 'description', weight: 0.3 },
+ * { name: 'stallName', weight: 0.2 },
+ * { name: 'categories', weight: 0.1 }
+ * ],
+ * threshold: 0.3,
+ * ignoreLocation: true
+ * },
+ * resultLimit: 50,
+ * minSearchLength: 2
+ * }
+ * )
+ * ```
+ */
+export function useFuzzySearch(
+ data: Ref | T[],
+ options: FuzzySearchOptions = {}
+): UseFuzzySearchReturn {
+ const {
+ fuseOptions = {
+ // Default Fuse.js options
+ threshold: 0.3,
+ distance: 100,
+ ignoreLocation: true,
+ useExtendedSearch: false,
+ minMatchCharLength: 1,
+ shouldSort: true,
+ findAllMatches: false,
+ location: 0,
+ isCaseSensitive: false,
+ keys: []
+ },
+ resultLimit,
+ matchAllWhenSearchEmpty = true,
+ debounceMs = 300,
+ minSearchLength = 0
+ } = options
+
+ // Search query state
+ const searchQuery = ref('')
+
+ // Create the Fuse instance using VueUse integration
+ const { results } = useFuse(
+ searchQuery,
+ data,
+ {
+ fuseOptions,
+ resultLimit,
+ matchAllWhenSearchEmpty
+ }
+ )
+
+ // Computed properties
+ const isSearching = computed(() => {
+ const query = searchQuery.value.trim()
+ return query.length >= minSearchLength
+ })
+
+ const filteredItems = computed(() => {
+ return results.value.map(result => result.item)
+ })
+
+ const resultCount = computed(() => results.value.length)
+
+ // Methods
+ const clearSearch = () => {
+ searchQuery.value = ''
+ }
+
+ const setSearchQuery = (query: string) => {
+ searchQuery.value = query
+ }
+
+ const updateData = (newData: T[]) => {
+ // The useFuse composable automatically watches for data changes
+ // so we just need to update the ref if it's reactive
+ if (Array.isArray(data)) {
+ // If data is not reactive, we need to handle this differently
+ console.warn('Data is not reactive. Consider using ref() for the data parameter.')
+ }
+ }
+
+ return {
+ searchQuery,
+ results,
+ filteredItems,
+ isSearching,
+ resultCount,
+ clearSearch,
+ setSearchQuery,
+ updateData
+ }
+}
\ No newline at end of file