);
}
```
View the [Demo](https://react-grid-layout.github.io/react-draggable/) and its [source](/example/example.js) for more examples.
## API
### ``
A `` element wraps an existing element and extends it with new event handlers and styles. It does not create a wrapper element in the DOM.
Draggable items are moved using CSS Transforms. This allows items to be dragged regardless of their current positioning (relative, absolute, or static). Elements can also be moved between drags without incident.
If the item you are dragging already has a CSS Transform applied, it will be overwritten by ``. Use an intermediate wrapper (`...`) in this case.
#### Props
```ts
type DraggableEventHandler = (e: Event, data: DraggableData) => void | false;
type DraggableData = {
node: HTMLElement,
x: number, y: number,
deltaX: number, deltaY: number,
lastX: number, lastY: number,
};
```
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `allowAnyClick` | `boolean` | `false` | Allow dragging on non-left-button clicks |
| `allowMobileScroll` | `boolean` | `false` | Don't prevent `touchstart`, allowing scrolling inside containers |
| `axis` | `'both' \| 'x' \| 'y' \| 'none'` | `'both'` | Axis to allow dragging on |
| `bounds` | `object \| string` | - | Restrict movement. Use `'parent'`, a CSS selector, or `{left, top, right, bottom}` |
| `cancel` | `string` | - | CSS selector for elements that should not initiate drag |
| `defaultClassName` | `string` | `'react-draggable'` | Class name applied to the element |
| `defaultClassNameDragging` | `string` | `'react-draggable-dragging'` | Class name applied while dragging |
| `defaultClassNameDragged` | `string` | `'react-draggable-dragged'` | Class name applied after drag |
| `defaultPosition` | `{x: number, y: number}` | `{x: 0, y: 0}` | Starting position |
| `disabled` | `boolean` | `false` | Disable dragging |
| `enableUserSelectHack` | `boolean` | `true` | Add `user-select: none` while dragging |
| `grid` | `[number, number]` | - | Snap to grid `[x, y]` |
| `handle` | `string` | - | CSS selector for the drag handle |
| `nodeRef` | `React.RefObject` | - | Ref to the DOM element. Required for React Strict Mode |
| `offsetParent` | `HTMLElement` | - | Custom offsetParent for drag calculations |
| `onDrag` | `DraggableEventHandler` | - | Called while dragging |
| `onMouseDown` | `(e: MouseEvent) => void` | - | Called on mouse down |
| `onStart` | `DraggableEventHandler` | - | Called when dragging starts. Return `false` to cancel |
| `onStop` | `DraggableEventHandler` | - | Called when dragging stops |
| `position` | `{x: number, y: number}` | - | Controlled position |
| `positionOffset` | `{x: number \| string, y: number \| string}` | - | Position offset (supports percentages) |
| `scale` | `number` | `1` | Scale factor for dragging inside transformed parents |
**Note:** Setting `className`, `style`, or `transform` on `` will error. Set them on the child element.
### ``
For users that require full control, `` provides drag callbacks without managing state or styles. It does not set any transforms; you must handle positioning yourself.
See [React-Resizable](https://github.com/react-grid-layout/react-resizable) and [React-Grid-Layout](https://github.com/react-grid-layout/react-grid-layout) for usage examples.
#### Props
`` accepts a subset of `` props:
- `allowAnyClick`
- `allowMobileScroll`
- `cancel`
- `disabled`
- `enableUserSelectHack`
- `grid`
- `handle`
- `nodeRef`
- `offsetParent`
- `onDrag`
- `onMouseDown`
- `onStart`
- `onStop`
- `scale`
## Using nodeRef
To avoid `ReactDOM.findDOMNode()` deprecation warnings in React Strict Mode, pass a `nodeRef` prop:
```jsx
function App() {
const nodeRef = useRef(null);
return (
Drag me!
);
}
```
For custom components, forward both the ref and props:
```jsx
const MyComponent = forwardRef((props, ref) => (
Draggable content
));
function App() {
const nodeRef = useRef(null);
return (
);
}
```
## Controlled vs. Uncontrolled
`` is a 'batteries-included' component that manages its own state. For complete control, use ``.
For programmatic repositioning while using ``'s state management, pass the `position` prop:
```jsx
function ControlledDraggable() {
const nodeRef = useRef(null);
const [position, setPosition] = useState({ x: 0, y: 0 });
const handleDrag = (e, data) => {
setPosition({ x: data.x, y: data.y });
};
const resetPosition = () => setPosition({ x: 0, y: 0 });
return (
<>
Drag me or reset!
>
);
}
```
## Contributing
- Fork the project
- Run `yarn dev` to start the development server
- Make changes and add tests
- Run `yarn test` to ensure tests pass
- Submit a PR
### Release Checklist
1. Update CHANGELOG.md
2. Run `make release-patch`, `make release-minor`, or `make release-major`
3. Run `make publish`
## License
MIT