vlist 3.0.0-next.2 → 3.0.0-next.4
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.github.md +88 -39
- package/README.md +44 -27
- package/dist/config.d.ts +129 -12
- package/dist/config.js +1 -1
- package/dist/core/create.d.ts +22 -4
- package/dist/core/dom.d.ts +22 -2
- package/dist/core/fold.d.ts +52 -0
- package/dist/core/hooks.d.ts +1 -1
- package/dist/core/index.d.ts +1 -1
- package/dist/core/pipeline.d.ts +1 -1
- package/dist/core/pool.d.ts +9 -2
- package/dist/core/runway.d.ts +29 -3
- package/dist/core/scroll.d.ts +1 -1
- package/dist/core/sizes.d.ts +1 -1
- package/dist/core/state.d.ts +13 -1
- package/dist/core/types.d.ts +151 -61
- package/dist/core/velocity.d.ts +1 -1
- package/dist/index.d.ts +17 -2
- package/dist/index.js +1 -1
- package/dist/internals.d.ts +0 -1
- package/dist/internals.js +1 -1
- package/dist/plugins/a11y/index.d.ts +1 -0
- package/dist/plugins/a11y/plugin.d.ts +1 -1
- package/dist/plugins/autosize/index.d.ts +2 -1
- package/dist/plugins/autosize/plugin.d.ts +13 -2
- package/dist/plugins/carousel/engine.d.ts +1 -1
- package/dist/plugins/carousel/index.d.ts +1 -0
- package/dist/plugins/carousel/plugin.d.ts +42 -6
- package/dist/plugins/carousel/presets.d.ts +1 -1
- package/dist/plugins/data/index.d.ts +1 -0
- package/dist/plugins/data/plugin.d.ts +15 -2
- package/dist/plugins/grid/index.d.ts +2 -1
- package/dist/plugins/grid/plugin.d.ts +14 -2
- package/dist/plugins/groups/async-bridge.d.ts +6 -6
- package/dist/plugins/groups/index.d.ts +1 -0
- package/dist/plugins/groups/layout.d.ts +2 -2
- package/dist/plugins/groups/plugin.d.ts +12 -4
- package/dist/plugins/groups/sticky.d.ts +2 -1
- package/dist/plugins/groups/types.d.ts +8 -3
- package/dist/plugins/masonry/index.d.ts +2 -1
- package/dist/plugins/masonry/plugin.d.ts +10 -2
- package/dist/plugins/masonry/renderer.d.ts +5 -1
- package/dist/plugins/page/plugin.d.ts +1 -1
- package/dist/plugins/scrollbar/index.d.ts +2 -1
- package/dist/plugins/scrollbar/plugin.d.ts +7 -2
- package/dist/plugins/search/index.d.ts +1 -0
- package/dist/plugins/search/plugin.d.ts +29 -1
- package/dist/plugins/selection/index.d.ts +2 -1
- package/dist/plugins/selection/plugin.d.ts +23 -2
- package/dist/plugins/snapshots/index.d.ts +1 -0
- package/dist/plugins/snapshots/plugin.d.ts +9 -2
- package/dist/plugins/sortable/index.d.ts +1 -0
- package/dist/plugins/sortable/plugin.d.ts +14 -3
- package/dist/plugins/table/index.d.ts +1 -0
- package/dist/plugins/table/plugin.d.ts +19 -3
- package/dist/plugins/transition/plugin.d.ts +1 -1
- package/dist/plugins/tree/index.d.ts +1 -0
- package/dist/plugins/tree/layout.d.ts +3 -1
- package/dist/plugins/tree/plugin.d.ts +37 -3
- package/dist/plugins/tree/types.d.ts +1 -1
- package/dist/rendering/sizes.d.ts +19 -1
- package/dist/size.json +1 -1
- package/dist/synthetic.d.ts +2 -2
- package/dist/synthetic.js +1 -1
- package/dist/types.d.ts +14 -21
- package/dist/utils/apply-scroll-behavior.d.ts +15 -0
- package/dist/utils/scroll-padding.d.ts +36 -0
- package/dist/utils/stats.d.ts +9 -1
- package/dist/vlist-tree.css +1 -1
- package/dist/vlist.css +1 -1
- package/package.json +6 -2
- package/dist/plugins/grid/renderer.d.ts +0 -68
package/dist/core/dom.d.ts
CHANGED
|
@@ -1,9 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vlist
|
|
2
|
+
* vlist — DOM Structure
|
|
3
3
|
* Container resolution and DOM scaffold creation.
|
|
4
4
|
*/
|
|
5
5
|
import type { DOMStructure } from "./types";
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* A row element, carrying the one slot a plugin may use to record that it has
|
|
8
|
+
* processed this row's current content. Zero means "written, nobody has looked
|
|
9
|
+
* at it since"; any other value belongs to whichever plugin wrote it, and only
|
|
10
|
+
* one plugin may (today: `search()`, for its `<mark>`s).
|
|
11
|
+
*/
|
|
12
|
+
export interface StampableRow extends HTMLElement {
|
|
13
|
+
_stamp?: number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Called by every renderer immediately after it writes a row's content.
|
|
17
|
+
*
|
|
18
|
+
* Neutralizes focusable descendants, and voids the row's stamp, so an observer
|
|
19
|
+
* can tell "this row was rewritten" apart from "this row only moved". Node
|
|
20
|
+
* identity cannot tell them apart: `item.template` may return an `HTMLElement`
|
|
21
|
+
* and hand back that same object on a later call, rewritten in place, so the
|
|
22
|
+
* row's child nodes outlive a rewrite that destroyed everything they held. The
|
|
23
|
+
* renderer doing the write is the only one that knows it happened, so it is
|
|
24
|
+
* the one that says so.
|
|
25
|
+
*/
|
|
26
|
+
export declare function rowContentWritten(el: HTMLElement): void;
|
|
7
27
|
export declare function resolveContainer(container: HTMLElement | string): HTMLElement;
|
|
8
28
|
export declare function createDOMStructure(container: HTMLElement, classPrefix: string, isX: boolean, ariaLabel?: string): DOMStructure;
|
|
9
29
|
//# sourceMappingURL=dom.d.ts.map
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wrap-mode fold: re-key mounted rows and shift the render window.
|
|
3
|
+
*
|
|
4
|
+
* A fold moves every virtual index by whole laps; the nodes and their paint
|
|
5
|
+
* positions are unchanged. Re-keying the map (and the `id` that encodes the
|
|
6
|
+
* virtual index) lets the next commit find them instead of releasing,
|
|
7
|
+
* re-templating and re-inserting the viewport. Lives here — not in pipeline
|
|
8
|
+
* or create — so a native list that never wraps does not import it (runway
|
|
9
|
+
* is pulled by carousel). The synthetic handler imports it because wrap
|
|
10
|
+
* folds for that entry go through commit(), not wrapRebase; putting the
|
|
11
|
+
* import in create.ts would charge every native list.
|
|
12
|
+
*
|
|
13
|
+
* Shifted with the fold: the typed-array window (`shiftWindow`), carousel
|
|
14
|
+
* `intendedVi`, velocity `_lp`, `lastEventScrollPos`, `id` (virtual index),
|
|
15
|
+
* `aria-activedescendant` (resolved to the same node after its id rewrite),
|
|
16
|
+
* `oddClass` when `indexShift` is odd (stripe is virtual-index parity).
|
|
17
|
+
* Fold-invariant: `data-index` / `aria-posinset` (public index), selection
|
|
18
|
+
* `focusedIndex` (data space under `indexMap`), snapshots (`dataIndex`).
|
|
19
|
+
*/
|
|
20
|
+
import type { EngineState } from "./state";
|
|
21
|
+
import type { WrapConfig } from "./runway";
|
|
22
|
+
/**
|
|
23
|
+
* Move every `rendered` key by `-indexShift` without touching the DOM tree.
|
|
24
|
+
* `data-index` / `aria-posinset` carry the public index and stay put.
|
|
25
|
+
*
|
|
26
|
+
* `aria-activedescendant` is resolved after every id rewrite: a uniform shift
|
|
27
|
+
* can make two nodes share an id mid-loop, so rewriting the attribute from a
|
|
28
|
+
* reconstructed old id in that window can point at the wrong node.
|
|
29
|
+
*/
|
|
30
|
+
export declare function rekeyRendered(rendered: Map<number, HTMLElement>, indexShift: number, prefix: string, content: HTMLElement, oddClass?: string): void;
|
|
31
|
+
/**
|
|
32
|
+
* Shift the committed render window by whole laps after a wrap fold.
|
|
33
|
+
*
|
|
34
|
+
* Virtual indices and offsets move with the logical origin; shifting them
|
|
35
|
+
* (and `prevBaseOffset`) keeps the range-unchanged fast path honest so the
|
|
36
|
+
* next frame does not treat identical paint as a new window.
|
|
37
|
+
*/
|
|
38
|
+
export declare function shiftWindow(state: EngineState, indexShift: number, pixelShift: number): void;
|
|
39
|
+
/**
|
|
40
|
+
* How many whole laps to fold by, for a drift from home measured in laps; 0 for none.
|
|
41
|
+
*
|
|
42
|
+
* An owner that folds every lap (threshold 1) keeps its position in
|
|
43
|
+
* `[home, home + lap)`: the floor, so that leaving the home lap backwards folds
|
|
44
|
+
* at once, exactly as leaving it forwards does. Truncation folded forwards on
|
|
45
|
+
* leaving the lap but backwards only a whole lap later — a carousel could rest in
|
|
46
|
+
* the lap before home at index 0, where a leading peek needs index -1: a blank
|
|
47
|
+
* peek, then a pop. A larger threshold keeps the symmetric dead zone it always had.
|
|
48
|
+
*/
|
|
49
|
+
export declare function wrapLaps(driftLaps: number, threshold: number): number;
|
|
50
|
+
/** Re-key mounted rows and shift window state for a wrap fold, before the next render. */
|
|
51
|
+
export declare function applyWrapFold(wrap: WrapConfig, shift: number, state: EngineState, content: HTMLElement, rendered: Map<number, HTMLElement> | undefined, prefix: string, oddClass?: string): void;
|
|
52
|
+
//# sourceMappingURL=fold.d.ts.map
|
package/dist/core/hooks.d.ts
CHANGED
package/dist/core/index.d.ts
CHANGED
package/dist/core/pipeline.d.ts
CHANGED
package/dist/core/pool.d.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vlist
|
|
2
|
+
* vlist — Element Pool
|
|
3
3
|
*
|
|
4
4
|
* acquire() = pop or create, release() = reset + push.
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
|
+
* No fixed cap. A cap of 100 dropped a window of 300 cells on a jump, and the
|
|
7
|
+
* next frame cloned 200 of them again. The pool still grows to the most rows
|
|
8
|
+
* that were on screen at once, and that peak does not fall on its own:
|
|
9
|
+
* release() only pushes, so a list that shrinks keeps every spare node until
|
|
10
|
+
* trim() drops them back to the number currently mounted. Core trims when
|
|
11
|
+
* scrolling has gone idle, and after a data change that is not mid-scroll, so
|
|
12
|
+
* a jump during a gesture still reuses the previous window.
|
|
6
13
|
*/
|
|
7
14
|
import type { ElementPool } from "./types";
|
|
8
15
|
export declare function createPool(classPrefix: string): ElementPool;
|
package/dist/core/runway.d.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*
|
|
7
7
|
* The content element is sized to a bounded *runway* (a multiple of the
|
|
8
8
|
* viewport, capped at the real virtual size) instead of `totalItems × itemSize`.
|
|
9
|
-
* This sidesteps the browser's ~16.7M px element-size limit without
|
|
10
|
-
*
|
|
9
|
+
* This sidesteps the browser's ~16.7M px element-size limit without compressing
|
|
10
|
+
* the coordinate space — no compression ratio leaks into offsets or hit-testing.
|
|
11
11
|
*
|
|
12
12
|
* Coordinates:
|
|
13
13
|
* logical = baseOffset + scrollTop (absolute virtual pixel position)
|
|
@@ -56,10 +56,18 @@ export interface BoundedScrollHandler extends ScrollHandler {
|
|
|
56
56
|
export interface WrapConfig {
|
|
57
57
|
/** Current lap period in virtual px (`realTotal × stepSize`). */
|
|
58
58
|
readonly lapSize: () => number;
|
|
59
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* Real items in one lap (e.g. the carousel's `realTotal`). The wrap handler
|
|
61
|
+
* uses this to re-key mounted elements on a fold so the same DOM nodes
|
|
62
|
+
* survive the virtual-index shift — only the key changed; paint did not.
|
|
63
|
+
*/
|
|
64
|
+
readonly itemsPerLap: () => number;
|
|
65
|
+
/** Logical position to fold back toward (the home lap). */
|
|
60
66
|
readonly home: () => number;
|
|
61
67
|
/** Fold the logical position back toward `home` once it drifts this many laps away. */
|
|
62
68
|
readonly thresholdLaps: number;
|
|
69
|
+
/** @internal Notify the wrap owner when its logical coordinates fold. */
|
|
70
|
+
readonly onFold?: (shift: number) => void;
|
|
63
71
|
}
|
|
64
72
|
export interface BoundedScrollConfig {
|
|
65
73
|
/** Logical row geometry for opt-in input providers (keyboard row steps). */
|
|
@@ -78,6 +86,24 @@ export interface BoundedScrollConfig {
|
|
|
78
86
|
/** Infinite-loop config (carousel). When set, the logical position wraps by
|
|
79
87
|
* whole laps toward `home` instead of clamping to a maximum. */
|
|
80
88
|
readonly wrap?: WrapConfig;
|
|
89
|
+
/**
|
|
90
|
+
* Mounted row map. A wrap fold re-keys it in place so phase 2 finds the
|
|
91
|
+
* same nodes; omitted when the handler is constructed without a viewport.
|
|
92
|
+
*/
|
|
93
|
+
readonly rendered?: Map<number, HTMLElement>;
|
|
94
|
+
/**
|
|
95
|
+
* Class prefix for rewriting `id` / `aria-activedescendant` on a wrap fold.
|
|
96
|
+
* Passed explicitly — a prefix containing `-content` cannot be recovered
|
|
97
|
+
* from the content element's class name.
|
|
98
|
+
*/
|
|
99
|
+
readonly classPrefix?: string;
|
|
100
|
+
/**
|
|
101
|
+
* Stripe class (`{prefix}-item--odd`). Re-toggled on a wrap fold when
|
|
102
|
+
* `indexShift` is odd, so virtual-index parity survives the re-key.
|
|
103
|
+
*/
|
|
104
|
+
readonly oddClass?: string;
|
|
105
|
+
/** @internal Coordinate fold: shift core telemetry references before rendering. */
|
|
106
|
+
readonly onFold?: (shift: number) => void;
|
|
81
107
|
/** Called synchronously per frame — triggers the 2-phase pipeline. */
|
|
82
108
|
readonly onFrame: () => void;
|
|
83
109
|
/** Called when scrolling becomes idle. */
|
package/dist/core/scroll.d.ts
CHANGED
package/dist/core/sizes.d.ts
CHANGED
package/dist/core/state.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vlist
|
|
2
|
+
* vlist — EngineState
|
|
3
3
|
*
|
|
4
4
|
* Persistent singleton instantiated once during createVList().
|
|
5
5
|
* All hot-path state lives in pre-allocated TypedArrays.
|
|
@@ -40,11 +40,23 @@ export interface EngineState {
|
|
|
40
40
|
renderPending: boolean;
|
|
41
41
|
initialized: boolean;
|
|
42
42
|
destroyed: boolean;
|
|
43
|
+
/** Set when the render window hit its ceiling, which only a degenerate size spec does. */
|
|
44
|
+
windowClamped: boolean;
|
|
45
|
+
/** Latch, so the ceiling is reported once rather than once per frame. */
|
|
46
|
+
windowClampReported: boolean;
|
|
43
47
|
prevAriaTotal: number;
|
|
44
48
|
/**
|
|
45
49
|
* Resize buffers when container changes. Cold path only.
|
|
46
50
|
* Heuristic: capacity = ceil(containerSize / minItemSize) + overscan * 2
|
|
47
51
|
*/
|
|
52
|
+
/**
|
|
53
|
+
* Grow buffers to hold at least `needed` entries. Cold path only.
|
|
54
|
+
*
|
|
55
|
+
* The render window is the authority on how many entries are required. The
|
|
56
|
+
* container/minItemSize heuristic below is only an estimate, and for a size
|
|
57
|
+
* function there is no knowable minimum to estimate from.
|
|
58
|
+
*/
|
|
59
|
+
ensureCapacity(needed: number): void;
|
|
48
60
|
resizeCapacity(containerSize: number, minItemSize: number, overscan?: number): void;
|
|
49
61
|
/** Reset to empty range sentinel. */
|
|
50
62
|
clear(): void;
|
package/dist/core/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* vlist
|
|
2
|
+
* vlist — Core Type Definitions
|
|
3
3
|
*
|
|
4
4
|
* Zero-allocation pipeline types. All hot-path state lives in TypedArrays
|
|
5
5
|
* on the EngineState singleton — no intermediate object allocation.
|
|
@@ -56,90 +56,162 @@ export interface ElementPool {
|
|
|
56
56
|
acquire(): HTMLElement;
|
|
57
57
|
release(element: HTMLElement): void;
|
|
58
58
|
readonly size: number;
|
|
59
|
+
/** Drop spare nodes until at most `keep` remain. Does not touch mounted rows. */
|
|
60
|
+
trim(keep: number): void;
|
|
59
61
|
clear(): void;
|
|
60
62
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
*
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
63
|
+
/**
|
|
64
|
+
* DOM structure, plus the element and role helpers that act on it.
|
|
65
|
+
*/
|
|
66
|
+
export interface DomCapability extends DOMStructure {
|
|
67
|
+
/** The rendered element for a layout index, honouring a plugin's override. */
|
|
68
|
+
renderedElement(index: number): HTMLElement | null;
|
|
69
|
+
/** Adopt the WAI-ARIA listbox roles. Selection and a11y call this; a list
|
|
70
|
+
* with neither stays a display-only `role="list"`. */
|
|
71
|
+
enableListbox(): void;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Logical scroll model boundary (RFC-012): the adapter's reads, plus the
|
|
75
|
+
* controls that write. Plugins go through this rather than touching
|
|
76
|
+
* `getState().scrollPosition` or raw `scrollTop`/`scrollLeft`.
|
|
77
|
+
*/
|
|
78
|
+
export interface ScrollCapability extends ScrollAdapter {
|
|
79
|
+
to(position: number): void;
|
|
80
|
+
/** Preserve synthetic motion during a measurement/anchor correction. */
|
|
81
|
+
shiftBy(delta: number): void;
|
|
82
|
+
smoothTo(target: number | (() => number), duration: number, easing?: (t: number) => number, onComplete?: () => void): void;
|
|
83
|
+
/** Cancel any in-flight smooth-scroll animation on the active handler. */
|
|
84
|
+
cancel(): void;
|
|
85
|
+
/** Commit an external position, render synchronously and schedule idle. */
|
|
86
|
+
commit(px: number): void;
|
|
82
87
|
/** Install an external writer and disable default scroll/wheel listeners. */
|
|
83
|
-
|
|
88
|
+
setSource(source: {
|
|
84
89
|
write(px: number): void;
|
|
85
90
|
onContentSize?(px: number): void;
|
|
86
91
|
}): void;
|
|
87
|
-
|
|
88
|
-
commitScroll(px: number): void;
|
|
92
|
+
setTarget(target: EventTarget): void;
|
|
89
93
|
/** Request the bounded scroll handler in infinite-loop (wrap) mode (carousel). */
|
|
90
94
|
setBoundedWrap(config: import("./runway").WrapConfig, createHandler: (config: import("./runway").BoundedScrollConfig) => import("./runway").BoundedScrollHandler): void;
|
|
91
|
-
|
|
95
|
+
setToPosFn(fn: (index: number, sizeCache: import("./sizes").SizeCache, containerSize: number, totalItems: number, align: string) => number): void;
|
|
96
|
+
setToIndexFn(fn: (index: number, align: string, behavior?: string, duration?: number, easing?: (t: number) => number) => void | false): void;
|
|
97
|
+
onFrame(): void;
|
|
98
|
+
onIdle(): void;
|
|
99
|
+
disableResize(): void;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* The item space: reads, mutations, and the inversion hooks a plugin installs
|
|
103
|
+
* to own them. One owner per hook — two plugins claiming the same one is how
|
|
104
|
+
* tree with data rendered nothing.
|
|
105
|
+
*/
|
|
106
|
+
export interface ItemsCapability<T extends VListItem = VListItem> {
|
|
107
|
+
all(): readonly T[];
|
|
108
|
+
at(index: number): T | undefined;
|
|
109
|
+
removeById(id: string | number): number;
|
|
110
|
+
insertAt(item: T, index: number): void;
|
|
111
|
+
setGetFn(fn: (index: number) => T | undefined): void;
|
|
112
|
+
setRemoveFn(fn: (id: string | number) => number): void;
|
|
113
|
+
setInsertFn(fn: (item: T, index: number) => void): void;
|
|
114
|
+
setUpdateFn(fn: (id: string | number, updates: Partial<T>) => boolean): void;
|
|
115
|
+
setIndexByIdFn(fn: (id: string | number) => number): void;
|
|
116
|
+
/** The public total. Also feeds `aria-setsize`. */
|
|
117
|
+
setTotalFn(fn: () => number): void;
|
|
92
118
|
setIndexMapFn(fn: (renderIndex: number) => number): void;
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
119
|
+
}
|
|
120
|
+
/** The size cache and the spec behind it. */
|
|
121
|
+
export interface SizesCapability {
|
|
122
|
+
readonly cache: SizeCache;
|
|
123
|
+
readonly rawSpec: number | ((index: number, ...args: unknown[]) => number);
|
|
124
|
+
/** Replace the size spec. `gap` is the spacing baked into the spec, so the
|
|
125
|
+
* cache can keep excluding one trailing gap from the total; omit it when the
|
|
126
|
+
* spec carries none (table's fixed row height, for instance). */
|
|
127
|
+
setConfig(config: number | ((index: number) => number), gap?: number): void;
|
|
128
|
+
rebuild(): void;
|
|
129
|
+
}
|
|
130
|
+
/** The render pipeline: run it, replace it, or describe item state to it. */
|
|
131
|
+
export interface RenderCapability {
|
|
132
|
+
force(): void;
|
|
133
|
+
ifNeeded(): void;
|
|
134
|
+
contentSize(size: number): void;
|
|
135
|
+
setFn(renderIfNeeded: () => void, forceRender: () => void): void;
|
|
136
|
+
setStateFn(fn: (index: number, state: ItemState) => void): void;
|
|
137
|
+
getStateFn(): ((index: number, state: ItemState) => void) | null;
|
|
138
|
+
}
|
|
139
|
+
/** The cross-plugin method bus and the shared event handlers. */
|
|
140
|
+
export interface HooksCapability {
|
|
141
|
+
/** Register a public method on the list. Public names are a contract:
|
|
142
|
+
* a second claimant throws. Underscore names are the internal protocol. */
|
|
143
|
+
method(name: string, fn: Function): void;
|
|
144
|
+
get(name: string): Function | undefined;
|
|
145
|
+
onClick(handler: (event: MouseEvent) => void): void;
|
|
146
|
+
onKeydown(handler: (event: KeyboardEvent) => void): void;
|
|
147
|
+
onDestroy(handler: () => void): void;
|
|
148
|
+
}
|
|
149
|
+
/** Keyboard navigation geometry, shared between layout plugins and selection. */
|
|
150
|
+
export interface NavCapability {
|
|
151
|
+
set(config: {
|
|
125
152
|
total?: () => number;
|
|
126
153
|
ud?: number;
|
|
127
154
|
lr?: number;
|
|
128
155
|
scrollIndex?: (itemIndex: number) => number;
|
|
129
156
|
navigate?: (currentIndex: number, key: string, total: number) => number;
|
|
157
|
+
/**
|
|
158
|
+
* Bring this navigation / focus index into view, the layout plugin's way.
|
|
159
|
+
* The index is the same space as `nav.total` (carousel: logical item
|
|
160
|
+
* index; grid: item index) — not a size-cache index and not a layout
|
|
161
|
+
* index that counts group headers or carousel laps.
|
|
162
|
+
* `selectNext` / `selectPrevious` call this when present so a plugin that
|
|
163
|
+
* owns motion (carousel snap, current virtual lap) reveals the item
|
|
164
|
+
* without selection falling back to a raw size-cache offset.
|
|
165
|
+
*/
|
|
166
|
+
reveal?: (index: number) => void;
|
|
130
167
|
}): void;
|
|
131
|
-
|
|
168
|
+
get(): {
|
|
132
169
|
ud: number;
|
|
133
170
|
lr: number;
|
|
134
171
|
scrollIndex: ((itemIndex: number) => number) | null;
|
|
135
172
|
navigate: ((currentIndex: number, key: string, total: number) => number) | null;
|
|
136
173
|
total: (() => number) | null;
|
|
174
|
+
/**
|
|
175
|
+
* Always present on the returned object: the owner's reveal, or `null`
|
|
176
|
+
* when no plugin published one. Plugin authors must read this property
|
|
177
|
+
* rather than treating a missing key as "no owner".
|
|
178
|
+
*/
|
|
179
|
+
reveal: ((index: number) => void) | null;
|
|
137
180
|
};
|
|
138
181
|
}
|
|
139
|
-
|
|
182
|
+
/**
|
|
183
|
+
* What a plugin receives in `setup()`. Grouped by capability rather than laid
|
|
184
|
+
* out flat: the flat form had fifty members with no map from a member to the
|
|
185
|
+
* part of the engine it reached.
|
|
186
|
+
*/
|
|
187
|
+
export interface PluginContext<T extends VListItem = VListItem> {
|
|
188
|
+
readonly dom: DomCapability;
|
|
189
|
+
readonly scroll: ScrollCapability;
|
|
190
|
+
readonly items: ItemsCapability<T>;
|
|
191
|
+
readonly sizes: SizesCapability;
|
|
192
|
+
readonly render: RenderCapability;
|
|
193
|
+
readonly hooks: HooksCapability;
|
|
194
|
+
readonly nav: NavCapability;
|
|
195
|
+
readonly pool: ElementPool;
|
|
196
|
+
readonly config: ResolvedConfig;
|
|
197
|
+
readonly emitter: Emitter<import("../types").VListEvents<T>>;
|
|
198
|
+
readonly template: ItemTemplate<T>;
|
|
199
|
+
getState(): EngineState;
|
|
200
|
+
}
|
|
201
|
+
export interface VListPlugin<T extends VListItem = VListItem, M = {}> {
|
|
140
202
|
readonly name: string;
|
|
141
203
|
readonly priority?: number;
|
|
142
204
|
readonly conflicts?: readonly string[];
|
|
205
|
+
/**
|
|
206
|
+
* Cold path: reject a list configuration this plugin cannot support.
|
|
207
|
+
*
|
|
208
|
+
* Runs before setup and outside its catch, so throwing here reaches the
|
|
209
|
+
* caller. A throw from `setup()` cannot: it is reported as an `error` event
|
|
210
|
+
* so that one plugin's failure does not stop the others, which is the right
|
|
211
|
+
* behaviour for a fault and the wrong one for a configuration the plugin has
|
|
212
|
+
* already decided it cannot serve.
|
|
213
|
+
*/
|
|
214
|
+
validateConfig?(config: ResolvedConfig): void;
|
|
143
215
|
/** Cold path: one-time wiring during createVList(). */
|
|
144
216
|
setup?(ctx: PluginContext<T>): void;
|
|
145
217
|
/** Hot path: compiled into linear arrays, iterated per frame. */
|
|
@@ -152,7 +224,25 @@ export interface VListPlugin<T extends VListItem = VListItem> {
|
|
|
152
224
|
};
|
|
153
225
|
/** Cleanup on destroy. */
|
|
154
226
|
destroy?(): void;
|
|
227
|
+
/**
|
|
228
|
+
* Phantom marker: the methods this plugin adds to the list instance.
|
|
229
|
+
* Never set at runtime; `createVList` reads it to type the returned list.
|
|
230
|
+
*/
|
|
231
|
+
readonly __methods?: M;
|
|
155
232
|
}
|
|
233
|
+
/** @internal Turns a union into an intersection. */
|
|
234
|
+
type UnionToIntersection<U> = (U extends unknown ? (x: U) => void : never) extends (x: infer I) => void ? I : never;
|
|
235
|
+
/**
|
|
236
|
+
* @internal The method map a single plugin declares. The item type is matched
|
|
237
|
+
* loosely: a plugin typed for a specific item is not assignable to
|
|
238
|
+
* `VListPlugin<VListItem, ...>` under strict function types.
|
|
239
|
+
*/
|
|
240
|
+
type MethodsOf<P> = P extends VListPlugin<any, infer M> ? M : {};
|
|
241
|
+
/**
|
|
242
|
+
* The methods a plugin array adds to the list instance. A plugin that declares
|
|
243
|
+
* no methods contributes nothing, so `createVList(config)` stays exactly `VList<T>`.
|
|
244
|
+
*/
|
|
245
|
+
export type PluginMethods<P extends readonly unknown[]> = UnionToIntersection<MethodsOf<P[number]>>;
|
|
156
246
|
export interface VList<T extends VListItem = VListItem> {
|
|
157
247
|
readonly element: HTMLElement;
|
|
158
248
|
readonly items: readonly T[];
|
|
@@ -176,7 +266,6 @@ export interface VList<T extends VListItem = VListItem> {
|
|
|
176
266
|
on<K extends keyof import("../types").VListEvents<T>>(event: K, handler: import("../types").EventHandler<import("../types").VListEvents<T>[K]>): import("../types").Unsubscribe;
|
|
177
267
|
off<K extends keyof import("../types").VListEvents<T>>(event: K, handler: import("../types").EventHandler<import("../types").VListEvents<T>[K]>): void;
|
|
178
268
|
destroy(): void;
|
|
179
|
-
[key: string]: unknown;
|
|
180
269
|
}
|
|
181
270
|
export interface CreateVListConfig<T extends VListItem = VListItem> {
|
|
182
271
|
container: HTMLElement | string;
|
|
@@ -192,4 +281,5 @@ export interface CreateVListConfig<T extends VListItem = VListItem> {
|
|
|
192
281
|
/** Defer initial render to the next animation frame. */
|
|
193
282
|
defer?: boolean;
|
|
194
283
|
}
|
|
284
|
+
export {};
|
|
195
285
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/core/velocity.d.ts
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -12,7 +12,9 @@ export { createVList } from "./core/create";
|
|
|
12
12
|
export { scrollbar } from "./plugins/scrollbar";
|
|
13
13
|
export type { ScrollbarPluginConfig } from "./plugins/scrollbar";
|
|
14
14
|
export { grid } from "./plugins/grid";
|
|
15
|
+
export type { GridPluginConfig } from "./plugins/grid";
|
|
15
16
|
export { a11y } from "./plugins/a11y";
|
|
17
|
+
export type { A11yPluginConfig } from "./plugins/a11y";
|
|
16
18
|
export { selection } from "./plugins/selection";
|
|
17
19
|
export type { SelectionPluginConfig } from "./plugins/selection";
|
|
18
20
|
export { page } from "./plugins/page";
|
|
@@ -39,10 +41,23 @@ export { search, DEFAULT_SEARCH_TEXT } from "./plugins/search";
|
|
|
39
41
|
export type { SearchPluginConfig, SearchText } from "./plugins/search";
|
|
40
42
|
export { carousel, registerPreset, getPreset, resolvePreset, full, hero, heroCenter, multi, uncontained } from "./plugins/carousel";
|
|
41
43
|
export type { CarouselPluginConfig, CarouselVariant, CarouselDirection, CarouselState, SlotConfig, SlotConfigResolver, TextFade } from "./plugins/carousel";
|
|
44
|
+
export type { AutosizeMethods } from "./plugins/autosize";
|
|
45
|
+
export type { CarouselMethods } from "./plugins/carousel";
|
|
46
|
+
export type { DataMethods } from "./plugins/data";
|
|
47
|
+
export type { GridMethods } from "./plugins/grid";
|
|
48
|
+
export type { GroupsMethods } from "./plugins/groups";
|
|
49
|
+
export type { MasonryMethods } from "./plugins/masonry";
|
|
50
|
+
export type { ScrollbarMethods } from "./plugins/scrollbar";
|
|
51
|
+
export type { SearchMethods } from "./plugins/search";
|
|
52
|
+
export type { SelectionMethods } from "./plugins/selection";
|
|
53
|
+
export type { SnapshotsMethods } from "./plugins/snapshots";
|
|
54
|
+
export type { SortableMethods } from "./plugins/sortable";
|
|
55
|
+
export type { TableMethods } from "./plugins/table";
|
|
56
|
+
export type { TreeMethods } from "./plugins/tree";
|
|
42
57
|
export { createStats } from "./utils/stats";
|
|
43
58
|
export type { Stats, StatsConfig, StatsState } from "./utils/stats";
|
|
44
59
|
export { rebuild } from "./utils/rebuild";
|
|
45
60
|
export type { RebuildOptions } from "./utils/rebuild";
|
|
46
|
-
export type { VListItem, VListEvents, ItemConfig, ItemTemplate, ItemState, SelectionMode, SelectionConfig, SelectionState,
|
|
47
|
-
export type { Axis, AxisConfig, VList, VListPlugin, PluginContext, CreateVListConfig, CompiledHooks, ResolvedConfig, DOMStructure, ElementPool, } from "./core/types";
|
|
61
|
+
export type { VListItem, VListEvents, ItemConfig, ItemTemplate, ItemState, SelectionMode, SelectionConfig, SelectionState, ScrollbarPadding, ScrollbarOptions, ScrollConfig, ScrollToOptions, ScrollSnapshot, VListAdapter, AdapterParams, AdapterResponse, Range, ViewportState, EventHandler, Unsubscribe, GridConfig, MasonryConfig, GroupsConfig, GroupHeaderConfig, GridSizeContext, GridHeightContext, TreeState, } from "./types";
|
|
62
|
+
export type { Axis, AxisConfig, VList, VListPlugin, PluginMethods, PluginContext, CreateVListConfig, CompiledHooks, ResolvedConfig, DOMStructure, ElementPool, } from "./core/types";
|
|
48
63
|
//# sourceMappingURL=index.d.ts.map
|