virtua 0.52.1 → 0.52.3

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.
@@ -405,14 +405,30 @@ var createListLayout = (length, itemSize, snapshot) => {
405
405
  var getAxisLength = (axis) => typeof axis === "number" ? axis : axis.length;
406
406
  var getAxisItem = (axis, index) => typeof axis === "number" ? index : axis[index];
407
407
  var createGridLayout = (axis, size, gap = 0) => {
408
+ let header = 0;
409
+ let footer = 0;
410
+ const setPinned = (nextHeader = 0, nextFooter = 0) => {
411
+ header = nextHeader;
412
+ footer = nextFooter;
413
+ };
414
+ const getPinnedStart = (length) => min(header, length);
415
+ const getTrailStart = (length) => max(length - footer, getPinnedStart(length));
416
+ const pinRange = (getRange, getOffset, length, startOffset, endOffset) => {
417
+ const insetStart = getOffset(getPinnedStart(length));
418
+ const insetEnd = getOffset(length) - getOffset(getTrailStart(length));
419
+ const start = startOffset + (insetStart ? insetStart - gap : 0);
420
+ return getRange(start, max(start, endOffset - (insetEnd ? insetEnd - gap : 0)));
421
+ };
408
422
  if (typeof size === "number") {
409
423
  let length = getAxisLength(axis);
410
424
  let itemSize = size;
411
425
  const findIndex = (offset) => itemSize + gap ? clamp(floor(offset / (itemSize + gap)), 0, length - 1) : 0;
426
+ const getItemOffset = (index) => index * (itemSize + gap);
427
+ const findRange = (startOffset, endOffset) => [findIndex(startOffset), findIndex(endOffset)];
412
428
  return {
413
- $getRange: (startOffset, endOffset) => [findIndex(startOffset), findIndex(endOffset)],
429
+ $getRange: (startOffset, endOffset) => pinRange(findRange, getItemOffset, length, startOffset, endOffset),
414
430
  $findIndex: findIndex,
415
- $getItemOffset: (index) => index * (itemSize + gap),
431
+ $getItemOffset: getItemOffset,
416
432
  $getItemSize: () => itemSize,
417
433
  $setItemSize: () => false,
418
434
  $isSizeEqual: () => false,
@@ -423,6 +439,9 @@ var createGridLayout = (axis, size, gap = 0) => {
423
439
  return 0;
424
440
  },
425
441
  $isMeasurable: () => false,
442
+ $setPinned: setPinned,
443
+ $getPinnedStart: () => getPinnedStart(length),
444
+ $getTrailStart: () => getTrailStart(length),
426
445
  $setAxis: (_axis, nextSize, scrollOffset) => {
427
446
  if (typeof nextSize !== "number" || nextSize === itemSize) {
428
447
  return;
@@ -441,7 +460,7 @@ var createGridLayout = (axis, size, gap = 0) => {
441
460
  const inner = createListLayout(length, undefined, [[], 40 + gap]);
442
461
  const isMeasurable = (index) => isAuto || !!autos[index];
443
462
  const layout = {
444
- $getRange: inner.$getRange,
463
+ $getRange: (startOffset, endOffset) => pinRange(inner.$getRange, inner.$getItemOffset, inner.$getLength(), startOffset, endOffset),
445
464
  $findIndex: inner.$findIndex,
446
465
  $getItemOffset: inner.$getItemOffset,
447
466
  $getItemSize: (index) => inner.$getItemSize(index) - gap,
@@ -452,6 +471,9 @@ var createGridLayout = (axis, size, gap = 0) => {
452
471
  $setLength: inner.$setLength,
453
472
  $estimateDefaultSize: isAuto ? inner.$estimateDefaultSize : undefined,
454
473
  $isMeasurable: isMeasurable,
474
+ $setPinned: setPinned,
475
+ $getPinnedStart: () => getPinnedStart(inner.$getLength()),
476
+ $getTrailStart: () => getTrailStart(inner.$getLength()),
455
477
  $setAxis: (nextAxis, requestedSize, scrollOffset, mutable) => {
456
478
  if (isAuto) {
457
479
  return;
@@ -492,8 +514,9 @@ var createGridLayout = (axis, size, gap = 0) => {
492
514
 
493
515
  //#endregion
494
516
  //#region src/core/grid.ts
495
- var updateGridAxis = (store, layout, axis, size, mutable) => {
517
+ var updateGridAxis = (store, layout, axis, size, header, footer, mutable) => {
496
518
  const length = getAxisLength(axis);
519
+ layout.$setPinned(header, footer);
497
520
  if (length !== store.$getItemsLength()) {
498
521
  store.$update(5, [length]);
499
522
  }
@@ -503,17 +526,7 @@ var updateGridAxis = (store, layout, axis, size, mutable) => {
503
526
  }
504
527
  };
505
528
  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
- };
529
+ var hasVisibleTrack = (from, to, pinnedStart, start, end, trailStart) => from < pinnedStart || max(from, start) < min(to, end + 1) || trailStart < to;
517
530
  var getSectionStarts = (sectionRows, pinnedStart, trailStart) => {
518
531
  const starts = [];
519
532
  for (const rowIndex of sectionRows) {
@@ -523,7 +536,7 @@ var getSectionStarts = (sectionRows, pinnedStart, trailStart) => {
523
536
  }
524
537
  return sort(starts);
525
538
  };
526
- var getSection = (starts, rowIndex, trailStart) => {
539
+ var getSectionIndex = (starts, rowIndex, trailStart) => {
527
540
  if (rowIndex >= trailStart) {
528
541
  return -1;
529
542
  }
@@ -539,38 +552,27 @@ var getSection = (starts, rowIndex, trailStart) => {
539
552
  }
540
553
  return lo - 1;
541
554
  };
542
- var addSectionHeader = (extras, sectionStarts, rowIndex, trailStart) => {
543
- const section = getSection(sectionStarts, rowIndex, trailStart);
544
- if (section >= 0) {
545
- extras.push(sectionStarts[section]);
555
+ var addExtras = (indexes, extras, e, bound, lastRendered) => {
556
+ const extrasLength = extras.length;
557
+ for (; e < extrasLength && extras[e] < bound; e++) {
558
+ const i = extras[e];
559
+ if (i > lastRendered) {
560
+ indexes.push(i);
561
+ lastRendered = i;
562
+ }
546
563
  }
564
+ return e;
547
565
  };
548
566
  var getTrackIndexes = (extras, count, pinnedStart, start, end, trailStart) => {
549
567
  const indexes = [];
550
568
  for (let i = 0; i < pinnedStart; i++) {
551
569
  indexes.push(i);
552
570
  }
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
- }
571
+ const e = addExtras(indexes, extras, 0, start, pinnedStart - 1);
563
572
  for (let i = start; i <= end; i++) {
564
573
  indexes.push(i);
565
574
  }
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
- }
575
+ addExtras(indexes, extras, e, trailStart, end);
574
576
  for (let i = trailStart; i < count; i++) {
575
577
  indexes.push(i);
576
578
  }
@@ -585,29 +587,24 @@ var getTemplate = (layout, indexes, measured, sortedCuts, measuredSize, count) =
585
587
  let line = 0;
586
588
  let i = 0;
587
589
  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) {
590
+ while (line < count) {
591
+ while (c < cutsLength && sortedCuts[c] <= line) {
592
592
  c++;
593
+ }
594
+ const index = i < indexesLength ? indexes[i] : count;
595
+ let to;
596
+ let size;
597
+ if (index === line) {
598
+ to = line + 1;
599
+ const m = measured[i];
600
+ size = m == null ? layout.$getItemSize(line) + "px" : m ? measuredSize : "minmax(" + layout.$getItemSize(line) + "px,auto)";
601
+ i++;
593
602
  } 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;
603
+ to = min(index, c < cutsLength ? sortedCuts[c] : count);
604
+ size = "minmax(" + (layout.$getItemOffset(to - 1) + layout.$getItemSize(to - 1) - layout.$getItemOffset(line)) + "px,auto)";
607
605
  }
608
- }
609
- if (line < count) {
610
- template += " minmax(" + (layout.$getTotalSize() - layout.$getItemOffset(line)) + "px,auto) [l" + count + "]";
606
+ template += " " + size + " [l" + to + "]";
607
+ line = to;
611
608
  }
612
609
  return template;
613
610
  };
@@ -618,13 +615,13 @@ var gridStyleToString = (style) => {
618
615
  }
619
616
  return css;
620
617
  };
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);
618
+ var createGridPlan = (rowLayout, colLayout, rowRange, colRange, sectionRows = EMPTY, spans = EMPTY, kept = EMPTY, sortedCell) => {
619
+ const totalRowCount = rowLayout.$getLength();
620
+ const totalColCount = colLayout.$getLength();
621
+ const rowPinnedStart = rowLayout.$getPinnedStart();
622
+ const rowTrailStart = rowLayout.$getTrailStart();
623
+ const colPinnedStart = colLayout.$getPinnedStart();
624
+ const colTrailStart = colLayout.$getTrailStart();
628
625
  const rowRangeStart = clamp(rowRange[0], rowPinnedStart, rowTrailStart);
629
626
  const rowRangeEnd = min(rowRange[1], rowTrailStart - 1);
630
627
  const colRangeStart = clamp(colRange[0], colPinnedStart, colTrailStart);
@@ -635,65 +632,59 @@ var createGridPlan = (rowLayout, colLayout, rowRange, colRange, headerRows = 0,
635
632
  const extraCols = [];
636
633
  const extraCells = [];
637
634
  for (const cell of kept) {
638
- if (cell.rowIndex < rowCount && cell.colIndex < colCount) {
635
+ if (cell.rowIndex < totalRowCount && cell.colIndex < totalColCount) {
639
636
  extraCells.push(cell);
640
637
  }
641
638
  }
639
+ const keptLength = extraCells.length;
642
640
  const sectionLength = sectionStarts.length;
643
- if (sectionLength) {
644
- addSectionHeader(extraRows, sectionStarts, rowRangeStart, rowTrailStart);
645
- extraCols.push(rowHeaderCol);
641
+ const firstSection = getSectionIndex(sectionStarts, rowRangeStart, rowTrailStart);
642
+ const firstSectionStart = firstSection < 0 ? -1 : sectionStarts[firstSection];
643
+ if (firstSectionStart >= 0) {
644
+ extraRows.push(firstSectionStart);
646
645
  }
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
- }
646
+ for (const span of spans) {
647
+ const row = span.rowIndex;
648
+ const col = span.colIndex;
649
+ const rowTo = getSpanRowEnd(span, totalRowCount);
650
+ const colTo = getSpanColEnd(span, totalColCount);
651
+ if (row < totalRowCount && col < totalColCount && (rowTo - row > 1 || colTo - col > 1)) {
652
+ let isLaid = (hasVisibleTrack(row, rowTo, rowPinnedStart, rowRangeStart, rowRangeEnd, rowTrailStart) || firstSectionStart >= row && firstSectionStart < rowTo) && hasVisibleTrack(col, colTo, colPinnedStart, colRangeStart, colRangeEnd, colTrailStart);
653
+ for (let k = 0; !isLaid && k < keptLength; k++) {
654
+ const { rowIndex, colIndex } = extraCells[k];
655
+ isLaid = rowIndex >= row && rowIndex < rowTo && colIndex >= col && colIndex < colTo;
675
656
  }
657
+ if (isLaid) {
658
+ extraCells.push(span);
659
+ }
660
+ }
661
+ }
662
+ for (const { rowIndex, colIndex } of extraCells) {
663
+ const section = getSectionIndex(sectionStarts, rowIndex, rowTrailStart);
664
+ extraRows.push(rowIndex);
665
+ if (section >= 0) {
666
+ extraRows.push(sectionStarts[section]);
676
667
  }
677
- waiting = rest;
678
- } while (l < extraCells.length);
668
+ extraCols.push(colIndex);
669
+ }
679
670
  sort(extraRows);
680
671
  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;
672
+ const rows = getTrackIndexes(extraRows, totalRowCount, rowPinnedStart, rowRangeStart, rowRangeEnd, rowTrailStart);
673
+ const cols = getTrackIndexes(extraCols, totalColCount, colPinnedStart, colRangeStart, colRangeEnd, colTrailStart);
674
+ const rowsLength = rows.length;
675
+ const colsLength = cols.length;
685
676
  const spanCells = new Map();
686
677
  const rowCuts = [];
687
678
  const colCuts = [];
688
679
  for (const span of extraCells) {
689
- const rowTo = getSpanRowEnd(span, rowCount);
690
- const colTo = getSpanColEnd(span, colCount);
680
+ const rowTo = getSpanRowEnd(span, totalRowCount);
681
+ const colTo = getSpanColEnd(span, totalColCount);
691
682
  rowCuts.push(rowTo);
692
683
  colCuts.push(colTo);
693
684
  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++) {
685
+ for (let i = rows.indexOf(span.rowIndex); i < rowsLength && rows[i] < rowTo; i++) {
686
+ const rowKey = rows[i] * totalColCount;
687
+ for (let j = colStart; j < colsLength && cols[j] < colTo; j++) {
697
688
  spanCells.set(rowKey + cols[j], span);
698
689
  }
699
690
  }
@@ -703,122 +694,125 @@ var createGridPlan = (rowLayout, colLayout, rowRange, colRange, headerRows = 0,
703
694
  measuredCols.push(colLayout.$isMeasurable(colIndex) ? false : null);
704
695
  }
705
696
  const measuredRows = [];
706
- const stickyTop = rowLayout.$getItemOffset(rowPinnedStart);
697
+ const sectionHeaderTop = rowLayout.$getItemOffset(rowPinnedStart);
707
698
  const groups = [];
708
699
  let groupRows = groups;
709
700
  const prev = rowStatesCache.get(rowLayout);
710
701
  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];
702
+ for (const rowIndex of rows) {
703
+ const isRowPinnedStart = rowIndex < rowPinnedStart;
704
+ const isRowPinnedEnd = rowIndex >= rowTrailStart;
705
+ const section = getSectionIndex(sectionStarts, rowIndex, rowTrailStart);
706
+ const groupStart = isRowPinnedStart ? 0 : isRowPinnedEnd ? rowTrailStart : section < 0 ? -1 : sectionStarts[section];
717
707
  if (rowIndex === groupStart) {
718
- const groupEnd = pinnedTop ? rowPinnedStart : pinnedBottom ? rowCount : section + 1 < sectionLength ? sectionStarts[section + 1] : rowTrailStart;
708
+ const groupEnd = isRowPinnedStart ? rowPinnedStart : isRowPinnedEnd ? totalRowCount : section + 1 < sectionLength ? sectionStarts[section + 1] : rowTrailStart;
719
709
  rowCuts.push(groupEnd);
720
- const rows = [];
710
+ const groupedRows = [];
721
711
  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)
712
+ $key: isRowPinnedStart ? -1 : isRowPinnedEnd ? -2 : -3 - groupStart,
713
+ $rows: groupedRows,
714
+ $style: getBoxStyle(groupStart, groupEnd, isRowPinnedStart || isRowPinnedEnd ? 0 : null, isRowPinnedEnd ? "bottom" : "top", 4)
725
715
  });
726
- groupRows = rows;
716
+ groupRows = groupedRows;
727
717
  } else if (groupStart < 0) {
728
718
  groupRows = groups;
729
719
  }
730
720
  const isSectionHeaderRow = section >= 0 && rowIndex === groupStart;
731
- const rowTop = isSectionHeaderRow ? stickyTop : null;
732
- const rowKey = rowIndex * colCount;
721
+ const isRowVisible = isRowPinnedStart || isRowPinnedEnd || rowIndex === firstSectionStart || rowIndex >= rowRangeStart && rowIndex <= rowRangeEnd;
722
+ const rowTop = isSectionHeaderRow ? sectionHeaderTop : null;
723
+ const rowKey = rowIndex * totalColCount;
733
724
  const prevRow = prev && prev.get(rowIndex);
734
725
  const prevCells = prevRow && prevRow.$cells;
735
726
  const rowCells = [];
736
727
  let p = 0;
737
728
  let measuredRow = rowLayout.$isMeasurable(rowIndex) ? false : null;
738
729
  let rowEnd = rowIndex + 1;
739
- let changed = false;
740
- for (let i = 0; i < colLength; i++) {
730
+ let hasChanged = false;
731
+ for (let i = 0; i < colsLength; i++) {
741
732
  const colIndex = cols[i];
742
- const startPinned = colIndex < colPinnedStart;
743
- const endPinned = colIndex >= colTrailStart;
744
- const colInRangeOrPinnedToEnd = endPinned || colIndex >= colRangeStart && colIndex <= colRangeEnd;
733
+ const isColPinnedStart = colIndex < colPinnedStart;
734
+ const isColPinnedEnd = colIndex >= colTrailStart;
735
+ const isColVisible = isColPinnedStart || isColPinnedEnd || colIndex >= colRangeStart && colIndex <= colRangeEnd;
745
736
  const span = spanCells.get(rowKey + colIndex);
746
- if (span ? span.rowIndex === rowIndex && span.colIndex === colIndex : rowInRangeOrPinnedToEnd && colInRangeOrPinnedToEnd || pinnedTop || isSectionHeaderRow || startPinned) {
747
- const rowTo = span ? getSpanRowEnd(span, rowCount) : rowIndex + 1;
748
- const colTo = span ? getSpanColEnd(span, colCount) : colIndex + 1;
749
- const spansRows = rowTo - rowIndex > 1;
750
- const spansCols = colTo - colIndex > 1;
751
- const spanning = spansRows || spansCols;
752
- const rowSpan = spanning ? rowTo - rowIndex : undefined;
753
- const colSpan = spanning ? colTo - colIndex : undefined;
737
+ if (span ? span.rowIndex === rowIndex && span.colIndex === colIndex : isRowVisible && isColVisible) {
738
+ const rowTo = span ? getSpanRowEnd(span, totalRowCount) : rowIndex + 1;
739
+ const colTo = span ? getSpanColEnd(span, totalColCount) : colIndex + 1;
740
+ const rowSpan = rowTo - rowIndex;
741
+ const colSpan = colTo - colIndex;
742
+ const isSpanningRows = rowSpan > 1;
743
+ const isSpanningCols = colSpan > 1;
744
+ const isSpanning = isSpanningRows || isSpanningCols;
754
745
  let measureRowIndex;
755
746
  let measureColIndex;
756
747
  rowEnd = max(rowEnd, rowTo);
757
- const stickyStart = startPinned ? colLayout.$getItemOffset(colIndex) : null;
758
- const stickyEnd = endPinned ? colLayout.$getTotalSize() - colLayout.$getItemOffset(colTo - 1) - colLayout.$getItemSize(colTo - 1) : null;
759
- if (measuredRow === false && !spansRows) {
748
+ const stickyStart = isColPinnedStart ? colLayout.$getItemOffset(colIndex) : null;
749
+ const stickyEnd = isColPinnedEnd ? colLayout.$getTotalSize() - colLayout.$getItemOffset(colTo - 1) - colLayout.$getItemSize(colTo - 1) : null;
750
+ if (measuredRow === false && !isSpanningRows) {
760
751
  measureRowIndex = rowIndex;
761
752
  measuredRow = true;
762
753
  }
763
- if (measuredCols[i] === false && !spansCols) {
754
+ if (measuredCols[i] === false && !isSpanningCols) {
764
755
  measureColIndex = colIndex;
765
756
  measuredCols[i] = true;
766
757
  }
767
- const role = pinnedTop ? "columnheader" : colIndex === rowHeaderCol && (startPinned || isSectionHeaderRow) ? "rowheader" : "cell";
768
- const sortOrder = role !== "cell" && sortedCell && sortedCell.rowIndex === rowIndex && sortedCell.colIndex === colIndex ? sortedCell.order : undefined;
758
+ const role = isRowPinnedStart ? "columnheader" : colIndex === rowHeaderCol && (isColPinnedStart || isSectionHeaderRow) ? "rowheader" : "cell";
759
+ const ariaRowSpan = isSpanning ? rowSpan : undefined;
760
+ const ariaColSpan = isSpanning ? colSpan : undefined;
761
+ const ariaSort = role !== "cell" && sortedCell && sortedCell.rowIndex === rowIndex && sortedCell.colIndex === colIndex ? sortedCell.order : undefined;
769
762
  let cell;
770
763
  if (prevCells) {
771
- while (p < prevCells.length && prevCells[p].$col < colIndex) {
764
+ const prevCellsLength = prevCells.length;
765
+ while (p < prevCellsLength && prevCells[p].$col < colIndex) {
772
766
  p++;
773
767
  }
774
- if (p < prevCells.length) {
768
+ if (p < prevCellsLength && prevCells[p].$col === colIndex) {
775
769
  cell = prevCells[p];
776
770
  }
777
771
  }
778
- 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) {
772
+ if (!cell || cell.$rowSpan !== ariaRowSpan || cell.$colSpan !== ariaColSpan || cell.$start !== stickyStart || cell.$end !== stickyEnd || cell.$measureRow !== measureRowIndex || cell.$measureCol !== measureColIndex || cell.$role !== role || cell.$sort !== ariaSort) {
773
+ let gridArea = "1/l" + colIndex;
774
+ if (isSpanning) {
775
+ gridArea += "/l" + rowTo + "/l" + colTo;
776
+ }
779
777
  const style = {
780
778
  contain: "layout style",
781
779
  display: "grid",
782
- gridArea: spanning ? "1/l" + colIndex + "/l" + rowTo + "/l" + colTo : "1/l" + colIndex
780
+ gridArea
783
781
  };
784
- if (spansRows) {
782
+ if (isSpanningRows) {
785
783
  style["height"] = "0px";
786
784
  style["minHeight"] = "100%";
787
785
  style["zIndex"] = 1;
788
786
  }
789
- if (spansCols) {
787
+ if (isSpanningCols) {
790
788
  style["width"] = "0px";
791
789
  style["minWidth"] = "100%";
792
790
  }
793
- if (startPinned || endPinned) {
794
- if (startPinned) {
795
- style["insetInlineStart"] = stickyStart + "px";
796
- } else {
797
- style["insetInlineEnd"] = stickyEnd + "px";
798
- }
791
+ if (isColPinnedStart || isColPinnedEnd) {
792
+ style[isColPinnedStart ? "insetInlineStart" : "insetInlineEnd"] = (isColPinnedStart ? stickyStart : stickyEnd) + "px";
799
793
  style["position"] = "sticky";
800
794
  style["zIndex"] = 2;
801
795
  }
802
796
  cell = {
803
797
  $col: colIndex,
804
- $rowSpan: rowSpan,
805
- $colSpan: colSpan,
798
+ $rowSpan: ariaRowSpan,
799
+ $colSpan: ariaColSpan,
806
800
  $measureRow: measureRowIndex,
807
801
  $measureCol: measureColIndex,
808
802
  $role: role,
809
- $sort: sortOrder,
803
+ $sort: ariaSort,
810
804
  $style: style,
811
805
  $start: stickyStart,
812
806
  $end: stickyEnd
813
807
  };
814
- changed = true;
808
+ hasChanged = true;
815
809
  }
816
810
  rowCells.push(cell);
817
811
  }
818
812
  }
819
813
  measuredRows.push(measuredRow);
820
814
  if (rowCells.length) {
821
- const row = prevRow && !changed && prevRow.$cells.length === rowCells.length && prevRow.$top === rowTop ? prevRow : {
815
+ const row = prevRow && !hasChanged && prevRow.$cells.length === rowCells.length && prevRow.$top === rowTop ? prevRow : {
822
816
  $row: rowIndex,
823
817
  $cells: rowCells,
824
818
  $style: getBoxStyle(rowIndex, rowEnd, rowTop, "top", 3),
@@ -830,8 +824,8 @@ var createGridPlan = (rowLayout, colLayout, rowRange, colRange, headerRows = 0,
830
824
  }
831
825
  rowStatesCache.set(rowLayout, rowStates);
832
826
  return {
833
- $rowTemplate: getTemplate(rowLayout, rowIndexes, measuredRows, sort(rowCuts), "max-content", rowCount),
834
- $colTemplate: getTemplate(colLayout, cols, measuredCols, sort(colCuts), "minmax(max-content,auto)", colCount),
827
+ $rowTemplate: getTemplate(rowLayout, rows, measuredRows, sort(rowCuts), "max-content", totalRowCount),
828
+ $colTemplate: getTemplate(colLayout, cols, measuredCols, sort(colCuts), "minmax(max-content,auto)", totalColCount),
835
829
  $groups: groups
836
830
  };
837
831
  };
@@ -1296,47 +1290,49 @@ var gridScrollBy = (driver, rowStore, colStore, vertical, horizontal) => {
1296
1290
  driver.$scroll(true, () => offset);
1297
1291
  }
1298
1292
  };
1299
- var scrollGridAxisToIndex = (driver, store, header, sections, footer, index, align, isHorizontal) => {
1293
+ var scrollGridAxisToIndex = (driver, store, layout, sections, index, align, isHorizontal) => {
1300
1294
  const count = store.$getItemsLength();
1301
- const pinnedStart = min(header, count);
1302
- const trailStart = max(count - footer, pinnedStart);
1295
+ const pinnedStart = layout.$getPinnedStart();
1296
+ const trailStart = layout.$getTrailStart();
1303
1297
  index = clamp(index, 0, count - 1);
1304
1298
  const starts = getSectionStarts(sections, pinnedStart, trailStart);
1305
- const section = getSection(starts, index, trailStart);
1299
+ const section = getSectionIndex(starts, index, trailStart);
1306
1300
  const sectionHeader = section < 0 ? -1 : starts[section];
1307
- 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)];
1301
+ const getInsetStart = () => layout.$getItemOffset(pinnedStart) + (sectionHeader < 0 || sectionHeader === index ? 0 : layout.$getItemOffset(sectionHeader + 1) - layout.$getItemOffset(sectionHeader));
1302
+ const getInsetEnd = () => layout.$getItemOffset(count) - layout.$getItemOffset(trailStart);
1308
1303
  if (align === "nearest") {
1309
1304
  if (index < pinnedStart || index >= trailStart) {
1310
1305
  return;
1311
1306
  }
1312
- const [insetStart, insetEnd] = getInsets();
1313
- const scrollOffset = store.$getScrollOffset();
1307
+ const insetStart = getInsetStart();
1308
+ const scrollOffset = store.$getScrollOffset() + insetStart;
1309
+ const viewportSize = store.$getViewportSize() - insetStart - getInsetEnd();
1314
1310
  const itemSize = store.$getItemSize(index);
1315
1311
  let itemOffset = store.$getItemOffset(index);
1316
1312
  if (sectionHeader === index) {
1317
1313
  const lastIndex = (section + 1 < starts.length ? starts[section + 1] : trailStart) - 1;
1318
- itemOffset = max(itemOffset, min(scrollOffset + insetStart, store.$getItemOffset(lastIndex) + store.$getItemSize(lastIndex) - itemSize));
1314
+ itemOffset = max(itemOffset, min(scrollOffset, store.$getItemOffset(lastIndex) + store.$getItemSize(lastIndex) - itemSize));
1319
1315
  }
1320
- if (itemOffset < scrollOffset + insetStart) {
1316
+ if (itemOffset < scrollOffset) {
1321
1317
  align = "start";
1322
- } else if (itemOffset + itemSize > scrollOffset + store.$getViewportSize() - insetEnd) {
1318
+ } else if (itemOffset + itemSize > scrollOffset + viewportSize) {
1323
1319
  align = "end";
1324
1320
  } else {
1325
1321
  return;
1326
1322
  }
1327
1323
  }
1328
1324
  driver.$scroll(isHorizontal, () => {
1329
- const [insetStart, insetEnd] = getInsets();
1330
- const rest = store.$getItemSize(index) - store.$getViewportSize();
1331
- return store.$getItemOffset(index) + (align === "end" ? rest + insetEnd : align === "center" ? (rest + insetEnd - insetStart) / 2 : -insetStart);
1325
+ const insetStart = getInsetStart();
1326
+ const rest = store.$getItemSize(index) - (store.$getViewportSize() - insetStart - getInsetEnd());
1327
+ return store.$getItemOffset(index) - insetStart + (align === "end" ? rest : align === "center" ? rest / 2 : 0);
1332
1328
  });
1333
1329
  };
1334
- var gridScrollToIndex = (driver, rowStore, colStore, headerRows = 0, sectionRows = EMPTY, footerRows = 0, headerCols = 0, footerCols = 0, { rowIndex, colIndex, rowAlign, colAlign }) => {
1330
+ var gridScrollToIndex = (driver, rowStore, colStore, rowLayout, colLayout, sectionRows = EMPTY, { rowIndex, colIndex, rowAlign, colAlign }) => {
1335
1331
  if (rowIndex != null) {
1336
- scrollGridAxisToIndex(driver, rowStore, headerRows, sectionRows, footerRows, rowIndex, rowAlign, false);
1332
+ scrollGridAxisToIndex(driver, rowStore, rowLayout, sectionRows, rowIndex, rowAlign, false);
1337
1333
  }
1338
1334
  if (colIndex != null) {
1339
- scrollGridAxisToIndex(driver, colStore, headerCols, EMPTY, footerCols, colIndex, colAlign, true);
1335
+ scrollGridAxisToIndex(driver, colStore, colLayout, EMPTY, colIndex, colAlign, true);
1340
1336
  }
1341
1337
  };
1342
1338
 
@@ -1744,16 +1740,16 @@ var VGrid = (props) => {
1744
1740
  rowStore.$subscribe(8, notifyScrollEnd);
1745
1741
  colStore.$subscribe(8, notifyScrollEnd);
1746
1742
  createComputed(() => {
1747
- updateGridAxis(rowStore, rowLayout, props.rows, props.rowHeight, true);
1743
+ updateGridAxis(rowStore, rowLayout, props.rows, props.rowHeight, props.headerRows, props.footerRows, true);
1748
1744
  });
1749
1745
  createComputed(() => {
1750
- updateGridAxis(colStore, colLayout, props.cols, props.colWidth, true);
1746
+ updateGridAxis(colStore, colLayout, props.cols, props.colWidth, props.headerCols, props.footerCols, true);
1751
1747
  });
1752
1748
  const rowCount = createMemo(() => stateVersion() && rowStore.$getItemsLength());
1753
1749
  const colCount = createMemo(() => stateVersion() && colStore.$getItemsLength());
1754
1750
  const plan = createMemo(() => {
1755
1751
  stateVersion();
1756
- 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);
1752
+ return createGridPlan(rowLayout, colLayout, rowStore.$getRange(props.bufferSize), colStore.$getRange(props.bufferSize), props.sectionRows, props.spans, props.keepMounted, props.ariaSort);
1757
1753
  });
1758
1754
  const keys = createMemo(() => plan().$groups.map((state) => "$rows" in state ? state.$key : state.$row));
1759
1755
  const isScrolling = createMemo(() => stateVersion() && (rowStore.$isScrolling() || colStore.$isScrolling()));
@@ -1802,7 +1798,7 @@ var VGrid = (props) => {
1802
1798
  getColOffset: colStore.$getItemOffset,
1803
1799
  getRowSize: rowStore.$getItemSize,
1804
1800
  getColSize: colStore.$getItemSize,
1805
- scrollToIndex: (opts) => gridScrollToIndex(driver, rowStore, colStore, props.headerRows, props.sectionRows, props.footerRows, props.headerCols, props.footerCols, opts),
1801
+ scrollToIndex: (opts) => gridScrollToIndex(driver, rowStore, colStore, rowLayout, colLayout, props.sectionRows, opts),
1806
1802
  scrollTo: ({ vertical, horizontal }) => gridScrollTo(driver, vertical, horizontal),
1807
1803
  scrollBy: ({ vertical, horizontal }) => gridScrollBy(driver, rowStore, colStore, vertical, horizontal)
1808
1804
  });