Skip to content
dnd-grid

Constraints

Enforce drag and resize rules.

Constraints are small functions that clamp item position and size during drag or resize. They run in order: grid-level constraints first, then per-item constraints on the LayoutItem.

Built-in constraints

ConstraintDescription
gridBoundsKeep items inside the grid bounds.
minMaxSizeRespect minW, maxW, minH, maxH on items.
containerBoundsClamp movement to the visible container height.
boundedXClamp horizontal movement only.
boundedYClamp vertical movement only.
aspectRatio(ratio)Maintain a width/height ratio while resizing.
snapToGrid(stepX, stepY)Snap movement to grid steps.
minSize(minW, minH)Enforce minimum size.
maxSize(maxW, maxH)Enforce maximum size.
defaultConstraints[gridBounds, minMaxSize].

Using constraints

import { useState } from "react";
import {
  DndGrid,
  type Layout,
  type LayoutConstraint,
  aspectRatio,
  defaultConstraints,
  snapToGrid,
} from "@dnd-grid/react";

const topBand: LayoutConstraint = {
  name: "topBand(2)",
  constrainPosition(item, x, y) {
    const maxY = Math.max(0, 2 - item.h);
    return { x, y: Math.min(y, maxY) };
  },
};

const layout: Layout = [
  { id: "snap", x: 0, y: 0, w: 4, h: 2 },
  { id: "ratio", x: 4, y: 0, w: 4, h: 2 },
  { id: "band", x: 8, y: 0, w: 4, h: 2, constraints: [topBand] },
];

const constraints = [
  ...defaultConstraints,
  snapToGrid(2, 1),
  aspectRatio(16 / 9),
];

export function ConstraintGrid() {
  const [currentLayout, setLayout] = useState(layout);
  return (
    <DndGrid
      layout={currentLayout}
      cols={12}
      rowHeight={40}
      constraints={constraints}
      onLayoutChange={setLayout}
    >
      {currentLayout.map((item) => (
        <div key={item.id}>{item.id}</div>
      ))}
    </DndGrid>
  );
}

Writing custom constraints

A LayoutConstraint can implement either constrainPosition, constrainSize, or both. The ConstraintContext provides grid metrics and the full layout.

import { type LayoutConstraint } from "@dnd-grid/react";

const lockRightColumn: LayoutConstraint = {
  name: "lockRightColumn",
  constrainPosition(item, x, y, { cols }) {
    const maxX = Math.max(0, cols - item.w);
    return { x: Math.max(x, maxX), y };
  },
};

Constraint utilities

If you are building your own drag interactions, you can apply the same rules manually with the exported helpers.

import {
  applyPositionConstraints,
  applySizeConstraints,
  defaultConstraints,
} from "@dnd-grid/react";

const position = applyPositionConstraints(
  defaultConstraints,
  item,
  nextX,
  nextY,
  context,
);

const size = applySizeConstraints(
  defaultConstraints,
  item,
  nextW,
  nextH,
  handle,
  context,
);