Inputs@knitui/components
MultiSelect
MultiSelect renders selected values as removable pills inside a PillsInput, backed by a Combobox dropdown. It supports controlled/uncontrolled values, search, grouped options, a max-values cap, and a clear button. Accent follows the active Tamagui theme via the palette ramp.
import { MultiSelect } from "@knitui/components";Playground
Loading playground…
<MultiSelect
data={["React", "Vue", "Svelte", "Angular", "Solid", "Qwik", "Ember"]}
placeholder="Pick a framework"
size="sm"
searchable={false}
clearable={false}
disabled={false}
readOnly={false}
/>Examples
Sizes
The seven sizes side by side with a pre-selected value so pills are visible.
Loading example…
Shadows
Each elevation of the inherited shadow prop applied to the field frame.
Loading example…
Disabled
Disabled state — pills render but the dropdown cannot be opened and values cannot change.
Loading example…
Read Only
ReadOnly mode — the dropdown opens but selecting and removing values is not possible.
Loading example…
Searchable
Searchable — the field accepts keyboard input to filter the options list.
Loading example…
Clearable
Clearable — a clear button appears once at least one value is selected.
Loading example…
Max Values
MaxValues — limits selection to two items; onMaxValues fires when the cap is hit.
Loading example…
Grouped
Grouped options — data contains { group, items } entries rendered under section headers.
Loading example…
With Label
WithLabel — label, description and error props attach accessible text around the field.
Loading example…
Hide Picked Options
HidePickedOptions — already-selected values disappear from the dropdown.
Loading example…
Custom Render Option
CustomRenderOption — each option renders with a custom icon alongside its label.
Loading example…
Styles
Per-slot styles targets individual parts — here the pill chips and the dropdown option rows.
Loading example…
Controlled
Controlled — value and onChange are wired to React state; pills reflect external state.
Loading example…
Props
| Prop | Type | Default | Description |
|---|---|---|---|
checkIconPosition | "left" | "right" | undefined | 'left' | Side the check icon renders on. |
clearable | boolean | undefined | false | Show a clear button when at least one value is selected. |
clearButtonProps | Partial<ComboboxClearButtonProps> | undefined | — | Props forwarded to the internal clear `Combobox.ClearButton`. |
clearSearchOnChange | boolean | undefined | true | Clear the search field after a value is selected. |
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 | — | Options to render. Strings, `{ value, label, disabled }`, or groups. |
defaultDropdownOpened | boolean | undefined | — | Uncontrolled initial dropdown opened state. |
defaultSearchValue | string | undefined | — | Uncontrolled initial search value. |
defaultValue | string[] | undefined | — | Uncontrolled initial values. |
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. |
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. |
hidePickedOptions | boolean | undefined | false | Hide already-selected options from the dropdown. |
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 | — | |
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 options 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. |
maxValues | number | undefined | Infinity | Maximum number of values that can be selected. |
nothingFoundMessage | ReactNode | — | Message shown when no option matches / data is empty. |
onBlur | FocusEventHandler<HTMLInputElement> | undefined | — | Field blur handler (forwarded to the inner field). |
onChange | ((value: string[]) => void) | undefined | — | Called when the selected values 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. |
onFocus | FocusEventHandler<HTMLInputElement> | undefined | — | Field focus handler (forwarded to the inner field). |
onKeyDown | KeyboardEventHandler<HTMLInputElement> | undefined | — | Field keydown handler (fires after the built-in navigation). |
onMaxValues | (() => void) | undefined | — | Called when the user tries to select more than `maxValues`. |
onOptionSubmit | ((value: string) => void) | undefined | — | Called when an option is submitted (before value changes). |
onRemove | ((value: string) => void) | undefined | — | Called with the value of a removed item. |
onSearchChange | ((value: string) => void) | undefined | — | Called when the search value changes. |
placeholder | string | undefined | Pick a framework | 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 values can't change). |
renderOption | ComboboxRenderOption | undefined | — | Custom option 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 |
searchable | boolean | undefined | false | Allow filtering options by typing into the field. |
searchValue | string | undefined | — | Controlled search value. |
selectFirstOptionOnChange | boolean | undefined | false | Highlight the first matching option 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' | Control size — height, padding, radius and font size. |
styles system | SlotStyles<MultiSelectStyles> | 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 selected values. |
variant system | InputVariant | undefined | "default" | Visual variant |
withAsterisk | boolean | undefined | — | |
withCheckIcon | boolean | undefined | true | Show a check icon next to selected options. |
withScrollArea | boolean | undefined | true | Wrap options 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 MultiSelect can be styled through the styles prop. Explicit props on the component always win over slot styles.
| Slot | Usage |
|---|---|
chevron | styles={{ chevron: { … } }} |
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 492 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.