suiss/ui · Interaction
Selection List
A list with an edit mode for selecting multiple rows and acting on them from a floating toolbar.
Selection List is an open-source interaction from suiss/ui for React, React Native, SwiftUI and Jetpack Compose. The @esuiss/ui CLI copies its source into your project, so you own the code.
SelectionList recreates the iOS Select mode for lists. Pressing SelectionListTrigger switches into editing: each SelectionListItem slides in a round checkmark indicator and becomes a checkbox, and SelectionListBar rises from the bottom of the screen as a floating toolbar. The row content is made inert while editing, so taps toggle selection instead of opening the row. Leaving editing clears the selection.
The trigger is a suiss/ui Button that reads Select or Done by default, and SelectionListCount shows how many rows are selected. Use it for lists where people manage several items at once, such as deleting notes or archiving mail.
Installation
CLI
Works in any project with a components.json. See Installation for the one-line registry setup. Or use the suiss/ui CLI:
Manual
- Install the dependencies and add the
cnhelper:
-
Add the pieces it builds on: Button.
-
Copy the source into
components/interactions/selection-list.tsx:
- Update the import paths to match your project.
Usage
- Place
SelectionListTrigger, theSelectionListItemrows, andSelectionListBarinsideSelectionList. Put your own action buttons andSelectionListCountinside the bar. - Editing and selection are each uncontrolled by default. Pass
editingandonEditingChange, orvalueandonValueChange, to control them. useSelectionListreturnsediting,setEditing,selected,setSelected,selectAll, andclearfor building actions such as Select All or Delete.- Shift-clicking a row, or pressing
ShiftwithEnterorSpace, selects the range from the previously toggled row. Escapeleaves editing.
Examples
Icon actions
A controlled selection drives icon-only toolbar actions that stay disabled until a row is picked.
API Reference
SelectionList
The root that holds the editing state and the selected values.
| Prop | Type | Default | Description |
|---|---|---|---|
editing | boolean | - | Whether the list is in editing mode, for controlled use. |
defaultEditing | boolean | false | Whether the list starts in editing mode when uncontrolled. |
onEditingChange | (editing: boolean) => void | - | Called when editing mode turns on or off. |
value | string[] | - | The selected row values, for controlled use. |
defaultValue | string[] | [] | The rows selected initially when uncontrolled. |
onValueChange | (value: string[]) => void | - | Called with the new array of selected values. |
Also accepts the props of React.ComponentProps<"div">.
SelectionListTrigger
The button that enters and leaves editing.
Also accepts the props of React.ComponentProps<typeof Button>.
SelectionListItem
A row that becomes a selectable checkbox while editing.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | Required | The unique value that identifies the row in the selection. |
Also accepts the props of React.ComponentProps<"div">.
SelectionListBar
The floating toolbar shown while editing.
Also accepts the props of React.ComponentProps<"div">.
SelectionListCount
A live label with the number of selected rows.
Also accepts the props of React.ComponentProps<"span">.
Accessibility
SelectionListTriggersetsaria-pressedwhile editing.- In editing mode, each row has
role="checkbox"witharia-checked, is focusable, and toggles withEnterorSpace. Its accessible name comes from the row's text unless you setaria-label. SelectionListBarhasrole="toolbar"and isinertwhile not editing; give it anaria-label.SelectionListCountis a polite live region, so selection changes are announced.
Notes
- The root sets
data-editingwhile editing, available to children as thegroup/selection-listTailwind group. Rows exposedata-valueanddata-checked. - Parts use
data-slotvaluesselection-list,selection-list-trigger,selection-list-item,selection-list-indicator,selection-list-item-content,selection-list-bar, andselection-list-count. - The bar is fixed to the bottom of the viewport, so leave room below the list for it.

