@himanshu-sorathiya/react-kit 1.0.30 → 1.0.32

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.
@@ -1,6 +1,6 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
- import { Key } from 'react';
3
+ import { RefCallback, RefObject } from 'react';
4
4
 
5
5
  /**
6
6
  * Configuration for `useBatcher`.
@@ -1090,95 +1090,1221 @@ export interface UseThrottlerReturn {
1090
1090
  * @returns See {@link UseThrottlerReturn}.
1091
1091
  */
1092
1092
  export declare function useThrottler(delay: number, options?: ThrottleOptions): UseThrottlerReturn;
1093
+ /**
1094
+ * How to tell {@link useIntersectionObserver} what to observe.
1095
+ *
1096
+ * @remarks
1097
+ * Three shapes are accepted, matching the `getScrollElement`-style
1098
+ * convention used elsewhere in this library:
1099
+ * - **omitted / `undefined`** - ref-callback mode. Attach the hook's
1100
+ * returned `ref` to your own JSX element.
1101
+ * - **`null`** - explicitly disabled; nothing is observed regardless of
1102
+ * `enabled`.
1103
+ * - **an element, a `RefObject`, or a getter function**
1104
+ * (`() => Element | null`) - resolved on every render, so it's safe to
1105
+ * pass e.g. `() => someRef.current` without memoizing it.
1106
+ *
1107
+ * Unlike {@link ResizeObserverTargetInput}, there's no `Document`/`Window`
1108
+ * option here - the native `IntersectionObserver.observe()` only accepts an
1109
+ * `Element`.
1110
+ */
1111
+ export type IntersectionTargetInput = Element | RefObject<Element | null> | (() => Element | null) | null;
1112
+ /** Options for {@link useIntersectionObserver}. */
1113
+ export interface UseIntersectionObserverOptions {
1114
+ /**
1115
+ * External target to observe.
1116
+ *
1117
+ * @defaultValue `undefined` (ref-callback mode - see {@link IntersectionTargetInput})
1118
+ */
1119
+ target?: IntersectionTargetInput;
1120
+ /**
1121
+ * The element (or `Document`) used as the viewport when checking for
1122
+ * intersection.
1123
+ *
1124
+ * @defaultValue `null` (the browser viewport)
1125
+ */
1126
+ root?: Element | Document | null | undefined;
1127
+ /**
1128
+ * Margin added around `root`'s bounding box before computing
1129
+ * intersections, in CSS `margin` shorthand syntax (e.g. `"200px 0px"`
1130
+ * to start intersecting 200px early, useful for pre-triggering
1131
+ * lazy-loads slightly before an element is actually on screen).
1132
+ *
1133
+ * @defaultValue `"0px"`
1134
+ */
1135
+ rootMargin?: string | undefined;
1136
+ /**
1137
+ * The intersection ratio (or ratios) at which the callback fires. A
1138
+ * single number fires once past that ratio; an array fires at each
1139
+ * threshold crossed, useful for progressive/scroll-linked effects.
1140
+ *
1141
+ * @defaultValue `0` (fires as soon as even one pixel is visible)
1142
+ */
1143
+ threshold?: number | number[] | undefined;
1144
+ /**
1145
+ * Pause observing without unmounting - `isIntersecting` and
1146
+ * `intersectionRatio` are retained at their last values, just no longer
1147
+ * updated.
1148
+ *
1149
+ * @defaultValue `true`
1150
+ */
1151
+ enabled?: boolean | undefined;
1152
+ /**
1153
+ * Once the target intersects for the first time, disconnect the
1154
+ * observer and leave `isIntersecting` latched at `true` permanently (for
1155
+ * this target - a new target gets a fresh chance). Useful for
1156
+ * lazy-load-once patterns, where there's no need to keep paying for
1157
+ * observation after the content has already loaded.
1158
+ *
1159
+ * @defaultValue `false`
1160
+ */
1161
+ freezeOnceVisible?: boolean | undefined;
1162
+ /**
1163
+ * Value returned before the first observation resolves.
1164
+ *
1165
+ * @defaultValue `false`
1166
+ */
1167
+ initialIsIntersecting?: boolean | undefined;
1168
+ /**
1169
+ * Debounce state updates by this many milliseconds. `0` applies every
1170
+ * observation immediately.
1171
+ *
1172
+ * @defaultValue `0`
1173
+ */
1174
+ debounceMs?: number | undefined;
1175
+ /**
1176
+ * Imperative callback fired on every observation update, in addition to
1177
+ * (not instead of) the hook's returned state updating.
1178
+ *
1179
+ * @param isIntersecting - Whether the target currently intersects `root`.
1180
+ * @param entry - The raw `IntersectionObserverEntry` for this observation.
1181
+ */
1182
+ onChange?: (isIntersecting: boolean, entry: IntersectionObserverEntry) => void | undefined;
1183
+ }
1184
+ /**
1185
+ * Return value of {@link useIntersectionObserver}.
1186
+ *
1187
+ * @typeParam T - Element type of the ref-callback, e.g. pass
1188
+ * `useIntersectionObserver<HTMLImageElement>()` for `ref` typed as
1189
+ * `RefCallback<HTMLImageElement>` instead of the default `RefCallback<Element>`.
1190
+ */
1191
+ export interface UseIntersectionObserverReturn<T extends Element = Element> {
1192
+ /**
1193
+ * Attach to your own JSX element to observe it: `<div ref={ref}>`. A
1194
+ * no-op (never called) when `target` is supplied instead.
1195
+ */
1196
+ ref: RefCallback<T>;
1197
+ /** Whether the target currently intersects `root`, per the last observation. */
1198
+ isIntersecting: boolean;
1199
+ /** How much of the target is currently visible, from `0` (none) to `1` (fully visible). */
1200
+ intersectionRatio: number;
1201
+ /** The raw entry from the most recent observation. `undefined` before the first one. */
1202
+ entry: IntersectionObserverEntry | undefined;
1203
+ }
1204
+ /**
1205
+ * Tracks whether an element intersects a root (by default, the viewport),
1206
+ * backed by the native `IntersectionObserver` API.
1207
+ *
1208
+ * @remarks
1209
+ * Supports two ways of choosing what to observe - see
1210
+ * {@link IntersectionTargetInput} for the full list of accepted shapes:
1211
+ * - **Ref-callback mode** (default): attach the returned `ref` to your own
1212
+ * JSX element.
1213
+ * - **External target mode**: pass `target` (an element, `RefObject`, or
1214
+ * getter function) to observe something you don't render yourself.
1215
+ *
1216
+ * `isIntersecting`/`intersectionRatio` reflect `initialIsIntersecting`/`0`
1217
+ * until the first observation resolves, which happens asynchronously after
1218
+ * mount.
1219
+ *
1220
+ * @typeParam T - Element type of the ref-callback, e.g. pass
1221
+ * `useIntersectionObserver<HTMLImageElement>()` if you want `ref` typed as
1222
+ * `RefCallback<HTMLImageElement>` instead of the default `RefCallback<Element>`.
1223
+ *
1224
+ * @param options - See {@link UseIntersectionObserverOptions}. All fields optional.
1225
+ * @returns See {@link UseIntersectionObserverReturn}.
1226
+ *
1227
+ * @example
1228
+ * Lazy-load an image once it's actually visible, then stop observing:
1229
+ * ```tsx
1230
+ * function LazyImage({ src }: { src: string }) {
1231
+ * const { ref, isIntersecting } = useIntersectionObserver<HTMLDivElement>({
1232
+ * freezeOnceVisible: true,
1233
+ * rootMargin: "200px",
1234
+ * });
1235
+ * return <div ref={ref}>{isIntersecting && <img src={src} />}</div>;
1236
+ * }
1237
+ * ```
1238
+ *
1239
+ * @example
1240
+ * External target mode, observing a scroll-triggered "load more" sentinel:
1241
+ * ```tsx
1242
+ * const sentinelRef = useRef<HTMLDivElement>(null);
1243
+ * const { isIntersecting } = useIntersectionObserver({
1244
+ * target: () => sentinelRef.current,
1245
+ * onChange: (visible) => visible && loadNextPage(),
1246
+ * });
1247
+ * ```
1248
+ *
1249
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API | Intersection Observer API} on MDN
1250
+ */
1251
+ export declare function useIntersectionObserver<T extends Element = Element>(options?: UseIntersectionObserverOptions): UseIntersectionObserverReturn<T>;
1252
+ /**
1253
+ * How to tell {@link useMutationObserver} what to observe.
1254
+ *
1255
+ * @remarks
1256
+ * Three shapes are accepted, matching the `getScrollElement`-style
1257
+ * convention used elsewhere in this library:
1258
+ * - **omitted / `undefined`** - ref-callback mode. Attach the hook's
1259
+ * returned `ref` to your own JSX element.
1260
+ * - **`null`** - explicitly disabled; nothing is observed regardless of
1261
+ * `enabled`.
1262
+ * - **a `Node`, a `RefObject`, or a getter function** (`() => Node | null`)
1263
+ * - resolved on every render, so it's safe to pass e.g.
1264
+ * `() => someRef.current` without memoizing it.
1265
+ *
1266
+ * Typed as `Node` (rather than `Element`, like {@link IntersectionTargetInput})
1267
+ * because the native `MutationObserver.observe()` accepts any `Node` -
1268
+ * `Document` and `DocumentFragment` included, not just elements.
1269
+ */
1270
+ export type MutationTargetInput = Node | RefObject<Node | null> | (() => Node | null) | null;
1271
+ /**
1272
+ * Options for {@link useMutationObserver}.
1273
+ *
1274
+ * @remarks
1275
+ * Extends the native `MutationObserverInit` directly, so `childList`,
1276
+ * `attributes`, `attributeFilter`, `attributeOldValue`, `characterData`,
1277
+ * `characterDataOldValue`, and `subtree` all work exactly as documented for
1278
+ * {@link https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe | MutationObserver.observe()} -
1279
+ * this hook doesn't change their meaning or defaults, just forwards them.
1280
+ * Note the native API throws if `attributeFilter`/`attributeOldValue` are
1281
+ * set while `attributes` is explicitly `false`.
1282
+ */
1283
+ export interface UseMutationObserverOptions {
1284
+ /**
1285
+ * External target to observe.
1286
+ *
1287
+ * @defaultValue `undefined` (ref-callback mode - see {@link MutationTargetInput})
1288
+ */
1289
+ target?: MutationTargetInput;
1290
+ /**
1291
+ * Pause observing without unmounting - the last delivered `records` are
1292
+ * retained, just no longer updated.
1293
+ *
1294
+ * @defaultValue `true`
1295
+ */
1296
+ enabled?: boolean | undefined;
1297
+ /**
1298
+ * Debounce state updates by this many milliseconds. `0` applies every
1299
+ * batch immediately. Note the native `MutationObserver` already batches
1300
+ * synchronous mutations into one callback per microtask on its own -
1301
+ * this further throttles the resulting React re-renders on top of that,
1302
+ * useful when mutations arrive in frequent, independent bursts.
1303
+ *
1304
+ * @defaultValue `0`
1305
+ */
1306
+ debounceMs?: number | undefined;
1307
+ /**
1308
+ * Imperative callback fired on every batch of mutations, in addition to
1309
+ * (not instead of) the hook's returned `records` state updating.
1310
+ *
1311
+ * @param mutations - The batch of records delivered by the native observer.
1312
+ * @param observer - The underlying `MutationObserver` instance, e.g. to call `.takeRecords()` from within the callback.
1313
+ */
1314
+ onMutate?: (mutations: MutationRecord[], observer: MutationObserver) => void | undefined;
1315
+ childList?: boolean | undefined;
1316
+ attributes?: boolean | undefined;
1317
+ attributeFilter?: string[] | undefined;
1318
+ attributeOldValue?: boolean | undefined;
1319
+ characterData?: boolean | undefined;
1320
+ characterDataOldValue?: boolean | undefined;
1321
+ subtree?: boolean | undefined;
1322
+ }
1323
+ /**
1324
+ * Return value of {@link useMutationObserver}.
1325
+ *
1326
+ * @typeParam T - Node type of the ref-callback, e.g. pass
1327
+ * `useMutationObserver<HTMLDivElement>()` for `ref` typed as
1328
+ * `RefCallback<HTMLDivElement>` instead of the default `RefCallback<Element>`.
1329
+ */
1330
+ export interface UseMutationObserverReturn<T extends Node = Element> {
1331
+ /**
1332
+ * Attach to your own JSX element to observe it: `<div ref={ref}>`. A
1333
+ * no-op (never called) when `target` is supplied instead.
1334
+ */
1335
+ ref: RefCallback<T>;
1336
+ /** The most recent batch of mutation records. Empty until the first batch arrives. */
1337
+ records: MutationRecord[];
1338
+ /**
1339
+ * Synchronously flushes and returns any mutation records queued but not
1340
+ * yet delivered to `onMutate`/`records` - a direct passthrough to the
1341
+ * native `MutationObserver.takeRecords()`. Useful immediately before
1342
+ * reading layout, to make sure you're not acting on stale DOM state.
1343
+ */
1344
+ takeRecords: () => MutationRecord[];
1345
+ }
1346
+ /**
1347
+ * Watches a DOM subtree for mutations - child list changes, attribute
1348
+ * changes, and/or character data changes - backed by the native
1349
+ * `MutationObserver` API.
1350
+ *
1351
+ * @remarks
1352
+ * Supports two ways of choosing what to observe - see
1353
+ * {@link MutationTargetInput} for the full list of accepted shapes:
1354
+ * - **Ref-callback mode** (default): attach the returned `ref` to your own
1355
+ * JSX element.
1356
+ * - **External target mode**: pass `target` (a node, `RefObject`, or getter
1357
+ * function) to observe something you don't render yourself.
1358
+ *
1359
+ * By default only `childList` is observed - pass `attributes: true`,
1360
+ * `characterData: true`, and/or `subtree: true` explicitly to also watch
1361
+ * those (see {@link UseMutationObserverOptions} for the full native option
1362
+ * set this hook forwards).
1363
+ *
1364
+ * This is a general-purpose DOM-watching hook, not something
1365
+ * {@link useVirtualList}/{@link useVirtualGrid} use internally - item
1366
+ * resizing is tracked via `measureElement` (backed by `ResizeObserver`
1367
+ * instead, which is the correct tool for size changes specifically).
1368
+ *
1369
+ * @typeParam T - Node type of the ref-callback, e.g. pass
1370
+ * `useMutationObserver<HTMLDivElement>()` if you want `ref` typed as
1371
+ * `RefCallback<HTMLDivElement>` instead of the default `RefCallback<Element>`.
1372
+ *
1373
+ * @param options - See {@link UseMutationObserverOptions}. All fields optional.
1374
+ * @returns See {@link UseMutationObserverReturn}.
1375
+ *
1376
+ * @example
1377
+ * Warn in development if a third-party script injects DOM nodes into a container React manages:
1378
+ * ```tsx
1379
+ * function ManagedContainer() {
1380
+ * const { ref, records } = useMutationObserver<HTMLDivElement>({ subtree: true });
1381
+ * useEffect(() => {
1382
+ * if (records.length) console.warn("Unexpected external DOM mutation", records);
1383
+ * }, [records]);
1384
+ * return <div ref={ref}>{"..."}</div>;
1385
+ * }
1386
+ * ```
1387
+ *
1388
+ * @example
1389
+ * External target mode, watching a specific attribute:
1390
+ * ```tsx
1391
+ * const rootRef = useRef<HTMLElement>(document.documentElement);
1392
+ * useMutationObserver({
1393
+ * target: () => rootRef.current,
1394
+ * attributes: true,
1395
+ * attributeFilter: ["data-theme"],
1396
+ * onMutate: () => console.log("theme changed"),
1397
+ * });
1398
+ * ```
1399
+ *
1400
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver | MutationObserver} on MDN
1401
+ */
1402
+ export declare function useMutationObserver<T extends Node = Element>(options?: UseMutationObserverOptions): UseMutationObserverReturn<T>;
1403
+ /**
1404
+ * Which CSS box model {@link useResizeObserver} measures.
1405
+ *
1406
+ * @remarks
1407
+ * Mirrors the `box` option of the native
1408
+ * {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver/observe | ResizeObserver.observe()}
1409
+ * method:
1410
+ * - `"content-box"` - padding and border excluded. The default, and what
1411
+ * most layout code expects (matches `element.clientWidth`/`clientHeight`
1412
+ * roughly, modulo scrollbars).
1413
+ * - `"border-box"` - padding and border included (matches
1414
+ * `getBoundingClientRect()` for elements without CSS transforms).
1415
+ * - `"device-pixel-content-box"` - content-box, but in physical device
1416
+ * pixels rather than CSS pixels. Useful for pixel-perfect canvas/WebGL
1417
+ * sizing on high-DPI screens. Falls back to `"content-box"` on browsers
1418
+ * that don't populate this field on the observer entry.
1419
+ *
1420
+ * Ignored when the observed target is a `Window` - see {@link ResizeObserverTargetElement}.
1421
+ */
1422
+ export type ResizeObserverBox = "border-box" | "content-box" | "device-pixel-content-box";
1423
+ /**
1424
+ * Anything {@link useResizeObserver} can observe: `Element` for a normal DOM
1425
+ * node, or `Document`/`Window` for whole-page sizing (both fall back to
1426
+ * `document.documentElement`'s `clientWidth`/`clientHeight` internally,
1427
+ * since `ResizeObserver` itself can only `observe()` an `Element`).
1428
+ */
1429
+ export type ResizeObserverTargetElement = Document | Element | Window;
1430
+ /**
1431
+ * How to tell {@link useResizeObserver} what to observe.
1432
+ *
1433
+ * @remarks
1434
+ * Four shapes are accepted, matching the `getScrollElement`-style
1435
+ * convention used elsewhere in this library:
1436
+ * - **omitted / `undefined`** - ref-callback mode. Attach the hook's
1437
+ * returned `ref` to your own JSX element.
1438
+ * - **`null`** - explicitly disabled; nothing is observed regardless of
1439
+ * `enabled`.
1440
+ * - **an element, `Document`, or `Window`** - observe it directly.
1441
+ * - **a `RefObject` or a getter function** (`() => ResizeObserverTargetElement | null`)
1442
+ * - resolved on every render, so it's safe to pass e.g. `() => scrollRef.current`
1443
+ * without memoizing it.
1444
+ */
1445
+ export type ResizeObserverTargetInput = ResizeObserverTargetElement | RefObject<ResizeObserverTargetElement | null> | (() => ResizeObserverTargetElement | null) | null;
1446
+ /** A measured width/height pair, in CSS pixels (or device pixels - see {@link ResizeObserverBox}). */
1447
+ export interface ObservedSize {
1448
+ width: number;
1449
+ height: number;
1450
+ }
1451
+ /** Options for {@link useResizeObserver}. */
1452
+ export interface UseResizeObserverOptions {
1453
+ /**
1454
+ * External target to observe.
1455
+ *
1456
+ * @defaultValue `undefined` (ref-callback mode - see {@link ResizeObserverTargetInput})
1457
+ */
1458
+ target?: ResizeObserverTargetInput;
1459
+ /**
1460
+ * Which box model to measure. Ignored when the target is a `Window`.
1461
+ *
1462
+ * @defaultValue `"content-box"`
1463
+ */
1464
+ box?: ResizeObserverBox;
1465
+ /**
1466
+ * Pause observing without unmounting - the last measured `width`/`height`
1467
+ * is retained, just no longer updated.
1468
+ *
1469
+ * @defaultValue `true`
1470
+ */
1471
+ enabled?: boolean;
1472
+ /**
1473
+ * Round `width`/`height` to whole pixels before updating state. Useful
1474
+ * because `ResizeObserver` can fire on sub-pixel changes, which is
1475
+ * usually more precision than layout code needs and causes more
1476
+ * re-renders than necessary.
1477
+ *
1478
+ * @defaultValue `false`
1479
+ */
1480
+ round?: boolean;
1481
+ /**
1482
+ * Debounce measurement updates by this many milliseconds. `0` applies
1483
+ * every measurement immediately (still batched by the browser's native
1484
+ * `ResizeObserver` delivery, just not further delayed by this hook).
1485
+ *
1486
+ * @defaultValue `0`
1487
+ */
1488
+ debounceMs?: number;
1489
+ /**
1490
+ * Value returned before the first real measurement resolves. Useful for
1491
+ * avoiding a `{ width: 0, height: 0 }` flash when you already know an
1492
+ * element's rough starting size (e.g. from a CSS `min-height`).
1493
+ *
1494
+ * @defaultValue `{ width: 0, height: 0 }`
1495
+ */
1496
+ initialSize?: ObservedSize;
1497
+ /**
1498
+ * Imperative callback fired on every measurement update, in addition to
1499
+ * (not instead of) the hook's returned `width`/`height` state updating.
1500
+ * Useful for side effects that don't need a re-render, like redrawing a
1501
+ * canvas.
1502
+ *
1503
+ * @param size - The newly measured (and possibly rounded) size.
1504
+ * @param entry - The raw `ResizeObserverEntry`, or `undefined` when the
1505
+ * target is a `Window` (which has no entry, since it's measured via the
1506
+ * native `resize` event rather than `ResizeObserver`).
1507
+ */
1508
+ onResize?: (size: ObservedSize, entry: ResizeObserverEntry | undefined) => void;
1509
+ }
1510
+ /**
1511
+ * Return value of {@link useResizeObserver}.
1512
+ *
1513
+ * @typeParam T - Element type of the ref-callback, for when you want e.g.
1514
+ * `RefCallback<HTMLDivElement>` instead of the default `RefCallback<Element>`.
1515
+ */
1516
+ export interface UseResizeObserverReturn<T extends Element = Element> {
1517
+ /**
1518
+ * Attach to your own JSX element to observe it:
1519
+ * `<div ref={ref}>`. A no-op (never called) when `target` is supplied
1520
+ * instead.
1521
+ */
1522
+ ref: RefCallback<T>;
1523
+ /** Latest measured width. `0` until the first measurement (or `initialSize.width`, if provided). */
1524
+ width: number;
1525
+ /** Latest measured height. `0` until the first measurement (or `initialSize.height`, if provided). */
1526
+ height: number;
1527
+ /**
1528
+ * The raw entry from the most recent measurement, for reading fields
1529
+ * this hook doesn't surface directly (e.g. `borderBoxSize` alongside a
1530
+ * `box: "content-box"` measurement). `undefined` before the first
1531
+ * measurement, and always `undefined` for `Window` targets.
1532
+ */
1533
+ entry: ResizeObserverEntry | undefined;
1534
+ }
1535
+ /**
1536
+ * Tracks an element's (or the window's) rendered size reactively, backed by
1537
+ * the native `ResizeObserver` API.
1538
+ *
1539
+ * @remarks
1540
+ * Supports two ways of choosing what to observe - see
1541
+ * {@link ResizeObserverTargetInput} for the full list of accepted shapes:
1542
+ * - **Ref-callback mode** (default): attach the returned `ref` to your own
1543
+ * JSX element.
1544
+ * - **External target mode**: pass `target` (an element, `RefObject`, or
1545
+ * getter function) to observe something you don't render yourself - for
1546
+ * example, a scroll container obtained via a `getScrollElement()`-style
1547
+ * callback.
1548
+ *
1549
+ * `width`/`height` are `0` (or `initialSize`, if provided) until the first
1550
+ * measurement resolves, which happens asynchronously after mount - so the
1551
+ * very first render on the client, and any render during SSR, will not yet
1552
+ * reflect the element's real size.
1553
+ *
1554
+ * @typeParam T - Element type of the ref-callback, e.g. pass
1555
+ * `useResizeObserver<HTMLDivElement>()` if you want `ref` typed as
1556
+ * `RefCallback<HTMLDivElement>` instead of the default `RefCallback<Element>`.
1557
+ *
1558
+ * @param options - See {@link UseResizeObserverOptions}. All fields optional.
1559
+ * @returns See {@link UseResizeObserverReturn}.
1560
+ *
1561
+ * @example
1562
+ * Ref-callback mode - observe your own element:
1563
+ * ```tsx
1564
+ * function Panel() {
1565
+ * const { ref, width, height } = useResizeObserver<HTMLDivElement>();
1566
+ * return <div ref={ref}>{width} x {height}</div>;
1567
+ * }
1568
+ * ```
1569
+ *
1570
+ * @example
1571
+ * External target mode - observe an element you don't render, e.g. a scroll container:
1572
+ * ```tsx
1573
+ * const scrollRef = useRef<HTMLDivElement>(null);
1574
+ * const { width, height } = useResizeObserver({
1575
+ * target: () => scrollRef.current,
1576
+ * });
1577
+ * ```
1578
+ *
1579
+ * @example
1580
+ * Debounced, rounded, with an imperative side effect:
1581
+ * ```tsx
1582
+ * const { width, height } = useResizeObserver({
1583
+ * round: true,
1584
+ * debounceMs: 100,
1585
+ * onResize: (size) => redrawCanvas(size),
1586
+ * });
1587
+ * ```
1588
+ *
1589
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver | ResizeObserver} on MDN
1590
+ */
1591
+ export declare function useResizeObserver<T extends Element = Element>(options?: UseResizeObserverOptions): UseResizeObserverReturn<T>;
1592
+ /**
1593
+ * How `scrollToIndex`/`scrollToOffset` (and the equivalent
1594
+ * row/column/cell methods on `useVirtualGrid`) position a target item
1595
+ * relative to the viewport.
1596
+ *
1597
+ * @remarks
1598
+ * - `"start"` - align the item's leading edge with the viewport's leading edge.
1599
+ * - `"end"` - align the item's trailing edge with the viewport's trailing edge.
1600
+ * - `"center"` - center the item within the viewport.
1601
+ * - `"auto"` - do nothing if the item is already fully visible; otherwise
1602
+ * scroll the minimum distance needed to bring it fully into view.
1603
+ *
1604
+ * For `reverse` lists, `"start"`/`"end"` are relative to the *logical*
1605
+ * reading direction (which visually flips), not the physical viewport -
1606
+ * `"auto"` always minimizes physical scroll distance regardless of
1607
+ * `reverse`, since "nearest" is a physical-space concept.
1608
+ */
1093
1609
  export type ScrollAlign = "start" | "center" | "end" | "auto";
