Resizable component for React applications with comprehensive resize handle controls and customization options.
npx @tessl/cli install tessl/npm-re-resizable@6.11.0re-resizable is a React component library that provides a comprehensive Resizable component for creating resizable UI elements with extensive customization options. It supports controlled and uncontrolled sizing modes, directional resize handles, constraint-based resizing with minimum/maximum dimensions, grid-based and snap-to-pixel positioning, aspect ratio locking, and boundary detection.
npm install re-resizableimport { Resizable } from "re-resizable";For CommonJS:
const { Resizable } = require("re-resizable");import React, { useState } from "react";
import { Resizable } from "re-resizable";
// Uncontrolled with default size
function UncontrolledExample() {
return (
<Resizable
defaultSize={{
width: 320,
height: 200,
}}
>
<div>Content that can be resized</div>
</Resizable>
);
}
// Controlled with state management
function ControlledExample() {
const [size, setSize] = useState({ width: 300, height: 200 });
return (
<Resizable
size={size}
onResizeStop={(e, direction, ref, delta) => {
setSize({
width: size.width + delta.width,
height: size.height + delta.height,
});
}}
>
<div>Controlled resizable content</div>
</Resizable>
);
}The primary resizable component with comprehensive configuration options.
/**
* Main resizable component that allows users to resize elements with drag handles
*/
class Resizable extends React.PureComponent<ResizableProps, State> {
/**
* Programmatically update component size, ignoring grid, snap, and size constraints
* @param size - Size object with width and/or height
*/
updateSize(size: Size): void;
/** Get parent DOM element */
readonly parentNode: HTMLElement | null;
/** Get window object reference */
readonly window: Window | null;
/** Get resolved size from props */
readonly propsSize: Size;
/** Get current actual size in pixels */
readonly size: NumberSize;
/** Get computed CSS size styles */
readonly sizeStyle: { width: string; height: string };
}Complete configuration interface for the Resizable component.
interface ResizableProps {
/** Wrapper element type (default: 'div') */
as?: string | React.ComponentType<any>;
/** Inline styles for resizable element */
style?: React.CSSProperties;
/** CSS class name for resizable element */
className?: string;
/** Snap grid increments [x, y] (default: [1, 1]) */
grid?: [number, number];
/** Grid gap spacing [x, y] (default: [0, 0]) */
gridGap?: [number, number];
/** Absolute pixel snap points */
snap?: {
x?: number[];
y?: number[];
};
/** Minimum gap required to move to next snap target (default: 0) */
snapGap?: number;
/** Resize boundaries */
bounds?: 'parent' | 'window' | HTMLElement;
/** Enable directional boundary detection (default: false) */
boundsByDirection?: boolean;
/** Controlled size (use with onResize callbacks) */
size?: Size;
/** Minimum width constraint */
minWidth?: string | number;
/** Minimum height constraint */
minHeight?: string | number;
/** Maximum width constraint */
maxWidth?: string | number;
/** Maximum height constraint */
maxHeight?: string | number;
/** Lock aspect ratio (true for initial ratio, number for specific ratio) */
lockAspectRatio?: boolean | number;
/** Extra width for aspect ratio calculations */
lockAspectRatioExtraWidth?: number;
/** Extra height for aspect ratio calculations */
lockAspectRatioExtraHeight?: number;
/** Enable/disable resize handles (false disables all) */
enable?: Enable | false;
/** Custom styles for resize handles */
handleStyles?: HandleStyles;
/** CSS classes for resize handles */
handleClasses?: HandleClassName;
/** Style for resize handles wrapper */
handleWrapperStyle?: React.CSSProperties;
/** CSS class for resize handles wrapper */
handleWrapperClass?: string;
/** Custom React components for resize handles */
handleComponent?: HandleComponent;
/** Child content */
children?: React.ReactNode;
/** Callback when resize starts */
onResizeStart?: ResizeStartCallback;
/** Callback during resize */
onResize?: ResizeCallback;
/** Callback when resize stops */
onResizeStop?: ResizeCallback;
/** Default size for uncontrolled mode */
defaultSize?: Size;
/** Scaling factor for nested scaled elements (default: 1) */
scale?: number;
/** Resize ratio control (default: 1) */
resizeRatio?: number | [number, number];
}Core interfaces for dimensions and sizing.
/** Size specification with optional width and height */
interface Size {
width?: string | number;
height?: string | number;
}
/** Numeric size with required width and height */
interface NumberSize {
width: number;
height: number;
}Interfaces for customizing resize handles.
/** Enable/disable individual resize handles */
interface Enable {
top?: boolean;
right?: boolean;
bottom?: boolean;
left?: boolean;
topRight?: boolean;
bottomRight?: boolean;
bottomLeft?: boolean;
topLeft?: boolean;
}
/** Custom styles for individual resize handles */
interface HandleStyles {
top?: React.CSSProperties;
right?: React.CSSProperties;
bottom?: React.CSSProperties;
left?: React.CSSProperties;
topRight?: React.CSSProperties;
bottomRight?: React.CSSProperties;
bottomLeft?: React.CSSProperties;
topLeft?: React.CSSProperties;
}
/** CSS classes for individual resize handles */
interface HandleClassName {
top?: string;
right?: string;
bottom?: string;
left?: string;
topRight?: string;
bottomRight?: string;
bottomLeft?: string;
topLeft?: string;
}
/** Custom React components for individual resize handles */
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>;
}Callback types for resize events.
/** Direction of resize operation */
type ResizeDirection = 'top' | 'right' | 'bottom' | 'left' | 'topRight' | 'bottomRight' | 'bottomLeft' | 'topLeft';
/**
* Callback for resize start events
* @param e - Mouse or touch event
* @param dir - Direction of resize
* @param elementRef - Reference to resizable element
* @returns void or boolean (false cancels resize)
*/
type ResizeStartCallback = (
e: React.MouseEvent<HTMLElement> | React.TouchEvent<HTMLElement>,
dir: ResizeDirection,
elementRef: HTMLElement,
) => void | boolean;
/**
* Callback for resize events (during and after resize)
* @param event - Native mouse or touch event
* @param direction - Direction of resize
* @param elementRef - Reference to resizable element
* @param delta - Change in size from original
*/
type ResizeCallback = (
event: MouseEvent | TouchEvent,
direction: ResizeDirection,
elementRef: HTMLElement,
delta: NumberSize,
) => void;<Resizable
defaultSize={{ width: 300, height: 200 }}
minWidth={100}
minHeight={50}
maxWidth={800}
maxHeight={600}
bounds="parent"
>
<div>Constrained content</div>
</Resizable><Resizable
defaultSize={{ width: 300, height: 200 }}
grid={[20, 20]}
gridGap={[5, 5]}
>
<div>Grid-snapped content</div>
</Resizable><Resizable
defaultSize={{ width: 400, height: 300 }}
lockAspectRatio={16/9}
lockAspectRatioExtraWidth={50}
>
<div>16:9 aspect ratio with 50px extra width</div>
</Resizable><Resizable
defaultSize={{ width: 300, height: 200 }}
handleStyles={{
right: { backgroundColor: 'blue', width: '8px' },
bottom: { backgroundColor: 'red', height: '8px' },
}}
handleClasses={{
topRight: 'my-corner-handle',
}}
>
<div>Custom styled handles</div>
</Resizable><Resizable
defaultSize={{ width: 300, height: 200 }}
enable={{
top: false,
right: true,
bottom: true,
left: false,
topRight: false,
bottomRight: true,
bottomLeft: false,
topLeft: false,
}}
>
<div>Only right, bottom, and bottom-right handles enabled</div>
</Resizable>re-resizable supports multiple size units:
// Pixels (number or string)
<Resizable defaultSize={{ width: 300, height: 200 }} />
<Resizable defaultSize={{ width: '300px', height: '200px' }} />
// Percentages
<Resizable defaultSize={{ width: '50%', height: '30%' }} />
// Viewport units
<Resizable defaultSize={{ width: '50vw', height: '40vh' }} />
<Resizable defaultSize={{ width: '50vmax', height: '30vmin' }} />
// Auto sizing
<Resizable defaultSize={{ width: 'auto', height: 'auto' }} />