0
# re-resizable
1
2
re-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.
3
4
## Package Information
5
6
- **Package Name**: re-resizable
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install re-resizable`
10
11
## Core Imports
12
13
```typescript
14
import { Resizable } from "re-resizable";
15
```
16
17
For CommonJS:
18
19
```javascript
20
const { Resizable } = require("re-resizable");
21
```
22
23
## Basic Usage
24
25
```typescript
26
import React, { useState } from "react";
27
import { Resizable } from "re-resizable";
28
29
// Uncontrolled with default size
30
function UncontrolledExample() {
31
return (
32
<Resizable
33
defaultSize={{
34
width: 320,
35
height: 200,
36
}}
37
>
38
<div>Content that can be resized</div>
39
</Resizable>
40
);
41
}
42
43
// Controlled with state management
44
function ControlledExample() {
45
const [size, setSize] = useState({ width: 300, height: 200 });
46
47
return (
48
<Resizable
49
size={size}
50
onResizeStop={(e, direction, ref, delta) => {
51
setSize({
52
width: size.width + delta.width,
53
height: size.height + delta.height,
54
});
55
}}
56
>
57
<div>Controlled resizable content</div>
58
</Resizable>
59
);
60
}
61
```
62
63
## Capabilities
64
65
### Main Component
66
67
The primary resizable component with comprehensive configuration options.
68
69
```typescript { .api }
70
/**
71
* Main resizable component that allows users to resize elements with drag handles
72
*/
73
class Resizable extends React.PureComponent<ResizableProps, State> {
74
/**
75
* Programmatically update component size, ignoring grid, snap, and size constraints
76
* @param size - Size object with width and/or height
77
*/
78
updateSize(size: Size): void;
79
80
/** Get parent DOM element */
81
readonly parentNode: HTMLElement | null;
82
83
/** Get window object reference */
84
readonly window: Window | null;
85
86
/** Get resolved size from props */
87
readonly propsSize: Size;
88
89
/** Get current actual size in pixels */
90
readonly size: NumberSize;
91
92
/** Get computed CSS size styles */
93
readonly sizeStyle: { width: string; height: string };
94
}
95
```
96
97
### Component Props
98
99
Complete configuration interface for the Resizable component.
100
101
```typescript { .api }
102
interface ResizableProps {
103
/** Wrapper element type (default: 'div') */
104
as?: string | React.ComponentType<any>;
105
106
/** Inline styles for resizable element */
107
style?: React.CSSProperties;
108
109
/** CSS class name for resizable element */
110
className?: string;
111
112
/** Snap grid increments [x, y] (default: [1, 1]) */
113
grid?: [number, number];
114
115
/** Grid gap spacing [x, y] (default: [0, 0]) */
116
gridGap?: [number, number];
117
118
/** Absolute pixel snap points */
119
snap?: {
120
x?: number[];
121
y?: number[];
122
};
123
124
/** Minimum gap required to move to next snap target (default: 0) */
125
snapGap?: number;
126
127
/** Resize boundaries */
128
bounds?: 'parent' | 'window' | HTMLElement;
129
130
/** Enable directional boundary detection (default: false) */
131
boundsByDirection?: boolean;
132
133
/** Controlled size (use with onResize callbacks) */
134
size?: Size;
135
136
/** Minimum width constraint */
137
minWidth?: string | number;
138
139
/** Minimum height constraint */
140
minHeight?: string | number;
141
142
/** Maximum width constraint */
143
maxWidth?: string | number;
144
145
/** Maximum height constraint */
146
maxHeight?: string | number;
147
148
/** Lock aspect ratio (true for initial ratio, number for specific ratio) */
149
lockAspectRatio?: boolean | number;
150
151
/** Extra width for aspect ratio calculations */
152
lockAspectRatioExtraWidth?: number;
153
154
/** Extra height for aspect ratio calculations */
155
lockAspectRatioExtraHeight?: number;
156
157
/** Enable/disable resize handles (false disables all) */
158
enable?: Enable | false;
159
160
/** Custom styles for resize handles */
161
handleStyles?: HandleStyles;
162
163
/** CSS classes for resize handles */
164
handleClasses?: HandleClassName;
165
166
/** Style for resize handles wrapper */
167
handleWrapperStyle?: React.CSSProperties;
168
169
/** CSS class for resize handles wrapper */
170
handleWrapperClass?: string;
171
172
/** Custom React components for resize handles */
173
handleComponent?: HandleComponent;
174
175
/** Child content */
176
children?: React.ReactNode;
177
178
/** Callback when resize starts */
179
onResizeStart?: ResizeStartCallback;
180
181
/** Callback during resize */
182
onResize?: ResizeCallback;
183
184
/** Callback when resize stops */
185
onResizeStop?: ResizeCallback;
186
187
/** Default size for uncontrolled mode */
188
defaultSize?: Size;
189
190
/** Scaling factor for nested scaled elements (default: 1) */
191
scale?: number;
192
193
/** Resize ratio control (default: 1) */
194
resizeRatio?: number | [number, number];
195
}
196
```
197
198
### Size Types
199
200
Core interfaces for dimensions and sizing.
201
202
```typescript { .api }
203
/** Size specification with optional width and height */
204
interface Size {
205
width?: string | number;
206
height?: string | number;
207
}
208
209
/** Numeric size with required width and height */
210
interface NumberSize {
211
width: number;
212
height: number;
213
}
214
```
215
216
### Handle Configuration
217
218
Interfaces for customizing resize handles.
219
220
```typescript { .api }
221
/** Enable/disable individual resize handles */
222
interface Enable {
223
top?: boolean;
224
right?: boolean;
225
bottom?: boolean;
226
left?: boolean;
227
topRight?: boolean;
228
bottomRight?: boolean;
229
bottomLeft?: boolean;
230
topLeft?: boolean;
231
}
232
233
/** Custom styles for individual resize handles */
234
interface HandleStyles {
235
top?: React.CSSProperties;
236
right?: React.CSSProperties;
237
bottom?: React.CSSProperties;
238
left?: React.CSSProperties;
239
topRight?: React.CSSProperties;
240
bottomRight?: React.CSSProperties;
241
bottomLeft?: React.CSSProperties;
242
topLeft?: React.CSSProperties;
243
}
244
245
/** CSS classes for individual resize handles */
246
interface HandleClassName {
247
top?: string;
248
right?: string;
249
bottom?: string;
250
left?: string;
251
topRight?: string;
252
bottomRight?: string;
253
bottomLeft?: string;
254
topLeft?: string;
255
}
256
257
/** Custom React components for individual resize handles */
258
interface HandleComponent {
259
top?: React.ReactElement<any>;
260
right?: React.ReactElement<any>;
261
bottom?: React.ReactElement<any>;
262
left?: React.ReactElement<any>;
263
topRight?: React.ReactElement<any>;
264
bottomRight?: React.ReactElement<any>;
265
bottomLeft?: React.ReactElement<any>;
266
topLeft?: React.ReactElement<any>;
267
}
268
```
269
270
### Event Callbacks
271
272
Callback types for resize events.
273
274
```typescript { .api }
275
/** Direction of resize operation */
276
type ResizeDirection = 'top' | 'right' | 'bottom' | 'left' | 'topRight' | 'bottomRight' | 'bottomLeft' | 'topLeft';
277
278
/**
279
* Callback for resize start events
280
* @param e - Mouse or touch event
281
* @param dir - Direction of resize
282
* @param elementRef - Reference to resizable element
283
* @returns void or boolean (false cancels resize)
284
*/
285
type ResizeStartCallback = (
286
e: React.MouseEvent<HTMLElement> | React.TouchEvent<HTMLElement>,
287
dir: ResizeDirection,
288
elementRef: HTMLElement,
289
) => void | boolean;
290
291
/**
292
* Callback for resize events (during and after resize)
293
* @param event - Native mouse or touch event
294
* @param direction - Direction of resize
295
* @param elementRef - Reference to resizable element
296
* @param delta - Change in size from original
297
*/
298
type ResizeCallback = (
299
event: MouseEvent | TouchEvent,
300
direction: ResizeDirection,
301
elementRef: HTMLElement,
302
delta: NumberSize,
303
) => void;
304
```
305
306
## Advanced Usage Examples
307
308
### Constrained Resizing
309
310
```typescript
311
<Resizable
312
defaultSize={{ width: 300, height: 200 }}
313
minWidth={100}
314
minHeight={50}
315
maxWidth={800}
316
maxHeight={600}
317
bounds="parent"
318
>
319
<div>Constrained content</div>
320
</Resizable>
321
```
322
323
### Grid Snapping
324
325
```typescript
326
<Resizable
327
defaultSize={{ width: 300, height: 200 }}
328
grid={[20, 20]}
329
gridGap={[5, 5]}
330
>
331
<div>Grid-snapped content</div>
332
</Resizable>
333
```
334
335
### Aspect Ratio Locking
336
337
```typescript
338
<Resizable
339
defaultSize={{ width: 400, height: 300 }}
340
lockAspectRatio={16/9}
341
lockAspectRatioExtraWidth={50}
342
>
343
<div>16:9 aspect ratio with 50px extra width</div>
344
</Resizable>
345
```
346
347
### Custom Handle Styling
348
349
```typescript
350
<Resizable
351
defaultSize={{ width: 300, height: 200 }}
352
handleStyles={{
353
right: { backgroundColor: 'blue', width: '8px' },
354
bottom: { backgroundColor: 'red', height: '8px' },
355
}}
356
handleClasses={{
357
topRight: 'my-corner-handle',
358
}}
359
>
360
<div>Custom styled handles</div>
361
</Resizable>
362
```
363
364
### Selective Handle Enablement
365
366
```typescript
367
<Resizable
368
defaultSize={{ width: 300, height: 200 }}
369
enable={{
370
top: false,
371
right: true,
372
bottom: true,
373
left: false,
374
topRight: false,
375
bottomRight: true,
376
bottomLeft: false,
377
topLeft: false,
378
}}
379
>
380
<div>Only right, bottom, and bottom-right handles enabled</div>
381
</Resizable>
382
```
383
384
### Size Units Support
385
386
re-resizable supports multiple size units:
387
388
```typescript
389
// Pixels (number or string)
390
<Resizable defaultSize={{ width: 300, height: 200 }} />
391
<Resizable defaultSize={{ width: '300px', height: '200px' }} />
392
393
// Percentages
394
<Resizable defaultSize={{ width: '50%', height: '30%' }} />
395
396
// Viewport units
397
<Resizable defaultSize={{ width: '50vw', height: '40vh' }} />
398
<Resizable defaultSize={{ width: '50vmax', height: '30vmin' }} />
399
400
// Auto sizing
401
<Resizable defaultSize={{ width: 'auto', height: 'auto' }} />
402
```