@joewinke/jatui 0.26.0 → 0.27.1
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/CLAUDE.md +106 -1
- package/dist/actions/keyboardScope.d.ts +58 -0
- package/dist/actions/keyboardScope.js +110 -0
- package/dist/actions/listNav.d.ts +48 -3
- package/dist/actions/listNav.js +267 -77
- package/dist/actions/longpress.d.ts +37 -0
- package/dist/actions/longpress.js +105 -0
- package/dist/actions/stickToBottom.d.ts +66 -0
- package/dist/actions/stickToBottom.js +155 -0
- package/dist/actions/swipe.d.ts +64 -0
- package/dist/actions/swipe.js +179 -0
- package/dist/components/BottomSheet.svelte +280 -0
- package/dist/components/BottomSheet.svelte.d.ts +27 -0
- package/dist/components/ConfirmDialog.svelte +21 -0
- package/dist/components/ConfirmDialog.svelte.d.ts +11 -1
- package/dist/components/ConfirmModal.svelte +15 -0
- package/dist/components/ConfirmModal.svelte.d.ts +5 -0
- package/dist/components/Drawer.svelte +18 -1
- package/dist/components/Drawer.svelte.d.ts +9 -1
- package/dist/components/InputDialog.svelte +21 -0
- package/dist/components/InputDialog.svelte.d.ts +11 -1
- package/dist/components/Modal.svelte +18 -1
- package/dist/components/Modal.svelte.d.ts +8 -0
- package/dist/components/basic/Empty.svelte +173 -9
- package/dist/components/basic/Empty.svelte.d.ts +50 -1
- package/dist/components/basic/ErrorState.svelte +128 -0
- package/dist/components/basic/ErrorState.svelte.d.ts +46 -0
- package/dist/components/basic/JumpToLatest.svelte +60 -0
- package/dist/components/basic/JumpToLatest.svelte.d.ts +9 -0
- package/dist/components/basic/PageHeader.svelte +216 -0
- package/dist/components/basic/PageHeader.svelte.d.ts +52 -0
- package/dist/components/basic/ProgressButton.svelte +221 -0
- package/dist/components/basic/ProgressButton.svelte.d.ts +63 -0
- package/dist/components/graph/GraphApiBridge.svelte +36 -0
- package/dist/components/graph/GraphApiBridge.svelte.d.ts +9 -0
- package/dist/components/graph/GraphCanvas.svelte +212 -27
- package/dist/components/graph/GraphCanvas.svelte.d.ts +113 -19
- package/dist/components/graph/api.d.ts +52 -0
- package/dist/components/graph/api.js +66 -0
- package/dist/components/graph/index.d.ts +2 -0
- package/dist/components/graph/index.js +1 -0
- package/dist/components/graph/theme.js +13 -0
- package/dist/components/messaging/MessageItem.svelte +5 -0
- package/dist/components/messaging/MessageItem.svelte.d.ts +7 -0
- package/dist/components/table/DataTable.svelte +452 -78
- package/dist/components/table/DataTable.svelte.d.ts +2 -2
- package/dist/components/table/ManageColumnsDropdown.svelte +466 -0
- package/dist/components/table/ManageColumnsDropdown.svelte.d.ts +26 -0
- package/dist/components/table/columnStorage.d.ts +29 -0
- package/dist/components/table/columnStorage.js +61 -0
- package/dist/components/table/groupRows.d.ts +72 -0
- package/dist/components/table/groupRows.js +118 -0
- package/dist/components/table/index.d.ts +7 -1
- package/dist/components/table/index.js +3 -0
- package/dist/components/table/types.d.ts +121 -20
- package/dist/index.d.ts +24 -2
- package/dist/index.js +36 -1
- package/dist/utils/ansiToHtml.d.ts +83 -0
- package/dist/utils/ansiToHtml.js +543 -0
- package/dist/utils/keyboardShortcutRegistry.d.ts +332 -11
- package/dist/utils/keyboardShortcutRegistry.js +1070 -76
- package/dist/utils/pollBackoff.d.ts +83 -0
- package/dist/utils/pollBackoff.js +151 -0
- package/dist/utils/snapFlick.d.ts +59 -0
- package/dist/utils/snapFlick.js +66 -0
- package/dist/video/advisors/qr.d.ts +1 -1
- package/dist/virtual/createRowWindow.d.ts +75 -0
- package/dist/virtual/createRowWindow.js +129 -0
- package/dist/virtual/index.d.ts +4 -0
- package/dist/virtual/index.js +5 -0
- package/dist/virtual/rowWindowCore.d.ts +202 -0
- package/dist/virtual/rowWindowCore.js +510 -0
- package/package.json +12 -2
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* rowWindowCore — the framework-free engine behind `createRowWindow`
|
|
3
|
+
* (jatui-u6d4e.1, spec: jat docs/design/datatable-virtualisation-group-rows.md §3.1).
|
|
4
|
+
*
|
|
5
|
+
* Variable-height windowing for SPACER-ROW layouts: the consumer renders
|
|
6
|
+
* `paddingTop` px of spacer, the rendered slice in document flow, then
|
|
7
|
+
* `paddingBottom` px of spacer. Nothing is absolutely positioned, so a
|
|
8
|
+
* `<table>` keeps `table-layout: fixed` widths and native sticky `<thead>`s.
|
|
9
|
+
*
|
|
10
|
+
* Layering:
|
|
11
|
+
* - Pure helpers (`normalizeStickyLevels`, `activeStickyIndices`,
|
|
12
|
+
* `extractWindowIndices`, `layoutWindow`, `findScrollRoot`) hold the
|
|
13
|
+
* window policy — threshold, pinned keys, sticky group headers, spacer
|
|
14
|
+
* maths. DOM-free, so `npm run test:unit` covers them under node:test.
|
|
15
|
+
* - `RowWindowEngine` drives `@tanstack/virtual-core` (an OPTIONAL peer,
|
|
16
|
+
* which is why this module only ships behind `@joewinke/jatui/virtual`)
|
|
17
|
+
* for measured sizes, scroll-offset tracking and scroll-anchor correction
|
|
18
|
+
* when a row above the viewport changes height.
|
|
19
|
+
* - `createRowWindow.svelte.ts` is the thin runes wrapper.
|
|
20
|
+
*/
|
|
21
|
+
import { type Range, type VirtualItem } from '@tanstack/virtual-core';
|
|
22
|
+
export type RowWindowAlign = 'auto' | 'start' | 'center' | 'end';
|
|
23
|
+
/** One rendered item of the window. */
|
|
24
|
+
export interface RowWindowItem<K = string> {
|
|
25
|
+
/** Index in the render list. */
|
|
26
|
+
index: number;
|
|
27
|
+
key: K;
|
|
28
|
+
/** Offset from the top of the anchor, px. */
|
|
29
|
+
start: number;
|
|
30
|
+
/** Measured height, or the estimate until the row has been measured. */
|
|
31
|
+
size: number;
|
|
32
|
+
/** `start + size`. */
|
|
33
|
+
end: number;
|
|
34
|
+
/**
|
|
35
|
+
* Spacer to render immediately BEFORE this item, px. Always 0 for the
|
|
36
|
+
* first item (that gap is `paddingTop`) and 0 between neighbours of a
|
|
37
|
+
* contiguous slice. Non-zero only when a pinned item or an active sticky
|
|
38
|
+
* header sits outside the visible slice, so the consumer can keep every
|
|
39
|
+
* item at its true offset.
|
|
40
|
+
*/
|
|
41
|
+
gapBefore: number;
|
|
42
|
+
/** The item is one of `stickyIndices` (a group header). */
|
|
43
|
+
sticky: boolean;
|
|
44
|
+
/** The item's key is in `pinned`. */
|
|
45
|
+
pinned: boolean;
|
|
46
|
+
}
|
|
47
|
+
export interface RowWindowSnapshot<K = string> {
|
|
48
|
+
items: ReadonlyArray<RowWindowItem<K>>;
|
|
49
|
+
/** Spacer above the first rendered item, px. */
|
|
50
|
+
paddingTop: number;
|
|
51
|
+
/** Spacer below the last rendered item, px. */
|
|
52
|
+
paddingBottom: number;
|
|
53
|
+
/** Height of the whole list (measured where known, estimated elsewhere), px. */
|
|
54
|
+
totalSize: number;
|
|
55
|
+
/** False when `count < threshold` and every item is rendered. */
|
|
56
|
+
windowed: boolean;
|
|
57
|
+
/** Number of items in the render list. */
|
|
58
|
+
count: number;
|
|
59
|
+
}
|
|
60
|
+
export declare const EMPTY_SNAPSHOT: RowWindowSnapshot<never>;
|
|
61
|
+
/**
|
|
62
|
+
* `stickyIndices` accepts one flat list (one header level) or one list per
|
|
63
|
+
* level, outermost first (`[projectHeaderIdx[], epicHeaderIdx[]]`). Returns the
|
|
64
|
+
* per-level form, each level sorted ascending with out-of-range entries dropped.
|
|
65
|
+
*/
|
|
66
|
+
export declare function normalizeStickyLevels(input: readonly number[] | readonly (readonly number[])[] | null | undefined, count: number): number[][];
|
|
67
|
+
/**
|
|
68
|
+
* The sticky header that is "active" at `startIndex` (the first visible item),
|
|
69
|
+
* per level. For level n it is the last level-n header at or above
|
|
70
|
+
* `startIndex` that comes AFTER level n-1's active header, so an epic header
|
|
71
|
+
* from the previous project never sticks under the current project's header.
|
|
72
|
+
*/
|
|
73
|
+
export declare function activeStickyIndices(levels: readonly (readonly number[])[], startIndex: number): number[];
|
|
74
|
+
export interface WindowPolicy {
|
|
75
|
+
/** Below this count, render everything. 0 = always window. */
|
|
76
|
+
threshold: number;
|
|
77
|
+
/** Indices that must render regardless of scroll position. */
|
|
78
|
+
pinnedIndices: readonly number[];
|
|
79
|
+
/** Sticky header indices per level (see `normalizeStickyLevels`). */
|
|
80
|
+
stickyLevels: readonly (readonly number[])[];
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The rangeExtractor: which indices to render for a visible `range`. The
|
|
84
|
+
* visible slice plus overscan, every pinned index, and the active sticky
|
|
85
|
+
* header of each level, sorted and de-duplicated. Below `threshold`, all.
|
|
86
|
+
*/
|
|
87
|
+
export declare function extractWindowIndices(range: Range, policy: WindowPolicy): number[];
|
|
88
|
+
/**
|
|
89
|
+
* Turn virtual-core's measured items (absolute offsets that include
|
|
90
|
+
* `scrollMargin`) into the spacer-row snapshot the consumer renders.
|
|
91
|
+
*/
|
|
92
|
+
export declare function layoutWindow<K>(virtualItems: readonly Pick<VirtualItem, 'index' | 'key' | 'start' | 'size'>[], opts: {
|
|
93
|
+
scrollMargin: number;
|
|
94
|
+
totalSize: number;
|
|
95
|
+
count: number;
|
|
96
|
+
windowed: boolean;
|
|
97
|
+
stickySet: ReadonlySet<number>;
|
|
98
|
+
pinnedSet: ReadonlySet<number>;
|
|
99
|
+
}): RowWindowSnapshot<K>;
|
|
100
|
+
/** Cheap structural equality so unchanged layouts don't churn reactive state. */
|
|
101
|
+
export declare function sameSnapshot<K>(a: RowWindowSnapshot<K>, b: RowWindowSnapshot<K>): boolean;
|
|
102
|
+
/** Minimal structural view of an element, so `findScrollRoot` is testable without a DOM. */
|
|
103
|
+
export interface ScrollRootCandidate {
|
|
104
|
+
parentElement: ScrollRootCandidate | null;
|
|
105
|
+
scrollHeight: number;
|
|
106
|
+
clientHeight: number;
|
|
107
|
+
tagName: string;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* `scrollRoot: 'auto'` — the nearest ancestor that actually scrolls
|
|
111
|
+
* vertically: `overflow-y` is auto/scroll/overlay AND its content overflows it.
|
|
112
|
+
* An `overflow-auto` wrapper that grows with its content never scrolls (the
|
|
113
|
+
* dash TaskTable case), so it is skipped in favour of the real scroller.
|
|
114
|
+
* Returns `null` for "the window".
|
|
115
|
+
*/
|
|
116
|
+
export declare function findScrollRoot<E extends ScrollRootCandidate>(node: E, overflowY: (el: E) => string): E | null;
|
|
117
|
+
export interface RowWindowEngineOptions {
|
|
118
|
+
/** Extra items rendered above and below the viewport. */
|
|
119
|
+
overscan: number;
|
|
120
|
+
/** Below this count, render everything. 0 = always window. */
|
|
121
|
+
threshold: number;
|
|
122
|
+
/** The scroller. `'auto'` resolves on attach (see `findScrollRoot`). */
|
|
123
|
+
scrollRoot: HTMLElement | Window | 'auto';
|
|
124
|
+
/** Viewport height assumed before the anchor mounts (SSR / first paint), px. */
|
|
125
|
+
initialViewportSize: number;
|
|
126
|
+
/** Space a sticky header covers at the top, honoured by `scrollTo*`. */
|
|
127
|
+
scrollPaddingStart: number;
|
|
128
|
+
scrollPaddingEnd: number;
|
|
129
|
+
/** Called whenever the rendered layout changes. */
|
|
130
|
+
onChange?: (snapshot: RowWindowSnapshot<unknown>) => void;
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Imperative windowing engine. One per list. Feed it the render list with
|
|
134
|
+
* `setItems`, mount it with `attach(anchor)`, register each rendered element
|
|
135
|
+
* with `measure`, and read `snapshot` (or listen via `onChange`).
|
|
136
|
+
*/
|
|
137
|
+
export declare class RowWindowEngine<K = string> {
|
|
138
|
+
private readonly opts;
|
|
139
|
+
private readonly v;
|
|
140
|
+
private keys;
|
|
141
|
+
private estimates;
|
|
142
|
+
private keyIndex;
|
|
143
|
+
private getItemKey;
|
|
144
|
+
private estimateSize;
|
|
145
|
+
private pinnedKeys;
|
|
146
|
+
private pinnedIndices;
|
|
147
|
+
private pinnedSet;
|
|
148
|
+
private stickyInput;
|
|
149
|
+
private stickyLevels;
|
|
150
|
+
private stickySet;
|
|
151
|
+
private rangeExtractor;
|
|
152
|
+
private scrollMargin;
|
|
153
|
+
private anchorEl;
|
|
154
|
+
private root;
|
|
155
|
+
private rootUnsub;
|
|
156
|
+
private anchorRO;
|
|
157
|
+
private prevOverflowAnchor;
|
|
158
|
+
private unmountVirtualizer;
|
|
159
|
+
private nodes;
|
|
160
|
+
private pendingScroll;
|
|
161
|
+
private sweepQueued;
|
|
162
|
+
private destroyed;
|
|
163
|
+
snapshot: RowWindowSnapshot<K>;
|
|
164
|
+
constructor(opts: RowWindowEngineOptions);
|
|
165
|
+
/** Replace the render list. `keys[i]` must be unique. */
|
|
166
|
+
setItems(keys: readonly K[], estimates: readonly number[]): void;
|
|
167
|
+
setPinned(keys: Iterable<K>): void;
|
|
168
|
+
/** Change the render-everything threshold. */
|
|
169
|
+
setThreshold(threshold: number): void;
|
|
170
|
+
setSticky(input: readonly number[] | readonly (readonly number[])[]): void;
|
|
171
|
+
private resolvePinned;
|
|
172
|
+
private rebuildRangeExtractor;
|
|
173
|
+
private buildOptions;
|
|
174
|
+
/** Push current inputs into virtual-core and recompute the snapshot. */
|
|
175
|
+
private sync;
|
|
176
|
+
private emit;
|
|
177
|
+
/** Mount on the element whose top is item 0's top (a `<tbody>` or list container). */
|
|
178
|
+
attach(anchor: HTMLElement): void;
|
|
179
|
+
detach(): void;
|
|
180
|
+
destroy(): void;
|
|
181
|
+
private resolveRoot;
|
|
182
|
+
private bindRoot;
|
|
183
|
+
/** The anchor or root resized: re-resolve an 'auto' root, refresh the margin. */
|
|
184
|
+
private onLayoutShift;
|
|
185
|
+
/** Distance from the scroller's content top to the anchor's top. */
|
|
186
|
+
private updateScrollMargin;
|
|
187
|
+
/** Register a rendered item element. Re-measured on every resize. */
|
|
188
|
+
measure(node: HTMLElement, key: K): void;
|
|
189
|
+
/** Forget an item element (it unmounted, or its key changed). */
|
|
190
|
+
unmeasure(node: HTMLElement, key: K): void;
|
|
191
|
+
private queueSweep;
|
|
192
|
+
scrollToIndex(index: number, opts?: {
|
|
193
|
+
align?: RowWindowAlign;
|
|
194
|
+
}): void;
|
|
195
|
+
scrollToKey(key: K, opts?: {
|
|
196
|
+
align?: RowWindowAlign;
|
|
197
|
+
}): void;
|
|
198
|
+
/** Index of `key` in the render list, or -1. */
|
|
199
|
+
indexOf(key: K): number;
|
|
200
|
+
/** Drop every cached measurement (e.g. after a column-width change). */
|
|
201
|
+
remeasure(): void;
|
|
202
|
+
}
|