---
name: FormTokenField
package: '@wordpress/components'
category: '@wordpress-components'
status: stable
canonical: 'https://system.automattic.design/components/formtokenfield/'
storybook: 'https://wordpress.github.io/gutenberg/?path=/docs/components-formtokenfield--docs'
github: 'https://github.com/WordPress/gutenberg/tree/trunk/packages/components/src/form-token-field'
figma: 'https://www.figma.com/design/jMgzw8IhsMC4gpMbMko4lv/WPDS--Gutenberg-22.3-?node-id=16530-21625'
---

# FormTokenField

A `FormTokenField` is a field similar to the tags and categories fields in the interim editor chrome,
or the "to" field in Mail on OS X. Tokens can be entered by typing them or selecting them from a list of suggested tokens.

Up to one hundred suggestions that match what the user has typed so far will be shown from which the user can pick from (auto-complete).
Tokens are separated by the "," character. Suggestions can be selected with the up or down arrows and added with the tab or enter key.

The `value` property is handled in a manner similar to controlled form components.
See [Forms](https://react.dev/reference/react-dom/components#form-components) in the React Documentation for more information.

```tsx
import { FormTokenField } from '@wordpress/components';
```

## Props

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `label` | `string` | `__( 'Add item' )` |  |
| `suggestions` | `string[]` | `[]` | An array of strings to present to the user as suggested tokens. |
| `maxSuggestions` | `number` | `100` | The maximum number of suggestions to display at a time. |
| `value` | `(string \| TokenItem)[]` | `[]` | An array of strings or objects to display as tokens in the field. If objects are present in the array, they **must** have a property of `value`. |
| `displayTransform` | `(token: string) => string` | `( value: string ) => value` | Function to call to transform tokens for display. (In the editor, this is needed to decode HTML entities embedded in tags - otherwise entities like `&` in tag names are double-encoded like `&amp;`, once by the REST API and once by React). |
| `saveTransform` | `(token: string) => string` | `( token ) => token.trim()` | Function to call to transform tokens for saving. The default is to trim the token value. This function is also applied when matching suggestions against the current value so that matching works correctly with leading or trailing spaces. (In the editor, this is needed to remove leading and trailing spaces from tag names, like wp-admin does. Otherwise the REST API won't save them.) |
| `onChange` | `(tokens: (string \| TokenItem)[]) => void` | `() => {}` | Function to call when the tokens have changed. An array of new tokens is passed to the callback. |
| `onInputChange` | `(input: string) => void` | `() => {}` | Function to call when the users types in the input field. It can be used to trigger autocomplete requests. |
| `onFocus` | `(event: FocusEvent<Element, Element>) => void` | `undefined` | Function to call when the TokenField has been focused on. The event is passed to the callback. Useful for analytics. |
| `isBorderless` | `boolean` | `false` | When true, renders tokens as without a background. |
| `maxLength` | `number` | — | If passed, `TokenField` will disable ability to add new tokens once number of tokens is greater than or equal to `maxLength`. |
| `disabled` | `boolean` | `false` | When true, tokens are not able to be added or removed. |
| `placeholder` | `string` | — | If passed, the `TokenField` input will show a placeholder string if no value tokens are present. |
| `tokenizeOnSpace` | `boolean` | `false` | If true, will add a token when `TokenField` is focused and `space` is pressed. |
| `messages` | `Messages` | `{ 			added: __( 'Item added.' ), 			removed: __( 'Item removed.' ), 			remove: __( 'Remove item' ), 			__experimentalInvalid: __( 'Invalid item' ), 		}` | Allows customizing the messages presented by screen readers in different occasions:<br>-   `added`: The user added a new token. -   `removed`: The user removed an existing token. -   `remove` : The user focused the button to remove the token. -   `__experimentalInvalid`: The user tried to add a token that didn't pass the validation. |
| `__experimentalExpandOnFocus` | `boolean` | `false` | If true, the suggestions list will be always expanded when the input field has the focus. |
| `__experimentalValidateInput` | `(token: string) => boolean` | `() => true` | If passed, all introduced values will be validated before being added as tokens. |
| `__experimentalShowHowTo` | `boolean` | — | Use the `help` prop instead. The `help` prop now defaults to the previous how-to text; if you were passing `__experimentalShowHowTo={ false }` to hide it, pass an empty string to `help` instead. |
| `__next36pxDefaultSize` | `boolean` | `false` | Deprecated. Use `__next40pxDefaultSize` instead. |
| `__next40pxDefaultSize` | `boolean` | — | Start opting into the larger default height that will become the default size in a future version. |
| `__experimentalAutoSelectFirstMatch` | `boolean` | `false` | If true, the select the first matching suggestion when the user presses the Enter key (or space when tokenizeOnSpace is true). |
| `__experimentalRenderItem` | `(args: { item: string; }) => ReactNode` | — | Custom renderer for suggestions. |
| `__nextHasNoMarginBottom` | `boolean` | `false` | Start opting into the new margin-free styles that will become the default in a future version. |
| `tokenizeOnBlur` | `boolean` | `false` | If true, add any incompleteTokenValue as a new token when the field loses focus. |
| `help` | `ReactNode` | — | Additional description for the control.<br>Only use for meaningful description or instructions for the control. An element containing the description will be programmatically associated to the `FormTokenField` via `aria-describedby`.<br>Defaults to a how-to message (e.g. _Separate with commas or the Enter key._); pass an empty string to hide it. |
| `className` | `string` | — |  |
| `autoCapitalize` | `"none" \| (string & {}) \| "off" \| "on" \| "sentences" \| "words" \| "characters" \| undefined` | — |  |
| `autoComplete` | `HTMLInputAutoCompleteAttribute \| undefined` | — |  |


## Examples

### Default

```tsx
const Default = () => {
    const [ selectedContinents, setSelectedContinents ] = useState<
		ComponentProps< typeof FormTokenField >[ 'value' ]
	>( [] );

    return (
        <FormTokenField
            label="Type a continent"
            suggestions={continents}
            value={ selectedContinents }
            onChange={ ( tokens ) => setSelectedContinents( tokens ) } />
    );
};
```

### Async

```tsx
const Async = () => {
    const [ selectedContinents, setSelectedContinents ] = useState<
		ComponentProps< typeof FormTokenField >[ 'value' ]
	>( [] );
    const [ availableContinents, setAvailableContinents ] = useState<
		string[]
	>( [] );

    const searchContinents = ( input: string ) => {
		const timeout = setTimeout( () => {
			const available = ( suggestions || [] ).filter( ( continent ) =>
				continent.toLowerCase().includes( input.toLowerCase() )
			);
			setAvailableContinents( available );
		}, 1000 );

		return () => clearTimeout( timeout );
	};

    return (
        <FormTokenField
            label="Type a continent"
            value={ selectedContinents }
            suggestions={ availableContinents }
            onChange={ ( tokens ) => setSelectedContinents( tokens ) }
            onInputChange={ searchContinents } />
    );
};
```

### Dropdown Selector

```tsx
const DropdownSelector = () => {
    const [ selectedContinents, setSelectedContinents ] = useState<
		ComponentProps< typeof FormTokenField >[ 'value' ]
	>( [] );

    return (
        <FormTokenField
            __experimentalExpandOnFocus
            __experimentalAutoSelectFirstMatch
            value={ selectedContinents }
            onChange={ ( tokens ) => setSelectedContinents( tokens ) } />
    );
};
```

### With Custom Rendered Items

The rendered content of each token can be customized by passing a
render function to the `displayTransform` prop.

Similarly, each suggestion can be customized by passing a
render function to the `__experimentalRenderItem` prop. (This is still an
experimental feature and is subject to change.)

```tsx
const WithCustomRenderedItems = () => {
    const [ selectedContinents, setSelectedContinents ] = useState<
		ComponentProps< typeof FormTokenField >[ 'value' ]
	>( [] );

    return (
        <FormTokenField
            displayTransform={( token ) => `📍 ${ token }`}
            __experimentalRenderItem={( { item } ) => (
                <div>{ `${ item } — a nice place to visit` }</div>
            )}
            __experimentalExpandOnFocus
            value={ selectedContinents }
            onChange={ ( tokens ) => setSelectedContinents( tokens ) } />
    );
};
```

### Validate New Tokens

Only values for which the `__experimentalValidateInput` function returns
`true` will be tokenized. (This is still an experimental feature and is
subject to change.)

In this example, the user can only add tokens that are already in the list.

```tsx
const ValidateNewTokens = () => {
    const [ selectedContinents, setSelectedContinents ] = useState<
		ComponentProps< typeof FormTokenField >[ 'value' ]
	>( [] );

    return (
        <FormTokenField
            __experimentalValidateInput={( input: string ) =>
                continents.includes( input )}
            __experimentalExpandOnFocus
            value={ selectedContinents }
            onChange={ ( tokens ) => setSelectedContinents( tokens ) } />
    );
};
```
