@pdanpdan/virtual-scroll 0.3.0 → 0.5.0

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/src/types.ts ADDED
@@ -0,0 +1,816 @@
1
+ /**
2
+ * The direction of the virtual scroll.
3
+ * - 'vertical': Single-column vertical scrolling.
4
+ * - 'horizontal': Single-row horizontal scrolling.
5
+ * - 'both': Bidirectional grid-based scrolling.
6
+ */
7
+ export type ScrollDirection = 'vertical' | 'horizontal' | 'both';
8
+
9
+ /**
10
+ * Alignment of an item within the viewport after a scroll operation.
11
+ * - 'start': Aligns item to the top or left edge.
12
+ * - 'center': Aligns item to the center of the viewport.
13
+ * - 'end': Aligns item to the bottom or right edge.
14
+ * - 'auto': Smart alignment. If visible, stays. If not, aligns to nearest edge.
15
+ */
16
+ export type ScrollAlignment = 'start' | 'center' | 'end' | 'auto';
17
+
18
+ /** Options for scroll alignment in a single axis or both axes. */
19
+ export interface ScrollAlignmentOptions {
20
+ /** Alignment on the X (horizontal) axis. */
21
+ x?: ScrollAlignment;
22
+ /** Alignment on the Y (vertical) axis. */
23
+ y?: ScrollAlignment;
24
+ }
25
+
26
+ /** Options for the `scrollToIndex` method. */
27
+ export interface ScrollToIndexOptions {
28
+ /**
29
+ * Where to align the item in the viewport.
30
+ * Can be a single value for both axes or an object for individual control.
31
+ * @default 'auto'
32
+ */
33
+ align?: ScrollAlignment | ScrollAlignmentOptions;
34
+
35
+ /**
36
+ * Scroll behavior.
37
+ * - 'auto': Instant jump.
38
+ * - 'smooth': Animated transition.
39
+ * @default 'smooth'
40
+ */
41
+ behavior?: 'auto' | 'smooth';
42
+
43
+ /**
44
+ * Internal flag for recursive correction calls.
45
+ * Users should generally not set this.
46
+ * @internal
47
+ */
48
+ isCorrection?: boolean;
49
+ }
50
+
51
+ /** Represents an item currently rendered in the virtual scroll area. */
52
+ export interface RenderedItem<T = unknown> {
53
+ /** The original data item from the provided source array. */
54
+ item: T;
55
+ /** The 0-based index of the item in the original array. */
56
+ index: number;
57
+ /** The calculated pixel offset relative to the items wrapper in display pixels (DU). */
58
+ offset: {
59
+ /** Horizontal offset (left) in DU. */
60
+ x: number;
61
+ /** Vertical offset (top) in DU. */
62
+ y: number;
63
+ };
64
+ /** The current measured or estimated size of the item in virtual units (VU). */
65
+ size: {
66
+ /** Pixel width in VU. */
67
+ width: number;
68
+ /** Pixel height in VU. */
69
+ height: number;
70
+ };
71
+ /** The original horizontal pixel offset before any sticky adjustments in VU. */
72
+ originalX: number;
73
+ /** The original vertical pixel offset before any sticky adjustments in VU. */
74
+ originalY: number;
75
+ /** Whether this item is configured to be sticky via the `stickyIndices` property. */
76
+ isSticky?: boolean;
77
+ /** Whether this item is currently in a stuck state at the viewport edge. */
78
+ isStickyActive?: boolean;
79
+ /** The relative translation applied to the item for the sticky pushing effect in DU. */
80
+ stickyOffset: {
81
+ /** Horizontal translation in DU. */
82
+ x: number;
83
+ /** Vertical translation in DU. */
84
+ y: number;
85
+ };
86
+ }
87
+
88
+ /** Information about the currently visible range of columns and their paddings. */
89
+ export interface ColumnRange {
90
+ /** Inclusive start index. */
91
+ start: number;
92
+ /** Exclusive end index. */
93
+ end: number;
94
+ /** Pixel padding to maintain at the start of the row in VU. */
95
+ padStart: number;
96
+ /** Pixel padding to maintain at the end of the row in VU. */
97
+ padEnd: number;
98
+ }
99
+
100
+ /** Comprehensive state of the virtual scroll system. */
101
+ export interface ScrollDetails<T = unknown> {
102
+ /** List of items currently rendered in the DOM buffer. */
103
+ items: RenderedItem<T>[];
104
+ /** Index of the first item visible below any sticky header in the viewport. */
105
+ currentIndex: number;
106
+ /** Index of the first column visible after any sticky column in the viewport (grid mode). */
107
+ currentColIndex: number;
108
+ /** Index of the last item visible above any sticky footer in the viewport. */
109
+ currentEndIndex: number;
110
+ /** Index of the last column visible before any sticky end column in the viewport (grid mode). */
111
+ currentEndColIndex: number;
112
+ /** Current relative pixel scroll position from the content start in VU. */
113
+ scrollOffset: {
114
+ /** Horizontal position (X) in VU. */
115
+ x: number;
116
+ /** Vertical position (Y) in VU. */
117
+ y: number;
118
+ };
119
+ /** Current display pixel scroll position (before scaling) in DU. */
120
+ displayScrollOffset: {
121
+ /** Horizontal position (X) in DU. */
122
+ x: number;
123
+ /** Vertical position (Y) in DU. */
124
+ y: number;
125
+ };
126
+ /** Current dimensions of the visible viewport area in VU. */
127
+ viewportSize: {
128
+ /** Pixel width in VU. */
129
+ width: number;
130
+ /** Pixel height in VU. */
131
+ height: number;
132
+ };
133
+ /** Current dimensions of the visible viewport area in display pixels (DU). */
134
+ displayViewportSize: {
135
+ /** Pixel width in DU. */
136
+ width: number;
137
+ /** Pixel height in DU. */
138
+ height: number;
139
+ };
140
+ /** Total calculated or estimated size of all items and gaps in VU. */
141
+ totalSize: {
142
+ /** Total pixel width in VU. */
143
+ width: number;
144
+ /** Total pixel height in VU. */
145
+ height: number;
146
+ };
147
+ /** Whether the container is currently being scrolled by the user or an animation. */
148
+ isScrolling: boolean;
149
+ /** Whether the current scroll operation was initiated programmatically. */
150
+ isProgrammaticScroll: boolean;
151
+ /** The range of item indices currently being rendered. */
152
+ range: {
153
+ /** Inclusive start index. */
154
+ start: number;
155
+ /** Exclusive end index. */
156
+ end: number;
157
+ };
158
+ /** The range of column indices and associated paddings currently being rendered. */
159
+ columnRange: ColumnRange;
160
+ }
161
+
162
+ /** Configuration properties for the `useVirtualScroll` composable. */
163
+ export interface VirtualScrollProps<T = unknown> {
164
+ /**
165
+ * Array of data items to virtualize.
166
+ */
167
+ items: T[];
168
+
169
+ /**
170
+ * Fixed size of each item in virtual units (VU) or a function that returns the size of an item.
171
+ * Pass `0`, `null` or `undefined` for automatic dynamic size detection via `ResizeObserver`.
172
+ */
173
+ itemSize?: number | ((item: T, index: number) => number) | undefined;
174
+
175
+ /**
176
+ * Direction of the virtual scroll.
177
+ * @default 'vertical'
178
+ */
179
+ direction?: ScrollDirection | undefined;
180
+
181
+ /**
182
+ * Number of items to render before the visible viewport.
183
+ * @default 5
184
+ */
185
+ bufferBefore?: number | undefined;
186
+
187
+ /**
188
+ * Number of items to render after the visible viewport.
189
+ * @default 5
190
+ */
191
+ bufferAfter?: number | undefined;
192
+
193
+ /**
194
+ * The scrollable element or window object.
195
+ * If not provided, virtualization usually happens relative to the `hostRef`.
196
+ */
197
+ container?: HTMLElement | Window | null | undefined;
198
+
199
+ /**
200
+ * The host element that directly wraps the absolute-positioned items.
201
+ * Used for calculating relative offsets in display pixels (DU).
202
+ */
203
+ hostElement?: HTMLElement | null | undefined;
204
+
205
+ /**
206
+ * The root element of the VirtualScroll component.
207
+ * Used for calculating relative offsets in display pixels (DU).
208
+ */
209
+ hostRef?: HTMLElement | null | undefined;
210
+
211
+ /**
212
+ * Configuration for Server-Side Rendering.
213
+ * Defines which items are rendered statically on the server.
214
+ */
215
+ ssrRange?: {
216
+ /** First row index. */
217
+ start: number;
218
+ /** Exclusive last row index. */
219
+ end: number;
220
+ /** First column index (grid mode). */
221
+ colStart?: number;
222
+ /** Exclusive last column index (grid mode). */
223
+ colEnd?: number;
224
+ } | undefined;
225
+
226
+ /**
227
+ * Number of columns for bidirectional grid scrolling.
228
+ */
229
+ columnCount?: number | undefined;
230
+
231
+ /**
232
+ * Fixed width of columns in VU, an array of widths, or a function returning widths.
233
+ * Pass `0`, `null` or `undefined` for dynamic column detection.
234
+ */
235
+ columnWidth?: number | number[] | ((index: number) => number) | undefined;
236
+
237
+ /**
238
+ * Pixel padding at the start of the scroll container in display pixels (DU).
239
+ */
240
+ scrollPaddingStart?: number | { x?: number; y?: number; } | undefined;
241
+
242
+ /**
243
+ * Pixel padding at the end of the scroll container in DU.
244
+ */
245
+ scrollPaddingEnd?: number | { x?: number; y?: number; } | undefined;
246
+
247
+ /**
248
+ * Size of sticky elements at the start of the viewport (top or left) in DU.
249
+ * Used to adjust the visible range and item positioning without increasing content size.
250
+ */
251
+ stickyStart?: number | { x?: number; y?: number; } | undefined;
252
+
253
+ /**
254
+ * Size of sticky elements at the end of the viewport (bottom or right) in DU.
255
+ * Used to adjust the visible range without increasing content size.
256
+ */
257
+ stickyEnd?: number | { x?: number; y?: number; } | undefined;
258
+
259
+ /**
260
+ * Gap between items in virtual units (VU).
261
+ * Applied vertically in list/grid mode, horizontally in horizontal list mode.
262
+ */
263
+ gap?: number | undefined;
264
+
265
+ /**
266
+ * Gap between columns in VU.
267
+ * Applied in horizontal and bidirectional grid modes.
268
+ */
269
+ columnGap?: number | undefined;
270
+
271
+ /**
272
+ * List of indices that should stick to the viewport edge.
273
+ */
274
+ stickyIndices?: number[] | undefined;
275
+
276
+ /**
277
+ * Extra padding (display pixels - DU) at the start of the flow (e.g. non-sticky header).
278
+ */
279
+ flowPaddingStart?: number | { x?: number; y?: number; } | undefined;
280
+
281
+ /**
282
+ * Extra padding (DU) at the end of the flow (e.g. non-sticky footer).
283
+ */
284
+ flowPaddingEnd?: number | { x?: number; y?: number; } | undefined;
285
+
286
+ /**
287
+ * Threshold distance from the end in display pixels (DU) to emit the 'load' event.
288
+ * @default 200
289
+ */
290
+ loadDistance?: number | undefined;
291
+
292
+ /**
293
+ * Whether data is currently loading.
294
+ */
295
+ loading?: boolean | undefined;
296
+
297
+ /**
298
+ * Whether to automatically restore and maintain scroll position when items are prepended to the array.
299
+ */
300
+ restoreScrollOnPrepend?: boolean | undefined;
301
+
302
+ /**
303
+ * Initial row index to jump to on mount.
304
+ */
305
+ initialScrollIndex?: number | undefined;
306
+
307
+ /**
308
+ * Initial scroll alignment logic.
309
+ * @default 'start'
310
+ */
311
+ initialScrollAlign?: ScrollAlignment | ScrollAlignmentOptions | undefined;
312
+
313
+ /**
314
+ * Default fallback size for items before they are measured in VU.
315
+ */
316
+ defaultItemSize?: number | undefined;
317
+
318
+ /**
319
+ * Default fallback width for columns before they are measured in VU.
320
+ */
321
+ defaultColumnWidth?: number | undefined;
322
+
323
+ /**
324
+ * Enable debug visualization of buffers and indices.
325
+ */
326
+ debug?: boolean | undefined;
327
+ }
328
+
329
+ /** Help provide axis specific information to the scrollbar. */
330
+ export type ScrollAxis = 'vertical' | 'horizontal';
331
+
332
+ /** Properties for the `VirtualScrollbar` component. */
333
+ export interface VirtualScrollbarProps {
334
+ /**
335
+ * The axis for this scrollbar.
336
+ * - 'vertical': Vertical scrollbar.
337
+ * - 'horizontal': Horizontal scrollbar.
338
+ * @default 'vertical'
339
+ */
340
+ axis?: ScrollAxis;
341
+
342
+ /**
343
+ * Total size of the scrollable content in pixels.
344
+ */
345
+ totalSize: number;
346
+
347
+ /**
348
+ * Current scroll position in pixels.
349
+ */
350
+ position: number;
351
+
352
+ /**
353
+ * Viewport size in pixels.
354
+ */
355
+ viewportSize: number;
356
+
357
+ /**
358
+ * Function to scroll to a specific pixel offset on this axis.
359
+ * @param offset - The pixel offset to scroll to.
360
+ */
361
+ scrollToOffset?: (offset: number) => void;
362
+
363
+ /**
364
+ * The ID of the container element this scrollbar controls.
365
+ */
366
+ containerId?: string;
367
+
368
+ /**
369
+ * Whether the scrollbar is in Right-to-Left (RTL) mode.
370
+ * @default false
371
+ */
372
+ isRtl?: boolean;
373
+ }
374
+
375
+ /** Properties passed to the 'scrollbar' scoped slot. */
376
+ export interface ScrollbarSlotProps {
377
+ /** Current scroll position as a percentage (0 to 1). */
378
+ positionPercent: number;
379
+ /** Viewport size as a percentage of total size (0 to 1). */
380
+ viewportPercent: number;
381
+ /** Calculated thumb size as a percentage of the track size (0 to 100). */
382
+ thumbSizePercent: number;
383
+ /** Calculated thumb position as a percentage of the track size (0 to 100). */
384
+ thumbPositionPercent: number;
385
+
386
+ /**
387
+ * Attributes and event listeners to be bound to the scrollbar track element.
388
+ * Use `v-bind="trackProps"` on your track element.
389
+ */
390
+ trackProps: Record<string, unknown>;
391
+
392
+ /**
393
+ * Attributes and event listeners to be bound to the scrollbar thumb element.
394
+ * Use `v-bind="thumbProps"` on your thumb element.
395
+ */
396
+ thumbProps: Record<string, unknown>;
397
+
398
+ /**
399
+ * Grouped props for the `VirtualScrollbar` component.
400
+ * Useful for passing directly to `<VirtualScrollbar v-bind="scrollbarProps" />`.
401
+ */
402
+ scrollbarProps: VirtualScrollbarProps;
403
+
404
+ /** Whether the thumb is currently being dragged. */
405
+ isDragging: boolean;
406
+ }
407
+
408
+ /** Properties passed to the 'item' scoped slot. */
409
+ export interface ItemSlotProps<T = unknown> {
410
+ /** The original data item being rendered. */
411
+ item: T;
412
+ /** The 0-based index of the item. */
413
+ index: number;
414
+ /** Information about the currently visible range of columns. */
415
+ columnRange: {
416
+ /** First rendered column. */
417
+ start: number;
418
+ /** Last rendered column (exclusive). */
419
+ end: number;
420
+ /** Pixel space before first column. */
421
+ padStart: number;
422
+ /** Pixel space after last column. */
423
+ padEnd: number;
424
+ };
425
+ /** Helper to get the current calculated width of any column index. */
426
+ getColumnWidth: (index: number) => number;
427
+ /** Vertical gap between items. */
428
+ gap: number;
429
+ /** Horizontal gap between columns. */
430
+ columnGap: number;
431
+ /** Whether this item index is configured as sticky. */
432
+ isSticky?: boolean | undefined;
433
+ /** Whether this item is currently in a sticky state at the edge. */
434
+ isStickyActive?: boolean | undefined;
435
+ }
436
+
437
+ /** Configuration properties for the `VirtualScroll` component. */
438
+ export interface VirtualScrollComponentProps<T = unknown> {
439
+ /** Array of items to be virtualized. */
440
+ items: T[];
441
+ /** Fixed size of each item (in pixels) or a function that returns the size of an item. */
442
+ itemSize?: number | ((item: T, index: number) => number) | null;
443
+ /** Direction of the scroll. */
444
+ direction?: ScrollDirection;
445
+ /** Number of items to render before the visible viewport. */
446
+ bufferBefore?: number;
447
+ /** Number of items to render after the visible viewport. */
448
+ bufferAfter?: number;
449
+ /** The scrollable container element or window. */
450
+ container?: HTMLElement | Window | null;
451
+ /** Range of items to render during Server-Side Rendering. */
452
+ ssrRange?: {
453
+ /** First row index to render. */
454
+ start: number;
455
+ /** Last row index to render (exclusive). */
456
+ end: number;
457
+ /** First column index to render (for grid mode). */
458
+ colStart?: number;
459
+ /** Last column index to render (exclusive, for grid mode). */
460
+ colEnd?: number;
461
+ };
462
+ /** Number of columns for bidirectional (grid) scroll. */
463
+ columnCount?: number;
464
+ /** Fixed width of columns (in pixels), an array of widths, or a function for column widths. */
465
+ columnWidth?: number | number[] | ((index: number) => number) | null;
466
+ /** The HTML tag to use for the root container. */
467
+ containerTag?: string;
468
+ /** The HTML tag to use for the items wrapper. */
469
+ wrapperTag?: string;
470
+ /** The HTML tag to use for each item. */
471
+ itemTag?: string;
472
+ /** Additional padding at the start of the scroll container (top or left). */
473
+ scrollPaddingStart?: number | { x?: number; y?: number; };
474
+ /** Additional padding at the end of the scroll container (bottom or right). */
475
+ scrollPaddingEnd?: number | { x?: number; y?: number; };
476
+ /** Whether the content in the 'header' slot is sticky. */
477
+ stickyHeader?: boolean;
478
+ /** Whether the content in the 'footer' slot is sticky. */
479
+ stickyFooter?: boolean;
480
+ /** Gap between items in pixels. */
481
+ gap?: number;
482
+ /** Gap between columns in pixels. */
483
+ columnGap?: number;
484
+ /** Indices of items that should stick to the top/start of the viewport. */
485
+ stickyIndices?: number[];
486
+ /** Distance from the end of the scrollable area (in pixels) to trigger the 'load' event. */
487
+ loadDistance?: number;
488
+ /** Whether items are currently being loaded. */
489
+ loading?: boolean;
490
+ /** Whether to automatically restore and maintain scroll position when items are prepended to the list. */
491
+ restoreScrollOnPrepend?: boolean;
492
+ /** Initial scroll index to jump to immediately after mount. */
493
+ initialScrollIndex?: number;
494
+ /** Alignment for the initial scroll index. */
495
+ initialScrollAlign?: ScrollAlignment | ScrollAlignmentOptions;
496
+ /** Default size for items before they are measured by ResizeObserver. */
497
+ defaultItemSize?: number;
498
+ /** Default width for columns before they are measured by ResizeObserver. */
499
+ defaultColumnWidth?: number;
500
+ /** Whether to show debug information (visible offsets and indices) over items. */
501
+ debug?: boolean;
502
+ /** Whether to use virtual scrollbars for styling purposes. */
503
+ virtualScrollbar?: boolean;
504
+ }
505
+
506
+ /** Exposed methods and properties of the `VirtualScroll` component instance. */
507
+ export interface VirtualScrollInstance<T = unknown> extends VirtualScrollComponentProps<T> {
508
+ /** Detailed information about the current scroll state. */
509
+ scrollDetails: ScrollDetails<T>;
510
+ /** Information about the current visible range of columns. */
511
+ columnRange: ScrollDetails<T>[ 'columnRange' ];
512
+ /** Helper to get the width of a specific column. */
513
+ getColumnWidth: (index: number) => number;
514
+ /** Helper to get the height of a specific row. */
515
+ getRowHeight: (index: number) => number;
516
+ /** Helper to get the virtual offset of a specific row. */
517
+ getRowOffset: (index: number) => number;
518
+ /** Helper to get the virtual offset of a specific column. */
519
+ getColumnOffset: (index: number) => number;
520
+ /** Helper to get the virtual offset of a specific item. */
521
+ getItemOffset: (index: number) => number;
522
+ /** Helper to get the size of a specific item along the scroll axis. */
523
+ getItemSize: (index: number) => number;
524
+ /** Programmatically scroll to a specific row and/or column. */
525
+ scrollToIndex: (rowIndex: number | null | undefined, colIndex: number | null | undefined, options?: ScrollAlignment | ScrollAlignmentOptions | ScrollToIndexOptions) => void;
526
+ /** Programmatically scroll to a specific pixel offset. */
527
+ scrollToOffset: (x?: number | null, y?: number | null, options?: { behavior?: 'auto' | 'smooth'; }) => void;
528
+ /** Resets all dynamic measurements and re-initializes from props. */
529
+ refresh: () => void;
530
+ /** Immediately stops any currently active smooth scroll animation and clears pending corrections. */
531
+ stopProgrammaticScroll: () => void;
532
+ /** Detects the current direction (LTR/RTL) of the scroll container. */
533
+ updateDirection: () => void;
534
+ /** Whether the scroll container is in Right-to-Left (RTL) mode. */
535
+ isRtl: boolean;
536
+ /** Whether the component has finished its first client - side mount and hydration. */
537
+ isHydrated: boolean;
538
+ /** Coordinate scaling factor for X axis. */
539
+ scaleX: number;
540
+ /** Coordinate scaling factor for Y axis. */
541
+ scaleY: number;
542
+ /** Physical width of the content in the DOM (clamped to browser limits). */
543
+ renderedWidth: number;
544
+ /** Physical height of the content in the DOM (clamped to browser limits). */
545
+ renderedHeight: number;
546
+ /** Absolute offset of the component within its container. */
547
+ componentOffset: { x: number; y: number; };
548
+ /** Properties for the vertical scrollbar. */
549
+ scrollbarPropsVertical: ScrollbarSlotProps | null;
550
+ /** Properties for the horizontal scrollbar. */
551
+ scrollbarPropsHorizontal: ScrollbarSlotProps | null;
552
+ }
553
+
554
+ /** Parameters for calculating the scroll target position. */
555
+ export interface ScrollTargetParams {
556
+ /** Row index to target. */
557
+ rowIndex: number | null | undefined;
558
+ /** Column index to target. */
559
+ colIndex: number | null | undefined;
560
+ /** Scroll options. */
561
+ options?: ScrollAlignment | ScrollAlignmentOptions | ScrollToIndexOptions | undefined;
562
+ /** Current scroll direction. */
563
+ direction: ScrollDirection;
564
+ /** Current viewport width. */
565
+ viewportWidth: number;
566
+ /** Current viewport height. */
567
+ viewportHeight: number;
568
+ /** Current total estimated width. */
569
+ totalWidth: number;
570
+ /** Current total estimated height. */
571
+ totalHeight: number;
572
+ /** Item gap. */
573
+ gap: number;
574
+ /** Column gap. */
575
+ columnGap: number;
576
+ /** Fixed item size. */
577
+ fixedSize: number | null;
578
+ /** Fixed column width. */
579
+ fixedWidth: number | null;
580
+ /** Current relative X scroll. */
581
+ relativeScrollX: number;
582
+ /** Current relative Y scroll. */
583
+ relativeScrollY: number;
584
+ /** Resolver for item height. */
585
+ getItemSizeY: (index: number) => number;
586
+ /** Resolver for item width. */
587
+ getItemSizeX: (index: number) => number;
588
+ /** Prefix sum resolver for item height. */
589
+ getItemQueryY: (index: number) => number;
590
+ /** Prefix sum resolver for item width. */
591
+ getItemQueryX: (index: number) => number;
592
+ /** Resolver for column size. */
593
+ getColumnSize: (index: number) => number;
594
+ /** Prefix sum resolver for column width. */
595
+ getColumnQuery: (index: number) => number;
596
+ /** Coordinate scaling factor for X axis. */
597
+ scaleX: number;
598
+ /** Coordinate scaling factor for Y axis. */
599
+ scaleY: number;
600
+ /** Host offset on X axis in display pixels. */
601
+ hostOffsetX: number;
602
+ /** Host offset on Y axis in display pixels. */
603
+ hostOffsetY: number;
604
+ /** List of sticky indices. */
605
+ stickyIndices?: number[] | undefined;
606
+ /** Sticky start offset on X axis. */
607
+ stickyStartX?: number | undefined;
608
+ /** Sticky start offset on Y axis. */
609
+ stickyStartY?: number | undefined;
610
+ /** Sticky end offset on X axis. */
611
+ stickyEndX?: number | undefined;
612
+ /** Sticky end offset on Y axis. */
613
+ stickyEndY?: number | undefined;
614
+ /** Flow padding start on X axis. */
615
+ flowPaddingStartX?: number | undefined;
616
+ /** Flow padding start on Y axis. */
617
+ flowPaddingStartY?: number | undefined;
618
+ /** Flow padding end on X axis. */
619
+ flowPaddingEndX?: number | undefined;
620
+ /** Flow padding end on Y axis. */
621
+ flowPaddingEndY?: number | undefined;
622
+ /** Scroll padding start on X axis. */
623
+ paddingStartX?: number | undefined;
624
+ /** Scroll padding start on Y axis. */
625
+ paddingStartY?: number | undefined;
626
+ /** Scroll padding end on X axis. */
627
+ paddingEndX?: number | undefined;
628
+ /** Scroll padding end on Y axis. */
629
+ paddingEndY?: number | undefined;
630
+ }
631
+
632
+ /** Calculated scroll target result. */
633
+ export interface ScrollTargetResult {
634
+ /** Target relative horizontal position. */
635
+ targetX: number;
636
+ /** Target relative vertical position. */
637
+ targetY: number;
638
+ /** Resolved width of the target item. */
639
+ itemWidth: number;
640
+ /** Resolved height of the target item. */
641
+ itemHeight: number;
642
+ /** Effective alignment used for X axis. */
643
+ effectiveAlignX: ScrollAlignment;
644
+ /** Effective alignment used for Y axis. */
645
+ effectiveAlignY: ScrollAlignment;
646
+ }
647
+
648
+ /** Parameters for calculating the visible range of items. */
649
+ export interface RangeParams {
650
+ /** Scroll direction. */
651
+ direction: ScrollDirection;
652
+ /** Relative horizontal scroll position. */
653
+ relativeScrollX: number;
654
+ /** Relative vertical scroll position. */
655
+ relativeScrollY: number;
656
+ /** Usable viewport width. */
657
+ usableWidth: number;
658
+ /** Usable viewport height. */
659
+ usableHeight: number;
660
+ /** Total item count. */
661
+ itemsLength: number;
662
+ /** Buffer items before. */
663
+ bufferBefore: number;
664
+ /** Buffer items after. */
665
+ bufferAfter: number;
666
+ /** Item gap. */
667
+ gap: number;
668
+ /** Column gap. */
669
+ columnGap: number;
670
+ /** Fixed item size. */
671
+ fixedSize: number | null;
672
+ /** Binary search for row index. */
673
+ findLowerBoundY: (offset: number) => number;
674
+ /** Binary search for row index (horizontal). */
675
+ findLowerBoundX: (offset: number) => number;
676
+ /** Prefix sum for row height. */
677
+ queryY: (index: number) => number;
678
+ /** Prefix sum for row width. */
679
+ queryX: (index: number) => number;
680
+ }
681
+
682
+ /** Parameters for calculating the visible range of columns in grid mode. */
683
+ export interface ColumnRangeParams {
684
+ /** Column count. */
685
+ columnCount: number;
686
+ /** Relative horizontal scroll position. */
687
+ relativeScrollX: number;
688
+ /** Usable viewport width. */
689
+ usableWidth: number;
690
+ /** Column buffer count. */
691
+ colBuffer: number;
692
+ /** Fixed column width. */
693
+ fixedWidth: number | null;
694
+ /** Column gap. */
695
+ columnGap: number;
696
+ /** Binary search for column index. */
697
+ findLowerBound: (offset: number) => number;
698
+ /** Prefix sum for column width. */
699
+ query: (index: number) => number;
700
+ /** Resolver for total column width. */
701
+ totalColsQuery: () => number;
702
+ }
703
+
704
+ /** Parameters for calculating sticky item offsets. */
705
+ export interface StickyParams {
706
+ /** Item index. */
707
+ index: number;
708
+ /** Is sticky configured. */
709
+ isSticky: boolean;
710
+ /** Scroll direction. */
711
+ direction: ScrollDirection;
712
+ /** Relative horizontal scroll. */
713
+ relativeScrollX: number;
714
+ /** Relative vertical scroll. */
715
+ relativeScrollY: number;
716
+ /** Original X offset. */
717
+ originalX: number;
718
+ /** Original Y offset. */
719
+ originalY: number;
720
+ /** Current width. */
721
+ width: number;
722
+ /** Current height. */
723
+ height: number;
724
+ /** All sticky indices. */
725
+ stickyIndices: number[];
726
+ /** Fixed item size. */
727
+ fixedSize: number | null;
728
+ /** Fixed column width. */
729
+ fixedWidth: number | null;
730
+ /** Item gap. */
731
+ gap: number;
732
+ /** Column gap. */
733
+ columnGap: number;
734
+ /** Prefix sum resolver for rows. */
735
+ getItemQueryY: (index: number) => number;
736
+ /** Prefix sum resolver for rows (horizontal). */
737
+ getItemQueryX: (index: number) => number;
738
+ }
739
+
740
+ /** Parameters for calculating an item's position and size. */
741
+ export interface ItemPositionParams {
742
+ /** Item index. */
743
+ index: number;
744
+ /** Scroll direction. */
745
+ direction: ScrollDirection;
746
+ /** Fixed item size. */
747
+ fixedSize: number | null;
748
+ /** Item gap. */
749
+ gap: number;
750
+ /** Column gap. */
751
+ columnGap: number;
752
+ /** Usable viewport width. */
753
+ usableWidth: number;
754
+ /** Usable viewport height. */
755
+ usableHeight: number;
756
+ /** Total estimated width. */
757
+ totalWidth: number;
758
+ /** Prefix sum for row height. */
759
+ queryY: (idx: number) => number;
760
+ /** Prefix sum for row width. */
761
+ queryX: (idx: number) => number;
762
+ /** Height resolver. */
763
+ getSizeY: (idx: number) => number;
764
+ /** Width resolver. */
765
+ getSizeX: (idx: number) => number;
766
+ /** Current column range (for grid mode). */
767
+ columnRange?: ColumnRange | undefined;
768
+ }
769
+
770
+ /** Parameters for calculating an item's style object. */
771
+ export interface ItemStyleParams<T = unknown> {
772
+ /** The rendered item state. */
773
+ item: RenderedItem<T>;
774
+ /** Scroll direction. */
775
+ direction: ScrollDirection;
776
+ /** Configured item size logic. */
777
+ itemSize: number | ((item: T, index: number) => number) | null | undefined;
778
+ /** Parent container tag. */
779
+ containerTag: string;
780
+ /** Padding start on X axis. */
781
+ paddingStartX: number;
782
+ /** Padding start on Y axis. */
783
+ paddingStartY: number;
784
+ /** Hydration state. */
785
+ isHydrated: boolean;
786
+ /** Whether the container is in Right-to-Left (RTL) mode. */
787
+ isRtl: boolean;
788
+ }
789
+
790
+ /** Parameters for calculating the total size of the scrollable area. */
791
+ export interface TotalSizeParams {
792
+ /** The scroll direction. */
793
+ direction: ScrollDirection;
794
+ /** The number of items in the list. */
795
+ itemsLength: number;
796
+ /** The number of columns (for grid mode). */
797
+ columnCount: number;
798
+ /** The fixed size of items, if applicable. */
799
+ fixedSize: number | null;
800
+ /** The fixed width of columns, if applicable. */
801
+ fixedWidth: number | null;
802
+ /** The gap between items. */
803
+ gap: number;
804
+ /** The gap between columns. */
805
+ columnGap: number;
806
+ /** Usable viewport width. */
807
+ usableWidth: number;
808
+ /** Usable viewport height. */
809
+ usableHeight: number;
810
+ /** Function to query the prefix sum of item heights. */
811
+ queryY: (index: number) => number;
812
+ /** Function to query the prefix sum of item widths. */
813
+ queryX: (index: number) => number;
814
+ /** Function to query the prefix sum of column widths. */
815
+ queryColumn: (index: number) => number;
816
+ }