Inputs@knitui/components
TagsInput
Free-text tags input built on Combobox + PillsInput. Tags are committed on Enter, a split character (default ,), or blur, and render as removable Pills. Optionally accepts data suggestions shown in a dropdown.
import { TagsInput } from "@knitui/components";Playground
Loading playground…
<TagsInput
placeholder="Add tag…"
size="sm"
disabled={false}
readOnly={false}
clearable={false}
/>Examples
Sizes
All seven sizes rendered side by side so metrics can be compared at a glance.
Loading example…
Shadows
The shadow elevation prop, inherited from Box, across all token levels.
Loading example…
Disabled
Disabled state — the field and remove buttons are inert.
Loading example…
Read Only
Read-only state — the dropdown opens but tags cannot be added or removed.
Loading example…
With Field Chrome
With label, description, and inline error message to verify field chrome.
Loading example…
With Suggestions
Suggestions dropdown — type to filter; pick an option to add it as a tag.
Loading example…
Clearable
Clearable — shows an × button when at least one tag is present.
Loading example…
Max Tags
Maximum tags — adding more than maxTags is silently ignored.
Loading example…
Controlled
Controlled — the parent owns the tag list and wires onChange.
Loading example…
Styles
Per-slot styles targets individual parts — here the pill and trigger.
Loading example…
Props
| Prop | Type | Default | Description |
|---|---|---|---|
acceptValueOnBlur | boolean | undefined | true | Commit the pending typed value on blur. |
allowDuplicates | boolean | undefined | false | Allow duplicate tags. |
clearable | boolean | undefined | false | Show a clear button when there is a value. |
clearButtonProps | Partial<ComboboxClearButtonProps> | undefined | — | Props forwarded to the internal clear `Combobox.ClearButton`. |
clearSearchOnChange | boolean | undefined | true | Clear the search field after a tag is added. |
clearSectionMode | "default" | "clear" | "rightSection" | "both" | undefined | 'both' | How the clear button and right section coexist. |
comboboxProps | Partial<ComboboxProps> | undefined | — | Props forwarded to the underlying `Combobox`. |
data | ComboboxData | undefined | — | Suggestion options shown in the dropdown. |
defaultDropdownOpened | boolean | undefined | — | Uncontrolled initial dropdown opened state. |
defaultSearchValue | string | undefined | — | Uncontrolled initial search value. |
defaultValue | string[] | undefined | — | Uncontrolled initial tags. |
description | ReactNode | — | |
descriptionProps | GetFinalProps<RNTamaguiTextNonStyleProps, TextStylePropsBase, { span?: boolean | undefined; size?: string | number | undefined; inherit?: boolean | undefined; lineClamp?: number | undefined; truncate?: boolean | "end" | "start" | undefined;… | — | |
disabled system | boolean | undefined | false | |
dropdownOpened | boolean | undefined | — | Controlled dropdown opened state. |
error | ReactNode | — | |
errorProps | GetFinalProps<RNTamaguiTextNonStyleProps, TextStylePropsBase, { span?: boolean | undefined; size?: string | number | undefined; inherit?: boolean | undefined; lineClamp?: number | undefined; truncate?: boolean | "end" | "start" | undefined;… | — | |
filter | OptionsFilter | undefined | a case-insensitive label substring match. | Custom options filter for the suggestions. |
form | string | undefined | — | Associated `<form>` id for the hidden input. |
hiddenInputName | string | undefined | — | Hidden web-form input name (renders a comma-joined hidden field). |
hiddenInputValuesDivider | string | undefined | ',' | Divider for the hidden input value. |
id | string | undefined | — | Same as the web id property for setting a uid on an element |
inputContainer | ((children: ReactNode) => ReactNode) | undefined | — | |
inputSize | string | undefined | — | Host size attribute for the input element |
inputWrapperOrder | InputWrapperOrderItem[] | undefined | — | |
isDuplicate | ((value: string, current: string[]) => boolean) | undefined | — | Custom duplicate check. Defaults to a case-insensitive match. |
label | ReactNode | — | |
labelElement | "div" | "label" | undefined | — | |
labelProps | InputLabelProps | undefined | — | |
leftSection | ReactNode | — | Content section displayed on the left side of the input |
leftSectionPointerEvents | InputSectionPointerEvents | undefined | "none" | Sets pointer-events styles on the left section element |
leftSectionProps | Partial<GetFinalProps<RNTamaguiViewNonStyleProps, StackStyleBase, { shadow?: "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined; sectionPointerEvents?: "none" | "all" | undefined; }>> | undefined | — | Props passed down to the left section element |
leftSectionWidth | number | Animated.AnimatedNode | GetThemeValueForKey<"width"> | null | undefined | — | Left section width, by default equals to the input height |
limit | number | undefined | Infinity | Maximum number of suggestions displayed. |
loading | boolean | undefined | — | Displays loading indicator in the left or right section |
loadingPosition | "left" | "right" | undefined | "right" | Position of the loading indicator |
maxDropdownHeight | number | undefined | 250 | Max dropdown height in px before scrolling. |
maxTags | number | undefined | Infinity | Maximum number of tags. |
nothingFoundMessage | ReactNode | — | Message shown when no suggestion matches. |
onBlur | FocusEventHandler<HTMLInputElement> | undefined | — | Field blur handler. |
onChange | ((value: string[]) => void) | undefined | — | Called when the tags change. |
onClear | (() => void) | undefined | — | Called when the clear button is pressed. |
onDropdownClose | (() => void) | undefined | — | Called when the dropdown closes. |
onDropdownOpen | (() => void) | undefined | — | Called when the dropdown opens. |
onDuplicate | ((value: string) => void) | undefined | — | Called when the user tries to add a duplicate tag. |
onFocus | FocusEventHandler<HTMLInputElement> | undefined | — | Field focus handler. |
onKeyDown | KeyboardEventHandler<HTMLInputElement> | undefined | — | Field keydown handler (fires after the built-in behaviour). |
onMaxTags | ((value: string) => void) | undefined | — | Called when the user tries to add more than `maxTags`. |
onOptionSubmit | ((value: string) => void) | undefined | — | Called when a suggestion option is submitted. |
onPaste | ClipboardEventHandler<HTMLInputElement> | undefined | — | Field paste handler (fires before the built-in split-on-paste behaviour). |
onRemove | ((value: string) => void) | undefined | — | Called with the value of a removed tag. |
onSearchChange | ((value: string) => void) | undefined | — | Called when the search value changes. |
placeholder | string | undefined | Add tag… | Placeholder for the inner field. |
pointer | boolean | undefined | — | Determines whether the input should have cursor: pointer style |
radius system | string | number | undefined | — | Key of theme radius or a valid CSS value to set border-radius |
readOnly | boolean | undefined | false | Read-only mode (dropdown opens but tags can't change). |
renderOption | ComboboxRenderOption | undefined | — | Custom suggestion content. Receives `{ option, checked }`. |
renderPill | ComboboxRenderPill | undefined | — | Custom pill content. Receives `{ option, value, onRemove, disabled }`; replaces the built-in `Pill`. |
required | boolean | undefined | — | |
rightSection | ReactNode | — | Content section displayed on the right side of the input |
rightSectionPointerEvents | InputSectionPointerEvents | undefined | "none" | Sets pointer-events styles on the right section element |
rightSectionProps | Partial<GetFinalProps<RNTamaguiViewNonStyleProps, StackStyleBase, { shadow?: "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined; sectionPointerEvents?: "none" | "all" | undefined; }>> | undefined | — | Props passed down to the right section element |
rightSectionWidth | number | Animated.AnimatedNode | GetThemeValueForKey<"width"> | null | undefined | — | Right section width, by default equals to the input height |
searchValue | string | undefined | — | Controlled search value. |
selectFirstOptionOnChange | boolean | undefined | false | Highlight the first matching suggestion after each search change. |
shadow system | "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined | — | |
size system | "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefinedxxs · xs · sm · md · lg · xl · xxl | 'md' | Controls height, padding, and font size of the input and pills. |
splitChars | string[] | undefined | [','] | Characters that trigger a tag split. |
styles system | SlotStyles<TagsInputStyles> | undefined | — | Per-slot style sugar — props spread onto the matching part. |
theme system | ThemeName | null | undefined | — | Applies a theme to this element |
value | string[] | undefined | — | Controlled tags. |
variant system | InputVariant | undefined | "default" | Visual variant |
withAsterisk | boolean | undefined | — | |
withScrollArea | boolean | undefined | true | Wrap suggestions in a `ScrollArea.Autosize`. |
wrapperProps | Partial<GetFinalProps<RNTamaguiViewNonStyleProps, StackStyleBase, { radius?: string | number | undefined; size?: string | number | undefined; shadow?: "xs" | "sm" | "md" | "lg" | "xl" | "xxs" | "xxl" | undefined; disabled?: boolean | undefi… | — |
Style slots
Every part of TagsInput can be styled through the styles prop. Explicit props on the component always win over slot styles.
| Slot | Usage |
|---|---|
clearButton | styles={{ clearButton: { … } }} |
dropdown | styles={{ dropdown: { … } }} |
empty | styles={{ empty: { … } }} |
group | styles={{ group: { … } }} |
option | styles={{ option: { … } }} |
options | styles={{ options: { … } }} |
pill | styles={{ pill: { … } }} |
pills | styles={{ pills: { … } }} |
root | styles={{ root: { … } }} |
trigger | styles={{ trigger: { … } }} |
Accessibility & DOM props (2)
| Prop | Type |
|---|---|
key | Key | null | undefined |
ref | Ref<(HTMLElement & TamaguiElementMethods) | View> | undefined |
Plus 491 inherited style props from Box — the full Tamagui/React Native style surface, including token shorthands like p, mx, bg and c. See Tokens for the scales they accept, or the full list.