Skip to main content
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

Event Emission

Emits a search event with the query when the user types, enabling integration with external search logic.

Debounced Search

Minimizes API calls by debouncing the search function.

Customizable Results Display

Supports rendering custom result items using a scoped result slot.

Flexible Layouts

Can be displayed inline or as a standalone search box with a label.

Usage

Basic Example

import { InputSearch } from '@robojuice/velure-ui';
<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

v-model
string
default:"''"
Two-way binding for the search query input.
label
string
default:"''"
Label text displayed above the search input.
placeholder
string
default:"''"
Placeholder text inside the search input.
lengthRequired
number
default:"3"
Minimum number of characters required to trigger the search event.
inline
boolean
default:"false"
Whether the search box is displayed inline with other elements.
results
array
default:"[]"
Array of search result objects to display in the result list.

Events

Triggered when the user types in the search box after the required character length is met.
leave
event
Triggered when the user blurs the search input but only when the search box is not open.
close
event
Triggered when the user closes the search input box.

Slots

iconLeft
slot
Slot for placing a custom icon on the left side of the search input. <template #iconLeft></template>
result
slot
Scoped slot for rendering custom search result items. Provides result as context. <template #result="{ result, state }"></template>
result-none
slot
Scoped slot for rendering custom no results message. Provides result as context. <template #result-none="{ state }"></template>
results
slot
Scoped slot for rendering a custom results list. Provides result as context. <template #results="{ state, results }"></template>
top
slot
Scoped slot for rendering before the result list. Provides result as context. <template #top="{ state }"></template>
bottom
slot
Scoped slot for rendering after the result list. Provides result as context. <template #bottom="{ state }"></template>

Example Use Cases

Inline Search with Custom Results

<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.
<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.