react-swipe-motion
v1.0.0
Published
A premium Tinder-style swipeable card stack for React with 4 signature exit animations: Paper Tear, Confetti Burst, Sparkle Dissolve, and Shatter.
Maintainers
Readme
A premium Tinder-style swipeable card stack component for React
Powered by Framer Motion · 4 Signature Exit Animations · Physics-based spring engine · Headless-ready
Preview
✨ Features
| | Feature | Description |
|---|---|---|
| 🎭 | Smooth Motion | Physics-based spring animations powered by framer-motion |
| 📄 | Paper Tear | Card tears in half on swipe left — unique and tactile |
| 🎊 | Confetti Burst | Colorful particle explosion on swipe right (like/accept) |
| ✨ | Sparkle Dissolve | Glowing star particles bloom and fade on swipe up |
| 💥 | Shatter | Card fractures into jagged shards on swipe down |
| 🔄 | Gesture Support | Swipe left, right, up, down with velocity & threshold detection |
| 📚 | 3D Stack Effect | Beautiful perspective depth with configurable gap & scale |
| 🎛️ | Imperative API | ref methods: swipeLeft(), swipeRight(), swipeUp(), swipeDown(), restoreCard(), reset() |
| ↩️ | Undo Support | Built-in card history and restoreCard() for undo |
| 🎨 | Custom Indicators | Fully custom LIKE / NOPE / SUPER / SKIP indicator components |
| 📱 | Responsive | Touch events + mouse drag on mobile and desktop |
📦 Installation
# npm
npm install react-swipe-motion
# yarn
yarn add react-swipe-motion
# pnpm
pnpm add react-swipe-motionPeer dependencies required:
react >= 18.0.0andframer-motion >= 11.0.0
🚀 Quick Start
import { SwipeStack } from 'react-swipe-motion'
import 'react-swipe-motion/dist/react-swipe-motion.css'
const cards = [
{ id: 1, name: 'Mia', bio: 'Coffee lover and sunset chaser.' },
{ id: 2, name: 'Noah', bio: 'Designer, traveler, and vinyl collector.' },
{ id: 3, name: 'Ava', bio: 'Product builder with a passion for motion.' },
]
export default function App() {
return (
<SwipeStack
data={cards}
renderCard={(item) => (
<div style={{ padding: 24 }}>
<h2>{item.name}</h2>
<p>{item.bio}</p>
</div>
)}
onSwipeLeft={(item) => console.log('Passed:', item.name)}
onSwipeRight={(item) => console.log('Liked:', item.name)}
/>
)
}🎛 Props Reference
Core Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | Array | [] | Array of items to render in the stack |
| renderCard | (item) => ReactNode | required | Renders the card content |
| onSwipeLeft | (item) => void | undefined | Swipe left callback (triggers Paper Tear) |
| onSwipeRight | (item) => void | undefined | Swipe right callback (triggers Confetti) |
| onSwipeUp | (item) => void | undefined | Swipe up callback (triggers Sparkle Dissolve) |
| onSwipeDown | (item) => void | undefined | Swipe down callback (triggers Shatter) |
| onStackEmpty | () => void | undefined | Called when all cards are gone |
| onSwipeProgress | ({x, y}) => void | undefined | Real-time drag offset (for parallax BG etc.) |
| emptyState | ReactNode | Built-in | Custom UI when no cards remain |
| animations | AnimationsConfig | See below | Override animations per direction |
| config | EngineConfig | See below | Physics & timing configuration |
| theme | ThemeConfig | See below | Visual stack configuration |
| indicators | { like, nope, super, skip } | Built-in labels | Override indicator text labels |
| renderIndicator | (props) => ReactNode | undefined | Fully custom indicator component |
config — Physics & Engine
config={{
swipeThreshold: 100, // px — drag distance to trigger swipe
velocityThreshold: 500, // px/s — flick speed to trigger swipe
tearDuration: 700, // ms — how long exit animations last
physics: {
stiffness: 300,
damping: 30,
mass: 0.8,
},
}}theme — Visual Stack
theme={{
maxVisible: 3, // cards visible behind the top
stackGap: 12, // px gap between stacked cards
stackScale: 0.05, // scale reduction per depth level
perspective: true, // enable 3D perspective depth
rotateIntensity: 0.08, // card rotation amount during drag
}}🪄 Exit Animations
Every direction has a signature animation — all enabled by default, zero config needed.
| Direction | Animation | Description | |-----------|-----------|-------------| | ⬅️ Swipe Left | Paper Tear | Card tears in half horizontally with physics | | ➡️ Swipe Right | Confetti Burst | Colorful multi-shape particle explosion | | ⬆️ Swipe Up | Sparkle Dissolve | Card blurs out as glowing stars float upward | | ⬇️ Swipe Down | Shatter | Card breaks into jagged shards that scatter |
Override Per Direction
<SwipeStack
animations={{
left: 'paperTear', // 'paperTear' | 'none'
right: 'confetti', // 'confetti' | 'none'
up: 'sparkle', // 'sparkle' | 'paperTear' | 'none'
down: 'shatter', // 'shatter' | 'none'
}}
/>🕹️ Imperative API (via ref)
import { useRef } from 'react'
import { SwipeStack } from 'react-swipe-motion'
function App() {
const stackRef = useRef(null)
return (
<>
<SwipeStack ref={stackRef} data={cards} renderCard={...} />
<button onClick={() => stackRef.current?.swipeLeft()}>Pass ✕</button>
<button onClick={() => stackRef.current?.swipeRight()}>Like ♥</button>
<button onClick={() => stackRef.current?.swipeUp()}>Super ★</button>
<button onClick={() => stackRef.current?.swipeDown()}>Skip ↓</button>
<button onClick={() => stackRef.current?.restoreCard()}>Undo ↩</button>
<button onClick={() => stackRef.current?.reset(newCards)}>Reset</button>
</>
)
}🎨 Theming & Styling
Override any built-in class with your own CSS:
.swipe-stack-container { } /* outer wrapper */
.swipe-stack { } /* the stack box */
.swipe-card { } /* each card */
.swipe-card-top { } /* top (draggable) card */
.swipe-empty-state { } /* empty state wrapper */Custom Indicator Component
<SwipeStack
renderIndicator={({ direction, label, opacity }) => (
<motion.div
className={`my-indicator my-indicator-${direction}`}
style={{ opacity }}
>
{label}
</motion.div>
)}
/>📦 Individual Animation Exports
All animation components are individually exported for advanced compositions:
import {
PaperTear,
ConfettiBurst,
Shatter,
SparkleDissolve,
} from 'react-swipe-motion'
// Use them standalone inside your own overlays
<ConfettiBurst onComplete={() => console.log('done!')} />🌐 Browser Support
| Browser | Support | |---------|---------| | Chrome | ✅ Latest | | Firefox | ✅ Latest | | Safari | ✅ Latest | | Edge | ✅ Latest | | Mobile (iOS / Android) | ✅ Touch Events Supported |
🛠 Contributing / Local Build
# Clone the repo
git clone https://github.com/DevCodeSpace/react-swipe-motion.git
cd react-swipe-motion
# Install dependencies
npm install --legacy-peer-deps
# Build the library
npm run build🤝 Contributing
Contributions, issues and feature requests are welcome!
📄 License
MIT © DevCodeSpace
If this package helps your project, consider giving it a ⭐ on GitHub.
Built with React + Framer Motion · Maintained by DevCodeSpace
GitHub · npm · Report Issue
