Swipe Deck
Stacked cards with gesture decisions, controls and undo
A tactile card stack that accepts left and right swipes using distance and velocity, springs back from uncertain gestures, and stays fully usable through visible buttons or arrow keys. Decisions can be undone or reset.
Preview
Weekend idea · 01
A quiet morning
Coffee, a long walk, and an hour with a book before the city wakes up.
2 hoursLow effort
Swipe or use ← →
Installation
Install the component using the CLI.
npx shadcn@latest add https://rohan.run/r/swipe-deck.jsonUsage
Import the component:
import { SwipeDeck } from "@/components/rohan/swipe-deck"Use it in your code:
<SwipeDeck
items={ideas.map((idea) => ({
id: idea.id,
ariaLabel: idea.title,
content: <IdeaCard idea={idea} />,
}))}
approveLabel="Save"
rejectLabel="Skip"
onDecision={(item, decision) => updateIdea(item.id, decision)}
/>Props
| Property | Type | Default | Description |
|---|---|---|---|
| items | SwipeDeckItem[] | — | Cards with stable ids, content and optional accessible names. |
| threshold | number | 96 | Horizontal distance in px required to accept a drag. |
| approveLabel / rejectLabel | string | "Approve" / "Reject" | Visible and accessible decision labels. |
| onDecision | (item, decision) => void | — | Called for every accepted swipe or control action. |
| onUndo | (item, decision) => void | — | Called when the latest decision is restored. |
| onReset | () => void | — | Called when an exhausted deck starts over. |