1610
+ /** Which scroll direction a size, offset, or measurement refers to. */
1094
1611
  export type Axis = "vertical" | "horizontal";
1612
+ /** Options shared by the imperative `scrollTo*` methods across the virtualization hooks. */
1095
1613
  export interface ScrollToOffsetOptions {
1614
+ /**
1615
+ * Use smooth (animated) scrolling instead of an instant jump.
1616
+ *
1617
+ * @defaultValue `false`
1618
+ */
1096
1619
  smooth?: boolean;
1097
1620
  }
1621
+ /** Options for {@link useVirtualGrid}'s `scrollToCell` method. */
1098
1622
  export interface ScrollToCellOptions {
1623
+ /**
1624
+ * How to position the target row within the viewport.
1625
+ *
1626
+ * @defaultValue `"auto"`
1627
+ */
1099
1628
  rowAlign?: ScrollAlign;
1629
+ /**
1630
+ * How to position the target column within the viewport.
1631
+ *
1632
+ * @defaultValue `"auto"`
1633
+ */
1100
1634
  colAlign?: ScrollAlign;
1635
+ /**
1636
+ * Use smooth (animated) scrolling instead of an instant jump.
1637
+ *
1638
+ * @defaultValue `false`
1639
+ */
1101
1640
  smooth?: boolean;
1102
1641
  }
