Drag & physics

Swipe stack

A stack of cards you flick left or right. The next card rises as the top one leaves.

Paste it into ChatGPT, Claude, Cursor or v0.
threshold110
visible depth2

Usage

React
import { SwipeStack, type SwipeStackHandle } from '@vizzele/react';

const stack = useRef<SwipeStackHandle>(null);

<SwipeStack
  ref={stack}
  items={people}
  renderCard={(p) => <ProfileCard person={p} />}
  onSwipe={(p, dir) => save(p, dir === 'right')}
/>
<button onClick={() => stack.current?.swipe('left')}>Nope</button>
<button onClick={() => stack.current?.swipe('right')}>Like</button>

Props

PropTypeDefaultDescription
itemsT[]—Cards, top first.
renderCard(item: T, i: number) => ReactNode—Card content.
onSwipe(item: T, dir: 'left' | 'right') => void—Called when a card leaves.
thresholdnumber110Drag distance (px) that counts as a swipe; a fast flick also counts.
depthnumber2Cards visible behind the top one.
loopbooleanfalseRecycle swiped cards to the bottom.
ref.swipe(dir)SwipeStackHandle—Swipe programmatically (for buttons).

Accessibility

  • The stack is focusable: ← and → swipe the top card. Results are announced politely.
  • Always pair swiping with visible buttons — gestures alone are not discoverable.
  • Cards behind the top one are hidden from assistive tech.