Prodular UI

Inputs

Multi-select

Pick several values from a list as chips, with groups, descriptions, select all and options that load from a server as people type.

npx prodular-ui add multi-select

Grouped with select all

Options grouped by team with a second line. Select all respects disabled options and the current filter.

Grouped by team. Elena is on leave until November 3 and cannot be picked. 2 of 8 selected.

Async search

loadOptions runs after a short pause in typing and cancels the previous request. Chips keep their labels as results change.

Results load as you type. Chips past the second collapse into a count.

Short list

A plain list with a hidden input per value for form posts.

Anatomy

<Field>  <FieldLabel>Approvers</FieldLabel>  <MultiSelect options={people} value={ids} onValueChange={setIds} selectAll /></Field>

Guidance

Use it when

  • Choosing several items from a known set: people, customers, labels, channels, regions.
  • loadOptions when the list is long or lives on the server.
  • selectAll when picking everything is a real case, like notifying every team.

Avoid

  • Two to five options that all fit on screen. Use a Checkbox group, it is faster to scan.
  • Free-form values people type, like email addresses. Use Tag input.

Rules for AI agents

Published in llms-full.txt and the registry, so coding agents follow them when they build with this component.

  • Give it a visible label with Field and FieldLabel, or aria-label.
  • Keep values as stable ids and labels as display names. onValueChange returns ids.
  • With loadOptions, honor the AbortSignal and return at most 20 results; ask people to type more instead of returning thousands.
  • Set maxChips so the field stays one or two lines tall; the rest collapse into +N.
  • Mark options people cannot pick as disabled and explain why in FieldDescription, do not hide them.

API

MultiSelect

PropTypeDefaultDescription
options{ value, label, description?, group?, icon?, disabled? }[]A fixed list, filtered as people type. Options with a group are listed under a heading.
loadOptions(query, signal) => Promise<Option[]>Loads options for a query instead of options.
value / defaultValue / onValueChangestring[]Selected option values.
maxChipsnumber3Chips shown before the rest collapse into +N.
selectAllbooleanfalseSelect all and Clear selection above the list.
emptyText / placeholderstringCopy for no matches and for an empty field.
namestringRenders one hidden input per value for form posts.