1642
+ /** Options for {@link useVirtualGrid}'s `scrollToRow` method. */
1103
1643
  export interface ScrollToRowOptions {
1644
+ /**
1645
+ * How to position the target row within the viewport.
1646
+ *
1647
+ * @defaultValue `"auto"`
1648
+ */
1104
1649
  align?: ScrollAlign;
1650
+ /**
1651
+ * Use smooth (animated) scrolling instead of an instant jump.
1652
+ *
1653
+ * @defaultValue `false`
1654
+ */
1105
1655
  smooth?: boolean;
1106
1656
  }
1657
+ /** Options for {@link useVirtualGrid}'s `scrollToColumn` method. */
1107
1658
  export interface ScrollToColumnOptions {
1659
+ /**
1660
+ * How to position the target column within the viewport.
1661
+ *
1662
+ * @defaultValue `"auto"`
1663
+ */
1108
1664
  align?: ScrollAlign;
1665
+ /**
1666
+ * Use smooth (animated) scrolling instead of an instant jump.
1667
+ *
1668
+ * @defaultValue `false`
1669
+ */
1109
1670
  smooth?: boolean;
1110
1671
  }
1672
+ /** A single rendered cell, as produced by {@link useVirtualGrid}'s `virtualCells`. */
1111
1673
  export interface VirtualCell {
1112
- key: Key;
1674
+ /**
1675
+ * A stable React key for this cell - derived from `itemKey` if
1676
+ * provided, otherwise `` `${rowIndex}:${colIndex}` ``.
1677
+ */
1678
+ key: string | number;
1679
+ /** This cell's row position in the full (un-virtualized) grid. */
1113
1680
  rowIndex: number;
1681
+ /** This cell's column position in the full (un-virtualized) grid. */
1114
1682
  colIndex: number;
1683
+ /** This cell's row height - the max measured height among its row's currently-tracked cells, if `measureElement` is in use. */
1115
1684
  height: number;
1685
+ /** This cell's column width - the max measured width among its column's currently-tracked cells, if `measureElement` is in use. */
1116
1686
  width: number;
1687
+ /** This cell's top position, relative to the top of the virtualized content (i.e. excluding `scrollMarginTop`). */
1117
1688
  top: number;
1689
+ /** This cell's left position, relative to the left of the virtualized content (i.e. excluding `scrollMarginLeft`). */
1118
1690
  left: number;
1691
+ /** `top + height` - this cell's bottom position, provided for convenience. */
1692
+ bottom: number;
1693
+ /** `left + width` - this cell's right position, provided for convenience. */
1694
+ right: number;
1695
+ }
1696
+ /** The currently-rendered row/column index ranges, as produced by {@link useVirtualGrid}'s `onRangeChange`. */
1697
+ export interface VirtualGridRange {
1698
+ /** Numerically lowest rendered row index (inclusive), overscan included. */
1699
+ rowStartIndex: number;
1700
+ /** Numerically highest rendered row index (inclusive), overscan included. */
1701
+ rowEndIndex: number;
1702
+ /** Numerically lowest rendered column index (inclusive), overscan included. */
1703
+ colStartIndex: number;
1704
+ /** Numerically highest rendered column index (inclusive), overscan included. */
1705
+ colEndIndex: number;
1119
1706
  }
