Skip to content

SearchField ​

A search field is a TextField with the search behaviours built in: a clear button that appears when there is something to clear, Esc to empty it, and a type="search" control so the browser offers the right keyboard and history.

ts
import {
  Label,
  SearchField,
  SearchFieldClearButton,
  SearchFieldGroup,
  SearchFieldInput,
  SearchFieldSearchIcon,
} from "ropav";
variant
size
template
<SearchField default-value="oklch">
  <Label>Search</Label>
  <SearchFieldGroup>
    <SearchFieldSearchIcon />
    <SearchFieldInput class="w-64" placeholder="Search…" />
    <SearchFieldClearButton />
  </SearchFieldGroup>
</SearchField>

SearchFieldGroup is the bordered box; the icon, the input and the clear button sit inside it in whatever order you put them.

search-field-clearable.vue
vue
<script setup lang="ts">
import {
  Label,
  SearchField,
  SearchFieldClearButton,
  SearchFieldGroup,
  SearchFieldInput,
  SearchFieldSearchIcon,
} from "ropav";
</script>

<template>
  <SearchField default-value="oklch" name="search">
    <Label>Search the docs</Label>
    <SearchFieldGroup>
      <SearchFieldSearchIcon />
      <SearchFieldInput class="field" placeholder="Search…" />
      <SearchFieldClearButton />
    </SearchFieldGroup>
  </SearchField>
</template>

<style scoped>
.field {
  width: calc(var(--rp-spacing) * 72);
}
</style>

Searching as you type, or on submit ​

The field emits change for every keystroke and submit when Enter is pressed. Which one you listen to is the difference between a filter and a search: a filter narrows a list that is already on screen, a search goes and fetches something.

Validation works as it does on any field — is-required, validate, and is-invalid taking the field over when it is set either way.

Accessibility ​

  • Esc clears the field. That is a real convenience and also a small hazard: a reader who presses it expecting to close something loses what they typed instead, so do not put a search field inside a dialog that Escape should close.
  • The clear button names itself and only appears when there is text, so it is not a button that sits in the tab order doing nothing.
  • SearchFieldSearchIcon is decoration. The Label is what names the field — a magnifying glass says "search" only to people who can see it.

API ​

SearchField

PropTypeDefaultDescription
ariaDescribedbystring—Ids of the elements that describe the field, on top of any nested help text.
ariaLabelstring—Accessible name, for a field with no visible label.
ariaLabelledbystring—Ids of the elements that name the field.
autoCapitalizestring—
autoCompletestring—
autoCorrectstring—
autoFocusboolean—Whether the field takes focus on mount.
defaultValuestring—Text the field starts with, and goes back to when the form is reset.
enterKeyHintstring—Action label for the enter key on a virtual keyboard.
formstring—id of the form to submit with, for a field rendered outside it.
fullWidthboolean—Whether the field stretches to fill its container.
idstring—Lands on the control, which is the field as far as assistive technology is concerned.
inputModestring—Keyboard the browser should offer on a touch device.
isDisabledboolean—Whether the field is disabled — no interaction, no submission.
isInvalidboolean—Whether the value fails validation. Setting it either way takes the field over: false claims the field is valid and shadows validate, the browser and the server alike.
isReadOnlyboolean—Whether the text can be read but not changed.
isRequiredboolean—Whether the field has to be filled in for the form to submit.
maxLengthnumber—
minLengthnumber—
namestring—Name submitted with the form.
onSubmit((value: string) => void)—Called when the search is submitted from the keyboard. A prop rather than an emit, because its mere presence decides what Enter does: with a handler the key is a submit and stops there, without one it belongs to the form, which submits on Enter in a single-line field of its own accord. Vue strips a declared emit from $attrs, so an emit gives the component no way to tell whether anyone is listening.
placeholderstring—Placeholder shown while the field is empty.
size"xs" | "sm" | "md" | "lg""md"How tall the field stands, matching a button of the same size.
spellCheckstring | boolean—
typestring"search"Kind of control the browser should offer.
validateValidationFunction<string>—Checks the value and returns a message when it is not acceptable.
validationBehavior"aria" | "native""native"How the field reports validation. Inherited from the surrounding form when unset.
valuestring—Text in the field. Makes it controlled.
variant"primary" | "secondary""primary"Visual variant.

The default slot receives:

Slot propType
isDisabledboolean
isEmptyboolean
isInvalidboolean
isReadOnlyboolean
isRequiredboolean
validationDetailsValidationDetails
validationErrorsstring[]
EventPayload
changestring
clear—
focusChangeboolean
update:valuestring

SearchFieldClearButton

Slots: default.

SearchFieldGroup

The default slot receives:

Slot propType
isDisabledboolean
isFocusVisibleboolean
isFocusWithinboolean
isHoveredboolean
isInvalidboolean

SearchFieldInput

PropTypeDefaultDescription
placeholderstring—Placeholder shown while the control is empty. Declared so it can also be set here rather than only on the field; every other native attribute arrives by attribute fallthrough.
valuestring—Text in the control. Set here it takes the control over from the field, so the caller owns the value — exactly as a value prop does in React. Without a listener to go with it the text is pinned.
EventPayload
changestring
update:valuestring

SearchFieldSearchIcon

Slots: default.