Drag and Drop Utility

Utility for adding draggable elements and drop zones with mouse, touch, and keyboard support. Not intended to replace full board-style state management frameworks.

Basic Usage

Mark draggables and drop zones with data attributes. Dropping an item into the target zone moves it there. This is the recommended baseline because it has minimal setup and preserves progressive enhancement.

Item 1
Item 2
Item 3

Drop target area

<div class="draggable-item" data-draggable>Item</div>
<div class="drop-zone" data-drop-zone></div>

initDragDrop(document);

Initial Value

Provide axis and handle config through data attributes.

Horizontal only
drag_indicator Handle drag

Variants

Use sortable and accept-filter drop zones based on data behavior.

Sortable List

  • Use when: Items need manual prioritization and reordering in one container.
  • Avoid when: Reordering is not user-visible or automatic sorting is expected.
First
Second
Third

Accept Filter

  • Use when: Only specific item classes should be dropped into a zone.
  • Avoid when: Rules are dynamic and require complex runtime validation logic.
Type A
Type B
Accepts only .type-a

States

Drop zones use active and hover classes while dragging, and draggable elements receive a drag class while in-flight.

Drag over me
  • Default: No drag-related classes applied.
  • Dragging: Draggable gets ds-dragging; screen reader announcement is emitted.
  • Drop active: Zone gets ds-drop-active and may apply acceptance filtering.
  • Drop hover: Zone gets ds-drop-hover when pointer intersects target.

Interactive Example

Track drag lifecycle callbacks from imperative setup.

Interactive item
Drop here
Event log:

API

Attributes

Attribute Type Default Description
data-draggable boolean false Marks draggable elements.
data-drop-zone boolean false Marks drop zones.
data-drag-axis string none x or y axis lock.
data-drop-sortable boolean false Enables sortable mode in a zone.
data-drop-accept string * Selector filter for accepted draggables.

Events

Event Detail Description
None - Utility uses callback options (`onDragStart`, `onDrop`, etc.).

Functions

Function Description
makeDraggable(element, options) Configures one draggable element.
makeDropZone(element, options) Configures one drop zone.
removeDraggable(element) Removes draggable behavior.
removeDropZone(element) Removes drop zone behavior.
initDragDrop(root?) Initializes nodes with data attributes.

Invalid or missing options fall back to utility defaults, for example accept: "*", sortable: false, and axis: null.

CSS Parts

Part Description
None Utility does not expose shadow parts.

CSS Custom Properties

Property Description
--md-sys-color-primary Active drop zone accent color.
--md-sys-color-outline Drop zone outline color.
--md-sys-shape-corner-medium Zone radius token.

Accessibility

Keyboard Map

Key Context Expected Result
Tab Before draggable Moves focus to next draggable item.
Space / Enter Focused draggable Toggles grab/drop behavior in keyboard mode.
Arrow keys Keyboard drag mode active Moves draggable by step increments.
Escape Keyboard drag mode active Cancels keyboard drag mode.

Semantics and Announcements

  • Draggables receive role="button" and aria-grabbed.
  • Drop zones receive role="region" and aria-dropeffect.
  • Keyboard controls: Space/Enter, Arrow keys, and Escape.
  • Live region announcements provide drag status updates.
  • Consumers should provide clear item labels so announcements remain meaningful.
Keyboard: Tab to focus, Space/Enter to grab or drop, Arrows to move, Escape to cancel.

Usage Guidelines

  • When to use: Reordering or moving items where spatial interaction is expected.
  • When not to use: Simple binary assignments where explicit buttons are clearer and more accessible.
  • Composition: Prefer drag handles for dense rows and pair drop zones with acceptance rules.
  • Common mistakes: Relying on drag-only input, omitting keyboard parity, and skipping announcement labels.

Known Limitations

  • Utility callbacks are imperative and do not emit custom DOM events by default.
  • Complex cross-container business rules should be handled in consumer logic via onDrop and related callbacks.