@crimson_dev/use-resize-observer 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md ADDED
@@ -0,0 +1,52 @@
1
+ # Changelog
2
+
3
+ All notable changes to `@crimson_dev/use-resize-observer` will be documented in this file.
4
+
5
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
+
8
+ ## [0.1.1] - 2026-03-06
9
+
10
+ ### Fixed
11
+ - API reference page returning 404 on GitHub Pages (`docs/api/` was gitignored)
12
+ - Pre-commit hook failing on non-processable file types (yml, md, gitignore)
13
+
14
+ ### Changed
15
+ - GitHub Actions updated to latest versions: checkout v6, setup-node v6, upload-pages-artifact v4, github-script v8
16
+ - VitePress theme enhanced with frosted-glass navigation, feature card hover effects, gradient hero text, animated entrance, custom scrollbar, and oklch color system
17
+
18
+ ## [0.1.0] - 2026-03-05
19
+
20
+ ### Added
21
+ - `useResizeObserver` — primary React hook with shared observer pool
22
+ - `useResizeObserverEntries` — multi-element observation hook
23
+ - `createResizeObserver` — framework-agnostic imperative factory
24
+ - `createResizeObservable` — EventTarget-based observable (`/core`)
25
+ - `createServerResizeObserverMock` — SSR/RSC safe mock (`/server`)
26
+ - `useResizeObserverWorker` — SharedArrayBuffer worker mode (`/worker`)
27
+ - ResizeObserver polyfill shim (`/shim`)
28
+ - `ResizeObserverContext` for dependency injection
29
+ - `ObserverPool` — single shared ResizeObserver per document root
30
+ - `RafScheduler` — requestAnimationFrame batching with `startTransition`
31
+ - `FinalizationRegistry` for automatic GC cleanup of detached elements
32
+ - ES2026 `using` / `Symbol.dispose` support on pool, scheduler, and factory
33
+ - All 3 box models: `content-box`, `border-box`, `device-pixel-content-box`
34
+ - TypeScript 6 strict configuration with `isolatedDeclarations`
35
+ - ESM-only build via tsdown (Rolldown)
36
+ - Biome 2.4.5 linting and formatting
37
+ - Vitest 4 test infrastructure (72 unit tests)
38
+ - Size-limit bundle size guards
39
+ - VitePress 2 documentation site
40
+ - GitHub Actions CI/CD pipeline
41
+ - Changeset-based release pipeline
42
+ - Performance benchmarks with tinybench
43
+
44
+ ### Architecture
45
+ - Shared observer pool eliminates per-component ResizeObserver overhead
46
+ - rAF + startTransition batching: 100 elements → 1 render cycle
47
+ - WeakMap-based pool registry scoped per document/shadow root
48
+ - Stable callback identity via ref pattern (React Compiler safe)
49
+ - Worker mode: SharedArrayBuffer + Float16Array + Atomics for off-main-thread
50
+
51
+ [0.1.1]: https://github.com/ABCrimson/use-resize-observer/releases/tag/v0.1.1
52
+ [0.1.0]: https://github.com/ABCrimson/use-resize-observer/releases/tag/v0.1.0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Crimson Dev
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,188 @@
1
+ <div align="center">
2
+
3
+ <br />
4
+
5
+ <picture>
6
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/ABCrimson/use-resize-observer/main/.github/assets/logo-dark.svg">
7
+ <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/ABCrimson/use-resize-observer/main/.github/assets/logo-light.svg">
8
+ <img alt="@crimson_dev/use-resize-observer" src="https://raw.githubusercontent.com/ABCrimson/use-resize-observer/main/.github/assets/logo-light.svg" width="480">
9
+ </picture>
10
+
11
+ <br />
12
+
13
+ **Zero-dependency, Worker-native, ESNext-first React 19 ResizeObserver hook**
14
+
15
+ <br />
16
+
17
+ [![npm version][npm-badge]][npm-url]
18
+ [![bundle size][size-badge]][size-url]
19
+ [![CI][ci-badge]][ci-url]
20
+ [![license][license-badge]][license-url]
21
+ [![TypeScript][ts-badge]][ts-url]
22
+ [![docs][docs-badge]][docs-url]
23
+
24
+ [npm-badge]: https://img.shields.io/npm/v/@crimson_dev/use-resize-observer?style=flat-square&color=DC143C&labelColor=0D1117
25
+ [npm-url]: https://npmjs.com/package/@crimson_dev/use-resize-observer
26
+ [size-badge]: https://img.shields.io/bundlephobia/minzip/@crimson_dev/use-resize-observer?style=flat-square&color=DC143C&labelColor=0D1117&label=gzip
27
+ [size-url]: https://bundlephobia.com/package/@crimson_dev/use-resize-observer
28
+ [ci-badge]: https://img.shields.io/github/actions/workflow/status/ABCrimson/use-resize-observer/ci.yml?style=flat-square&labelColor=0D1117&label=CI
29
+ [ci-url]: https://github.com/ABCrimson/use-resize-observer/actions/workflows/ci.yml
30
+ [license-badge]: https://img.shields.io/npm/l/@crimson_dev/use-resize-observer?style=flat-square&color=DC143C&labelColor=0D1117
31
+ [license-url]: https://github.com/ABCrimson/use-resize-observer/blob/main/LICENSE
32
+ [ts-badge]: https://img.shields.io/badge/TypeScript-6.0-3178C6?style=flat-square&labelColor=0D1117
33
+ [ts-url]: https://www.typescriptlang.org/
34
+ [docs-badge]: https://img.shields.io/badge/docs-GitHub%20Pages-DC143C?style=flat-square&labelColor=0D1117
35
+ [docs-url]: https://abcrimson.github.io/use-resize-observer/
36
+
37
+ </div>
38
+
39
+ ---
40
+
41
+ ## Quick Start
42
+
43
+ ```bash
44
+ npm install @crimson_dev/use-resize-observer
45
+ ```
46
+
47
+ ```tsx
48
+ import { useResizeObserver } from '@crimson_dev/use-resize-observer';
49
+
50
+ function ResponsiveCard() {
51
+ const { ref, width, height } = useResizeObserver<HTMLDivElement>();
52
+
53
+ return (
54
+ <div ref={ref}>
55
+ {width} × {height}
56
+ </div>
57
+ );
58
+ }
59
+ ```
60
+
61
+ ## Why This Exists
62
+
63
+ Most resize hooks create **one `ResizeObserver` per component**. At scale, that means hundreds of observers competing for the main thread. This library uses a **shared observer pool** — one `ResizeObserver` per document root — with `requestAnimationFrame` batching and React `startTransition` wrapping. The result: **100 elements resizing = 1 render cycle**.
64
+
65
+ ## Highlights
66
+
67
+ <table>
68
+ <tr><td>📦</td><td><strong>&lt; 1.1kB</strong> gzip &middot; zero dependencies</td></tr>
69
+ <tr><td>⚡</td><td>Shared <code>ResizeObserver</code> pool &middot; rAF batching &middot; <code>startTransition</code></td></tr>
70
+ <tr><td>🧵</td><td>Worker mode via <code>SharedArrayBuffer</code> + <code>Float16Array</code></td></tr>
71
+ <tr><td>🎯</td><td>All 3 box models: <code>content-box</code>, <code>border-box</code>, <code>device-pixel-content-box</code></td></tr>
72
+ <tr><td>🧹</td><td><code>FinalizationRegistry</code> for automatic GC cleanup</td></tr>
73
+ <tr><td>🏗️</td><td>ES2026: <code>using</code> / <code>Symbol.dispose</code>, <code>Promise.try()</code></td></tr>
74
+ <tr><td>⚛️</td><td>React 19.3+ &middot; React Compiler verified</td></tr>
75
+ <tr><td>📝</td><td>TypeScript 6 strict &middot; <code>isolatedDeclarations</code></td></tr>
76
+ <tr><td>🌐</td><td>SSR/RSC safe &middot; server entry with mock result</td></tr>
77
+ </table>
78
+
79
+ ## Entry Points
80
+
81
+ ```typescript
82
+ // Main — primary hook
83
+ import { useResizeObserver } from '@crimson_dev/use-resize-observer';
84
+
85
+ // Multi-element — observe N elements with 1 hook
86
+ import { useResizeObserverEntries } from '@crimson_dev/use-resize-observer';
87
+
88
+ // Factory — framework-agnostic, imperative API
89
+ import { createResizeObserver } from '@crimson_dev/use-resize-observer';
90
+
91
+ // Worker — off-main-thread via SharedArrayBuffer
92
+ import { useResizeObserverWorker } from '@crimson_dev/use-resize-observer/worker';
93
+
94
+ // Core — EventTarget-based, any framework
95
+ import { createResizeObservable } from '@crimson_dev/use-resize-observer/core';
96
+
97
+ // Server — SSR/RSC safe
98
+ import { createServerResizeObserverMock } from '@crimson_dev/use-resize-observer/server';
99
+
100
+ // Shim — polyfill for legacy browsers
101
+ import '@crimson_dev/use-resize-observer/shim';
102
+ ```
103
+
104
+ ## API
105
+
106
+ ### `useResizeObserver<T>(options?)`
107
+
108
+ ```typescript
109
+ const { ref, width, height, entry } = useResizeObserver<HTMLDivElement>({
110
+ box: 'content-box', // 'content-box' | 'border-box' | 'device-pixel-content-box'
111
+ ref: externalRef, // optional external ref
112
+ root: shadowRoot, // optional Document | ShadowRoot
113
+ onResize: (entry) => {}, // stable callback (no useCallback needed)
114
+ });
115
+ ```
116
+
117
+ | Return | Type | Description |
118
+ |--------|------|-------------|
119
+ | `ref` | `RefObject<T \| null>` | Attach to the element to observe |
120
+ | `width` | `number \| undefined` | Inline size of the observed box |
121
+ | `height` | `number \| undefined` | Block size of the observed box |
122
+ | `entry` | `ResizeObserverEntry \| undefined` | Raw entry from the observer |
123
+
124
+ ### `useResizeObserverEntries(refs, options?)`
125
+
126
+ ```typescript
127
+ const entries = useResizeObserverEntries([ref1, ref2, ref3], {
128
+ box: 'border-box',
129
+ });
130
+ // entries: Map<Element, { width, height, entry }>
131
+ ```
132
+
133
+ ### `createResizeObserver(options?)`
134
+
135
+ ```typescript
136
+ using observer = createResizeObserver({ box: 'border-box' });
137
+ observer.observe(element, (entry) => console.log(entry));
138
+ // Automatically cleaned up via Symbol.dispose
139
+ ```
140
+
141
+ ## Architecture
142
+
143
+ ```
144
+ ┌─────────────────────────────────────────────────┐
145
+ │ Your Components │
146
+ │ useResizeObserver() useResizeObserverEntries() │
147
+ └──────────────────────┬──────────────────────────┘
148
+
149
+ ┌────────▼────────┐
150
+ │ ObserverPool │ 1 per document root
151
+ │ (WeakMap) │ FinalizationRegistry
152
+ └────────┬────────┘
153
+
154
+ ┌────────▼────────┐
155
+ │ RafScheduler │ Map<Element, FlushEntry>
156
+ │ last-write-wins│ requestAnimationFrame
157
+ └────────┬────────┘
158
+
159
+ ┌────────▼────────┐
160
+ │ startTransition │ Non-urgent batched update
161
+ │ setState() │ 1 render per frame
162
+ └─────────────────┘
163
+ ```
164
+
165
+ ## Comparison
166
+
167
+ | | `use-resize-observer@9` | `@crimson_dev/use-resize-observer` |
168
+ |---|---|---|
169
+ | Bundle | ~800B | **< 1.1kB** (pool + scheduler + hook) |
170
+ | React | 16.8+ | **19.3+** with Compiler |
171
+ | Module | CJS + ESM | **ESM only** |
172
+ | TypeScript | 4.x | **6.0 strict** |
173
+ | Observer model | 1 per component | **Shared pool** |
174
+ | Worker mode | — | **SharedArrayBuffer** |
175
+ | Box models | content-box only | **All 3** |
176
+ | GC cleanup | Manual | **Automatic** |
177
+ | Batching | None | **rAF + startTransition** |
178
+
179
+ ## Requirements
180
+
181
+ - **Node** ≥ 25.0.0
182
+ - **React** ≥ 19.3.0
183
+ - **TypeScript** ≥ 6.0 (recommended)
184
+ - **Browser** with native `ResizeObserver` (or use the `/shim` entry)
185
+
186
+ ## License
187
+
188
+ [MIT](./LICENSE) — Crimson Dev
package/dist/core.d.ts ADDED
@@ -0,0 +1,38 @@
1
+
2
+ import { r as ResizeObserverBoxOptions } from "./types-ASPFw2w_.js";
3
+
4
+ //#region src/core.d.ts
5
+ /** Detail payload for resize events dispatched by the observable. */
6
+ interface ResizeEventDetail {
7
+ readonly width: number;
8
+ readonly height: number;
9
+ readonly entry: ResizeObserverEntry;
10
+ }
11
+ /** Custom event type for resize observations. */
12
+ declare class ResizeEvent extends CustomEvent<ResizeEventDetail> {
13
+ constructor(detail: ResizeEventDetail);
14
+ }
15
+ /** Options for the framework-agnostic observable. */
16
+ interface CreateResizeObservableOptions {
17
+ /** Which box model to report. @default 'content-box' */
18
+ box?: ResizeObserverBoxOptions;
19
+ }
20
+ /** Framework-agnostic resize observable with EventTarget-based dispatching. */
21
+ interface ResizeObservable extends EventTarget, Disposable {
22
+ /** Stop observing and clean up resources. */
23
+ disconnect(): void;
24
+ }
25
+ /**
26
+ * Create a framework-agnostic resize observable for an element.
27
+ *
28
+ * Wraps a `ResizeObserver` with `EventTarget` dispatching — consumers
29
+ * subscribe via `addEventListener('resize', handler)`.
30
+ *
31
+ * @param target - The DOM element to observe.
32
+ * @param options - Configuration options.
33
+ * @returns A `ResizeObservable` with `addEventListener` and `disconnect`.
34
+ */
35
+ declare const createResizeObservable: (target: Element, options?: CreateResizeObservableOptions) => ResizeObservable;
36
+ //#endregion
37
+ export { CreateResizeObservableOptions, ResizeEvent, ResizeEventDetail, ResizeObservable, createResizeObservable };
38
+ //# sourceMappingURL=core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.d.ts","names":[],"sources":["../src/core.ts"],"mappings":";;;;;UAoBiB,iBAAA;EAAA,SACN,KAAA;EAAA,SACA,MAAA;EAAA,SACA,KAAA,EAAO,mBAAA;AAAA;;cAIL,WAAA,SAAoB,WAAA,CAAY,iBAAA;EAC3C,WAAA,CAAY,MAAA,EAAQ,iBAAA;AAAA;;UAML,6BAAA;EAAA;EAEf,GAAA,GAAM,wBAAA;AAAA;;UAIS,gBAAA,SAAyB,WAAA,EAAa,UAAA;EAAtC;EAEf,UAAA;AAAA;;;;;;AA+BF;;;;;cAAa,sBAAA,GACX,MAAA,EAAQ,OAAA,EACR,OAAA,GAAS,6BAAA,KACR,gBAAA"}
package/dist/core.js ADDED
@@ -0,0 +1,58 @@
1
+ 'use client';
2
+ //#region src/core.ts
3
+ /** Custom event type for resize observations. */
4
+ var ResizeEvent = class extends CustomEvent {
5
+ constructor(detail) {
6
+ super("resize", { detail });
7
+ }
8
+ };
9
+ /**
10
+ * Extract the first size entry for the given box model.
11
+ * @internal
12
+ */
13
+ const extractBoxSize = (entry, box) => {
14
+ switch (box) {
15
+ case "border-box": return entry.borderBoxSize[0];
16
+ case "device-pixel-content-box": return (entry.devicePixelContentBoxSize ?? entry.contentBoxSize)[0];
17
+ default: return entry.contentBoxSize[0];
18
+ }
19
+ };
20
+ /**
21
+ * Create a framework-agnostic resize observable for an element.
22
+ *
23
+ * Wraps a `ResizeObserver` with `EventTarget` dispatching — consumers
24
+ * subscribe via `addEventListener('resize', handler)`.
25
+ *
26
+ * @param target - The DOM element to observe.
27
+ * @param options - Configuration options.
28
+ * @returns A `ResizeObservable` with `addEventListener` and `disconnect`.
29
+ */
30
+ const createResizeObservable = (target, options = {}) => {
31
+ const { box = "content-box" } = options;
32
+ const eventTarget = new EventTarget();
33
+ const observer = new ResizeObserver((entries) => {
34
+ for (const entry of entries) {
35
+ const sizeEntry = extractBoxSize(entry, box);
36
+ const detail = {
37
+ width: sizeEntry?.inlineSize ?? 0,
38
+ height: sizeEntry?.blockSize ?? 0,
39
+ entry
40
+ };
41
+ eventTarget.dispatchEvent(new ResizeEvent(detail));
42
+ }
43
+ });
44
+ observer.observe(target, { box });
45
+ const disconnect = () => {
46
+ observer.disconnect();
47
+ };
48
+ return Object.assign(eventTarget, {
49
+ disconnect,
50
+ [Symbol.dispose]() {
51
+ disconnect();
52
+ }
53
+ });
54
+ };
55
+
56
+ //#endregion
57
+ export { ResizeEvent, createResizeObservable };
58
+ //# sourceMappingURL=core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"core.js","names":[],"sources":["../src/core.ts"],"sourcesContent":["/**\n * Framework-agnostic core observable for ResizeObserver events.\n *\n * Uses the `EventTarget` API for zero-dependency event dispatching.\n * Can be adapted by any framework (React, Solid, Vue, Svelte, vanilla).\n *\n * Implements `Disposable` for ES2026 `using` declarations.\n *\n * @example\n * ```ts\n * using observable = createResizeObservable(element, { box: 'content-box' });\n * observable.addEventListener('resize', (e) => {\n * console.log(e.detail.width, e.detail.height);\n * });\n * ```\n */\n\nimport type { ResizeObserverBoxOptions } from './types.js';\n\n/** Detail payload for resize events dispatched by the observable. */\nexport interface ResizeEventDetail {\n readonly width: number;\n readonly height: number;\n readonly entry: ResizeObserverEntry;\n}\n\n/** Custom event type for resize observations. */\nexport class ResizeEvent extends CustomEvent<ResizeEventDetail> {\n constructor(detail: ResizeEventDetail) {\n super('resize', { detail });\n }\n}\n\n/** Options for the framework-agnostic observable. */\nexport interface CreateResizeObservableOptions {\n /** Which box model to report. @default 'content-box' */\n box?: ResizeObserverBoxOptions;\n}\n\n/** Framework-agnostic resize observable with EventTarget-based dispatching. */\nexport interface ResizeObservable extends EventTarget, Disposable {\n /** Stop observing and clean up resources. */\n disconnect(): void;\n}\n\n/**\n * Extract the first size entry for the given box model.\n * @internal\n */\nconst extractBoxSize = (\n entry: ResizeObserverEntry,\n box: ResizeObserverBoxOptions,\n): ResizeObserverSize | undefined => {\n switch (box) {\n case 'border-box':\n return entry.borderBoxSize[0];\n case 'device-pixel-content-box':\n return (entry.devicePixelContentBoxSize ?? entry.contentBoxSize)[0];\n default:\n return entry.contentBoxSize[0];\n }\n};\n\n/**\n * Create a framework-agnostic resize observable for an element.\n *\n * Wraps a `ResizeObserver` with `EventTarget` dispatching — consumers\n * subscribe via `addEventListener('resize', handler)`.\n *\n * @param target - The DOM element to observe.\n * @param options - Configuration options.\n * @returns A `ResizeObservable` with `addEventListener` and `disconnect`.\n */\nexport const createResizeObservable = (\n target: Element,\n options: CreateResizeObservableOptions = {},\n): ResizeObservable => {\n const { box = 'content-box' } = options;\n const eventTarget = new EventTarget();\n\n const observer = new ResizeObserver((entries) => {\n for (const entry of entries) {\n const sizeEntry = extractBoxSize(entry, box);\n\n const detail: ResizeEventDetail = {\n width: sizeEntry?.inlineSize ?? 0,\n height: sizeEntry?.blockSize ?? 0,\n entry,\n };\n\n eventTarget.dispatchEvent(new ResizeEvent(detail));\n }\n });\n\n observer.observe(target, { box });\n\n const disconnect = (): void => {\n observer.disconnect();\n };\n\n return Object.assign(eventTarget, {\n disconnect,\n [Symbol.dispose](): void {\n disconnect();\n },\n });\n};\n"],"mappings":";;;AA2BA,IAAa,cAAb,cAAiC,YAA+B;CAC9D,YAAY,QAA2B;AACrC,QAAM,UAAU,EAAE,QAAQ,CAAC;;;;;;;AAoB/B,MAAM,kBACJ,OACA,QACmC;AACnC,SAAQ,KAAR;EACE,KAAK,aACH,QAAO,MAAM,cAAc;EAC7B,KAAK,2BACH,SAAQ,MAAM,6BAA6B,MAAM,gBAAgB;EACnE,QACE,QAAO,MAAM,eAAe;;;;;;;;;;;;;AAclC,MAAa,0BACX,QACA,UAAyC,EAAE,KACtB;CACrB,MAAM,EAAE,MAAM,kBAAkB;CAChC,MAAM,cAAc,IAAI,aAAa;CAErC,MAAM,WAAW,IAAI,gBAAgB,YAAY;AAC/C,OAAK,MAAM,SAAS,SAAS;GAC3B,MAAM,YAAY,eAAe,OAAO,IAAI;GAE5C,MAAM,SAA4B;IAChC,OAAO,WAAW,cAAc;IAChC,QAAQ,WAAW,aAAa;IAChC;IACD;AAED,eAAY,cAAc,IAAI,YAAY,OAAO,CAAC;;GAEpD;AAEF,UAAS,QAAQ,QAAQ,EAAE,KAAK,CAAC;CAEjC,MAAM,mBAAyB;AAC7B,WAAS,YAAY;;AAGvB,QAAO,OAAO,OAAO,aAAa;EAChC;EACA,CAAC,OAAO,WAAiB;AACvB,eAAY;;EAEf,CAAC"}
@@ -0,0 +1,99 @@
1
+
2
+ import { a as UseResizeObserverOptions, i as ResizeObserverFactory, n as ResizeCallback, o as UseResizeObserverResult, r as ResizeObserverBoxOptions, t as CreateResizeObserverOptions } from "./types-ASPFw2w_.js";
3
+ import React, { RefObject } from "react";
4
+
5
+ //#region src/context.d.ts
6
+ /**
7
+ * Context for injecting a custom `ResizeObserver` constructor.
8
+ *
9
+ * Useful for:
10
+ * - **Testing**: Inject a mock `ResizeObserver` for deterministic tests.
11
+ * - **SSR**: Inject a no-op implementation to avoid `ReferenceError`.
12
+ * - **Polyfills**: Inject a polyfill without modifying `globalThis`.
13
+ *
14
+ * @example
15
+ * ```tsx
16
+ * // In tests:
17
+ * <ResizeObserverContext.Provider value={MockResizeObserver}>
18
+ * <ComponentThatUsesResize />
19
+ * </ResizeObserverContext.Provider>
20
+ * ```
21
+ */
22
+ declare const ResizeObserverContext: React.Context<typeof ResizeObserver | null>;
23
+ //#endregion
24
+ //#region src/factory.d.ts
25
+ /**
26
+ * Framework-agnostic factory for creating a ResizeObserver subscription
27
+ * using the shared pool architecture.
28
+ *
29
+ * Uses the same pool and scheduler as the React hook — no duplicate observers.
30
+ * Implements cleanup tracking with `Map` for efficient iteration.
31
+ *
32
+ * @param options - Configuration options.
33
+ * @returns An object with `observe`, `unobserve`, and `disconnect` methods.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * using observer = createResizeObserver({ box: 'border-box' });
38
+ * observer.observe(element, (entry) => {
39
+ * console.log(entry.contentRect.width);
40
+ * });
41
+ * ```
42
+ */
43
+ declare const createResizeObserver: (options?: CreateResizeObserverOptions) => ResizeObserverFactory & Disposable;
44
+ //#endregion
45
+ //#region src/hook.d.ts
46
+ /**
47
+ * Primary React hook for observing element resize events.
48
+ *
49
+ * Features:
50
+ * - Single shared `ResizeObserver` per document root (pool architecture)
51
+ * - `requestAnimationFrame` batching with `startTransition` wrapping
52
+ * - GC-backed cleanup via `FinalizationRegistry`
53
+ * - React Compiler-safe (stable callback identity via ref pattern)
54
+ * - Sub-300B gzip bundle contribution
55
+ *
56
+ * @param options - Configuration options.
57
+ * @returns Ref, width, height, and raw entry.
58
+ *
59
+ * @example
60
+ * ```tsx
61
+ * const { ref, width, height } = useResizeObserver<HTMLDivElement>();
62
+ * return <div ref={ref}>Size: {width} x {height}</div>;
63
+ * ```
64
+ */
65
+ declare const useResizeObserver: <T extends Element = Element>(options?: UseResizeObserverOptions<T>) => UseResizeObserverResult<T>;
66
+ //#endregion
67
+ //#region src/hook-multi.d.ts
68
+ /** Entry data for a single observed element in the multi-element hook. */
69
+ interface ResizeEntry {
70
+ readonly width: number;
71
+ readonly height: number;
72
+ readonly entry: ResizeObserverEntry;
73
+ }
74
+ /** Options for `useResizeObserverEntries`. */
75
+ interface UseResizeObserverEntriesOptions {
76
+ /** Which box model to report. @default 'content-box' */
77
+ box?: ResizeObserverBoxOptions;
78
+ /** Document or ShadowRoot scoping the pool. @default document */
79
+ root?: Document | ShadowRoot;
80
+ }
81
+ /**
82
+ * Multi-element variant: observe multiple elements simultaneously through
83
+ * a single pool subscription.
84
+ *
85
+ * @param refs - Array of refs pointing to elements to observe.
86
+ * @param options - Configuration options.
87
+ * @returns A `Map<Element, ResizeEntry>` keyed by observed element.
88
+ *
89
+ * @example
90
+ * ```tsx
91
+ * const ref1 = useRef<HTMLDivElement>(null);
92
+ * const ref2 = useRef<HTMLDivElement>(null);
93
+ * const entries = useResizeObserverEntries([ref1, ref2]);
94
+ * ```
95
+ */
96
+ declare const useResizeObserverEntries: (refs: ReadonlyArray<RefObject<Element | null>>, options?: UseResizeObserverEntriesOptions) => Map<Element, ResizeEntry>;
97
+ //#endregion
98
+ export { type CreateResizeObserverOptions, type ResizeCallback, type ResizeEntry, type ResizeObserverBoxOptions, ResizeObserverContext, type ResizeObserverFactory, type UseResizeObserverEntriesOptions, type UseResizeObserverOptions, type UseResizeObserverResult, createResizeObserver, useResizeObserver, useResizeObserverEntries };
99
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/context.ts","../src/factory.ts","../src/hook.ts","../src/hook-multi.ts"],"mappings":";;;;;;;;AAqBA;;;;;;;;;;;;ACIA;cDJa,qBAAA,EAAuB,KAAA,CAAM,OAAA,QAAe,cAAA;;;;;;AAAzD;;;;;;;;;;;;ACIA;;;cAAa,oBAAA,GACX,OAAA,GAAS,2BAAA,KACR,qBAAA,GAAwB,UAAA;;;;;;ADN3B;;;;;;;;;;;;ACIA;;;;cC+Ba,iBAAA,aAA+B,OAAA,GAAU,OAAA,EACpD,OAAA,GAAS,wBAAA,CAAyB,CAAA,MACjC,uBAAA,CAAwB,CAAA;;;;UCjDV,WAAA;EAAA,SACN,KAAA;EAAA,SACA,MAAA;EAAA,SACA,KAAA,EAAO,mBAAA;AAAA;;UAID,+BAAA;;EAEf,GAAA,GAAM,wBAAA;EHGiD;EGDvD,IAAA,GAAO,QAAA,GAAW,UAAA;AAAA;;AFKpB;;;;;;;;;;;;;;cE+Ba,wBAAA,GACX,IAAA,EAAM,aAAA,CAAc,SAAA,CAAU,OAAA,WAC9B,OAAA,GAAS,+BAAA,KACR,GAAA,CAAI,OAAA,EAAS,WAAA"}