@pretable/react 0.0.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/dist/index.cjs +1421 -0
- package/dist/index.d.cts +240 -0
- package/dist/index.d.ts +240 -0
- package/dist/index.mjs +1412 -0
- package/package.json +42 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,1412 @@
|
|
|
1
|
+
import { useMemo, useSyncExternalStore, useLayoutEffect, useRef, useCallback, useState, createElement } from 'react';
|
|
2
|
+
import { createGrid } from '@pretable/core';
|
|
3
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// src/pretable-surface.tsx
|
|
6
|
+
|
|
7
|
+
// src/row-height.ts
|
|
8
|
+
var MIN_ROW_HEIGHT = 44;
|
|
9
|
+
function parsePxLength(value) {
|
|
10
|
+
if (!value) {
|
|
11
|
+
return 0;
|
|
12
|
+
}
|
|
13
|
+
const parsed = parseFloat(value);
|
|
14
|
+
return Number.isFinite(parsed) ? parsed : 0;
|
|
15
|
+
}
|
|
16
|
+
function measureRenderedRowHeight(row) {
|
|
17
|
+
const style = getComputedStyle(row);
|
|
18
|
+
const verticalPadding = parsePxLength(style.paddingTop) + parsePxLength(style.paddingBottom);
|
|
19
|
+
const borderHeight = parsePxLength(style.borderBottomWidth);
|
|
20
|
+
const wrappedCells = [
|
|
21
|
+
...row.querySelectorAll(
|
|
22
|
+
'[data-pretable-cell][data-pretable-wrap="true"]'
|
|
23
|
+
)
|
|
24
|
+
];
|
|
25
|
+
const measuredCells = wrappedCells.length > 0 ? wrappedCells : [...row.querySelectorAll("[data-pretable-cell]")];
|
|
26
|
+
const contentHeight = Math.max(
|
|
27
|
+
0,
|
|
28
|
+
...measuredCells.map((cell) => cell.scrollHeight).filter(Number.isFinite)
|
|
29
|
+
);
|
|
30
|
+
return Math.max(
|
|
31
|
+
MIN_ROW_HEIGHT,
|
|
32
|
+
Math.ceil(contentHeight + verticalPadding + borderHeight)
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ../layout-core/dist/prefix-sums.js
|
|
37
|
+
function createRowMetricsIndex(estimatedHeights) {
|
|
38
|
+
return new PrefixSumsRowMetricsIndex(estimatedHeights);
|
|
39
|
+
}
|
|
40
|
+
var PrefixSumsRowMetricsIndex = class {
|
|
41
|
+
rowCount;
|
|
42
|
+
#heights;
|
|
43
|
+
#starts;
|
|
44
|
+
#totalHeight;
|
|
45
|
+
constructor(estimatedHeights) {
|
|
46
|
+
this.rowCount = estimatedHeights.length;
|
|
47
|
+
this.#heights = estimatedHeights.map((height) => normalizeHeight(height));
|
|
48
|
+
this.#starts = [0];
|
|
49
|
+
for (const height of this.#heights) {
|
|
50
|
+
this.#starts.push((this.#starts.at(-1) ?? 0) + height);
|
|
51
|
+
}
|
|
52
|
+
this.#totalHeight = this.#starts.at(-1) ?? 0;
|
|
53
|
+
}
|
|
54
|
+
getHeight(index) {
|
|
55
|
+
return this.#heights[index] ?? 0;
|
|
56
|
+
}
|
|
57
|
+
getOffsetForIndex(index) {
|
|
58
|
+
if (index <= 0) {
|
|
59
|
+
return 0;
|
|
60
|
+
}
|
|
61
|
+
if (index >= this.rowCount) {
|
|
62
|
+
return this.#totalHeight;
|
|
63
|
+
}
|
|
64
|
+
return this.#starts[index] ?? this.#totalHeight;
|
|
65
|
+
}
|
|
66
|
+
getIndexForOffset(offset) {
|
|
67
|
+
if (this.rowCount === 0 || offset <= 0) {
|
|
68
|
+
return 0;
|
|
69
|
+
}
|
|
70
|
+
if (offset >= this.#totalHeight) {
|
|
71
|
+
return this.rowCount;
|
|
72
|
+
}
|
|
73
|
+
let low = 0;
|
|
74
|
+
let high = this.rowCount - 1;
|
|
75
|
+
while (low <= high) {
|
|
76
|
+
const middle = Math.floor((low + high) / 2);
|
|
77
|
+
const start = this.#starts[middle] ?? 0;
|
|
78
|
+
const end = this.#starts[middle + 1] ?? this.#totalHeight;
|
|
79
|
+
if (offset < start) {
|
|
80
|
+
high = middle - 1;
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (offset >= end) {
|
|
84
|
+
low = middle + 1;
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
return middle;
|
|
88
|
+
}
|
|
89
|
+
return Math.min(this.rowCount, low);
|
|
90
|
+
}
|
|
91
|
+
getTotalHeight() {
|
|
92
|
+
return this.#totalHeight;
|
|
93
|
+
}
|
|
94
|
+
updateHeight(index, height) {
|
|
95
|
+
const nextHeight = normalizeHeight(height);
|
|
96
|
+
const previousHeight = this.#heights[index];
|
|
97
|
+
if (previousHeight === void 0) {
|
|
98
|
+
throw new RangeError(`Row index ${index} is out of bounds.`);
|
|
99
|
+
}
|
|
100
|
+
const delta = nextHeight - previousHeight;
|
|
101
|
+
if (delta === 0) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
this.#heights[index] = nextHeight;
|
|
105
|
+
for (let startIndex = index + 1; startIndex < this.#starts.length; startIndex += 1) {
|
|
106
|
+
this.#starts[startIndex] = (this.#starts[startIndex] ?? 0) + delta;
|
|
107
|
+
}
|
|
108
|
+
this.#totalHeight += delta;
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
function normalizeHeight(height) {
|
|
112
|
+
return Math.max(1, Math.round(height));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// ../layout-core/dist/column-plan.js
|
|
116
|
+
function planColumns(input) {
|
|
117
|
+
const pinned = [];
|
|
118
|
+
const scrollable = [];
|
|
119
|
+
let pinnedLeftWidth = 0;
|
|
120
|
+
let scrollableLeft = 0;
|
|
121
|
+
for (let i = 0; i < input.columns.length; i++) {
|
|
122
|
+
const col = input.columns[i];
|
|
123
|
+
if (col.pinned === "left") {
|
|
124
|
+
pinned.push({
|
|
125
|
+
index: i,
|
|
126
|
+
id: col.id,
|
|
127
|
+
left: pinnedLeftWidth,
|
|
128
|
+
width: col.width,
|
|
129
|
+
pinned: "left"
|
|
130
|
+
});
|
|
131
|
+
pinnedLeftWidth += col.width;
|
|
132
|
+
} else {
|
|
133
|
+
scrollable.push({
|
|
134
|
+
index: i,
|
|
135
|
+
id: col.id,
|
|
136
|
+
width: col.width,
|
|
137
|
+
left: scrollableLeft
|
|
138
|
+
});
|
|
139
|
+
scrollableLeft += col.width;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const totalWidth = pinnedLeftWidth + scrollableLeft;
|
|
143
|
+
if (scrollable.length === 0) {
|
|
144
|
+
return { columns: pinned, totalWidth, pinnedLeftWidth };
|
|
145
|
+
}
|
|
146
|
+
let low = 0;
|
|
147
|
+
let high = scrollable.length - 1;
|
|
148
|
+
let visibleStart = scrollable.length;
|
|
149
|
+
while (low <= high) {
|
|
150
|
+
const mid = Math.floor((low + high) / 2);
|
|
151
|
+
const colRight = scrollable[mid].left + scrollable[mid].width + pinnedLeftWidth;
|
|
152
|
+
if (colRight <= input.scrollLeft) {
|
|
153
|
+
low = mid + 1;
|
|
154
|
+
} else {
|
|
155
|
+
visibleStart = mid;
|
|
156
|
+
high = mid - 1;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
let visibleEnd = visibleStart;
|
|
160
|
+
const scrollRight = input.scrollLeft + input.viewportWidth;
|
|
161
|
+
while (visibleEnd < scrollable.length) {
|
|
162
|
+
const colLeft = scrollable[visibleEnd].left + pinnedLeftWidth;
|
|
163
|
+
if (colLeft >= scrollRight) {
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
visibleEnd++;
|
|
167
|
+
}
|
|
168
|
+
const overscanStart = Math.max(0, visibleStart - input.overscan);
|
|
169
|
+
const overscanEnd = Math.min(scrollable.length, visibleEnd + input.overscan);
|
|
170
|
+
const visibleScrollable = [];
|
|
171
|
+
for (let i = overscanStart; i < overscanEnd; i++) {
|
|
172
|
+
const col = scrollable[i];
|
|
173
|
+
visibleScrollable.push({
|
|
174
|
+
index: col.index,
|
|
175
|
+
id: col.id,
|
|
176
|
+
left: col.left + pinnedLeftWidth,
|
|
177
|
+
width: col.width
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
return {
|
|
181
|
+
columns: [...pinned, ...visibleScrollable],
|
|
182
|
+
totalWidth,
|
|
183
|
+
pinnedLeftWidth
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// ../layout-core/dist/viewport-plan.js
|
|
188
|
+
function planViewport(input) {
|
|
189
|
+
const totalHeight = input.rowMetrics.getTotalHeight();
|
|
190
|
+
const rowCount = input.rowMetrics.rowCount;
|
|
191
|
+
if (rowCount === 0) {
|
|
192
|
+
return {
|
|
193
|
+
range: { start: 0, end: 0 },
|
|
194
|
+
rows: [],
|
|
195
|
+
totalHeight,
|
|
196
|
+
pinned: {
|
|
197
|
+
left: planPinnedColumns(input.pinnedLeft ?? [], "left"),
|
|
198
|
+
right: planPinnedColumns(input.pinnedRight ?? [], "right")
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
const clampedScrollTop = Math.max(0, Math.min(input.scrollTop, Math.max(0, totalHeight - 1)));
|
|
203
|
+
const visibleStart = Math.min(rowCount - 1, input.rowMetrics.getIndexForOffset(clampedScrollTop));
|
|
204
|
+
const visibleEndExclusive = Math.min(rowCount, Math.max(visibleStart + 1, input.rowMetrics.getIndexForOffset(clampedScrollTop + Math.max(0, input.viewportHeight)) + 1));
|
|
205
|
+
const start = Math.max(0, visibleStart - Math.max(0, input.overscan));
|
|
206
|
+
const end = Math.min(rowCount, visibleEndExclusive + Math.max(0, input.overscan));
|
|
207
|
+
const rows = [];
|
|
208
|
+
for (let index = start; index < end; index += 1) {
|
|
209
|
+
rows.push({
|
|
210
|
+
index,
|
|
211
|
+
top: input.rowMetrics.getOffsetForIndex(index),
|
|
212
|
+
height: input.rowMetrics.getHeight(index)
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
range: { start, end },
|
|
217
|
+
rows,
|
|
218
|
+
totalHeight,
|
|
219
|
+
pinned: {
|
|
220
|
+
left: planPinnedColumns(input.pinnedLeft ?? [], "left"),
|
|
221
|
+
right: planPinnedColumns(input.pinnedRight ?? [], "right")
|
|
222
|
+
}
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
function planPinnedColumns(columns, side) {
|
|
226
|
+
let offset = 0;
|
|
227
|
+
return columns.map((column) => {
|
|
228
|
+
const planned = {
|
|
229
|
+
...column,
|
|
230
|
+
side,
|
|
231
|
+
start: offset,
|
|
232
|
+
end: offset + column.width
|
|
233
|
+
};
|
|
234
|
+
offset = planned.end;
|
|
235
|
+
return planned;
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// ../text-core/dist/layout-text.js
|
|
240
|
+
var DEFAULT_LINE_HEIGHT_PX = 20;
|
|
241
|
+
function layoutPreparedText(prepared, width, options = {}) {
|
|
242
|
+
const wrapMode = options.wrapMode ?? "wrap";
|
|
243
|
+
const lineHeightPx = options.lineHeightPx ?? DEFAULT_LINE_HEIGHT_PX;
|
|
244
|
+
const paddingBlockPx = options.paddingBlockPx ?? 0;
|
|
245
|
+
const explicitLineCount = countExplicitLines(prepared.tokens);
|
|
246
|
+
if (wrapMode === "nowrap") {
|
|
247
|
+
return buildLayout({
|
|
248
|
+
lineCount: explicitLineCount,
|
|
249
|
+
lineHeightPx,
|
|
250
|
+
paddingBlockPx,
|
|
251
|
+
measuredWidth: prepared.graphemeCount * prepared.averageCharWidth,
|
|
252
|
+
overflowX: prepared.graphemeCount * prepared.averageCharWidth > width
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
const charsPerLine = Math.max(1, Math.floor(width / prepared.averageCharWidth));
|
|
256
|
+
const { lineCount, maxLineChars } = wrapTokens(prepared.tokens, charsPerLine);
|
|
257
|
+
return buildLayout({
|
|
258
|
+
lineCount,
|
|
259
|
+
lineHeightPx,
|
|
260
|
+
paddingBlockPx,
|
|
261
|
+
measuredWidth: Math.min(width, maxLineChars * prepared.averageCharWidth),
|
|
262
|
+
overflowX: false
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
function countExplicitLines(tokens) {
|
|
266
|
+
return tokens.reduce((count, token) => count + (token.kind === "newline" ? 1 : 0), 1);
|
|
267
|
+
}
|
|
268
|
+
function wrapTokens(tokens, charsPerLine) {
|
|
269
|
+
let lineCount = 1;
|
|
270
|
+
let currentLineChars = 0;
|
|
271
|
+
let maxLineChars = 0;
|
|
272
|
+
const pushLine = () => {
|
|
273
|
+
maxLineChars = Math.max(maxLineChars, currentLineChars);
|
|
274
|
+
lineCount += 1;
|
|
275
|
+
currentLineChars = 0;
|
|
276
|
+
};
|
|
277
|
+
for (const token of tokens) {
|
|
278
|
+
if (token.kind === "newline") {
|
|
279
|
+
maxLineChars = Math.max(maxLineChars, currentLineChars);
|
|
280
|
+
lineCount += 1;
|
|
281
|
+
currentLineChars = 0;
|
|
282
|
+
continue;
|
|
283
|
+
}
|
|
284
|
+
if (token.kind === "space") {
|
|
285
|
+
if (currentLineChars === 0) {
|
|
286
|
+
continue;
|
|
287
|
+
}
|
|
288
|
+
if (currentLineChars + token.length <= charsPerLine) {
|
|
289
|
+
currentLineChars += token.length;
|
|
290
|
+
} else {
|
|
291
|
+
pushLine();
|
|
292
|
+
}
|
|
293
|
+
continue;
|
|
294
|
+
}
|
|
295
|
+
placeWord(token.length);
|
|
296
|
+
}
|
|
297
|
+
maxLineChars = Math.max(maxLineChars, currentLineChars);
|
|
298
|
+
return { lineCount, maxLineChars };
|
|
299
|
+
function placeWord(wordLength) {
|
|
300
|
+
if (currentLineChars === 0) {
|
|
301
|
+
currentLineChars = placeAtLineStart(wordLength);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
if (currentLineChars + wordLength <= charsPerLine) {
|
|
305
|
+
currentLineChars += wordLength;
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
308
|
+
pushLine();
|
|
309
|
+
currentLineChars = placeAtLineStart(wordLength);
|
|
310
|
+
}
|
|
311
|
+
function placeAtLineStart(wordLength) {
|
|
312
|
+
if (wordLength <= charsPerLine) {
|
|
313
|
+
return wordLength;
|
|
314
|
+
}
|
|
315
|
+
const wrappedLines = Math.ceil(wordLength / charsPerLine);
|
|
316
|
+
lineCount += wrappedLines - 1;
|
|
317
|
+
maxLineChars = Math.max(maxLineChars, charsPerLine);
|
|
318
|
+
return wordLength % charsPerLine || charsPerLine;
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
function buildLayout(input) {
|
|
322
|
+
return {
|
|
323
|
+
lineCount: input.lineCount,
|
|
324
|
+
height: input.lineCount * input.lineHeightPx + input.paddingBlockPx * 2,
|
|
325
|
+
measuredWidth: input.measuredWidth,
|
|
326
|
+
overflowX: input.overflowX
|
|
327
|
+
};
|
|
328
|
+
}
|
|
329
|
+
function prepareText(input) {
|
|
330
|
+
const text = input.text.replaceAll("\r\n", "\n");
|
|
331
|
+
const graphemes = Array.from(text);
|
|
332
|
+
return {
|
|
333
|
+
text,
|
|
334
|
+
fontKey: input.fontKey,
|
|
335
|
+
graphemeCount: graphemes.length,
|
|
336
|
+
breakpoints: collectBreakpoints(graphemes),
|
|
337
|
+
averageCharWidth: input.averageCharWidth,
|
|
338
|
+
tokens: tokenizeText(text)
|
|
339
|
+
};
|
|
340
|
+
}
|
|
341
|
+
function collectBreakpoints(graphemes) {
|
|
342
|
+
const breakpoints = [];
|
|
343
|
+
for (let index = 0; index < graphemes.length; index += 1) {
|
|
344
|
+
const value = graphemes[index];
|
|
345
|
+
if (value === void 0) {
|
|
346
|
+
continue;
|
|
347
|
+
}
|
|
348
|
+
if (/\s/u.test(value) || value === "-" || value === "/" || value === "_") {
|
|
349
|
+
breakpoints.push(index + 1);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
return breakpoints;
|
|
353
|
+
}
|
|
354
|
+
function tokenizeText(text) {
|
|
355
|
+
const matches = text.match(/\n|[^\S\n]+|[^\s]+/gu) ?? [];
|
|
356
|
+
return matches.map((value) => {
|
|
357
|
+
if (value === "\n") {
|
|
358
|
+
return { kind: "newline", value, length: 0 };
|
|
359
|
+
}
|
|
360
|
+
if (/^[^\S\n]+$/u.test(value)) {
|
|
361
|
+
return { kind: "space", value, length: Array.from(value).length };
|
|
362
|
+
}
|
|
363
|
+
return { kind: "word", value, length: Array.from(value).length };
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// ../renderer-dom/dist/create-renderer.js
|
|
368
|
+
var DEFAULT_ROW_HEIGHT = 44;
|
|
369
|
+
var WRAPPED_COLUMN_WIDTH = 220;
|
|
370
|
+
var FIXED_COLUMN_WIDTH = 140;
|
|
371
|
+
var ROW_LINE_HEIGHT = 24;
|
|
372
|
+
var ROW_CHROME_HEIGHT = 42;
|
|
373
|
+
var ESTIMATED_CHARACTER_WIDTH = 7;
|
|
374
|
+
var ESTIMATE_FONT_KEY = "Pretable Estimate 14";
|
|
375
|
+
var estimatedRowHeightCache = /* @__PURE__ */ new WeakMap();
|
|
376
|
+
function createDomRenderSnapshot(input) {
|
|
377
|
+
const rowHeights = input.snapshot.visibleRows.map((entry) => {
|
|
378
|
+
const measuredHeight = input.measuredHeights?.[entry.id];
|
|
379
|
+
return measuredHeight ?? estimateRowHeight(entry.row, input.columns);
|
|
380
|
+
});
|
|
381
|
+
const rowMetrics = createRowMetricsIndex(rowHeights);
|
|
382
|
+
const viewportPlan = planViewport({
|
|
383
|
+
scrollTop: input.scrollTop,
|
|
384
|
+
viewportHeight: input.viewportHeight,
|
|
385
|
+
overscan: input.overscan,
|
|
386
|
+
rowMetrics,
|
|
387
|
+
pinnedLeft: input.columns.filter((column) => column.pinned === "left").map((column) => ({
|
|
388
|
+
columnId: column.id,
|
|
389
|
+
width: getColumnWidth(column)
|
|
390
|
+
}))
|
|
391
|
+
});
|
|
392
|
+
const rows = viewportPlan.rows.flatMap((plannedRow) => {
|
|
393
|
+
const entry = input.snapshot.visibleRows[plannedRow.index];
|
|
394
|
+
if (!entry) {
|
|
395
|
+
return [];
|
|
396
|
+
}
|
|
397
|
+
return [
|
|
398
|
+
{
|
|
399
|
+
id: entry.id,
|
|
400
|
+
row: entry.row,
|
|
401
|
+
rowIndex: plannedRow.index,
|
|
402
|
+
top: plannedRow.top,
|
|
403
|
+
height: plannedRow.height
|
|
404
|
+
}
|
|
405
|
+
];
|
|
406
|
+
});
|
|
407
|
+
const columnInputs = input.columns.map((col) => ({
|
|
408
|
+
id: col.id,
|
|
409
|
+
width: getColumnWidth(col),
|
|
410
|
+
pinned: col.pinned
|
|
411
|
+
}));
|
|
412
|
+
const columnPlan = input.viewportWidth !== void 0 ? planColumns({
|
|
413
|
+
columns: columnInputs,
|
|
414
|
+
scrollLeft: input.scrollLeft ?? 0,
|
|
415
|
+
viewportWidth: input.viewportWidth,
|
|
416
|
+
overscan: input.overscan
|
|
417
|
+
}) : {
|
|
418
|
+
columns: (() => {
|
|
419
|
+
let left = 0;
|
|
420
|
+
return columnInputs.map((col, index) => {
|
|
421
|
+
const entry = {
|
|
422
|
+
index,
|
|
423
|
+
id: col.id,
|
|
424
|
+
left,
|
|
425
|
+
width: col.width,
|
|
426
|
+
pinned: col.pinned
|
|
427
|
+
};
|
|
428
|
+
left += col.width;
|
|
429
|
+
return entry;
|
|
430
|
+
});
|
|
431
|
+
})(),
|
|
432
|
+
totalWidth: columnInputs.reduce((sum, col) => sum + col.width, 0),
|
|
433
|
+
pinnedLeftWidth: columnInputs.filter((col) => col.pinned === "left").reduce((sum, col) => sum + col.width, 0)
|
|
434
|
+
};
|
|
435
|
+
return {
|
|
436
|
+
frame: {
|
|
437
|
+
snapshot: input.snapshot
|
|
438
|
+
},
|
|
439
|
+
rows,
|
|
440
|
+
columns: columnPlan.columns,
|
|
441
|
+
nodeCount: rows.length * columnPlan.columns.length,
|
|
442
|
+
totalHeight: viewportPlan.totalHeight,
|
|
443
|
+
totalWidth: columnPlan.totalWidth
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
function estimateRowHeight(row, columns) {
|
|
447
|
+
const cached = estimatedRowHeightCache.get(row);
|
|
448
|
+
if (cached && cached.columnsRef === columns) {
|
|
449
|
+
return cached.height;
|
|
450
|
+
}
|
|
451
|
+
const signature = getEstimatedRowHeightSignature(row, columns);
|
|
452
|
+
if (cached?.signature === signature) {
|
|
453
|
+
cached.columnsRef = columns;
|
|
454
|
+
return cached.height;
|
|
455
|
+
}
|
|
456
|
+
let estimatedHeight = DEFAULT_ROW_HEIGHT;
|
|
457
|
+
for (const column of columns) {
|
|
458
|
+
if (!column.wrap) {
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
const prepared = prepareText({
|
|
462
|
+
text: String(readCellValue(row, column)),
|
|
463
|
+
fontKey: ESTIMATE_FONT_KEY,
|
|
464
|
+
averageCharWidth: ESTIMATED_CHARACTER_WIDTH
|
|
465
|
+
});
|
|
466
|
+
const layout = layoutPreparedText(prepared, getColumnWidth(column), {
|
|
467
|
+
lineHeightPx: ROW_LINE_HEIGHT,
|
|
468
|
+
wrapMode: "wrap"
|
|
469
|
+
});
|
|
470
|
+
estimatedHeight = Math.max(estimatedHeight, layout.height + ROW_CHROME_HEIGHT);
|
|
471
|
+
}
|
|
472
|
+
estimatedRowHeightCache.set(row, {
|
|
473
|
+
signature,
|
|
474
|
+
height: estimatedHeight,
|
|
475
|
+
columnsRef: columns
|
|
476
|
+
});
|
|
477
|
+
return estimatedHeight;
|
|
478
|
+
}
|
|
479
|
+
function getEstimatedRowHeightSignature(row, columns) {
|
|
480
|
+
return columns.filter((column) => column.wrap).map((column) => {
|
|
481
|
+
const value = String(readCellValue(row, column) ?? "");
|
|
482
|
+
return `${column.id}:${getColumnWidth(column)}:${value}`;
|
|
483
|
+
}).join("|");
|
|
484
|
+
}
|
|
485
|
+
function readCellValue(row, column) {
|
|
486
|
+
return column.getValue ? column.getValue(row) : row[column.id];
|
|
487
|
+
}
|
|
488
|
+
function getColumnWidth(column) {
|
|
489
|
+
return column.widthPx ?? (column.wrap ? WRAPPED_COLUMN_WIDTH : FIXED_COLUMN_WIDTH);
|
|
490
|
+
}
|
|
491
|
+
function usePretable({
|
|
492
|
+
autosize,
|
|
493
|
+
columns,
|
|
494
|
+
rows,
|
|
495
|
+
getRowId
|
|
496
|
+
}) {
|
|
497
|
+
return useMemo(
|
|
498
|
+
() => createGrid({ columns, rows, getRowId, autosize }),
|
|
499
|
+
[autosize, columns, getRowId, rows]
|
|
500
|
+
);
|
|
501
|
+
}
|
|
502
|
+
function usePretableModel({
|
|
503
|
+
autosize,
|
|
504
|
+
columns,
|
|
505
|
+
rows,
|
|
506
|
+
getRowId,
|
|
507
|
+
viewportHeight,
|
|
508
|
+
viewportWidth,
|
|
509
|
+
overscan = 6,
|
|
510
|
+
interactionOverrides,
|
|
511
|
+
measuredHeights
|
|
512
|
+
}) {
|
|
513
|
+
const grid = usePretable({ autosize, columns, rows, getRowId });
|
|
514
|
+
if (interactionOverrides) {
|
|
515
|
+
grid.setSort(
|
|
516
|
+
interactionOverrides.sort?.columnId ?? null,
|
|
517
|
+
interactionOverrides.sort?.direction ?? null
|
|
518
|
+
);
|
|
519
|
+
grid.replaceFilters(interactionOverrides.filters ?? {});
|
|
520
|
+
if (interactionOverrides.focusedRowId !== void 0) {
|
|
521
|
+
const firstColumnId = columns[0]?.id ?? null;
|
|
522
|
+
grid.setFocus(
|
|
523
|
+
interactionOverrides.focusedRowId,
|
|
524
|
+
interactionOverrides.focusedRowId ? firstColumnId : null
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
if (interactionOverrides.selectedRowId !== void 0) {
|
|
528
|
+
grid.selectRow(interactionOverrides.selectedRowId);
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
const snapshot = useSyncExternalStore(
|
|
532
|
+
grid.subscribe,
|
|
533
|
+
grid.getSnapshot,
|
|
534
|
+
grid.getSnapshot
|
|
535
|
+
);
|
|
536
|
+
useLayoutEffect(() => {
|
|
537
|
+
if (snapshot.viewport.height === viewportHeight && snapshot.viewport.width === (viewportWidth ?? 0)) {
|
|
538
|
+
return;
|
|
539
|
+
}
|
|
540
|
+
grid.setViewport({
|
|
541
|
+
scrollTop: snapshot.viewport.scrollTop,
|
|
542
|
+
scrollLeft: snapshot.viewport.scrollLeft,
|
|
543
|
+
height: viewportHeight,
|
|
544
|
+
width: viewportWidth ?? 0
|
|
545
|
+
});
|
|
546
|
+
}, [
|
|
547
|
+
grid,
|
|
548
|
+
snapshot.viewport.height,
|
|
549
|
+
snapshot.viewport.width,
|
|
550
|
+
snapshot.viewport.scrollTop,
|
|
551
|
+
snapshot.viewport.scrollLeft,
|
|
552
|
+
viewportHeight,
|
|
553
|
+
viewportWidth
|
|
554
|
+
]);
|
|
555
|
+
const renderSnapshot = useMemo(
|
|
556
|
+
() => createDomRenderSnapshot({
|
|
557
|
+
columns: grid.options.columns,
|
|
558
|
+
snapshot,
|
|
559
|
+
scrollTop: snapshot.viewport.scrollTop,
|
|
560
|
+
scrollLeft: snapshot.viewport.scrollLeft,
|
|
561
|
+
viewportHeight,
|
|
562
|
+
viewportWidth,
|
|
563
|
+
overscan,
|
|
564
|
+
measuredHeights
|
|
565
|
+
}),
|
|
566
|
+
[
|
|
567
|
+
grid.options.columns,
|
|
568
|
+
measuredHeights,
|
|
569
|
+
overscan,
|
|
570
|
+
snapshot,
|
|
571
|
+
viewportHeight,
|
|
572
|
+
viewportWidth
|
|
573
|
+
]
|
|
574
|
+
);
|
|
575
|
+
const telemetry = useMemo(() => {
|
|
576
|
+
const viewportBottom = snapshot.viewport.scrollTop + Math.max(snapshot.viewport.height, viewportHeight);
|
|
577
|
+
const viewportRows = renderSnapshot.rows.filter((row) => {
|
|
578
|
+
const rowBottom = row.top + row.height;
|
|
579
|
+
return row.top < viewportBottom && rowBottom > snapshot.viewport.scrollTop;
|
|
580
|
+
});
|
|
581
|
+
const firstVisibleRow = viewportRows[0];
|
|
582
|
+
const lastVisibleRow = viewportRows[viewportRows.length - 1];
|
|
583
|
+
return {
|
|
584
|
+
focusedRowId: snapshot.focus.rowId,
|
|
585
|
+
rowModelRowCount: snapshot.visibleRows.length,
|
|
586
|
+
renderedRowCount: renderSnapshot.rows.length,
|
|
587
|
+
selectedRowId: snapshot.selection.rowIds[0] ?? null,
|
|
588
|
+
totalRowCount: snapshot.totalRowCount,
|
|
589
|
+
totalHeight: renderSnapshot.totalHeight,
|
|
590
|
+
visibleRowCount: viewportRows.length,
|
|
591
|
+
visibleRowRange: firstVisibleRow && lastVisibleRow ? {
|
|
592
|
+
start: firstVisibleRow.rowIndex,
|
|
593
|
+
end: lastVisibleRow.rowIndex + 1
|
|
594
|
+
} : {
|
|
595
|
+
start: 0,
|
|
596
|
+
end: 0
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
}, [
|
|
600
|
+
renderSnapshot.rows,
|
|
601
|
+
renderSnapshot.totalHeight,
|
|
602
|
+
snapshot.focus.rowId,
|
|
603
|
+
snapshot.visibleRows.length,
|
|
604
|
+
snapshot.selection.rowIds,
|
|
605
|
+
snapshot.totalRowCount,
|
|
606
|
+
snapshot.viewport.height,
|
|
607
|
+
snapshot.viewport.scrollTop,
|
|
608
|
+
viewportHeight
|
|
609
|
+
]);
|
|
610
|
+
return {
|
|
611
|
+
grid,
|
|
612
|
+
snapshot,
|
|
613
|
+
renderSnapshot,
|
|
614
|
+
telemetry
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
// src/rendering.ts
|
|
619
|
+
var DEFAULT_ROW_HEIGHT2 = 44;
|
|
620
|
+
var DEFAULT_WRAPPED_COLUMN_WIDTH = 220;
|
|
621
|
+
var DEFAULT_FIXED_COLUMN_WIDTH = 140;
|
|
622
|
+
var HEADER_HEIGHT = 52;
|
|
623
|
+
function getColumnWidth2(column) {
|
|
624
|
+
return column.widthPx ?? (column.wrap ? DEFAULT_WRAPPED_COLUMN_WIDTH : DEFAULT_FIXED_COLUMN_WIDTH);
|
|
625
|
+
}
|
|
626
|
+
function getPinnedLeftOffsets(columns) {
|
|
627
|
+
const offsets = {};
|
|
628
|
+
let left = 0;
|
|
629
|
+
for (const column of columns) {
|
|
630
|
+
if (column.pinned !== "left") {
|
|
631
|
+
continue;
|
|
632
|
+
}
|
|
633
|
+
offsets[column.id] = left;
|
|
634
|
+
left += getColumnWidth2(column);
|
|
635
|
+
}
|
|
636
|
+
return offsets;
|
|
637
|
+
}
|
|
638
|
+
function getNextSortDirection(current) {
|
|
639
|
+
if (current === null) {
|
|
640
|
+
return "desc";
|
|
641
|
+
}
|
|
642
|
+
if (current === "desc") {
|
|
643
|
+
return "asc";
|
|
644
|
+
}
|
|
645
|
+
return null;
|
|
646
|
+
}
|
|
647
|
+
function resolveCellValue(row, column) {
|
|
648
|
+
return column.getValue ? column.getValue(row) : row[column.id];
|
|
649
|
+
}
|
|
650
|
+
function formatCellValue(value) {
|
|
651
|
+
if (Array.isArray(value)) {
|
|
652
|
+
return value.join(", ");
|
|
653
|
+
}
|
|
654
|
+
return String(value ?? "");
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
// src/density.ts
|
|
658
|
+
var FALLBACK_ROW_HEIGHT = 32;
|
|
659
|
+
var FALLBACK_HEADER_HEIGHT = HEADER_HEIGHT;
|
|
660
|
+
function parsePx(value) {
|
|
661
|
+
const match = value.trim().match(/^([\d.]+)px$/);
|
|
662
|
+
return match ? parseFloat(match[1]) : null;
|
|
663
|
+
}
|
|
664
|
+
function getDensityHeights() {
|
|
665
|
+
if (typeof document === "undefined") {
|
|
666
|
+
return {
|
|
667
|
+
rowHeight: FALLBACK_ROW_HEIGHT,
|
|
668
|
+
headerHeight: FALLBACK_HEADER_HEIGHT
|
|
669
|
+
};
|
|
670
|
+
}
|
|
671
|
+
const styles = getComputedStyle(document.documentElement);
|
|
672
|
+
const read = (name) => {
|
|
673
|
+
if (typeof styles?.getPropertyValue !== "function") return "";
|
|
674
|
+
return styles.getPropertyValue(name);
|
|
675
|
+
};
|
|
676
|
+
return {
|
|
677
|
+
rowHeight: parsePx(read("--pretable-row-height")) ?? FALLBACK_ROW_HEIGHT,
|
|
678
|
+
headerHeight: parsePx(read("--pretable-header-height")) ?? FALLBACK_HEADER_HEIGHT
|
|
679
|
+
};
|
|
680
|
+
}
|
|
681
|
+
function subscribe(callback) {
|
|
682
|
+
if (typeof document === "undefined") return () => {
|
|
683
|
+
};
|
|
684
|
+
const observer = new MutationObserver(callback);
|
|
685
|
+
observer.observe(document.documentElement, {
|
|
686
|
+
attributes: true,
|
|
687
|
+
attributeFilter: ["data-density", "data-theme", "class", "style"]
|
|
688
|
+
});
|
|
689
|
+
return () => observer.disconnect();
|
|
690
|
+
}
|
|
691
|
+
function useResolvedHeights(rowHeightProp, headerHeightProp) {
|
|
692
|
+
const cachedClient = useRef(null);
|
|
693
|
+
const cachedServer = useRef(null);
|
|
694
|
+
const getSnapshot = useCallback(() => {
|
|
695
|
+
const css = getDensityHeights();
|
|
696
|
+
const rowHeight = rowHeightProp ?? css.rowHeight;
|
|
697
|
+
const headerHeight = headerHeightProp ?? css.headerHeight;
|
|
698
|
+
const prev = cachedClient.current;
|
|
699
|
+
if (prev !== null && prev.rowHeight === rowHeight && prev.headerHeight === headerHeight) {
|
|
700
|
+
return prev;
|
|
701
|
+
}
|
|
702
|
+
const next = { rowHeight, headerHeight };
|
|
703
|
+
cachedClient.current = next;
|
|
704
|
+
return next;
|
|
705
|
+
}, [rowHeightProp, headerHeightProp]);
|
|
706
|
+
const getServerSnapshot = useCallback(() => {
|
|
707
|
+
const rowHeight = rowHeightProp ?? FALLBACK_ROW_HEIGHT;
|
|
708
|
+
const headerHeight = headerHeightProp ?? FALLBACK_HEADER_HEIGHT;
|
|
709
|
+
const prev = cachedServer.current;
|
|
710
|
+
if (prev !== null && prev.rowHeight === rowHeight && prev.headerHeight === headerHeight) {
|
|
711
|
+
return prev;
|
|
712
|
+
}
|
|
713
|
+
const next = { rowHeight, headerHeight };
|
|
714
|
+
cachedServer.current = next;
|
|
715
|
+
return next;
|
|
716
|
+
}, [rowHeightProp, headerHeightProp]);
|
|
717
|
+
return useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
// src/styles.ts
|
|
721
|
+
function getViewportStyle(height) {
|
|
722
|
+
return {
|
|
723
|
+
contain: "content",
|
|
724
|
+
containIntrinsicSize: `auto ${height}px`,
|
|
725
|
+
contentVisibility: "auto",
|
|
726
|
+
height,
|
|
727
|
+
overflow: "auto",
|
|
728
|
+
overflowAnchor: "none",
|
|
729
|
+
overscrollBehavior: "contain",
|
|
730
|
+
position: "relative"
|
|
731
|
+
};
|
|
732
|
+
}
|
|
733
|
+
function getHeaderRowStyle(totalWidth, headerHeight = HEADER_HEIGHT) {
|
|
734
|
+
return {
|
|
735
|
+
display: "flex",
|
|
736
|
+
height: headerHeight,
|
|
737
|
+
insetInline: 0,
|
|
738
|
+
minWidth: totalWidth,
|
|
739
|
+
position: "sticky",
|
|
740
|
+
top: 0,
|
|
741
|
+
zIndex: 3
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
function getScrollContentStyle(totalHeight, totalWidth) {
|
|
745
|
+
return {
|
|
746
|
+
height: Math.max(totalHeight, 0),
|
|
747
|
+
minWidth: totalWidth,
|
|
748
|
+
position: "relative"
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
function getRowStyle(top, height) {
|
|
752
|
+
return {
|
|
753
|
+
boxSizing: "border-box",
|
|
754
|
+
display: "flex",
|
|
755
|
+
height,
|
|
756
|
+
insetInline: 0,
|
|
757
|
+
position: "absolute",
|
|
758
|
+
top
|
|
759
|
+
};
|
|
760
|
+
}
|
|
761
|
+
function getCellStyle(left, width) {
|
|
762
|
+
return {
|
|
763
|
+
boxSizing: "border-box",
|
|
764
|
+
height: "100%",
|
|
765
|
+
left,
|
|
766
|
+
position: "absolute",
|
|
767
|
+
top: 0,
|
|
768
|
+
width
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
function getHeaderCellStyle(left, width) {
|
|
772
|
+
return {
|
|
773
|
+
boxSizing: "border-box",
|
|
774
|
+
height: "100%",
|
|
775
|
+
left,
|
|
776
|
+
position: "absolute",
|
|
777
|
+
top: 0,
|
|
778
|
+
width
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
function getPinnedCellStyle(left) {
|
|
782
|
+
return {
|
|
783
|
+
left,
|
|
784
|
+
position: "sticky",
|
|
785
|
+
top: 0,
|
|
786
|
+
zIndex: 1
|
|
787
|
+
};
|
|
788
|
+
}
|
|
789
|
+
function PretableSurface({
|
|
790
|
+
ariaLabel,
|
|
791
|
+
autosize,
|
|
792
|
+
columns,
|
|
793
|
+
getBodyCellClassName,
|
|
794
|
+
getBodyCellProps,
|
|
795
|
+
getHeaderCellClassName,
|
|
796
|
+
getHeaderCellProps,
|
|
797
|
+
getRowClassName,
|
|
798
|
+
getRowId,
|
|
799
|
+
getRowProps,
|
|
800
|
+
interactionState,
|
|
801
|
+
overscan = 6,
|
|
802
|
+
onGridReady,
|
|
803
|
+
onSelectedRowIdChange,
|
|
804
|
+
onSortChange,
|
|
805
|
+
onTelemetryChange,
|
|
806
|
+
renderBodyCell,
|
|
807
|
+
renderHeaderCell,
|
|
808
|
+
rows,
|
|
809
|
+
selectFocusedRowOnArrowKey = false,
|
|
810
|
+
viewportStyle,
|
|
811
|
+
viewportHeight
|
|
812
|
+
}) {
|
|
813
|
+
const [measuredHeights, setMeasuredHeights] = useState({});
|
|
814
|
+
const [viewportWidth, setViewportWidth] = useState(0);
|
|
815
|
+
const measuredHeightsRef = useRef({});
|
|
816
|
+
const measuredRowKeysRef = useRef({});
|
|
817
|
+
const rowNodesRef = useRef(/* @__PURE__ */ new Map());
|
|
818
|
+
const viewportRef = useRef(null);
|
|
819
|
+
const { headerHeight } = useResolvedHeights();
|
|
820
|
+
const bodyViewportHeight = Math.max(viewportHeight - headerHeight, 0);
|
|
821
|
+
const { grid, snapshot, renderSnapshot, telemetry } = usePretableModel({
|
|
822
|
+
autosize,
|
|
823
|
+
columns,
|
|
824
|
+
getRowId,
|
|
825
|
+
interactionOverrides: interactionState ?? void 0,
|
|
826
|
+
measuredHeights,
|
|
827
|
+
overscan,
|
|
828
|
+
rows,
|
|
829
|
+
viewportHeight: bodyViewportHeight,
|
|
830
|
+
viewportWidth: viewportWidth || void 0
|
|
831
|
+
});
|
|
832
|
+
const pinnedOffsets = useMemo(() => getPinnedLeftOffsets(columns), [columns]);
|
|
833
|
+
useLayoutEffect(() => {
|
|
834
|
+
const el = viewportRef.current;
|
|
835
|
+
if (el && viewportWidth === 0) {
|
|
836
|
+
setViewportWidth(el.clientWidth);
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
useLayoutEffect(() => {
|
|
840
|
+
onTelemetryChange?.(telemetry);
|
|
841
|
+
}, [onTelemetryChange, telemetry]);
|
|
842
|
+
useLayoutEffect(() => {
|
|
843
|
+
onGridReady?.(grid);
|
|
844
|
+
}, [grid, onGridReady]);
|
|
845
|
+
useLayoutEffect(() => {
|
|
846
|
+
if (!interactionState?.selectedRowId) {
|
|
847
|
+
return;
|
|
848
|
+
}
|
|
849
|
+
const currentSelectedRowId = snapshot.selection.rowIds[0] ?? null;
|
|
850
|
+
if (currentSelectedRowId !== interactionState.selectedRowId) {
|
|
851
|
+
onSelectedRowIdChange?.(interactionState.selectedRowId);
|
|
852
|
+
}
|
|
853
|
+
}, [interactionState, onSelectedRowIdChange, snapshot.selection.rowIds]);
|
|
854
|
+
useLayoutEffect(() => {
|
|
855
|
+
let nextHeights = measuredHeightsRef.current;
|
|
856
|
+
let nextKeys = measuredRowKeysRef.current;
|
|
857
|
+
let changed = false;
|
|
858
|
+
for (const [rowId, node] of rowNodesRef.current) {
|
|
859
|
+
const plannedHeight = Number(node.getAttribute("data-row-height"));
|
|
860
|
+
const cachedHeight = nextHeights[rowId];
|
|
861
|
+
const currentRowKey = getRowMeasurementKey(node);
|
|
862
|
+
const cachedRowKey = nextKeys[rowId];
|
|
863
|
+
if (Number.isFinite(plannedHeight) && cachedHeight !== void 0 && cachedHeight === plannedHeight && cachedRowKey === currentRowKey) {
|
|
864
|
+
continue;
|
|
865
|
+
}
|
|
866
|
+
const measuredHeight = measureRenderedRowHeight(node);
|
|
867
|
+
if (measuredHeight <= DEFAULT_ROW_HEIGHT2) {
|
|
868
|
+
if (cachedHeight !== void 0 && cachedRowKey !== currentRowKey) {
|
|
869
|
+
const restHeights = { ...nextHeights };
|
|
870
|
+
delete restHeights[rowId];
|
|
871
|
+
const restKeys = { ...nextKeys };
|
|
872
|
+
delete restKeys[rowId];
|
|
873
|
+
nextHeights = restHeights;
|
|
874
|
+
nextKeys = restKeys;
|
|
875
|
+
changed = true;
|
|
876
|
+
}
|
|
877
|
+
continue;
|
|
878
|
+
}
|
|
879
|
+
if (nextHeights[rowId] === measuredHeight) {
|
|
880
|
+
if (cachedRowKey !== currentRowKey) {
|
|
881
|
+
nextKeys = { ...nextKeys, [rowId]: currentRowKey };
|
|
882
|
+
}
|
|
883
|
+
continue;
|
|
884
|
+
}
|
|
885
|
+
nextHeights = { ...nextHeights, [rowId]: measuredHeight };
|
|
886
|
+
nextKeys = { ...nextKeys, [rowId]: currentRowKey };
|
|
887
|
+
changed = true;
|
|
888
|
+
}
|
|
889
|
+
measuredHeightsRef.current = nextHeights;
|
|
890
|
+
measuredRowKeysRef.current = nextKeys;
|
|
891
|
+
if (changed) {
|
|
892
|
+
setMeasuredHeights(nextHeights);
|
|
893
|
+
}
|
|
894
|
+
}, [snapshot.visibleRows, columns, viewportWidth]);
|
|
895
|
+
return /* @__PURE__ */ jsxs(
|
|
896
|
+
"div",
|
|
897
|
+
{
|
|
898
|
+
"aria-label": ariaLabel,
|
|
899
|
+
"data-pretable-scroll-viewport": "",
|
|
900
|
+
ref: viewportRef,
|
|
901
|
+
role: "grid",
|
|
902
|
+
tabIndex: 0,
|
|
903
|
+
onKeyDown: (event) => {
|
|
904
|
+
if (event.key === "ArrowDown" || event.key === "ArrowUp") {
|
|
905
|
+
grid.moveFocus(event.key === "ArrowDown" ? 1 : -1);
|
|
906
|
+
const nextFocus = grid.getSnapshot().focus;
|
|
907
|
+
if (nextFocus.rowId && nextFocus.columnId === null && columns[0]) {
|
|
908
|
+
grid.setFocus(nextFocus.rowId, columns[0].id);
|
|
909
|
+
}
|
|
910
|
+
if (selectFocusedRowOnArrowKey && nextFocus.rowId) {
|
|
911
|
+
grid.selectRow(nextFocus.rowId);
|
|
912
|
+
onSelectedRowIdChange?.(nextFocus.rowId);
|
|
913
|
+
}
|
|
914
|
+
event.preventDefault();
|
|
915
|
+
return;
|
|
916
|
+
}
|
|
917
|
+
if (event.key === "Enter" || event.key === " " || event.key === "Space") {
|
|
918
|
+
const focusedRowId = grid.getSnapshot().focus.rowId;
|
|
919
|
+
if (focusedRowId) {
|
|
920
|
+
grid.selectRow(focusedRowId);
|
|
921
|
+
onSelectedRowIdChange?.(focusedRowId);
|
|
922
|
+
event.preventDefault();
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
},
|
|
926
|
+
onScroll: (event) => {
|
|
927
|
+
const el = event.currentTarget;
|
|
928
|
+
grid.setViewport({
|
|
929
|
+
scrollTop: el.scrollTop,
|
|
930
|
+
scrollLeft: el.scrollLeft,
|
|
931
|
+
height: bodyViewportHeight,
|
|
932
|
+
width: el.clientWidth
|
|
933
|
+
});
|
|
934
|
+
if (el.clientWidth !== viewportWidth) {
|
|
935
|
+
setViewportWidth(el.clientWidth);
|
|
936
|
+
}
|
|
937
|
+
},
|
|
938
|
+
style: {
|
|
939
|
+
...getViewportStyle(viewportHeight),
|
|
940
|
+
...viewportStyle
|
|
941
|
+
},
|
|
942
|
+
children: [
|
|
943
|
+
/* @__PURE__ */ jsx(
|
|
944
|
+
"div",
|
|
945
|
+
{
|
|
946
|
+
"data-pretable-header-row": "",
|
|
947
|
+
style: getHeaderRowStyle(renderSnapshot.totalWidth, headerHeight),
|
|
948
|
+
children: renderSnapshot.columns.map((plannedCol) => {
|
|
949
|
+
const column = columns[plannedCol.index];
|
|
950
|
+
if (!column) {
|
|
951
|
+
return null;
|
|
952
|
+
}
|
|
953
|
+
const label = column.header ?? column.id;
|
|
954
|
+
const sortDirection = snapshot.sort.columnId === column.id ? snapshot.sort.direction : null;
|
|
955
|
+
const headerProps = getHeaderCellProps?.({
|
|
956
|
+
column,
|
|
957
|
+
sortDirection
|
|
958
|
+
}) ?? {};
|
|
959
|
+
const pinnedOffset = pinnedOffsets[column.id];
|
|
960
|
+
const positionStyle = plannedCol.pinned === "left" && pinnedOffset !== void 0 ? {
|
|
961
|
+
...getHeaderCellStyle(plannedCol.left, plannedCol.width),
|
|
962
|
+
...getPinnedCellStyle(pinnedOffset)
|
|
963
|
+
} : getHeaderCellStyle(plannedCol.left, plannedCol.width);
|
|
964
|
+
return /* @__PURE__ */ createElement(
|
|
965
|
+
"button",
|
|
966
|
+
{
|
|
967
|
+
...headerProps,
|
|
968
|
+
"aria-label": `Sort ${label}`,
|
|
969
|
+
className: getHeaderCellClassName?.({
|
|
970
|
+
column,
|
|
971
|
+
sortDirection
|
|
972
|
+
}),
|
|
973
|
+
"data-pretable-header-cell": "",
|
|
974
|
+
"data-pinned": plannedCol.pinned === "left" ? "left" : void 0,
|
|
975
|
+
key: column.id,
|
|
976
|
+
onClick: () => {
|
|
977
|
+
const nextDirection = getNextSortDirection(sortDirection);
|
|
978
|
+
grid.setSort(column.id, nextDirection);
|
|
979
|
+
if (nextDirection) {
|
|
980
|
+
onSortChange?.({
|
|
981
|
+
columnId: column.id,
|
|
982
|
+
direction: nextDirection
|
|
983
|
+
});
|
|
984
|
+
} else {
|
|
985
|
+
onSortChange?.(null);
|
|
986
|
+
}
|
|
987
|
+
},
|
|
988
|
+
style: {
|
|
989
|
+
alignItems: "start",
|
|
990
|
+
border: 0,
|
|
991
|
+
borderRight: "1px solid rgba(255, 255, 255, 0.06)",
|
|
992
|
+
color: "inherit",
|
|
993
|
+
display: "grid",
|
|
994
|
+
gap: 4,
|
|
995
|
+
textAlign: "left",
|
|
996
|
+
...positionStyle
|
|
997
|
+
},
|
|
998
|
+
type: "button"
|
|
999
|
+
},
|
|
1000
|
+
renderHeaderCell ? renderHeaderCell({
|
|
1001
|
+
column,
|
|
1002
|
+
label,
|
|
1003
|
+
sortDirection
|
|
1004
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1005
|
+
/* @__PURE__ */ jsx("span", { children: label }),
|
|
1006
|
+
/* @__PURE__ */ jsx("strong", { children: sortDirection === "desc" ? "Newest" : sortDirection === "asc" ? "Oldest" : "Sort" })
|
|
1007
|
+
] })
|
|
1008
|
+
);
|
|
1009
|
+
})
|
|
1010
|
+
}
|
|
1011
|
+
),
|
|
1012
|
+
/* @__PURE__ */ jsx(
|
|
1013
|
+
"div",
|
|
1014
|
+
{
|
|
1015
|
+
"data-pretable-scroll-content": "",
|
|
1016
|
+
style: getScrollContentStyle(
|
|
1017
|
+
renderSnapshot.totalHeight,
|
|
1018
|
+
renderSnapshot.totalWidth
|
|
1019
|
+
),
|
|
1020
|
+
children: renderSnapshot.rows.map(({ height, id, row, rowIndex, top }) => {
|
|
1021
|
+
const isFocused = snapshot.focus.rowId === id;
|
|
1022
|
+
const isSelected = snapshot.selection.rowIds.includes(id);
|
|
1023
|
+
const rowProps = getRowProps?.({
|
|
1024
|
+
isFocused,
|
|
1025
|
+
isSelected,
|
|
1026
|
+
row,
|
|
1027
|
+
rowId: id,
|
|
1028
|
+
rowIndex
|
|
1029
|
+
}) ?? {};
|
|
1030
|
+
return /* @__PURE__ */ createElement(
|
|
1031
|
+
"div",
|
|
1032
|
+
{
|
|
1033
|
+
...rowProps,
|
|
1034
|
+
"aria-rowindex": rowIndex + 1,
|
|
1035
|
+
"aria-selected": isSelected,
|
|
1036
|
+
className: getRowClassName?.({
|
|
1037
|
+
isFocused,
|
|
1038
|
+
isSelected,
|
|
1039
|
+
row,
|
|
1040
|
+
rowId: id,
|
|
1041
|
+
rowIndex
|
|
1042
|
+
}),
|
|
1043
|
+
"data-focused": isFocused ? "true" : "false",
|
|
1044
|
+
"data-pretable-row": "",
|
|
1045
|
+
"data-row-height": height,
|
|
1046
|
+
"data-row-id": id,
|
|
1047
|
+
"data-row-index": rowIndex,
|
|
1048
|
+
"data-selected": isSelected ? "true" : "false",
|
|
1049
|
+
"data-testid": "pretable-row",
|
|
1050
|
+
key: id,
|
|
1051
|
+
onClick: () => {
|
|
1052
|
+
grid.setFocus(id, columns[0]?.id ?? null);
|
|
1053
|
+
grid.selectRow(id);
|
|
1054
|
+
onSelectedRowIdChange?.(id);
|
|
1055
|
+
},
|
|
1056
|
+
ref: (node) => {
|
|
1057
|
+
if (node) {
|
|
1058
|
+
rowNodesRef.current.set(id, node);
|
|
1059
|
+
} else {
|
|
1060
|
+
rowNodesRef.current.delete(id);
|
|
1061
|
+
}
|
|
1062
|
+
},
|
|
1063
|
+
style: getRowStyle(top, height)
|
|
1064
|
+
},
|
|
1065
|
+
renderSnapshot.columns.map((plannedCol) => {
|
|
1066
|
+
const column = columns[plannedCol.index];
|
|
1067
|
+
if (!column) {
|
|
1068
|
+
return null;
|
|
1069
|
+
}
|
|
1070
|
+
const value = resolveCellValue(row, column);
|
|
1071
|
+
const bodyInput = {
|
|
1072
|
+
column,
|
|
1073
|
+
isFocused,
|
|
1074
|
+
isSelected,
|
|
1075
|
+
row,
|
|
1076
|
+
rowId: id,
|
|
1077
|
+
rowIndex,
|
|
1078
|
+
value
|
|
1079
|
+
};
|
|
1080
|
+
const bodyProps = getBodyCellProps?.(bodyInput) ?? {};
|
|
1081
|
+
const pinnedOffset = pinnedOffsets[column.id];
|
|
1082
|
+
const positionStyle = plannedCol.pinned === "left" && pinnedOffset !== void 0 ? {
|
|
1083
|
+
...getCellStyle(plannedCol.left, plannedCol.width),
|
|
1084
|
+
...getPinnedCellStyle(pinnedOffset)
|
|
1085
|
+
} : getCellStyle(plannedCol.left, plannedCol.width);
|
|
1086
|
+
return /* @__PURE__ */ createElement(
|
|
1087
|
+
"div",
|
|
1088
|
+
{
|
|
1089
|
+
...bodyProps,
|
|
1090
|
+
className: getBodyCellClassName?.(bodyInput),
|
|
1091
|
+
"data-column-id": column.id,
|
|
1092
|
+
"data-focused": isFocused ? "true" : "false",
|
|
1093
|
+
"data-pinned": column.pinned === "left" ? "left" : void 0,
|
|
1094
|
+
"data-pretable-cell": "",
|
|
1095
|
+
"data-pretable-wrap": column.wrap ? "true" : void 0,
|
|
1096
|
+
"data-selected": isSelected ? "true" : "false",
|
|
1097
|
+
key: `${id}:${column.id}`,
|
|
1098
|
+
style: {
|
|
1099
|
+
overflowWrap: column.wrap ? "anywhere" : "normal",
|
|
1100
|
+
whiteSpace: column.wrap ? "pre-wrap" : "nowrap",
|
|
1101
|
+
...positionStyle
|
|
1102
|
+
}
|
|
1103
|
+
},
|
|
1104
|
+
renderBodyCell ? renderBodyCell(bodyInput) : formatCellValue(value)
|
|
1105
|
+
);
|
|
1106
|
+
})
|
|
1107
|
+
);
|
|
1108
|
+
})
|
|
1109
|
+
}
|
|
1110
|
+
)
|
|
1111
|
+
]
|
|
1112
|
+
}
|
|
1113
|
+
);
|
|
1114
|
+
}
|
|
1115
|
+
function getRowMeasurementKey(rowNode) {
|
|
1116
|
+
const rowParts = [
|
|
1117
|
+
rowNode.getAttribute("class") ?? "",
|
|
1118
|
+
normalizeStyleSignature(rowNode.getAttribute("style") ?? ""),
|
|
1119
|
+
rowNode.getAttribute("aria-selected") ?? "",
|
|
1120
|
+
rowNode.getAttribute("data-focused") ?? "",
|
|
1121
|
+
rowNode.getAttribute("data-selected") ?? ""
|
|
1122
|
+
];
|
|
1123
|
+
const cellParts = [
|
|
1124
|
+
...rowNode.querySelectorAll("[data-pretable-cell]")
|
|
1125
|
+
].map(
|
|
1126
|
+
(cell) => [
|
|
1127
|
+
cell.getAttribute("data-column-id") ?? "",
|
|
1128
|
+
cell.getAttribute("class") ?? "",
|
|
1129
|
+
cell.getAttribute("style") ?? "",
|
|
1130
|
+
cell.getAttribute("data-pretable-wrap") ?? "",
|
|
1131
|
+
cell.getAttribute("data-focused") ?? "",
|
|
1132
|
+
cell.getAttribute("data-selected") ?? "",
|
|
1133
|
+
cell.textContent ?? ""
|
|
1134
|
+
].join(":")
|
|
1135
|
+
);
|
|
1136
|
+
return [...rowParts, ...cellParts].join("|");
|
|
1137
|
+
}
|
|
1138
|
+
function normalizeStyleSignature(styleValue) {
|
|
1139
|
+
return styleValue.split(";").map((declaration) => declaration.trim()).filter(Boolean).filter((declaration) => !/^top\s*:/i.test(declaration)).join(";");
|
|
1140
|
+
}
|
|
1141
|
+
var VIEWPORT_HEIGHT = 320;
|
|
1142
|
+
var BENCHMARK_VIEWPORT_STYLE = {
|
|
1143
|
+
contain: "none",
|
|
1144
|
+
containIntrinsicSize: "none",
|
|
1145
|
+
contentVisibility: "visible",
|
|
1146
|
+
overflowAnchor: "none",
|
|
1147
|
+
overscrollBehavior: "contain"
|
|
1148
|
+
};
|
|
1149
|
+
function Pretable({
|
|
1150
|
+
columns,
|
|
1151
|
+
getRowId,
|
|
1152
|
+
rows
|
|
1153
|
+
}) {
|
|
1154
|
+
const resolvedGetRowId = getRowId ?? ((row, index) => {
|
|
1155
|
+
const candidate = row.id;
|
|
1156
|
+
if (typeof candidate === "string" || typeof candidate === "number") {
|
|
1157
|
+
return String(candidate);
|
|
1158
|
+
}
|
|
1159
|
+
return String(index);
|
|
1160
|
+
});
|
|
1161
|
+
return /* @__PURE__ */ jsxs(
|
|
1162
|
+
"section",
|
|
1163
|
+
{
|
|
1164
|
+
"aria-label": "Pretable React adapter",
|
|
1165
|
+
style: {
|
|
1166
|
+
display: "grid",
|
|
1167
|
+
gap: 12
|
|
1168
|
+
},
|
|
1169
|
+
children: [
|
|
1170
|
+
/* @__PURE__ */ jsxs("header", { children: [
|
|
1171
|
+
/* @__PURE__ */ jsx(
|
|
1172
|
+
"p",
|
|
1173
|
+
{
|
|
1174
|
+
style: {
|
|
1175
|
+
margin: 0,
|
|
1176
|
+
fontWeight: 700
|
|
1177
|
+
},
|
|
1178
|
+
children: "Pretable React adapter"
|
|
1179
|
+
}
|
|
1180
|
+
),
|
|
1181
|
+
/* @__PURE__ */ jsxs("p", { style: { margin: "4px 0 0", opacity: 0.8 }, children: [
|
|
1182
|
+
"Rows: ",
|
|
1183
|
+
rows.length
|
|
1184
|
+
] }),
|
|
1185
|
+
/* @__PURE__ */ jsxs("p", { style: { margin: "4px 0 0", opacity: 0.8 }, children: [
|
|
1186
|
+
"Columns: ",
|
|
1187
|
+
columns.length
|
|
1188
|
+
] })
|
|
1189
|
+
] }),
|
|
1190
|
+
/* @__PURE__ */ jsx(
|
|
1191
|
+
PretableSurface,
|
|
1192
|
+
{
|
|
1193
|
+
ariaLabel: "Pretable React adapter",
|
|
1194
|
+
columns,
|
|
1195
|
+
getRowId: resolvedGetRowId,
|
|
1196
|
+
renderBodyCell: ({ column, value }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1197
|
+
/* @__PURE__ */ jsx(
|
|
1198
|
+
"strong",
|
|
1199
|
+
{
|
|
1200
|
+
style: {
|
|
1201
|
+
display: "block",
|
|
1202
|
+
fontSize: 12,
|
|
1203
|
+
lineHeight: "16px",
|
|
1204
|
+
marginBottom: 4,
|
|
1205
|
+
opacity: 0.7
|
|
1206
|
+
},
|
|
1207
|
+
children: column.header ?? column.id
|
|
1208
|
+
}
|
|
1209
|
+
),
|
|
1210
|
+
/* @__PURE__ */ jsx(
|
|
1211
|
+
"span",
|
|
1212
|
+
{
|
|
1213
|
+
style: {
|
|
1214
|
+
display: "block",
|
|
1215
|
+
lineHeight: "22px"
|
|
1216
|
+
},
|
|
1217
|
+
children: String(value ?? "")
|
|
1218
|
+
}
|
|
1219
|
+
)
|
|
1220
|
+
] }),
|
|
1221
|
+
renderHeaderCell: ({ label, sortDirection }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1222
|
+
/* @__PURE__ */ jsx("span", { children: label }),
|
|
1223
|
+
/* @__PURE__ */ jsx(
|
|
1224
|
+
"strong",
|
|
1225
|
+
{
|
|
1226
|
+
style: {
|
|
1227
|
+
fontSize: 12,
|
|
1228
|
+
lineHeight: "16px",
|
|
1229
|
+
opacity: 0.7
|
|
1230
|
+
},
|
|
1231
|
+
children: sortDirection === "desc" ? "Newest" : sortDirection === "asc" ? "Oldest" : "Sort"
|
|
1232
|
+
}
|
|
1233
|
+
)
|
|
1234
|
+
] }),
|
|
1235
|
+
rows,
|
|
1236
|
+
viewportStyle: BENCHMARK_VIEWPORT_STYLE,
|
|
1237
|
+
viewportHeight: VIEWPORT_HEIGHT
|
|
1238
|
+
}
|
|
1239
|
+
)
|
|
1240
|
+
]
|
|
1241
|
+
}
|
|
1242
|
+
);
|
|
1243
|
+
}
|
|
1244
|
+
|
|
1245
|
+
// ../scenario-data/dist/inspection-profile.js
|
|
1246
|
+
var inspectionColumns = [
|
|
1247
|
+
{ id: "timestamp", header: "Timestamp", pinned: "left", widthPx: 188 },
|
|
1248
|
+
{ id: "severity", header: "Severity", pinned: "left", widthPx: 112 },
|
|
1249
|
+
{ id: "source", header: "Source", widthPx: 160 },
|
|
1250
|
+
{ id: "owner", header: "Owner", widthPx: 144 },
|
|
1251
|
+
{
|
|
1252
|
+
id: "tags",
|
|
1253
|
+
header: "Tags",
|
|
1254
|
+
widthPx: 200,
|
|
1255
|
+
getValue: (row) => row.tags.join(", ")
|
|
1256
|
+
},
|
|
1257
|
+
{ id: "message", header: "Message", wrap: true, widthPx: 480 }
|
|
1258
|
+
];
|
|
1259
|
+
function LabeledGridSurface({
|
|
1260
|
+
ariaLabel,
|
|
1261
|
+
bodyCellClassName,
|
|
1262
|
+
columns,
|
|
1263
|
+
formatValue,
|
|
1264
|
+
getBodyCellProps,
|
|
1265
|
+
getHeaderCellProps,
|
|
1266
|
+
getRowId,
|
|
1267
|
+
headerCellClassName,
|
|
1268
|
+
interactionState,
|
|
1269
|
+
labelClassName,
|
|
1270
|
+
overscan,
|
|
1271
|
+
onSelectedRowIdChange,
|
|
1272
|
+
onSortChange,
|
|
1273
|
+
onTelemetryChange,
|
|
1274
|
+
pinnedClassName,
|
|
1275
|
+
rowClassName,
|
|
1276
|
+
rows,
|
|
1277
|
+
selectFocusedRowOnArrowKey,
|
|
1278
|
+
valueClassName,
|
|
1279
|
+
viewportHeight
|
|
1280
|
+
}) {
|
|
1281
|
+
const getPinnedClassName = (column) => column.pinned === "left" && pinnedClassName ? pinnedClassName : void 0;
|
|
1282
|
+
const activeFilterColumns = new Set(
|
|
1283
|
+
Object.entries(interactionState?.filters ?? {}).filter(([, value]) => value.trim() !== "").map(([columnId]) => columnId)
|
|
1284
|
+
);
|
|
1285
|
+
const getFormattedValue = ({
|
|
1286
|
+
column,
|
|
1287
|
+
row,
|
|
1288
|
+
value
|
|
1289
|
+
}) => formatValue ? formatValue({ column, row, value }) : formatDefaultValue(value);
|
|
1290
|
+
return /* @__PURE__ */ jsx(
|
|
1291
|
+
PretableSurface,
|
|
1292
|
+
{
|
|
1293
|
+
ariaLabel,
|
|
1294
|
+
columns,
|
|
1295
|
+
getBodyCellClassName: ({ column }) => joinClassNames(bodyCellClassName, getPinnedClassName(column)),
|
|
1296
|
+
getBodyCellProps: (input) => mergeProps(
|
|
1297
|
+
input.column.pinned === "left" ? {
|
|
1298
|
+
"data-pinned": "left"
|
|
1299
|
+
} : void 0,
|
|
1300
|
+
getBodyCellProps?.(input)
|
|
1301
|
+
),
|
|
1302
|
+
getHeaderCellClassName: ({ column }) => joinClassNames(
|
|
1303
|
+
headerCellClassName,
|
|
1304
|
+
getPinnedClassName(column),
|
|
1305
|
+
activeFilterColumns.has(column.id) ? "is-filtered" : void 0
|
|
1306
|
+
),
|
|
1307
|
+
getHeaderCellProps: (input) => mergeProps(
|
|
1308
|
+
input.column.pinned === "left" ? {
|
|
1309
|
+
"data-pinned": "left"
|
|
1310
|
+
} : void 0,
|
|
1311
|
+
getHeaderCellProps?.(input)
|
|
1312
|
+
),
|
|
1313
|
+
getRowClassName: () => rowClassName,
|
|
1314
|
+
getRowId,
|
|
1315
|
+
interactionState,
|
|
1316
|
+
overscan,
|
|
1317
|
+
onSelectedRowIdChange,
|
|
1318
|
+
onSortChange,
|
|
1319
|
+
onTelemetryChange,
|
|
1320
|
+
renderBodyCell: ({ column, row, value }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1321
|
+
/* @__PURE__ */ jsx("span", { className: labelClassName, children: column.header ?? column.id }),
|
|
1322
|
+
/* @__PURE__ */ jsx("span", { className: valueClassName, children: getFormattedValue({
|
|
1323
|
+
column,
|
|
1324
|
+
row,
|
|
1325
|
+
value
|
|
1326
|
+
}) })
|
|
1327
|
+
] }),
|
|
1328
|
+
renderHeaderCell: ({ label, sortDirection }) => /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1329
|
+
/* @__PURE__ */ jsx("span", { children: label }),
|
|
1330
|
+
sortDirection ? /* @__PURE__ */ jsx("span", { className: "sort-indicator", children: sortDirection === "desc" ? "\u25BC" : "\u25B2" }) : null
|
|
1331
|
+
] }),
|
|
1332
|
+
rows,
|
|
1333
|
+
selectFocusedRowOnArrowKey,
|
|
1334
|
+
viewportHeight
|
|
1335
|
+
}
|
|
1336
|
+
);
|
|
1337
|
+
}
|
|
1338
|
+
function joinClassNames(...values) {
|
|
1339
|
+
return values.filter(Boolean).join(" ") || void 0;
|
|
1340
|
+
}
|
|
1341
|
+
function mergeProps(base, extra) {
|
|
1342
|
+
if (!base) {
|
|
1343
|
+
return extra;
|
|
1344
|
+
}
|
|
1345
|
+
if (!extra) {
|
|
1346
|
+
return base;
|
|
1347
|
+
}
|
|
1348
|
+
return {
|
|
1349
|
+
...base,
|
|
1350
|
+
...extra
|
|
1351
|
+
};
|
|
1352
|
+
}
|
|
1353
|
+
function formatDefaultValue(value) {
|
|
1354
|
+
if (Array.isArray(value)) {
|
|
1355
|
+
return value.join(", ");
|
|
1356
|
+
}
|
|
1357
|
+
return String(value ?? "");
|
|
1358
|
+
}
|
|
1359
|
+
var inspectionGridColumns = [...inspectionColumns];
|
|
1360
|
+
var getInspectionRowId = (row) => row.id;
|
|
1361
|
+
var filterableBodyProps = {
|
|
1362
|
+
"data-filterable": "true"
|
|
1363
|
+
};
|
|
1364
|
+
var filterableHeaderProps = {
|
|
1365
|
+
"data-filterable": "true"
|
|
1366
|
+
};
|
|
1367
|
+
function InspectionGrid({
|
|
1368
|
+
ariaLabel,
|
|
1369
|
+
filterableColumnIds,
|
|
1370
|
+
interactionState,
|
|
1371
|
+
onSelectedRowIdChange,
|
|
1372
|
+
onSortChange,
|
|
1373
|
+
onTelemetryChange,
|
|
1374
|
+
overscan,
|
|
1375
|
+
rows,
|
|
1376
|
+
viewportHeight
|
|
1377
|
+
}) {
|
|
1378
|
+
const filterableColumns = new Set(filterableColumnIds);
|
|
1379
|
+
return /* @__PURE__ */ jsx(
|
|
1380
|
+
LabeledGridSurface,
|
|
1381
|
+
{
|
|
1382
|
+
ariaLabel,
|
|
1383
|
+
bodyCellClassName: "inspection-cell",
|
|
1384
|
+
columns: inspectionGridColumns,
|
|
1385
|
+
formatValue: ({ value }) => formatInspectionValue(value),
|
|
1386
|
+
getBodyCellProps: ({ column }) => filterableColumns.has(column.id) ? filterableBodyProps : void 0,
|
|
1387
|
+
getHeaderCellProps: ({ column }) => filterableColumns.has(column.id) ? filterableHeaderProps : void 0,
|
|
1388
|
+
getRowId: getInspectionRowId,
|
|
1389
|
+
headerCellClassName: "inspection-header-cell",
|
|
1390
|
+
interactionState,
|
|
1391
|
+
labelClassName: "inspection-cell-label",
|
|
1392
|
+
overscan,
|
|
1393
|
+
onSelectedRowIdChange,
|
|
1394
|
+
onSortChange,
|
|
1395
|
+
onTelemetryChange,
|
|
1396
|
+
pinnedClassName: "is-pinned",
|
|
1397
|
+
rowClassName: "inspection-row",
|
|
1398
|
+
rows,
|
|
1399
|
+
selectFocusedRowOnArrowKey: true,
|
|
1400
|
+
valueClassName: "inspection-cell-value",
|
|
1401
|
+
viewportHeight
|
|
1402
|
+
}
|
|
1403
|
+
);
|
|
1404
|
+
}
|
|
1405
|
+
function formatInspectionValue(value) {
|
|
1406
|
+
if (Array.isArray(value)) {
|
|
1407
|
+
return value.join(", ");
|
|
1408
|
+
}
|
|
1409
|
+
return String(value ?? "");
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
export { InspectionGrid, LabeledGridSurface, Pretable, PretableSurface, measureRenderedRowHeight, usePretable, usePretableModel, useResolvedHeights };
|