@canvas-components/list-table 0.3.1 → 0.3.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.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { stringifyDataIndex, getValueByDataIndex, clamp, copyTextSync, copyText, exportTableToXlsx, formatPreciseNumber, addPreciseNumbers, comparePreciseNumbers, dividePreciseNumber, roundPreciseNumber, parseNumberValue, formatNumberValue, formatPercentValue, formatScientificValue, formatChineseNumber, parseChineseNumber, exportTableToTxt, exportTableToCsv, downloadJsonFile, mapRowsToExportRecords, copyJson, copyRows, isDateTimeFormatPattern, normalizeDecimalPlaces, formatDateTimeValue, formatCustomNumberPattern, isSameDataIndex, isPointInRect as isPointInRect$1 } from '@canvas-components/utils';
1
+ import { stringifyDataIndex, getValueByDataIndex, clamp, copyTextSync, copyText, exportTableToXlsx, formatPreciseNumber, addPreciseNumbers, comparePreciseNumbers, isSameDataIndex, dividePreciseNumber, roundPreciseNumber, parseNumberValue, formatNumberValue, formatPercentValue, formatScientificValue, formatChineseNumber, parseChineseNumber, exportTableToTxt, exportTableToCsv, downloadJsonFile, mapRowsToExportRecords, copyJson, copyRows, isDateTimeFormatPattern, normalizeDecimalPlaces, formatDateTimeValue, formatCustomNumberPattern, isPointInRect as isPointInRect$1 } from '@canvas-components/utils';
2
2
  import { drawBarcodeToCanvas } from '@canvas-components/barcode';
3
3
  import { drawCanvasChartToCanvas, getCanvasChartRenderer, resolveCanvasChartTooltipText } from '@canvas-components/chart';
4
4
  import { drawQrCodeToCanvas } from '@canvas-components/qrcode';
@@ -333,6 +333,30 @@ function stretchColumnWidths(columns, containerWidth) {
333
333
  stretchableColumns[stretchableColumns.length - 1].width += remain;
334
334
  }
335
335
  }
336
+ function shrinkColumnWidthsToFit(columns, containerWidth) {
337
+ let remaining = Math.max(
338
+ Math.ceil(computeColumnWidths(columns) - containerWidth),
339
+ 0
340
+ );
341
+ let shrinkableColumns = columns.filter(
342
+ (column) => column.width > column.minWidth
343
+ );
344
+ while (remaining > 0 && shrinkableColumns.length > 0) {
345
+ const share = Math.max(Math.floor(remaining / shrinkableColumns.length), 1);
346
+ shrinkableColumns.forEach((column) => {
347
+ if (remaining <= 0) {
348
+ return;
349
+ }
350
+ const shrink = Math.min(column.width - column.minWidth, share, remaining);
351
+ column.width -= shrink;
352
+ remaining -= shrink;
353
+ });
354
+ shrinkableColumns = shrinkableColumns.filter(
355
+ (column) => column.width > column.minWidth
356
+ );
357
+ }
358
+ return remaining === 0;
359
+ }
336
360
 
337
361
  // src/domain/columns/flatten-leaf-columns.ts
