@floor/vlist 0.7.6 → 0.8.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.
@@ -1,9 +1,9 @@
1
1
  /**
2
- * vlist/builder — Self-contained composable virtual list builder
2
+ * vlist/builder — Composable virtual list builder
3
3
  *
4
- * Everything inlined height cache, emitter, DOM, element pool, renderer,
5
- * range calculations, scroll handling. Zero module imports means the builder
6
- * core is ~12 KB minified instead of ~25 KB.
4
+ * Pure utilities (velocity, DOM, pool, range, scroll) live in sibling files.
5
+ * Height cache and emitter are reused from rendering/ and events/ modules.
6
+ * Bun.build inlines everything into a single bundle automatically.
7
7
  *
8
8
  * Plugins compose features *around* the hot path via extension points:
9
9
  * afterScroll, clickHandlers, keydownHandlers, resizeHandlers, destroyHandlers,
@@ -36,18 +36,16 @@ export interface SimpleDataManager<T extends VListItem = VListItem> {
36
36
  getStorage: () => unknown;
37
37
  getPlaceholders: () => unknown;
38
38
  getItem: (index: number) => T | undefined;
39
- getItemById: (id: string | number) => T | undefined;
40
- getIndexById: (id: string | number) => number;
41
39
  isItemLoaded: (index: number) => boolean;
42
40
  getItemsInRange: (start: number, end: number) => T[];
43
41
  setTotal: (total: number) => void;
44
42
  setItems: (items: T[], offset?: number, total?: number) => void;
45
- updateItem: (id: string | number, updates: Partial<T>) => boolean;
46
- removeItem: (id: string | number) => boolean;
43
+ updateItem: (index: number, updates: Partial<T>) => boolean;
44
+ removeItem: (index: number) => boolean;
47
45
  loadRange: (start: number, end: number) => Promise<void>;
48
46
  ensureRange: (start: number, end: number) => Promise<void>;
49
47
  loadInitial: () => Promise<void>;
50
- loadMore: () => Promise<boolean>;
48
+ loadMore: (direction?: "down" | "up") => Promise<boolean>;
51
49
  reload: () => Promise<void>;
52
50
  evictDistant: (visibleStart: number, visibleEnd: number) => void;
53
51
  clear: () => void;
@@ -0,0 +1,13 @@
1
+ /**
2
+ * vlist/builder — DOM Structure
3
+ * Container resolution and DOM scaffold creation for the virtual list.
4
+ */
5
+ export interface DOMStructure {
6
+ root: HTMLElement;
7
+ viewport: HTMLElement;
8
+ content: HTMLElement;
9
+ items: HTMLElement;
10
+ }
11
+ export declare const resolveContainer: (container: HTMLElement | string) => HTMLElement;
12
+ export declare const createDOMStructure: (container: HTMLElement, classPrefix: string, ariaLabel?: string, horizontal?: boolean) => DOMStructure;
13
+ //# sourceMappingURL=dom.d.ts.map
@@ -0,0 +1,146 @@
1
+ /**
2
+ * vlist/builder — Materialize Context Factory
3
+ *
4
+ * Extracts the BuilderContext object, default data-manager proxy, and default
5
+ * scroll-controller proxy out of materialize() in core.ts.
6
+ *
7
+ * All shared mutable state lives in a single `$` (MRefs) object that both
8
+ * core.ts and this module read/write through. Property names are kept short
9
+ * (2–3 chars) so they survive minification without bloating the bundle.
10
+ * Each factory destructures to readable locals on entry.
11
+ *
12
+ * Immutable dependencies are passed via a `deps` (MDeps) object — these are
13
+ * destructured once and never re-read, so their names don't matter at runtime.
14
+ */
15
+ import type { VListItem, VListEvents, ItemTemplate, ItemState, Range } from "../types";
16
+ import type { HeightCache } from "../rendering/heights";
17
+ import type { Emitter } from "../events/emitter";
18
+ import type { DOMStructure } from "./dom";
19
+ import type { createElementPool } from "./pool";
20
+ import type { BuilderConfig, BuilderContext, BuilderState, ResolvedBuilderConfig } from "./types";
21
+ /**
22
+ * Mutable refs object shared between core.ts materialize() and context factories.
23
+ *
24
+ * Key mapping (short → long):
25
+ *
26
+ * | Key | Meaning |
27
+ * |------|------------------------|
28
+ * | it | items |
29
+ * | hc | heightCache |
30
+ * | ch | containerHeight |
31
+ * | cw | containerWidth |
32
+ * | id | isDestroyed |
33
+ * | ii | isInitialized |
34
+ * | ls | lastScrollTop |
35
+ * | vt | velocityTracker |
36
+ * | ss | selectionSet |
37
+ * | fi | focusedIndex |
38
+ * | la | lastAriaSetSize |
39
+ * | dm | dataManagerProxy |
40
+ * | sc | scrollControllerProxy |
41
+ * | vtf | virtualTotalFn |
42
+ * | sgt | scrollGetTop |
43
+ * | sst | scrollSetTop |
44
+ * | sab | scrollIsAtBottom |
45
+ * | sic | scrollIsCompressed |
46
+ * | rfn | renderIfNeededFn |
47
+ * | ffn | forceRenderFn |
48
+ * | gvr | getVisibleRange |
49
+ * | gsp | getScrollToPos |
50
+ * | pef | positionElementFn |
51
+ * | at | activeTemplate |
52
+ * | vre | viewportResizeEnabled |
53
+ * | st | scrollTarget |
54
+ * | gcw | getContainerWidth |
55
+ * | gch | getContainerHeight |
56
+ */
57
+ export interface MRefs<T extends VListItem = VListItem> {
58
+ /** items */
59
+ it: T[];
60
+ /** heightCache */
61
+ hc: HeightCache;
62
+ /** containerHeight */
63
+ ch: number;
64
+ /** containerWidth */
65
+ cw: number;
66
+ /** isDestroyed */
67
+ id: boolean;
68
+ /** isInitialized */
69
+ ii: boolean;
70
+ /** lastScrollTop */
71
+ ls: number;
72
+ /** velocityTracker */
73
+ vt: {
74
+ velocity: number;
75
+ sampleCount: number;
76
+ };
77
+ /** selectionSet */
78
+ ss: Set<string | number>;
79
+ /** focusedIndex */
80
+ fi: number;
81
+ /** lastAriaSetSize */
82
+ la: string;
83
+ /** dataManagerProxy */
84
+ dm: any;
85
+ /** scrollControllerProxy */
86
+ sc: any;
87
+ /** virtualTotalFn */
88
+ vtf: () => number;
89
+ /** scrollGetTop */
90
+ sgt: () => number;
91
+ /** scrollSetTop */
92
+ sst: (pos: number) => void;
93
+ /** scrollIsAtBottom */
94
+ sab: (threshold?: number) => boolean;
95
+ /** scrollIsCompressed */
96
+ sic: boolean;
97
+ /** renderIfNeededFn */
98
+ rfn: () => void;
99
+ /** forceRenderFn */
100
+ ffn: () => void;
101
+ /** getVisibleRange */
102
+ gvr: (scrollTop: number, cHeight: number, hc: HeightCache, total: number, out: Range) => void;
103
+ /** getScrollToPos */
104
+ gsp: (index: number, hc: HeightCache, cHeight: number, total: number, align: "start" | "center" | "end") => number;
105
+ /** positionElementFn */
106
+ pef: (element: HTMLElement, index: number) => void;
107
+ /** activeTemplate */
108
+ at: ItemTemplate<T>;
109
+ /** viewportResizeEnabled */
110
+ vre: boolean;
111
+ /** scrollTarget */
112
+ st: HTMLElement | Window;
113
+ /** getContainerWidth */
114
+ gcw: () => number;
115
+ /** getContainerHeight */
116
+ gch: () => number;
117
+ }
118
+ /** Immutable dependencies the context factory needs from materialize(). */
119
+ export interface MDeps<T extends VListItem = VListItem> {
120
+ readonly dom: DOMStructure;
121
+ readonly emitter: Emitter<VListEvents<T>>;
122
+ readonly resolvedConfig: ResolvedBuilderConfig;
123
+ readonly rawConfig: BuilderConfig<T>;
124
+ readonly rendered: Map<number, HTMLElement>;
125
+ readonly pool: ReturnType<typeof createElementPool>;
126
+ readonly itemState: ItemState;
127
+ readonly sharedState: BuilderState;
128
+ readonly renderRange: Range;
129
+ readonly isHorizontal: boolean;
130
+ readonly classPrefix: string;
131
+ readonly contentSizeHandlers: Array<() => void>;
132
+ readonly afterScroll: Array<(scrollTop: number, direction: string) => void>;
133
+ readonly clickHandlers: Array<(event: MouseEvent) => void>;
134
+ readonly keydownHandlers: Array<(event: KeyboardEvent) => void>;
135
+ readonly resizeHandlers: Array<(width: number, height: number) => void>;
136
+ readonly destroyHandlers: Array<() => void>;
137
+ readonly methods: Map<string, Function>;
138
+ readonly onScrollFrame: () => void;
139
+ readonly resizeObserver: ResizeObserver;
140
+ readonly applyTemplate: (element: HTMLElement, result: string | HTMLElement) => void;
141
+ readonly updateContentSize: () => void;
142
+ }
143
+ export declare const createMaterializeCtx: <T extends VListItem = VListItem>($: MRefs<T>, deps: MDeps<T>) => BuilderContext<T>;
144
+ export declare const createDefaultDataProxy: <T extends VListItem = VListItem>($: MRefs<T>, deps: Pick<MDeps<T>, "rendered" | "itemState" | "contentSizeHandlers" | "applyTemplate" | "updateContentSize">, ctx: BuilderContext<T>) => any;
145
+ export declare const createDefaultScrollProxy: <T extends VListItem = VListItem>($: MRefs<T>, deps: Pick<MDeps<T>, "dom" | "classPrefix">) => any;
146
+ //# sourceMappingURL=materializectx.d.ts.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * vlist/builder — Element Pool
3
+ * Recycling pool for DOM elements to reduce allocation during scrolling.
4
+ */
5
+ export declare const createElementPool: (maxSize?: number) => {
6
+ acquire: () => HTMLElement;
7
+ release: (el: HTMLElement) => void;
8
+ clear: () => void;
9
+ };
10
+ //# sourceMappingURL=pool.d.ts.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * vlist/builder — Range Calculations
3
+ * Visible range detection, overscan application, and scroll-to-index positioning.
4
+ */
5
+ import type { Range } from "../types";
6
+ import type { HeightCache } from "../rendering/heights";
7
+ export declare const calcVisibleRange: (scrollTop: number, containerHeight: number, hc: HeightCache, totalItems: number, out: Range) => void;
8
+ export declare const applyOverscan: (visible: Range, overscan: number, totalItems: number, out: Range) => void;
9
+ export declare const calcScrollToPosition: (index: number, hc: HeightCache, containerHeight: number, totalItems: number, align: "start" | "center" | "end") => number;
10
+ //# sourceMappingURL=range.d.ts.map
@@ -0,0 +1,13 @@
1
+ /**
2
+ * vlist/builder — Scroll Utilities
3
+ * Easing function and scroll-argument resolution for smooth scrolling.
4
+ */
5
+ import type { ScrollToOptions } from "../types";
6
+ export declare const DEFAULT_SMOOTH_DURATION = 300;
7
+ export declare const easeInOutQuad: (t: number) => number;
8
+ export declare const resolveScrollArgs: (alignOrOptions?: "start" | "center" | "end" | ScrollToOptions) => {
9
+ align: "start" | "center" | "end";
10
+ behavior: "auto" | "smooth";
11
+ duration: number;
12
+ };
13
+ //# sourceMappingURL=scroll.d.ts.map
@@ -255,7 +255,6 @@ export interface BuiltVList<T extends VListItem = VListItem> {
255
255
  removeItem: (id: string | number) => void;
256
256
  reload: () => Promise<void>;
257
257
  scrollToIndex: (index: number, alignOrOptions?: "start" | "center" | "end" | ScrollToOptions) => void;
258
- scrollToItem: (id: string | number, alignOrOptions?: "start" | "center" | "end" | ScrollToOptions) => void;
259
258
  cancelScroll: () => void;
260
259
  getScrollPosition: () => number;
261
260
  on: <K extends keyof VListEvents<T>>(event: K, handler: EventHandler<VListEvents<T>[K]>) => Unsubscribe;
@@ -0,0 +1,22 @@
1
+ /**
2
+ * vlist/builder — Velocity Tracking
3
+ * Circular-buffer velocity tracker for scroll momentum detection.
4
+ */
5
+ export declare const VELOCITY_SAMPLE_COUNT = 5;
6
+ export declare const STALE_GAP_MS = 100;
7
+ export declare const MIN_RELIABLE_SAMPLES = 2;
8
+ export interface VelocitySample {
9
+ position: number;
10
+ time: number;
11
+ }
12
+ export interface VelocityTracker {
13
+ velocity: number;
14
+ lastPosition: number;
15
+ lastTime: number;
16
+ samples: VelocitySample[];
17
+ sampleIndex: number;
18
+ sampleCount: number;
19
+ }
20
+ export declare const createVelocityTracker: (initialPosition?: number) => VelocityTracker;
21
+ export declare const updateVelocityTracker: (tracker: VelocityTracker, newPosition: number) => VelocityTracker;
22
+ //# sourceMappingURL=velocity.d.ts.map