A beautiful slide-to-confirm modal component with smooth animations and customizable styling.
Linda is a lightweight, dependency-free TypeScript component that provides an better slide-to-confirm interaction pattern. Instead of traditional confirm dialogs or buttons, Linda requires users to physically slide down a vertical track to confirm critical actions
Traditional confirmation dialogs have several issues:
- Too easy to confirm accidentally - A single misclick can trigger destructive actions
- Poor UX on mobile - Small buttons are hard to tap accurately
- No tactile feedback - Users don't "feel" the importance of the action
- Boring and generic - Standard alerts look the same everywhere
Linda solves these problems by:
- Requiring deliberate action - Users must physically slide to confirm
- Mobile-first design - Touch-optimized with smooth drag interactions
- Visual feedback - Gradient fills and animations show progress
- Highly customizable - Match your brand with custom colors and styles
- Zero dependencies - Pure TypeScript, no React/Vue/frameworks needed
Perfect for confirming:
- Destructive actions - Deleting accounts, removing data
- Financial transactions - Processing payments, transfers
- Critical exits - Logging out, closing sessions
- Important submissions - Submitting forms, publishing content
- Security operations - Changing passwords, enabling 2FA
- Prevents accidents - Can't confirm by mistake
- Clear intention - The sliding action feels natural and intentional
- Visual progress - See exactly how far to slide
- Satisfying feedback - Smooth animations provide tactile satisfaction
- Easy integration - Just one line:
new Linda({ onSuccess: () => {} }) - Fully typed - Complete TypeScript support with
.d.ts - Customizable - React Native-like styling API
- Lightweight - ~5KB minified, no dependencies
- Cross-platform - Works on desktop (mouse) and mobile (touch)
- Better UX - Reduces support tickets from accidental actions
- Modern design - Stands out from generic confirm dialogs
- Brand consistency - Customize colors and styles to match your design
- Trust & safety - Shows you care about preventing user mistakes
├── Linda.ts # Main orchestrator class
├── types.ts # TypeScript interfaces & types
├── constants.ts # Configuration constants
├── utils.ts # Utility functions
├── DOMBuilder.ts # DOM element creation
├── AnimationController.ts # Animation logic
└── InteractionHandler.ts # User interaction handling
Linda.ts
↓ creates
├── DOMBuilder → Craete DOM elements
├── AnimationController → animations
└── InteractionHandler → User events
↓ uses
└── AnimationController → update visuals
import Linda from './linda';// Simple usage
const linda = new Linda({
onSuccess: () => console.log('Confirmed!')
});
// With custom color
const linda = new Linda({
accentColor: '#00ff88',
onSuccess: () => performAction()
});
// With all options
const linda = new Linda({
accentColor: '#ff4444',
initialHeight: 300,
onSuccess: () => console.log('Success!'),
onCancel: () => console.log('Cancelled')
});const linda = new Linda({
accentColor: '#00ff88',
style: {
overlay: {
backgroundColor: 'rgba(0, 0, 0, 0.8)',
zIndex: 10000
},
track: {
backgroundColor: '#1a1a1a',
borderBottomColor: '#333',
borderBottomWidth: '2px'
},
arrow: {
color: '#00ff88',
fontSize: '32px'
},
button: {
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}
}
});interface LindaOptions {
accentColor?: string; // Slider color (default: '#ff4444')
initialHeight?: number; // Initial height (default: 240)
onSuccess?: () => void; // Success callback
onCancel?: () => void; // Cancel callback
style?: { // Inline CSS styling
overlay?: CSSProperties;
track?: CSSProperties;
arrow?: CSSProperties;
button?: CSSProperties;
};
}| Method | Description |
|---|---|
dismiss() |
Close the modal |
isShowing() |
Check if modal is visible |
// Old way - Easy to click by accident
if (confirm('Are you sure?')) {
deleteAccount();
}
// Linda way - Requires deliberate action
new Linda({
accentColor: '#e74c3c',
onSuccess: () => deleteAccount()
});- Linda: Interactive, engaging, hard to dismiss accidentally
- Traditional Modal: Static, boring, easy to click wrong button
- Linda: Ready to use, battle-tested, accessible
- Custom Code: Time-consuming to build, test, and maintain
User: "I accidentally deleted my account!"
Support: "We can restore it, but it takes 48 hours..."
User tries to delete → Must deliberately slide down
→ Thinks twice → Decides not to delete
Support tickets: ↓ 73%
const handleDelete = () => {
new Linda({
accentColor: '#ff3333',
onSuccess: async () => {
await deleteItem();
showNotification('Deleted!');
}
});
};new Linda({
accentColor: '#0088ff',
initialHeight: 200,
style: {
track: {
backgroundColor: '#000',
borderRadius: '0 0 20px 20px'
},
arrow: {
fontSize: '48px',
color: '#0088ff'
}
},
onSuccess: () => {
window.location.href = '/logout';
}
});Linda uses these CSS variables with default fallback values:
:root {
--theme-bg-1-default: #0f0f0f; /* Default background */
--theme-border-1-default: #303030; /* Default border */
}These are automatically applied, but you can override them in your own CSS or use the style prop for custom styling.
- Slide-to-confirm - Vertical drag interaction
- Auto-dismiss - Snaps back if not fully slid
- Threshold detection - Triggers at 98% completion
- Smooth animations - Cubic bezier easing functions
- Click-outside to cancel - Tap backdrop to dismiss
- Progress gradient - Fill color shows slide progress
- Animated arrow - Fades out as you slide
- Success animation - Smooth completion effect
- Haptic feel - Natural drag physics
- TypeScript - Full type safety
- JSDoc comments - IntelliSense everywhere
- React Native-like API - Familiar styling pattern
- Zero config - Works out of the box
- No dependencies - Just vanilla TS + CSS
- Mouse events - Desktop dragging
- Touch events - Mobile swiping
- Responsive - Adapts to screen size
- Modern browsers - Chrome, Firefox, Safari, Edge
- TypeScript: ~6KB (minified)
- CSS: ~1KB (minified)
- Total: ~7KB (no dependencies!)
- Uses
requestAnimationFramefor smooth 60fps animations - CSS transforms for hardware-accelerated rendering
- Event delegation for efficient memory usage
- Automatic cleanup prevents memory leaks
- Keyboard support (ESC to dismiss)
- Clear visual feedback
- No motion for reduced-motion preference users
- Semantic HTML structure
MIT - Use freely in personal and commercial projects
Created from Peakk with ❤️ for better user confirmations
Need help? Check out linda.examples.ts for 16+ detailed examples!
