suiss/uim · Interaction

Selection List

An edit mode for lists where rows slide in check circles, toggle on press, and a floating bar shows bulk actions.

Selection List is an open-source mobile interaction from suiss/uim for React Native and Expo, with SwiftUI and Jetpack Compose versions built from the same design tokens. The @esuiss/uim CLI copies its source into your project, so you own the code.

iOS
Selection List on iOS in light mode

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

$ pnpm dlx @esuiss/uim@latest add selection-list

The CLI also adds what it builds on: Button, Icon, Text.

Manual

  1. Install the dependencies:
npx expo install cn phosphor-react-native react-native-reanimated react-native-safe-area-context react-native-svg react-native-worklets
  1. Add the pieces it builds on: Button, Icon, Text, and the primitives components/primitives/hooks.tsx, components/primitives/portal.tsx.

  2. Copy the source into components/interactions/selection-list.tsx:

uniwind/components/interactions/selection-list.tsx
import { cn } from "cn"
import { CheckIcon } from "phosphor-react-native"
import * as React from "react"
import { Pressable, View, type ViewProps } from "react-native"
import {
  Easing,
  Keyframe,
  ReduceMotion,
  useAnimatedStyle,
  withTiming,
} from "react-native-reanimated"
import { useSafeAreaInsets } from "react-native-safe-area-context"
import { useBackHandler } from "@/components/primitives/hooks"
import { Portal } from "@/components/primitives/portal"
import { AnimatedView } from "@/components/ui/animated-view"
import { Button } from "@/components/ui/button"
  1. Update the import paths to match your project.

Usage

import { SelectionList, SelectionListTrigger, SelectionListItem, SelectionListBar, SelectionListCount } from "@/components/interactions/selection-list"
<NotesExample />

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.

iOS
Selection List (editing) on iOS in light mode

Icon actions

A mail list whose bar holds icon-only actions.

iOS
Selection List (icon actions) on iOS in light mode

API Reference

SelectionList

The root that holds the editing state and selection.

ExtendsViewProps
PropType
About
Controls editing mode.
Type
boolean
Default
—
About
Whether editing starts on when uncontrolled.
Type
boolean
Default
false
About
Called when editing turns on or off.
Type
(editing: boolean) => void
Default
—
About
Selected item values when controlled.
Type
string[]
Default
—
About
Initially selected values when uncontrolled.
Type
string[]
Default
EMPTY
About
Called with the new selection.
Type
(value: string[]) => void
Default
—

SelectionListTrigger

A plain button that toggles editing.

ExtendsReact.ComponentProps<typeof Button>

SelectionListItem

A row that toggles its value while editing.

ExtendsReact.ComponentProps<typeof Pressable>
PropType
About
The value this row adds to the selection.
Type
string
Default
required
Type
React.ReactNode
Default
—

SelectionListBar

A floating toolbar shown while editing.

ExtendsViewProps
PropType
About
Name of a portal host to render into.
Type
string
Default
—

SelectionListCount

Text showing the number of selected items.

ExtendsReact.ComponentProps<typeof Text>

Accessibility

  • While editing, rows have the checkbox role and expose their checked state; otherwise the row wrapper is not focusable and its children are.
  • The trigger exposes a selected state while editing.
  • The bar has the toolbar role.
  • SelectionListCount is a polite live region, reading Select items or n selected by default.

Notes

  • Selected rows use bg-item-selected; checked circles use bg-accent with an on-accent check.
  • The bar uses bg-surface-raised, or bg-surface-secondary in dark mode, and is up to max-w-md wide.
  • Animations respect the system reduce motion setting.