swipeon-react
v1.0.8
Published
A high-performance React swipe card library with smooth animations and multi-directional swipe support
Maintainers
Readme
🎴 SwipeOn React
A high-performance, zero-dependency React swipe card library with smooth animations and multi-directional swipe support. Perfect for building Tinder-like interfaces, interactive card stacks, and gesture-based UI components.
🎬 Demo
Tinder-style profile cards with 4-direction swipes, custom overlay labels (LIKE/NOPE), and smooth 60fps animations.
✨ Features
- 🚀 High Performance: Optimized with
requestAnimationFrameand hardware-accelerated transforms - 🎯 4-Way Swipe: Support for left, right, up, and down swipes
- 📱 Touch & Mouse: Works seamlessly on both desktop and mobile devices
- 🎨 Smooth Animations: Butter-smooth 60fps animations with spring-back effects
- 💪 TypeScript: Full TypeScript support with comprehensive type definitions
- 🪶 Zero Dependencies: No external dependencies except React
- ⚙️ Highly Configurable: Customizable thresholds, velocities, and animations
- 🎭 Rotation Effects: Optional card rotation during drag for realistic feel
📦 Installation
npm install swipeon-reactyarn add swipeon-reactpnpm add swipeon-react🚀 Quick Start
import React from 'react';
import { SwipeCard } from 'swipeon-react';
function App() {
return (
<SwipeCard
onSwipeLeft={() => console.log('Swiped left! 👈')}
onSwipeRight={() => console.log('Swiped right! 👉')}
onSwipeUp={() => console.log('Swiped up! 👆')}
onSwipeDown={() => console.log('Swiped down! 👇')}
>
<div style={{ padding: '40px', background: '#fff', borderRadius: '10px' }}>
<h2>Swipe me in any direction!</h2>
<p>Works with mouse and touch</p>
</div>
</SwipeCard>
);
}
export default App;📖 API Reference
SwipeCard Component
Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| children | ReactNode | required | Content to render inside the card |
| onSwipeLeft | () => void | undefined | Callback triggered when card is swiped left |
| onSwipeRight | () => void | undefined | Callback triggered when card is swiped right |
| onSwipeUp | () => void | undefined | Callback triggered when card is swiped up |
| onSwipeDown | () => void | undefined | Callback triggered when card is swiped down |
| onSwipeStart | () => void | undefined | Callback triggered when swipe starts |
| onSwipeEnd | () => void | undefined | Callback triggered when swipe ends |
| threshold | number | 100 | Minimum distance (px) required to trigger a swipe |
| velocityThreshold | number | 0.5 | Minimum velocity required to trigger a swipe |
| maxRotation | number | 15 | Maximum rotation angle (degrees) during drag |
| exitDuration | number | 300 | Duration (ms) of the exit animation |
| returnDuration | number | 200 | Duration (ms) of the spring-back animation |
| enableRotation | boolean | true | Enable/disable rotation effect during drag |
| className | string | '' | Additional CSS class name |
| style | CSSProperties | {} | Additional inline styles |
useSwipe Hook
For advanced use cases, you can use the useSwipe hook directly:
import { useSwipe } from 'swipeon-react';
function CustomCard() {
const { ref, transform, opacity, transition, isDragging } = useSwipe(
{
onSwipeLeft: () => console.log('Left!'),
onSwipeRight: () => console.log('Right!'),
},
{
threshold: 100,
velocityThreshold: 0.5,
}
);
return (
<div
ref={ref}
style={{
transform,
opacity,
transition,
cursor: isDragging ? 'grabbing' : 'grab',
}}
>
Your content here
</div>
);
}Hook Return Values
| Property | Type | Description |
|----------|------|-------------|
| ref | RefObject<HTMLDivElement> | Ref to attach to your swipeable element |
| transform | string | CSS transform value for positioning/rotation |
| opacity | number | Opacity value based on drag distance |
| transition | string | CSS transition value for animations |
| isDragging | boolean | Whether the element is currently being dragged |
💡 Examples
Card Stack (Tinder-like)
import React, { useState } from 'react';
import { SwipeCard } from 'swipeon-react';
const cards = [
{ id: 1, name: 'Card 1', image: '/card1.jpg' },
{ id: 2, name: 'Card 2', image: '/card2.jpg' },
{ id: 3, name: 'Card 3', image: '/card3.jpg' },
];
function CardStack() {
const [deck, setDeck] = useState(cards);
const handleRemove = () => {
setTimeout(() => {
setDeck((prev) => prev.slice(0, -1));
}, 300);
};
if (deck.length === 0) {
return <div>No more cards!</div>;
}
return (
<div style={{ position: 'relative', width: '300px', height: '400px' }}>
{deck.map((card, index) => (
<SwipeCard
key={card.id}
onSwipeLeft={handleRemove}
onSwipeRight={handleRemove}
onSwipeUp={handleRemove}
onSwipeDown={handleRemove}
style={{
position: 'absolute',
width: '100%',
height: '100%',
zIndex: deck.length - index,
}}
>
<div style={{
width: '100%',
height: '100%',
background: '#fff',
borderRadius: '10px',
boxShadow: '0 4px 8px rgba(0,0,0,0.1)',
}}>
<img src={card.image} alt={card.name} style={{ width: '100%' }} />
<h3>{card.name}</h3>
</div>
</SwipeCard>
))}
</div>
);
}Custom Thresholds
<SwipeCard
threshold={150} // Require 150px movement
velocityThreshold={0.8} // Require faster swipes
maxRotation={25} // More dramatic rotation
exitDuration={500} // Slower exit animation
>
<YourContent />
</SwipeCard>Disable Rotation
<SwipeCard
enableRotation={false}
onSwipeLeft={() => console.log('Left')}
onSwipeRight={() => console.log('Right')}
>
<YourContent />
</SwipeCard>Only Horizontal Swipes
<SwipeCard
onSwipeLeft={() => handleSwipe('left')}
onSwipeRight={() => handleSwipe('right')}
// Don't provide onSwipeUp/onSwipeDown
>
<YourContent />
</SwipeCard>🎨 Styling
The component applies minimal styling by default. You can customize appearance using:
- CSS Classes:
<SwipeCard className="my-custom-card">
<YourContent />
</SwipeCard>- Inline Styles:
<SwipeCard
style={{
borderRadius: '20px',
boxShadow: '0 10px 40px rgba(0,0,0,0.2)'
}}
>
<YourContent />
</SwipeCard>- Styled Components / Emotion:
const StyledSwipeCard = styled(SwipeCard)`
border-radius: 20px;
background: white;
box-shadow: 0 10px 40px rgba(0,0,0,0.2);
`;⚡ Performance Tips
- Use
keyprop: When rendering multiple cards, always provide a uniquekey - Optimize callbacks: Use
useCallbackfor swipe handlers to prevent unnecessary re-renders - Limit card stack: Don't render more than 3-5 cards in a stack
- Optimize images: Use appropriately sized images to improve performance
- CSS containment: The library uses
will-changeandtransform3dfor hardware acceleration
🌐 Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
- Mobile browsers (iOS Safari, Chrome Mobile)
📱 Running the Demo
# Clone the repository
git clone https://github.com/react-forge/swipeon-react.git
cd swipeon-react
# Install dependencies
npm install
# Run the demo
cd example
npm install
npm run devThe demo will open at http://localhost:3000
🛠️ Development
# Install dependencies
npm install
# Build the library
npm run build
# Watch mode for development
npm run dev🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
📄 License
MIT © react-forge
🙏 Acknowledgments
- Inspired by Tinder's swipe interface
- Built with React and TypeScript
- Uses Pointer Events API for unified input handling
📧 Support
Made with ❤️ by react-forge
