PickList
Available on the left, chosen on the right.
About
Two-pane transfer list, available first and chosen second in reading order, for column choosers and report builders. Rows cross by the transfer controls, by pointer drag between or within the panes, or by a keyboard lift. Drag is never the only path; dragOnly hides the controls but the keyboard lift stays.
Usage
Basic
Rows in each pane are options in a listbox with one tab stop per pane. A row is { value, label } and takes the optional fields a sui-list row draws, so two columns with one label stay two rows. Every keyboard move is announced in a live region, so the transfer never needs a pointer.
Checkbox selection
selection-mode="checkbox" puts a box on every row under a select-all header per pane, and the transfer controls carry the whole ticked set at once. Ticks live in one pane at a time: ticking in the other clears the first, because every control and both crossing arrow keys act on the pane that holds the selection.
Nothing ticked.
Filter
Each pane gets its own box, named after that pane. Narrowing a pane to find the rows you want and moving them across is the point, so a transfer still runs while a box has text; only a move inside that pane waits for it to empty.
Nothing chosen yet
An empty pane reads "Nothing here yet." until a row lands in it, or empty-message when set, and "Drop here" while a drag is in flight; a filter that finds nothing reads empty-filter-message. The header count tracks each pane.
Drag only, controls only
drag-only hides the four transfer controls, and no-drag removes the pointer drag and the insertion indicator for a touch surface where a long press already means something else. The keyboard lift stays in both.
Loading and stacked
loading holds the controls and puts one loading row in each pane while the lists are on their way. breakpoint is the frame width under which the panes stack with the controls between them, 640 unless set and measured by the element itself, so a pick list in a narrow column stacks whatever the screen is.
Events
suiSelectionChange carries the new selection, the picked values; a transfer carries the picks with their rows and does not fire it. suiSourceChange and suiTargetChange carry each pane after a transfer or reorder that changed it, so saving the chosen columns is one listener. None bubbles.
Nothing selected.
Keyboard
| Key | Action |
|---|---|
| Tab | Enters the available pane, then the four transfer buttons, then the chosen pane. Each pane is one tab stop, at the row that has it, and in checkbox mode its select-all header is the stop before it. A transfer button that runs out of rows hands focus to the first row where they landed. |
| Space | In single mode, lifts the focused row, and drops a lifted row where it is. In checkbox mode, ticks the focused row. On a select-all header, ticks every row that pane shows, or clears them. |
| Enter | Lifts the focused row, and drops a lifted row where it is, in both modes. |
| ArrowDown ArrowUp | Moves the tab stop within the pane, and the selection with it in single mode. With a row lifted, moves the row one place. |
| ArrowRight | From the available pane, moves to the chosen pane, at its selected row or else its first. With a row lifted, carries it to the end of the chosen pane. Under dir="rtl" the pair swaps, so the arrow that points along the reading direction is always the forward one. |
| ArrowLeft | From the chosen pane, moves to the available pane, at its selected row or else its first. With a row lifted, carries it to the end of the available pane. |
| Home End | Moves to the first or last row of the pane. With a row lifted, moves the row to the top or bottom. |
| Escape | Cancels a lift and returns the row to the pane and place it started in. |
| ArrowDown ArrowUp stacked | Under the breakpoint the panes stack and the pair crosses between them: ArrowDown past the last available row lands on the chosen pane and ArrowUp from its first row comes back. With a row lifted, ArrowDown carries it to the chosen pane. |
API
<sui-pick-list>
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
breakpoint | breakpoint | number | 640 | Frame width in px under which the two panes stack, the available pane over the chosen one, with the transfer controls in a row between them and their arrows turned. Measured by the element's own observer, so a pane in a narrow column stacks whatever the screen is. Zero keeps the panes side by side at every width. |
dragOnly | drag-only | boolean | false | Hides the four transfer controls (move, move all, remove, remove all); pointer drag and the keyboard lift remain. Reflected. |
emptyFilterMessage | empty-filter-message | stringstring | undefined | Row a pane shows when its filter box narrowed the rows to none. An empty list and a search that found nothing are two states, so this is a second prop; defaults to "No matches.". | |
emptyMessage | empty-message | stringstring | undefined | Row a pane shows when its list holds nothing. Defaults to "Nothing here yet.". | |
filter | filter | boolean | false | Shows a filter box over each pane. It narrows what a pane draws (by label, description and meta), never the source and target arrays. Transfers still run while a pane is filtered, which is the point of filtering a column chooser; reordering inside a filtered pane waits for an empty box. Reflected. |
height | height | number | 240 | Maximum pane height in px before it scrolls (minimum 120). |
loading | loading | boolean | false | The rows are still on their way: one loading row stands in for each pane, the controls are held and the panes are aria-busy. Reflected, so a page can style the wait. |
noDrag | no-drag | boolean | false | Turns off the pointer drag between and within the panes, and its insertion indicator. The transfer controls and the keyboard lift stay. Reflected. |
selection | property only | SuiKey[] | [] | Values of the selected rows, in pane order. The picks live in one pane at a time: picking in the other pane clears them, since every control and every arrow key acts on the pane that holds the selection. Values, not positions, so the selection travels with its rows through a reorder or a transfer; a value no row holds is ignored and dropped at the next change. Mutable; updated before suiSelectionChange fires. Property, not attribute. |
selectionMode | selection-mode | SuiListSelectionMode"checkbox" | "single" | 'single' | single picks one row at a time. checkbox draws a box on every row under a per-pane select-all header, and the transfer controls carry the whole ticked set at once. Reflected. |
source | property only | SuiReorderItem[] | [] | Available rows, { value, label, description?, meta?, icon?, avatar?, initials?, severity? }. value is the row's identity, unique across both panes, so two rows with one label stay two rows. Mutable: a transfer or a reorder writes back here and emits suiSourceChange. Property, not attribute. |
sourceHeading | source-heading | stringstring | undefined | Heading of the available pane, the first in reading order. heading is the settled word across the library. | |
target | property only | SuiReorderItem[] | [] | Chosen rows, in the same shape as source. Mutable: a transfer or a reorder writes back here and emits suiTargetChange. Property, not attribute. |
targetHeading | target-heading | stringstring | undefined | Heading of the chosen pane, the second in reading order. |
Events
| Event | Detail | React | Vue | Description |
|---|---|---|---|---|
suiSelectionChange | SuiKey[] | onSuiSelectionChange | @sui-selection-change | Fires when the selection changes; detail is the new selection, the picked rows' values in pane order. A transfer carries the picks with their rows and does not fire it. Does not bubble. |
suiSourceChange | SuiReorderItem[] | onSuiSourceChange | @sui-source-change | Fires after a transfer or a reorder that changed the available pane; detail is the new source. A transfer changes both panes and fires this, then suiTargetChange. A state report: the pick list is not a form field, so a form around it never hears it. Does not bubble. |
suiTargetChange | SuiReorderItem[] | onSuiTargetChange | @sui-target-change | Fires after a transfer or a reorder that changed the chosen pane; detail is the new target. Does not bubble. |
Methods
| Method | Signature | Description |
|---|---|---|
setFocus() | setFocus() => Promise<void> | Moves keyboard focus to the tab stop of the pane holding the selection (else the first row of the available pane). |
Types
SuiKey typeA record's or an item's key wherever the library identifies one: a row, a tree node, a list item, a selected value. Numbers stay numbers, so a numeric id round-trips through selection, the events and a framework binding without turning into a string. | |||
|---|---|---|---|
| No members. |
SuiListSelectionMode typeHow a reorderable list picks rows: one at a time, or many through checkboxes under a select-all header. sui-order-list and sui-pick-list share it, and it is the same vocabulary sui-tree's selectionMode uses, minus the none a tree can offer and a reorder list cannot: the move controls act on a selection, so a list with no way to select is inert. | |||
|---|---|---|---|
| No members. |
SuiReorderItem interfaceOne row of sui-order-list and sui-pick-list. value is the row's identity, which selection holds and which keeps two rows with one label apart; label is what the row reads. The optional fields are the ones a sui-list row draws: a supporting line, a trailing figure and a leading disc. | |||
|---|---|---|---|
value | SuiKey | Identity, unique in the list (in both panes of a pick list), kept as given. | |
label | string | The row's text, and what the filter box, the announcements and a drag carry. | |
description? | string | Supporting line under the label. | |
meta? | string | Trailing text on the label line in tabular figures: a count, a date. | |
icon? | string | Font Awesome class drawn in a neutral disc before the text. | |
avatar? | string | Image URL for an avatar disc before the text; wins over severity and icon. | |
initials? | string | Letters for an avatar disc without an image. | |
severity? | SuiSeverity | Status disc before the text, on the shared ladder; wins over icon. | |
SuiSeverity type | |||
|---|---|---|---|
| No members. |
Theming
Every design token this element can render with, read from its own stylesheets and the ones it imports. Set a token on :root or on any ancestor and every use below follows it. The values shown are the ones in the theme you are viewing. The list is read per stylesheet, so an element that imports a shared drawing module lists that module's tokens too, whether or not it paints with all of them.
Color31
Typography1
Spacing and size4
Radius3
Elevation2
Motion2
Every name above is listed with its value and its role in Foundations.