MultiSelect
Pick several values, shown as removable pills in a wrapping, searchable input — the whole family working together (Combobox + PillsInput + Pill).
MultiSelect lets the user pick several values, rendered as removable Pills in a wrapping PillsInput-style field, searchable by default. It's the whole family in one component: the Combobox engine (in multiple mode) drives selection, the control is the pills shell, and each value is a Pill.
import { MultiSelect } from '@42/ui-react/multi-select';
<MultiSelect
data={['Libft', 'ft_printf', 'Get Next Line', 'Minishell']}
defaultValue={['Libft']}
placeholder="Pick projects"
/>Playground
Component
Dir
Presets
Props
Code
<Component placeholder="Pick a project" clearSectionMode="replace" size="md"/>Adding & removing
Type to filter, pick to add — a check marks selected options. Remove a value with its pill's ×, Backspace on the empty field, or the clear button (clearable). data accepts the same shapes as Select, including groups.
Hide picked options
With hidePickedOptions, chosen values drop out of the dropdown so the list only ever shows what's still addable.
Max values
maxValues caps the selection — once reached, adding more is rejected (removals still work).
Not searchable
searchable={false} turns it into a click-to-open multi-picker — the field no longer filters, it just toggles the dropdown.
Max lines
maxLines caps the pills at N rows; any beyond collapse into a static +N counter (it's measured, so it adapts to the field's width). The hidden values stay selected and submitted — deselect them from the dropdown.
Start & end slots
startSlot and endSlot place content at the field's inline-start / inline-end with the same slot layout as Input. endSlot renders before the built-in clear button and chevron.
Code
import { Search } from 'lucide-react';<MultiSelectdata={['Libft', 'ft_printf', 'Get Next Line', 'Minishell']}defaultValue={['Libft']}startSlot={<Search />}placeholder="Pick projects"/>Custom rendering
renderItem owns each dropdown option's content — the same (item, state) => ReactNode renderer as Select, with item being { value, label, disabled } and state { selected, highlighted }. The pills in the field still render from the label; only the dropdown rows change. Define the function in a "use client" module so it survives the server → client boundary.
Typed payload
Attach arbitrary data to an item via payload and read it back as item.payload in renderItem — inferred from data, and undefined for bare-string or payload-less items. Only the dropdown rows see it; the pills still render the label.
'use client';
import { Badge } from '@42/ui-react/badge';
const projects = [
{ value: 'libft', label: 'Libft', payload: { xp: 420 } },
{ value: 'webserv', label: 'Webserv', payload: { xp: 1340 } },
];
// item.payload is inferred as { xp: number } | undefined
const renderOption = (item) => (
<span className="flex flex-1 items-center justify-between gap-2">
{item.label}
{item.payload && <Badge>{item.payload.xp} XP</Badge>}
</span>
);
<MultiSelect data={projects} renderItem={renderOption} />Controlled
value is a string[]; onChange hands you the full selection on every add or remove.
'use client';
import { useState } from 'react';
import { MultiSelect } from '@42/ui-react/multi-select';
export function ProjectPicker() {
const [value, setValue] = useState<string[]>([]);
return (
<MultiSelect
data={['Libft', 'ft_printf', 'Get Next Line', 'Minishell']}
value={value}
onChange={setValue}
clearable
/>
);
}Label, description & error
Built-in via Field, like the rest of the family:
Code
<MultiSelectlabel="Projects"description="Pick all that apply"data={['Libft', 'ft_printf', 'Get Next Line']}defaultValue={['Libft']}/>API
Prop
Type
Accessibility
- Full combobox keyboard model from Ark: type to filter,
↑/↓to move,Enterto toggle an option,Backspaceon the empty field to remove the last value,Escto close. - Each pill's × is an independently focusable, labelled button;
role="combobox"/listbox/optionand the active-descendant wiring come from the Ark machine, with label / description / error associated via the built-inField. - RTL: the pills, field, and dropdown all mirror under
dir="rtl".
Select
Data-driven single-value picker on Ark UI's Select machine — pass data, get a styled trigger, dropdown, native form submission, typeahead, and full keyboard / RTL / ARIA.
TreeSelect
Pick a single value from hierarchical data — an always-expanded tree in a Popover where only leaves are selectable.