@astronox/core 0.4.3 → 0.4.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/package.json +1 -1
- package/src/patterns/Table/Table.css +2 -8
- package/src/patterns/Table/TableBody.astro +0 -17
- package/src/patterns/Table/TableSkeleton.css +4 -24
- package/src/patterns/Table/tableProgressiveController.ts +16 -78
- package/src/patterns/Table/tableSortController.ts +3 -6
- package/src/patterns/Table/tableScrollPosition.ts +0 -41
package/package.json
CHANGED
|
@@ -49,10 +49,7 @@
|
|
|
49
49
|
|
|
50
50
|
.table[data-table-sticky-header]:has([data-sticky-surface])
|
|
51
51
|
[data-table-header] {
|
|
52
|
-
top: var(
|
|
53
|
-
--surface-group-sticky-occlusion-size,
|
|
54
|
-
calc(var(--nox-layout-gap) + var(--nox-section-responsive-block-size))
|
|
55
|
-
);
|
|
52
|
+
top: calc(var(--nox-layout-gap) + var(--nox-section-responsive-block-size));
|
|
56
53
|
}
|
|
57
54
|
|
|
58
55
|
@container nox-table (width < 32rem) {
|
|
@@ -63,10 +60,7 @@
|
|
|
63
60
|
|
|
64
61
|
.table[data-table-sticky-header]:has([data-sticky-surface])
|
|
65
62
|
[data-table-header] {
|
|
66
|
-
top: var(
|
|
67
|
-
--surface-group-sticky-occlusion-size,
|
|
68
|
-
calc(var(--nox-layout-gap) + var(--nox-section-compact-block-size))
|
|
69
|
-
);
|
|
63
|
+
top: calc(var(--nox-layout-gap) + var(--nox-section-compact-block-size));
|
|
70
64
|
}
|
|
71
65
|
}
|
|
72
66
|
|
|
@@ -55,23 +55,6 @@ const stateMessage =
|
|
|
55
55
|
data-tooltip-boundary
|
|
56
56
|
data-tone={dataTone}
|
|
57
57
|
>
|
|
58
|
-
<div
|
|
59
|
-
class="table-body__initial-skeleton"
|
|
60
|
-
data-table-initial-skeleton
|
|
61
|
-
aria-hidden="true"
|
|
62
|
-
>
|
|
63
|
-
{
|
|
64
|
-
columns.map((column) => (
|
|
65
|
-
<div
|
|
66
|
-
class="table-skeleton__cell"
|
|
67
|
-
data-align={getTableColumnAlignment(column)}
|
|
68
|
-
data-table-column-role={column.role}
|
|
69
|
-
>
|
|
70
|
-
<span class="table-skeleton__placeholder" />
|
|
71
|
-
</div>
|
|
72
|
-
))
|
|
73
|
-
}
|
|
74
|
-
</div>
|
|
75
58
|
<table class="table-body__table">
|
|
76
59
|
<caption class="table-body__visually-hidden">{caption}</caption>
|
|
77
60
|
<thead class="table-body__visually-hidden">
|
|
@@ -7,23 +7,6 @@
|
|
|
7
7
|
border-block-start: 0;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
.table-body__initial-skeleton {
|
|
11
|
-
display: none;
|
|
12
|
-
min-width: 0;
|
|
13
|
-
min-height: var(--table-row-min-block-size);
|
|
14
|
-
grid-template-columns: var(--table-column-template);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
[data-nox-table-enhanced]
|
|
18
|
-
.table:is(
|
|
19
|
-
[data-table-loading-state='pending'],
|
|
20
|
-
[data-table-loading-state='refreshing']
|
|
21
|
-
)
|
|
22
|
-
.table-body:not(:has(.table-skeleton__row))
|
|
23
|
-
> .table-body__initial-skeleton {
|
|
24
|
-
display: grid;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
10
|
.table-skeleton__row + .table-skeleton__row,
|
|
28
11
|
[data-nox-table-enhanced]
|
|
29
12
|
.table[data-table-loading-state='appending']
|
|
@@ -34,6 +17,9 @@
|
|
|
34
17
|
|
|
35
18
|
[data-nox-table-enhanced]
|
|
36
19
|
.table[data-table-loading-state='pending']
|
|
20
|
+
.table-body__row[data-table-row],
|
|
21
|
+
[data-nox-table-enhanced]
|
|
22
|
+
.table[data-table-loading-state='refreshing']
|
|
37
23
|
.table-body__row[data-table-row] {
|
|
38
24
|
display: none;
|
|
39
25
|
}
|
|
@@ -97,11 +83,6 @@
|
|
|
97
83
|
min-height: var(--table-index-row-block-size);
|
|
98
84
|
}
|
|
99
85
|
|
|
100
|
-
.table[data-table-layout='index'] .table-body__initial-skeleton {
|
|
101
|
-
block-size: var(--table-index-row-block-size);
|
|
102
|
-
min-height: var(--table-index-row-block-size);
|
|
103
|
-
}
|
|
104
|
-
|
|
105
86
|
@media (prefers-reduced-motion: no-preference) {
|
|
106
87
|
.table-skeleton__placeholder {
|
|
107
88
|
animation: table-skeleton-pulse 1.4s ease-in-out infinite;
|
|
@@ -119,8 +100,7 @@
|
|
|
119
100
|
}
|
|
120
101
|
|
|
121
102
|
@container (width < 36rem) {
|
|
122
|
-
.table-skeleton__row
|
|
123
|
-
.table-body__initial-skeleton {
|
|
103
|
+
.table-skeleton__row {
|
|
124
104
|
min-height: var(--table-row-narrow-min-block-size);
|
|
125
105
|
}
|
|
126
106
|
}
|
|
@@ -3,7 +3,6 @@ import type {
|
|
|
3
3
|
TableProgressiveModel,
|
|
4
4
|
} from '../../display/contracts';
|
|
5
5
|
import { tableProgressiveBatchSize } from '../../display/tableProgressive';
|
|
6
|
-
import { mutateTablePreservingScroll } from './tableScrollPosition';
|
|
7
6
|
|
|
8
7
|
const initializedAttribute = 'data-table-progressive-initialized';
|
|
9
8
|
|
|
@@ -152,8 +151,6 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
152
151
|
let disposed = false;
|
|
153
152
|
let generation = 0;
|
|
154
153
|
let prepared = false;
|
|
155
|
-
let retainedWindowSize = Math.max(batchSize, getRows(activeRowsRoot).length);
|
|
156
|
-
let scheduledRenderFrame: number | null = null;
|
|
157
154
|
|
|
158
155
|
registerRows(getRows(activeRowsRoot));
|
|
159
156
|
|
|
@@ -184,11 +181,8 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
184
181
|
activeSkeletonTemplate.content.querySelectorAll<HTMLElement>(
|
|
185
182
|
'[data-table-skeleton-row]',
|
|
186
183
|
),
|
|
187
|
-
);
|
|
188
|
-
|
|
189
|
-
skeletonRows = Array.from({ length: count }, (_, index) =>
|
|
190
|
-
document.importNode(candidates[index % candidates.length]!, true),
|
|
191
|
-
);
|
|
184
|
+
).slice(0, count);
|
|
185
|
+
skeletonRows = candidates.map((row) => document.importNode(row, true));
|
|
192
186
|
insertBeforeEmpty(activeRowsRoot, empty, skeletonRows);
|
|
193
187
|
}
|
|
194
188
|
|
|
@@ -210,21 +204,6 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
210
204
|
);
|
|
211
205
|
}
|
|
212
206
|
|
|
213
|
-
function replaceRows(rows: readonly HTMLElement[]): void {
|
|
214
|
-
for (const row of rows) row.hidden = false;
|
|
215
|
-
mutateTablePreservingScroll(root, () => {
|
|
216
|
-
removeSkeleton();
|
|
217
|
-
detachRenderedRows();
|
|
218
|
-
insertBeforeEmpty(activeRowsRoot, empty, rows);
|
|
219
|
-
});
|
|
220
|
-
root.dispatchEvent(
|
|
221
|
-
new CustomEvent<TableRowsAppendedDetail>('table:rows-appended', {
|
|
222
|
-
bubbles: true,
|
|
223
|
-
detail: { rows },
|
|
224
|
-
}),
|
|
225
|
-
);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
207
|
function updateEmptyState(): void {
|
|
229
208
|
if (empty) empty.hidden = results.length > 0;
|
|
230
209
|
}
|
|
@@ -307,12 +286,10 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
307
286
|
TableLoadingState,
|
|
308
287
|
'pending' | 'refreshing' | 'appending'
|
|
309
288
|
> = 'appending',
|
|
310
|
-
requestedCount = batchSize,
|
|
311
|
-
replace = false,
|
|
312
289
|
): Promise<void> {
|
|
313
290
|
if (request || disposed || cursor >= results.length) return;
|
|
314
291
|
|
|
315
|
-
const target = results.slice(cursor, cursor +
|
|
292
|
+
const target = results.slice(cursor, cursor + batchSize);
|
|
316
293
|
if (target.length === 0) {
|
|
317
294
|
removeSkeleton();
|
|
318
295
|
updatePagination();
|
|
@@ -328,9 +305,7 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
328
305
|
request = activeRequest;
|
|
329
306
|
setPaginationState(activePagination, activeStatus, 'loading');
|
|
330
307
|
updateTableState(loadingState);
|
|
331
|
-
|
|
332
|
-
addSkeleton(target.length);
|
|
333
|
-
}
|
|
308
|
+
addSkeleton(target.length);
|
|
334
309
|
|
|
335
310
|
try {
|
|
336
311
|
await loadSources(missing, activeRequest.signal);
|
|
@@ -361,16 +336,9 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
361
336
|
return;
|
|
362
337
|
}
|
|
363
338
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
removeSkeleton();
|
|
367
|
-
appendRows(rows as HTMLElement[]);
|
|
368
|
-
}
|
|
339
|
+
removeSkeleton();
|
|
340
|
+
appendRows(rows as HTMLElement[]);
|
|
369
341
|
cursor += target.length;
|
|
370
|
-
retainedWindowSize = Math.max(
|
|
371
|
-
retainedWindowSize,
|
|
372
|
-
getRows(activeRowsRoot).length,
|
|
373
|
-
);
|
|
374
342
|
updatePagination();
|
|
375
343
|
updateTableState('ready');
|
|
376
344
|
}
|
|
@@ -435,48 +403,22 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
435
403
|
offset: number,
|
|
436
404
|
state: Extract<TableLoadingState, 'pending' | 'refreshing'>,
|
|
437
405
|
): void {
|
|
438
|
-
retainedWindowSize = Math.max(
|
|
439
|
-
retainedWindowSize,
|
|
440
|
-
getRows(activeRowsRoot).length,
|
|
441
|
-
);
|
|
442
406
|
generation += 1;
|
|
443
407
|
request?.abort();
|
|
444
408
|
request = null;
|
|
445
|
-
if (scheduledRenderFrame !== null) {
|
|
446
|
-
window.cancelAnimationFrame(scheduledRenderFrame);
|
|
447
|
-
scheduledRenderFrame = null;
|
|
448
|
-
}
|
|
449
|
-
observer.disconnect();
|
|
450
409
|
updateTableState(state);
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
mutateTablePreservingScroll(root, () => {
|
|
454
|
-
detachRenderedRows();
|
|
455
|
-
addSkeleton(retainedWindowSize);
|
|
456
|
-
});
|
|
457
|
-
|
|
410
|
+
addSkeleton(batchSize);
|
|
411
|
+
detachRenderedRows();
|
|
458
412
|
applyQuery();
|
|
459
413
|
cursor = Math.min(offset, results.length);
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
replaceRows([]);
|
|
469
|
-
updatePagination();
|
|
470
|
-
updateTableState('empty');
|
|
471
|
-
return;
|
|
472
|
-
}
|
|
473
|
-
void renderNextBatch(
|
|
474
|
-
state,
|
|
475
|
-
Math.min(retainedWindowSize, results.length - cursor),
|
|
476
|
-
true,
|
|
477
|
-
);
|
|
478
|
-
});
|
|
479
|
-
});
|
|
414
|
+
updateEmptyState();
|
|
415
|
+
if (results.length === 0) {
|
|
416
|
+
removeSkeleton();
|
|
417
|
+
updatePagination();
|
|
418
|
+
updateTableState('empty');
|
|
419
|
+
return;
|
|
420
|
+
}
|
|
421
|
+
void renderNextBatch(state);
|
|
480
422
|
}
|
|
481
423
|
|
|
482
424
|
function refresh(): void {
|
|
@@ -492,10 +434,6 @@ export function initTableProgressive(root: HTMLElement): () => void {
|
|
|
492
434
|
destroy() {
|
|
493
435
|
disposed = true;
|
|
494
436
|
request?.abort();
|
|
495
|
-
if (scheduledRenderFrame !== null) {
|
|
496
|
-
window.cancelAnimationFrame(scheduledRenderFrame);
|
|
497
|
-
scheduledRenderFrame = null;
|
|
498
|
-
}
|
|
499
437
|
observer.disconnect();
|
|
500
438
|
removeSkeleton();
|
|
501
439
|
activePagination.hidden = !fallbackLink;
|
|
@@ -4,7 +4,6 @@ import {
|
|
|
4
4
|
setTableProgressiveSort,
|
|
5
5
|
updateTableProgressiveEntry,
|
|
6
6
|
} from './tableProgressiveController';
|
|
7
|
-
import { mutateTablePreservingScroll } from './tableScrollPosition';
|
|
8
7
|
|
|
9
8
|
type SortDirection = 'ascending' | 'descending';
|
|
10
9
|
type SortType = 'number' | 'text';
|
|
@@ -97,11 +96,9 @@ export function initTableSort(root: HTMLElement): () => void {
|
|
|
97
96
|
orderDirty = activeState !== null;
|
|
98
97
|
if (rows.every((row, index) => row === sortedRows[index])) return;
|
|
99
98
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
rowsRoot.prepend(fragment);
|
|
104
|
-
});
|
|
99
|
+
const fragment = document.createDocumentFragment();
|
|
100
|
+
for (const row of sortedRows) fragment.append(row);
|
|
101
|
+
rowsRoot.prepend(fragment);
|
|
105
102
|
};
|
|
106
103
|
|
|
107
104
|
const scheduleSort = (): void => {
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
type ScrollRestoreState = {
|
|
2
|
-
frame: number;
|
|
3
|
-
originalOverflowAnchor: string;
|
|
4
|
-
scrollRoot: HTMLElement;
|
|
5
|
-
scrollTop: number;
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const restoreStates = new WeakMap<HTMLElement, ScrollRestoreState>();
|
|
9
|
-
|
|
10
|
-
export function mutateTablePreservingScroll(
|
|
11
|
-
root: HTMLElement,
|
|
12
|
-
mutation: () => void,
|
|
13
|
-
): void {
|
|
14
|
-
const scrollRoot = root.closest<HTMLElement>('[data-site-viewport]');
|
|
15
|
-
if (!scrollRoot) {
|
|
16
|
-
mutation();
|
|
17
|
-
return;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
const previous = restoreStates.get(root);
|
|
21
|
-
if (previous) window.cancelAnimationFrame(previous.frame);
|
|
22
|
-
const originalOverflowAnchor =
|
|
23
|
-
previous?.originalOverflowAnchor ?? root.style.overflowAnchor;
|
|
24
|
-
const scrollTop = scrollRoot.scrollTop;
|
|
25
|
-
|
|
26
|
-
root.style.overflowAnchor = 'none';
|
|
27
|
-
mutation();
|
|
28
|
-
scrollRoot.scrollTop = scrollTop;
|
|
29
|
-
|
|
30
|
-
const state: ScrollRestoreState = {
|
|
31
|
-
frame: window.requestAnimationFrame(() => {
|
|
32
|
-
scrollRoot.scrollTop = scrollTop;
|
|
33
|
-
root.style.overflowAnchor = originalOverflowAnchor;
|
|
34
|
-
restoreStates.delete(root);
|
|
35
|
-
}),
|
|
36
|
-
originalOverflowAnchor,
|
|
37
|
-
scrollRoot,
|
|
38
|
-
scrollTop,
|
|
39
|
-
};
|
|
40
|
-
restoreStates.set(root, state);
|
|
41
|
-
}
|