> ## Documentation Index
> Fetch the complete documentation index at: https://docs.velure.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Search Input

> InputSearch.vue Component Documentation

The `InputSearch.vue` component is a flexible and dynamic search input field that supports real-time searching with debounced API calls. It provides customization options for inline or labeled search layouts, and it supports displaying search results with scoped slots for templating.

***

## Features

<CardGroup cols={2}>
  <Card title="Event Emission" icon="square-1">
    Emits a <code>search</code> event with the query when the user types, enabling integration with external search logic.
  </Card>

  <Card title="Debounced Search" icon="square-2">
    Minimizes API calls by debouncing the search function.
  </Card>

  <Card title="Customizable Results Display" icon="square-3">
    Supports rendering custom result items using a scoped <code>result</code> slot.
  </Card>

  <Card title="Flexible Layouts" icon="square-4">
    Can be displayed inline or as a standalone search box with a label.
  </Card>
</CardGroup>

***

## Usage

### Basic Example

```js theme={null}
import { InputSearch } from '@robojuice/velure-ui';
```

```vue theme={null}
<template>
  <InputSearch
    :length-required="3"
    v-model="search.query"
    :results="search.results"
    @search="searchResults"
    label="Search"
    placeholder="Type to search"
  >
    <template #result="{ result, state }">
      <button type="button" @click="resultClicked(result)" class="button-text">
        {{ result.text }} @ {{ result.url }}
      </button>
    </template>
  </InputSearch>
</template>

<script setup>
import { reactive } from 'vue';

const search = reactive({ query: '', results: [] });

const searchResults = (q) => {
  const data = [
    { text: 'one', url: '/one' },
    { text: 'one more', url: '/one-more' },
    { text: 'two', url: '/two' },
  ];
  search.results = data.filter((item) =>
    item.text.toLowerCase().includes(q.toLowerCase())
  );
};

const resultClicked = (result) => {
  console.log('Result clicked:', result);
};
</script>
```

***

## Props

<ParamField path="v-model" type="string" default="''">
  Two-way binding for the search query input.
</ParamField>

<ParamField path="label" type="string" default="''">
  Label text displayed above the search input.
</ParamField>

<ParamField path="placeholder" type="string" default="''">
  Placeholder text inside the search input.
</ParamField>

<ParamField path="lengthRequired" type="number" default="3">
  Minimum number of characters required to trigger the `search` event.
</ParamField>

<ParamField path="inline" type="boolean" default="false">
  Whether the search box is displayed inline with other elements.
</ParamField>

<ParamField path="results" type="array" default="[]">
  Array of search result objects to display in the result list.
</ParamField>

***

## Events

<ParamField path="search" type="event" payload="string (query)">
  Triggered when the user types in the search box after the required character length is met.
</ParamField>

<ParamField path="leave" type="event" payload="object|array (model)">
  Triggered when the user blurs the search input but only when the search box is not open.
</ParamField>

<ParamField path="close" type="event" payload="{object|array (model), object (state)}">
  Triggered when the user closes the search input box.
</ParamField>

***

## Slots

<ParamField path="iconLeft" type="slot">
  Slot for placing a custom icon on the left side of the search input. `<template #iconLeft></template>`
</ParamField>

<ParamField path="result" type="slot" scope="{ result, state }">
  Scoped slot for rendering custom search result items. Provides `result` as context. `<template #result="{ result, state }"></template>`
</ParamField>

<ParamField path="result-none" type="slot" scope="{ state }">
  Scoped slot for rendering custom no results message. Provides `result` as context. `<template #result-none="{ state }"></template>`
</ParamField>

<ParamField path="results" type="slot" scope="{ state, results }">
  Scoped slot for rendering a custom results list. Provides `result` as context. `<template #results="{ state, results }"></template>`
</ParamField>

<ParamField path="top" type="slot" scope="{ state, results }">
  Scoped slot for rendering before the result list. Provides `result` as context. `<template #top="{ state }"></template>`
</ParamField>

<ParamField path="bottom" type="slot" scope="{ state, results }">
  Scoped slot for rendering after the result list. Provides `result` as context. `<template #bottom="{ state }"></template>`
</ParamField>

***

## Example Use Cases

### Inline Search with Custom Results

```vue theme={null}
<InputSearch
  :length-required="2"
  v-model="search.query"
  :results="search.results"
  @search="searchResults"
  :inline="true"
  label="Inline Search"
  placeholder="Type here"
>
  <template #result="{ result, state }">
    <button @click="resultClicked(result)" class="button-text">
      {{ result.text }} - {{ result.url }}
    </button>
  </template>
</InputSearch>
```

### Close Search After Click

You can close the search box setting `state.open` to `false`. The `state` is a result slot template parameter.

```vue theme={null}
<InputSearch
  :length-required="2"
  v-model="search.query"
  :results="search.results"
  @search="searchResults"
  :inline="true"
  label="Inline Search"
  placeholder="Type here"
>
  <template #result="{ result, state }">
  <button @click="resultClicked(result); state.open = false" class="button-text">
    {{ result.text }} - {{ result.url }}
  </button>
  </template>
</InputSearch>
```

***

## About the Debounce System

The debounce system ensures that the search event is not triggered for every keystroke, but rather after a specified delay once the user stops typing. This minimizes performance overhead and reduces the number of unnecessary API calls or search function executions. The debounce function wraps the searchBox function, delaying its execution by `500` milliseconds after the last keypress.

### Purpose:

* Prevents triggering the search logic too frequently while the user is typing.
* Ensures smooth and efficient operation, especially for remote or API-based search systems.

***

## Notes

* **Debounced Searching**: The component includes a debounced search function, reducing unnecessary API calls or computations.
* **Custom Result Rendering**: Use the `result` slot to fully control how search results are displayed.
* **Flexible Layouts**: Adjust the layout using the `inline` prop to fit various design requirements.

For further customization, refer to the component's source code.