1707
+ /** Customizes what "visible" means for the `pauseWhenOffscreen` option - see {@link UseVirtualGridOptions.pauseWhenOffscreen}. */
1708
+ export interface PauseWhenOffscreenConfig {
1709
+ /**
1710
+ * The element used as the viewport when checking whether the scroll
1711
+ * container is visible.
1712
+ *
1713
+ * @defaultValue `null` (the nearest scrollable ancestor / browser viewport, per `IntersectionObserver`'s native `root` behavior)
1714
+ */
1715
+ root?: Element | Document | null;
1716
+ /**
1717
+ * Margin added around `root`'s bounding box before checking visibility,
1718
+ * in CSS `margin` shorthand syntax.
1719
+ *
1720
+ * @defaultValue `"0px"`
1721
+ */
1722
+ rootMargin?: string;
1723
+ }
1724
+ /** Options for {@link useVirtualGrid}. */
1120
1725
  export interface UseVirtualGridOptions {
1726
+ /** Total number of rows in the full (un-virtualized) grid. */
1121
1727
  rowCount: number;
1728
+ /** Total number of columns in the full (un-virtualized) grid. */
1122
1729
  colCount: number;
1730
+ /**
1731
+ * Each row's height - a constant applied to every row, or a function
1732
+ * called per row index.
1733
+ *
1734
+ * @remarks
1735
+ * When a function is used and `measureElement` isn't attached to your
1736
+ * rendered cells, this is treated as a fixed height (not just an
1737
+ * initial estimate). A function here is memoized internally keyed on
1738
+ * its own reference identity - see the equivalent note on
1739
+ * {@link estimateColumnWidth}, which applies the same way to this field.
1740
+ */
1123
1741
  estimateRowHeight: number | ((rowIndex: number) => number);
1742
+ /**
1743
+ * Each column's width - a constant applied to every column, or a
1744
+ * function called per column index.
1745
+ *
1746
+ * @remarks
1747
+ * When a function is used and `measureElement` isn't attached to your
1748
+ * rendered cells, this is treated as a fixed width (not just an
1749
+ * initial estimate) - attach `measureElement` if you want actual
1750
+ * rendered sizes to refine it over time.
1751
+ *
1752
+ * A function `estimateColumnWidth` (and likewise `estimateRowHeight`)
1753
+ * is memoized internally keyed on its own reference identity - passing
1754
+ * a new inline function every render rebuilds the entire internal size
1755
+ * cache on every render, which defeats the point of caching. Memoize it
1756
+ * if it's not already stable.
1757
+ */
1124
1758
  estimateColumnWidth: number | ((colIndex: number) => number);
1759
+ /**
1760
+ * Returns the scrollable element to track - called fresh on every
1761
+ * render, so it's safe to pass e.g. `() => scrollRef.current` without
1762
+ * memoizing it. Return `window` or `document` to virtualize within the
1763
+ * whole page's own scroll, instead of a dedicated scrollable container.
1764
+ */
1125
1765
  getScrollElement: () => HTMLElement | Window | Document | null;
1766
+ /**
1767
+ * Extra rows rendered beyond each edge of the visible range, to reduce
1768
+ * blank flashes during fast scrolling.
1769
+ *
1770
+ * @defaultValue `3`
1771
+ */
1126
1772
  overscanRows?: number;
1773
+ /**
1774
+ * Extra columns rendered beyond each edge of the visible range.
1775
+ *
1776
+ * @defaultValue `3`
1777
+ */
1127
1778
  overscanCols?: number;
1779
+ /**
1780
+ * Space between rows.
1781
+ *
1782
+ * @defaultValue `0`
1783
+ */
1784
+ rowGap?: number;
1785
+ /**
1786
+ * Space between columns.
1787
+ *
1788
+ * @defaultValue `0`
1789
+ */
1790
+ columnGap?: number;
1791
+ /**
1792
+ * Distance this grid's content starts from the top of a shared scroll
1793
+ * container - e.g. page content above it when using Window/Document
1794
+ * scrolling.
1795
+ *
1796
+ * @defaultValue `0`
1797
+ */
1798
+ scrollMarginTop?: number;
1799
+ /**
1800
+ * Distance this grid's content starts from the left of a shared scroll
1801
+ * container.
1802
+ *
1803
+ * @defaultValue `0`
1804
+ */
1805
+ scrollMarginLeft?: number;
1806
+ /**
1807
+ * RTL horizontal scrolling (affects the column axis). Uses the modern
1808
+ * (negative `scrollLeft`) convention - not cross-browser verified.
1809
+ *
1810
+ * @defaultValue `false`
1811
+ */
1812
+ isRtl?: boolean;
1813
+ /**
1814
+ * Pause scroll/resize tracking without unmounting. Virtual cells freeze
1815
+ * at their last computed state rather than going blank.
1816
+ *
1817
+ * @defaultValue `true`
1818
+ */
1819
+ enabled?: boolean;
1820
+ /**
1821
+ * Also pause scroll/resize tracking whenever the scroll element itself
1822
+ * isn't visible on screen - `true` for defaults, or a
1823
+ * {@link PauseWhenOffscreenConfig} to customize the
1824
+ * `IntersectionObserver` `root`/`rootMargin`. Has no effect when
1825
+ * `getScrollElement` returns `Window`/`Document`, since a whole-page
1826
+ * scroller has no meaningful "offscreen" state of its own.
1827
+ *
1828
+ * @defaultValue `false` (opt-in, since it adds an observer)
1829
+ */
1830
+ pauseWhenOffscreen?: boolean | PauseWhenOffscreenConfig;
1831
+ /**
1832
+ * How long scrolling must stay idle before `isScrolling` flips back to
1833
+ * `false`. `0` (or any non-positive value) resolves `isScrolling` to
1834
+ * `false` immediately, rather than disabling tracking altogether.
1835
+ *
1836
+ * @defaultValue `150`
1837
+ */
1128
1838
  scrollingDelay?: number;
1839
+ /**
1840
+ * Assumed viewport height before the scroll container has been
1841
+ * measured.
1842
+ *
1843
+ * @defaultValue `0`
1844
+ */
1129
1845
  initialViewportHeight?: number;
1846
+ /**
1847
+ * Assumed viewport width before the scroll container has been
1848
+ * measured.
1849
+ *
1850
+ * @defaultValue `0`
1851
+ */
1130
1852
  initialViewportWidth?: number;
1853
+ /** Scroll to this vertical offset on mount, before the first paint. Takes priority over `initialScrollRow` if both are set. */
1131
1854
  initialScrollTop?: number;
1855
+ /** Scroll to this horizontal offset on mount, before the first paint. Takes priority over `initialScrollCol` if both are set. */
1132
1856
  initialScrollLeft?: number;
1857
+ /** Scroll so this row is visible on mount, before the first paint. Ignored if `initialScrollTop` is also set. */
1133
1858
  initialScrollRow?: number;
1859
+ /** Scroll so this column is visible on mount, before the first paint. Ignored if `initialScrollLeft` is also set. */
1134
1860
  initialScrollCol?: number;
1135
- itemKey?: (rowIndex: number, colIndex: number) => Key;
1861
+ /**
1862
+ * How `initialScrollRow` is aligned within the viewport. Only used
1863
+ * together with `initialScrollRow`.
1864
+ *
1865
+ * @defaultValue `"start"`
1866
+ */
1867
+ initialRowAlign?: ScrollAlign;
1868
+ /**
1869
+ * How `initialScrollCol` is aligned within the viewport. Only used
1870
+ * together with `initialScrollCol`.
1871
+ *
1872
+ * @defaultValue `"start"`
1873
+ */
1874
+ initialColAlign?: ScrollAlign;
1875
+ /**
1876
+ * When `measureElement` reports a size for a row/column positioned
1877
+ * before the current viewport, adjust `scrollTop`/`scrollLeft` by the
1878
+ * same delta so already-visible content doesn't visually jump.
1879
+ *
1880
+ * @defaultValue `true`
1881
+ */
1882
+ adjustScrollOnMeasure?: boolean;
1883
+ /**
1884
+ * Derives each rendered cell's React `key`. Falls back to
1885
+ * `` `${rowIndex}:${colIndex}` `` if omitted.
1886
+ */
1887
+ itemKey?: (rowIndex: number, colIndex: number) => string | number;
1888
+ /**
1889
+ * Called whenever the rendered row or column index range actually
1890
+ * changes (not on every render). Useful for analytics, or triggering
1891
+ * data-fetching from outside the hook.
1892
+ */
1893
+ onRangeChange?: (range: VirtualGridRange) => void;
1136
1894
  }
