Search Field
Headless Search Field; covers HTML search input, React Aria SearchField, Reka UI Primitive.
| Package | @vizejs/ui/search-field |
| Maturity | stable |
| Own the source | vize lib pull search-field |
| Requires | controllable-state, id |
| Aliases | search box, search input, query field |
| Covers | HTML search input, React Aria SearchField, Reka UI Primitive |
Minimal setup
Use a Vue 3.5+ project with Vue SFC compilation configured (see Vite+ integration).
vp install @vizejs/ui
Add the public import below to <script setup lang="ts">. Components provide behavior without styles; the preview uses optional Paper styles.
import { SearchField } from "@vizejs/ui/search-field";
Or copy the source into your project with vize lib pull search-field (see Source Distribution).
Try it
This is the basic example maintained with the component source, using the public package imports. The preview adds the optional Paper styles.
Open the interactive example · Styling these components
Copy the example
<!-- Controlled search field with a native label and a built-in clear button. -->
<script setup lang="ts">
import { ref, useId } from "vue";
import { SearchField } from "@vizejs/ui/search-field";
const query = ref("");
const inputId = useId();
</script>
<template>
<div>
<label :for="inputId">Search articles</label>
<SearchField :id="inputId" v-model="query" name="q" placeholder="Try “hydration”">
<template #clear>×</template>
</SearchField>
<p>{{ query === "" ? "Type to search." : `Results for “${query}”` }}</p>
</div>
</template>
API
SearchField
Source: src/families/form/search-field/search-field.vue
Props
| Prop | Type | Default | Description |
|---|---|---|---|
id |
string | null |
undefined |
Consumer-owned input id; nullish values use a deterministic fallback. |
name |
string |
undefined |
Native form field name. |
modelValue |
string |
undefined |
Controlled string value; undefined selects uncontrolled behavior. |
defaultValue |
string |
"" |
Initial uncontrolled value and form-reset target. |
disabled |
boolean |
false |
Disable editing, clearing, focus, and native form submission. |
readOnly |
boolean |
false |
Keep focusability while preventing user editing and clearing. |
required |
boolean |
false |
Mark the native search input as required. |
placeholder |
string |
undefined |
Native placeholder text. |
autocomplete |
string |
undefined |
Native autocomplete hint. |
inputMode |
SearchFieldInputMode |
"search" |
Native virtual-keyboard input mode. |
enterKeyHint |
SearchFieldEnterKeyHint |
"search" |
Native virtual-keyboard enter key hint. |
showClear |
SearchFieldClearVisibility |
"auto" |
Clear button visibility policy. |
clearLabel |
string |
"Clear search" |
Accessible name for the default clear button. |
ariaLabel |
string |
undefined |
Accessible name when no label or aria-labelledby supplies one. |
ariaLabelledby |
string |
undefined |
Space-separated ids that label the search input. |
ariaDescribedby |
string |
undefined |
Space-separated ids that describe the search input. |
ariaErrormessage |
string |
undefined |
Id of the validation error message used while invalid. |
ariaInvalid |
SearchFieldAriaInvalid |
false |
Invalid state announced to assistive technology. |
Events
| Event | Payload | Description |
|---|---|---|
update:modelValue |
[value: string] |
Fired when the value requests a new controlled string. |
clear |
[value: "", nativeEvent: MouseEvent] |
Fired after the default clear button clears the field. |
change |
[value: string, nativeEvent: Event] |
Fired after a native change/commit with the current string and native Event. |
compositionEnd |
[value: string, nativeEvent: CompositionEvent] |
Fired when IME composition ends. |
compositionStart |
[value: string, nativeEvent: CompositionEvent] |
Fired when IME composition starts. |
input |
[value: string, nativeEvent: Event] |
Fired after a native input event with the next string and native Event. |
search |
[value: string, nativeEvent: Event] |
Fired after a native search event with the committed search string. |
Slots
| Slot | Slot props | Description |
|---|---|---|
clear |
SearchFieldClearSlotState |
Replaces the default clear button contents with availability state. |
Exposed
| Member | Type | Description |
|---|---|---|
composing |
boolean |
Whether the native input is currently inside IME composition. |
value |
string |
Current controlled or uncontrolled string value. |
clear |
() => boolean |
Clear the current value and report whether it changed. |
focus |
(options?: FocusOptions) => void |
Move focus to the native search input. |
reset |
() => boolean |
Restore the current default value and report whether it changed. |
select |
() => void |
Select the current native search text. |
setValue |
(value: string) => boolean |
Request a value update and report whether it differs. |
element |
Readonly<ShallowRef<HTMLElement | null>> |
Template ref to the rendered root element. |
Behavior
Normative state × input → outcome table for search-field.vue (@vizejs/ui/search-field).
Every row is proven by the named mounted-DOM test in
src/families/form/search-field/search-field.test.ts;
a row without a passing test is a contract violation.
| # | State | Input | Outcome | Proven by |
|---|---|---|---|---|
| S1 | editable, native | render | role="search" root, native searchbox, deterministic input/clear ids, search keyboard hints, form attributes, and invalid ARIA state |
renders a named native searchbox with root landmark and accessibility attributes |
| S2 | uncontrolled | input / change/search | value follows the native element; emits update:modelValue before input, change, and search |
uncontrolled search field emits model before input, change, and search |
| S3 | controlled | native input | emits the request; the rendered value reverts to modelValue until the parent accepts the update |
controlled search value wins until the parent accepts the request |
| S4 | uncontrolled, seeded | form reset | defaultValue seeds the initial value and form reset restores it without request-global state |
defaultValue seeds state and native form reset restores it |
| S5 | clearable | default clear button | default clear emits update:modelValue before clear, empties the field, and returns focus to the searchbox |
clear button updates before clear event and returns focus to the searchbox |
| S6 | unavailable | render / Tab | clear availability and focus follow empty, disabled, and readonly state while preserving native input semantics | clear visibility and availability follow empty, disabled, and readonly state |
| S7 | composing | IME composition | native text is not rewritten during composition; real CompositionEvent payloads are emitted and reconciliation happens afterward |
tracks IME composition without rewriting controlled native text |
| S8 | uncontrolled | exposed methods | setValue(), clear(), select(), focus(), and reset() update the native searchbox without bundled CSS |
exposes value mutation, clear, selection, focus, and reset controls |
The subpath remains tree-shakable and retains no packaged CSS; those package
contracts are pinned by distribution.test.ts, check:size, and
check:tree-shaking.