0
# RC Resize Observer
1
2
RC Resize Observer is a React component library that provides a declarative interface for monitoring DOM element size changes using the ResizeObserver API. It includes automatic fallback to polyfill for browser compatibility and offers both individual element observation and batch collection for multiple elements.
3
4
## Package Information
5
6
- **Package Name**: rc-resize-observer
7
- **Package Type**: npm
8
- **Language**: TypeScript
9
- **Installation**: `npm install rc-resize-observer`
10
11
## Core Imports
12
13
```typescript
14
import ResizeObserver from "rc-resize-observer";
15
import { _rs } from "rc-resize-observer"; // Test utility only
16
```
17
18
For CommonJS:
19
20
```javascript
21
const ResizeObserver = require("rc-resize-observer");
22
const { _rs } = require("rc-resize-observer"); // Test utility only
23
```
24
25
## Basic Usage
26
27
```typescript
28
import ResizeObserver from "rc-resize-observer";
29
30
// Basic resize observation
31
<ResizeObserver onResize={(size, element) => console.log(size)}>
32
<div>Content to observe</div>
33
</ResizeObserver>
34
35
// Collection for multiple elements
36
<ResizeObserver.Collection onBatchResize={(resizeInfos) => console.log(resizeInfos)}>
37
<ResizeObserver><div>Item 1</div></ResizeObserver>
38
<ResizeObserver><div>Item 2</div></ResizeObserver>
39
</ResizeObserver.Collection>
40
41
// Render props pattern
42
<ResizeObserver onResize={(size) => console.log(size)}>
43
{(ref) => <div ref={ref}>Content</div>}
44
</ResizeObserver>
45
```
46
47
## Architecture
48
49
RC Resize Observer is built around several key components:
50
51
- **ResizeObserver Component**: Main component that wraps child elements and observes their size changes
52
- **Collection Component**: Batches resize events from multiple ResizeObserver children into a single callback
53
- **Internal Observer System**: Uses ResizeObserver polyfill with automatic fallback for browser compatibility
54
- **Type System**: Complete TypeScript interfaces for size information and component props
55
56
## Capabilities
57
58
### ResizeObserver Component
59
60
Main component for monitoring individual element size changes with React-friendly API.
61
62
```typescript { .api }
63
interface ResizeObserverProps {
64
/** Pass to ResizeObserver.Collection with additional data */
65
data?: any;
66
children: React.ReactNode | ((ref: React.RefObject<any>) => React.ReactElement);
67
disabled?: boolean;
68
/** Trigger if element resized. Will always trigger when first time render. */
69
onResize?: OnResize;
70
}
71
72
type OnResize = (size: SizeInfo, element: HTMLElement) => void;
73
74
interface SizeInfo {
75
width: number;
76
height: number;
77
offsetWidth: number;
78
offsetHeight: number;
79
}
80
81
declare const ResizeObserver: React.ForwardRefExoticComponent<
82
React.PropsWithoutRef<ResizeObserverProps> & React.RefAttributes<any>
83
> & {
84
Collection: typeof Collection;
85
};
86
87
/** @private Test only for mock trigger resize event */
88
export declare const _rs: (entities: ResizeObserverEntry[]) => void;
89
```
90
91
**Usage Examples:**
92
93
```typescript
94
import ResizeObserver from "rc-resize-observer";
95
96
// Simple observation
97
<ResizeObserver onResize={(size, element) => {
98
console.log(`Element resized to ${size.width}x${size.height}`);
99
}}>
100
<textarea placeholder="Resize me" />
101
</ResizeObserver>
102
103
// With disabled state
104
import { useState } from "react";
105
const [disabled, setDisabled] = useState(false);
106
<ResizeObserver
107
disabled={disabled}
108
onResize={(size) => console.log('Resized:', size)}
109
>
110
<div>Conditional observation</div>
111
</ResizeObserver>
112
113
// Render props for ref control
114
<ResizeObserver onResize={(size) => console.log(size)}>
115
{(ref) => <canvas ref={ref} width={400} height={300} />}
116
</ResizeObserver>
117
118
// Forward ref access
119
import { useRef } from "react";
120
const observerRef = useRef<HTMLElement>(null);
121
<ResizeObserver ref={observerRef} onResize={handleResize}>
122
<div>Referable element</div>
123
</ResizeObserver>
124
```
125
126
### Collection Component
127
128
Collects resize events from multiple ResizeObserver children and batches them into a single callback for efficient handling.
129
130
```typescript { .api }
131
interface CollectionProps {
132
/** Trigger when some children ResizeObserver changed. Collect by frame render level */
133
onBatchResize?: (resizeInfo: ResizeInfo[]) => void;
134
children?: React.ReactNode;
135
}
136
137
interface ResizeInfo {
138
size: SizeInfo;
139
data: any;
140
element: HTMLElement;
141
}
142
143
declare function Collection(props: CollectionProps): React.ReactElement;
144
```
145
146
**Usage Examples:**
147
148
```typescript
149
import ResizeObserver from "rc-resize-observer";
150
151
// Batch multiple resize events
152
<ResizeObserver.Collection
153
onBatchResize={(resizeInfos) => {
154
console.log(`${resizeInfos.length} elements resized`);
155
resizeInfos.forEach(({ size, element, data }) => {
156
console.log(`Element ${data.id}: ${size.width}x${size.height}`);
157
});
158
}}
159
>
160
<ResizeObserver data={{ id: 'panel1' }}>
161
<div>Panel 1</div>
162
</ResizeObserver>
163
<ResizeObserver data={{ id: 'panel2' }}>
164
<div>Panel 2</div>
165
</ResizeObserver>
166
<ResizeObserver data={{ id: 'panel3' }}>
167
<div>Panel 3</div>
168
</ResizeObserver>
169
</ResizeObserver.Collection>
170
171
// Nested collections
172
<ResizeObserver.Collection onBatchResize={handleOuterBatch}>
173
<ResizeObserver.Collection onBatchResize={handleInnerBatch}>
174
<ResizeObserver><div>Nested item</div></ResizeObserver>
175
</ResizeObserver.Collection>
176
<ResizeObserver><div>Outer item</div></ResizeObserver>
177
</ResizeObserver.Collection>
178
```
179
180
181
### Context API
182
183
Provides context for collection-level resize events.
184
185
```typescript { .api }
186
type onCollectionResize = (size: SizeInfo, element: HTMLElement, data: any) => void;
187
188
declare const CollectionContext: React.Context<onCollectionResize>;
189
```
190
191
### Utility Functions
192
193
Low-level observation utilities used internally.
194
195
```typescript { .api }
196
type ResizeListener = (element: Element) => void;
197
198
/**
199
* Register a resize listener for an element
200
* @param element - DOM element to observe
201
* @param callback - Callback function to call on resize
202
*/
203
declare function observe(element: Element, callback: ResizeListener): void;
204
205
/**
206
* Unregister a resize listener for an element
207
* @param element - DOM element to stop observing
208
* @param callback - Callback function to remove
209
*/
210
declare function unobserve(element: Element, callback: ResizeListener): void;
211
```
212
213
## Types
214
215
### Core Types
216
217
```typescript { .api }
218
interface SizeInfo {
219
width: number;
220
height: number;
221
offsetWidth: number;
222
offsetHeight: number;
223
}
224
225
type OnResize = (size: SizeInfo, element: HTMLElement) => void;
226
227
type ResizeListener = (element: Element) => void;
228
229
type onCollectionResize = (size: SizeInfo, element: HTMLElement, data: any) => void;
230
```
231
232
### Component Props
233
234
```typescript { .api }
235
interface ResizeObserverProps {
236
/** Pass to ResizeObserver.Collection with additional data */
237
data?: any;
238
children: React.ReactNode | ((ref: React.RefObject<any>) => React.ReactElement);
239
disabled?: boolean;
240
/** Trigger if element resized. Will always trigger when first time render. */
241
onResize?: OnResize;
242
}
243
244
interface SingleObserverProps extends ResizeObserverProps {
245
children: React.ReactElement | ((ref: React.RefObject<Element>) => React.ReactElement);
246
}
247
248
interface CollectionProps {
249
/** Trigger when some children ResizeObserver changed. Collect by frame render level */
250
onBatchResize?: (resizeInfo: ResizeInfo[]) => void;
251
children?: React.ReactNode;
252
}
253
254
interface ResizeInfo {
255
size: SizeInfo;
256
data: any;
257
element: HTMLElement;
258
}
259
```
260
261
## Error Handling
262
263
RC Resize Observer includes built-in development warnings:
264
265
- **Multiple Children Warning**: Warns when more than one child is passed to ResizeObserver (suggests using Collection instead)
266
- **Empty Children Warning**: Warns when no children are provided to ResizeObserver
267
- **Automatic Cleanup**: Automatically unobserves elements when components unmount to prevent memory leaks
268
269
## Testing Utilities
270
271
RC Resize Observer exports a test utility for mocking resize events in test environments.
272
273
```typescript { .api }
274
/** @private Test only for mock trigger resize event */
275
declare const _rs: (entities: ResizeObserverEntry[]) => void;
276
```
277
278
**Usage in Tests:**
279
280
```typescript
281
import { _rs } from "rc-resize-observer";
282
283
// Mock resize event for testing
284
const mockEntry = {
285
target: document.querySelector('.test-element'),
286
contentRect: { width: 100, height: 50 },
287
borderBoxSize: [{ inlineSize: 100, blockSize: 50 }],
288
contentBoxSize: [{ inlineSize: 100, blockSize: 50 }],
289
devicePixelContentBoxSize: [{ inlineSize: 100, blockSize: 50 }]
290
} as ResizeObserverEntry;
291
292
_rs([mockEntry]);
293
```
294
295
## Browser Compatibility
296
297
RC Resize Observer uses `resize-observer-polyfill` for automatic fallback support in browsers that don't natively support the ResizeObserver API. No additional configuration is required - the polyfill is automatically used when needed.