1895
+ /** Return value of {@link useVirtualGrid}. */
1137
1896
  export interface UseVirtualGridReturn {
1897
+ /** The currently-rendered cells (visible rows x visible columns, plus overscan), each with a computed size/position. Render these, not the full `rowCount` x `colCount`. */
1138
1898
  virtualCells: VirtualCell[];
1899
+ /** Total height of all rows plus row gaps - set this as the virtualized container's height so the vertical scrollbar is sized correctly. */
1139
1900
  totalHeight: number;
1901
+ /** Total width of all columns plus column gaps - set this as the virtualized container's width so the horizontal scrollbar is sized correctly. */
1140
1902
  totalWidth: number;
1903
+ /** Whether the grid is currently scrolling, per `scrollingDelay`. Useful for cheaper rendering while actively scrolling. */
1141
1904
  isScrolling: boolean;
1905
+ /** Imperatively scrolls so the given cell is visible on both axes, per the requested {@link ScrollToCellOptions}. Stable across renders. */
1142
1906
  scrollToCell: (rowIndex: number, colIndex: number, options?: ScrollToCellOptions) => void;
1907
+ /** Imperatively scrolls to exact top/left offsets, each clamped into range. Stable across renders. */
1143
1908
  scrollToOffset: (offsets: {
1144
1909
  top: number;
1145
1910
  left: number;
1146
1911
  }, options?: ScrollToOffsetOptions) => void;
1912
+ /** Imperatively scrolls so the given row is visible, leaving the horizontal scroll position untouched. Stable across renders. */
1147
1913
  scrollToRow: (rowIndex: number, options?: ScrollToRowOptions) => void;
1914
+ /** Imperatively scrolls so the given column is visible, leaving the vertical scroll position untouched. Stable across renders. */
1148
1915
  scrollToColumn: (colIndex: number, options?: ScrollToColumnOptions) => void;
1916
+ /**
1917
+ * Attach to your rendered cell's DOM node to enable dynamic measurement:
1918
+ * `<div ref={measureElement} data-row-index={cell.rowIndex} data-col-index={cell.colIndex}>`.
1919
+ * Row height is taken as the max measured height among that row's
1920
+ * currently-tracked cells (and likewise column width); reads indices
1921
+ * from data attributes (rather than taking them as parameters) so this
1922
+ * stays referentially stable and can be passed directly as `ref`.
1923
+ * No-op when both estimateRowHeight and estimateColumnWidth are plain
1924
+ * numbers (nothing to refine).
1925
+ */
1926
+ measureElement: RefCallback<Element>;
1149
1927
  }
