Swipe Action List
List rows swipe left or right to expose archive/delete actions, executing directly once the threshold is crossed.
This is a WebberUI Pro component
Free during the launch campaign: sign up or sign in, then hit “Copy install command” in the preview above and it installs straight away — no payment, no credit card. The command below returns 401 while you are signed out.
The swipe action list familiar from mobile: dragging right exposes a green archive layer, dragging left exposes a red delete layer, and past the threshold the icon pops larger and the action runs automatically, with the row flying out and collapsing away. On desktop, hover or keyboard focus reveals a button fallback, so nothing depends on the drag gesture.
npx shadcn@latest add "https://webberui.com/r/swipe-action-list.json?t=<install token>"Playground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<SwipeActionList />
Installation
npx shadcn@latest add "https://webberui.com/r/swipe-action-list.json?t=<install token>"Or, once registries are configured in components.json, install it as @webberui/swipe-action-list.
Usage
import { SwipeActionList } from "@/components/ui/swipe-action-list";
<SwipeActionList
items={[
{
id: "msg-1",
title: "Emily Lin",
description: "The design file is updated — mind taking a look?",
meta: "09:24",
},
]}
onArchive={(item) => console.log("archive", item.id)}
onDelete={(item) => console.log("delete", item.id)}
/>Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | SwipeActionItem[] | — | List data; a row is removed from the internal list once archived or deleted |
onArchive | (item: SwipeActionItem) => void | — | Fires when a right swipe (or the archive button) crosses the threshold |
onDelete | (item: SwipeActionItem) => void | — | Fires when a left swipe (or the delete button) crosses the threshold |
threshold | number | 96 | Drag distance required to trigger an action (px) |
className | string | — | Forwarded to the outer container |
SwipeActionItem fields:
| Field | Type | Default | Description |
|---|---|---|---|
id | string | — | Unique identifier, used as the React key and passed to the action callbacks |
title | string | — | The row's main title (the avatar initial is taken from its first character) |
description | string | — | Secondary description text, truncated to one line when too long |
meta | string | — | Supporting information on the right, such as a time or a tag |
hue | number | derived from id | Avatar gradient hue (0-360) |
Accessibility
- Desktop hover or keyboard Tab focus reveals the archive/delete button fallback (each with an
aria-label), so the full functionality never depends on the drag gesture - Each archive/delete announces its result through an
aria-live="polite"region (for example, "Archived 'Emily Lin'") - When the user has "reduce motion" enabled at the system level, the fly-out and collapse animations are skipped and the row is removed directly
- The drag is locked to the horizontal axis and keeps
touch-pan-y, so it never blocks vertical page scrolling - The action layers on both sides are purely visual cues and are hidden from assistive technology (
aria-hidden)