# SearchBox

A specialized text input component designed for search functionality with a built-in search icon and optimized input handling. Features composition event handling for international text input and clear functionality.

## Installation

```bash
npm install @ticatec/uniface-element
```

## Import

```typescript
import SearchBox from "@ticatec/uniface-element/SearchBox";
```

## Basic Usage

```svelte
<script>
  import SearchBox from "@ticatec/uniface-element/SearchBox";
  
  let searchQuery = '';
  
  function handleSearch(query) {
    console.log('Searching for:', query);
  }
</script>

<SearchBox 
  bind:value={searchQuery} 
  onchange={handleSearch}
  placeholder="Search..."
/>
```

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `value` | `string \| null` | Required | Current search input value |
| `onchange` | `OnChangeHandler<string \| null>` | `null` | Callback when input value changes (on blur/enter) |
| `oninput` | `OnChangeHandler<string \| null>` | `null` | Callback when input value changes (real-time) |
| `onfocus` | `((event: FocusEvent) => void) \| null` | `null` | Callback when input gains focus |
| `onblur` | `((event: FocusEvent) => void) \| null` | `null` | Callback when input loses focus |
| `disabled` | `boolean` | `false` | Whether the input is disabled |
| `placeholder` | `string \| null` | `null` | Placeholder text |
| `variant` | `"" \| "plain" \| "outlined" \| "filled"` | `""` | Input visual variant |
| `compact` | `boolean` | `false` | Whether to use compact spacing |
| `style` | `string` | `""` | Additional CSS styles |

## Methods

| Method | Description |
|--------|-------------|
| `focus()` | Programmatically focus the search input |

## Examples

### Basic Search

```svelte
<script>
  import SearchBox from "@ticatec/uniface-element/SearchBox";
  
  let searchTerm = '';
  let results = [];
  
  function performSearch(query) {
    if (query) {
      // Simulate search
      results = [`Result for "${query}" 1`, `Result for "${query}" 2`];
    } else {
      results = [];
    }
  }
</script>

<SearchBox 
  bind:value={searchTerm}
  onchange={performSearch}
  placeholder="Search products..."
/>

{#if results.length > 0}
  <ul>
    {#each results as result}
      <li>{result}</li>
    {/each}
  </ul>
{/if}
```

### Real-time Search

```svelte
<script>
  import SearchBox from "@ticatec/uniface-element/SearchBox";
  import { debounce } from 'lodash-es';
  
  let searchQuery = '';
  let suggestions = [];
  
  // Debounced search function
  const debouncedSearch = debounce((query) => {
    if (query.length > 2) {
      // Simulate API call
      suggestions = [
        `${query} suggestion 1`,
        `${query} suggestion 2`,
        `${query} suggestion 3`
      ];
    } else {
      suggestions = [];
    }
  }, 300);
  
  function handleInput(query) {
    debouncedSearch(query);
  }
</script>

<SearchBox 
  bind:value={searchQuery}
  oninput={handleInput}
  placeholder="Type to search..."
/>

{#if suggestions.length > 0}
  <div class="suggestions">
    {#each suggestions as suggestion}
      <div class="suggestion-item">{suggestion}</div>
    {/each}
  </div>
{/if}

<style>
  .suggestions {
    border: 1px solid #ddd;
    border-radius: 4px;
    margin-top: 4px;
  }
  
  .suggestion-item {
    padding: 8px 12px;
    cursor: pointer;
  }
  
  .suggestion-item:hover {
    background-color: #f5f5f5;
  }
</style>
```

### With Event Handlers

```svelte
<script>
  import SearchBox from "@ticatec/uniface-element/SearchBox";
  
  let searchValue = '';
  let isSearching = false;
  
  function handleChange(query) {
    console.log('Search committed:', query);
    // Perform final search
  }
  
  function handleInput(query) {
    console.log('Input changed:', query);
    // Real-time suggestions
  }
  
  function handleFocus(event) {
    console.log('Search box focused');
    isSearching = true;
  }
  
  function handleBlur(event) {
    console.log('Search box blurred');
    isSearching = false;
  }
</script>

<SearchBox 
  bind:value={searchValue}
  onchange={handleChange}
  oninput={handleInput}
  onfocus={handleFocus}
  onblur={handleBlur}
  placeholder="Search..."
/>

{#if isSearching}
  <p>Search is active...</p>
{/if}
```

### Different Variants

```svelte
<script>
  import SearchBox from "@ticatec/uniface-element/SearchBox";
  
  let search1 = '', search2 = '', search3 = '';
</script>

<!-- Default variant -->
<SearchBox bind:value={search1} placeholder="Default search" />

<!-- Outlined variant -->
<SearchBox bind:value={search2} variant="outlined" placeholder="Outlined search" />

<!-- Filled variant -->
<SearchBox bind:value={search3} variant="filled" placeholder="Filled search" />
```

### Compact Mode

