virtua 0.52.1 → 0.52.2

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
  }
@@ -523,7 +546,7 @@ var getSectionStarts = (sectionRows, pinnedStart, trailStart) => {
523
546
  }
524
547
  return sort(starts);
525
548
  };
526
- var getSection = (starts, rowIndex, trailStart) => {
549
+ var getSectionIndex = (starts, rowIndex, trailStart) => {
527
550
  if (rowIndex >= trailStart) {
528
551
  return -1;
529
552
  }
@@ -540,37 +563,32 @@ var getSection = (starts, rowIndex, trailStart) => {
540
563
  return lo - 1;
541
564
  };
542
565
  var addSectionHeader = (extras, sectionStarts, rowIndex, trailStart) => {
543
- const section = getSection(sectionStarts, rowIndex, trailStart);
566
+ const section = getSectionIndex(sectionStarts, rowIndex, trailStart);
544
567
  if (section >= 0) {
545
568
  extras.push(sectionStarts[section]);
546
569
  }
547
570
  };
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
- }
571
+ var addExtras = (indexes, extras, e, bound, lastRendered) => {
553
572
  const extrasLength = extras.length;
554
- let e = 0;
555
- let last = pinnedStart - 1;
556
- for (; e < extrasLength && extras[e] < start; e++) {
573
+ for (; e < extrasLength && extras[e] < bound; e++) {
557
574
  const i = extras[e];
558
- if (i > last) {
575
+ if (i > lastRendered) {
559
576
  indexes.push(i);
560
- last = i;
577
+ lastRendered = i;
561
578
  }
562
579
  }
563
- for (let i = start; i <= end; i++) {
580
+ return e;
581
+ };
582
+ var getTrackIndexes = (extras, count, pinnedStart, start, end, trailStart) => {
583
+ const indexes = [];
584
+ for (let i = 0; i < pinnedStart; i++) {
564
585
  indexes.push(i);
565
586
  }
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
- }
587
+ const e = addExtras(indexes, extras, 0, start, pinnedStart - 1);
588
+ for (let i = start; i <= end; i++) {
589
+ indexes.push(i);
573
590
  }
591
+ addExtras(indexes, extras, e, trailStart, end);
574
592
  for (let i = trailStart; i < count; i++) {
575
593
  indexes.push(i);
576
594
  }
@@ -585,29 +603,24 @@ var getTemplate = (layout, indexes, measured, sortedCuts, measuredSize, count) =
585
603
  let line = 0;
586
604
  let i = 0;
587
605
  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) {
606
+ while (line < count) {
607
+ while (c < cutsLength && sortedCuts[c] <= line) {
592
608
  c++;
609
+ }
610
+ const index = i < indexesLength ? indexes[i] : count;
611
+ let to;
612
+ let size;
613
+ if (index === line) {
614
+ to = line + 1;
615
+ const m = measured[i];
616
+ size = m == null ? layout.$getItemSize(line) + "px" : m ? measuredSize : "minmax(" + layout.$getItemSize(line) + "px,auto)";
617
+ i++;
593
618
  } 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;
619
+ to = min(index, c < cutsLength ? sortedCuts[c] : count);
620
+ size = "minmax(" + (layout.$getItemOffset(to - 1) + layout.$getItemSize(to - 1) - layout.$getItemOffset(line)) + "px,auto)";
607
621
  }
608
- }
609
- if (line < count) {
610
- template += " minmax(" + (layout.$getTotalSize() - layout.$getItemOffset(line)) + "px,auto) [l" + count + "]";
622
+ template += " " + size + " [l" + to + "]";
623
+ line = to;
611
624
  }
612
625
  return template;
613
626
  };
@@ -618,13 +631,13 @@ var gridStyleToString = (style) => {
618
631
  }
619
632
  return css;
620
633
  };
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);
634
+ var createGridPlan = (rowLayout, colLayout, rowRange, colRange, sectionRows = EMPTY, spans = EMPTY, kept = EMPTY, sortedCell) => {
635
+ const totalRowCount = rowLayout.$getLength();
636
+ const totalColCount = colLayout.$getLength();
637
+ const rowPinnedStart = rowLayout.$getPinnedStart();
638
+ const rowTrailStart = rowLayout.$getTrailStart();
639
+ const colPinnedStart = colLayout.$getPinnedStart();
640
+ const colTrailStart = colLayout.$getTrailStart();
628
641
  const rowRangeStart = clamp(rowRange[0], rowPinnedStart, rowTrailStart);
629
642
  const rowRangeEnd = min(rowRange[1], rowTrailStart - 1);
630
643
  const colRangeStart = clamp(colRange[0], colPinnedStart, colTrailStart);
@@ -635,7 +648,7 @@ var createGridPlan = (rowLayout, colLayout, rowRange, colRange, headerRows = 0,
635
648
  const extraCols = [];
636
649
  const extraCells = [];
637
650
  for (const cell of kept) {
638
- if (cell.rowIndex < rowCount && cell.colIndex < colCount) {
651
+ if (cell.rowIndex < totalRowCount && cell.colIndex < totalColCount) {
639
652
  extraCells.push(cell);
640
653
  }
641
654
  }
@@ -657,17 +670,16 @@ var createGridPlan = (rowLayout, colLayout, rowRange, colRange, headerRows = 0,
657
670
  for (const span of waiting) {
658
671
  const row = span.rowIndex;
659
672
  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
- }
673
+ const rowTo = getSpanRowEnd(span, totalRowCount);
674
+ const colTo = getSpanColEnd(span, totalColCount);
675
+ if (row < totalRowCount && col < totalColCount && (rowTo - row > 1 || colTo - col > 1)) {
676
+ const hasRenderedRow = hasTrackIn(extraRows, row, rowTo, rowPinnedStart, rowRangeStart, rowRangeEnd, rowTrailStart);
677
+ if (hasRenderedRow && hasTrackIn(extraCols, col, colTo, colPinnedStart, colRangeStart, colRangeEnd, colTrailStart)) {
678
+ extraCells.push(span);
679
+ } else if (hasRenderedRow) {
680
+ const section = getSectionIndex(sectionStarts, rowTo - 1, rowTrailStart);
681
+ if (row < rowPinnedStart || section >= 0 && sectionStarts[section] >= row) {
682
+ rest.push(span);
671
683
  }
672
684
  } else if (col < colPinnedStart) {
673
685
  rest.push(span);
@@ -678,22 +690,22 @@ var createGridPlan = (rowLayout, colLayout, rowRange, colRange, headerRows = 0,
678
690
  } while (l < extraCells.length);
679
691
  sort(extraRows);
680
692
  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;
693
+ const rows = getTrackIndexes(extraRows, totalRowCount, rowPinnedStart, rowRangeStart, rowRangeEnd, rowTrailStart);
694
+ const cols = getTrackIndexes(extraCols, totalColCount, colPinnedStart, colRangeStart, colRangeEnd, colTrailStart);
695
+ const rowsLength = rows.length;
696
+ const colsLength = cols.length;
685
697
  const spanCells = new Map();
686
698
  const rowCuts = [];
687
699
  const colCuts = [];
688
700
  for (const span of extraCells) {
689
- const rowTo = getSpanRowEnd(span, rowCount);
690
- const colTo = getSpanColEnd(span, colCount);
701
+ const rowTo = getSpanRowEnd(span, totalRowCount);
702
+ const colTo = getSpanColEnd(span, totalColCount);
691
703
  rowCuts.push(rowTo);
692
704
  colCuts.push(colTo);
693
705
  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++) {
706
+ for (let i = rows.indexOf(span.rowIndex); i < rowsLength && rows[i] < rowTo; i++) {
707
+ const rowKey = rows[i] * totalColCount;
708
+ for (let j = colStart; j < colsLength && cols[j] < colTo; j++) {
697
709
  spanCells.set(rowKey + cols[j], span);
698
710
  }
699
711
  }
@@ -703,122 +715,125 @@ var createGridPlan = (rowLayout, colLayout, rowRange, colRange, headerRows = 0,
703
715
  measuredCols.push(colLayout.$isMeasurable(colIndex) ? false : null);
704
716
  }
705
717
  const measuredRows = [];
706
- const stickyTop = rowLayout.$getItemOffset(rowPinnedStart);
718
+ const sectionHeaderTop = rowLayout.$getItemOffset(rowPinnedStart);
707
719
  const groups = [];
708
720
  let groupRows = groups;
709
721
  const prev = rowStatesCache.get(rowLayout);
710
722
  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];
723
+ for (const rowIndex of rows) {
724
+ const isRowPinnedStart = rowIndex < rowPinnedStart;
725
+ const isRowPinnedEnd = rowIndex >= rowTrailStart;
726
+ const isRowInRangeOrPinnedToEnd = isRowPinnedEnd || rowIndex >= rowRangeStart && rowIndex <= rowRangeEnd;
727
+ const section = getSectionIndex(sectionStarts, rowIndex, rowTrailStart);
728
+ const groupStart = isRowPinnedStart ? 0 : isRowPinnedEnd ? rowTrailStart : section < 0 ? -1 : sectionStarts[section];
717
729
  if (rowIndex === groupStart) {
718
- const groupEnd = pinnedTop ? rowPinnedStart : pinnedBottom ? rowCount : section + 1 < sectionLength ? sectionStarts[section + 1] : rowTrailStart;
730
+ const groupEnd = isRowPinnedStart ? rowPinnedStart : isRowPinnedEnd ? totalRowCount : section + 1 < sectionLength ? sectionStarts[section + 1] : rowTrailStart;
719
731
  rowCuts.push(groupEnd);
720
- const rows = [];
732
+ const groupedRows = [];
721
733
  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)
734
+ $key: isRowPinnedStart ? -1 : isRowPinnedEnd ? -2 : -3 - groupStart,
735
+ $rows: groupedRows,
736
+ $style: getBoxStyle(groupStart, groupEnd, isRowPinnedStart || isRowPinnedEnd ? 0 : null, isRowPinnedEnd ? "bottom" : "top", 4)
725
737
  });
726
- groupRows = rows;
738
+ groupRows = groupedRows;
727
739
  } else if (groupStart < 0) {
728
740
  groupRows = groups;
729
741
  }
730
742
  const isSectionHeaderRow = section >= 0 && rowIndex === groupStart;
731
- const rowTop = isSectionHeaderRow ? stickyTop : null;
732
- const rowKey = rowIndex * colCount;
743
+ const rowTop = isSectionHeaderRow ? sectionHeaderTop : null;
744
+ const rowKey = rowIndex * totalColCount;
733
745
  const prevRow = prev && prev.get(rowIndex);
734
746
  const prevCells = prevRow && prevRow.$cells;
735
747
  const rowCells = [];
736
748
  let p = 0;
737
749
  let measuredRow = rowLayout.$isMeasurable(rowIndex) ? false : null;
738
750
  let rowEnd = rowIndex + 1;
739
- let changed = false;
740
- for (let i = 0; i < colLength; i++) {
751
+ let hasChanged = false;
752
+ for (let i = 0; i < colsLength; i++) {
741
753
  const colIndex = cols[i];
742
- const startPinned = colIndex < colPinnedStart;
743
- const endPinned = colIndex >= colTrailStart;
744
- const colInRangeOrPinnedToEnd = endPinned || colIndex >= colRangeStart && colIndex <= colRangeEnd;
754
+ const isColPinnedStart = colIndex < colPinnedStart;
755
+ const isColPinnedEnd = colIndex >= colTrailStart;
756
+ const isColInRangeOrPinnedToEnd = isColPinnedEnd || colIndex >= colRangeStart && colIndex <= colRangeEnd;
745
757
  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;
758
+ if (span ? span.rowIndex === rowIndex && span.colIndex === colIndex : isRowInRangeOrPinnedToEnd && isColInRangeOrPinnedToEnd || isRowPinnedStart || isSectionHeaderRow || isColPinnedStart) {
759
+ const rowTo = span ? getSpanRowEnd(span, totalRowCount) : rowIndex + 1;
760
+ const colTo = span ? getSpanColEnd(span, totalColCount) : colIndex + 1;
761
+ const rowSpan = rowTo - rowIndex;
762
+ const colSpan = colTo - colIndex;
763
+ const isSpanningRows = rowSpan > 1;
764
+ const isSpanningCols = colSpan > 1;
765
+ const isSpanning = isSpanningRows || isSpanningCols;
754
766
  let measureRowIndex;
755
767
  let measureColIndex;
756
768
  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) {
769
+ const stickyStart = isColPinnedStart ? colLayout.$getItemOffset(colIndex) : null;
770
+ const stickyEnd = isColPinnedEnd ? colLayout.$getTotalSize() - colLayout.$getItemOffset(colTo - 1) - colLayout.$getItemSize(colTo - 1) : null;
771
+ if (measuredRow === false && !isSpanningRows) {
760
772
  measureRowIndex = rowIndex;
761
773
  measuredRow = true;
762
774
  }
763
- if (measuredCols[i] === false && !spansCols) {
775
+ if (measuredCols[i] === false && !isSpanningCols) {
764
776
  measureColIndex = colIndex;
765
777
  measuredCols[i] = true;
766
778
  }
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;
779
+ const role = isRowPinnedStart ? "columnheader" : colIndex === rowHeaderCol && (isColPinnedStart || isSectionHeaderRow) ? "rowheader" : "cell";
780
+ const ariaRowSpan = isSpanning ? rowSpan : undefined;
781
+ const ariaColSpan = isSpanning ? colSpan : undefined;
782
+ const ariaSort = role !== "cell" && sortedCell && sortedCell.rowIndex === rowIndex && sortedCell.colIndex === colIndex ? sortedCell.order : undefined;
769
783
  let cell;
770
784
  if (prevCells) {
771
- while (p < prevCells.length && prevCells[p].$col < colIndex) {
785
+ const prevCellsLength = prevCells.length;
786
+ while (p < prevCellsLength && prevCells[p].$col < colIndex) {
772
787
  p++;
773
788
  }
774
- if (p < prevCells.length) {
789
+ if (p < prevCellsLength && prevCells[p].$col === colIndex) {
775
790
  cell = prevCells[p];
776
791
  }
777
792
  }
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) {
793
+ 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) {
794
+ let gridArea = "1/l" + colIndex;
795
+ if (isSpanning) {
796
+ gridArea += "/l" + rowTo + "/l" + colTo;
797
+ }
779
798
  const style = {
780
799
  contain: "layout style",
781
800
  display: "grid",
782
- gridArea: spanning ? "1/l" + colIndex + "/l" + rowTo + "/l" + colTo : "1/l" + colIndex
801
+ gridArea
783
802
  };
784
- if (spansRows) {
803
+ if (isSpanningRows) {
785
804
  style["height"] = "0px";
786
805
  style["minHeight"] = "100%";
787
806
  style["zIndex"] = 1;
788
807
  }
789
- if (spansCols) {
808
+ if (isSpanningCols) {
790
809
  style["width"] = "0px";
791
810
  style["minWidth"] = "100%";
792
811
  }
793
- if (startPinned || endPinned) {
794
- if (startPinned) {
795
- style["insetInlineStart"] = stickyStart + "px";
796
- } else {
797
- style["insetInlineEnd"] = stickyEnd + "px";
798
- }
812
+ if (isColPinnedStart || isColPinnedEnd) {
813
+ style[isColPinnedStart ? "insetInlineStart" : "insetInlineEnd"] = (isColPinnedStart ? stickyStart : stickyEnd) + "px";
799
814
  style["position"] = "sticky";
800
815
  style["zIndex"] = 2;
801
816
  }
802
817
  cell = {
803
818
  $col: colIndex,
804
- $rowSpan: rowSpan,
805
- $colSpan: colSpan,
819
+ $rowSpan: ariaRowSpan,
820
+ $colSpan: ariaColSpan,
806
821
  $measureRow: measureRowIndex,
807
822
  $measureCol: measureColIndex,
808
823
  $role: role,
809
- $sort: sortOrder,
824
+ $sort: ariaSort,
810
825
  $style: style,
811
826
  $start: stickyStart,
812
827
  $end: stickyEnd
813
828
  };
814
- changed = true;
829
+ hasChanged = true;
815
830
  }
816
831
  rowCells.push(cell);
817
832
  }
818
833
  }
819
834
  measuredRows.push(measuredRow);
820
835
  if (rowCells.length) {
821
- const row = prevRow && !changed && prevRow.$cells.length === rowCells.length && prevRow.$top === rowTop ? prevRow : {
836
+ const row = prevRow && !hasChanged && prevRow.$cells.length === rowCells.length && prevRow.$top === rowTop ? prevRow : {
822
837
  $row: rowIndex,
823
838
  $cells: rowCells,
824
839
  $style: getBoxStyle(rowIndex, rowEnd, rowTop, "top", 3),
@@ -830,8 +845,8 @@ var createGridPlan = (rowLayout, colLayout, rowRange, colRange, headerRows = 0,
830
845
  }
831
846
  rowStatesCache.set(rowLayout, rowStates);
832
847
  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),
848
+ $rowTemplate: getTemplate(rowLayout, rows, measuredRows, sort(rowCuts), "max-content", totalRowCount),
849
+ $colTemplate: getTemplate(colLayout, cols, measuredCols, sort(colCuts), "minmax(max-content,auto)", totalColCount),
835
850
  $groups: groups
836
851
  };
837
852
  };
@@ -1296,47 +1311,49 @@ var gridScrollBy = (driver, rowStore, colStore, vertical, horizontal) => {
1296
1311
  driver.$scroll(true, () => offset);
1297
1312
  }
1298
1313
  };
1299
- var scrollGridAxisToIndex = (driver, store, header, sections, footer, index, align, isHorizontal) => {
1314
+ var scrollGridAxisToIndex = (driver, store, layout, sections, index, align, isHorizontal) => {
1300
1315
  const count = store.$getItemsLength();
1301
- const pinnedStart = min(header, count);
1302
- const trailStart = max(count - footer, pinnedStart);
1316
+ const pinnedStart = layout.$getPinnedStart();
1317
+ const trailStart = layout.$getTrailStart();
1303
1318
  index = clamp(index, 0, count - 1);
1304
1319
  const starts = getSectionStarts(sections, pinnedStart, trailStart);
1305
- const section = getSection(starts, index, trailStart);
1320
+ const section = getSectionIndex(starts, index, trailStart);
1306
1321
  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)];
1322
+ const getInsetStart = () => layout.$getItemOffset(pinnedStart) + (sectionHeader < 0 || sectionHeader === index ? 0 : store.$getItemOffset(sectionHeader + 1) - store.$getItemOffset(sectionHeader));
1323
+ const getInsetEnd = () => layout.$getItemOffset(count) - layout.$getItemOffset(trailStart);
1308
1324
  if (align === "nearest") {
1309
1325
  if (index < pinnedStart || index >= trailStart) {
1310
1326
  return;
1311
1327
  }
1312
- const [insetStart, insetEnd] = getInsets();
1313
- const scrollOffset = store.$getScrollOffset();
1328
+ const insetStart = getInsetStart();
1329
+ const scrollOffset = store.$getScrollOffset() + insetStart;
1330
+ const viewportSize = store.$getViewportSize() - insetStart - getInsetEnd();
1314
1331
  const itemSize = store.$getItemSize(index);
1315
1332
  let itemOffset = store.$getItemOffset(index);
1316
1333
  if (sectionHeader === index) {
1317
1334
  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));
1335
+ itemOffset = max(itemOffset, min(scrollOffset, store.$getItemOffset(lastIndex) + store.$getItemSize(lastIndex) - itemSize));
1319
1336
  }
1320
- if (itemOffset < scrollOffset + insetStart) {
1337
+ if (itemOffset < scrollOffset) {
1321
1338
  align = "start";
1322
- } else if (itemOffset + itemSize > scrollOffset + store.$getViewportSize() - insetEnd) {
1339
+ } else if (itemOffset + itemSize > scrollOffset + viewportSize) {
1323
1340
  align = "end";
1324
1341
  } else {
1325
1342
  return;
1326
1343
  }
1327
1344
  }
1328
1345
  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);
1346
+ const insetStart = getInsetStart();
1347
+ const rest = store.$getItemSize(index) - (store.$getViewportSize() - insetStart - getInsetEnd());
1348
+ return store.$getItemOffset(index) - insetStart + (align === "end" ? rest : align === "center" ? rest / 2 : 0);
1332
1349
  });
1333
1350
  };
1334
- var gridScrollToIndex = (driver, rowStore, colStore, headerRows = 0, sectionRows = EMPTY, footerRows = 0, headerCols = 0, footerCols = 0, { rowIndex, colIndex, rowAlign, colAlign }) => {
1351
+ var gridScrollToIndex = (driver, rowStore, colStore, rowLayout, colLayout, sectionRows = EMPTY, { rowIndex, colIndex, rowAlign, colAlign }) => {
1335
1352
  if (rowIndex != null) {
1336
- scrollGridAxisToIndex(driver, rowStore, headerRows, sectionRows, footerRows, rowIndex, rowAlign, false);
1353
+ scrollGridAxisToIndex(driver, rowStore, rowLayout, sectionRows, rowIndex, rowAlign, false);
1337
1354
  }
1338
1355
  if (colIndex != null) {
1339
- scrollGridAxisToIndex(driver, colStore, headerCols, EMPTY, footerCols, colIndex, colAlign, true);
1356
+ scrollGridAxisToIndex(driver, colStore, colLayout, EMPTY, colIndex, colAlign, true);
1340
1357
  }
1341
1358
  };
1342
1359
 
@@ -1744,16 +1761,16 @@ var VGrid = (props) => {
1744
1761
  rowStore.$subscribe(8, notifyScrollEnd);
1745
1762
  colStore.$subscribe(8, notifyScrollEnd);
1746
1763
  createComputed(() => {
1747
- updateGridAxis(rowStore, rowLayout, props.rows, props.rowHeight, true);
1764
+ updateGridAxis(rowStore, rowLayout, props.rows, props.rowHeight, props.headerRows, props.footerRows, true);
1748
1765
  });
1749
1766
  createComputed(() => {
1750
- updateGridAxis(colStore, colLayout, props.cols, props.colWidth, true);
1767
+ updateGridAxis(colStore, colLayout, props.cols, props.colWidth, props.headerCols, props.footerCols, true);
1751
1768
  });
1752
1769
  const rowCount = createMemo(() => stateVersion() && rowStore.$getItemsLength());
1753
1770
  const colCount = createMemo(() => stateVersion() && colStore.$getItemsLength());
1754
1771
  const plan = createMemo(() => {
1755
1772
  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);
1773
+ return createGridPlan(rowLayout, colLayout, rowStore.$getRange(props.bufferSize), colStore.$getRange(props.bufferSize), props.sectionRows, props.spans, props.keepMounted, props.ariaSort);
1757
1774
  });
1758
1775
  const keys = createMemo(() => plan().$groups.map((state) => "$rows" in state ? state.$key : state.$row));
1759
1776
  const isScrolling = createMemo(() => stateVersion() && (rowStore.$isScrolling() || colStore.$isScrolling()));
@@ -1802,7 +1819,7 @@ var VGrid = (props) => {
1802
1819
  getColOffset: colStore.$getItemOffset,
1803
1820
  getRowSize: rowStore.$getItemSize,
1804
1821
  getColSize: colStore.$getItemSize,
1805
- scrollToIndex: (opts) => gridScrollToIndex(driver, rowStore, colStore, props.headerRows, props.sectionRows, props.footerRows, props.headerCols, props.footerCols, opts),
1822
+ scrollToIndex: (opts) => gridScrollToIndex(driver, rowStore, colStore, rowLayout, colLayout, props.sectionRows, opts),
1806
1823
  scrollTo: ({ vertical, horizontal }) => gridScrollTo(driver, vertical, horizontal),
1807
1824
  scrollBy: ({ vertical, horizontal }) => gridScrollBy(driver, rowStore, colStore, vertical, horizontal)
1808
1825
  });