1928
+ /**
1929
+ * Renders only the cells currently visible in a scrollable container (plus
1930
+ * a small overscan buffer on each axis), instead of the full
1931
+ * `rowCount` x `colCount` grid - keeps DOM node count roughly constant
1932
+ * regardless of how large the grid is.
1933
+ *
1934
+ * @remarks
1935
+ * Core behavior comes from `rowCount`/`colCount` + `estimateRowHeight`/
1936
+ * `estimateColumnWidth` + `getScrollElement`; everything else in
1937
+ * {@link UseVirtualGridOptions} is opt-in on top of that: `isRtl` for the
1938
+ * column axis's direction, `rowGap`/`columnGap`/`scrollMarginTop`/
1939
+ * `scrollMarginLeft` for layout details, `measureElement` (returned) for
1940
+ * refining both estimate functions with real rendered sizes (a row's
1941
+ * height becomes the max measured height among its currently-tracked
1942
+ * cells, and likewise for column width), `pauseWhenOffscreen`/`enabled`
1943
+ * for pausing tracking when inactive, and `initialScrollRow`/
1944
+ * `initialScrollCol`/`initialScrollTop`/`initialScrollLeft` for where to
1945
+ * start scrolled to. There's no `reverse` layout option here, unlike
1946
+ * {@link useVirtualList} - grids don't support reversed axes.
1947
+ *
1948
+ * `estimateRowHeight`/`estimateColumnWidth`, when functions, should be
1949
+ * memoized (stable across renders) - see the note on
1950
+ * {@link UseVirtualGridOptions.estimateColumnWidth} for why.
1951
+ *
1952
+ * @param options - See {@link UseVirtualGridOptions}.
1953
+ * @returns See {@link UseVirtualGridReturn}.
1954
+ *
1955
+ * @example
1956
+ * Fixed-size grid:
1957
+ * ```tsx
1958
+ * function Grid({ rows, cols }: { rows: number; cols: number }) {
1959
+ * const scrollRef = useRef<HTMLDivElement>(null);
1960
+ * const { virtualCells, totalHeight, totalWidth } = useVirtualGrid({
1961
+ * rowCount: rows,
1962
+ * colCount: cols,
1963
+ * estimateRowHeight: 32,
1964
+ * estimateColumnWidth: 120,
1965
+ * getScrollElement: () => scrollRef.current,
1966
+ * });
1967
+ *
1968
+ * return (
1969
+ * <div ref={scrollRef} style={{ height: 400, overflow: "auto" }}>
1970
+ * <div style={{ height: totalHeight, width: totalWidth, position: "relative" }}>
1971
+ * {virtualCells.map((cell) => (
1972
+ * <div
1973
+ * key={cell.key}
1974
+ * style={{ position: "absolute", top: cell.top, left: cell.left, height: cell.height, width: cell.width }}
1975
+ * >
1976
+ * {cell.rowIndex},{cell.colIndex}
1977
+ * </div>
1978
+ * ))}
1979
+ * </div>
1980
+ * </div>
1981
+ * );
1982
+ * }
1983
+ * ```
1984
+ *
1985
+ * @example
1986
+ * Variable-size cells, refined by real measurements:
1987
+ * ```tsx
1988
+ * const { virtualCells, measureElement } = useVirtualGrid({
1989
+ * rowCount: rows,
1990
+ * colCount: cols,
1991
+ * estimateRowHeight: () => 32, // rough guess
1992
+ * estimateColumnWidth: () => 120,
1993
+ * getScrollElement: () => scrollRef.current,
1994
+ * });
1995
+ * // in the cell: <div ref={measureElement} data-row-index={cell.rowIndex} data-col-index={cell.colIndex}>...
1996
+ * ```
1997
+ */
1150
1998
  export declare function useVirtualGrid(options: UseVirtualGridOptions): UseVirtualGridReturn;