```svelte
<script>
  import SearchBox from "@ticatec/uniface-element/SearchBox";
  
  let compactSearch = '';
</script>

<div class="toolbar">
  <SearchBox 
    bind:value={compactSearch} 
    compact 
    placeholder="Quick search" 
  />
</div>

<style>
  .toolbar {
    display: flex;
    align-items: center;
    padding: 8px;
    background: #f8f9fa;
  }
</style>
```

### Search with Filter

```svelte
<script>
  import SearchBox from "@ticatec/uniface-element/SearchBox";
  import Button from "@ticatec/uniface-element/Button";
  
  let searchTerm = '';
  let filterType = 'all';
  let items = [
    { name: 'Apple iPhone', category: 'electronics' },
    { name: 'Nike Shoes', category: 'clothing' },
    { name: 'Coffee Maker', category: 'appliances' },
    { name: 'Samsung TV', category: 'electronics' }
  ];
  
  $: filteredItems = items.filter(item => {
    const matchesSearch = !searchTerm || 
      item.name.toLowerCase().includes(searchTerm.toLowerCase());
    const matchesFilter = filterType === 'all' || 
      item.category === filterType;
    return matchesSearch && matchesFilter;
  });
  
  function clearSearch() {
    searchTerm = '';
  }
</script>

<div class="search-controls">
  <SearchBox 
    bind:value={searchTerm}
    placeholder="Search products..."
    style="flex: 1; margin-right: 8px;"
  />
  <Button label="Clear" onClick={clearSearch} />
</div>

<div class="filters">
  <label>
    <input type="radio" bind:group={filterType} value="all" />
    All
  </label>
  <label>
    <input type="radio" bind:group={filterType} value="electronics" />
    Electronics
  </label>
  <label>
    <input type="radio" bind:group={filterType} value="clothing" />
    Clothing
  </label>
</div>

<div class="results">
  {#each filteredItems as item}
    <div class="item">{item.name} - {item.category}</div>
  {/each}
</div>

<style>
  .search-controls {
    display: flex;
    margin-bottom: 16px;
  }
  
  .filters {
    display: flex;
    gap: 16px;
    margin-bottom: 16px;
  }
  
  .item {
    padding: 8px;
    border-bottom: 1px solid #eee;
  }
</style>
```

### Disabled State

```svelte
<script>
  import SearchBox from "@ticatec/uniface-element/SearchBox";
  
  let searchValue = '';
  let isDisabled = false;
</script>

<label>
  <input type="checkbox" bind:checked={isDisabled} />
  Disable search
</label>

<SearchBox 
  bind:value={searchValue}
  disabled={isDisabled}
  placeholder="Search when enabled..."
/>
```

### Programmatic Focus

```svelte
<script>
  import SearchBox from "@ticatec/uniface-element/SearchBox";
  import Button from "@ticatec/uniface-element/Button";
  
  let searchBox;
  let searchValue = '';
  
  function focusSearch() {
    searchBox.focus();
  }
</script>

<Button label="Focus Search" onClick={focusSearch} />

<SearchBox 
  bind:this={searchBox}
  bind:value={searchValue}
  placeholder="Click button to focus me"
/>
```

## Features

- **Search Icon**: Built-in search icon for clear visual indication
- **Clear Functionality**: Automatic clear button when text is present
- **Composition Events**: Proper handling of international text input (IME support)
- **Real-time Input**: Separate handlers for input and change events
- **Focus Management**: Programmatic focus control and event handling
- **Flexible Styling**: Multiple visual variants and custom styling options

## Input Handling

The SearchBox component provides sophisticated input handling:

1. **Real-time Updates**: `oninput` fires on every keystroke
2. **Committed Changes**: `onchange` fires on blur or Enter key
3. **Composition Support**: Properly handles IME input for international languages
4. **Clear Action**: Triggers both input and change callbacks when cleared

## Behavior

1. **Typing**: Real-time updates trigger `oninput` callback
2. **Enter/Blur**: Committed changes trigger `onchange` callback
3. **Clear Button**: Appears when text is present, clears input when clicked
4. **Focus**: Click or tab to focus, programmable via `focus()` method
5. **IME Input**: Composition events prevent premature updates during multi-key input

## Accessibility

- Proper ARIA attributes for search functionality
- Keyboard navigation support
- Screen reader compatible
- Focus indicators and management
- Clear button accessibility

## Best Practices

1. **Search Feedback**: Provide visual feedback during search operations
2. **Debouncing**: Use debouncing for real-time search to avoid excessive API calls
3. **Empty States**: Handle empty search results gracefully
4. **Loading States**: Show loading indicators for async searches
5. **Clear Action**: Always provide a way to clear the search
6. **Placeholder Text**: Use descriptive placeholder text


## Browser Support

- Modern browsers with composition event support
- Compatible with Svelte 5+
- IME (Input Method Editor) support for international input
- Touch-friendly interface

## Related Components

- `TextEditor` - Basic text input without search features
- `PromptsTextEditor` - Text input with suggestion dropdown
- `LookupEditor` - Advanced lookup with search and selection
- `OptionsSelect` - Dropdown selection with search capability