SelectionList switches a list between normal and editing modes. In editing mode each SelectionListItem slides in a check circle at its start, the whole row toggles on press, and selected rows are highlighted.
SelectionListBar floats above the bottom safe area while editing, sliding up into view, for actions such as delete or move. Leaving editing mode clears the selection. On Android the hardware back button also leaves it. Use it for mail, notes or photo lists that need bulk actions.
Installation
The CLI also adds what it builds on: Button, Icon, Text. On React Native it also adds the animated view components/ui/animated-view.tsx.
Manual
- Install the dependencies:
-
Add the pieces it builds on: Button, Icon, Text, and the primitives
components/primitives/hooks.tsx,components/primitives/portal.tsx, and the animated viewcomponents/ui/animated-view.tsxfrom the next step. -
Copy the animated view into
components/ui/animated-view.tsx:
- Copy the source into
components/interactions/selection-list.tsx:
- Update the import paths to match your project.
- Install the dependencies:
-
Add the pieces it builds on: Button, Icon, Text, and the primitives
components/primitives/hooks.tsx,components/primitives/portal.tsx, and the animated viewcomponents/ui/animated-view.tsxfrom the next step. -
Copy the animated view into
components/ui/animated-view.tsx:
- Copy the source into
components/interactions/selection-list.tsx:
- Update the import paths to match your project.
- Install the dependencies:
-
Add the pieces it builds on: Button, Icon, Text, and the primitives
components/primitives/hooks.tsx,components/primitives/portal.tsx, and the animated viewcomponents/ui/animated-view.tsxfrom the next step. -
Copy the animated view into
components/ui/animated-view.tsx:
- Copy the source into
components/interactions/selection-list.tsx:
- Update the import paths to match your project.
-
Target iOS 17 or later.
-
Add the Swift package to your app:
- Copy the theme files every view uses:
- Copy the source and every file it uses:
- Add the files to your app target.
- Set
minSdkto 24 or higher and add the dependencies:
- Copy the theme files every view uses:
- Copy the source and every file it uses:
- Update the
com.esuiss.uipackage names to match your project.
Usage
Wrap the list in SelectionList, add a SelectionListTrigger that toggles editing (it reads Select and Done by default), and give each SelectionListItem a unique value. Put your buttons and a SelectionListCount in SelectionListBar.
Editing and the selection can be uncontrolled with defaultEditing and defaultValue, or controlled with editing, onEditingChange, value and onValueChange. useSelectionList returns editing, selected, toggle, selectAll and clear for custom actions. Outside editing mode, the row's children receive presses as usual.
Examples
Editing
Starts in editing mode with two notes selected.

Icon actions
A mail list whose bar holds icon-only actions.
API Reference
SelectionList
The root that holds the editing state and selection.
| Prop | Type | Default | Description |
|---|---|---|---|
editing | boolean | - | Controls editing mode. |
defaultEditing | boolean | false | Whether editing starts on when uncontrolled. |
onEditingChange | (editing: boolean) => void | - | Called when editing turns on or off. |
value | string[] | - | Selected item values when controlled. |
defaultValue | string[] | EMPTY | Initially selected values when uncontrolled. |
onValueChange | (value: string[]) => void | - | Called with the new selection. |
Also accepts the props of ViewProps.
SelectionListTrigger
A plain button that toggles editing.
Also accepts the props of React.ComponentProps<typeof Button>.
SelectionListItem
A row that toggles its value while editing.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | Required | The value this row adds to the selection. |
children | React.ReactNode | - |
Also accepts the props of React.ComponentProps<typeof Pressable>.
SelectionListBar
A floating toolbar shown while editing.
| Prop | Type | Default | Description |
|---|---|---|---|
portalHost | string | - | Name of a portal host to render into. |
Also accepts the props of ViewProps.
SelectionListCount
Text showing the number of selected items.
Also accepts the props of React.ComponentProps<typeof Text>.
Accessibility
- While editing, rows have the
checkboxrole and expose theircheckedstate; otherwise the row wrapper is not focusable and its children are. - The trigger exposes a
selectedstate while editing. - The bar has the
toolbarrole. SelectionListCountis a polite live region, readingSelect itemsorn selectedby default.
Notes
- Selected rows use
bg-accent; checked circles usebg-primarywith aprimary-foregroundcheck. - The bar uses
bg-card, orbg-mutedin dark mode, and is up tomax-w-mdwide. - Animations respect the system reduce motion setting.