338
362
  function flattenLeafColumns(columns) {
@@ -3216,7 +3240,7 @@ function drawBodyButtonContent(params) {
3216
3240
  const top = rect.y + (rect.height - height) / 2;
3217
3241
  const palette = resolveButtonPalette(content);
3218
3242
  const textIndent = resolveContentTextIndent(content);
3219
- const paddingInline = BUTTON_PADDING_INLINE_MAP[size];
3243
+ const paddingInline = resolveButtonPaddingInline(content, size);
3220
3244
  const radius = BUTTON_RADIUS_MAP[size];
3221
3245
  ctx.save();
3222
3246
  ctx.globalAlpha *= resolveContentOpacity(content);
@@ -3324,9 +3348,12 @@ function measureButtonContentWidth(ctx, content, theme) {
3324
3348
  const intrinsicWidth = Math.max(
3325
3349
  ctx.measureText(content.text).width + resolveContentTextIndent(content),
3326
3350
  0
3327
- ) + BUTTON_PADDING_INLINE_MAP[size] * 2;
3351
+ ) + resolveButtonPaddingInline(content, size) * 2;
3328
3352
  return resolveContentLayoutWidth(content, intrinsicWidth);
3329
3353
  }
3354
+ function resolveButtonPaddingInline(content, size) {
3355
+ return content.buttonType === "link" || content.buttonType === "text" ? 4 : BUTTON_PADDING_INLINE_MAP[size];
3356
+ }
3330
3357
  function measureButtonContentHeight(content) {
3331
3358
  return BUTTON_HEIGHT_MAP[resolveButtonSize(content.size)];
3332
3359
  }
@@ -3926,11 +3953,25 @@ function drawImagePlaceholder(ctx, x, y, width, height, backgroundColor = PLACEH
3926
3953
  var SYMBOL_COLOR_MAP = {
3927
3954
  star: "#fadb14",
3928
3955
  sun: "#faad14",
3929
- moon: "#597ef7"
3956
+ moon: "#597ef7",
3957
+ check: "#52c41a",
3958
+ close: "#ff4d4f"
3930
3959
  };
3931
3960
  function drawCellSymbol(ctx, params) {
3932
3961
  const { type, x, y, size, activeColor, inactiveColor } = params;
3933
3962
  const fillRatio = Math.min(Math.max(params.fillRatio, 0), 1);
3963
+ if (type === "check" || type === "close") {
3964
+ drawStatusSymbol(ctx, {
3965
+ type,
3966
+ x,
3967
+ y,
3968
+ size,
3969
+ activeColor,
3970
+ inactiveColor,
3971
+ fillRatio
3972
+ });
3973
+ return;
3974
+ }
3934
3975
  appendCellSymbolPath(ctx, type, x, y, size);
3935
3976
  ctx.fillStyle = inactiveColor;
3936
3977
  ctx.fill("evenodd");
@@ -3948,6 +3989,10 @@ function resolveCellSymbolColor(type) {
3948
3989
  return SYMBOL_COLOR_MAP[type];
3949
3990
  }
3950
3991
  function appendCellSymbolPath(ctx, type, x, y, size) {
3992
+ if (type === "check" || type === "close") {
3993
+ appendStatusSymbolPath(ctx, type, x, y, size);
3994
+ return;
3995
+ }
3951
3996
  if (type === "moon") {
3952
3997
  appendMoonPath(ctx, x, y, size);
3953
3998
  return;
@@ -3968,6 +4013,38 @@ function appendCellSymbolPath(ctx, type, x, y, size) {
3968
4013
  }
3969
4014
  ctx.closePath();
3970
4015
  }
4016
+ function drawStatusSymbol(ctx, params) {
4017
+ const { type, x, y, size, activeColor, inactiveColor, fillRatio } = params;
4018
+ ctx.save();
4019
+ ctx.lineCap = "round";
4020
+ ctx.lineJoin = "round";
4021
+ ctx.lineWidth = Math.max(size * 0.12, 1.5);
4022
+ appendStatusSymbolPath(ctx, type, x, y, size);
4023
+ ctx.strokeStyle = inactiveColor;
4024
+ ctx.stroke();
4025
+ if (fillRatio > 0) {
4026
+ ctx.beginPath();
4027
+ ctx.rect(x, y, size * fillRatio, size);
4028
+ ctx.clip();
4029
+ appendStatusSymbolPath(ctx, type, x, y, size);
4030
+ ctx.strokeStyle = activeColor;
4031
+ ctx.stroke();
4032
+ }
4033
+ ctx.restore();
4034
+ }
4035
+ function appendStatusSymbolPath(ctx, type, x, y, size) {
4036
+ ctx.beginPath();
4037
+ if (type === "check") {
4038
+ ctx.moveTo(x + size * 0.16, y + size * 0.52);
4039
+ ctx.lineTo(x + size * 0.4, y + size * 0.76);
4040
+ ctx.lineTo(x + size * 0.84, y + size * 0.26);
4041
+ return;
4042
+ }
4043
+ ctx.moveTo(x + size * 0.22, y + size * 0.22);
4044
+ ctx.lineTo(x + size * 0.78, y + size * 0.78);
4045
+ ctx.moveTo(x + size * 0.78, y + size * 0.22);
4046
+ ctx.lineTo(x + size * 0.22, y + size * 0.78);
4047
+ }
3971
4048
  function appendMoonPath(ctx, x, y, size) {
3972
4049
  ctx.beginPath();
3973
4050
  ctx.moveTo(x + size * 0.64, y + size * 0.04);
@@ -6237,6 +6314,7 @@ function resolveColumnFormItemProps(column, context) {
6237
6314
  // src/rendering/cell-content/cell-content-renderer.ts
6238
6315
  var CONTENT_HORIZONTAL_PADDING = 12;
6239
6316
  var CONTENT_GAP = 8;
6317
+ var LINK_CONTENT_GAP = 4;
6240
6318
  var CONTENT_VERTICAL_PADDING = 6;
6241
6319
  function resolveBodyCellContents(params) {
6242
6320
  return resolveRawBodyCellContents(params).filter(
@@ -6671,8 +6749,8 @@ function drawBodyCellContents(params) {
6671
6749
  align: column.align
6672
6750
  });
6673
6751
  line.items.forEach((item, itemIndex) => {
6674
- if (itemIndex > 0 && item.gapBefore) {
6675
- cursorX += CONTENT_GAP;
6752
+ if (itemIndex > 0) {
6753
+ cursorX += item.gapBefore;
6676
6754
  }
6677
6755
  const itemDescriptors = [];
6678
6756
  drawExpandedBodyContent({
@@ -6767,7 +6845,7 @@ function measureBodyCellContentsWidth(params) {
6767
6845
  currentLineWidth = 0;
6768
6846
  return;
6769
6847
  }
6770
- const gapWidth = currentLineWidth > 0 && item.gapBefore ? CONTENT_GAP : 0;
6848
+ const gapWidth = currentLineWidth > 0 ? item.gapBefore : 0;
6771
6849
  currentLineWidth += gapWidth + contentWidth;
6772
6850
  });
6773
6851
  return Math.ceil(
@@ -6798,10 +6876,11 @@ function expandBodyContents(contents) {
6798
6876
  const textOnly = contents.every((content) => content.type === "text");
6799
6877
  const expanded = [];
6800
6878
  contents.forEach((content, contentIndex) => {
6879
+ const previousContent = contents[contentIndex - 1];
6801
6880
  expanded.push({
6802
6881
  content,
6803
6882
  contentIndex,
6804
- gapBefore: expanded.length > 0 && !textOnly
6883
+ gapBefore: expanded.length === 0 || textOnly ? 0 : resolveInlineContentGap(previousContent, content)
6805
6884
  });
6806
6885
  if ((content.type === "checkbox" || content.type === "radio") && content.label) {
6807
6886
  const textLabelContent = {
@@ -6814,12 +6893,18 @@ function expandBodyContents(contents) {
6814
6893
  expanded.push({
6815
6894
  content: textLabelContent,
6816
6895
  contentIndex,
6817
- gapBefore: true
6896
+ gapBefore: CONTENT_GAP
6818
6897
  });
6819
6898
  }
6820
6899
  });
6821
6900
  return expanded;
6822
6901
  }
6902
+ function resolveInlineContentGap(previous, current) {
6903
+ return isInlineActionContent(previous) && isInlineActionContent(current) ? LINK_CONTENT_GAP : CONTENT_GAP;
6904
+ }
6905
+ function isInlineActionContent(content) {
6906
+ return content?.type === "link" || content?.type === "button" && (content.buttonType === "link" || content.buttonType === "text");
6907
+ }
6823
6908
  function buildSingleLineLayout(ctx, contents, availableWidth, theme) {
6824
6909
  const line = {
6825
6910
  items: [],
@@ -6855,7 +6940,7 @@ function buildSingleLineLayout(ctx, contents, availableWidth, theme) {
6855
6940
  }
6856
6941
  break;
6857
6942
  }
6858
- const gapWidth = line.items.length > 0 && item.gapBefore ? CONTENT_GAP : 0;
6943
+ const gapWidth = line.items.length > 0 ? item.gapBefore : 0;
6859
6944
  const remainingWidth = availableWidth - line.width - gapWidth;
6860
6945
  if (remainingWidth <= 0) {
6861
6946
  truncated = true;
@@ -6923,7 +7008,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6923
7008
  items: [
6924
7009
  {
6925
7010
  ...currentItem,
6926
- gapBefore: false,
7011
+ gapBefore: 0,
6927
7012
  width: fullWidth2
6928
7013
  }
6929
7014
  ],
@@ -6954,7 +7039,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6954
7039
  {
6955
7040
  ...currentItem,
6956
7041
  content: fittedContent2,
6957
- gapBefore: false,
7042
+ gapBefore: 0,
6958
7043
  width: fittedWidth
6959
7044
  }
6960
7045
  ],
@@ -6976,11 +7061,11 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6976
7061
  currentItem = {
6977
7062
  ...currentItem,
6978
7063
  content: setBreakableContentText(currentItem.content, remainingText2),
6979
- gapBefore: false
7064
+ gapBefore: 0
6980
7065
  };
6981
7066
  continue;
6982
7067
  }
6983
- const gapWidth = currentLine.items.length > 0 && currentItem.gapBefore ? CONTENT_GAP : 0;
7068
+ const gapWidth = currentLine.items.length > 0 ? currentItem.gapBefore : 0;
6984
7069
  const remainingWidth = availableWidth - currentLine.width - gapWidth;
6985
7070
  if (remainingWidth <= 0) {
6986
7071
  if (lines.length + 1 >= maxLines) {
@@ -6994,7 +7079,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6994
7079
  currentLine = { items: [], width: 0 };
6995
7080
  currentItem = {
6996
7081
  ...currentItem,
6997
- gapBefore: false
7082
+ gapBefore: 0
6998
7083
  };
6999
7084
  continue;
7000
7085
  }
@@ -7014,7 +7099,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
7014
7099
  currentLine = { items: [], width: 0 };
7015
7100
  currentItem = {
7016
7101
  ...currentItem,
7017
- gapBefore: false
7102
+ gapBefore: 0
7018
7103
  };
7019
7104
  continue;
7020
7105
  }
@@ -7054,7 +7139,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
7054
7139
  currentLine = { items: [], width: 0 };
7055
7140
  currentItem = {
7056
7141
  ...currentItem,
7057
- gapBefore: false
7142
+ gapBefore: 0
7058
7143
  };
7059
7144
  continue;
7060
7145
  }
@@ -7082,7 +7167,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
7082
7167
  currentItem = {
7083
7168
  ...currentItem,
7084
7169
  content: setBreakableContentText(currentItem.content, remainingText),
7085
- gapBefore: false
7170
+ gapBefore: 0
7086
7171
  };
7087
7172
  }
7088
7173
  if (truncated) {
@@ -7595,10 +7680,10 @@ function applyTrailingEllipsis(ctx, line, theme, availableWidth) {
7595
7680
  continue;
7596
7681
  }
7597
7682
  const widthBefore = line.items.slice(0, index).reduce((sum, current, currentIndex) => {
7598
- const gapWidth2 = currentIndex > 0 && current.gapBefore ? CONTENT_GAP : 0;
7683
+ const gapWidth2 = currentIndex > 0 ? current.gapBefore : 0;
7599
7684
  return sum + gapWidth2 + current.width;
7600
7685
  }, 0);
7601
- const gapWidth = index > 0 && item.gapBefore ? CONTENT_GAP : 0;
7686
+ const gapWidth = index > 0 ? item.gapBefore : 0;
7602
7687
  const nextContent = truncateExpandedContent(
7603
7688
  ctx,
7604
7689
  item.content,
@@ -10409,7 +10494,7 @@ var ListTableCarouselController = class {
10409
10494
  var SUMMARY_ASYNC_BATCH_SIZE = 2e3;
10410
10495
  var SUMMARY_ASYNC_FRAME_BUDGET = 8;
10411
10496
  async function computeSummaryValuesAsync(params) {
10412
- const { rows, columns, signal } = params;
10497
+ const { rows, columns, mergeCell, signal } = params;
10413
10498
  const summaryValues = /* @__PURE__ */ new Map();
10414
10499
  const accumulators = [];
10415
10500
  columns.forEach((column) => {
@@ -10462,8 +10547,14 @@ async function computeSummaryValuesAsync(params) {
10462
10547
  }
10463
10548
  startIndex = endIndex;
10464
10549
  }
10550
+ const mergedRowCount = accumulators.some(
10551
+ (item) => item.type === "mergedRowCount"
10552
+ ) ? countMergedRows(rows, columns, mergeCell) : null;
10465
10553
  accumulators.forEach((item) => {
10466
- summaryValues.set(item.column.key, finalizeSummaryValue(item, rows));
10554
+ summaryValues.set(
10555
+ item.column.key,
10556
+ finalizeSummaryValue(item, rows, mergedRowCount)
10557
+ );
10467
10558
  });
10468
10559
  return summaryValues;
10469
10560
  }
@@ -10518,7 +10609,7 @@ function updateSummaryAccumulator(item, record) {
10518
10609
  item.max = numericValue;
10519
10610
  }
10520
10611
  }
10521
- function finalizeSummaryValue(item, rows) {
10612
+ function finalizeSummaryValue(item, rows, mergedRowCount) {
10522
10613
  if (item.column.summaryTitle != null) {
10523
10614
  return item.column.summaryTitle;
10524
10615
  }
@@ -10526,7 +10617,11 @@ function finalizeSummaryValue(item, rows) {
10526
10617
  return formatSummaryOutput(item, String(rows.length), rows);
10527
10618
  }
10528
10619
  if (item.type === "mergedRowCount") {
10529
- return formatSummaryOutput(item, String(countMergedRows(rows)), rows);
10620
+ return formatSummaryOutput(
10621
+ item,
10622
+ String(mergedRowCount ?? rows.length),
10623
+ rows
10624
+ );
10530
10625
  }
10531
10626
  if (item.type === "count") {
10532
10627
  return formatSummaryOutput(item, String(item.valueCount), rows);
@@ -10617,7 +10712,76 @@ function formatSummaryOutput(item, value, rows) {
10617
10712
  }
10618
10713
  return value;
10619
10714
  }
10620
- function countMergedRows(rows) {
10715
+ function countMergedRows(rows, columns, mergeCell) {
10716
+ const coveredRowIndexes = /* @__PURE__ */ new Set();
10717
+ const explicitRowSpans = /* @__PURE__ */ new Map();
10718
+ columns.forEach((column) => {
10719
+ if (!column.onCell) {
10720
+ return;
10721
+ }
10722
+ rows.forEach((record, rowIndex) => {
10723
+ const value = getValueByDataIndex(record, column.dataIndex);
10724
+ const span = column.onCell?.(value, record, rowIndex, column);
10725
+ if (!span || !Object.prototype.hasOwnProperty.call(span, "rowSpan")) {
10726
+ return;
10727
+ }
10728
+ const rowSpan = span.rowSpan ?? 1;
10729
+ explicitRowSpans.set(`${rowIndex}::${column.key}`, rowSpan);
10730
+ if (rowSpan === 0) {
10731
+ coveredRowIndexes.add(rowIndex);
10732
+ return;
10733
+ }
10734
+ if (!Number.isFinite(rowSpan) || rowSpan <= 1) {
10735
+ return;
10736
+ }
10737
+ const spanEnd = Math.min(
10738
+ rows.length,
10739
+ rowIndex + Math.floor(rowSpan)
10740
+ );
10741
+ for (let index = rowIndex + 1; index < spanEnd; index += 1) {
10742
+ coveredRowIndexes.add(index);
10743
+ }
10744
+ });
10745
+ });
10746
+ const rowMergeRule = mergeCell?.row;
10747
+ const targetDataIndexes = rowMergeRule?.columns?.length ? rowMergeRule.columns : rowMergeRule?.keys;
10748
+ const targetMergeColumns = columns.filter(
10749
+ (column) => targetDataIndexes?.some(
10750
+ (dataIndex) => isSameDataIndex(column.dataIndex, dataIndex)
10751
+ )
10752
+ );
10753
+ if (rowMergeRule?.keys.length && targetMergeColumns.length) {
10754
+ targetMergeColumns.forEach((column) => {
10755
+ let rowIndex = 0;
10756
+ while (rowIndex < rows.length) {
10757
+ if (explicitRowSpans.has(`${rowIndex}::${column.key}`)) {
10758
+ rowIndex += 1;
10759
+ continue;
10760
+ }
10761
+ const currentGroupKey = getMergeGroupKey(
10762
+ rows[rowIndex],
10763
+ rowMergeRule.keys
10764
+ );
10765
+ let rowSpan = 1;
10766
+ for (let index = rowIndex + 1; index < rows.length; index += 1) {
10767
+ if (explicitRowSpans.has(`${index}::${column.key}`)) {
10768
+ break;
10769
+ }
10770
+ if (getMergeGroupKey(rows[index], rowMergeRule.keys) !== currentGroupKey) {
10771
+ break;
10772
+ }
10773
+ rowSpan += 1;
10774
+ }
10775
+ for (let index = rowIndex + 1; index < rowIndex + rowSpan; index += 1) {
10776
+ coveredRowIndexes.add(index);
10777
+ }
10778
+ rowIndex += rowSpan;
10779
+ }
10780
+ });
10781
+ }
10782
+ if (coveredRowIndexes.size > 0) {
10783
+ return rows.length - coveredRowIndexes.size;
10784
+ }
10621
10785
  return rows.reduce((count, record) => {
10622
10786
  if (record == null || typeof record !== "object") {
10623
10787
  return count + 1;
@@ -10629,6 +10793,20 @@ function countMergedRows(rows) {
10629
10793
  return rowSpan > 0 ? count + 1 : count;
10630
10794
  }, 0);
10631
10795
  }
10796
+ function getMergeGroupKey(record, keys) {
10797
+ return keys.map(
10798
+ (dataIndex) => normalizeMergeValue(getValueByDataIndex(record, dataIndex))
10799
+ ).join("|");
10800
+ }
10801
+ function normalizeMergeValue(value) {
10802
+ if (value == null) {
10803
+ return "";
10804
+ }
10805
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
10806
+ return String(value);
10807
+ }
10808
+ return JSON.stringify(value) ?? "";
10809
+ }
10632
10810
  function yieldToMainThread() {
10633
10811
  return new Promise((resolve) => {
10634
10812
  if (typeof requestAnimationFrame === "function") {
@@ -20125,7 +20303,7 @@ function buildListTableRenderSnapshot(params) {
20125
20303
  options.scrollbar?.thickness ?? DEFAULT_SCROLLBAR_THICKNESS,
20126
20304
  6
20127
20305
  );
20128
- let width = hostWidth;
20306
+ let width = Math.max(hostWidth - scrollbarThickness, 0);
20129
20307
  let height = hostHeight;
20130
20308
  const sourceNormalizedColumns = normalizeColumns(
20131
20309
  getResolvedColumns(options, selectedRowKeys)
@@ -20137,6 +20315,10 @@ function buildListTableRenderSnapshot(params) {
20137
20315
  groupedColumnKeys
20138
20316
  );
20139
20317
  const leafColumns = flattenLeafColumns(normalizedColumns);
20318
+ const totalColumnWidth = computeColumnWidths(leafColumns);
20319
+ if (width > 0 && totalColumnWidth > width && totalColumnWidth <= hostWidth) {
20320
+ shrinkColumnWidthsToFit(leafColumns, width);
20321
+ }
20140
20322
  if (options.stretchColumns !== false && width > 0 && !draggingResize) {
20141
20323
  stretchColumnWidths(leafColumns, width);
20142
20324
  }
@@ -20400,54 +20582,6 @@ function buildListTableRenderSnapshot(params) {
20400
20582
  fixedWidthRight: columnMetrics.fixedWidthRight,
20401
20583
  scroll
20402
20584
  });
20403
- for (let index = 0; index < 2 && scrollbarThickness > 0; index += 1) {
20404
- const nextWidth = Math.max(
20405
- hostWidth - (viewportResult.viewport.maxScrollTop > 0 ? scrollbarThickness : 0),
20406
- 0
20407
- );
20408
- const nextHeight = Math.max(
20409
- hostHeight - (viewportResult.viewport.maxScrollLeft > 0 ? scrollbarThickness : 0),
20410
- 0
20411
- );
20412
- if (nextWidth === width && nextHeight === height) {
20413
- break;
20414
- }
20415
- width = nextWidth;
20416
- height = nextHeight;
20417
- bodyState = resolveCurrentBodyState();
20418
- if (plainRowWindow) {
20419
- bodyState.frozenRows.scroll.windowed = true;
20420
- bodyState.frozenRows.scroll.dataRowIndexAligned = true;
20421
- bodyState.frozenRows.scroll.rowIndexMap = plainRowWindow.rowIndexMap;
20422
- bodyState.frozenRows.scroll.rowOffsetMap = plainRowWindow.rowOffsetMap;
20423
- bodyState.bodyLayout = resolveBodyLayout({
20424
- height,
20425
- headerHeight,
20426
- summaryRowHeight,
20427
- hasSummary,
20428
- rowHeight,
20429
- totalBodyHeight: plainRowWindow.totalBodyHeight,
20430
- topFrozenRowCount: 0,
20431
- bottomFrozenRowCount: 0,
20432
- scrollRowCount: plainRowWindow.totalRowCount
20433
- });
20434
- }
20435
- columnMetrics = resolveColumnMetrics({
20436
- columns: leafColumns,
20437
- tableWidth: width
20438
- });
20439
- viewportResult = computeViewport({
20440
- width,
20441
- height,
20442
- headerHeight,
20443
- bodyHeight: bodyState.bodyLayout.scrollBodyHeight,
20444
- totalWidth: columnMetrics.totalWidth,
20445
- totalBodyHeight: bodyState.bodyLayout.totalBodyHeight,
20446
- fixedWidthLeft: columnMetrics.fixedWidthLeft,
20447
- fixedWidthRight: columnMetrics.fixedWidthRight,
20448
- scroll
20449
- });
20450
- }
20451
20585
  scrollPageSize = resolveScrollPageSize({
20452
20586
  options,
20453
20587
  pageSize: query.pagination.pageSize,
@@ -20728,8 +20862,8 @@ function updateListTableRenderSnapshotScroll(params) {
20728
20862
  } : snapshot.frozenRows;
20729
20863
  return {
20730
20864
  ...snapshot,
20731
- width,
20732
- height,
20865
+ width: snapshot.width,
20866
+ height: snapshot.height,
20733
20867
  columnSegments,
20734
20868
  headerRows,
20735
20869
  scrollbarLayout,
@@ -21114,13 +21248,8 @@ function drawScrollbars(ctx, layout, descriptors, borderColor, opacity = 1, inte
21114
21248
  verticalFrame.bodyBackgroundColor
21115
21249
  );
21116
21250
  }
21117
- if (layout.vertical && verticalFrame) {
21118
- drawVerticalScrollbarFrame(
21119
- ctx,
21120
- layout.vertical,
21121
- verticalFrame,
21122
- borderColor
21123
- );
21251
+ if (verticalFrame) {
21252
+ drawVerticalScrollbarFrame(ctx, verticalFrame, borderColor);
21124
21253
  }
21125
21254
  if (layout.horizontal) {
21126
21255
  drawAxisScrollbar(
@@ -21238,28 +21367,28 @@ function drawTrackBorder(ctx, rect, axis, borderColor) {
21238
21367
  ctx.stroke();
21239
21368
  ctx.restore();
21240
21369
  }
21241
- function drawVerticalScrollbarFrame(ctx, layout, frame, borderColor) {
21242
- const left = Math.round(layout.decreaseButton.x) + 0.5;
21243
- const right = Math.round(layout.decreaseButton.x + layout.decreaseButton.width) - 0.5;
21370
+ function drawVerticalScrollbarFrame(ctx, frame, borderColor) {
21371
+ const left = Math.round(frame.x) + 0.5;
21372
+ const right = Math.round(frame.x + frame.width) - 0.5;
21244
21373
  const top = Math.round(frame.top) + 0.5;
21245
21374
  const bottom = Math.round(frame.top + frame.height) - 0.5;
21246
21375
  const headerBottom = Math.round(frame.headerBottom) + 0.5;
21247
- if (right <= left || bottom <= top) {
21376
+ if (frame.width <= 0 || right <= left || bottom <= top) {
21248
21377
  return;
21249
21378
  }
21250
21379
  ctx.save();
21251
21380
  ctx.fillStyle = frame.headerBackgroundColor;
21252
21381
  ctx.fillRect(
21253
- layout.decreaseButton.x,
21382
+ frame.x,
21254
21383
  frame.top,
21255
- layout.decreaseButton.width,
21384
+ frame.width,
21256
21385
  Math.max(frame.headerBottom - frame.top, 0)
21257
21386
  );
21258
21387
  ctx.fillStyle = frame.bodyBackgroundColor;
21259
21388
  ctx.fillRect(
21260
- layout.decreaseButton.x,
21389
+ frame.x,
21261
21390
  frame.headerBottom,
21262
- layout.decreaseButton.width,
21391
+ frame.width,
21263
21392
  Math.max(frame.top + frame.height - frame.headerBottom, 0)
21264
21393
  );
21265
21394
  ctx.strokeStyle = borderColor;
@@ -22105,7 +22234,7 @@ function buildAutoRowSpanMap(rows, columns, rule, spanConfigMap, sourceRowIndexM
22105
22234
  rowIndex += 1;
22106
22235
  continue;
22107
22236
  }
22108
- const currentGroupKey = getMergeGroupKey(rows[rowIndex], groupKeys);
22237
+ const currentGroupKey = getMergeGroupKey2(rows[rowIndex], groupKeys);
22109
22238
  let rowSpan = 1;
22110
22239
  for (let index = rowIndex + 1; index < rows.length; index += 1) {
22111
22240
  if (sourceRowIndexMap[index] !== (sourceRowIndexMap[index - 1] ?? index - 1) + 1) {
@@ -22115,7 +22244,7 @@ function buildAutoRowSpanMap(rows, columns, rule, spanConfigMap, sourceRowIndexM
22115
22244
  if (hasExplicitSpan(spanConfigMap.get(nextCellKey), "rowSpan")) {
22116
22245
  break;
22117
22246
  }
22118
- if (getMergeGroupKey(rows[index], groupKeys) !== currentGroupKey) {
22247
+ if (getMergeGroupKey2(rows[index], groupKeys) !== currentGroupKey) {
22119
22248
  break;
22120
22249
  }
22121
22250
  rowSpan += 1;
@@ -22218,13 +22347,13 @@ function clampSpan(span, max) {
22218
22347
  }
22219
22348
  return Math.max(1, Math.min(Math.floor(span), max));
22220
22349
  }
22221
- function getMergeGroupKey(record, keys) {
22350
+ function getMergeGroupKey2(record, keys) {
22222
22351
  if (!keys?.length) {
22223
22352
  return "";
22224
22353
  }
22225
- return keys.map((key) => normalizeMergeValue(getValueByDataIndex(record, key))).join("|");
22354
+ return keys.map((key) => normalizeMergeValue2(getValueByDataIndex(record, key))).join("|");
22226
22355
  }
22227
- function normalizeMergeValue(value) {
22356
+ function normalizeMergeValue2(value) {
22228
22357
  if (value == null) {
22229
22358
  return "";
22230
22359
  }
@@ -22234,7 +22363,7 @@ function normalizeMergeValue(value) {
22234
22363
  return JSON.stringify(value) ?? "";
22235
22364
  }
22236
22365
  function isSameMergeValue(left, right) {
22237
- return normalizeMergeValue(left) === normalizeMergeValue(right);
22366
+ return normalizeMergeValue2(left) === normalizeMergeValue2(right);
22238
22367
  }
22239
22368
  function getMergedCellWidth(columns, startIndex, colSpan) {
22240
22369
  let width = 0;
@@ -24497,6 +24626,11 @@ function executeListTableRenderPipeline(params) {
24497
24626
  scrollbarOpacity,
24498
24627
  isScrollbarInteractive,
24499
24628
  {
24629
+ x: width,
24630
+ width: options.scrollbar?.visible === false ? 0 : Math.max(
24631
+ options.scrollbar?.thickness ?? DEFAULT_SCROLLBAR_THICKNESS,
24632
+ 6
24633
+ ),
24500
24634
  top: 0,
24501
24635
  height,
24502
24636
  headerBottom: headerHeight,
@@ -25998,6 +26132,7 @@ var ListTableSummaryController = class {
25998
26132
  const summaryTask = computeSummaryValuesAsync({
25999
26133
  rows: snapshot.displayRows,
26000
26134
  columns: snapshot.leafColumns,
26135
+ mergeCell: this.options.getOptions().query?.mergeCell,
26001
26136
  signal
26002
26137
  }).then((summaryValues) => {
26003
26138
  if (signal.aborted || taskId !== this.summaryTaskId) {