Introducing PrimeReact v11-alpha 🎉Discover Now

useInputTags

Hook that manages tag input state, keyboard navigation, and optional typeahead suggestions.

basic-demo

Usage#

import { useInputTags } from '@primereact/headless/inputtags';
 
const inputtags = useInputTags({ value: tags, onValueChange: (e) => setTags(e.value) });
const { rootProps, inputProps, getItemProps, getRemoveProps, state } = inputtags;
 
return (
    <div {...rootProps}>
        {state.value.map((tag, index) => (
            <span key={index} {...getItemProps(index)}>
                <button {...getRemoveProps(index)}></button>
            </span>
        ))}
        <input {...inputProps} />
    </div>
);

useInputTags composes useListbox and usePopover internally, managing chip creation, removal, keyboard navigation between chips, and optional typeahead integration. Each chip is rendered manually using getItemProps and getRemoveProps — see Primitive for a component-based API that uses Chip sub-components by default.

With Positioner#

When options are provided for typeahead support, use positionerProps, popupProps, listProps, and arrowProps to render the suggestion dropdown.

import { useInputTags } from '@primereact/headless/inputtags';
 
const inputtags = useInputTags({ value: tags, options: filteredItems, optionLabel: 'label', onValueChange: (e) => setTags(e.value), onComplete: search });
const { rootProps, inputProps, getItemProps, getRemoveProps, positionerProps, popupProps, listProps, arrowProps, state, listbox } = inputtags;
 
<div {...rootProps}>
    {state.value.map((tag, index) => (
        <span key={index} {...getItemProps(index)}>
            <button {...getRemoveProps(index)}></button>
        </span>
    ))}
    <input {...inputProps} />
    <div {...positionerProps}>
        <div {...arrowProps} />
        <div {...popupProps}>
            <ul {...listProps}>...</ul>
        </div>
    </div>
</div>;

Features#

  • rootProps, inputProps, hiddenInputProps return spread-ready prop objects for container and input elements
  • getItemProps(index) and getRemoveProps(index) return per-item prop objects with keyboard handlers and ARIA attributes
  • onItemRemoveClick(index) and onRemoveAllItems() for imperative tag removal
  • Optional typeahead via options, onComplete, and built-in positionerProps, popupProps, listProps, arrowProps for dropdown rendering
  • Composes useListbox internally — the returned listbox instance provides option iteration, selection state, and useListboxOption support
  • show() and hide() for imperative overlay control
  • setRendered() controls whether the overlay has been rendered at least once, useful for lazy rendering strategies
  • state.value array for iterating over current tags

Behavior#

Default Value#

Set defaultValue for uncontrolled tag management.

const inputtags = useInputTags({ defaultValue: ['React', 'Vue'] });

Default Input Value#

Set defaultInputValue to provide an initial input text in uncontrolled mode.

const inputtags = useInputTags({ defaultInputValue: 'Vu' });

Controlled#

Pass value and onValueChange for controlled tag state.

const [tags, setTags] = React.useState<string[]>(['React']);
 
const inputtags = useInputTags({
    value: tags,
    onValueChange: (e) => setTags(e.value)
});

Controlled Input Value#

Use inputValue and onInputValueChange to control the text input independently from the tag list. This is useful for custom filtering, clearing the input programmatically, or syncing the query with external state.

const [query, setQuery] = React.useState('');
 
const inputtags = useInputTags({
    inputValue: query,
    onInputValueChange: (e) => setQuery(e.query)
});

Delimiter#

Set delimiter to allow creating tags with a specific character in addition to the Enter key. Supports strings and regular expressions.

const inputtags = useInputTags({ delimiter: ',' });

Max Tags#

Set max to limit the number of tags that can be added.

const inputtags = useInputTags({ max: 5 });

Allow Duplicates#

Set allowDuplicate to permit adding the same tag more than once. Disabled by default.

const inputtags = useInputTags({ allowDuplicate: true });

Add Triggers#

Use addOnBlur to add the current input as a tag when the input loses focus, addOnTab to add on Tab key press, and addOnPaste to split pasted text by the delimiter and add each part as a tag.

const inputtags = useInputTags({ addOnBlur: true, addOnTab: true, addOnPaste: true, delimiter: ',' });

Add and Remove Events#

Use onAdd and onRemove callbacks to respond to individual tag changes.

const inputtags = useInputTags({
    onAdd: (e) => console.log('Added:', e.value),
    onRemove: (e) => console.log('Removed:', e.value)
});

Typeahead#

Pass options, optionLabel, and onComplete to enable suggestion dropdown support. The hook returns positionerProps, popupProps, and listProps to render the dropdown overlay, along with the listbox instance for option iteration.

const { rootProps, inputProps, positionerProps, popupProps, listProps, state, listbox } = useInputTags({
    options: filteredItems,
    optionLabel: 'label'
});

Option Fields#

Use optionLabel, optionValue, optionDisabled, and optionKey to map fields when typeahead options are objects.

const inputtags = useInputTags({
    options: items,
    optionLabel: 'name',
    optionValue: 'code',
    optionDisabled: 'inactive',
    optionKey: 'code'
});

Grouped Options#

