React component for creating draggable and resizable UI elements with comprehensive interaction controls
npx @tessl/cli install tessl/npm-react-rnd@10.5.0React RnD is a React component library that provides a unified Rnd component for creating draggable and resizable UI elements. It combines functionality from react-draggable and re-resizable libraries into a single, comprehensive component with extensive customization options.
npm install react-rndimport {
Rnd,
Grid,
Position,
DraggableData,
RndDragCallback,
RndDragEvent,
RndResizeStartCallback,
ResizableDelta,
RndResizeCallback,
ResizeEnable,
HandleClasses,
HandleStyles,
HandleComponent,
Props
} from "react-rnd";For CommonJS:
const {
Rnd,
Grid,
Position,
DraggableData,
RndDragCallback,
RndDragEvent,
RndResizeStartCallback,
ResizableDelta,
RndResizeCallback,
ResizeEnable,
HandleClasses,
HandleStyles,
HandleComponent,
Props
} = require("react-rnd");Most common imports:
import { Rnd, Position, DraggableData, ResizableDelta } from "react-rnd";import React from "react";
import { Rnd } from "react-rnd";
function App() {
return (
<Rnd
default={{
x: 0,
y: 0,
width: 320,
height: 200,
}}
minWidth={200}
minHeight={100}
bounds="window"
>
<div style={{ background: "#f0f0f0", width: "100%", height: "100%" }}>
Draggable and resizable content
</div>
</Rnd>
);
}React RnD is built around several key design patterns:
Rnd component that wraps both draggable and resizable functionalityThe main Rnd component that provides both draggable and resizable functionality with comprehensive configuration options.
interface Rnd extends React.PureComponent<Props, State> {
/** Programmatically update component size */
updateSize(size: { width: number | string; height: number | string }): void;
/** Programmatically update component position */
updatePosition(position: Position): void;
}Configuration for size constraints, positioning, default values, and controlled vs uncontrolled behavior.
interface SizePositionProps {
default?: { x: number; y: number; width?: number | string; height?: number | string };
position?: { x: number; y: number };
size?: { width: string | number; height: string | number };
minWidth?: number | string;
minHeight?: number | string;
maxWidth?: number | string;
maxHeight?: number | string;
}Configuration for dragging behavior including axis constraints, bounds, grid snapping, and handle specification.
interface DragProps {
disableDragging?: boolean;
dragAxis?: "x" | "y" | "both" | "none";
dragHandleClassName?: string;
dragGrid?: Grid;
bounds?: string | Element;
cancel?: string;
allowAnyClick?: boolean;
}Configuration for resizing behavior including handle customization, aspect ratio locking, and directional control.
interface ResizeProps {
enableResizing?: ResizeEnable;
resizeGrid?: Grid;
resizeHandleStyles?: HandleStyles;
resizeHandleClasses?: HandleClasses;
resizeHandleComponent?: HandleComponent;
resizeHandleWrapperClass?: string;
resizeHandleWrapperStyle?: React.CSSProperties;
lockAspectRatio?: boolean | number;
lockAspectRatioExtraWidth?: number;
lockAspectRatioExtraHeight?: number;
}Callback props for all drag and resize interaction phases with detailed event data.
interface EventProps {
onDragStart?: RndDragCallback;
onDrag?: RndDragCallback;
onDragStop?: RndDragCallback;
onResizeStart?: RndResizeStartCallback;
onResize?: RndResizeCallback;
onResizeStop?: RndResizeCallback;
onMouseDown?: (e: MouseEvent) => void;
onMouseUp?: (e: MouseEvent) => void;
}type Grid = [number, number];
interface Position {
x: number;
y: number;
}
interface DraggableData extends Position {
node: HTMLElement;
deltaX: number;
deltaY: number;
lastX: number;
lastY: number;
}
interface ResizableDelta {
width: number;
height: number;
}
type RndDragEvent =
| React.MouseEvent<HTMLElement | SVGElement>
| React.TouchEvent<HTMLElement | SVGElement>
| MouseEvent
| TouchEvent;
// RndDragCallback is imported from react-draggable as DraggableEventHandler
type RndDragCallback = import("react-draggable").DraggableEventHandler;
type RndResizeStartCallback = (
e: React.MouseEvent<HTMLElement> | React.TouchEvent<HTMLElement>,
dir: ResizeDirection,
elementRef: HTMLElement
) => void | boolean;
type RndResizeCallback = (
e: MouseEvent | TouchEvent,
dir: ResizeDirection,
elementRef: HTMLElement,
delta: ResizableDelta,
position: Position
) => void;
// ResizeDirection is imported from 're-resizable' dependency
type ResizeDirection =
| "top"
| "right"
| "bottom"
| "left"
| "topRight"
| "bottomRight"
| "bottomLeft"
| "topLeft";
type ResizeEnable =
| {
bottom?: boolean;
bottomLeft?: boolean;
bottomRight?: boolean;
left?: boolean;
right?: boolean;
top?: boolean;
topLeft?: boolean;
topRight?: boolean;
}
| boolean;
interface HandleStyles {
bottom?: React.CSSProperties;
bottomLeft?: React.CSSProperties;
bottomRight?: React.CSSProperties;
left?: React.CSSProperties;
right?: React.CSSProperties;
top?: React.CSSProperties;
topLeft?: React.CSSProperties;
topRight?: React.CSSProperties;
}
interface HandleClasses {
bottom?: string;
bottomLeft?: string;
bottomRight?: string;
left?: string;
right?: string;
top?: string;
topLeft?: string;
topRight?: string;
}
interface HandleComponent {
top?: React.ReactElement<any>;
right?: React.ReactElement<any>;
bottom?: React.ReactElement<any>;
left?: React.ReactElement<any>;
topRight?: React.ReactElement<any>;
bottomRight?: React.ReactElement<any>;
bottomLeft?: React.ReactElement<any>;
topLeft?: React.ReactElement<any>;
}