1999
+ /** Options for {@link useVirtualList}'s `scrollToIndex` method. */
1151
2000
  export interface ScrollToIndexOptions {
2001
+ /**
2002
+ * How to position the target item relative to the viewport.
2003
+ *
2004
+ * @defaultValue `"auto"`
2005
+ */
1152
2006
  align?: ScrollAlign;
2007
+ /**
2008
+ * Use smooth (animated) scrolling instead of an instant jump.
2009
+ *
2010
+ * @defaultValue `false`
2011
+ */
1153
2012
  smooth?: boolean;
1154
2013
  }
2014
+ /** A single rendered item, as produced by {@link useVirtualList}'s `virtualItems`. */
1155
2015
  export interface VirtualItem {
1156
- key: Key;
2016
+ /**
2017
+ * A stable React key for this item - derived from `itemKey` if
2018
+ * provided, otherwise falls back to `index`.
2019
+ */
2020
+ key: string | number;
2021
+ /** This item's position in the full (un-virtualized) list. */
1157
2022
  index: number;
2023
+ /** This item's size along the scrolling axis (height for vertical lists, width for horizontal). */
1158
2024
  size: number;
2025
+ /**
2026
+ * This item's start position along the scrolling axis, relative to the
2027
+ * top/left of the virtualized content (i.e. excluding `scrollMargin`) -
2028
+ * typically consumed as a `transform: translateY(start)` (or
2029
+ * `translateX` for horizontal lists).
2030
+ */
1159
2031
  start: number;
2032
+ /** `start + size` - this item's end position, provided for convenience. */
2033
+ end: number;
1160
2034
  }
2035
+ /** The currently-rendered index range, as produced by {@link useVirtualList}'s `onRangeChange`. */
2036
+ export interface VirtualRange {
2037
+ /** Numerically lowest rendered index (inclusive), overscan included. */
2038
+ startIndex: number;
2039
+ /** Numerically highest rendered index (inclusive), overscan included. */
2040
+ endIndex: number;
2041
+ }
2042
+ interface PauseWhenOffscreenConfig$1 {
2043
+ /**
2044
+ * The element used as the viewport when checking whether the scroll
2045
+ * container is visible.
2046
+ *
2047
+ * @defaultValue `null` (the nearest scrollable ancestor / browser viewport, per `IntersectionObserver`'s native `root` behavior)
2048
+ */
2049
+ root?: Element | Document | null;
2050
+ /**
2051
+ * Margin added around `root`'s bounding box before checking visibility,
2052
+ * in CSS `margin` shorthand syntax - e.g. `"200px"` to keep tracking
2053
+ * active slightly before the list is actually on screen.
2054
+ *
2055
+ * @defaultValue `"0px"`
2056
+ */
2057
+ rootMargin?: string;
2058
+ }
2059
+ /** Options for {@link useVirtualList}. */
1161
2060
  export interface UseVirtualListOptions<T = unknown> {
2061
+ /** Total number of items in the full (un-virtualized) list. */
1162
2062
  count: number;
2063
+ /**
2064
+ * Each item's size along the scrolling axis - a constant applied to
2065
+ * every item, or a function called per-index.
2066
+ *
2067
+ * @remarks
2068
+ * When a function is used and `measureElement` isn't attached to your
2069
+ * rendered items, this is treated as a fixed size (not just an initial
2070
+ * estimate) - attach `measureElement` if you want actual rendered sizes
2071
+ * to refine it over time.
2072
+ *
2073
+ * A function `estimateSize` is memoized internally keyed on its own
2074
+ * reference identity - passing a new inline function every render (e.g.
2075
+ * `estimateSize={(i) => 50}` written directly in JSX/hook options,
2076
+ * rather than a `useCallback`-wrapped or module-level function) rebuilds
2077
+ * the entire internal size cache on every render, which defeats the
2078
+ * point of caching. Memoize it if it's not already stable.
2079
+ */
1163
2080
  estimateSize: number | ((index: number) => number);
2081
+ /**
2082
+ * Returns the scrollable element to track - called fresh on every
2083
+ * render, so it's safe to pass e.g. `() => scrollRef.current` without
2084
+ * memoizing it. Return `window` or `document` to virtualize within the
2085
+ * whole page's own scroll, instead of a dedicated scrollable container.
2086
+ */
1164
2087
  getScrollElement: () => HTMLElement | Window | Document | null;
2088
+ /**
2089
+ * Extra items rendered beyond each edge of the visible range, to reduce
2090
+ * blank flashes during fast scrolling and give browsers a head start on
2091
+ * things like image decoding.
2092
+ *
2093
+ * @defaultValue `3`
2094
+ */
1165
2095
  overscan?: number;
2096
+ /**
2097
+ * Scroll and measure along the horizontal axis (`scrollLeft`/width)
2098
+ * instead of the default vertical axis (`scrollTop`/height).
2099
+ *
2100
+ * @defaultValue `false`
2101
+ */
1166
2102
  horizontal?: boolean;
2103
+ /**
2104
+ * Render items in reverse physical order - index `0` at the visual
2105
+ * bottom/trailing end, `count - 1` at the visual top/leading end (the
2106
+ * indices themselves don't change, only where each one is positioned).
2107
+ * Suited to chat-style UIs. See {@link ScrollAlign} for how this
2108
+ * interacts with alignment.
2109
+ *
2110
+ * @defaultValue `false`
2111
+ */
1167
2112
  reverse?: boolean;
2113
+ /**
2114
+ * RTL horizontal scrolling. Only meaningful when `horizontal` is `true`.
2115
+ * Uses the modern (negative `scrollLeft`) convention - not
2116
+ * cross-browser verified.
2117
+ *
2118
+ * @defaultValue `false`
2119
+ */
2120
+ isRtl?: boolean;
2121
+ /**
2122
+ * Space between consecutive items along the scrolling axis. Not added
2123
+ * after the last item.
2124
+ *
2125
+ * @defaultValue `0`
2126
+ */
2127
+ gap?: number;
2128
+ /**
2129
+ * Distance this list's content starts from the top (or left, if
2130
+ * `horizontal`) of a shared scroll container - e.g. page content above
2131
+ * it when using Window/Document scrolling.
2132
+ *
2133
+ * @defaultValue `0`
2134
+ */
2135
+ scrollMargin?: number;
2136
+ /**
2137
+ * Pause scroll/resize tracking without unmounting. Virtual items freeze
2138
+ * at their last computed state rather than going blank.
2139
+ *
2140
+ * @defaultValue `true`
2141
+ */
2142
+ enabled?: boolean;
2143
+ /**
2144
+ * Also pause scroll/resize tracking whenever the scroll element itself
2145
+ * isn't visible on screen (e.g. a hidden tab panel, or far down a long
2146
+ * page) - `true` for defaults, or a {@link PauseWhenOffscreenConfig} to
2147
+ * customize the `IntersectionObserver` `root`/`rootMargin` used to
2148
+ * decide "visible". Has no effect when `getScrollElement` returns
2149
+ * `Window`/`Document`, since a whole-page scroller has no meaningful
2150
+ * "offscreen" state of its own.
2151
+ *
2152
+ * @defaultValue `false` (opt-in, since it adds an observer)
2153
+ */
2154
+ pauseWhenOffscreen?: boolean | PauseWhenOffscreenConfig$1;
2155
+ /**
2156
+ * How long scrolling must stay idle before `isScrolling` flips back to
2157
+ * `false`. `0` (or any non-positive value) resolves `isScrolling` to
2158
+ * `false` immediately on the next scroll-idle check, rather than
2159
+ * disabling `isScrolling` tracking altogether.
2160
+ *
2161
+ * @defaultValue `150`
2162
+ */
1168
2163
  scrollingDelay?: number;
2164
+ /**
2165
+ * Assumed viewport size before the scroll container has been measured
2166
+ * (e.g. during SSR, or the first client render before layout runs).
2167
+ * Also used as a fallback if a live measurement ever comes back `0`.
2168
+ *
2169
+ * @defaultValue `0`
2170
+ */
1169
2171
  initialViewportSize?: number;
2172
+ /**
2173
+ * Scroll to this offset on mount, before the first paint. Takes
2174
+ * priority over `initialScrollIndex` if both are set.
2175
+ */
1170
2176
  initialOffset?: number;
2177
+ /** Scroll so this index is visible on mount, before the first paint. Ignored if `initialOffset` is also set. */
1171
2178
  initialScrollIndex?: number;
2179
+ /**
2180
+ * How `initialScrollIndex` is aligned within the viewport. Only used
2181
+ * together with `initialScrollIndex`.
2182
+ *
2183
+ * @defaultValue `"start"`
2184
+ */
2185
+ initialScrollAlign?: ScrollAlign;
2186
+ /**
2187
+ * When `measureElement` reports a size for an item positioned before
2188
+ * the current viewport, adjust `scrollOffset` by the same delta so
2189
+ * already-visible content doesn't visually jump.
2190
+ *
2191
+ * @defaultValue `true`
2192
+ */
2193
+ adjustScrollOnMeasure?: boolean;
2194
+ /** Backing data array, used together with a string/string-array `itemKey` to derive each item's key. Not required when `itemKey` is a function, or when omitting `itemKey` entirely (falls back to `index` as the key). */
1172
2195
  data?: T[];
1173
- itemKey?: string | string[] | ((index: number, item?: T) => Key);
2196
+ /**
2197
+ * How to derive each rendered item's React `key`.
2198
+ *
2199
+ * @remarks
2200
+ * Accepts three shapes:
2201
+ * - a **function** `(index, item?) => key` - called with the index and
2202
+ * (if `data` is provided) that index's item; return value used
2203
+ * directly.
2204
+ * - a **string** - a property path into `data[index]`, dot-separated
2205
+ * for nested access (e.g. `"name.firstName"` reads `data[index].name.firstName`).
2206
+ * - a **string array** - the same path, pre-split into segments (e.g.
2207
+ * `["name", "firstName"]`), useful when a real key name itself
2208
+ * contains a literal dot.
2209
+ *
2210
+ * Falls back to `index` if `data` is missing, the resolved value isn't
2211
+ * a `string`/`number`, or `itemKey` is omitted entirely. Using a stable
2212
+ * value derived from your data (rather than the default `index`) is
2213
+ * recommended whenever items can be inserted, removed, or reordered.
2214
+ */
2215
+ itemKey?: string | string[] | ((index: number, item?: T) => string | number);
2216
+ /**
2217
+ * Called whenever the rendered index range actually changes (not on
2218
+ * every render). Useful for analytics, or triggering data-fetching from
2219
+ * outside the hook.
2220
+ */
2221
+ onRangeChange?: (range: VirtualRange) => void;
1174
2222
  }
