Skip to main content

Overview

Modifiers transform the movement of draggable elements during drag operations. They can restrict movement to axes or boundaries, adjust positioning, or implement any custom movement logic.

Built-in Modifiers

Abstract Modifiers

Available in @dnd-kit/abstract/modifiers, these modifiers are environment-agnostic:

RestrictToHorizontalAxis

Constrain movement to the horizontal axis only

RestrictToVerticalAxis

Constrain movement to the vertical axis only

Snap

Snap movement to a grid with configurable size
Example using axis restriction:
import {RestrictToVerticalAxis} from '@dnd-kit/abstract/modifiers';

// Only allow vertical movement
const manager = new DragDropManager({
  modifiers: [RestrictToVerticalAxis],
});
Example combining modifiers:
import {
  Snap,
  RestrictToHorizontalAxis
} from '@dnd-kit/abstract/modifiers';

// Horizontal movement that snaps to a grid
const manager = new DragDropManager({
  modifiers: [
    RestrictToHorizontalAxis,
    Snap.configure({
      size: {
        x: 20,  // Snap every 20px horizontally
        y: 0    // No vertical snapping (already restricted)
      }
    })
  ],
});
Modifiers are applied in order, so place restrictions before transformations.

Concrete Modifiers

Environment-specific modifiers for the DOM, available in @dnd-kit/dom/modifiers:

RestrictToWindow

Constrain movement within the window boundaries

RestrictToElement

Constrain movement within a container element

Usage

Modifiers can be applied globally or per draggable element. The modifiers option accepts either an array or a function that receives the default modifiers.

Extending defaults

Use the function form to add modifiers without replacing the defaults:
import {DragDropManager} from '@dnd-kit/dom';
import {RestrictToWindow} from '@dnd-kit/dom/modifiers';

const manager = new DragDropManager({
  modifiers: (defaults) => [...defaults, RestrictToWindow],
});

Replacing defaults

Pass an array to fully replace the default modifiers:
import {DragDropManager} from '@dnd-kit/dom';
import {RestrictToWindow} from '@dnd-kit/dom/modifiers';

const manager = new DragDropManager({
  modifiers: [RestrictToWindow],
});

Per-draggable modifiers

Modifiers can also be configured on individual draggable elements:
import {RestrictToElement} from '@dnd-kit/dom/modifiers';

const draggable = new Draggable({
  id: 'draggable-1',
  element,
  modifiers: [
    RestrictToElement.configure({
      element: containerElement
    })
  ],
}, manager);
Local modifiers on draggable elements take precedence over global modifiers.

Creating Custom Modifiers

Create custom modifiers by extending the Modifier class:
import {Modifier} from '@dnd-kit/abstract';
import type {Coordinates} from '@dnd-kit/geometry';

interface GridOptions {
  gridSize: number;
}

class SnapToGrid extends Modifier {
  constructor(manager, options?: GridOptions) {
    super(manager, options);
  }

  public apply(operation): Coordinates {
    if (this.disabled) return operation.transform;

    const {gridSize = 20} = this.options ?? {};
    const {transform} = operation;

    return {
      x: Math.round(transform.x / gridSize) * gridSize,
      y: Math.round(transform.y / gridSize) * gridSize,
    };
  }
}

Modifier Lifecycle

  1. Construction
    • Modifier instance created
    • Options configured
  2. Application
    • apply() called during drag
    • Transforms coordinates
    • Can access drag operation state
  3. Cleanup
    • Resources cleaned up on destroy

API Reference

Base Modifier Class

manager
DragDropManager
required
Reference to the drag and drop manager instance.
options
Record<string, any>
Optional configuration for the modifier.

Methods

  • apply(operation): Transform drag coordinates
  • enable(): Enable the modifier
  • disable(): Disable the modifier
  • isDisabled(): Check if modifier is disabled
  • destroy(): Clean up resources

Static Methods

  • configure(options): Create configured modifier
const snapToGrid = SnapToGrid.configure({
  gridSize: 10
});

const manager = new DragDropManager({
  modifiers: [snapToGrid]
});