---
title: "SearchInput"
description: "An input with a built-in search icon that searches on Enter."
category: Form
status: beta
since: 0.3.4
tags: [search, input, form]
syncStatus: reviewed
verified: true
---

## Usage

### Basic
Enter emits `search` immediately.
:::TuffDemoWrapper{demo="SearchInputSearchInputDemo" code-lang="vue"}
---
code: |
  <template>
    <TxSearchInput v-model="value" placeholder="Search anything" @search="onSearch" />
  </template>
---
:::

### Remote Search
`remote` emits `search` once typing pauses for `searchDebounce` ms; the host renders the results panel.
:::TuffDemoWrapper{demo="SearchInputSearchInputRemoteDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  import { ref } from 'vue'

  const value = ref('')
  const hits = ref<string[]>([])
  const open = ref(false)

  async function onSearch(query: string) {
    hits.value = await searchApi(query)
    open.value = true
  }
  </script>

  <template>
    <TxPopover v-model="open" reference-full-width>
      <template #reference>
        <TxSearchInput
          v-model="value"
          remote
          :search-debounce="250"
          @focus="open = true"
          @search="onSearch"
        />
      </template>

      <button v-for="hit in hits" :key="hit" @click="value = hit">
        {{ hit }}
      </button>
    </TxPopover>
  </template>
---
:::

### Filter Toolbar
`TxSearchInput` takes the keyword, `TxSearchSelect` the scope, and `TxSearchEmpty` shows when nothing matches.
:::TuffDemoWrapper{demo="ComponentsSearchFiltersDemo" code-lang="vue"}
---
code: |
  <template>
    <TxSearchInput
      v-model="query"
      remote
      :search-debounce="180"
      placeholder="Search plugins / docs / tasks"
      @search="onSearch"
    />
    <TxSearchSelect v-model="scope" :options="scopeOptions" placeholder="Filter scope" />
    <TxSearchEmpty v-if="!filteredRecords.length" description="Try another keyword or filter scope." />
  </template>
---
:::

### Best Practices

- Use `TxSearchInput` for keyword-and-Enter flows; use `TxSearchSelect` when results need a panel or the picked value fills the field.
- With `remote`, Enter and the debounce can emit the same query, so keep request handling idempotent.
- Don't rely on the placeholder alone for meaning; give dense toolbars an external label or context.
- Set `searchDebounce` to `0` only for local or fully cached searches.
- Use `TuffInput` directly when you need a custom prefix or suffix.

## API Reference

### Props

| Prop | Type | Default | Description |
|------|------|---------|------|
| `modelValue` | `string` | `''` | Input value, bound with `v-model`. |
| `placeholder` | `string` | `'Search'` | Placeholder text. |
| `disabled` | `boolean` | `false` | Blocks typing, clearing, and remote search. |
| `clearable` | `boolean` | `true` | Shows the clear button when there is a value. |
| `remote` | `boolean` | `false` | Emits debounced `search` events while typing. |
| `searchDebounce` | `number` | `200` | Remote-search debounce in milliseconds. |

### Events

| Event | Params | Description |
|------|------|------|
| `update:modelValue` | `(v: string)` | Fires when the input value changes. |
| `input` | `(v: string)` | Fires together with `update:modelValue`. |
| `focus` | `(e: FocusEvent)` | Fires when the input gains focus. |
| `blur` | `(e: FocusEvent)` | Fires when the input loses focus. |
| `clear` | - | Fires after the clear button resets the value. |
| `search` | `(v: string)` | Fires on Enter, and with `remote` also after the debounce. |

### Exposed Methods

| Name | Type | Description |
|------|------|------|
| `focus()` | `() => void` | Focuses the input. |
| `blur()` | `() => void` | Blurs the input. |
| `clear()` | `() => void` | Clears the value and emits `clear`. |
| `setValue(v)` | `(v: string) => void` | Sets the input value. |
| `getValue()` | `() => string` | Returns the input value. |

## Technologies

- Wraps `TuffInput` with a built-in search icon; clearing and the exposed methods forward to `TuffInput`.
- Source: `packages/tuffex/packages/components/src/search-input/`.

<TuffDocSourceLink />
