Dots

Token Search Field

A search field where typed filters such as from:alex become removable tokens.

FromMaya Chen
Statuspending
"use client"

import {

The TokenSearchField component is a search input for lists such as payment history, where people narrow results with filters. Typing a known operator such as from:maya and pressing Space or Enter turns it into a token, and free text stays editable after the tokens. Use it when filters are part of the query. For a plain text search, use a search field; for a fixed set of filters, use chips or a select next to it.

Installation

pnpm dlx shadcn@latest add @dots/token-search-field

Usage

import {
  TokenSearchField,
  type SearchOperator,
} from "@/components/ui/token-search-field"
const operators: SearchOperator[] = [
  { key: "from", label: "From" },
  { key: "is", label: "Status" },
]
 
<TokenSearchField label="Search payments" operators={operators} />

Features

  • Typed operators become tokens on Space or Enter when the caret is at the end
  • Backspace at the start of the input moves to the last token, a second Backspace removes it
  • Arrow keys move between tokens; Escape, typing, or the arrow past the last token returns to the input
  • A clear button that removes the text and all tokens
  • Controlled or uncontrolled tokens and text, and an onSubmit with both
  • Tokens added from outside, including plain text tokens with no operator
  • Polite announcements when tokens are added, removed or cleared

Operators

Pass operators to list what the user can type before a colon. Only known operators turn into tokens; amount:5 stays text if amount is not listed.

Type from:maya and press Space. Backspace at the start selects the last filter, a second Backspace removes it.

"use client"

import {

Controlled

Pass tokens with onTokensChange and value with onChange to own the query. onSubmit runs on Enter when there is no operator to finish and receives { text, tokens }.

Categorytravel

Press Enter to search.

"use client"

import * as React from "react"

Filters from outside

Add tokens from your own controls, such as suggestion chips. A token without operator shows its value only.

coffee
"use client"

import * as React from "react"

Disabled

Set isDisabled to lock the input and the tokens. The clear and remove buttons are hidden.

Statusfailed
"use client"

import {

Accessibility

TokenSearchField is built on React Aria SearchField and TagGroup. The input gets search semantics, Escape clears it, and the tokens are a grid of tags you move through with the arrow keys and remove with Backspace or Delete.

Label the field

Pass label for a visible label. Without one, pass aria-label.

<TokenSearchField aria-label="Search payments" operators={operators} />

Labels for the parts

tokensLabel names the list of tokens, removeLabel starts the name of each remove button, and clearLabel names the clear button. Each remove button is named after its token, such as "Remove Status pending". Translate all three with the rest of your UI.

Announcements

A hidden live region says "Added", "Removed" or "Cleared filters" so screen reader users hear changes that happen without a focus move.

API Reference

TokenSearchField

Accepts all React Aria SearchField props except children, className, onSubmit, value, defaultValue and onChange, which are replaced below.

PropTypeDefaultDescription
operatorsSearchOperator[][]Operators that turn key:value into a token.
tokensSearchToken[]-Finished filters (controlled).
defaultTokensSearchToken[][]Finished filters (uncontrolled).
onTokensChange(tokens: SearchToken[]) => void-Called when tokens are added or removed.
valuestring-Free text after the tokens (controlled).
defaultValuestring""Free text after the tokens (uncontrolled).
onChange(value: string) => void-Called when the free text changes.
onSubmit(query: { text: string; tokens: SearchToken[] }) => void-Called on Enter when there is no operator to finish.
labelReactNode-Visible label. Without it, pass aria-label.
placeholderstring"Search"Shown only while there are no tokens.
tokensLabelstring"Filters"Names the list of tokens for screen readers.
removeLabelstring"Remove"Start of each remove button's name.
clearLabelstring"Clear search"Name of the clear button.
isDisabledboolean-Disables the input and the tokens.
classNamestring-Additional classes to apply to the root element.

SearchToken

FieldTypeDescription
idstringUnique key for the token.
operatorstringOperator key, such as "from". Omit for plain text.
valuestringThe filter value, such as "pending".

SearchOperator

FieldTypeDescription
keystringWhat the user types before the colon, such as "from".
labelstringQuiet name shown on the token, such as "From".