Skip to content

ListPicker

Edits a list field, offering the vocabulary its schema declares.

It is the shared picker control with rows from the field’s valid values. The set is fixed and read once, so there is no search row unless a caller asks for one, and the control is the summary trigger: the value reads as plain text, the way a select does.

Single and multi: ListMultiPicker takes several values.

Terminal window
pnpm dlx shadcn@latest add https://sg-widgets.vercel.app/r/react/list-picker.json
Terminal window
pnpm dlx shadcn-svelte@latest add https://sg-widgets.vercel.app/r/svelte/list-picker.json
ListPicker: valid values, labels, a project's hidden values removed, a search box, and a mandatory field

React

Loading the React demo…

Svelte

Loading the Svelte demo…

chosen emitted
a row that row’s value, byte for byte
the clear control null

The offered set is the field’s valid values, minus its hidden values when a project id is given. A row already holding a value outside that set keeps a row of its own, labelled with the value.

proptypedefaultmeaning
valuestring | nullnullThe stored string. Two-way in Svelte.
onValueChange(value: string | null) => void—Called on every change.
fieldPick<FieldSchema, 'displayName' | 'mandatory' | 'validValues' | 'displayValues' | 'hiddenValues'> | nullnullSupplies the valid values, the labels and the hidden values.
projectIdnumber—Given, the field's hidden values are removed from the list.
optionsListOption[]—The set on offer, of the caller's own making. Wins over the field.
showCodebooleanfalseDraws the stored string as a row's right-aligned secondary, where it says more than the label.
secondary(option) => stringthe valueA row's right-aligned value, of the caller's own making.
subLabel(option) => string—The muted line under a row's label.
loadErrorstring | nullnullWhat a caller's read failed with, drawn in place of the list.
class / classNamestring—Merged after the widget's own classes.
slotstring'list-picker'The data-slot prefix every part of this picker carries.
pickerstring'list'The data-picker the popup carries.
searchablebooleanfalseOffers a search box, which narrows the set in the browser.
sizefrom PickerControl'sm' | 'md' | 'lg''md'Control height: 7, 8 and 9.
disabledbooleanfalseGreys the control and takes it out of the tab order.
readonlybooleanfalseKeeps full contrast and drops the chevron, the popup and the clear control.
invalidbooleanfalseSets aria-invalid and the destructive ring.
clearablebooleanthe fieldOffers a control that clears the value. Unset, it follows the field: a mandatory one is never clearable.
placeholderstring'Choose'Shown while the field is unset.
searchPlaceholderstring'Search values…'Placeholder of the search box.
openfrom PickerControlbooleanrequiredReact: whether the popup is showing.
openfrom PickerControlbooleanfalseSvelte: whether the popup is showing, two-way.
onOpenChangefrom PickerControl(open: boolean) => voidrequiredReact: called when the popup opens or closes.
onOpenChangefrom PickerControl(open: boolean) => void—Svelte: called when the popup opens or closes.
loadingbooleanfalseA caller's read is in flight: skeletons, and the control is inert.
errorstring | nullnullA message from the caller, drawn under the control.
emptyLabelstring'No rows'Shown when the list offers nothing.
loadingLabelstring'Loading…'Names the skeletons a read stands behind, for a screen reader.
errorLabelstring—Shown in place of what the failed read said.
clearLabelfrom PickerControlstring'Clear the selection'
triggerLabelfrom PickerControlstring'Show the options'

Every other attribute is spread onto the root: id, aria-*, data-*, key handlers and a ref to the root element.

A row is the row anatomy of the design rules: the label as the main text and, with showCode, the stored string right-aligned. A value has no picture and no fields of its own, so the row’s leading slot is empty unless a caller fills it and its secondary is a function rather than a field name.

The clear control follows the field. Left unset, clearable reads the field’s schema, and a field the site flags mandatory offers no clear, since clearing it writes a value the site refuses.

eventpayloadwhen
onErrorChangestring | nullThe message changed.

onValueChange fires as soon as a row is chosen, and with null when the value is cleared. onErrorChange fires with null on that same change, so a message the caller set clears when the field is answered.

onOpenChange fires when the popup opens or closes. Svelte also binds it with bind:open.

slotreceivesdraws
markthe optionA row's leading mark. Given, every row carries one.
valueChipthe chosen stringThe control's value, in place of plain text.
errorMessagethe messageThe line under the control.
keydoes
Space, Enter, ↓Opens the list
↑ ↓Move the highlight
typingNarrows the list, where the picker is searchable
EnterChooses the highlighted row and closes
BackspaceIn an empty search box, clears the value
EscCloses the list and keeps the value
TabLeaves the control, or reaches the clear control when there is one
ArrowDown / ArrowUpfrom PickerControlMoves the highlight, and the list scrolls it into view.
Enterfrom PickerControlTakes the highlighted row. A multi picker keeps the popup open.
Escapefrom PickerControlCloses the popup and clears the query. On a closed picker it does nothing.
Backspacefrom PickerControlIn an empty query: takes the caret to the last chip of a multi picker; clears a single one.
ArrowLeft / ArrowRightfrom PickerControlOn a chip, walks the row. ArrowRight past the last chip returns to the input.
Deletefrom PickerControlOn a chip, removes it and leaves the caret on its neighbour.
Tabfrom PickerControlLeaves the control.

Despite the name a list field holds one bare string. A write outside valid_values is a 400 and case-sensitive, down to a trailing space, so the schema’s vocabulary is the whole set a picker may offer (field_types/list).

A filter is case-insensitive where a write is not, so a value read out of a filter is never safe to write back (field_types/list).

Hidden values reach the schema only when it is read with a project id, and REST does not enforce them on write, so the subtraction is the client’s (probe 009).