@floor/vlist 0.8.2 → 0.9.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/README.md +48 -4
- package/dist/builder/context.d.ts +3 -3
- package/dist/builder/core.d.ts +1 -1
- package/dist/builder/materializectx.d.ts +7 -7
- package/dist/builder/range.d.ts +3 -3
- package/dist/builder/types.d.ts +12 -13
- package/dist/features/grid/plugin.d.ts +1 -1
- package/dist/features/grid/renderer.d.ts +5 -5
- package/dist/features/page/plugin.d.ts +1 -1
- package/dist/features/sections/index.d.ts +1 -1
- package/dist/features/sections/layout.d.ts +6 -5
- package/dist/features/sections/plugin.d.ts +1 -1
- package/dist/features/sections/sticky.d.ts +4 -3
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/rendering/index.d.ts +2 -2
- package/dist/rendering/renderer.d.ts +7 -7
- package/dist/rendering/scale.d.ts +17 -17
- package/dist/rendering/sizes.d.ts +63 -0
- package/dist/rendering/viewport.d.ts +23 -23
- package/dist/types.d.ts +15 -15
- package/package.json +1 -1
- package/dist/rendering/heights.d.ts +0 -63
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*
|
|
5
5
|
* Compression support is NOT imported here — it's injected via
|
|
6
6
|
* CompressionState parameters. When compression is inactive
|
|
7
|
-
* (the common case), all calculations use simple
|
|
7
|
+
* (the common case), all calculations use simple size-cache math
|
|
8
8
|
* with zero dependency on the compression module.
|
|
9
9
|
*
|
|
10
10
|
* This keeps the builder core lightweight. The withCompression plugin
|
|
@@ -12,15 +12,15 @@
|
|
|
12
12
|
* separately and pass the state in.
|
|
13
13
|
*/
|
|
14
14
|
import type { Range, ViewportState } from "../types";
|
|
15
|
-
import type {
|
|
15
|
+
import type { SizeCache } from "./sizes";
|
|
16
16
|
/** Compression calculation result */
|
|
17
17
|
export interface CompressionState {
|
|
18
18
|
/** Whether compression is active */
|
|
19
19
|
isCompressed: boolean;
|
|
20
|
-
/** The actual total
|
|
21
|
-
|
|
22
|
-
/** The virtual
|
|
23
|
-
|
|
20
|
+
/** The actual total size (uncompressed) */
|
|
21
|
+
actualSize: number;
|
|
22
|
+
/** The virtual size (capped at MAX_VIRTUAL_HEIGHT) */
|
|
23
|
+
virtualSize: number;
|
|
24
24
|
/** Compression ratio (1 = no compression, <1 = compressed) */
|
|
25
25
|
ratio: number;
|
|
26
26
|
}
|
|
@@ -30,23 +30,23 @@ export interface CompressionState {
|
|
|
30
30
|
*/
|
|
31
31
|
export declare const NO_COMPRESSION: CompressionState;
|
|
32
32
|
/**
|
|
33
|
-
* Create a trivial compression state from a
|
|
33
|
+
* Create a trivial compression state from a size cache.
|
|
34
34
|
* No compression logic — just reads the total height.
|
|
35
35
|
* For use when the full compression module is not loaded.
|
|
36
36
|
*/
|
|
37
|
-
export declare const getSimpleCompressionState: (_totalItems: number,
|
|
37
|
+
export declare const getSimpleCompressionState: (_totalItems: number, sizeCache: SizeCache) => CompressionState;
|
|
38
38
|
/**
|
|
39
39
|
* Signature for the function that calculates the visible item range.
|
|
40
40
|
* The compression module provides a version that handles compressed scroll;
|
|
41
41
|
* virtual.ts provides a simple fallback for non-compressed lists.
|
|
42
42
|
*/
|
|
43
|
-
export type VisibleRangeFn = (
|
|
43
|
+
export type VisibleRangeFn = (scrollPosition: number, containerHeight: number, sizeCache: SizeCache, totalItems: number, compression: CompressionState, out: Range) => Range;
|
|
44
44
|
/**
|
|
45
45
|
* Signature for the scroll-to-index calculator.
|
|
46
46
|
*/
|
|
47
|
-
export type ScrollToIndexFn = (index: number,
|
|
47
|
+
export type ScrollToIndexFn = (index: number, sizeCache: SizeCache, containerHeight: number, totalItems: number, compression: CompressionState, align: "start" | "center" | "end") => number;
|
|
48
48
|
/**
|
|
49
|
-
* Calculate visible range using
|
|
49
|
+
* Calculate visible range using size cache lookups.
|
|
50
50
|
* Fast path for lists that don't need compression (< ~350 000 items at 48px).
|
|
51
51
|
* Mutates `out` to avoid allocation on the scroll hot path.
|
|
52
52
|
*/
|
|
@@ -59,27 +59,27 @@ export declare const simpleVisibleRange: VisibleRangeFn;
|
|
|
59
59
|
export declare const calculateRenderRange: (visibleRange: Range, overscan: number, totalItems: number, out: Range) => Range;
|
|
60
60
|
/**
|
|
61
61
|
* Simple scroll-to-index calculation (non-compressed).
|
|
62
|
-
* Uses
|
|
62
|
+
* Uses size cache offsets directly.
|
|
63
63
|
*/
|
|
64
64
|
export declare const simpleScrollToIndex: ScrollToIndexFn;
|
|
65
65
|
/**
|
|
66
66
|
* Calculate total content height.
|
|
67
|
-
* Uses compression's
|
|
67
|
+
* Uses compression's virtualSize when compressed, raw height otherwise.
|
|
68
68
|
*/
|
|
69
|
-
export declare const
|
|
69
|
+
export declare const calculateTotalSize: (_totalItems: number, sizeCache: SizeCache, compression?: CompressionState | null) => number;
|
|
70
70
|
/**
|
|
71
|
-
* Calculate actual total
|
|
71
|
+
* Calculate actual total size (without compression cap)
|
|
72
72
|
*/
|
|
73
|
-
export declare const
|
|
73
|
+
export declare const calculateActualSize: (_totalItems: number, sizeCache: SizeCache) => number;
|
|
74
74
|
/**
|
|
75
75
|
* Calculate the offset (translateY) for an item
|
|
76
76
|
* For non-compressed lists only
|
|
77
77
|
*/
|
|
78
|
-
export declare const calculateItemOffset: (index: number,
|
|
78
|
+
export declare const calculateItemOffset: (index: number, sizeCache: SizeCache) => number;
|
|
79
79
|
/**
|
|
80
80
|
* Clamp scroll position to valid range
|
|
81
81
|
*/
|
|
82
|
-
export declare const clampScrollPosition: (
|
|
82
|
+
export declare const clampScrollPosition: (scrollPosition: number, totalHeight: number, containerHeight: number) => number;
|
|
83
83
|
/**
|
|
84
84
|
* Determine scroll direction
|
|
85
85
|
*/
|
|
@@ -90,29 +90,29 @@ export declare const getScrollDirection: (currentScrollTop: number, previousScro
|
|
|
90
90
|
* Accepts an optional `visibleRangeFn` so that compression-aware callers
|
|
91
91
|
* can inject the compressed version. Defaults to `simpleVisibleRange`.
|
|
92
92
|
*/
|
|
93
|
-
export declare const createViewportState: (containerHeight: number,
|
|
93
|
+
export declare const createViewportState: (containerHeight: number, sizeCache: SizeCache, totalItems: number, overscan: number, compression: CompressionState, visibleRangeFn?: VisibleRangeFn) => ViewportState;
|
|
94
94
|
/**
|
|
95
95
|
* Update viewport state after scroll.
|
|
96
96
|
* Mutates state in place for performance on the scroll hot path.
|
|
97
97
|
*/
|
|
98
|
-
export declare const updateViewportState: (state: ViewportState,
|
|
98
|
+
export declare const updateViewportState: (state: ViewportState, scrollPosition: number, sizeCache: SizeCache, totalItems: number, overscan: number, compression: CompressionState, visibleRangeFn?: VisibleRangeFn) => ViewportState;
|
|
99
99
|
/**
|
|
100
100
|
* Update viewport state when container resizes.
|
|
101
101
|
* Mutates state in place for performance.
|
|
102
102
|
*/
|
|
103
|
-
export declare const updateViewportSize: (state: ViewportState, containerHeight: number,
|
|
103
|
+
export declare const updateViewportSize: (state: ViewportState, containerHeight: number, sizeCache: SizeCache, totalItems: number, overscan: number, compression: CompressionState, visibleRangeFn?: VisibleRangeFn) => ViewportState;
|
|
104
104
|
/**
|
|
105
105
|
* Update viewport state when total items changes.
|
|
106
106
|
* Mutates state in place for performance.
|
|
107
107
|
*/
|
|
108
|
-
export declare const updateViewportItems: (state: ViewportState,
|
|
108
|
+
export declare const updateViewportItems: (state: ViewportState, sizeCache: SizeCache, totalItems: number, overscan: number, compression: CompressionState, visibleRangeFn?: VisibleRangeFn) => ViewportState;
|
|
109
109
|
/**
|
|
110
110
|
* Calculate scroll position to bring an index into view.
|
|
111
111
|
*
|
|
112
112
|
* Accepts an optional `scrollToIndexFn` so that compression-aware callers
|
|
113
113
|
* can inject the compressed version. Defaults to `simpleScrollToIndex`.
|
|
114
114
|
*/
|
|
115
|
-
export declare const calculateScrollToIndex: (index: number,
|
|
115
|
+
export declare const calculateScrollToIndex: (index: number, sizeCache: SizeCache, containerHeight: number, totalItems: number, align: "start" | "center" | "end" | undefined, compression: CompressionState, scrollToIndexFn?: ScrollToIndexFn) => number;
|
|
116
116
|
/**
|
|
117
117
|
* Check if two ranges are equal
|
|
118
118
|
*/
|
package/dist/types.d.ts
CHANGED
|
@@ -85,8 +85,8 @@ export interface ItemConfig<T extends VListItem = VListItem> {
|
|
|
85
85
|
* }
|
|
86
86
|
* ```
|
|
87
87
|
*
|
|
88
|
-
* Required when `
|
|
89
|
-
* Optional when `
|
|
88
|
+
* Required when `orientation` is `'vertical'` (default).
|
|
89
|
+
* Optional when `orientation` is `'horizontal'` (used as cross-axis size).
|
|
90
90
|
*/
|
|
91
91
|
height?: number | ((index: number, context?: GridHeightContext) => number);
|
|
92
92
|
/**
|
|
@@ -95,8 +95,8 @@ export interface ItemConfig<T extends VListItem = VListItem> {
|
|
|
95
95
|
* - `number` — Fixed width for all items (fast path, zero overhead)
|
|
96
96
|
* - `(index: number) => number` — Variable width per item (prefix-sum based lookups)
|
|
97
97
|
*
|
|
98
|
-
* Required when `
|
|
99
|
-
* Ignored when `
|
|
98
|
+
* Required when `orientation` is `'horizontal'`.
|
|
99
|
+
* Ignored when `orientation` is `'vertical'` (default).
|
|
100
100
|
*/
|
|
101
101
|
width?: number | ((index: number) => number);
|
|
102
102
|
/** Template function to render each item */
|
|
@@ -107,7 +107,7 @@ export interface VListConfig<T extends VListItem = VListItem> {
|
|
|
107
107
|
/** Container element or selector */
|
|
108
108
|
container: HTMLElement | string;
|
|
109
109
|
/**
|
|
110
|
-
*
|
|
110
|
+
* Layout orientation (default: 'vertical').
|
|
111
111
|
*
|
|
112
112
|
* - `'vertical'` — Standard top-to-bottom scrolling (default)
|
|
113
113
|
* - `'horizontal'` — Left-to-right scrolling (carousel, timeline, etc.)
|
|
@@ -120,7 +120,7 @@ export interface VListConfig<T extends VListItem = VListItem> {
|
|
|
120
120
|
*
|
|
121
121
|
* Cannot be combined with `groups`, `grid`, or `reverse`.
|
|
122
122
|
*/
|
|
123
|
-
|
|
123
|
+
orientation?: "vertical" | "horizontal";
|
|
124
124
|
/** Item configuration (height and template) */
|
|
125
125
|
item: ItemConfig<T>;
|
|
126
126
|
/** Static items array (optional if using adapter) */
|
|
@@ -411,14 +411,14 @@ export interface Range {
|
|
|
411
411
|
}
|
|
412
412
|
/** Viewport state */
|
|
413
413
|
export interface ViewportState {
|
|
414
|
-
/** Current scroll position */
|
|
415
|
-
|
|
416
|
-
/** Container height */
|
|
417
|
-
|
|
418
|
-
/** Total content
|
|
419
|
-
|
|
420
|
-
/** Actual total
|
|
421
|
-
|
|
414
|
+
/** Current scroll position along main axis (scrollTop for vertical, scrollLeft for horizontal) */
|
|
415
|
+
scrollPosition: number;
|
|
416
|
+
/** Container size along main axis (height for vertical, width for horizontal) */
|
|
417
|
+
containerSize: number;
|
|
418
|
+
/** Total content size (may be capped for compression) */
|
|
419
|
+
totalSize: number;
|
|
420
|
+
/** Actual total size without compression */
|
|
421
|
+
actualSize: number;
|
|
422
422
|
/** Whether compression is active */
|
|
423
423
|
isCompressed: boolean;
|
|
424
424
|
/** Compression ratio (1 = no compression, <1 = compressed) */
|
|
@@ -449,7 +449,7 @@ export interface VListEvents<T extends VListItem = VListItem> extends EventMap {
|
|
|
449
449
|
};
|
|
450
450
|
/** Scroll position changed */
|
|
451
451
|
scroll: {
|
|
452
|
-
|
|
452
|
+
scrollPosition: number;
|
|
453
453
|
direction: "up" | "down";
|
|
454
454
|
};
|
|
455
455
|
/** Scroll velocity changed */
|
package/package.json
CHANGED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* vlist - Height Cache
|
|
3
|
-
* Efficient height management for fixed and variable item heights
|
|
4
|
-
*
|
|
5
|
-
* Provides two implementations:
|
|
6
|
-
* - Fixed: O(1) operations using multiplication (zero overhead, matches existing behavior)
|
|
7
|
-
* - Variable: O(1) offset lookup via prefix sums, O(log n) binary search for index-at-offset
|
|
8
|
-
*
|
|
9
|
-
* The HeightCache abstraction allows all virtual scrolling and compression code
|
|
10
|
-
* to work identically with both fixed and variable heights.
|
|
11
|
-
*/
|
|
12
|
-
/** Height cache for efficient offset/index lookups */
|
|
13
|
-
export interface HeightCache {
|
|
14
|
-
/** Get offset (Y position) for an item index — O(1) */
|
|
15
|
-
getOffset(index: number): number;
|
|
16
|
-
/** Get height of a specific item */
|
|
17
|
-
getHeight(index: number): number;
|
|
18
|
-
/** Find item index at a scroll offset — O(1) fixed, O(log n) variable */
|
|
19
|
-
indexAtOffset(offset: number): number;
|
|
20
|
-
/** Total content height */
|
|
21
|
-
getTotalHeight(): number;
|
|
22
|
-
/** Current total item count */
|
|
23
|
-
getTotal(): number;
|
|
24
|
-
/** Rebuild cache (call when items change) */
|
|
25
|
-
rebuild(totalItems: number): void;
|
|
26
|
-
/** Whether heights are variable (false = fixed fast path) */
|
|
27
|
-
isVariable(): boolean;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Create a height cache — returns fixed or variable implementation
|
|
31
|
-
*
|
|
32
|
-
* When height is a number, returns a zero-overhead fixed implementation.
|
|
33
|
-
* When height is a function, builds a prefix-sum array for efficient lookups.
|
|
34
|
-
*/
|
|
35
|
-
export declare const createHeightCache: (height: number | ((index: number) => number), initialTotal: number) => HeightCache;
|
|
36
|
-
/**
|
|
37
|
-
* Count how many items fit in a given container height starting from startIndex
|
|
38
|
-
* Used for compressed mode visible range calculations
|
|
39
|
-
*
|
|
40
|
-
* For fixed heights: O(1) via division
|
|
41
|
-
* For variable heights: O(k) where k = visible item count (typically 10-50)
|
|
42
|
-
*/
|
|
43
|
-
export declare const countVisibleItems: (heightCache: HeightCache, startIndex: number, containerHeight: number, totalItems: number) => number;
|
|
44
|
-
/**
|
|
45
|
-
* Count how many items fit starting from the bottom of the list
|
|
46
|
-
* Used for near-bottom interpolation in compressed mode
|
|
47
|
-
*
|
|
48
|
-
* For fixed heights: O(1) via division
|
|
49
|
-
* For variable heights: O(k) where k = items fitting (typically 10-50)
|
|
50
|
-
*/
|
|
51
|
-
export declare const countItemsFittingFromBottom: (heightCache: HeightCache, containerHeight: number, totalItems: number) => number;
|
|
52
|
-
/**
|
|
53
|
-
* Calculate the pixel offset for a fractional virtual scroll index
|
|
54
|
-
*
|
|
55
|
-
* In compressed mode, the scroll position maps to a fractional item index
|
|
56
|
-
* (e.g., 5.3 means 30% into item 5). This function calculates the actual
|
|
57
|
-
* pixel offset for such a fractional position using variable heights.
|
|
58
|
-
*
|
|
59
|
-
* For fixed heights this reduces to: virtualIndex * itemHeight
|
|
60
|
-
* For variable heights: offset(floor) + frac * height(floor)
|
|
61
|
-
*/
|
|
62
|
-
export declare const getOffsetForVirtualIndex: (heightCache: HeightCache, virtualIndex: number, totalItems: number) => number;
|
|
63
|
-
//# sourceMappingURL=heights.d.ts.map
|