React component for creating draggable and resizable UI elements with comprehensive interaction controls
—
The Rnd component is the core of react-rnd, providing both draggable and resizable functionality in a single React component.
The main React component that wraps content to make it draggable and resizable.
/**
* React component that makes its children draggable and resizable
* Extends React.PureComponent with comprehensive prop interface
*/
class Rnd extends React.PureComponent<Props, State> {
/** Default prop values */
static defaultProps: {
maxWidth: number;
maxHeight: number;
scale: number;
onResizeStart: () => void;
onResize: () => void;
onResizeStop: () => void;
onDragStart: () => void;
onDrag: () => void;
onDragStop: () => void;
};
/** Programmatically update component size */
updateSize(size: { width: number | string; height: number | string }): void;
/** Programmatically update component position */
updatePosition(position: Position): void;
}
interface Props {
// Size and Position
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;
// Drag Configuration
disableDragging?: boolean;
dragAxis?: "x" | "y" | "both" | "none";
dragHandleClassName?: string;
dragGrid?: Grid;
bounds?: string | Element;
cancel?: string;
allowAnyClick?: boolean;
dragPositionOffset?: DraggableProps["positionOffset"];
// Resize Configuration
enableResizing?: ResizeEnable;
resizeGrid?: Grid;
resizeHandleStyles?: HandleStyles;
resizeHandleClasses?: HandleClasses;
resizeHandleComponent?: HandleComponent;
resizeHandleWrapperClass?: string;
resizeHandleWrapperStyle?: React.CSSProperties;
lockAspectRatio?: boolean | number;
lockAspectRatioExtraWidth?: number;
lockAspectRatioExtraHeight?: number;
// Event Handlers
onDragStart?: RndDragCallback;
onDrag?: RndDragCallback;
onDragStop?: RndDragCallback;
onResizeStart?: RndResizeStartCallback;
onResize?: RndResizeCallback;
onResizeStop?: RndResizeCallback;
onMouseDown?: (e: MouseEvent) => void;
onMouseUp?: (e: MouseEvent) => void;
// Styling
className?: string;
style?: React.CSSProperties;
children?: React.ReactNode;
// Advanced
enableUserSelectHack?: boolean;
scale?: number;
dragPositionOffset?: import("react-draggable").DraggableProps["positionOffset"];
// Extension - allows any additional props to be passed through
[key: string]: any;
}Usage Examples:
import React, { useRef } from "react";
import { Rnd } from "react-rnd";
// Basic usage with default positioning
function BasicExample() {
return (
<Rnd
default={{
x: 0,
y: 0,
width: 320,
height: 200,
}}
>
<div>Draggable and resizable content</div>
</Rnd>
);
}
// Controlled component with state management
function ControlledExample() {
const [state, setState] = React.useState({
x: 0,
y: 0,
width: 320,
height: 200,
});
return (
<Rnd
size={{ width: state.width, height: state.height }}
position={{ x: state.x, y: state.y }}
onDragStop={(e, d) => {
setState(prev => ({ ...prev, x: d.x, y: d.y }));
}}
onResizeStop={(e, direction, ref, delta, position) => {
setState({
width: ref.style.width,
height: ref.style.height,
...position,
});
}}
>
<div>Controlled draggable and resizable content</div>
</Rnd>
);
}
// Using ref for programmatic control
function ProgrammaticExample() {
const rndRef = useRef<Rnd>(null);
const updateSize = () => {
if (rndRef.current) {
rndRef.current.updateSize({ width: 400, height: 300 });
}
};
const updatePosition = () => {
if (rndRef.current) {
rndRef.current.updatePosition({ x: 100, y: 100 });
}
};
return (
<div>
<button onClick={updateSize}>Resize to 400x300</button>
<button onClick={updatePosition}>Move to (100, 100)</button>
<Rnd
ref={rndRef}
default={{ x: 0, y: 0, width: 320, height: 200 }}
>
<div>Programmatically controlled content</div>
</Rnd>
</div>
);
}Programmatically update the component's size, bypassing normal prop updates.
/**
* Programmatically update component size
* @param size - New width and height values
* @param size.width - New width (number in pixels or string with units)
* @param size.height - New height (number in pixels or string with units)
*/
updateSize(size: { width: number | string; height: number | string }): void;Programmatically update the component's position, bypassing grid and bounds constraints.
/**
* Programmatically update component position
* @param position - New x and y coordinates
* @param position.x - New x coordinate in pixels
* @param position.y - New y coordinate in pixels
*/
updatePosition(position: Position): void;The Rnd component comes with sensible default values:
{
maxWidth: Number.MAX_SAFE_INTEGER,
maxHeight: Number.MAX_SAFE_INTEGER,
scale: 1,
onResizeStart: () => {},
onResize: () => {},
onResizeStop: () => {},
onDragStart: () => {},
onDrag: () => {},
onDragStop: () => {},
}These props provide fine-grained control over component behavior for special use cases:
/**
* Scale factor for all size and position calculations
* Used when component is rendered in a scaled container (CSS transform: scale)
* Affects boundary calculations and positioning accuracy
* @default 1
*/
scale?: number;Usage Example:
// When component is in a scaled container
<div style={{ transform: 'scale(0.5)' }}>
<Rnd
scale={0.5}
default={{ x: 0, y: 0, width: 200, height: 200 }}
bounds="parent"
>
Content in scaled container
</Rnd>
</div>/**
* Enables a workaround for user-select behavior during drag operations
* Prevents text selection issues while dragging in some browsers
* @default undefined
*/
enableUserSelectHack?: boolean;/**
* Advanced position offset configuration for drag calculations
* Passes through to react-draggable's positionOffset prop
* Used for custom positioning behavior
*/
dragPositionOffset?: import("react-draggable").DraggableProps["positionOffset"];The component maintains internal state for:
Install with Tessl CLI
npx tessl i tessl/npm-react-rnd