# 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
<script setup lang="ts">
import { ref } from 'vue'
import { useFuzzySearch } from '@/composables/useFuzzySearch'

interface Product {
  id: number
  name: string
  description: string
  category: string
}

const products = ref<Product[]>([
  { id: 1, name: 'Laptop', description: 'High-performance laptop', category: 'Electronics' },
  { id: 2, name: 'Smartphone', description: 'Latest smartphone', category: 'Electronics' },
  // ... more products
])

const { searchQuery, filteredItems, isSearching, resultCount, clearSearch } = useFuzzySearch(
  products,
  {
    fuseOptions: {
      keys: ['name', 'description', 'category'],
      threshold: 0.3,
    },
    resultLimit: 10,
    minSearchLength: 2,
  }
)
</script>

<template>
  <div>
    <input v-model="searchQuery" placeholder="Search products..." />
    <p>Found {{ resultCount }} results</p>
    
    <div v-for="product in filteredItems" :key="product.id">
      {{ product.name }}
    </div>
  </div>
</template>
```

### Using the Component

```vue
<script setup lang="ts">
import { ref } from 'vue'
import { FuzzySearch } from '@/components/ui/fuzzy-search'

interface Product {
  id: number
  name: string
  description: string
}

const products = ref<Product[]>([
  { id: 1, name: 'Laptop', description: 'High-performance laptop' },
  { id: 2, name: 'Smartphone', description: 'Latest smartphone' },
])

const handleSearchResults = (results: Product[]) => {
  console.log('Search results:', results)
}
</script>

<template>
  <FuzzySearch
    :data="products"
    :options="{
      fuseOptions: {
        keys: ['name', 'description'],
        threshold: 0.3,
      },
      resultLimit: 10,
    }"
    placeholder="Search products..."
    @results="handleSearchResults"
  />
</template>
```

## API Reference

### `useFuzzySearch` Composable

#### Parameters

- `data: Ref<T[]> | T[]` - The data to search through
- `options?: FuzzySearchOptions<T>` - Configuration options

#### Returns

- `searchQuery: Ref<string>` - Current search query
- `results: ComputedRef<FuseResult<T>[]>` - Search results with scoring
- `filteredItems: ComputedRef<T[]>` - Filtered items (just the items)
- `isSearching: ComputedRef<boolean>` - Whether search is active
- `resultCount: ComputedRef<number>` - 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<T>` - 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<T = any> {
  /**
   * Fuse.js options for configuring the search behavior
   */
  fuseOptions?: FuseOptions<T>
  /**
   * 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. 