2223
+ /** Return value of {@link useVirtualList}. */
1175
2224
  export interface UseVirtualListReturn {
2225
+ /** The currently-rendered items (visible range plus overscan), each with a computed `size`/`start`/`end`. Render these, not the full `count`. */
1176
2226
  virtualItems: VirtualItem[];
2227
+ /** Total size of all `count` items plus gaps, along the scrolling axis - set this as the virtualized container's height (or width, if `horizontal`) so the scrollbar is sized correctly. */
1177
2228
  totalSize: number;
2229
+ /** Whether the list is currently scrolling, per `scrollingDelay`. Useful for cheaper rendering (e.g. skipping expensive item content) while actively scrolling. */
1178
2230
  isScrolling: boolean;
2231
+ /** Imperatively scrolls so the given index is visible, per the requested {@link ScrollToIndexOptions.align}. Stable across renders - safe to put in a dependency array. */
1179
2232
  scrollToIndex: (index: number, options?: ScrollToIndexOptions) => void;
2233
+ /** Imperatively scrolls to an exact offset, clamped into range. Stable across renders. */
1180
2234
  scrollToOffset: (offset: number, options?: ScrollToOffsetOptions) => void;
2235
+ /**
2236
+ * Attach to your rendered item's DOM node to enable dynamic measurement:
2237
+ * `<div ref={measureElement} data-index={item.index}>`. Reads the index
2238
+ * from a data-index attribute (rather than taking it as a parameter) so
2239
+ * this stays referentially stable and can be passed directly as `ref`
2240
+ * without an inline wrapper causing detach/reattach on every render.
2241
+ * No-op when estimateSize is a plain number (nothing to refine).
2242
+ */
2243
+ measureElement: RefCallback<Element>;
1181
2244
  }
2245
+ /**
2246
+ * Renders only the items currently visible in a scrollable container (plus
2247
+ * a small overscan buffer), instead of the full list - keeps DOM node count
2248
+ * roughly constant regardless of how many items there are in total.
2249
+ *
2250
+ * @remarks
2251
+ * Core behavior comes from `count` + `estimateSize` + `getScrollElement`;
2252
+ * everything else in {@link UseVirtualListOptions} is opt-in on top of that:
2253
+ * `horizontal`/`isRtl` for axis and direction, `reverse` for chat-style
2254
+ * bottom-anchored layouts, `gap`/`scrollMargin` for layout details,
2255
+ * `measureElement` (returned) for refining `estimateSize` with real
2256
+ * rendered sizes, `pauseWhenOffscreen`/`enabled` for pausing tracking when
2257
+ * inactive, and `initialOffset`/`initialScrollIndex` for where to start
2258
+ * scrolled to.
2259
+ *
2260
+ * `estimateSize` as a function should be memoized (stable across renders)
2261
+ * - see the note on {@link UseVirtualListOptions.estimateSize} for why.
2262
+ *
2263
+ * @typeParam T - Type of each item in `data`, when using `data` + a
2264
+ * string/string-array `itemKey` to derive keys from your own data shape.
2265
+ *
2266
+ * @param options - See {@link UseVirtualListOptions}.
2267
+ * @returns See {@link UseVirtualListReturn}.
2268
+ *
2269
+ * @example
2270
+ * Fixed-size list:
2271
+ * ```tsx
2272
+ * function List({ items }: { items: string[] }) {
2273
+ * const scrollRef = useRef<HTMLDivElement>(null);
2274
+ * const { virtualItems, totalSize } = useVirtualList({
2275
+ * count: items.length,
2276
+ * estimateSize: 40,
2277
+ * getScrollElement: () => scrollRef.current,
2278
+ * });
2279
+ *
2280
+ * return (
2281
+ * <div ref={scrollRef} style={{ height: 400, overflow: "auto" }}>
2282
+ * <div style={{ height: totalSize, position: "relative" }}>
2283
+ * {virtualItems.map((item) => (
2284
+ * <div
2285
+ * key={item.key}
2286
+ * style={{ position: "absolute", top: item.start, height: item.size }}
2287
+ * >
2288
+ * {items[item.index]}
2289
+ * </div>
2290
+ * ))}
2291
+ * </div>
2292
+ * </div>
2293
+ * );
2294
+ * }
2295
+ * ```
2296
+ *
2297
+ * @example
2298
+ * Variable-size items, refined by real measurements:
2299
+ * ```tsx
2300
+ * const { virtualItems, totalSize, measureElement } = useVirtualList({
2301
+ * count: items.length,
2302
+ * estimateSize: (index) => estimateFor(items[index]), // rough guess
2303
+ * getScrollElement: () => scrollRef.current,
2304
+ * });
2305
+ * // in the row: <div ref={measureElement} data-index={item.index}>...
2306
+ * ```
2307
+ */
1182
2308
  export declare function useVirtualList<T = unknown>(options: UseVirtualListOptions<T>): UseVirtualListReturn;
1183
2309
 
1184
2310
  export {};