@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/README.md CHANGED
@@ -170,7 +170,9 @@ table.mount();
170
170
  - `checkbox`
171
171
  - `radio`
172
172
  - `switch`
173
- - `link`
173
+ - `link`
174
+
175
+ `icon` 当前内置 `star`、`sun`、`moon`、`check`(√)和 `close`(×)。
174
176
 
175
177
  ### 金额单元格示例
176
178
 
package/dist/index.cjs CHANGED
@@ -335,6 +335,30 @@ function stretchColumnWidths(columns, containerWidth) {
335
335
  stretchableColumns[stretchableColumns.length - 1].width += remain;
336
336
  }
337
337
  }
338
+ function shrinkColumnWidthsToFit(columns, containerWidth) {
339
+ let remaining = Math.max(
340
+ Math.ceil(computeColumnWidths(columns) - containerWidth),
341
+ 0
342
+ );
343
+ let shrinkableColumns = columns.filter(
344
+ (column) => column.width > column.minWidth
345
+ );
346
+ while (remaining > 0 && shrinkableColumns.length > 0) {
347
+ const share = Math.max(Math.floor(remaining / shrinkableColumns.length), 1);
348
+ shrinkableColumns.forEach((column) => {
349
+ if (remaining <= 0) {
350
+ return;
351
+ }
352
+ const shrink = Math.min(column.width - column.minWidth, share, remaining);
353
+ column.width -= shrink;
354
+ remaining -= shrink;
355
+ });
356
+ shrinkableColumns = shrinkableColumns.filter(
357
+ (column) => column.width > column.minWidth
358
+ );
359
+ }
360
+ return remaining === 0;
361
+ }
338
362
 
339
363
  // src/domain/columns/flatten-leaf-columns.ts
