A lightweight, accessible React component for creating draggable buttons with smooth animations and touch support.
- 🖱️ Smooth drag interactions
- 📱 Touch device support
- ♿ Accessibility focused
- 🎨 Customizable styling
- 🔄 Position tracking
- 🚫 Disabled state support
npm install drag-button
# or
yarn add drag-button
import { DragButton } from 'drag-button';
function App() {
const handleDragStart = (event, { offsetX, offsetY }) => {
console.log('Drag started at:', offsetX, offsetY);
};
const handleDrag = (event, { x, y }) => {
console.log('Dragging at:', x, y);
};
const handleDragEnd = (event) => {
console.log('Drag ended');
};
return (
<DragButton
onDragStart={handleDragStart}
onDrag={handleDrag}
onDragEnd={handleDragEnd}
>
Drag me!
</DragButton>
);
}
Prop | Type | Default | Description |
---|---|---|---|
children |
node |
Required | Content to be rendered inside the button |
onDragStart |
function |
undefined |
Called when drag starts |
onDrag |
function |
undefined |
Called while dragging |
onDragEnd |
function |
undefined |
Called when drag ends |
className |
string |
'' |
Additional CSS classes |
disabled |
boolean |
false |
Disables the drag functionality |
The component comes with default styles but can be customized using the className
prop:
<DragButton className="custom-button">
Custom Styled Button
</DragButton>
The component automatically handles touch events for mobile devices. No additional configuration needed!
- Proper focus management
- Keyboard navigation support
- ARIA attributes
- High contrast mode support
import { DragButton } from 'drag-button';
import { useState } from 'react';
function PositionTracker() {
const [position, setPosition] = useState({ x: 0, y: 0 });
return (
<div>
<DragButton
onDrag={(event, pos) => setPosition(pos)}
style={{ marginBottom: '20px' }}
>
Drag me and watch the position
</DragButton>
<div>
Current position: X: {Math.round(position.x)}, Y: {Math.round(position.y)}
</div>
</div>
);
}
To explore the component interactively and view all examples:
npm run storybook
Then visit http://localhost:6006 in your browser.
To stop the Storybook server:
- Method 1: Press
Ctrl + C
in the terminal window where Storybook is running- When prompted "Terminate batch job (Y/N)?", type
Y
and press Enter
- When prompted "Terminate batch job (Y/N)?", type
- Method 2: Using TaskKill (if the process is stuck or Method 1 doesn't work)
# Find the process using port 6006 netstat -ano | findstr :6006 # Look for the PID in the LISTENING state (usually the first entry) # Kill that process (replace XXXX with the PID) taskkill /PID XXXX /F
- Default: Basic DragButton implementation with standard functionality
- Disabled: Example of the button in a disabled state
- CustomStyle: Demonstration of custom styling options
- WithPositionTracking: Interactive example showing real-time position tracking
- Create stories in
src/stories
directory - Follow the naming convention:
ComponentName.stories.jsx
- Use the template pattern for consistent story creation:
import React from 'react';
import { fn } from '@storybook/test';
import DragButton from '../../src/components/DragButton';
export default {
title: 'Components/DragButton',
component: DragButton,
argTypes: {
// Define your props here
},
};
const Template = (args) => <DragButton {...args} />;
export const YourStory = Template.bind({});
YourStory.args = {
// Define your story props here
};
- Document all props using
argTypes
- Include examples of common use cases
- Add interactive examples for complex features
- Use actions to demonstrate event handling
- Include accessibility information in the docs
Contributions are welcome! Please feel free to submit a Pull Request.
MIT © Mark Castle