Set optionGroupLabel and optionGroupChildren to support grouped option structures in typeahead mode.

const inputtags = useInputTags({
    options: groupedItems,
    optionGroupLabel: 'label',
    optionGroupChildren: 'items'
});

Search Delay#

Set delay to debounce the onComplete callback in milliseconds.

const inputtags = useInputTags({ delay: 300 });

Minimum Length#

Set minLength to require a minimum number of characters before triggering the search.

const inputtags = useInputTags({ minLength: 2 });

Disabled#

Set disabled to prevent all interaction.

const inputtags = useInputTags({ disabled: true });

Use open and onOpenChange for controlled popup state, or defaultOpen for uncontrolled initial state.

const [open, setOpen] = React.useState(false);
 
const inputtags = useInputTags({
    open,
    onOpenChange: (e) => setOpen(e.value)
});

Set closeOnEscape to dismiss the overlay with the Escape key, autoFocus to move focus into the overlay when it opens, and trapped to keep focus within the overlay.

const inputtags = useInputTags({ closeOnEscape: true, autoFocus: true, trapped: true });

Form Integration#

Use name to set the input's name attribute for form submission. A hidden input is also rendered with the joined tag values.

const inputtags = useInputTags({ name: 'technologies' });

Custom Styling with Data Attributes#

Every prop object includes data-scope="inputtags" and a data-part that identifies the element. State-driven attributes appear or disappear automatically.

PartState Attributes
itemaria-selected
popupdata-open

Options rendered via useListboxOption use data-scope="listbox" with the following state attributes.

PartState Attributes
optiondata-selected, data-unselected, data-focused, data-disabled
optionindicatordata-selected, data-unselected
/* Root focus-within ring */
[data-scope='inputtags'][data-part='root']:focus-within {
    border-color: var(--p-primary-color);
    box-shadow: 0 0 0 1px var(--p-primary-color);
}
 
/* Tag item */
[data-scope='inputtags'][data-part='item'] {
    background: var(--p-surface-100);
    border-radius: 4px;
    padding: 2px 8px;
}
[data-scope='inputtags'][data-part='item'][aria-selected='true'] {
    background: var(--p-primary-color);
    color: var(--p-primary-contrast-color);
}
 
/* Popup entrance */
[data-scope='inputtags'][data-part='popup'][data-open] {
    border: 1px solid var(--p-content-border-color);
    border-radius: 6px;
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
 
/* Option states */
[data-scope='listbox'][data-part='option'][data-focused] {
    background: var(--p-surface-100);
}
[data-scope='listbox'][data-part='option'][data-selected] {
    background: var(--p-primary-color);
    color: var(--p-primary-contrast-color);
}
[data-scope='listbox'][data-part='option'][data-disabled] {
    opacity: 0.5;
    pointer-events: none;
}

API#

useInputTags#

NameTypeDefault
valuestring[]—
Value of the items.
defaultValuestring[]—
Default value of the items.
inputValuestring—
Value of the input field (controlled).
defaultInputValuestring—
Default value of the input field.
openboolean—
Controlled open state of the input tags overlay.
defaultOpenboolean—
Default open state for uncontrolled mode.
namestring—
The name attribute for the element, typically used in form submissions.
disabledbooleanfalse
When present, it specifies that the component should be disabled.
maxnumber—
Maximum number of items allowed.
delimiterstring | RegExp—
Delimiter character or regex to split input into items.
allowDuplicateboolean—
Whether to allow duplicate items.
addOnBlurboolean—
Whether to add item on blur event.
addOnPasteboolean—
Whether to add item on paste event.
addOnTabboolean—
Whether to add item on tab key press.
optionsunknown[]—
An array of options to display in dropdown.
optionKeystring—
Unique key for each option.
optionLabelstring—
Label field for each option.
optionValuestring—
Value field for each option.
optionDisabledstring—
Field to check if an option is disabled.
optionGroupLabelstring—
Label field for option groups.
optionGroupChildrenstring—
Field that contains the children options in a group.
delaynumber—
Delay between keystrokes to wait before sending a query.
minLengthnumber—
Minimum number of characters to initiate a search.
appendTo"body" | HTMLElement | "self"—
A valid query selector or an HTMLElement to specify where the overlay gets attached.
closeOnEscapeboolean—
When enabled, the overlay closes when Escape key is pressed.
autoFocusboolean—
When enabled, the overlay receives focus automatically when opened.
trappedboolean—
When enabled, focus is trapped within the overlay.
onValueChange(event: useInputTagsValueChangeEvent) => void—
Callback to invoke when value changes.
onAdd(event: useInputTagsAddEvent) => void—
Callback to invoke when a item is added.
onRemove(event: useInputTagsRemoveEvent) => void—
Callback to invoke when a item is removed.
onInputValueChange(event: useInputTagsInputValueChangeEvent) => void—
Callback when the input value changes.
onComplete(event: useInputTagsCompleteEvent) => void—
Callback to invoke to search for suggestions.
onOpenChange(event: useInputTagsOpenChangeEvent) => void—
Callback to invoke when the open state changes.

Accessibility#

See InputTags Primitive for WAI-ARIA compliance details and keyboard support.