virtua 0.51.2 → 0.52.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +37 -13
- package/lib/angular/VGrid.d.ts +249 -0
- package/lib/angular/VList.d.ts +3 -3
- package/lib/angular/Virtualizer.d.ts +3 -3
- package/lib/angular/WindowVirtualizer.d.ts +3 -3
- package/lib/angular/index.d.ts +2 -0
- package/lib/angular/index.js +1150 -332
- package/lib/angular/index.js.map +1 -1
- package/lib/core/grid.d.ts +30 -0
- package/lib/core/index.cjs +480 -271
- package/lib/core/index.cjs.map +1 -1
- package/lib/core/index.d.ts +5 -3
- package/lib/core/index.js +436 -228
- package/lib/core/index.js.map +1 -1
- package/lib/core/layouts/grid.d.ts +21 -0
- package/lib/core/scroll-to.d.ts +50 -1
- package/lib/core/types.d.ts +0 -25
- package/lib/index.cjs +763 -565
- package/lib/index.cjs.map +1 -1
- package/lib/index.d.ts +2 -1
- package/lib/index.js +734 -518
- package/lib/index.js.map +1 -1
- package/lib/react/VGrid.d.ts +105 -80
- package/lib/react/index.d.ts +3 -2
- package/lib/solid/VGrid.d.ts +193 -0
- package/lib/solid/index.cjs +825 -301
- package/lib/solid/index.cjs.map +1 -1
- package/lib/solid/index.d.ts +3 -0
- package/lib/solid/index.js +797 -286
- package/lib/solid/index.js.map +1 -1
- package/lib/solid/index.jsx +760 -142
- package/lib/solid/index.jsx.map +1 -1
- package/lib/svelte/GridCell.svelte +44 -0
- package/lib/svelte/GridRow.svelte +42 -0
- package/lib/svelte/GridRowGroup.svelte +42 -0
- package/lib/svelte/VGrid.svelte +238 -0
- package/lib/svelte/VGrid.type.d.ts +185 -0
- package/lib/svelte/index.d.ts +3 -0
- package/lib/svelte/index.js +2 -1
- package/lib/vue/VGrid.d.ts +194 -0
- package/lib/vue/index.cjs +873 -368
- package/lib/vue/index.cjs.map +1 -1
- package/lib/vue/index.d.ts +3 -0
- package/lib/vue/index.js +861 -357
- package/lib/vue/index.js.map +1 -1
- package/package.json +4 -3
package/lib/solid/index.jsx
CHANGED
|
@@ -3,10 +3,11 @@ import { Dynamic, isServer } from "solid-js/web";
|
|
|
3
3
|
|
|
4
4
|
//#region src/core/utils.ts
|
|
5
5
|
var NULL = null;
|
|
6
|
+
var EMPTY = [];
|
|
6
7
|
var { min, max, abs, floor } = Math;
|
|
7
8
|
var clamp = (value, minValue, maxValue) => min(maxValue, max(minValue, value));
|
|
8
9
|
var sort = (arr) => {
|
|
9
|
-
return
|
|
10
|
+
return arr.sort((a, b) => a - b);
|
|
10
11
|
};
|
|
11
12
|
var timeout = setTimeout;
|
|
12
13
|
var cancelTimeout = clearTimeout;
|
|
@@ -51,6 +52,7 @@ var ACTION_ITEMS_LENGTH_CHANGE = 5;
|
|
|
51
52
|
var ACTION_START_OFFSET_CHANGE = 6;
|
|
52
53
|
var ACTION_MANUAL_SCROLL = 7;
|
|
53
54
|
var ACTION_BEFORE_MANUAL_SMOOTH_SCROLL = 8;
|
|
55
|
+
var ACTION_RELAYOUT = 9;
|
|
54
56
|
var UPDATE_VIRTUAL_STATE = 1;
|
|
55
57
|
var UPDATE_SIZE_EVENT = 2;
|
|
56
58
|
var UPDATE_SCROLL_EVENT = 4;
|
|
@@ -250,6 +252,11 @@ var createVirtualStore = ({ $getRange: getRange, $findIndex: findIndex, $getItem
|
|
|
250
252
|
_scrollMode = SCROLL_BY_MANUAL_SCROLL;
|
|
251
253
|
break;
|
|
252
254
|
}
|
|
255
|
+
case 9: {
|
|
256
|
+
applyJump(payload);
|
|
257
|
+
mutated = 1 + 2;
|
|
258
|
+
break;
|
|
259
|
+
}
|
|
253
260
|
case 8: {
|
|
254
261
|
_frozenRange = getRange(payload, payload + viewportSize);
|
|
255
262
|
mutated = 1;
|
|
@@ -382,10 +389,10 @@ var createListLayout = (length, itemSize, snapshot) => {
|
|
|
382
389
|
}
|
|
383
390
|
});
|
|
384
391
|
computedOffsetIndex = -1;
|
|
385
|
-
|
|
386
|
-
const len =
|
|
392
|
+
sort(measuredSizes);
|
|
393
|
+
const len = measuredSizes.length;
|
|
387
394
|
const mid = len / 2 | 0;
|
|
388
|
-
const median = len % 2 === 0 ? (
|
|
395
|
+
const median = len % 2 === 0 ? (measuredSizes[mid - 1] + measuredSizes[mid]) / 2 : measuredSizes[mid];
|
|
389
396
|
const prevDefaultItemSize = defaultItemSize;
|
|
390
397
|
return ((defaultItemSize = median) - prevDefaultItemSize) * max(startIndex - measuredCountBeforeStart, 0);
|
|
391
398
|
},
|
|
@@ -393,6 +400,459 @@ var createListLayout = (length, itemSize, snapshot) => {
|
|
|
393
400
|
};
|
|
394
401
|
};
|
|
395
402
|
|
|
403
|
+
//#endregion
|
|
404
|
+
//#region src/core/layouts/grid.ts
|
|
405
|
+
var getAxisLength = (axis) => typeof axis === "number" ? axis : axis.length;
|
|
406
|
+
var getAxisItem = (axis, index) => typeof axis === "number" ? index : axis[index];
|
|
407
|
+
var createGridLayout = (axis, size, gap = 0) => {
|
|
408
|
+
if (typeof size === "number") {
|
|
409
|
+
let length = getAxisLength(axis);
|
|
410
|
+
let itemSize = size;
|
|
411
|
+
const findIndex = (offset) => itemSize + gap ? clamp(floor(offset / (itemSize + gap)), 0, length - 1) : 0;
|
|
412
|
+
return {
|
|
413
|
+
$getRange: (startOffset, endOffset) => [findIndex(startOffset), findIndex(endOffset)],
|
|
414
|
+
$findIndex: findIndex,
|
|
415
|
+
$getItemOffset: (index) => index * (itemSize + gap),
|
|
416
|
+
$getItemSize: () => itemSize,
|
|
417
|
+
$setItemSize: () => false,
|
|
418
|
+
$isSizeEqual: () => false,
|
|
419
|
+
$getTotalSize: () => length ? length * (itemSize + gap) - gap : 0,
|
|
420
|
+
$getLength: () => length,
|
|
421
|
+
$setLength: (nextLength) => {
|
|
422
|
+
length = nextLength;
|
|
423
|
+
return 0;
|
|
424
|
+
},
|
|
425
|
+
$isMeasurable: () => false,
|
|
426
|
+
$setAxis: (_axis, nextSize, scrollOffset) => {
|
|
427
|
+
if (typeof nextSize !== "number" || nextSize === itemSize) {
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
const jump = findIndex(scrollOffset) * (nextSize - itemSize);
|
|
431
|
+
itemSize = nextSize;
|
|
432
|
+
return jump;
|
|
433
|
+
}
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
const isAuto = size === "auto";
|
|
437
|
+
let currentAxis;
|
|
438
|
+
let currentSize = size;
|
|
439
|
+
const length = getAxisLength(axis);
|
|
440
|
+
const autos = [];
|
|
441
|
+
const inner = createListLayout(length, undefined, [[], 40 + gap]);
|
|
442
|
+
const isMeasurable = (index) => isAuto || !!autos[index];
|
|
443
|
+
const layout = {
|
|
444
|
+
$getRange: inner.$getRange,
|
|
445
|
+
$findIndex: inner.$findIndex,
|
|
446
|
+
$getItemOffset: inner.$getItemOffset,
|
|
447
|
+
$getItemSize: (index) => inner.$getItemSize(index) - gap,
|
|
448
|
+
$setItemSize: (index, s) => isMeasurable(index) && inner.$setItemSize(index, s + gap),
|
|
449
|
+
$isSizeEqual: (index, s) => inner.$isSizeEqual(index, s + gap),
|
|
450
|
+
$getTotalSize: () => inner.$getLength() ? inner.$getTotalSize() - gap : 0,
|
|
451
|
+
$getLength: inner.$getLength,
|
|
452
|
+
$setLength: inner.$setLength,
|
|
453
|
+
$estimateDefaultSize: isAuto ? inner.$estimateDefaultSize : undefined,
|
|
454
|
+
$isMeasurable: isMeasurable,
|
|
455
|
+
$setAxis: (nextAxis, requestedSize, scrollOffset, mutable) => {
|
|
456
|
+
if (isAuto) {
|
|
457
|
+
return;
|
|
458
|
+
}
|
|
459
|
+
const nextSize = typeof requestedSize === "number" || requestedSize === "auto" ? currentSize : requestedSize;
|
|
460
|
+
const length = inner.$getLength();
|
|
461
|
+
if (!mutable && nextAxis === currentAxis && nextSize === currentSize && length === autos.length) {
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
currentAxis = nextAxis;
|
|
465
|
+
currentSize = nextSize;
|
|
466
|
+
autos.length = length;
|
|
467
|
+
const anchorIndex = inner.$findIndex(scrollOffset);
|
|
468
|
+
const prevOffset = inner.$getItemOffset(anchorIndex);
|
|
469
|
+
let changed;
|
|
470
|
+
for (let i = 0; i < length; i++) {
|
|
471
|
+
const item = nextAxis[i];
|
|
472
|
+
const itemSize = item !== null && typeof item === "object" ? item[nextSize] : null;
|
|
473
|
+
const isAutoItem = typeof itemSize !== "number";
|
|
474
|
+
if (!isAutoItem || !autos[i]) {
|
|
475
|
+
autos[i] = isAutoItem;
|
|
476
|
+
const target = isAutoItem ? -1 : itemSize + gap;
|
|
477
|
+
if (!inner.$isSizeEqual(i, target)) {
|
|
478
|
+
inner.$setItemSize(i, target);
|
|
479
|
+
changed = true;
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
if (!changed) {
|
|
484
|
+
return;
|
|
485
|
+
}
|
|
486
|
+
return inner.$getItemOffset(anchorIndex) - prevOffset;
|
|
487
|
+
}
|
|
488
|
+
};
|
|
489
|
+
layout.$setAxis(axis, size, 0);
|
|
490
|
+
return layout;
|
|
491
|
+
};
|
|
492
|
+
|
|
493
|
+
//#endregion
|
|
494
|
+
//#region src/core/grid.ts
|
|
495
|
+
var updateGridAxis = (store, layout, axis, size, mutable) => {
|
|
496
|
+
const length = getAxisLength(axis);
|
|
497
|
+
if (length !== store.$getItemsLength()) {
|
|
498
|
+
store.$update(5, [length]);
|
|
499
|
+
}
|
|
500
|
+
const jump = layout.$setAxis(axis, size, store.$getScrollOffset() - store.$getItemOffset(0), mutable);
|
|
501
|
+
if (jump != null) {
|
|
502
|
+
store.$update(9, jump);
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
var rowStatesCache = /*#__PURE__*/ new WeakMap();
|
|
506
|
+
var hasTrackIn = (extras, from, to, pinnedStart, start, end, trailStart) => {
|
|
507
|
+
if (from < pinnedStart || max(from, start) < min(to, end + 1) || trailStart < to) {
|
|
508
|
+
return true;
|
|
509
|
+
}
|
|
510
|
+
for (const i of extras) {
|
|
511
|
+
if (i >= from && i < to) {
|
|
512
|
+
return true;
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
return false;
|
|
516
|
+
};
|
|
517
|
+
var getSectionStarts = (sectionRows, pinnedStart, trailStart) => {
|
|
518
|
+
const starts = [];
|
|
519
|
+
for (const rowIndex of sectionRows) {
|
|
520
|
+
if (rowIndex >= pinnedStart && rowIndex < trailStart) {
|
|
521
|
+
starts.push(rowIndex);
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
return sort(starts);
|
|
525
|
+
};
|
|
526
|
+
var getSection = (starts, rowIndex, trailStart) => {
|
|
527
|
+
if (rowIndex >= trailStart) {
|
|
528
|
+
return -1;
|
|
529
|
+
}
|
|
530
|
+
let lo = 0;
|
|
531
|
+
let hi = starts.length;
|
|
532
|
+
while (lo < hi) {
|
|
533
|
+
const mid = lo + hi >> 1;
|
|
534
|
+
if (starts[mid] <= rowIndex) {
|
|
535
|
+
lo = mid + 1;
|
|
536
|
+
} else {
|
|
537
|
+
hi = mid;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
return lo - 1;
|
|
541
|
+
};
|
|
542
|
+
var addSectionHeader = (extras, sectionStarts, rowIndex, trailStart) => {
|
|
543
|
+
const section = getSection(sectionStarts, rowIndex, trailStart);
|
|
544
|
+
if (section >= 0) {
|
|
545
|
+
extras.push(sectionStarts[section]);
|
|
546
|
+
}
|
|
547
|
+
};
|
|
548
|
+
var getTrackIndexes = (extras, count, pinnedStart, start, end, trailStart) => {
|
|
549
|
+
const indexes = [];
|
|
550
|
+
for (let i = 0; i < pinnedStart; i++) {
|
|
551
|
+
indexes.push(i);
|
|
552
|
+
}
|
|
553
|
+
const extrasLength = extras.length;
|
|
554
|
+
let e = 0;
|
|
555
|
+
let last = pinnedStart - 1;
|
|
556
|
+
for (; e < extrasLength && extras[e] < start; e++) {
|
|
557
|
+
const i = extras[e];
|
|
558
|
+
if (i > last) {
|
|
559
|
+
indexes.push(i);
|
|
560
|
+
last = i;
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
for (let i = start; i <= end; i++) {
|
|
564
|
+
indexes.push(i);
|
|
565
|
+
}
|
|
566
|
+
last = end;
|
|
567
|
+
for (; e < extrasLength && extras[e] < trailStart; e++) {
|
|
568
|
+
const i = extras[e];
|
|
569
|
+
if (i > last) {
|
|
570
|
+
indexes.push(i);
|
|
571
|
+
last = i;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
for (let i = trailStart; i < count; i++) {
|
|
575
|
+
indexes.push(i);
|
|
576
|
+
}
|
|
577
|
+
return indexes;
|
|
578
|
+
};
|
|
579
|
+
var getSpanRowEnd = (span, rowCount) => min(span.rowIndex + (span.rowSpan || 1), rowCount);
|
|
580
|
+
var getSpanColEnd = (span, colCount) => min(span.colIndex + (span.colSpan || 1), colCount);
|
|
581
|
+
var getTemplate = (layout, indexes, measured, sortedCuts, measuredSize, count) => {
|
|
582
|
+
const indexesLength = indexes.length;
|
|
583
|
+
const cutsLength = sortedCuts.length;
|
|
584
|
+
let template = "[l0]";
|
|
585
|
+
let line = 0;
|
|
586
|
+
let i = 0;
|
|
587
|
+
let c = 0;
|
|
588
|
+
while (i < indexesLength || c < cutsLength) {
|
|
589
|
+
const index = i < indexesLength ? indexes[i] : count;
|
|
590
|
+
const cut = c < cutsLength ? sortedCuts[c] : count;
|
|
591
|
+
if (cut <= line) {
|
|
592
|
+
c++;
|
|
593
|
+
} else {
|
|
594
|
+
let to;
|
|
595
|
+
let size;
|
|
596
|
+
if (index === line) {
|
|
597
|
+
to = line + 1;
|
|
598
|
+
const m = measured[i];
|
|
599
|
+
size = m == null ? layout.$getItemSize(line) + "px" : m ? measuredSize : "minmax(" + layout.$getItemSize(line) + "px,auto)";
|
|
600
|
+
i++;
|
|
601
|
+
} else {
|
|
602
|
+
to = min(index, cut);
|
|
603
|
+
size = "minmax(" + (layout.$getItemOffset(to - 1) + layout.$getItemSize(to - 1) - layout.$getItemOffset(line)) + "px,auto)";
|
|
604
|
+
}
|
|
605
|
+
template += " " + size + " [l" + to + "]";
|
|
606
|
+
line = to;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
if (line < count) {
|
|
610
|
+
template += " minmax(" + (layout.$getTotalSize() - layout.$getItemOffset(line)) + "px,auto) [l" + count + "]";
|
|
611
|
+
}
|
|
612
|
+
return template;
|
|
613
|
+
};
|
|
614
|
+
var gridStyleToString = (style) => {
|
|
615
|
+
let css = "";
|
|
616
|
+
for (const key in style) {
|
|
617
|
+
css += key.replace(/[A-Z]/g, (c) => "-" + c.toLowerCase()) + ":" + style[key] + ";";
|
|
618
|
+
}
|
|
619
|
+
return css;
|
|
620
|
+
};
|
|
621
|
+
var createGridPlan = (rowLayout, colLayout, rowRange, colRange, headerRows = 0, sectionRows = EMPTY, footerRows = 0, headerCols = 0, footerCols = 0, spans = EMPTY, kept = EMPTY, sortedCell) => {
|
|
622
|
+
const rowCount = rowLayout.$getLength();
|
|
623
|
+
const colCount = colLayout.$getLength();
|
|
624
|
+
const rowPinnedStart = min(headerRows, rowCount);
|
|
625
|
+
const rowTrailStart = max(rowCount - footerRows, rowPinnedStart);
|
|
626
|
+
const colPinnedStart = min(headerCols, colCount);
|
|
627
|
+
const colTrailStart = max(colCount - footerCols, colPinnedStart);
|
|
628
|
+
const rowRangeStart = clamp(rowRange[0], rowPinnedStart, rowTrailStart);
|
|
629
|
+
const rowRangeEnd = min(rowRange[1], rowTrailStart - 1);
|
|
630
|
+
const colRangeStart = clamp(colRange[0], colPinnedStart, colTrailStart);
|
|
631
|
+
const colRangeEnd = min(colRange[1], colTrailStart - 1);
|
|
632
|
+
const sectionStarts = getSectionStarts(sectionRows, rowPinnedStart, rowTrailStart);
|
|
633
|
+
const rowHeaderCol = max(colPinnedStart - 1, 0);
|
|
634
|
+
const extraRows = [];
|
|
635
|
+
const extraCols = [];
|
|
636
|
+
const extraCells = [];
|
|
637
|
+
for (const cell of kept) {
|
|
638
|
+
if (cell.rowIndex < rowCount && cell.colIndex < colCount) {
|
|
639
|
+
extraCells.push(cell);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
const sectionLength = sectionStarts.length;
|
|
643
|
+
if (sectionLength) {
|
|
644
|
+
addSectionHeader(extraRows, sectionStarts, rowRangeStart, rowTrailStart);
|
|
645
|
+
extraCols.push(rowHeaderCol);
|
|
646
|
+
}
|
|
647
|
+
let waiting = spans;
|
|
648
|
+
let l = 0;
|
|
649
|
+
do {
|
|
650
|
+
for (; l < extraCells.length; l++) {
|
|
651
|
+
const { rowIndex, colIndex } = extraCells[l];
|
|
652
|
+
extraRows.push(rowIndex);
|
|
653
|
+
addSectionHeader(extraRows, sectionStarts, rowIndex, rowTrailStart);
|
|
654
|
+
extraCols.push(colIndex);
|
|
655
|
+
}
|
|
656
|
+
const rest = [];
|
|
657
|
+
for (const span of waiting) {
|
|
658
|
+
const row = span.rowIndex;
|
|
659
|
+
const col = span.colIndex;
|
|
660
|
+
const rowTo = getSpanRowEnd(span, rowCount);
|
|
661
|
+
const colTo = getSpanColEnd(span, colCount);
|
|
662
|
+
if (row < rowCount && col < colCount && (rowTo - row > 1 || colTo - col > 1)) {
|
|
663
|
+
if (hasTrackIn(extraRows, row, rowTo, rowPinnedStart, rowRangeStart, rowRangeEnd, rowTrailStart)) {
|
|
664
|
+
if (hasTrackIn(extraCols, col, colTo, colPinnedStart, colRangeStart, colRangeEnd, colTrailStart)) {
|
|
665
|
+
extraCells.push(span);
|
|
666
|
+
} else {
|
|
667
|
+
const section = getSection(sectionStarts, rowTo - 1, rowTrailStart);
|
|
668
|
+
if (row < rowPinnedStart || section >= 0 && sectionStarts[section] >= row) {
|
|
669
|
+
rest.push(span);
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
} else if (col < colPinnedStart) {
|
|
673
|
+
rest.push(span);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
waiting = rest;
|
|
678
|
+
} while (l < extraCells.length);
|
|
679
|
+
sort(extraRows);
|
|
680
|
+
sort(extraCols);
|
|
681
|
+
const rowIndexes = getTrackIndexes(extraRows, rowCount, rowPinnedStart, rowRangeStart, rowRangeEnd, rowTrailStart);
|
|
682
|
+
const cols = getTrackIndexes(extraCols, colCount, colPinnedStart, colRangeStart, colRangeEnd, colTrailStart);
|
|
683
|
+
const rowLength = rowIndexes.length;
|
|
684
|
+
const colLength = cols.length;
|
|
685
|
+
const spanCells = new Map();
|
|
686
|
+
const rowCuts = [];
|
|
687
|
+
const colCuts = [];
|
|
688
|
+
for (const span of extraCells) {
|
|
689
|
+
const rowTo = getSpanRowEnd(span, rowCount);
|
|
690
|
+
const colTo = getSpanColEnd(span, colCount);
|
|
691
|
+
rowCuts.push(rowTo);
|
|
692
|
+
colCuts.push(colTo);
|
|
693
|
+
const colStart = cols.indexOf(span.colIndex);
|
|
694
|
+
for (let i = rowIndexes.indexOf(span.rowIndex); i < rowLength && rowIndexes[i] < rowTo; i++) {
|
|
695
|
+
const rowKey = rowIndexes[i] * colCount;
|
|
696
|
+
for (let j = colStart; j < colLength && cols[j] < colTo; j++) {
|
|
697
|
+
spanCells.set(rowKey + cols[j], span);
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
}
|
|
701
|
+
const measuredCols = [];
|
|
702
|
+
for (const colIndex of cols) {
|
|
703
|
+
measuredCols.push(colLayout.$isMeasurable(colIndex) ? false : null);
|
|
704
|
+
}
|
|
705
|
+
const measuredRows = [];
|
|
706
|
+
const stickyTop = rowLayout.$getItemOffset(rowPinnedStart);
|
|
707
|
+
const groups = [];
|
|
708
|
+
let groupRows = groups;
|
|
709
|
+
const prev = rowStatesCache.get(rowLayout);
|
|
710
|
+
const rowStates = new Map();
|
|
711
|
+
for (const rowIndex of rowIndexes) {
|
|
712
|
+
const pinnedTop = rowIndex < rowPinnedStart;
|
|
713
|
+
const pinnedBottom = rowIndex >= rowTrailStart;
|
|
714
|
+
const rowInRangeOrPinnedToEnd = pinnedBottom || rowIndex >= rowRangeStart && rowIndex <= rowRangeEnd;
|
|
715
|
+
const section = getSection(sectionStarts, rowIndex, rowTrailStart);
|
|
716
|
+
const groupStart = pinnedTop ? 0 : pinnedBottom ? rowTrailStart : section < 0 ? -1 : sectionStarts[section];
|
|
717
|
+
if (rowIndex === groupStart) {
|
|
718
|
+
const groupEnd = pinnedTop ? rowPinnedStart : pinnedBottom ? rowCount : section + 1 < sectionLength ? sectionStarts[section + 1] : rowTrailStart;
|
|
719
|
+
rowCuts.push(groupEnd);
|
|
720
|
+
const rows = [];
|
|
721
|
+
groups.push({
|
|
722
|
+
$key: pinnedTop ? -1 : pinnedBottom ? -2 : -3 - groupStart,
|
|
723
|
+
$rows: rows,
|
|
724
|
+
$style: getBoxStyle(groupStart, groupEnd, pinnedTop || pinnedBottom ? 0 : null, pinnedBottom ? "bottom" : "top", 4)
|
|
725
|
+
});
|
|
726
|
+
groupRows = rows;
|
|
727
|
+
} else if (groupStart < 0) {
|
|
728
|
+
groupRows = groups;
|
|
729
|
+
}
|
|
730
|
+
const isSectionHeaderRow = section >= 0 && rowIndex === groupStart;
|
|
731
|
+
const rowTop = isSectionHeaderRow ? stickyTop : null;
|
|
732
|
+
const rowKey = rowIndex * colCount;
|
|
733
|
+
const prevRow = prev && prev.get(rowIndex);
|
|
734
|
+
const prevCells = prevRow && prevRow.$cells;
|
|
735
|
+
const rowCells = [];
|
|
736
|
+
let p = 0;
|
|
737
|
+
let measuredRow = rowLayout.$isMeasurable(rowIndex) ? false : null;
|
|
738
|
+
let rowEnd = rowIndex + 1;
|
|
739
|
+
let changed = false;
|
|
740
|
+
for (let i = 0; i < colLength; i++) {
|
|
741
|
+
const colIndex = cols[i];
|
|
742
|
+
const startPinned = colIndex < colPinnedStart;
|
|
743
|
+
const endPinned = colIndex >= colTrailStart;
|
|
744
|
+
const colInRangeOrPinnedToEnd = endPinned || colIndex >= colRangeStart && colIndex <= colRangeEnd;
|
|
745
|
+
const span = spanCells.get(rowKey + colIndex);
|
|
746
|
+
if (span ? span.rowIndex !== rowIndex || span.colIndex !== colIndex : !(rowInRangeOrPinnedToEnd && colInRangeOrPinnedToEnd) && !pinnedTop && !isSectionHeaderRow && !startPinned) {
|
|
747
|
+
continue;
|
|
748
|
+
}
|
|
749
|
+
const rowTo = span ? getSpanRowEnd(span, rowCount) : rowIndex + 1;
|
|
750
|
+
const colTo = span ? getSpanColEnd(span, colCount) : colIndex + 1;
|
|
751
|
+
const spansRows = rowTo - rowIndex > 1;
|
|
752
|
+
const spansCols = colTo - colIndex > 1;
|
|
753
|
+
const spanning = spansRows || spansCols;
|
|
754
|
+
const rowSpan = spanning ? rowTo - rowIndex : undefined;
|
|
755
|
+
const colSpan = spanning ? colTo - colIndex : undefined;
|
|
756
|
+
let measureRowIndex;
|
|
757
|
+
let measureColIndex;
|
|
758
|
+
rowEnd = max(rowEnd, rowTo);
|
|
759
|
+
const stickyStart = startPinned ? colLayout.$getItemOffset(colIndex) : null;
|
|
760
|
+
const stickyEnd = endPinned ? colLayout.$getTotalSize() - colLayout.$getItemOffset(colTo - 1) - colLayout.$getItemSize(colTo - 1) : null;
|
|
761
|
+
if (measuredRow === false && !spansRows) {
|
|
762
|
+
measureRowIndex = rowIndex;
|
|
763
|
+
measuredRow = true;
|
|
764
|
+
}
|
|
765
|
+
if (measuredCols[i] === false && !spansCols) {
|
|
766
|
+
measureColIndex = colIndex;
|
|
767
|
+
measuredCols[i] = true;
|
|
768
|
+
}
|
|
769
|
+
const role = pinnedTop ? "columnheader" : colIndex === rowHeaderCol && (startPinned || isSectionHeaderRow) ? "rowheader" : "cell";
|
|
770
|
+
const sortOrder = role !== "cell" && sortedCell && sortedCell.rowIndex === rowIndex && sortedCell.colIndex === colIndex ? sortedCell.order : undefined;
|
|
771
|
+
let cell;
|
|
772
|
+
if (prevCells) {
|
|
773
|
+
while (p < prevCells.length && prevCells[p].$col < colIndex) {
|
|
774
|
+
p++;
|
|
775
|
+
}
|
|
776
|
+
if (p < prevCells.length) {
|
|
777
|
+
cell = prevCells[p];
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
if (!cell || cell.$col !== colIndex || cell.$rowSpan !== rowSpan || cell.$colSpan !== colSpan || cell.$start !== stickyStart || cell.$end !== stickyEnd || cell.$measureRow !== measureRowIndex || cell.$measureCol !== measureColIndex || cell.$role !== role || cell.$sort !== sortOrder) {
|
|
781
|
+
const style = {
|
|
782
|
+
contain: "layout style",
|
|
783
|
+
display: "grid",
|
|
784
|
+
gridArea: spanning ? "1/l" + colIndex + "/l" + rowTo + "/l" + colTo : "1/l" + colIndex
|
|
785
|
+
};
|
|
786
|
+
if (spansRows) {
|
|
787
|
+
style["height"] = "0px";
|
|
788
|
+
style["minHeight"] = "100%";
|
|
789
|
+
style["zIndex"] = 1;
|
|
790
|
+
}
|
|
791
|
+
if (spansCols) {
|
|
792
|
+
style["width"] = "0px";
|
|
793
|
+
style["minWidth"] = "100%";
|
|
794
|
+
}
|
|
795
|
+
if (startPinned || endPinned) {
|
|
796
|
+
if (startPinned) {
|
|
797
|
+
style["insetInlineStart"] = stickyStart + "px";
|
|
798
|
+
} else {
|
|
799
|
+
style["insetInlineEnd"] = stickyEnd + "px";
|
|
800
|
+
}
|
|
801
|
+
style["position"] = "sticky";
|
|
802
|
+
style["zIndex"] = 2;
|
|
803
|
+
}
|
|
804
|
+
cell = {
|
|
805
|
+
$col: colIndex,
|
|
806
|
+
$rowSpan: rowSpan,
|
|
807
|
+
$colSpan: colSpan,
|
|
808
|
+
$measureRow: measureRowIndex,
|
|
809
|
+
$measureCol: measureColIndex,
|
|
810
|
+
$role: role,
|
|
811
|
+
$sort: sortOrder,
|
|
812
|
+
$style: style,
|
|
813
|
+
$start: stickyStart,
|
|
814
|
+
$end: stickyEnd
|
|
815
|
+
};
|
|
816
|
+
changed = true;
|
|
817
|
+
}
|
|
818
|
+
rowCells.push(cell);
|
|
819
|
+
}
|
|
820
|
+
measuredRows.push(measuredRow);
|
|
821
|
+
if (!rowCells.length) {
|
|
822
|
+
continue;
|
|
823
|
+
}
|
|
824
|
+
const row = prevRow && !changed && prevRow.$cells.length === rowCells.length && prevRow.$top === rowTop ? prevRow : {
|
|
825
|
+
$row: rowIndex,
|
|
826
|
+
$cells: rowCells,
|
|
827
|
+
$style: getBoxStyle(rowIndex, rowEnd, rowTop, "top", 3),
|
|
828
|
+
$top: rowTop
|
|
829
|
+
};
|
|
830
|
+
rowStates.set(rowIndex, row);
|
|
831
|
+
groupRows.push(row);
|
|
832
|
+
}
|
|
833
|
+
rowStatesCache.set(rowLayout, rowStates);
|
|
834
|
+
return {
|
|
835
|
+
$rowTemplate: getTemplate(rowLayout, rowIndexes, measuredRows, sort(rowCuts), "max-content", rowCount),
|
|
836
|
+
$colTemplate: getTemplate(colLayout, cols, measuredCols, sort(colCuts), "minmax(max-content,auto)", colCount),
|
|
837
|
+
$groups: groups
|
|
838
|
+
};
|
|
839
|
+
};
|
|
840
|
+
var getBoxStyle = (from, to, inset, edge, zIndex) => {
|
|
841
|
+
const style = {
|
|
842
|
+
display: "grid",
|
|
843
|
+
gridTemplateRows: "subgrid",
|
|
844
|
+
gridTemplateColumns: "subgrid",
|
|
845
|
+
gridColumn: "1/-1",
|
|
846
|
+
gridRow: "l" + from + "/l" + to
|
|
847
|
+
};
|
|
848
|
+
if (inset != null) {
|
|
849
|
+
style["position"] = "sticky";
|
|
850
|
+
style[edge] = inset + "px";
|
|
851
|
+
style["zIndex"] = zIndex;
|
|
852
|
+
}
|
|
853
|
+
return style;
|
|
854
|
+
};
|
|
855
|
+
|
|
396
856
|
//#endregion
|
|
397
857
|
//#region src/core/observer.ts
|
|
398
858
|
var createResizeObserver = (cb) => {
|
|
@@ -572,18 +1032,18 @@ var createContainerDriver = (store, isHorizontal) => {
|
|
|
572
1032
|
let viewportElement;
|
|
573
1033
|
let scrollObserver;
|
|
574
1034
|
let initialized = createPromise();
|
|
575
|
-
const sizeKey = isHorizontal ? "width" : "height";
|
|
576
1035
|
const mountedIndexes = new WeakMap();
|
|
577
1036
|
const resizeObserver = createResizeObserver((entries) => {
|
|
578
1037
|
const resizes = [];
|
|
579
|
-
for (const { target, contentRect } of entries) {
|
|
580
|
-
if (!target.offsetParent) continue;
|
|
1038
|
+
for (const { target, contentRect: { width, height } } of entries) {
|
|
581
1039
|
if (target === viewportElement) {
|
|
582
|
-
|
|
583
|
-
|
|
1040
|
+
if (width || height) {
|
|
1041
|
+
store.$update(4, isHorizontal ? width : height);
|
|
1042
|
+
}
|
|
1043
|
+
} else if (target.offsetParent) {
|
|
584
1044
|
const index = mountedIndexes.get(target);
|
|
585
1045
|
if (index != null) {
|
|
586
|
-
resizes.push([index,
|
|
1046
|
+
resizes.push([index, isHorizontal ? width : height]);
|
|
587
1047
|
}
|
|
588
1048
|
}
|
|
589
1049
|
}
|
|
@@ -637,19 +1097,17 @@ var createWindowDriver = (store, isHorizontal) => {
|
|
|
637
1097
|
let getBaseOffset;
|
|
638
1098
|
let onViewportResize;
|
|
639
1099
|
let initialized = createPromise();
|
|
640
|
-
const sizeKey = isHorizontal ? "width" : "height";
|
|
641
1100
|
const mountedIndexes = new WeakMap();
|
|
642
1101
|
const resizeObserver = createResizeObserver((entries) => {
|
|
643
1102
|
const resizes = [];
|
|
644
|
-
for (const { target, contentRect } of entries) {
|
|
1103
|
+
for (const { target, contentRect: { width, height } } of entries) {
|
|
645
1104
|
if (target === viewportElement) {
|
|
646
1105
|
onViewportResize && onViewportResize();
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
resizes.push([index, contentRect[sizeKey]]);
|
|
1106
|
+
} else if (target.offsetParent) {
|
|
1107
|
+
const index = mountedIndexes.get(target);
|
|
1108
|
+
if (index != null) {
|
|
1109
|
+
resizes.push([index, isHorizontal ? width : height]);
|
|
1110
|
+
}
|
|
653
1111
|
}
|
|
654
1112
|
}
|
|
655
1113
|
if (resizes.length) {
|
|
@@ -718,96 +1176,55 @@ var createContainerGridDriver = (rowStore, colStore) => {
|
|
|
718
1176
|
let rowScrollObserver;
|
|
719
1177
|
let colScrollObserver;
|
|
720
1178
|
let initialized = createPromise();
|
|
721
|
-
const
|
|
722
|
-
const
|
|
723
|
-
const maybeCachedColIndexes = new Set();
|
|
724
|
-
const sizeCache = new Map();
|
|
725
|
-
const getKey = (rowIndex, colIndex) => `${rowIndex}-${colIndex}`;
|
|
1179
|
+
const mountedRowIndexes = new WeakMap();
|
|
1180
|
+
const mountedColIndexes = new WeakMap();
|
|
726
1181
|
const resizeObserver = createResizeObserver((entries) => {
|
|
727
|
-
const
|
|
728
|
-
const
|
|
1182
|
+
const rowResizes = [];
|
|
1183
|
+
const colResizes = [];
|
|
729
1184
|
for (const { target, contentRect: { width, height } } of entries) {
|
|
730
|
-
if (!target.offsetParent) continue;
|
|
731
1185
|
if (target === viewportElement) {
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
} else {
|
|
745
|
-
if (prevSize[0] !== height) {
|
|
746
|
-
rowResized = true;
|
|
747
|
-
}
|
|
748
|
-
if (prevSize[1] !== width) {
|
|
749
|
-
colResized = true;
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
if (rowResized) {
|
|
753
|
-
resizedRows.add(rowIndex);
|
|
754
|
-
}
|
|
755
|
-
if (colResized) {
|
|
756
|
-
resizedCols.add(colIndex);
|
|
757
|
-
}
|
|
758
|
-
if (rowResized || colResized) {
|
|
759
|
-
sizeCache.set(key, [height, width]);
|
|
760
|
-
}
|
|
1186
|
+
if (width || height) {
|
|
1187
|
+
rowStore.$update(4, height);
|
|
1188
|
+
colStore.$update(4, width);
|
|
1189
|
+
}
|
|
1190
|
+
} else if (target.offsetParent) {
|
|
1191
|
+
const rowIndex = mountedRowIndexes.get(target);
|
|
1192
|
+
const colIndex = mountedColIndexes.get(target);
|
|
1193
|
+
if (rowIndex != null) {
|
|
1194
|
+
rowResizes.push([rowIndex, height]);
|
|
1195
|
+
}
|
|
1196
|
+
if (colIndex != null) {
|
|
1197
|
+
colResizes.push([colIndex, width]);
|
|
761
1198
|
}
|
|
762
1199
|
}
|
|
763
1200
|
}
|
|
764
|
-
if (
|
|
765
|
-
|
|
766
|
-
resizedRows.forEach((rowIndex) => {
|
|
767
|
-
let maxHeight = 0;
|
|
768
|
-
maybeCachedColIndexes.forEach((colIndex) => {
|
|
769
|
-
const size = sizeCache.get(getKey(rowIndex, colIndex));
|
|
770
|
-
if (size) {
|
|
771
|
-
maxHeight = max(maxHeight, size[0]);
|
|
772
|
-
}
|
|
773
|
-
});
|
|
774
|
-
if (maxHeight) {
|
|
775
|
-
heightResizes.push([rowIndex, maxHeight]);
|
|
776
|
-
}
|
|
777
|
-
});
|
|
778
|
-
rowStore.$update(3, heightResizes);
|
|
1201
|
+
if (rowResizes.length) {
|
|
1202
|
+
rowStore.$update(3, rowResizes);
|
|
779
1203
|
}
|
|
780
|
-
if (
|
|
781
|
-
|
|
782
|
-
resizedCols.forEach((colIndex) => {
|
|
783
|
-
let maxWidth = 0;
|
|
784
|
-
maybeCachedRowIndexes.forEach((rowIndex) => {
|
|
785
|
-
const size = sizeCache.get(getKey(rowIndex, colIndex));
|
|
786
|
-
if (size) {
|
|
787
|
-
maxWidth = max(maxWidth, size[1]);
|
|
788
|
-
}
|
|
789
|
-
});
|
|
790
|
-
if (maxWidth) {
|
|
791
|
-
widthResizes.push([colIndex, maxWidth]);
|
|
792
|
-
}
|
|
793
|
-
});
|
|
794
|
-
colStore.$update(3, widthResizes);
|
|
1204
|
+
if (colResizes.length) {
|
|
1205
|
+
colStore.$update(3, colResizes);
|
|
795
1206
|
}
|
|
796
1207
|
});
|
|
797
1208
|
return {
|
|
798
|
-
$
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
1209
|
+
async $scroll(isHorizontal, getTargetOffset) {
|
|
1210
|
+
if (await initialized[0]) {
|
|
1211
|
+
(isHorizontal ? colScrollObserver : rowScrollObserver)._scroll(getTargetOffset);
|
|
1212
|
+
}
|
|
1213
|
+
},
|
|
1214
|
+
$observe(containerElement) {
|
|
1215
|
+
const viewport = viewportElement = containerElement.parentElement;
|
|
1216
|
+
resizeObserver._observe(viewport);
|
|
1217
|
+
const observe = (store, isHorizontal) => createScrollObserver(store, viewport, viewport, isHorizontal, isHorizontal && getComputedStyle(viewport).direction === "rtl", () => {
|
|
1218
|
+
const overflowKey = isHorizontal ? "overflowX" : "overflowY";
|
|
802
1219
|
const style = viewport.style;
|
|
803
1220
|
const prev = style[overflowKey];
|
|
804
1221
|
style[overflowKey] = "hidden";
|
|
805
1222
|
timeout(() => {
|
|
806
1223
|
style[overflowKey] = prev;
|
|
807
1224
|
});
|
|
808
|
-
};
|
|
809
|
-
rowScrollObserver =
|
|
810
|
-
colScrollObserver =
|
|
1225
|
+
});
|
|
1226
|
+
rowScrollObserver = observe(rowStore, false);
|
|
1227
|
+
colScrollObserver = observe(colStore, true);
|
|
811
1228
|
initialized[1](true);
|
|
812
1229
|
},
|
|
813
1230
|
$dispose() {
|
|
@@ -818,41 +1235,19 @@ var createContainerGridDriver = (rowStore, colStore) => {
|
|
|
818
1235
|
initialized = createPromise();
|
|
819
1236
|
},
|
|
820
1237
|
$observeItem(el, rowIndex, colIndex) {
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
1238
|
+
if (rowIndex != null) {
|
|
1239
|
+
mountedRowIndexes.set(el, rowIndex);
|
|
1240
|
+
}
|
|
1241
|
+
if (colIndex != null) {
|
|
1242
|
+
mountedColIndexes.set(el, colIndex);
|
|
1243
|
+
}
|
|
824
1244
|
resizeObserver._observe(el);
|
|
825
1245
|
return () => {
|
|
826
|
-
|
|
1246
|
+
mountedRowIndexes.delete(el);
|
|
1247
|
+
mountedColIndexes.delete(el);
|
|
827
1248
|
resizeObserver._unobserve(el);
|
|
828
1249
|
};
|
|
829
1250
|
},
|
|
830
|
-
$resizeRows(rows) {
|
|
831
|
-
for (const [r] of rows) {
|
|
832
|
-
for (let c = 0; c < colStore.$getItemsLength(); c++) {
|
|
833
|
-
sizeCache.delete(getKey(r, c));
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
rowStore.$update(3, rows);
|
|
837
|
-
},
|
|
838
|
-
$resizeCols(cols) {
|
|
839
|
-
for (const [c] of cols) {
|
|
840
|
-
for (let r = 0; r < rowStore.$getItemsLength(); r++) {
|
|
841
|
-
sizeCache.delete(getKey(r, c));
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
colStore.$update(3, cols);
|
|
845
|
-
},
|
|
846
|
-
async $scrollX(getTargetOffset, smooth) {
|
|
847
|
-
if (await initialized[0]) {
|
|
848
|
-
colScrollObserver._scroll(getTargetOffset, smooth);
|
|
849
|
-
}
|
|
850
|
-
},
|
|
851
|
-
async $scrollY(getTargetOffset, smooth) {
|
|
852
|
-
if (await initialized[0]) {
|
|
853
|
-
rowScrollObserver._scroll(getTargetOffset, smooth);
|
|
854
|
-
}
|
|
855
|
-
},
|
|
856
1251
|
$effect() {
|
|
857
1252
|
rowScrollObserver && rowScrollObserver._fixScrollJump();
|
|
858
1253
|
colScrollObserver && colScrollObserver._fixScrollJump();
|
|
@@ -885,32 +1280,65 @@ var scrollToIndex = (driver, store, index, { align, smooth, offset = 0 } = {}) =
|
|
|
885
1280
|
return offset + driver.$getBaseOffset() + store.$getItemOffset(index) + (align === "end" ? store.$getItemSize(index) - store.$getViewportSize() : align === "center" ? (store.$getItemSize(index) - store.$getViewportSize()) / 2 : 0);
|
|
886
1281
|
}, smooth);
|
|
887
1282
|
};
|
|
888
|
-
var gridScrollTo = (driver,
|
|
889
|
-
if (
|
|
890
|
-
driver.$
|
|
1283
|
+
var gridScrollTo = (driver, vertical, horizontal) => {
|
|
1284
|
+
if (vertical != null) {
|
|
1285
|
+
driver.$scroll(false, () => vertical);
|
|
891
1286
|
}
|
|
892
|
-
if (
|
|
893
|
-
driver.$
|
|
1287
|
+
if (horizontal != null) {
|
|
1288
|
+
driver.$scroll(true, () => horizontal);
|
|
894
1289
|
}
|
|
895
1290
|
};
|
|
896
|
-
var gridScrollBy = (driver, rowStore, colStore,
|
|
897
|
-
if (
|
|
898
|
-
const
|
|
899
|
-
driver.$
|
|
1291
|
+
var gridScrollBy = (driver, rowStore, colStore, vertical, horizontal) => {
|
|
1292
|
+
if (vertical != null) {
|
|
1293
|
+
const offset = vertical + rowStore.$getScrollOffset();
|
|
1294
|
+
driver.$scroll(false, () => offset);
|
|
900
1295
|
}
|
|
901
|
-
if (
|
|
902
|
-
const
|
|
903
|
-
driver.$
|
|
1296
|
+
if (horizontal != null) {
|
|
1297
|
+
const offset = horizontal + colStore.$getScrollOffset();
|
|
1298
|
+
driver.$scroll(true, () => offset);
|
|
904
1299
|
}
|
|
905
1300
|
};
|
|
906
|
-
var
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
1301
|
+
var scrollGridAxisToIndex = (driver, store, header, sections, footer, index, align, isHorizontal) => {
|
|
1302
|
+
const count = store.$getItemsLength();
|
|
1303
|
+
const pinnedStart = min(header, count);
|
|
1304
|
+
const trailStart = max(count - footer, pinnedStart);
|
|
1305
|
+
index = clamp(index, 0, count - 1);
|
|
1306
|
+
const starts = getSectionStarts(sections, pinnedStart, trailStart);
|
|
1307
|
+
const section = getSection(starts, index, trailStart);
|
|
1308
|
+
const sectionHeader = section < 0 ? -1 : starts[section];
|
|
1309
|
+
const getInsets = () => [store.$getItemOffset(pinnedStart) - store.$getItemOffset(0) + (sectionHeader < 0 || sectionHeader === index ? 0 : store.$getItemOffset(sectionHeader + 1) - store.$getItemOffset(sectionHeader)), store.$getItemOffset(count) - store.$getItemOffset(trailStart)];
|
|
1310
|
+
if (align === "nearest") {
|
|
1311
|
+
if (index < pinnedStart || index >= trailStart) {
|
|
1312
|
+
return;
|
|
1313
|
+
}
|
|
1314
|
+
const [insetStart, insetEnd] = getInsets();
|
|
1315
|
+
const scrollOffset = store.$getScrollOffset();
|
|
1316
|
+
const itemSize = store.$getItemSize(index);
|
|
1317
|
+
let itemOffset = store.$getItemOffset(index);
|
|
1318
|
+
if (sectionHeader === index) {
|
|
1319
|
+
const lastIndex = (section + 1 < starts.length ? starts[section + 1] : trailStart) - 1;
|
|
1320
|
+
itemOffset = max(itemOffset, min(scrollOffset + insetStart, store.$getItemOffset(lastIndex) + store.$getItemSize(lastIndex) - itemSize));
|
|
1321
|
+
}
|
|
1322
|
+
if (itemOffset < scrollOffset + insetStart) {
|
|
1323
|
+
align = "start";
|
|
1324
|
+
} else if (itemOffset + itemSize > scrollOffset + store.$getViewportSize() - insetEnd) {
|
|
1325
|
+
align = "end";
|
|
1326
|
+
} else {
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
910
1329
|
}
|
|
911
|
-
|
|
912
|
-
const
|
|
913
|
-
|
|
1330
|
+
driver.$scroll(isHorizontal, () => {
|
|
1331
|
+
const [insetStart, insetEnd] = getInsets();
|
|
1332
|
+
const rest = store.$getItemSize(index) - store.$getViewportSize();
|
|
1333
|
+
return store.$getItemOffset(index) + (align === "end" ? rest + insetEnd : align === "center" ? (rest + insetEnd - insetStart) / 2 : -insetStart);
|
|
1334
|
+
});
|
|
1335
|
+
};
|
|
1336
|
+
var gridScrollToIndex = (driver, rowStore, colStore, headerRows = 0, sectionRows = EMPTY, footerRows = 0, headerCols = 0, footerCols = 0, { rowIndex, colIndex, rowAlign, colAlign }) => {
|
|
1337
|
+
if (rowIndex != null) {
|
|
1338
|
+
scrollGridAxisToIndex(driver, rowStore, headerRows, sectionRows, footerRows, rowIndex, rowAlign, false);
|
|
1339
|
+
}
|
|
1340
|
+
if (colIndex != null) {
|
|
1341
|
+
scrollGridAxisToIndex(driver, colStore, headerCols, EMPTY, footerCols, colIndex, colAlign, true);
|
|
914
1342
|
}
|
|
915
1343
|
};
|
|
916
1344
|
|
|
@@ -1219,5 +1647,195 @@ var WindowVirtualizer = (props) => {
|
|
|
1219
1647
|
};
|
|
1220
1648
|
|
|
1221
1649
|
//#endregion
|
|
1222
|
-
|
|
1650
|
+
//#region src/solid/VGrid.tsx
|
|
1651
|
+
var GridCell = (props) => {
|
|
1652
|
+
let elementRef;
|
|
1653
|
+
const [state, setState] = createSignal(undefined);
|
|
1654
|
+
createComputed(() => setState(props._state));
|
|
1655
|
+
const measureRowIndex = createMemo(() => state().$measureRow);
|
|
1656
|
+
const measureColIndex = createMemo(() => state().$measureCol);
|
|
1657
|
+
const row = createMemo(() => props._row);
|
|
1658
|
+
const col = createMemo(() => props._col);
|
|
1659
|
+
const children = createMemo(() => {
|
|
1660
|
+
const r = row();
|
|
1661
|
+
const c = col();
|
|
1662
|
+
return untrack(() => props._children(r, c, {
|
|
1663
|
+
rowIndex: props._rowIndex,
|
|
1664
|
+
colIndex: state().$col
|
|
1665
|
+
}));
|
|
1666
|
+
});
|
|
1667
|
+
createEffect(on([measureRowIndex, measureColIndex], ([rowIndex, colIndex]) => {
|
|
1668
|
+
if (!elementRef || rowIndex == null && colIndex == null) return;
|
|
1669
|
+
onCleanup(props._resizer(elementRef, rowIndex, colIndex));
|
|
1670
|
+
}));
|
|
1671
|
+
const style = createMemo(() => gridStyleToString(state().$style));
|
|
1672
|
+
return <div ref={elementRef} role={state().$role} aria-colindex={state().$col + 1} aria-rowspan={state().$rowSpan} aria-colspan={state().$colSpan} aria-sort={state().$sort} style={style()}>
|
|
1673
|
+
{children()}
|
|
1674
|
+
</div>;
|
|
1675
|
+
};
|
|
1676
|
+
var GridRow = (props) => {
|
|
1677
|
+
const state = createMemo(() => props._state);
|
|
1678
|
+
const cols = createMemo(() => state().$cells.map((cell) => cell.$col));
|
|
1679
|
+
const style = createMemo(() => gridStyleToString(state().$style));
|
|
1680
|
+
return <div role="row" aria-rowindex={state().$row + 1} style={style()}>
|
|
1681
|
+
<For each={cols()}>
|
|
1682
|
+
{(colIndex, i) => <GridCell _state={state().$cells[i()]} _children={props._children} _row={props._row} _col={getAxisItem(props._cols, colIndex)} _rowIndex={state().$row} _resizer={props._resizer} />}
|
|
1683
|
+
</For>
|
|
1684
|
+
</div>;
|
|
1685
|
+
};
|
|
1686
|
+
var GridRowGroup = (props) => {
|
|
1687
|
+
const rows = createMemo(() => props._state.$rows.map((row) => row.$row));
|
|
1688
|
+
const style = createMemo(() => gridStyleToString(props._state.$style));
|
|
1689
|
+
return <div role="rowgroup" style={style()}>
|
|
1690
|
+
<For each={rows()}>
|
|
1691
|
+
{(rowIndex, i) => <GridRow _state={props._state.$rows[i()]} _children={props._children} _row={getAxisItem(props._rows, rowIndex)} _cols={props._cols} _resizer={props._resizer} />}
|
|
1692
|
+
</For>
|
|
1693
|
+
</div>;
|
|
1694
|
+
};
|
|
1695
|
+
var VGrid = (props) => {
|
|
1696
|
+
let containerRef;
|
|
1697
|
+
const withDefaults = mergeProps({ gap: 0 }, props);
|
|
1698
|
+
const { rows, cols, rowHeight, colWidth, gap } = withDefaults;
|
|
1699
|
+
const [, others] = splitProps(props, [
|
|
1700
|
+
"ref",
|
|
1701
|
+
"children",
|
|
1702
|
+
"rows",
|
|
1703
|
+
"cols",
|
|
1704
|
+
"rowHeight",
|
|
1705
|
+
"colWidth",
|
|
1706
|
+
"headerRows",
|
|
1707
|
+
"sectionRows",
|
|
1708
|
+
"footerRows",
|
|
1709
|
+
"headerCols",
|
|
1710
|
+
"footerCols",
|
|
1711
|
+
"spans",
|
|
1712
|
+
"keepMounted",
|
|
1713
|
+
"bufferSize",
|
|
1714
|
+
"gap",
|
|
1715
|
+
"ariaSort",
|
|
1716
|
+
"onVerticalScroll",
|
|
1717
|
+
"onHorizontalScroll",
|
|
1718
|
+
"onScrollEnd",
|
|
1719
|
+
"style"
|
|
1720
|
+
]);
|
|
1721
|
+
const rowLayout = createGridLayout(rows, rowHeight, gap);
|
|
1722
|
+
const colLayout = createGridLayout(cols, colWidth, gap);
|
|
1723
|
+
const rowStore = createVirtualStore(rowLayout);
|
|
1724
|
+
const colStore = createVirtualStore(colLayout);
|
|
1725
|
+
const driver = createContainerGridDriver(rowStore, colStore);
|
|
1726
|
+
const getStateVersion = () => rowStore.$getStateVersion() + colStore.$getStateVersion();
|
|
1727
|
+
const [stateVersion, setRerender] = createSignal(getStateVersion());
|
|
1728
|
+
const rerender = () => setRerender(getStateVersion());
|
|
1729
|
+
rowStore.$subscribe(1, rerender);
|
|
1730
|
+
colStore.$subscribe(1, rerender);
|
|
1731
|
+
let scrolled = false;
|
|
1732
|
+
rowStore.$subscribe(4, () => {
|
|
1733
|
+
scrolled = true;
|
|
1734
|
+
props.onVerticalScroll && props.onVerticalScroll(rowStore.$getScrollOffset());
|
|
1735
|
+
});
|
|
1736
|
+
colStore.$subscribe(4, () => {
|
|
1737
|
+
scrolled = true;
|
|
1738
|
+
props.onHorizontalScroll && props.onHorizontalScroll(colStore.$getScrollOffset());
|
|
1739
|
+
});
|
|
1740
|
+
const notifyScrollEnd = () => {
|
|
1741
|
+
if (scrolled && !rowStore.$isScrolling() && !colStore.$isScrolling()) {
|
|
1742
|
+
scrolled = false;
|
|
1743
|
+
props.onScrollEnd && props.onScrollEnd();
|
|
1744
|
+
}
|
|
1745
|
+
};
|
|
1746
|
+
rowStore.$subscribe(8, notifyScrollEnd);
|
|
1747
|
+
colStore.$subscribe(8, notifyScrollEnd);
|
|
1748
|
+
createComputed(() => {
|
|
1749
|
+
updateGridAxis(rowStore, rowLayout, props.rows, props.rowHeight, true);
|
|
1750
|
+
});
|
|
1751
|
+
createComputed(() => {
|
|
1752
|
+
updateGridAxis(colStore, colLayout, props.cols, props.colWidth, true);
|
|
1753
|
+
});
|
|
1754
|
+
const rowCount = createMemo(() => stateVersion() && rowStore.$getItemsLength());
|
|
1755
|
+
const colCount = createMemo(() => stateVersion() && colStore.$getItemsLength());
|
|
1756
|
+
const plan = createMemo(() => {
|
|
1757
|
+
stateVersion();
|
|
1758
|
+
return createGridPlan(rowLayout, colLayout, rowStore.$getRange(props.bufferSize), colStore.$getRange(props.bufferSize), props.headerRows, props.sectionRows, props.footerRows, props.headerCols, props.footerCols, props.spans, props.keepMounted, props.ariaSort);
|
|
1759
|
+
});
|
|
1760
|
+
const keys = createMemo(() => plan().$groups.map((state) => "$rows" in state ? state.$key : state.$row));
|
|
1761
|
+
const isScrolling = createMemo(() => stateVersion() && (rowStore.$isScrolling() || colStore.$isScrolling()));
|
|
1762
|
+
const containerStyle = createMemo(() => {
|
|
1763
|
+
const { $rowTemplate, $colTemplate } = plan();
|
|
1764
|
+
const marginTop = rowStore.$getItemOffset(0);
|
|
1765
|
+
const marginInlineStart = colStore.$getItemOffset(0);
|
|
1766
|
+
return {
|
|
1767
|
+
contain: "size style",
|
|
1768
|
+
"overflow-anchor": "none",
|
|
1769
|
+
flex: "none",
|
|
1770
|
+
display: "grid",
|
|
1771
|
+
"grid-template-rows": $rowTemplate,
|
|
1772
|
+
"grid-template-columns": $colTemplate,
|
|
1773
|
+
gap: withDefaults.gap + "px",
|
|
1774
|
+
"margin-top": marginTop + "px",
|
|
1775
|
+
"margin-inline-start": marginInlineStart + "px",
|
|
1776
|
+
height: getScrollSize(rowStore) - marginTop + "px",
|
|
1777
|
+
"pointer-events": isScrolling() ? "none" : undefined
|
|
1778
|
+
};
|
|
1779
|
+
});
|
|
1780
|
+
const ref = props.ref;
|
|
1781
|
+
if (!isServer && ref) {
|
|
1782
|
+
ref({
|
|
1783
|
+
get verticalScrollOffset() {
|
|
1784
|
+
return rowStore.$getScrollOffset();
|
|
1785
|
+
},
|
|
1786
|
+
get horizontalScrollOffset() {
|
|
1787
|
+
return colStore.$getScrollOffset();
|
|
1788
|
+
},
|
|
1789
|
+
get scrollHeight() {
|
|
1790
|
+
return getScrollSize(rowStore);
|
|
1791
|
+
},
|
|
1792
|
+
get scrollWidth() {
|
|
1793
|
+
return getScrollSize(colStore);
|
|
1794
|
+
},
|
|
1795
|
+
get viewportHeight() {
|
|
1796
|
+
return rowStore.$getViewportSize();
|
|
1797
|
+
},
|
|
1798
|
+
get viewportWidth() {
|
|
1799
|
+
return colStore.$getViewportSize();
|
|
1800
|
+
},
|
|
1801
|
+
findRowIndex: rowStore.$findItemIndex,
|
|
1802
|
+
findColIndex: colStore.$findItemIndex,
|
|
1803
|
+
getRowOffset: rowStore.$getItemOffset,
|
|
1804
|
+
getColOffset: colStore.$getItemOffset,
|
|
1805
|
+
getRowSize: rowStore.$getItemSize,
|
|
1806
|
+
getColSize: colStore.$getItemSize,
|
|
1807
|
+
scrollToIndex: (opts) => gridScrollToIndex(driver, rowStore, colStore, props.headerRows, props.sectionRows, props.footerRows, props.headerCols, props.footerCols, opts),
|
|
1808
|
+
scrollTo: ({ vertical, horizontal }) => gridScrollTo(driver, vertical, horizontal),
|
|
1809
|
+
scrollBy: ({ vertical, horizontal }) => gridScrollBy(driver, rowStore, colStore, vertical, horizontal)
|
|
1810
|
+
});
|
|
1811
|
+
onCleanup(() => ref());
|
|
1812
|
+
}
|
|
1813
|
+
onMount(() => {
|
|
1814
|
+
driver.$observe(containerRef);
|
|
1815
|
+
onCleanup(() => {
|
|
1816
|
+
rowStore.$dispose();
|
|
1817
|
+
colStore.$dispose();
|
|
1818
|
+
driver.$dispose();
|
|
1819
|
+
});
|
|
1820
|
+
});
|
|
1821
|
+
createEffect(on(stateVersion, () => {
|
|
1822
|
+
driver.$effect();
|
|
1823
|
+
}));
|
|
1824
|
+
return <div role="table" aria-rowcount={rowCount()} aria-colcount={colCount()} {...others} style={{
|
|
1825
|
+
overflow: "auto",
|
|
1826
|
+
contain: "strict",
|
|
1827
|
+
width: "100%",
|
|
1828
|
+
height: "100%",
|
|
1829
|
+
...props.style
|
|
1830
|
+
}}>
|
|
1831
|
+
<div ref={containerRef} style={containerStyle()}>
|
|
1832
|
+
<For each={keys()}>
|
|
1833
|
+
{(key, i) => key < 0 ? <GridRowGroup _state={plan().$groups[i()]} _children={props.children} _rows={props.rows} _cols={props.cols} _resizer={driver.$observeItem} /> : <GridRow _state={plan().$groups[i()]} _children={props.children} _row={getAxisItem(props.rows, key)} _cols={props.cols} _resizer={driver.$observeItem} />}
|
|
1834
|
+
</For>
|
|
1835
|
+
</div>
|
|
1836
|
+
</div>;
|
|
1837
|
+
};
|
|
1838
|
+
|
|
1839
|
+
//#endregion
|
|
1840
|
+
export { VGrid, VList, Virtualizer, WindowVirtualizer };
|
|
1223
1841
|
//# sourceMappingURL=index.jsx.map
|