useDragDropManager
An imperative API for drag and drop.
The useDragDropManager hook returns the page-wide imperative API. It has four registration methods, registerDraggable, registerDropTarget, registerAutoScroller, and registerMonitor. It also provides startKeyboardDrag and cancelDrag. The React components and hooks use the same registration methods internally.
Every call controls the same manager. Calling the hook in two boards does not isolate them, and cancelDrag() ends whichever drag is active on the page. Use distinct kinds and target accept declarations to keep independent features from interacting.
Use it to register an existing element, integrate a non-React widget, or keep registrations in one parent component. The shape sorter above registers its pieces, cutouts, and monitor through one manager. It does not render Draggable.Root, DropTarget.Root, or useDragMonitor.
Call the hook at the top of your component:
registerDraggable, registerDropTarget, and registerAutoScroller take the target element and a getter for its parameters; registerMonitor takes only a getter, since a monitor observes every drag rather than an element. All four return a cleanup that unregisters. Register from an effect and return the cleanup:
The methods are reference-stable, so they are safe to list as effect dependencies.
When each parameter is read
Base UI reads parameters from the getter at different times:
- Every dispatch. Event callbacks such as
onDragStart,onDrag, andonDrop, and conditions such ascanDrop,canScroll, andallowedAxis, are read from the getter each time. Base UI does not make the getter’s closure reactive. Re-register from an effect when its dependencies change, or read mutable refs from the getter when the registration must stay mounted. - Once at pickup. Base UI reads
kind,payload,label, and preview settings when the drag starts. Changes during the drag apply to the next drag. - At registration and the next interaction. Base UI applies gesture styles,
aria-roledescription,aria-describedby, anddragHandlewhen the element registers. It reads them again on the nextpointerdownorfocusin. Drag behavior, includingdisabled,keyboardActivation, anddragHandle, is always checked at pickup. Re-register the element to update the idle DOM attributes immediately.
Base UI evaluates a monitor’s accept once when it joins a drag. A monitor whose accept excludes a drag ignores it until it ends. A monitor registered during a drag is matched against the drag already in progress.
Base UI reads the locale and nearest Draggable.PreviewProvider where useDragDropManager is called. Put those providers above the component that calls the hook, regardless of where the registered elements render.
Draggables
Register a drag source with registerDraggable. It accepts the Draggable.Root options, including kind, payload or getPayload, pointerActivation, label, disabled, and the drag event callbacks. It also accepts dragHandle and dragPreview. dragHandle can be an element, ref, or function that restricts pickup to a handle. Unlike Draggable.Root, registerDraggable does not manage tabIndex. Make the element focusable to support keyboard dragging.
Drag preview
With no preview part to nest, an imperative source uses the same sanitized clone by default. It preserves classes and live element state but rewrites IDs to keep the document unique. Pass dragPreview only to configure or replace it:
offset, modifiers, disabled, and container work as they do on the preview parts. Instead of children, pass a render function for the content. It resolves once at drag start and receives the drag source:
A render needs a Draggable.PreviewProvider in the tree, like a Draggable.Preview does, and throws without one. A source that uses the default clone needs no provider.
Drop targets
Register a drop target with registerDropTarget. Its parameters are the props of DropTarget.Root without the element and without trackDragOver (drag-over tracking is a React-layer concept): accept, onDragEnter, onDragLeave, onDrop, and the rest.
TypeScript infers the source payload from accept, but cannot also infer the target’s own payload through the getter. Specify both type arguments, as in registerDropTarget<typeof card, SlotData>, when the target sets payload and reads it as self.payload.
Auto-scroll
registerAutoScroller enables automatic scrolling and configures one element. If a DragAutoScroll.Provider is already mounted, the registration only changes that element’s behavior. It accepts the same parameters as DragAutoScroll.Root. Use allowedAxis to limit the axes, canScroll to disable scrolling for a drag, maxSpeed to set the speed, and applyScroll to implement custom scrolling. For example, a transformed canvas has no scroll offsets for Base UI to update and often already has a viewport ref.
Register document.documentElement to customize or disable page auto-scroll.
With a provider mounted, Base UI detects a container that appears after data loads or inside a third-party widget when a drag reaches it. Register the container only if you need to change its behavior.
Monitor drags
Observe every drag with registerMonitor, like useDragMonitor. It takes only a getter:
Starting a keyboard drag
startKeyboardDrag starts a drag as if the user pressed Space. It focuses the source or handle and returns whether the drag started. Pass the registered element or one of its descendants. The arrow keys move the drag, Space or Enter drops it, and Escape cancels it. Announcements and focus restoration work normally.
Use it with keyboardActivation="manual" when the element needs Space for another action. For example, a “Reorder” menu item can start the drag after Space opens the menu.
It returns false if another drag is active, the draggable is disabled, keyboard activation is off, or onBeforeDragStart cancels. It also returns false for null or a detached element. This handles a source that unmounts before a deferred menu-close callback runs. Passing a mounted element outside a registered draggable throws an error.
Cancelling a drag
cancelDrag ends the active drag and fires onDragEnd with canceled: true and the reason 'imperative-action'. For a keyboard drag, it also restores focus and announces the cancellation. It does nothing when no drag is active. Use it when a route change, dialog, or deleted record invalidates the drag.
API reference
Returns the page-wide drag-and-drop manager. It includes the registration methods that
Draggable.Root, DropTarget.Root, DragAutoScroll.Root, and useDragMonitor
are built on, plus startKeyboardDrag to open a keyboard drag from your own
trigger and cancelDrag to end the drag in progress.
Use it to register an existing element, integrate a non-React widget, or keep registrations in one place.
Every call controls the same page-wide manager. Base UI reads the locale and
nearest Draggable.PreviewProvider at the hook’s call site. Put both providers
above the component that calls useDragDropManager, even when the registered
elements render elsewhere.
Return value
UseDragDropManagerReturnValue
registerDraggablefunction
- Description
Registers a drag source and returns a cleanup that unregisters it.
Base UI reads behavior from the getter on every event. It applies gesture styles,
aria-roledescription, andaria-describedbywhen the element registers, then reads them again on the next pointer press or focus event. Re-register the element to update these idle DOM attributes immediately.- Type
registerDropTargetfunction
- Description
Registers a drop target, a place a matching drag can be released, and returns a cleanup that unregisters it.
- Type
registerAutoScrollerfunction
- Description
Registers auto-scroll parameters for an element, and returns a cleanup that unregisters them.
Scroll containers work without registration. Register one to change its behavior.
disabledexcludes the element, andoverflow: hiddenoroverflow: clipprevents the page from scrolling. For a canvas moved by a CSStransform, useapplyScrollto apply the scroll delta yourself.- Type
registerMonitorfunction
- Name
- Description
Registers a monitor that observes every matching drag, and returns a cleanup that unregisters it.
- Type
cancelDragfunction
- Name
- Description
Cancels the drag in progress, if any. Fires
onDragEndwithcanceled: trueand, for a keyboard drag, restores focus and announces the cancellation.- Type
startKeyboardDragfunction
- Description
Starts a keyboard drag on a registered draggable as if the user pressed Space, and returns whether it started. Arrow keys move the drag, Space or Enter drops it, and Escape cancels it.
With
keyboardActivation: 'manual', call this method from another control, such as a “Reorder” item in the draggable’s menu.Pass the registered element or one of its descendants. A
nullor detached element returnsfalse, which handles a source that unmounts before a deferred menu-close callback runs. The method also returnsfalseif another drag is active, the draggable is disabled, keyboard activation is off, oronBeforeDragStartcancels. A mounted element outside a registered draggable throws an error.- Type