suiss/uim · Interaction

Undo Bar

A floating bar at the bottom of the screen that offers Undo for a few seconds after a destructive action.

Undo Bar 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
Undo Bar on iOS in light mode

UndoBarProvider shows a pill-shaped bar above the bottom safe area when show is called from useUndoBar. It holds a message, a countdown ring and an Undo button, and slides up into view.

If the user presses Undo, onUndo runs. If the countdown runs out, onCommit runs. Only one bar shows at a time: calling show again commits the previous action first. The countdown pauses while the app is in the background and resumes with the time left. Use it after deleting, archiving or moving items.

Installation

$ pnpm dlx @esuiss/uim@latest add undo-bar

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

Manual

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

  2. Copy the source into components/interactions/undo-bar.tsx:

uniwind/components/interactions/undo-bar.tsx
import { cn } from "cn"
import * as React from "react"
import {
  AccessibilityInfo,
  AppState,
  I18nManager,
  useWindowDimensions,
  View,
} from "react-native"
import {
  cancelAnimation,
  Easing,
  Keyframe,
  ReduceMotion,
  type SharedValue,
  useAnimatedStyle,
  1. Update the import paths to match your project.

Usage

import { UndoBarProvider } from "@/components/interactions/undo-bar"
<UndoBarProvider>
  <NotesList />
</UndoBarProvider>

Wrap the screen or app in UndoBarProvider. After removing an item from the UI, call show({ title, onUndo, onCommit?, actionLabel? }): restore the item in onUndo, and do the permanent work, such as a server delete, in onCommit.

useUndoBar also returns undo, which runs the current undo, and dismiss, which commits and hides the bar.

Examples

Showing

The bar shown right after deleting a note, with a long timeout.

iOS
Undo Bar (showing) on iOS in light mode

Longer timeout

Uses a 10 second timeout.

iOS
Undo Bar (longer timeout) on iOS in light mode

With swipe actions

Shows the bar after a swipe-to-delete in a list with swipe actions.

iOS
Undo Bar (with swipe actions) on iOS in light mode

API Reference

UndoBarProvider

Holds the current undo entry and renders the bar in a portal.

PropType
About
Countdown length in milliseconds. Defaults to 5000.
Type
number
Default
5000
About
Classes for the bar.
Type
string
Default
—
About
Name of a portal host to render into.
Type
string
Default
—
Type
React.ReactNode
Default
—

Accessibility

  • A string title is announced when the bar appears.
  • The bar has the group role and is a polite live region.
  • The countdown ring is hidden from screen readers.

Notes

  • The bar is up to 384 points wide and centered; it uses bg-surface-raised, or bg-surface-secondary in dark mode, with a border-separator outline.
  • The ring drains linearly and runs counterclockwise in right-to-left layouts.
  • Slide animations respect the system reduce motion setting; the countdown always runs.