|Kit

MultiComboboxList

A searchable, multi-value option list with checkboxes and no trigger of its own — embed it inline inside a Popover, Drawer, or panel you already control.

MultiComboboxList is MultiSelect's data contract without the trigger or the pills: a search box and a checkbox list that render permanently open, for embedding inside a container you already own the visibility of (a Popover, a Drawer, a custom panel). Picking an option toggles its checkbox without closing the list — same idea as ComboboxList, just for several values at once. It's what powers DataTable's multi-select column filter.

'use client';
import { MultiComboboxList } from '@42/ui-react/multi-combobox-list';

<MultiComboboxList data={['Libft', 'ft_printf', 'Get Next Line']} defaultValue={['Libft']} />

For a self-contained trigger with pills in the field, use MultiSelect instead — same data / value / onChange contract. For the single-value equivalent see ComboboxList.

The playground below renders the list bare, on the page — in real use it almost always sits inside something else that owns the open/close state (see ComboboxList's Popover example).

Playground

Component

SpinnerLoading preview

Props

Code

<Component placeholder="Search…" size="md" />

Checkboxes, not pills

Every option shows a checkbox instead of a check mark; picking one adds it to the selection and keeps the list open so you can keep picking. data accepts the same shapes as MultiSelect — strings, objects, or groups.

Paris
Lyon
Nice
Le Havre
Berlin
Madrid
Lisbon
Helsinki

Hide picked options

With hidePickedOptions, chosen values drop out of the list so it only ever shows what's still addable.

Cub3D
Fract-ol
ft_printf
ft_transcendence
Get Next Line
Inception
Libft
Minishell

Max values

maxValues caps the selection — once reached, adding more is rejected (removals still work).

Born2beroot
CPP Modules
Cub3D
Fract-ol
ft_printf
ft_transcendence
Get Next Line
Inception
Libft
Minishell

Clearable

clearable adds a button that clears every value at once.

Born2beroot
CPP Modules
Cub3D
Fract-ol
ft_printf
ft_transcendence
Get Next Line
Inception
Libft
Minishell

Custom rendering

renderItem owns each row's whole content — the same (item, state) => ReactNode renderer as Select's, with item being { value, label, disabled } and state { selected, highlighted }. It fully replaces the default checkbox + label row, so if you still want a selected affordance, draw your own from state.selected.

boBorn2beroot360 XP
cpCPP Modules480 XP
cuCub3D690 XP
frFract-ol420 XP
ftft_printf240 XP
ftft_transcendence2100 XP
geGet Next Line240 XP
inInception945 XP
liLibft360 XP
miMinishell1080 XP

Label, description & error

Built in via Field, like the rest of the family — though most of the time you'll omit them here, since the container embedding this (a filter popover, a drawer) usually carries its own label.

Born2beroot
CPP Modules
Cub3D
Fract-ol
ft_printf
ft_transcendence
Get Next Line
Inception
Libft
Minishell
Pick as many as you like

Controlled

value is a string[]; onChange hands you the full selection on every add or remove.

'use client';
import { useState } from 'react';
import { MultiComboboxList } from '@42/ui-react/multi-combobox-list';

export function ProjectList() {
  const [value, setValue] = useState<string[]>([]);
  return (
    <MultiComboboxList
      data={['Libft', 'ft_printf', 'Get Next Line']}
      value={value}
      onChange={setValue}
      clearable
    />
  );
}

Forms

A name renders one hidden input per selected value, so it wires into native <form> submission and FormData — the search input itself is never named (it would submit the typed query, not the selection).

<form action={save}>
  <MultiComboboxList name="projects" data={['Libft', 'ft_printf', 'Get Next Line']} />
</form>

API

Prop

Type

Accessibility

  • Full combobox keyboard model from Ark: type to filter, / to move, Enter to toggle an option, Esc handled by the embedding container.
  • role="combobox" on the search input with aria-expanded="true" (it is permanently open), role="option" with aria-selected on each row, aria-multiselectable on the list.
  • There's no trigger and no floating panel — accessibility for the open/close affordance (focus return, Esc handling, aria-haspopup) is the embedding container's job (e.g. Popover already provides it).

On this page