Token Field

Token field lets users enter text with inline tokens such as mentions, tags, or object references.

Message
Ping @alexmiller about the #launch checklist
const defaultValue = /* ... */;

<TokenField allowsNewlines defaultValue={defaultValue} className="w-[320px]">
  <Label>Message</Label>
  <TokenInput />
</TokenField>

Installation

npx shadcn@latest add @dotui/token-field

About

TokenField is built on the TokenField primitive from React Aria's upcoming release (adobe/react-spectrum#10318), vendored until it ships in react-aria-components. The primitive handles content-editable editing, IME composition, undo/redo, token-aware clipboard and drag behaviour, and screen-reader announcements.

Usage

Compose a TokenField with a TokenInput for the editable area, and a Label before it when you want a visible label (otherwise give the input an aria-label). Without allowsNewlines the field stays single-line.

import { Label } from '@/components/ui/field'
import { TokenField, TokenInput } from '@/components/ui/token-field'
<TokenField allowsNewlines>
  <Label>Message</Label>
  <TokenInput />
</TokenField>

Anatomy

<TokenField>
  <Label />
  <TokenInput>
    <Token />
  </TokenInput>
</TokenField>

TokenField owns the value and provides the label and description slots, TokenInput renders the text and inline tokens, and Token renders a single inline token. Tokens render as Tokens by default; pass a render function as TokenInput's children to customize them.

<TokenInput>{(token) => <Token>{token.text}</Token>}</TokenInput>

Value

The value is a TokenSegmentList — a list of plain-text and token segments. Use defaultValue for uncontrolled state, or value with onChange to control it; toString() joins the segments back into plain text.

const [value, setValue] = React.useState(
  () =>
    new TokenSegmentList([
      { type: 'text', text: 'Hello ' },
      { type: 'token', text: '@sarahjones' },
    ]),
)

<TokenField value={value} onChange={setValue}>
  {/* ... */}
</TokenField>

Tokenization

Subclass TokenSegmentList and override tokenize to convert typed text into tokens automatically — for hashtags, tag inputs, or structured search filters. tokenize receives the text of an edited region and returns the segments it should become.

class TagSegmentList extends TokenSegmentList {
  protected tokenize(text: string): TokenFieldSegment[] {
    // split on commas/spaces and return text + token segments
  }
}

Autocomplete

For trigger-based suggestions (@-mentions, /-commands) use the Mention component, which wires a caret-anchored suggestions menu onto the token field.

Examples

Basic

Message
Ping @alexmiller about the #launch checklist

Automatic tokenization

Post
This field tokenizes #hashtags and @usernames as you type.

Tag input

Categories
DesignEngineeringMarketing

Controlled

Message
Hello @sarahjones!

Value: Hello @sarahjones!

API Reference

TokenField

A token field lets users enter text with inline tokens — mentions, tags, or object references. Use it to build AI prompt fields, tag inputs, structured search fields, and mention inputs. The value is a `TokenSegmentList` of text and token segments; subclass it and override `tokenize` to convert typed text into tokens automatically. Built on the `TokenField` primitive vendored from React Aria's upcoming release (adobe/react-spectrum#10318).

PropType
boolean
boolean
boolean
ReactNode | function
TokenSegmentList<any>
TokenSegmentList<any>
function

TokenInput

The editable area of a `TokenField`: a content-editable surface that renders the value's text and inline tokens.

PropType
union
boolean
string

Token

An inline token within a `TokenInput`.

PropType
ReactNode | function

Last updated on 7/19/2026