340
364
  function flattenLeafColumns(columns) {
@@ -3218,7 +3242,7 @@ function drawBodyButtonContent(params) {
3218
3242
  const top = rect.y + (rect.height - height) / 2;
3219
3243
  const palette = resolveButtonPalette(content);
3220
3244
  const textIndent = resolveContentTextIndent(content);
3221
- const paddingInline = BUTTON_PADDING_INLINE_MAP[size];
3245
+ const paddingInline = resolveButtonPaddingInline(content, size);
3222
3246
  const radius = BUTTON_RADIUS_MAP[size];
3223
3247
  ctx.save();
3224
3248
  ctx.globalAlpha *= resolveContentOpacity(content);
@@ -3326,9 +3350,12 @@ function measureButtonContentWidth(ctx, content, theme) {
3326
3350
  const intrinsicWidth = Math.max(
3327
3351
  ctx.measureText(content.text).width + resolveContentTextIndent(content),
3328
3352
  0
3329
- ) + BUTTON_PADDING_INLINE_MAP[size] * 2;
3353
+ ) + resolveButtonPaddingInline(content, size) * 2;
3330
3354
  return resolveContentLayoutWidth(content, intrinsicWidth);
3331
3355
  }
3356
+ function resolveButtonPaddingInline(content, size) {
3357
+ return content.buttonType === "link" || content.buttonType === "text" ? 4 : BUTTON_PADDING_INLINE_MAP[size];
3358
+ }
3332
3359
  function measureButtonContentHeight(content) {
3333
3360
  return BUTTON_HEIGHT_MAP[resolveButtonSize(content.size)];
3334
3361
  }
@@ -3928,11 +3955,25 @@ function drawImagePlaceholder(ctx, x, y, width, height, backgroundColor = PLACEH
3928
3955
  var SYMBOL_COLOR_MAP = {
3929
3956
  star: "#fadb14",
3930
3957
  sun: "#faad14",
3931
- moon: "#597ef7"
3958
+ moon: "#597ef7",
3959
+ check: "#52c41a",
3960
+ close: "#ff4d4f"
3932
3961
  };
3933
3962
  function drawCellSymbol(ctx, params) {
3934
3963
  const { type, x, y, size, activeColor, inactiveColor } = params;
3935
3964
  const fillRatio = Math.min(Math.max(params.fillRatio, 0), 1);
3965
+ if (type === "check" || type === "close") {
3966
+ drawStatusSymbol(ctx, {
3967
+ type,
3968
+ x,
3969
+ y,
3970
+ size,
3971
+ activeColor,
3972
+ inactiveColor,
3973
+ fillRatio
3974
+ });
3975
+ return;
3976
+ }
3936
3977
  appendCellSymbolPath(ctx, type, x, y, size);
3937
3978
  ctx.fillStyle = inactiveColor;
3938
3979
  ctx.fill("evenodd");
@@ -3950,6 +3991,10 @@ function resolveCellSymbolColor(type) {
3950
3991
  return SYMBOL_COLOR_MAP[type];
3951
3992
  }
3952
3993
  function appendCellSymbolPath(ctx, type, x, y, size) {
3994
+ if (type === "check" || type === "close") {
3995
+ appendStatusSymbolPath(ctx, type, x, y, size);
3996
+ return;
3997
+ }
3953
3998
  if (type === "moon") {
3954
3999
  appendMoonPath(ctx, x, y, size);
3955
4000
  return;
@@ -3970,6 +4015,38 @@ function appendCellSymbolPath(ctx, type, x, y, size) {
3970
4015
  }
3971
4016
  ctx.closePath();
3972
4017
  }
4018
+ function drawStatusSymbol(ctx, params) {
4019
+ const { type, x, y, size, activeColor, inactiveColor, fillRatio } = params;
4020
+ ctx.save();
4021
+ ctx.lineCap = "round";
4022
+ ctx.lineJoin = "round";
4023
+ ctx.lineWidth = Math.max(size * 0.12, 1.5);
4024
+ appendStatusSymbolPath(ctx, type, x, y, size);
4025
+ ctx.strokeStyle = inactiveColor;
4026
+ ctx.stroke();
4027
+ if (fillRatio > 0) {
4028
+ ctx.beginPath();
4029
+ ctx.rect(x, y, size * fillRatio, size);
4030
+ ctx.clip();
4031
+ appendStatusSymbolPath(ctx, type, x, y, size);
4032
+ ctx.strokeStyle = activeColor;
4033
+ ctx.stroke();
4034
+ }
4035
+ ctx.restore();
4036
+ }
4037
+ function appendStatusSymbolPath(ctx, type, x, y, size) {
4038
+ ctx.beginPath();
4039
+ if (type === "check") {
4040
+ ctx.moveTo(x + size * 0.16, y + size * 0.52);
4041
+ ctx.lineTo(x + size * 0.4, y + size * 0.76);
4042
+ ctx.lineTo(x + size * 0.84, y + size * 0.26);
4043
+ return;
4044
+ }
4045
+ ctx.moveTo(x + size * 0.22, y + size * 0.22);
4046
+ ctx.lineTo(x + size * 0.78, y + size * 0.78);
4047
+ ctx.moveTo(x + size * 0.78, y + size * 0.22);
4048
+ ctx.lineTo(x + size * 0.22, y + size * 0.78);
4049
+ }
3973
4050
  function appendMoonPath(ctx, x, y, size) {
3974
4051
  ctx.beginPath();
3975
4052
  ctx.moveTo(x + size * 0.64, y + size * 0.04);
@@ -6239,6 +6316,7 @@ function resolveColumnFormItemProps(column, context) {
6239
6316
  // src/rendering/cell-content/cell-content-renderer.ts
6240
6317
  var CONTENT_HORIZONTAL_PADDING = 12;
6241
6318
  var CONTENT_GAP = 8;
6319
+ var LINK_CONTENT_GAP = 4;
6242
6320
  var CONTENT_VERTICAL_PADDING = 6;
6243
6321
  function resolveBodyCellContents(params) {
6244
6322
  return resolveRawBodyCellContents(params).filter(
@@ -6673,8 +6751,8 @@ function drawBodyCellContents(params) {
6673
6751
  align: column.align
6674
6752
  });
6675
6753
  line.items.forEach((item, itemIndex) => {
6676
- if (itemIndex > 0 && item.gapBefore) {
6677
- cursorX += CONTENT_GAP;
6754
+ if (itemIndex > 0) {
6755
+ cursorX += item.gapBefore;
6678
6756
  }
6679
6757
  const itemDescriptors = [];
6680
6758
  drawExpandedBodyContent({
@@ -6769,7 +6847,7 @@ function measureBodyCellContentsWidth(params) {
6769
6847
  currentLineWidth = 0;
6770
6848
  return;
6771
6849
  }
6772
- const gapWidth = currentLineWidth > 0 && item.gapBefore ? CONTENT_GAP : 0;
6850
+ const gapWidth = currentLineWidth > 0 ? item.gapBefore : 0;
6773
6851
  currentLineWidth += gapWidth + contentWidth;
6774
6852
  });
6775
6853
  return Math.ceil(
@@ -6800,10 +6878,11 @@ function expandBodyContents(contents) {
6800
6878
  const textOnly = contents.every((content) => content.type === "text");
6801
6879
  const expanded = [];
6802
6880
  contents.forEach((content, contentIndex) => {
6881
+ const previousContent = contents[contentIndex - 1];
6803
6882
  expanded.push({
6804
6883
  content,
6805
6884
  contentIndex,
6806
- gapBefore: expanded.length > 0 && !textOnly
6885
+ gapBefore: expanded.length === 0 || textOnly ? 0 : resolveInlineContentGap(previousContent, content)
6807
6886
  });
6808
6887
  if ((content.type === "checkbox" || content.type === "radio") && content.label) {
6809
6888
  const textLabelContent = {
@@ -6816,12 +6895,18 @@ function expandBodyContents(contents) {
6816
6895
  expanded.push({
6817
6896
  content: textLabelContent,
6818
6897
  contentIndex,
6819
- gapBefore: true
6898
+ gapBefore: CONTENT_GAP
6820
6899
  });
6821
6900
  }
6822
6901
  });
6823
6902
  return expanded;
6824
6903
  }
6904
+ function resolveInlineContentGap(previous, current) {
6905
+ return isInlineActionContent(previous) && isInlineActionContent(current) ? LINK_CONTENT_GAP : CONTENT_GAP;
6906
+ }
6907
+ function isInlineActionContent(content) {
6908
+ return content?.type === "link" || content?.type === "button" && (content.buttonType === "link" || content.buttonType === "text");
6909
+ }
6825
6910
  function buildSingleLineLayout(ctx, contents, availableWidth, theme) {
6826
6911
  const line = {
6827
6912
  items: [],
@@ -6857,7 +6942,7 @@ function buildSingleLineLayout(ctx, contents, availableWidth, theme) {
6857
6942
  }
6858
6943
  break;
6859
6944
  }
6860
- const gapWidth = line.items.length > 0 && item.gapBefore ? CONTENT_GAP : 0;
6945
+ const gapWidth = line.items.length > 0 ? item.gapBefore : 0;
6861
6946
  const remainingWidth = availableWidth - line.width - gapWidth;
6862
6947
  if (remainingWidth <= 0) {
6863
6948
  truncated = true;
@@ -6925,7 +7010,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6925
7010
  items: [
6926
7011
  {
6927
7012
  ...currentItem,
6928
- gapBefore: false,
7013
+ gapBefore: 0,
6929
7014
  width: fullWidth2
6930
7015
  }
6931
7016
  ],
@@ -6956,7 +7041,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6956
7041
  {
6957
7042
  ...currentItem,
6958
7043
  content: fittedContent2,
6959
- gapBefore: false,
7044
+ gapBefore: 0,
6960
7045
  width: fittedWidth
6961
7046
  }
6962
7047
  ],
@@ -6978,11 +7063,11 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6978
7063
  currentItem = {
6979
7064
  ...currentItem,
6980
7065
  content: setBreakableContentText(currentItem.content, remainingText2),
6981
- gapBefore: false
7066
+ gapBefore: 0
6982
7067
  };
6983
7068
  continue;
6984
7069
  }
6985
- const gapWidth = currentLine.items.length > 0 && currentItem.gapBefore ? CONTENT_GAP : 0;
7070
+ const gapWidth = currentLine.items.length > 0 ? currentItem.gapBefore : 0;
6986
7071
  const remainingWidth = availableWidth - currentLine.width - gapWidth;
6987
7072
  if (remainingWidth <= 0) {
6988
7073
  if (lines.length + 1 >= maxLines) {
@@ -6996,7 +7081,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6996
7081
  currentLine = { items: [], width: 0 };
6997
7082
  currentItem = {
6998
7083
  ...currentItem,
6999
- gapBefore: false
7084
+ gapBefore: 0
7000
7085
  };
7001
7086
  continue;
7002
7087
  }
@@ -7016,7 +7101,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
7016
7101
  currentLine = { items: [], width: 0 };
7017
7102
  currentItem = {
7018
7103
  ...currentItem,
7019
- gapBefore: false
7104
+ gapBefore: 0
7020
7105
  };
7021
7106
  continue;
7022
7107
  }
@@ -7056,7 +7141,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
7056
7141
  currentLine = { items: [], width: 0 };
7057
7142
  currentItem = {
7058
7143
  ...currentItem,
7059
- gapBefore: false
7144
+ gapBefore: 0
7060
7145
  };
7061
7146
  continue;
7062
7147
  }
@@ -7084,7 +7169,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
7084
7169
  currentItem = {
7085
7170
  ...currentItem,
7086
7171
  content: setBreakableContentText(currentItem.content, remainingText),
7087
- gapBefore: false
7172
+ gapBefore: 0
7088
7173
  };
7089
7174
  }
7090
7175
  if (truncated) {
@@ -7597,10 +7682,10 @@ function applyTrailingEllipsis(ctx, line, theme, availableWidth) {
7597
7682
  continue;
7598
7683
  }
7599
7684
  const widthBefore = line.items.slice(0, index).reduce((sum, current, currentIndex) => {
7600
- const gapWidth2 = currentIndex > 0 && current.gapBefore ? CONTENT_GAP : 0;
7685
+ const gapWidth2 = currentIndex > 0 ? current.gapBefore : 0;
7601
7686
  return sum + gapWidth2 + current.width;
7602
7687
  }, 0);
7603
- const gapWidth = index > 0 && item.gapBefore ? CONTENT_GAP : 0;
7688
+ const gapWidth = index > 0 ? item.gapBefore : 0;
7604
7689
  const nextContent = truncateExpandedContent(
7605
7690
  ctx,
7606
7691
  item.content,
@@ -10411,7 +10496,7 @@ var ListTableCarouselController = class {
10411
10496
  var SUMMARY_ASYNC_BATCH_SIZE = 2e3;
10412
10497
  var SUMMARY_ASYNC_FRAME_BUDGET = 8;
10413
10498
  async function computeSummaryValuesAsync(params) {
10414
- const { rows, columns, signal } = params;
10499
+ const { rows, columns, mergeCell, signal } = params;
10415
10500
  const summaryValues = /* @__PURE__ */ new Map();
10416
10501
  const accumulators = [];
10417
10502
  columns.forEach((column) => {
@@ -10464,8 +10549,14 @@ async function computeSummaryValuesAsync(params) {
10464
10549
  }
10465
10550
  startIndex = endIndex;
10466
10551
  }
10552
+ const mergedRowCount = accumulators.some(
10553
+ (item) => item.type === "mergedRowCount"
10554
+ ) ? countMergedRows(rows, columns, mergeCell) : null;
10467
10555
  accumulators.forEach((item) => {
10468
- summaryValues.set(item.column.key, finalizeSummaryValue(item, rows));
10556
+ summaryValues.set(
10557
+ item.column.key,
10558
+ finalizeSummaryValue(item, rows, mergedRowCount)
10559
+ );
10469
10560
  });
10470
10561
  return summaryValues;
10471
10562
  }
@@ -10520,7 +10611,7 @@ function updateSummaryAccumulator(item, record) {
10520
10611
  item.max = numericValue;
10521
10612
  }
10522
10613
  }
10523
- function finalizeSummaryValue(item, rows) {
10614
+ function finalizeSummaryValue(item, rows, mergedRowCount) {
10524
10615
  if (item.column.summaryTitle != null) {
10525
10616
  return item.column.summaryTitle;
10526
10617
  }
@@ -10528,7 +10619,11 @@ function finalizeSummaryValue(item, rows) {
10528
10619
  return formatSummaryOutput(item, String(rows.length), rows);
10529
10620
  }
10530
10621
  if (item.type === "mergedRowCount") {
10531
- return formatSummaryOutput(item, String(countMergedRows(rows)), rows);
10622
+ return formatSummaryOutput(
10623
+ item,
10624
+ String(mergedRowCount ?? rows.length),
10625
+ rows
10626
+ );
10532
10627
  }
10533
10628
  if (item.type === "count") {
10534
10629
  return formatSummaryOutput(item, String(item.valueCount), rows);
@@ -10619,7 +10714,76 @@ function formatSummaryOutput(item, value, rows) {
10619
10714
  }
10620
10715
  return value;
10621
10716
  }
10622
- function countMergedRows(rows) {
10717
+ function countMergedRows(rows, columns, mergeCell) {
10718
+ const coveredRowIndexes = /* @__PURE__ */ new Set();
10719
+ const explicitRowSpans = /* @__PURE__ */ new Map();
10720
+ columns.forEach((column) => {
10721
+ if (!column.onCell) {
10722
+ return;
10723
+ }
10724
+ rows.forEach((record, rowIndex) => {
10725
+ const value = utils.getValueByDataIndex(record, column.dataIndex);
10726
+ const span = column.onCell?.(value, record, rowIndex, column);
10727
+ if (!span || !Object.prototype.hasOwnProperty.call(span, "rowSpan")) {
10728
+ return;
10729
+ }
10730
+ const rowSpan = span.rowSpan ?? 1;
10731
+ explicitRowSpans.set(`${rowIndex}::${column.key}`, rowSpan);
10732
+ if (rowSpan === 0) {
10733
+ coveredRowIndexes.add(rowIndex);
10734
+ return;
10735
+ }
10736
+ if (!Number.isFinite(rowSpan) || rowSpan <= 1) {
10737
+ return;
10738
+ }
10739
+ const spanEnd = Math.min(
10740
+ rows.length,
10741
+ rowIndex + Math.floor(rowSpan)
10742
+ );
10743
+ for (let index = rowIndex + 1; index < spanEnd; index += 1) {
10744
+ coveredRowIndexes.add(index);
10745
+ }
10746
+ });
10747
+ });
10748
+ const rowMergeRule = mergeCell?.row;
10749
+ const targetDataIndexes = rowMergeRule?.columns?.length ? rowMergeRule.columns : rowMergeRule?.keys;
10750
+ const targetMergeColumns = columns.filter(
10751
+ (column) => targetDataIndexes?.some(
10752
+ (dataIndex) => utils.isSameDataIndex(column.dataIndex, dataIndex)
10753
+ )
10754
+ );
10755
+ if (rowMergeRule?.keys.length && targetMergeColumns.length) {
10756
+ targetMergeColumns.forEach((column) => {
10757
+ let rowIndex = 0;
10758
+ while (rowIndex < rows.length) {
10759
+ if (explicitRowSpans.has(`${rowIndex}::${column.key}`)) {
10760
+ rowIndex += 1;
10761
+ continue;
10762
+ }
10763
+ const currentGroupKey = getMergeGroupKey(
10764
+ rows[rowIndex],
10765
+ rowMergeRule.keys
10766
+ );
10767
+ let rowSpan = 1;
10768
+ for (let index = rowIndex + 1; index < rows.length; index += 1) {
10769
+ if (explicitRowSpans.has(`${index}::${column.key}`)) {
10770
+ break;
10771
+ }
10772
+ if (getMergeGroupKey(rows[index], rowMergeRule.keys) !== currentGroupKey) {
10773
+ break;
10774
+ }
10775
+ rowSpan += 1;
10776
+ }
10777
+ for (let index = rowIndex + 1; index < rowIndex + rowSpan; index += 1) {
10778
+ coveredRowIndexes.add(index);
10779
+ }
10780
+ rowIndex += rowSpan;
10781
+ }
10782
+ });
10783
+ }
10784
+ if (coveredRowIndexes.size > 0) {
10785
+ return rows.length - coveredRowIndexes.size;
10786
+ }
10623
10787
  return rows.reduce((count, record) => {
10624
10788
  if (record == null || typeof record !== "object") {
10625
10789
  return count + 1;
@@ -10631,6 +10795,20 @@ function countMergedRows(rows) {
10631
10795
  return rowSpan > 0 ? count + 1 : count;
10632
10796
  }, 0);
10633
10797
  }
10798
+ function getMergeGroupKey(record, keys) {
10799
+ return keys.map(
10800
+ (dataIndex) => normalizeMergeValue(utils.getValueByDataIndex(record, dataIndex))
10801
+ ).join("|");
10802
+ }
10803
+ function normalizeMergeValue(value) {
10804
+ if (value == null) {
10805
+ return "";
10806
+ }
10807
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
10808
+ return String(value);
10809
+ }
10810
+ return JSON.stringify(value) ?? "";
10811
+ }
10634
10812
  function yieldToMainThread() {
10635
10813
  return new Promise((resolve) => {
10636
10814
  if (typeof requestAnimationFrame === "function") {
@@ -20127,7 +20305,7 @@ function buildListTableRenderSnapshot(params) {
20127
20305
  options.scrollbar?.thickness ?? DEFAULT_SCROLLBAR_THICKNESS,
20128
20306
  6
20129
20307
  );
20130
- let width = hostWidth;
20308
+ let width = Math.max(hostWidth - scrollbarThickness, 0);
20131
20309
  let height = hostHeight;
20132
20310
  const sourceNormalizedColumns = normalizeColumns(
20133
20311
  getResolvedColumns(options, selectedRowKeys)
@@ -20139,6 +20317,10 @@ function buildListTableRenderSnapshot(params) {
20139
20317
  groupedColumnKeys
20140
20318
  );
20141
20319
  const leafColumns = flattenLeafColumns(normalizedColumns);
20320
+ const totalColumnWidth = computeColumnWidths(leafColumns);
20321
+ if (width > 0 && totalColumnWidth > width && totalColumnWidth <= hostWidth) {
20322
+ shrinkColumnWidthsToFit(leafColumns, width);
20323
+ }
20142
20324
  if (options.stretchColumns !== false && width > 0 && !draggingResize) {
20143
20325
  stretchColumnWidths(leafColumns, width);
20144
20326
  }
@@ -20402,54 +20584,6 @@ function buildListTableRenderSnapshot(params) {
20402
20584
  fixedWidthRight: columnMetrics.fixedWidthRight,
20403
20585
  scroll
20404
20586
  });
20405
- for (let index = 0; index < 2 && scrollbarThickness > 0; index += 1) {
20406
- const nextWidth = Math.max(
20407
- hostWidth - (viewportResult.viewport.maxScrollTop > 0 ? scrollbarThickness : 0),
20408
- 0
20409
- );
20410
- const nextHeight = Math.max(
20411
- hostHeight - (viewportResult.viewport.maxScrollLeft > 0 ? scrollbarThickness : 0),
20412
- 0
20413
- );
20414
- if (nextWidth === width && nextHeight === height) {
20415
- break;
20416
- }
20417
- width = nextWidth;
20418
- height = nextHeight;
20419
- bodyState = resolveCurrentBodyState();
20420
- if (plainRowWindow) {
20421
- bodyState.frozenRows.scroll.windowed = true;
20422
- bodyState.frozenRows.scroll.dataRowIndexAligned = true;
20423
- bodyState.frozenRows.scroll.rowIndexMap = plainRowWindow.rowIndexMap;
20424
- bodyState.frozenRows.scroll.rowOffsetMap = plainRowWindow.rowOffsetMap;
20425
- bodyState.bodyLayout = resolveBodyLayout({
20426
- height,
20427
- headerHeight,
20428
- summaryRowHeight,
20429
- hasSummary,
20430
- rowHeight,
20431
- totalBodyHeight: plainRowWindow.totalBodyHeight,
20432
- topFrozenRowCount: 0,
20433
- bottomFrozenRowCount: 0,
20434
- scrollRowCount: plainRowWindow.totalRowCount
20435
- });
20436
- }
20437
- columnMetrics = resolveColumnMetrics({
20438
- columns: leafColumns,
20439
- tableWidth: width
20440
- });
20441
- viewportResult = computeViewport({
20442
- width,
20443
- height,
20444
- headerHeight,
20445
- bodyHeight: bodyState.bodyLayout.scrollBodyHeight,
20446
- totalWidth: columnMetrics.totalWidth,
20447
- totalBodyHeight: bodyState.bodyLayout.totalBodyHeight,
20448
- fixedWidthLeft: columnMetrics.fixedWidthLeft,
20449
- fixedWidthRight: columnMetrics.fixedWidthRight,
20450
- scroll
20451
- });
20452
- }
20453
20587
  scrollPageSize = resolveScrollPageSize({
20454
20588
  options,
20455
20589
  pageSize: query.pagination.pageSize,
@@ -20730,8 +20864,8 @@ function updateListTableRenderSnapshotScroll(params) {
20730
20864
  } : snapshot.frozenRows;
20731
20865
  return {
20732
20866
  ...snapshot,
20733
- width,
20734
- height,
20867
+ width: snapshot.width,
20868
+ height: snapshot.height,
20735
20869
  columnSegments,
20736
20870
  headerRows,
20737
20871
  scrollbarLayout,
@@ -21116,13 +21250,8 @@ function drawScrollbars(ctx, layout, descriptors, borderColor, opacity = 1, inte
21116
21250
  verticalFrame.bodyBackgroundColor
21117
21251
  );
21118
21252
  }
21119
- if (layout.vertical && verticalFrame) {
21120
- drawVerticalScrollbarFrame(
21121
- ctx,
21122
- layout.vertical,
21123
- verticalFrame,
21124
- borderColor
21125
- );
21253
+ if (verticalFrame) {
21254
+ drawVerticalScrollbarFrame(ctx, verticalFrame, borderColor);
21126
21255
  }
21127
21256
  if (layout.horizontal) {
21128
21257
  drawAxisScrollbar(
@@ -21240,28 +21369,28 @@ function drawTrackBorder(ctx, rect, axis, borderColor) {
21240
21369
  ctx.stroke();
21241
21370
  ctx.restore();
21242
21371
  }
21243
- function drawVerticalScrollbarFrame(ctx, layout, frame, borderColor) {
21244
- const left = Math.round(layout.decreaseButton.x) + 0.5;
21245
- const right = Math.round(layout.decreaseButton.x + layout.decreaseButton.width) - 0.5;
21372
+ function drawVerticalScrollbarFrame(ctx, frame, borderColor) {
21373
+ const left = Math.round(frame.x) + 0.5;
21374
+ const right = Math.round(frame.x + frame.width) - 0.5;
21246
21375
  const top = Math.round(frame.top) + 0.5;
21247
21376
  const bottom = Math.round(frame.top + frame.height) - 0.5;
21248
21377
  const headerBottom = Math.round(frame.headerBottom) + 0.5;
21249
- if (right <= left || bottom <= top) {
21378
+ if (frame.width <= 0 || right <= left || bottom <= top) {
21250
21379
  return;
21251
21380
  }
21252
21381
  ctx.save();
21253
21382
  ctx.fillStyle = frame.headerBackgroundColor;
21254
21383
  ctx.fillRect(
21255
- layout.decreaseButton.x,
21384
+ frame.x,
21256
21385
  frame.top,
21257
- layout.decreaseButton.width,
21386
+ frame.width,
21258
21387
  Math.max(frame.headerBottom - frame.top, 0)
21259
21388
  );
21260
21389
  ctx.fillStyle = frame.bodyBackgroundColor;
21261
21390
  ctx.fillRect(
21262
- layout.decreaseButton.x,
21391
+ frame.x,
21263
21392
  frame.headerBottom,
21264
- layout.decreaseButton.width,
21393
+ frame.width,
21265
21394
  Math.max(frame.top + frame.height - frame.headerBottom, 0)
21266
21395
  );
21267
21396
  ctx.strokeStyle = borderColor;
@@ -22107,7 +22236,7 @@ function buildAutoRowSpanMap(rows, columns, rule, spanConfigMap, sourceRowIndexM
22107
22236
  rowIndex += 1;
22108
22237
  continue;
22109
22238
  }
22110
- const currentGroupKey = getMergeGroupKey(rows[rowIndex], groupKeys);
22239
+ const currentGroupKey = getMergeGroupKey2(rows[rowIndex], groupKeys);
22111
22240
  let rowSpan = 1;
22112
22241
  for (let index = rowIndex + 1; index < rows.length; index += 1) {
22113
22242
  if (sourceRowIndexMap[index] !== (sourceRowIndexMap[index - 1] ?? index - 1) + 1) {
@@ -22117,7 +22246,7 @@ function buildAutoRowSpanMap(rows, columns, rule, spanConfigMap, sourceRowIndexM
22117
22246
  if (hasExplicitSpan(spanConfigMap.get(nextCellKey), "rowSpan")) {
22118
22247
  break;
22119
22248
  }
22120
- if (getMergeGroupKey(rows[index], groupKeys) !== currentGroupKey) {
22249
+ if (getMergeGroupKey2(rows[index], groupKeys) !== currentGroupKey) {
22121
22250
  break;
22122
22251
  }
22123
22252
  rowSpan += 1;
@@ -22220,13 +22349,13 @@ function clampSpan(span, max) {
22220
22349
  }
22221
22350
  return Math.max(1, Math.min(Math.floor(span), max));
22222
22351
  }
22223
- function getMergeGroupKey(record, keys) {
22352
+ function getMergeGroupKey2(record, keys) {
22224
22353
  if (!keys?.length) {
22225
22354
  return "";
22226
22355
  }
22227
- return keys.map((key) => normalizeMergeValue(utils.getValueByDataIndex(record, key))).join("|");
22356
+ return keys.map((key) => normalizeMergeValue2(utils.getValueByDataIndex(record, key))).join("|");
22228
22357
  }
22229
- function normalizeMergeValue(value) {
22358
+ function normalizeMergeValue2(value) {
22230
22359
  if (value == null) {
22231
22360
  return "";
22232
22361
  }
@@ -22236,7 +22365,7 @@ function normalizeMergeValue(value) {
22236
22365
  return JSON.stringify(value) ?? "";
22237
22366
  }
22238
22367
  function isSameMergeValue(left, right) {
22239
- return normalizeMergeValue(left) === normalizeMergeValue(right);
22368
+ return normalizeMergeValue2(left) === normalizeMergeValue2(right);
22240
22369
  }
22241
22370
  function getMergedCellWidth(columns, startIndex, colSpan) {
22242
22371
  let width = 0;
@@ -24499,6 +24628,11 @@ function executeListTableRenderPipeline(params) {
24499
24628
  scrollbarOpacity,
24500
24629
  isScrollbarInteractive,
24501
24630
  {
24631
+ x: width,
24632
+ width: options.scrollbar?.visible === false ? 0 : Math.max(
24633
+ options.scrollbar?.thickness ?? DEFAULT_SCROLLBAR_THICKNESS,
24634
+ 6
24635
+ ),
24502
24636
  top: 0,
24503
24637
  height,
24504
24638
  headerBottom: headerHeight,
@@ -26000,6 +26134,7 @@ var ListTableSummaryController = class {
26000
26134
  const summaryTask = computeSummaryValuesAsync({
26001
26135
  rows: snapshot.displayRows,
26002
26136
  columns: snapshot.leafColumns,
26137
+ mergeCell: this.options.getOptions().query?.mergeCell,
26003
26138
  signal
26004
26139
  }).then((summaryValues) => {
26005
26140
  if (signal.aborted || taskId !== this.summaryTaskId) {