@canvas-components/list-table 0.2.7 → 0.3.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.
package/dist/index.cjs CHANGED
@@ -982,6 +982,7 @@ function collectLeafColumns(columns) {
982
982
  // src/domain/constants.ts
983
983
  var DEFAULT_ROW_HEIGHT = 32;
984
984
  var DEFAULT_HEADER_ROW_HEIGHT = DEFAULT_ROW_HEIGHT;
985
+ var DEFAULT_SCROLLBAR_THICKNESS = 10;
985
986
  var HORIZONTAL_SCROLL_STEP = 120;
986
987
  var DEFAULT_SUMMARY_ROW_HEIGHT = DEFAULT_ROW_HEIGHT;
987
988
  var DEFAULT_EMPTY_BODY_HEIGHT = 96;
@@ -990,6 +991,7 @@ var FALLBACK_TABLE_WIDTH = 320;
990
991
  var FALLBACK_TABLE_HEIGHT = 240;
991
992
  var BODY_TOOLTIP_DELAY = 1e3;
992
993
  var TABLE_CONTENT_BORDER_SIZE = 2;
994
+ var TABLE_CONTENT_BORDER_RADIUS = 8;
993
995
  var SCROLL_OVERFLOW_EPSILON = 1;
994
996
  function resolveTableSize(value, fallback) {
995
997
  if (value == null) {
@@ -1050,6 +1052,7 @@ var ListTableDomHost = class {
1050
1052
  return this.nodes;
1051
1053
  }
1052
1054
  const wrapper = document.createElement("div");
1055
+ wrapper.className = "canvas-list-table-root";
1053
1056
  wrapper.style.position = "relative";
1054
1057
  wrapper.style.display = "flex";
1055
1058
  wrapper.style.flexDirection = "column";
@@ -1114,7 +1117,7 @@ var ListTableDomHost = class {
1114
1117
  );
1115
1118
  this.applyWrapperHeight();
1116
1119
  this.nodes.contentLayerElement.style.border = `1px solid ${theme.borderColor}`;
1117
- this.nodes.contentLayerElement.style.borderRadius = "0";
1120
+ this.nodes.contentLayerElement.style.borderRadius = `${TABLE_CONTENT_BORDER_RADIUS}px`;
1118
1121
  this.nodes.contentLayerElement.style.background = theme.backgroundColor;
1119
1122
  this.nodes.paginationElement.style.borderTop = `1px solid ${theme.borderColor}`;
1120
1123
  this.nodes.paginationElement.style.background = theme.backgroundColor;
@@ -1761,7 +1764,7 @@ var headerSelectionStateCache = /* @__PURE__ */ new WeakMap();
1761
1764
  var ROW_SELECTION_COLUMN_KEY = "__row_selection__";
1762
1765
  var ROW_SELECTOR_COLUMN_KEY = "__row_selector__";
1763
1766
  var EXPAND_COLUMN_KEY = "__row_expand__";
1764
- var DEFAULT_ROW_SELECTOR_WIDTH = 12;
1767
+ var DEFAULT_ROW_SELECTOR_WIDTH = DEFAULT_SCROLLBAR_THICKNESS;
1765
1768
  function getInitialSelectedRowKeys(options) {
1766
1769
  const rowSelection = options.rowSelection;
1767
1770
  if (!rowSelection) {
@@ -2550,8 +2553,14 @@ function getPriority(descriptor) {
2550
2553
  if (descriptor.kind === "body" && descriptor.fixed) {
2551
2554
  priority += 1;
2552
2555
  }
2556
+ if (isHeaderDescriptor(descriptor.kind) && descriptor.fixed) {
2557
+ priority += 3;
2558
+ }
2553
2559
  return priority;
2554
2560
  }
2561
+ function isHeaderDescriptor(kind) {
2562
+ return kind === "header" || kind === "header-selection" || kind === "header-action" || kind === "column-collapse-trigger" || kind === "resize-handle";
2563
+ }
2555
2564
  function getBasePriority(kind) {
2556
2565
  switch (kind) {
2557
2566
  case "grouping-remove":
@@ -3919,11 +3928,25 @@ function drawImagePlaceholder(ctx, x, y, width, height, backgroundColor = PLACEH
3919
3928
  var SYMBOL_COLOR_MAP = {
3920
3929
  star: "#fadb14",
3921
3930
  sun: "#faad14",
3922
- moon: "#597ef7"
3931
+ moon: "#597ef7",
3932
+ check: "#52c41a",
3933
+ close: "#ff4d4f"
3923
3934
  };
3924
3935
  function drawCellSymbol(ctx, params) {
3925
3936
  const { type, x, y, size, activeColor, inactiveColor } = params;
3926
3937
  const fillRatio = Math.min(Math.max(params.fillRatio, 0), 1);
3938
+ if (type === "check" || type === "close") {
3939
+ drawStatusSymbol(ctx, {
3940
+ type,
3941
+ x,
3942
+ y,
3943
+ size,
3944
+ activeColor,
3945
+ inactiveColor,
3946
+ fillRatio
3947
+ });
3948
+ return;
3949
+ }
3927
3950
  appendCellSymbolPath(ctx, type, x, y, size);
3928
3951
  ctx.fillStyle = inactiveColor;
3929
3952
  ctx.fill("evenodd");
@@ -3941,6 +3964,10 @@ function resolveCellSymbolColor(type) {
3941
3964
  return SYMBOL_COLOR_MAP[type];
3942
3965
  }
3943
3966
  function appendCellSymbolPath(ctx, type, x, y, size) {
3967
+ if (type === "check" || type === "close") {
3968
+ appendStatusSymbolPath(ctx, type, x, y, size);
3969
+ return;
3970
+ }
3944
3971
  if (type === "moon") {
3945
3972
  appendMoonPath(ctx, x, y, size);
3946
3973
  return;
@@ -3961,6 +3988,38 @@ function appendCellSymbolPath(ctx, type, x, y, size) {
3961
3988
  }
3962
3989
  ctx.closePath();
3963
3990
  }
3991
+ function drawStatusSymbol(ctx, params) {
3992
+ const { type, x, y, size, activeColor, inactiveColor, fillRatio } = params;
3993
+ ctx.save();
3994
+ ctx.lineCap = "round";
3995
+ ctx.lineJoin = "round";
3996
+ ctx.lineWidth = Math.max(size * 0.12, 1.5);
3997
+ appendStatusSymbolPath(ctx, type, x, y, size);
3998
+ ctx.strokeStyle = inactiveColor;
3999
+ ctx.stroke();
4000
+ if (fillRatio > 0) {
4001
+ ctx.beginPath();
4002
+ ctx.rect(x, y, size * fillRatio, size);
4003
+ ctx.clip();
4004
+ appendStatusSymbolPath(ctx, type, x, y, size);
4005
+ ctx.strokeStyle = activeColor;
4006
+ ctx.stroke();
4007
+ }
4008
+ ctx.restore();
4009
+ }
4010
+ function appendStatusSymbolPath(ctx, type, x, y, size) {
4011
+ ctx.beginPath();
4012
+ if (type === "check") {
4013
+ ctx.moveTo(x + size * 0.16, y + size * 0.52);
4014
+ ctx.lineTo(x + size * 0.4, y + size * 0.76);
4015
+ ctx.lineTo(x + size * 0.84, y + size * 0.26);
4016
+ return;
4017
+ }
4018
+ ctx.moveTo(x + size * 0.22, y + size * 0.22);
4019
+ ctx.lineTo(x + size * 0.78, y + size * 0.78);
4020
+ ctx.moveTo(x + size * 0.78, y + size * 0.22);
4021
+ ctx.lineTo(x + size * 0.22, y + size * 0.78);
4022
+ }
3964
4023
  function appendMoonPath(ctx, x, y, size) {
3965
4024
  ctx.beginPath();
3966
4025
  ctx.moveTo(x + size * 0.64, y + size * 0.04);
@@ -6230,6 +6289,7 @@ function resolveColumnFormItemProps(column, context) {
6230
6289
  // src/rendering/cell-content/cell-content-renderer.ts
6231
6290
  var CONTENT_HORIZONTAL_PADDING = 12;
6232
6291
  var CONTENT_GAP = 8;
6292
+ var LINK_CONTENT_GAP = 4;
6233
6293
  var CONTENT_VERTICAL_PADDING = 6;
6234
6294
  function resolveBodyCellContents(params) {
6235
6295
  return resolveRawBodyCellContents(params).filter(
@@ -6625,10 +6685,7 @@ function drawBodyCellContents(params) {
6625
6685
  return void 0;
6626
6686
  }
6627
6687
  const tooltipText = column.ellipsis === true && layout.truncated ? buildBodyContentsPlainText(contents) : void 0;
6628
- const blockHeight = Math.min(
6629
- layout.lines.length * lineHeight,
6630
- availableHeight
6631
- );
6688
+ const blockHeight = layout.lines.length * lineHeight;
6632
6689
  const contentTop = resolveContentTop(
6633
6690
  rect,
6634
6691
  blockHeight,
@@ -6637,9 +6694,9 @@ function drawBodyCellContents(params) {
6637
6694
  );
6638
6695
  const contentRect = {
6639
6696
  x: rect.x + paddingInline,
6640
- y: rect.y + paddingBlock,
6697
+ y: rect.y,
6641
6698
  width: availableWidth,
6642
- height: availableHeight
6699
+ height: rect.height
6643
6700
  };
6644
6701
  const contentVisibleRect = visibleRect ? intersectRects(contentRect, visibleRect) : contentRect;
6645
6702
  if (!contentVisibleRect) {
@@ -6667,8 +6724,8 @@ function drawBodyCellContents(params) {
6667
6724
  align: column.align
6668
6725
  });
6669
6726
  line.items.forEach((item, itemIndex) => {
6670
- if (itemIndex > 0 && item.gapBefore) {
6671
- cursorX += CONTENT_GAP;
6727
+ if (itemIndex > 0) {
6728
+ cursorX += item.gapBefore;
6672
6729
  }
6673
6730
  const itemDescriptors = [];
6674
6731
  drawExpandedBodyContent({
@@ -6763,7 +6820,7 @@ function measureBodyCellContentsWidth(params) {
6763
6820
  currentLineWidth = 0;
6764
6821
  return;
6765
6822
  }
6766
- const gapWidth = currentLineWidth > 0 && item.gapBefore ? CONTENT_GAP : 0;
6823
+ const gapWidth = currentLineWidth > 0 ? item.gapBefore : 0;
6767
6824
  currentLineWidth += gapWidth + contentWidth;
6768
6825
  });
6769
6826
  return Math.ceil(
@@ -6794,10 +6851,11 @@ function expandBodyContents(contents) {
6794
6851
  const textOnly = contents.every((content) => content.type === "text");
6795
6852
  const expanded = [];
6796
6853
  contents.forEach((content, contentIndex) => {
6854
+ const previousContent = contents[contentIndex - 1];
6797
6855
  expanded.push({
6798
6856
  content,
6799
6857
  contentIndex,
6800
- gapBefore: expanded.length > 0 && !textOnly
6858
+ gapBefore: expanded.length === 0 || textOnly ? 0 : previousContent?.type === "link" && content.type === "link" ? LINK_CONTENT_GAP : CONTENT_GAP
6801
6859
  });
6802
6860
  if ((content.type === "checkbox" || content.type === "radio") && content.label) {
6803
6861
  const textLabelContent = {
@@ -6810,7 +6868,7 @@ function expandBodyContents(contents) {
6810
6868
  expanded.push({
6811
6869
  content: textLabelContent,
6812
6870
  contentIndex,
6813
- gapBefore: true
6871
+ gapBefore: CONTENT_GAP
6814
6872
  });
6815
6873
  }
6816
6874
  });
@@ -6851,7 +6909,7 @@ function buildSingleLineLayout(ctx, contents, availableWidth, theme) {
6851
6909
  }
6852
6910
  break;
6853
6911
  }
6854
- const gapWidth = line.items.length > 0 && item.gapBefore ? CONTENT_GAP : 0;
6912
+ const gapWidth = line.items.length > 0 ? item.gapBefore : 0;
6855
6913
  const remainingWidth = availableWidth - line.width - gapWidth;
6856
6914
  if (remainingWidth <= 0) {
6857
6915
  truncated = true;
@@ -6919,7 +6977,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6919
6977
  items: [
6920
6978
  {
6921
6979
  ...currentItem,
6922
- gapBefore: false,
6980
+ gapBefore: 0,
6923
6981
  width: fullWidth2
6924
6982
  }
6925
6983
  ],
@@ -6950,7 +7008,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6950
7008
  {
6951
7009
  ...currentItem,
6952
7010
  content: fittedContent2,
6953
- gapBefore: false,
7011
+ gapBefore: 0,
6954
7012
  width: fittedWidth
6955
7013
  }
6956
7014
  ],
@@ -6972,11 +7030,11 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6972
7030
  currentItem = {
6973
7031
  ...currentItem,
6974
7032
  content: setBreakableContentText(currentItem.content, remainingText2),
6975
- gapBefore: false
7033
+ gapBefore: 0
6976
7034
  };
6977
7035
  continue;
6978
7036
  }
6979
- const gapWidth = currentLine.items.length > 0 && currentItem.gapBefore ? CONTENT_GAP : 0;
7037
+ const gapWidth = currentLine.items.length > 0 ? currentItem.gapBefore : 0;
6980
7038
  const remainingWidth = availableWidth - currentLine.width - gapWidth;
6981
7039
  if (remainingWidth <= 0) {
6982
7040
  if (lines.length + 1 >= maxLines) {
@@ -6990,7 +7048,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
6990
7048
  currentLine = { items: [], width: 0 };
6991
7049
  currentItem = {
6992
7050
  ...currentItem,
6993
- gapBefore: false
7051
+ gapBefore: 0
6994
7052
  };
6995
7053
  continue;
6996
7054
  }
@@ -7010,7 +7068,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
7010
7068
  currentLine = { items: [], width: 0 };
7011
7069
  currentItem = {
7012
7070
  ...currentItem,
7013
- gapBefore: false
7071
+ gapBefore: 0
7014
7072
  };
7015
7073
  continue;
7016
7074
  }
@@ -7050,7 +7108,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
7050
7108
  currentLine = { items: [], width: 0 };
7051
7109
  currentItem = {
7052
7110
  ...currentItem,
7053
- gapBefore: false
7111
+ gapBefore: 0
7054
7112
  };
7055
7113
  continue;
7056
7114
  }
@@ -7078,7 +7136,7 @@ function buildWrappedLineLayout(ctx, contents, availableWidth, maxLines, theme)
7078
7136
  currentItem = {
7079
7137
  ...currentItem,
7080
7138
  content: setBreakableContentText(currentItem.content, remainingText),
7081
- gapBefore: false
7139
+ gapBefore: 0
7082
7140
  };
7083
7141
  }
7084
7142
  if (truncated) {
@@ -7591,10 +7649,10 @@ function applyTrailingEllipsis(ctx, line, theme, availableWidth) {
7591
7649
  continue;
7592
7650
  }
7593
7651
  const widthBefore = line.items.slice(0, index).reduce((sum, current, currentIndex) => {
7594
- const gapWidth2 = currentIndex > 0 && current.gapBefore ? CONTENT_GAP : 0;
7652
+ const gapWidth2 = currentIndex > 0 ? current.gapBefore : 0;
7595
7653
  return sum + gapWidth2 + current.width;
7596
7654
  }, 0);
7597
- const gapWidth = index > 0 && item.gapBefore ? CONTENT_GAP : 0;
7655
+ const gapWidth = index > 0 ? item.gapBefore : 0;
7598
7656
  const nextContent = truncateExpandedContent(
7599
7657
  ctx,
7600
7658
  item.content,
@@ -8042,23 +8100,24 @@ function resolveScrollbarRole(x, y, scrollbar) {
8042
8100
 
8043
8101
  // src/services/scrollbar-service.ts
8044
8102
  function resolvePointerHitWithScrollbars(result, x, y, scrollbarLayout) {
8045
- if (result.area !== "empty") {
8046
- return result;
8047
- }
8048
8103
  const horizontalScrollbar = scrollbarLayout.horizontal;
8049
8104
  if (horizontalScrollbar && isPointInScrollbar(x, y, horizontalScrollbar)) {
8105
+ const scrollbarRole = resolveScrollbarRole(x, y, horizontalScrollbar);
8050
8106
  return {
8051
8107
  area: "horizontal-scrollbar",
8052
8108
  columnKey: "__horizontal_scrollbar__",
8053
- scrollbarRole: resolveScrollbarRole(x, y, horizontalScrollbar)
8109
+ scrollbarRole,
8110
+ cursor: scrollbarRole === "thumb" ? "grab" : "pointer"
8054
8111
  };
8055
8112
  }
8056
8113
  const verticalScrollbar = scrollbarLayout.vertical;
8057
8114
  if (verticalScrollbar && isPointInScrollbar(x, y, verticalScrollbar)) {
8115
+ const scrollbarRole = resolveScrollbarRole(x, y, verticalScrollbar);
8058
8116
  return {
8059
8117
  area: "vertical-scrollbar",
8060
8118
  columnKey: "__vertical_scrollbar__",
8061
- scrollbarRole: resolveScrollbarRole(x, y, verticalScrollbar)
8119
+ scrollbarRole,
8120
+ cursor: scrollbarRole === "thumb" ? "grab" : "pointer"
8062
8121
  };
8063
8122
  }
8064
8123
  return result;
@@ -11577,6 +11636,9 @@ function resolveVisibleRowIndexForDataRow(params) {
11577
11636
  if (rowIndex >= params.rowCount) {
11578
11637
  return null;
11579
11638
  }
11639
+ if (params.frozenRows.scroll.dataRowIndexAligned) {
11640
+ return rowIndex;
11641
+ }
11580
11642
  for (const section of [
11581
11643
  params.frozenRows.top,
11582
11644
  params.frozenRows.scroll,
@@ -11600,7 +11662,7 @@ function resolveScrollTopForRowIndex(params) {
11600
11662
  if (frozenRows.top.rowIndexMap?.includes(rowIndex) || frozenRows.bottom.rowIndexMap?.includes(rowIndex)) {
11601
11663
  return null;
11602
11664
  }
11603
- const scrollSectionIndex = frozenRows.scroll.rowIndexMap ? frozenRows.scroll.rowIndexMap.indexOf(rowIndex) : rowIndex;
11665
+ const scrollSectionIndex = frozenRows.scroll.dataRowIndexAligned ? rowIndex : frozenRows.scroll.rowIndexMap ? frozenRows.scroll.rowIndexMap.indexOf(rowIndex) : rowIndex;
11604
11666
  if (scrollSectionIndex < 0) {
11605
11667
  return null;
11606
11668
  }
@@ -12949,69 +13011,55 @@ function matchFilterValue(rawValue, filterValue, optionValue = serializeFilterOp
12949
13011
  }
12950
13012
  function isMeaningfulFilterValue(value) {
12951
13013
  if ((value.filterType ?? "value") === "condition") {
12952
- return isSingleConditionActive(
12953
- value.conditionOperator ?? "none",
12954
- value.conditionValue?.trim() ?? "",
12955
- value.conditionSecondValue?.trim() ?? ""
12956
- ) || isSingleConditionActive(
12957
- value.secondConditionOperator ?? "none",
12958
- value.secondConditionValue?.trim() ?? "",
12959
- value.secondConditionSecondValue?.trim() ?? ""
13014
+ return resolveFilterConditions(value).some(
13015
+ (condition) => isSingleConditionActive(
13016
+ condition.operator,
13017
+ condition.value,
13018
+ condition.secondValue
13019
+ )
12960
13020
  );
12961
13021
  }
12962
13022
  return value.keyword.trim().length > 0 || (value.selectedKeys?.filter(Boolean).length ?? 0) > 0;
12963
13023
  }
12964
13024
  function matchConditionFilterValue(rawValue, filterValue) {
12965
13025
  const sourceText = stringifyFilterValue(rawValue).toLowerCase();
12966
- const firstOperator = filterValue.conditionOperator ?? "none";
12967
- const firstValue = filterValue.conditionValue?.trim().toLowerCase() ?? "";
12968
- const firstSecondValue = filterValue.conditionSecondValue?.trim().toLowerCase() ?? "";
12969
- const secondOperator = filterValue.secondConditionOperator ?? "none";
12970
- const secondValue = filterValue.secondConditionValue?.trim().toLowerCase() ?? "";
12971
- const secondSecondValue = filterValue.secondConditionSecondValue?.trim().toLowerCase() ?? "";
12972
- const relation = filterValue.conditionRelation ?? "and";
12973
- const hasFirst = isSingleConditionActive(
12974
- firstOperator,
12975
- firstValue,
12976
- firstSecondValue
12977
- );
12978
- const hasSecond = isSingleConditionActive(
12979
- secondOperator,
12980
- secondValue,
12981
- secondSecondValue
13026
+ const conditions = resolveFilterConditions(filterValue).filter(
13027
+ (condition) => isSingleConditionActive(
13028
+ condition.operator,
13029
+ condition.value,
13030
+ condition.secondValue
13031
+ )
12982
13032
  );
12983
- if (!hasFirst && !hasSecond) {
13033
+ const relation = filterValue.conditionRelation ?? "and";
13034
+ if (conditions.length === 0) {
12984
13035
  return true;
12985
13036
  }
12986
- if (!hasFirst) {
12987
- return evaluateCondition(
12988
- sourceText,
12989
- secondOperator,
12990
- secondValue,
12991
- secondSecondValue
12992
- );
12993
- }
12994
- if (!hasSecond) {
12995
- return evaluateCondition(
12996
- sourceText,
12997
- firstOperator,
12998
- firstValue,
12999
- firstSecondValue
13000
- );
13001
- }
13002
- const primaryResult = evaluateCondition(
13003
- sourceText,
13004
- firstOperator,
13005
- firstValue,
13006
- firstSecondValue
13007
- );
13008
- const secondaryResult = evaluateCondition(
13037
+ const matches = (condition) => evaluateCondition(
13009
13038
  sourceText,
13010
- secondOperator,
13011
- secondValue,
13012
- secondSecondValue
13039
+ condition.operator,
13040
+ condition.value,
13041
+ condition.secondValue
13013
13042
  );
13014
- return relation === "or" ? primaryResult || secondaryResult : primaryResult && secondaryResult;
13043
+ return relation === "or" ? conditions.some(matches) : conditions.every(matches);
13044
+ }
13045
+ function resolveFilterConditions(filterValue) {
13046
+ const source = filterValue.conditions?.length ? filterValue.conditions : [
13047
+ {
13048
+ operator: filterValue.conditionOperator ?? "none",
13049
+ value: filterValue.conditionValue,
13050
+ secondValue: filterValue.conditionSecondValue
13051
+ },
13052
+ {
13053
+ operator: filterValue.secondConditionOperator ?? "none",
13054
+ value: filterValue.secondConditionValue,
13055
+ secondValue: filterValue.secondConditionSecondValue
13056
+ }
13057
+ ];
13058
+ return source.map((condition) => ({
13059
+ operator: condition.operator,
13060
+ value: condition.value?.trim().toLowerCase() ?? "",
13061
+ secondValue: condition.secondValue?.trim().toLowerCase() ?? ""
13062
+ }));
13015
13063
  }
13016
13064
  function isSingleConditionActive(operator, conditionValue, conditionSecondValue) {
13017
13065
  if (!operator || operator === "none") {
@@ -13140,7 +13188,10 @@ var FILTER_PANEL_TEXTS = {
13140
13188
  relationAndLabel: "\u5E76\u4E14",
13141
13189
  relationOrLabel: "\u6216\u8005",
13142
13190
  resetAction: "\u91CD\u7F6E",
13143
- applyAction: "\u5E94\u7528"
13191
+ applyAction: "\u5E94\u7528",
13192
+ conditionLabel: "\u6761\u4EF6",
13193
+ addConditionAction: "\u65B0\u589E\u6761\u4EF6",
13194
+ deleteConditionAction: "\u5220\u9664\u6761\u4EF6"
13144
13195
  };
13145
13196
  var ASYNC_FILTER_OPTION_BATCH_SIZE = 2e4;
13146
13197
  function sortRows(rows, sortState, leafColumns) {
@@ -13238,7 +13289,8 @@ function buildFilterPanelValue(currentValue) {
13238
13289
  conditionRelation: currentValue.conditionRelation,
13239
13290
  secondConditionOperator: currentValue.secondConditionOperator,
13240
13291
  secondConditionValue: currentValue.secondConditionValue,
13241
- secondConditionSecondValue: currentValue.secondConditionSecondValue
13292
+ secondConditionSecondValue: currentValue.secondConditionSecondValue,
13293
+ conditions: currentValue.conditions
13242
13294
  };
13243
13295
  }
13244
13296
  function resolveFilterModes(column) {
@@ -13363,7 +13415,12 @@ function buildFilterStateValue(value) {
13363
13415
  conditionRelation: value.conditionRelation,
13364
13416
  secondConditionOperator: value.secondConditionOperator,
13365
13417
  secondConditionValue: value.secondConditionValue,
13366
- secondConditionSecondValue: value.secondConditionSecondValue
13418
+ secondConditionSecondValue: value.secondConditionSecondValue,
13419
+ conditions: value.conditions?.map((condition) => ({
13420
+ operator: condition.operator,
13421
+ value: condition.value,
13422
+ secondValue: condition.secondValue
13423
+ }))
13367
13424
  };
13368
13425
  }
13369
13426
  function toQueryFilters(filters) {
@@ -13684,6 +13741,9 @@ function showHeaderContextMenu(params) {
13684
13741
  return true;
13685
13742
  }
13686
13743
  function resolveContextMenuDensity(rowHeight) {
13744
+ if (rowHeight === "auto") {
13745
+ return "auto";
13746
+ }
13687
13747
  if (rowHeight === 56) {
13688
13748
  return "comfortable";
13689
13749
  }
@@ -15123,6 +15183,9 @@ var ListTableEventController = class {
15123
15183
  event.clientY
15124
15184
  );
15125
15185
  const result = this.host.resolvePointerHit(position.x, position.y);
15186
+ this.host.canvasHost.setCursor(
15187
+ result.area === "resize-handle" ? "col-resize" : result.cursor ?? ""
15188
+ );
15126
15189
  const nextHover = {
15127
15190
  rowIndex: result.rowIndex ?? null,
15128
15191
  columnKey: result.columnKey ?? null,
@@ -15145,9 +15208,6 @@ var ListTableEventController = class {
15145
15208
  result,
15146
15209
  () => this.host.updateTooltip(result)
15147
15210
  );
15148
- this.host.canvasHost.setCursor(
15149
- result.area === "resize-handle" ? "col-resize" : result.cursor ?? ""
15150
- );
15151
15211
  this.host.scheduleRender(result);
15152
15212
  });
15153
15213
  __publicField(this, "handleMouseDown", (event) => {
@@ -15318,6 +15378,9 @@ var ListTableEventController = class {
15318
15378
  if (!viewport) {
15319
15379
  return;
15320
15380
  }
15381
+ this.host.canvasHost.setCursor(
15382
+ result.scrollbarRole === "thumb" ? "grabbing" : "pointer"
15383
+ );
15321
15384
  if (result.scrollbarRole === "decrease-button") {
15322
15385
  this.stepScrollbar(result.area, -1, viewport);
15323
15386
  this.startContinuousScroll(result.area, -1, viewport);
@@ -15408,6 +15471,7 @@ var ListTableEventController = class {
15408
15471
  columnKey: null,
15409
15472
  area: "empty"
15410
15473
  };
15474
+ this.host.canvasHost.setCursor("");
15411
15475
  this.host.render();
15412
15476
  });
15413
15477
  __publicField(this, "handleContextMenu", (event) => {
@@ -16553,6 +16617,7 @@ var ListTableEventController = class {
16553
16617
  this.host.setGroupingBarDropActive?.(false);
16554
16618
  this.stopContinuousScroll();
16555
16619
  this.host.tooltip.hide();
16620
+ this.host.canvasHost.setCursor("");
16556
16621
  if (options?.unbindWindowEvents !== false) {
16557
16622
  this.host.canvasHost.unbindWindowDragEvents();
16558
16623
  }
@@ -17460,6 +17525,13 @@ function resolveToggleHeaderColumnVisibilityAction(params) {
17460
17525
 
17461
17526
  // src/shared/theme/density.ts
17462
17527
  function resolveDensitySizes(density) {
17528
+ if (density === "auto") {
17529
+ return {
17530
+ rowHeight: "auto",
17531
+ headerRowHeight: void 0,
17532
+ summaryRowHeight: void 0
17533
+ };
17534
+ }
17463
17535
  if (density === "comfortable") {
17464
17536
  return {
17465
17537
  rowHeight: 56,
@@ -18136,7 +18208,7 @@ function buildStoredColumnConfig(columns, sortState, filterState, zoom, summaryR
18136
18208
  filters: filterState,
18137
18209
  ...typeof zoom === "number" && Number.isFinite(zoom) && zoom > 0 ? { zoom } : null,
18138
18210
  ...typeof summaryRowHeight === "number" && Number.isFinite(summaryRowHeight) && summaryRowHeight >= 0 ? { summaryRowHeight } : null,
18139
- ...density === 32 || density === 48 || density === 56 ? { density } : null
18211
+ ...density === 32 || density === 48 || density === 56 || density === "auto" ? { density } : null
18140
18212
  };
18141
18213
  }
18142
18214
 
@@ -18186,7 +18258,7 @@ async function loadListTableStoredConfig(params) {
18186
18258
  filterState: stored.filters ? stored.filters : null,
18187
18259
  zoom: typeof stored.zoom === "number" && Number.isFinite(stored.zoom) && stored.zoom > 0 ? stored.zoom : null,
18188
18260
  summaryRowHeight: typeof stored.summaryRowHeight === "number" && Number.isFinite(stored.summaryRowHeight) && stored.summaryRowHeight >= 0 ? stored.summaryRowHeight : null,
18189
- density: stored.density === 32 || stored.density === 48 || stored.density === 56 ? stored.density : null
18261
+ density: stored.density === 32 || stored.density === 48 || stored.density === 56 || stored.density === "auto" ? stored.density : null
18190
18262
  };
18191
18263
  }
18192
18264
 
@@ -18219,11 +18291,12 @@ var ListTablePersistenceController = class {
18219
18291
  }
18220
18292
  let currentOptions = this.options.getOptions();
18221
18293
  if (stored.density != null) {
18294
+ const densitySizes = resolveDensitySizes(
18295
+ stored.density === "auto" ? "auto" : stored.density === 32 ? "compact" : stored.density === 56 ? "comfortable" : "middle"
18296
+ );
18222
18297
  currentOptions = {
18223
18298
  ...currentOptions,
18224
- rowHeight: stored.density,
18225
- headerRowHeight: stored.density,
18226
- summaryRowHeight: stored.density
18299
+ ...densitySizes
18227
18300
  };
18228
18301
  }
18229
18302
  if (stored.summaryRowHeight != null) {
@@ -18528,7 +18601,6 @@ function getMaxDepth(columns) {
18528
18601
  }
18529
18602
 
18530
18603
  // src/domain/layout/compute-scrollbar-layout.ts
18531
- var DEFAULT_SCROLLBAR_THICKNESS = 10;
18532
18604
  var DEFAULT_HORIZONTAL_LEFT = 0;
18533
18605
  var DEFAULT_HORIZONTAL_RIGHT = 0;
18534
18606
  var DEFAULT_HORIZONTAL_BOTTOM = 0;
@@ -20103,8 +20175,11 @@ function buildListTableRenderSnapshot(params) {
20103
20175
  baseRowsOverride,
20104
20176
  displayRowsOverride
20105
20177
  } = params;
20106
- const scrollbarThickness = options.scrollbar?.visible === false ? 0 : Math.max(options.scrollbar?.thickness ?? 10, 6);
20107
- let width = hostWidth;
20178
+ const scrollbarThickness = options.scrollbar?.visible === false ? 0 : Math.max(
20179
+ options.scrollbar?.thickness ?? DEFAULT_SCROLLBAR_THICKNESS,
20180
+ 6
20181
+ );
20182
+ let width = Math.max(hostWidth - scrollbarThickness, 0);
20108
20183
  let height = hostHeight;
20109
20184
  const sourceNormalizedColumns = normalizeColumns(
20110
20185
  getResolvedColumns(options, selectedRowKeys)
@@ -20325,6 +20400,7 @@ function buildListTableRenderSnapshot(params) {
20325
20400
  let bodyState = resolveCurrentBodyState();
20326
20401
  if (plainRowWindow) {
20327
20402
  bodyState.frozenRows.scroll.windowed = true;
20403
+ bodyState.frozenRows.scroll.dataRowIndexAligned = true;
20328
20404
  bodyState.frozenRows.scroll.rowIndexMap = plainRowWindow.rowIndexMap;
20329
20405
  bodyState.frozenRows.scroll.rowOffsetMap = plainRowWindow.rowOffsetMap;
20330
20406
  bodyState.bodyLayout = resolveBodyLayout({
@@ -20348,6 +20424,7 @@ function buildListTableRenderSnapshot(params) {
20348
20424
  bodyState = resolveCurrentBodyState();
20349
20425
  if (plainRowWindow) {
20350
20426
  bodyState.frozenRows.scroll.windowed = true;
20427
+ bodyState.frozenRows.scroll.dataRowIndexAligned = true;
20351
20428
  bodyState.frozenRows.scroll.rowIndexMap = plainRowWindow.rowIndexMap;
20352
20429
  bodyState.frozenRows.scroll.rowOffsetMap = plainRowWindow.rowOffsetMap;
20353
20430
  bodyState.bodyLayout = resolveBodyLayout({
@@ -20377,53 +20454,6 @@ function buildListTableRenderSnapshot(params) {
20377
20454
  fixedWidthRight: columnMetrics.fixedWidthRight,
20378
20455
  scroll
20379
20456
  });
20380
- for (let index = 0; index < 2 && scrollbarThickness > 0; index += 1) {
20381
- const nextWidth = Math.max(
20382
- hostWidth - (viewportResult.viewport.maxScrollTop > 0 ? scrollbarThickness : 0),
20383
- 0
20384
- );
20385
- const nextHeight = Math.max(
20386
- hostHeight - (viewportResult.viewport.maxScrollLeft > 0 ? scrollbarThickness : 0),
20387
- 0
20388
- );
20389
- if (nextWidth === width && nextHeight === height) {
20390
- break;
20391
- }
20392
- width = nextWidth;
20393
- height = nextHeight;
20394
- bodyState = resolveCurrentBodyState();
20395
- if (plainRowWindow) {
20396
- bodyState.frozenRows.scroll.windowed = true;
20397
- bodyState.frozenRows.scroll.rowIndexMap = plainRowWindow.rowIndexMap;
20398
- bodyState.frozenRows.scroll.rowOffsetMap = plainRowWindow.rowOffsetMap;
20399
- bodyState.bodyLayout = resolveBodyLayout({
20400
- height,
20401
- headerHeight,
20402
- summaryRowHeight,
20403
- hasSummary,
20404
- rowHeight,
20405
- totalBodyHeight: plainRowWindow.totalBodyHeight,
20406
- topFrozenRowCount: 0,
20407
- bottomFrozenRowCount: 0,
20408
- scrollRowCount: plainRowWindow.totalRowCount
20409
- });
20410
- }
20411
- columnMetrics = resolveColumnMetrics({
20412
- columns: leafColumns,
20413
- tableWidth: width
20414
- });
20415
- viewportResult = computeViewport({
20416
- width,
20417
- height,
20418
- headerHeight,
20419
- bodyHeight: bodyState.bodyLayout.scrollBodyHeight,
20420
- totalWidth: columnMetrics.totalWidth,
20421
- totalBodyHeight: bodyState.bodyLayout.totalBodyHeight,
20422
- fixedWidthLeft: columnMetrics.fixedWidthLeft,
20423
- fixedWidthRight: columnMetrics.fixedWidthRight,
20424
- scroll
20425
- });
20426
- }
20427
20457
  scrollPageSize = resolveScrollPageSize({
20428
20458
  options,
20429
20459
  pageSize: query.pagination.pageSize,
@@ -20914,7 +20944,7 @@ function resolveAutoRowHeightMeasureRows(rows, sampleCount = AUTO_ROW_HEIGHT_SAM
20914
20944
  return rows.slice(0, sampleCount);
20915
20945
  }
20916
20946
  function resolveListTableHeaderRowHeight(params) {
20917
- return params.headerRowHeight ?? (params.rowHeight === "auto" ? DEFAULT_ROW_HEIGHT : params.resolvedRowHeight);
20947
+ return params.headerRowHeight ?? params.resolvedRowHeight;
20918
20948
  }
20919
20949
  function buildListTableDebugSnapshot(params) {
20920
20950
  const {
@@ -21076,13 +21106,28 @@ function resolveListTableRenderHostSize(params) {
21076
21106
  }
21077
21107
 
21078
21108
  // src/rendering/primitives/draw-scrollbars.ts
21079
- function drawScrollbars(ctx, layout, descriptors, borderColor, opacity = 1, interactive = true) {
21109
+ function drawScrollbars(ctx, layout, descriptors, borderColor, opacity = 1, interactive = true, verticalFrame) {
21080
21110
  const alpha = Number.isFinite(opacity) ? Math.min(Math.max(opacity, 0), 1) : 1;
21081
21111
  if (alpha <= 1e-3) {
21082
21112
  return;
21083
21113
  }
21084
21114
  ctx.save();
21085
21115
  ctx.globalAlpha = alpha;
21116
+ if (layout.horizontal && verticalFrame) {
21117
+ drawHorizontalScrollbarMask(
21118
+ ctx,
21119
+ layout.horizontal,
21120
+ verticalFrame.bodyBackgroundColor
21121
+ );
21122
+ }
21123
+ if (layout.vertical && verticalFrame) {
21124
+ drawVerticalScrollbarFrame(
21125
+ ctx,
21126
+ layout.vertical,
21127
+ verticalFrame,
21128
+ borderColor
21129
+ );
21130
+ }
21086
21131
  if (layout.horizontal) {
21087
21132
  drawAxisScrollbar(
21088
21133
  ctx,
@@ -21103,6 +21148,45 @@ function drawScrollbars(ctx, layout, descriptors, borderColor, opacity = 1, inte
21103
21148
  interactive
21104
21149
  );
21105
21150
  }
21151
+ if (layout.horizontal) {
21152
+ drawHorizontalScrollbarTopBorder(
21153
+ ctx,
21154
+ layout.horizontal,
21155
+ layout.vertical,
21156
+ borderColor
21157
+ );
21158
+ }
21159
+ ctx.restore();
21160
+ }
21161
+ function drawHorizontalScrollbarMask(ctx, layout, backgroundColor) {
21162
+ const left = layout.decreaseButton.x;
21163
+ const right = layout.increaseButton.x + layout.increaseButton.width;
21164
+ const top = layout.decreaseButton.y;
21165
+ const height = layout.decreaseButton.height;
21166
+ if (right <= left || height <= 0) {
21167
+ return;
21168
+ }
21169
+ ctx.save();
21170
+ ctx.fillStyle = backgroundColor;
21171
+ ctx.fillRect(left, top, right - left, height);
21172
+ ctx.restore();
21173
+ }
21174
+ function drawHorizontalScrollbarTopBorder(ctx, horizontal, vertical, borderColor) {
21175
+ const left = Math.round(horizontal.decreaseButton.x) + 0.5;
21176
+ const horizontalRight = horizontal.increaseButton.x + horizontal.increaseButton.width;
21177
+ const verticalRight = vertical ? vertical.decreaseButton.x + vertical.decreaseButton.width : horizontalRight;
21178
+ const right = Math.round(Math.max(horizontalRight, verticalRight)) - 0.5;
21179
+ const top = Math.round(horizontal.decreaseButton.y) + 0.5;
21180
+ if (right <= left) {
21181
+ return;
21182
+ }
21183
+ ctx.save();
21184
+ ctx.strokeStyle = borderColor;
21185
+ ctx.lineWidth = 1;
21186
+ ctx.beginPath();
21187
+ ctx.moveTo(left, top);
21188
+ ctx.lineTo(right, top);
21189
+ ctx.stroke();
21106
21190
  ctx.restore();
21107
21191
  }
21108
21192
  function drawAxisScrollbar(ctx, layout, axis, descriptors, borderColor, interactive) {
@@ -21133,19 +21217,69 @@ function drawAxisScrollbar(ctx, layout, axis, descriptors, borderColor, interact
21133
21217
  scrollbarRole: "increase-button"
21134
21218
  });
21135
21219
  }
21136
- drawTrack(ctx, layout.track, borderColor);
21137
21220
  drawButton(ctx, layout.decreaseButton, axis, "decrease");
21138
21221
  drawButton(ctx, layout.increaseButton, axis, "increase");
21139
21222
  drawThumb(ctx, layout.thumb);
21223
+ drawTrackBorder(ctx, layout.track, axis, borderColor);
21224
+ }
21225
+ function drawTrackBorder(ctx, rect, axis, borderColor) {
21226
+ const left = Math.round(rect.x) + 0.5;
21227
+ const right = Math.round(rect.x + rect.width) - 0.5;
21228
+ const top = Math.round(rect.y) + 0.5;
21229
+ const bottom = Math.round(rect.y + rect.height) - 0.5;
21230
+ if (right <= left || bottom <= top) {
21231
+ return;
21232
+ }
21233
+ ctx.save();
21234
+ ctx.strokeStyle = borderColor;
21235
+ ctx.lineWidth = 1;
21236
+ ctx.beginPath();
21237
+ if (axis === "horizontal") {
21238
+ ctx.moveTo(left, top);
21239
+ ctx.lineTo(right, top);
21240
+ } else {
21241
+ ctx.moveTo(left, top);
21242
+ ctx.lineTo(left, bottom);
21243
+ }
21244
+ ctx.stroke();
21245
+ ctx.restore();
21140
21246
  }
21141
- function drawTrack(ctx, rect, borderColor) {
21247
+ function drawVerticalScrollbarFrame(ctx, layout, frame, borderColor) {
21248
+ const left = Math.round(layout.decreaseButton.x) + 0.5;
21249
+ const right = Math.round(layout.decreaseButton.x + layout.decreaseButton.width) - 0.5;
21250
+ const top = Math.round(frame.top) + 0.5;
21251
+ const bottom = Math.round(frame.top + frame.height) - 0.5;
21252
+ const headerBottom = Math.round(frame.headerBottom) + 0.5;
21253
+ if (right <= left || bottom <= top) {
21254
+ return;
21255
+ }
21142
21256
  ctx.save();
21143
- ctx.fillStyle = "rgba(148, 163, 184, 0.16)";
21257
+ ctx.fillStyle = frame.headerBackgroundColor;
21258
+ ctx.fillRect(
21259
+ layout.decreaseButton.x,
21260
+ frame.top,
21261
+ layout.decreaseButton.width,
21262
+ Math.max(frame.headerBottom - frame.top, 0)
21263
+ );
21264
+ ctx.fillStyle = frame.bodyBackgroundColor;
21265
+ ctx.fillRect(
21266
+ layout.decreaseButton.x,
21267
+ frame.headerBottom,
21268
+ layout.decreaseButton.width,
21269
+ Math.max(frame.top + frame.height - frame.headerBottom, 0)
21270
+ );
21144
21271
  ctx.strokeStyle = borderColor;
21145
21272
  ctx.lineWidth = 1;
21146
- roundRect(ctx, rect.x, rect.y, rect.width, rect.height, rect.height / 2);
21147
- ctx.fill();
21273
+ ctx.beginPath();
21274
+ ctx.moveTo(left, top);
21275
+ ctx.lineTo(left, bottom);
21148
21276
  ctx.stroke();
21277
+ if (headerBottom > top && headerBottom < bottom) {
21278
+ ctx.beginPath();
21279
+ ctx.moveTo(left, headerBottom);
21280
+ ctx.lineTo(right, headerBottom);
21281
+ ctx.stroke();
21282
+ }
21149
21283
  ctx.restore();
21150
21284
  }
21151
21285
  function drawThumb(ctx, rect) {
@@ -21157,34 +21291,25 @@ function drawThumb(ctx, rect) {
21157
21291
  }
21158
21292
  function drawButton(ctx, rect, axis, direction) {
21159
21293
  ctx.save();
21160
- ctx.fillStyle = "rgba(226, 232, 240, 0.92)";
21161
- ctx.strokeStyle = "rgba(148, 163, 184, 0.65)";
21162
- ctx.lineWidth = 1;
21163
- roundRect(ctx, rect.x, rect.y, rect.width, rect.height, rect.height / 2);
21164
- ctx.fill();
21165
- ctx.stroke();
21166
21294
  ctx.fillStyle = "rgba(71, 85, 105, 0.88)";
21167
21295
  ctx.beginPath();
21296
+ const centerX = rect.x + rect.width / 2;
21297
+ const centerY = rect.y + rect.height / 2;
21298
+ const iconSize = Math.min(rect.width, rect.height) * 0.64;
21299
+ const directionOffset = iconSize * 0.4;
21300
+ const crossAxisOffset = iconSize / 2;
21168
21301
  if (axis === "horizontal") {
21169
- const centerY = rect.y + rect.height / 2;
21170
- const iconWidth = rect.width * 0.28;
21171
- const iconHeight = rect.height * 0.22;
21172
- const centerX = rect.x + rect.width / 2;
21173
- const tipX = direction === "decrease" ? centerX - iconWidth / 2 : centerX + iconWidth / 2;
21174
- const tailX = direction === "decrease" ? centerX + iconWidth / 2 : centerX - iconWidth / 2;
21302
+ const tipX = centerX + (direction === "decrease" ? -1 : 1) * directionOffset;
21303
+ const tailX = centerX + (direction === "decrease" ? 1 : -1) * directionOffset;
21175
21304
  ctx.moveTo(tipX, centerY);
21176
- ctx.lineTo(tailX, centerY - iconHeight);
21177
- ctx.lineTo(tailX, centerY + iconHeight);
21305
+ ctx.lineTo(tailX, centerY - crossAxisOffset);
21306
+ ctx.lineTo(tailX, centerY + crossAxisOffset);
21178
21307
  } else {
21179
- const centerX = rect.x + rect.width / 2;
21180
- const iconWidth = rect.width * 0.22;
21181
- const iconHeight = rect.height * 0.28;
21182
- const centerY = rect.y + rect.height / 2;
21183
- const tipY = direction === "decrease" ? centerY - iconHeight / 2 : centerY + iconHeight / 2;
21184
- const tailY = direction === "decrease" ? centerY + iconHeight / 2 : centerY - iconHeight / 2;
21308
+ const tipY = centerY + (direction === "decrease" ? -1 : 1) * directionOffset;
21309
+ const tailY = centerY + (direction === "decrease" ? 1 : -1) * directionOffset;
21185
21310
  ctx.moveTo(centerX, tipY);
21186
- ctx.lineTo(centerX - iconWidth, tailY);
21187
- ctx.lineTo(centerX + iconWidth, tailY);
21311
+ ctx.lineTo(centerX - crossAxisOffset, tailY);
21312
+ ctx.lineTo(centerX + crossAxisOffset, tailY);
21188
21313
  }
21189
21314
  ctx.closePath();
21190
21315
  ctx.fill();
@@ -23112,7 +23237,8 @@ function drawHeaderCell(params, cell, clipRect) {
23112
23237
  descriptors.push({
23113
23238
  kind: "header",
23114
23239
  rect,
23115
- columnKey: cell.node.key
23240
+ columnKey: cell.node.key,
23241
+ fixed: cell.node.fixed
23116
23242
  });
23117
23243
  if (params.rowSelection.type === "checkbox") {
23118
23244
  drawHeaderSelectionControl(params, rect);
@@ -23120,7 +23246,8 @@ function drawHeaderCell(params, cell, clipRect) {
23120
23246
  kind: "header-selection",
23121
23247
  rect: getHeaderSelectionRect(rect),
23122
23248
  columnKey: cell.node.key,
23123
- controlType: params.rowSelection.type
23249
+ controlType: params.rowSelection.type,
23250
+ fixed: cell.node.fixed
23124
23251
  });
23125
23252
  }
23126
23253
  ctx.restore();
@@ -23130,7 +23257,8 @@ function drawHeaderCell(params, cell, clipRect) {
23130
23257
  descriptors.push({
23131
23258
  kind: "header",
23132
23259
  rect,
23133
- columnKey: cell.node.key
23260
+ columnKey: cell.node.key,
23261
+ fixed: cell.node.fixed
23134
23262
  });
23135
23263
  ctx.restore();
23136
23264
  return;
@@ -23179,12 +23307,25 @@ function drawHeaderCell(params, cell, clipRect) {
23179
23307
  textLayout,
23180
23308
  titleContent,
23181
23309
  ctx
23182
- )
23310
+ ),
23311
+ fixed: cell.node.fixed
23183
23312
  });
23184
23313
  if (cell.node.children.length === 0) {
23185
- drawCollapsedColumnMarkers(params, rect, cell.node.key, collapseMarkerSet);
23186
- drawHeaderActions(params, rect, cell.node.key, visibleState);
23187
- drawResizeHandles(params, rect, cell.node.key);
23314
+ drawCollapsedColumnMarkers(
23315
+ params,
23316
+ rect,
23317
+ cell.node.key,
23318
+ collapseMarkerSet,
23319
+ cell.node.fixed
23320
+ );
23321
+ drawHeaderActions(
23322
+ params,
23323
+ rect,
23324
+ cell.node.key,
23325
+ visibleState,
23326
+ cell.node.fixed
23327
+ );
23328
+ drawResizeHandles(params, rect, cell.node.key, cell.node.fixed);
23188
23329
  }
23189
23330
  ctx.restore();
23190
23331
  }
@@ -23222,7 +23363,7 @@ function measureHeaderContentWidth(ctx, contents) {
23222
23363
  0
23223
23364
  ) + Math.max(contents.length - 1, 0) * gap;
23224
23365
  }
23225
- function drawHeaderActions(params, rect, columnKey, visibilityState) {
23366
+ function drawHeaderActions(params, rect, columnKey, visibilityState, fixed) {
23226
23367
  if (!visibilityState.visible) {
23227
23368
  return;
23228
23369
  }
@@ -23275,7 +23416,8 @@ function drawHeaderActions(params, rect, columnKey, visibilityState) {
23275
23416
  rect: actionRect,
23276
23417
  columnKey,
23277
23418
  actionType,
23278
- visibilityState
23419
+ visibilityState,
23420
+ fixed
23279
23421
  });
23280
23422
  });
23281
23423
  }
@@ -23297,15 +23439,15 @@ function resolveCollapsedColumnMarkerSet(markers, columnKey) {
23297
23439
  hasRightMarker: !!right
23298
23440
  };
23299
23441
  }
23300
- function drawCollapsedColumnMarkers(params, rect, columnKey, markerSet) {
23442
+ function drawCollapsedColumnMarkers(params, rect, columnKey, markerSet, fixed) {
23301
23443
  if (markerSet.left) {
23302
- drawCollapsedColumnMarker(params, rect, columnKey, markerSet.left);
23444
+ drawCollapsedColumnMarker(params, rect, columnKey, markerSet.left, fixed);
23303
23445
  }
23304
23446
  if (markerSet.right) {
23305
- drawCollapsedColumnMarker(params, rect, columnKey, markerSet.right);
23447
+ drawCollapsedColumnMarker(params, rect, columnKey, markerSet.right, fixed);
23306
23448
  }
23307
23449
  }
23308
- function drawCollapsedColumnMarker(params, rect, columnKey, marker) {
23450
+ function drawCollapsedColumnMarker(params, rect, columnKey, marker, fixed) {
23309
23451
  const triggerRect = {
23310
23452
  x: marker.align === "left" ? rect.x + GRID_LINE_OFFSET2 - COLLAPSE_TRIGGER_WIDTH / 2 : rect.x + rect.width + GRID_LINE_OFFSET2 - COLLAPSE_TRIGGER_WIDTH / 2,
23311
23453
  y: rect.y + (rect.height - COLLAPSE_TRIGGER_HEIGHT) / 2,
@@ -23319,7 +23461,8 @@ function drawCollapsedColumnMarker(params, rect, columnKey, marker) {
23319
23461
  rect: triggerRect,
23320
23462
  columnKey,
23321
23463
  cursor: "pointer",
23322
- contentKey: `${marker.rangeStart}:${marker.rangeEnd}`
23464
+ contentKey: `${marker.rangeStart}:${marker.rangeEnd}`,
23465
+ fixed
23323
23466
  });
23324
23467
  }
23325
23468
  function isHeaderCellSelected(params, columnKey, rect) {
@@ -23341,13 +23484,14 @@ function isHeaderCellInRange(rangeHighlight, cell) {
23341
23484
  function isSameRect(left, right) {
23342
23485
  return Math.abs(left.x - right.x) <= 1 && Math.abs(left.y - right.y) <= 1 && Math.abs(left.width - right.width) <= 1 && Math.abs(left.height - right.height) <= 1;
23343
23486
  }
23344
- function drawResizeHandles(params, rect, columnKey) {
23487
+ function drawResizeHandles(params, rect, columnKey, fixed) {
23345
23488
  if (params.isResizable(columnKey)) {
23346
23489
  params.descriptors.push({
23347
23490
  kind: "resize-handle",
23348
23491
  rect: getResizeHandleRect(params, rect, "right"),
23349
23492
  columnKey,
23350
- resizeEdge: "right"
23493
+ resizeEdge: "right",
23494
+ fixed
23351
23495
  });
23352
23496
  }
23353
23497
  const leafIndex = params.leafColumnKeys?.indexOf(columnKey) ?? -1;
@@ -23357,7 +23501,8 @@ function drawResizeHandles(params, rect, columnKey) {
23357
23501
  kind: "resize-handle",
23358
23502
  rect: getResizeHandleRect(params, rect, "left"),
23359
23503
  columnKey: previousColumnKey,
23360
- resizeEdge: "left"
23504
+ resizeEdge: "left",
23505
+ fixed
23361
23506
  });
23362
23507
  }
23363
23508
  }
@@ -23751,15 +23896,18 @@ function resolveActiveCellOverlayLayout(params) {
23751
23896
  const descriptor = selection.rowIndex != null && selection.columnKey != null ? params.descriptors.find(
23752
23897
  (item) => item.kind === "body" && item.rowIndex === selection.rowIndex && item.columnKey === selection.columnKey
23753
23898
  ) : void 0;
23754
- const rangeRects = resolveRangeHighlightLayouts({
23899
+ const rangeLayout = resolveRangeHighlightLayouts({
23755
23900
  descriptors: params.descriptors,
23756
23901
  rangeHighlight: params.rangeHighlight,
23757
23902
  highlightMode: params.highlightMode,
23758
23903
  columnKeys: params.columnKeys ?? [],
23759
23904
  allowColumnRange: selection.rowIndex == null,
23760
23905
  allowRowRange: selection.columnKey === ROW_SELECTOR_COLUMN_KEY,
23761
- resolveClipRect: (item) => resolveActiveCellSectionClipRect(item, params)
23906
+ resolveClipRect: (item) => resolveActiveCellSectionClipRect(item, params),
23907
+ width: params.width,
23908
+ height: params.height
23762
23909
  });
23910
+ const rangeRects = rangeLayout.rects;
23763
23911
  if (!descriptor && rangeRects.length === 0) {
23764
23912
  return null;
23765
23913
  }
@@ -23770,6 +23918,7 @@ function resolveActiveCellOverlayLayout(params) {
23770
23918
  return {
23771
23919
  rect: descriptor?.rect ?? { x: 0, y: 0, width: 0, height: 0 },
23772
23920
  clipRect,
23921
+ rangeSegments: rangeLayout.segments,
23773
23922
  rangeRects
23774
23923
  };
23775
23924
  }
@@ -23778,14 +23927,44 @@ function drawActiveCellOverlay(params) {
23778
23927
  return;
23779
23928
  }
23780
23929
  const { ctx, layout } = params;
23781
- layout.rangeRects.forEach(({ rect, clipRect, omitLeft, omitRight }) => {
23782
- ctx.save();
23783
- ctx.beginPath();
23784
- ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
23785
- ctx.clip();
23786
- drawRangeHighlightBorder(ctx, rect, { omitLeft, omitRight });
23787
- ctx.restore();
23788
- });
23930
+ if (layout.rangeSegments?.length) {
23931
+ layout.rangeSegments.forEach((segment) => {
23932
+ ctx.save();
23933
+ ctx.beginPath();
23934
+ ctx.rect(
23935
+ segment.clipRect.x,
23936
+ segment.clipRect.y,
23937
+ segment.clipRect.width,
23938
+ segment.clipRect.height
23939
+ );
23940
+ ctx.clip();
23941
+ ctx.strokeStyle = "#1677ff";
23942
+ ctx.lineWidth = 1;
23943
+ ctx.beginPath();
23944
+ ctx.moveTo(segment.startX, segment.startY);
23945
+ if (segment.controlX != null && segment.controlY != null) {
23946
+ ctx.quadraticCurveTo(
23947
+ segment.controlX,
23948
+ segment.controlY,
23949
+ segment.endX,
23950
+ segment.endY
23951
+ );
23952
+ } else {
23953
+ ctx.lineTo(segment.endX, segment.endY);
23954
+ }
23955
+ ctx.stroke();
23956
+ ctx.restore();
23957
+ });
23958
+ } else {
23959
+ layout.rangeRects.forEach(({ rect, clipRect, omitLeft, omitRight }) => {
23960
+ ctx.save();
23961
+ ctx.beginPath();
23962
+ ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
23963
+ ctx.clip();
23964
+ drawRangeHighlightBorder(ctx, rect, { omitLeft, omitRight });
23965
+ ctx.restore();
23966
+ });
23967
+ }
23789
23968
  if (layout.rangeRects.length === 0 && layout.rect.width > 0 && layout.rect.height > 0) {
23790
23969
  ctx.save();
23791
23970
  ctx.beginPath();
@@ -23806,17 +23985,19 @@ function resolveRangeHighlightLayouts(params) {
23806
23985
  const cellRange = params.rangeHighlight?.selectedCellRange;
23807
23986
  const rowSelectorRange = rowRange && params.allowRowRange;
23808
23987
  if (!cellRange && !rowSelectorRange && (!columnRange || !params.allowColumnRange)) {
23809
- return [];
23988
+ return { rects: [], segments: [] };
23810
23989
  }
23811
23990
  const bodyDescriptors = params.descriptors.filter(
23812
23991
  (item) => item.kind === "body" && item.columnKey != null && item.rowIndex != null
23813
23992
  );
23814
23993
  const selected = bodyDescriptors.filter((item) => {
23815
- const rowSelected = rowRange != null && item.rowIndex >= rowRange.start && item.rowIndex <= rowRange.end;
23994
+ const itemRowStart = item.rowIndex;
23995
+ const itemRowEnd = itemRowStart + Math.max(item.rowSpan ?? 1, 1) - 1;
23996
+ const rowSelected = rowRange != null && itemRowEnd >= rowRange.start && itemRowStart <= rowRange.end;
23816
23997
  const columnIndex = params.columnKeys.indexOf(item.columnKey);
23817
23998
  const columnSelected = columnRange != null && columnIndex >= columnRange.start && columnIndex <= columnRange.end;
23818
23999
  if (cellRange) {
23819
- return item.rowIndex >= cellRange.startRowIndex && item.rowIndex <= cellRange.endRowIndex && columnIndex >= cellRange.startColumnIndex && columnIndex <= cellRange.endColumnIndex;
24000
+ return itemRowEnd >= cellRange.startRowIndex && itemRowStart <= cellRange.endRowIndex && columnIndex >= cellRange.startColumnIndex && columnIndex <= cellRange.endColumnIndex;
23820
24001
  }
23821
24002
  if (rowSelectorRange) {
23822
24003
  return rowSelected;
@@ -23852,7 +24033,7 @@ function resolveRangeHighlightLayouts(params) {
23852
24033
  layer.push(range);
23853
24034
  groupedByLayer.set(key, layer);
23854
24035
  });
23855
- return ranges.map((range) => {
24036
+ const rects = ranges.map((range) => {
23856
24037
  const layer = groupedByLayer.get(`${range.rect.y}:${range.rect.height}`) ?? [];
23857
24038
  const minX = Math.min(...layer.map((item) => item.rect.x));
23858
24039
  const maxX = Math.max(
@@ -23864,6 +24045,172 @@ function resolveRangeHighlightLayouts(params) {
23864
24045
  omitRight: range.rect.x + range.rect.width < maxX
23865
24046
  };
23866
24047
  });
24048
+ return {
24049
+ rects,
24050
+ segments: roundRangeBorderAtTableBottom(
24051
+ resolveRangeBorderSegments(selected, params.resolveClipRect),
24052
+ params.width,
24053
+ params.height
24054
+ )
24055
+ };
24056
+ }
24057
+ function roundRangeBorderAtTableBottom(segments, width, height) {
24058
+ const inset = 0.5;
24059
+ const left = inset;
24060
+ const right = width - inset;
24061
+ const bottom = height - inset;
24062
+ const radius = Math.max(
24063
+ TABLE_CONTENT_BORDER_RADIUS - TABLE_CONTENT_BORDER_SIZE / 2,
24064
+ 0
24065
+ );
24066
+ if (radius <= 0) return segments;
24067
+ const rounded = segments.map((segment) => ({ ...segment }));
24068
+ const curves = [];
24069
+ const bottomSegments = rounded.filter(
24070
+ (segment) => nearlyEqual(segment.startY, bottom) && nearlyEqual(segment.endY, bottom)
24071
+ );
24072
+ const leftBottom = bottomSegments.find(
24073
+ (segment) => nearlyEqual(segment.startX, left)
24074
+ );
24075
+ const leftSide = rounded.find(
24076
+ (segment) => nearlyEqual(segment.startX, left) && nearlyEqual(segment.endX, left) && nearlyEqual(segment.endY, bottom)
24077
+ );
24078
+ if (leftBottom && leftSide) {
24079
+ leftBottom.startX = Math.min(left + radius, leftBottom.endX);
24080
+ leftSide.endY = Math.max(bottom - radius, leftSide.startY);
24081
+ curves.push({
24082
+ startX: leftSide.endX,
24083
+ startY: leftSide.endY,
24084
+ controlX: left,
24085
+ controlY: bottom,
24086
+ endX: leftBottom.startX,
24087
+ endY: leftBottom.startY,
24088
+ clipRect: leftSide.clipRect
24089
+ });
24090
+ }
24091
+ const rightBottom = bottomSegments.find(
24092
+ (segment) => nearlyEqual(segment.endX, right)
24093
+ );
24094
+ const rightSide = rounded.find(
24095
+ (segment) => nearlyEqual(segment.startX, right) && nearlyEqual(segment.endX, right) && nearlyEqual(segment.endY, bottom)
24096
+ );
24097
+ if (rightBottom && rightSide) {
24098
+ rightBottom.endX = Math.max(right - radius, rightBottom.startX);
24099
+ rightSide.endY = Math.max(bottom - radius, rightSide.startY);
24100
+ curves.push({
24101
+ startX: rightBottom.endX,
24102
+ startY: rightBottom.endY,
24103
+ controlX: right,
24104
+ controlY: bottom,
24105
+ endX: rightSide.endX,
24106
+ endY: rightSide.endY,
24107
+ clipRect: rightSide.clipRect
24108
+ });
24109
+ }
24110
+ return [...rounded, ...curves];
24111
+ }
24112
+ function nearlyEqual(left, right) {
24113
+ return Math.abs(left - right) < 1e-3;
24114
+ }
24115
+ function resolveRangeBorderSegments(descriptors, resolveClipRect) {
24116
+ const byLeft = groupDescriptorsByCoordinate(
24117
+ descriptors,
24118
+ (descriptor) => descriptor.rect.x
24119
+ );
24120
+ const byRight = groupDescriptorsByCoordinate(
24121
+ descriptors,
24122
+ (descriptor) => descriptor.rect.x + descriptor.rect.width
24123
+ );
24124
+ const byTop = groupDescriptorsByCoordinate(
24125
+ descriptors,
24126
+ (descriptor) => descriptor.rect.y
24127
+ );
24128
+ const byBottom = groupDescriptorsByCoordinate(
24129
+ descriptors,
24130
+ (descriptor) => descriptor.rect.y + descriptor.rect.height
24131
+ );
24132
+ return descriptors.flatMap((descriptor) => {
24133
+ const { rect } = descriptor;
24134
+ const left = rect.x;
24135
+ const right = rect.x + rect.width;
24136
+ const top = rect.y;
24137
+ const bottom = rect.y + rect.height;
24138
+ const clipRect = resolveClipRect(descriptor);
24139
+ const horizontal = (y, side) => {
24140
+ const adjacent = (side === "top" ? byBottom : byTop).get(
24141
+ coordinateKey(side === "top" ? top : bottom)
24142
+ ) ?? [];
24143
+ return subtractCoveredIntervals(
24144
+ left,
24145
+ right,
24146
+ adjacent.flatMap((other) => {
24147
+ if (other === descriptor) return [];
24148
+ return [[other.rect.x, other.rect.x + other.rect.width]];
24149
+ })
24150
+ ).map(([start, end]) => ({
24151
+ startX: start + (Math.abs(start - left) < 1e-3 ? 0.5 : 0),
24152
+ startY: y,
24153
+ endX: end - (Math.abs(end - right) < 1e-3 ? 0.5 : 0),
24154
+ endY: y,
24155
+ clipRect
24156
+ }));
24157
+ };
24158
+ const vertical = (x, side) => {
24159
+ const adjacent = (side === "left" ? byRight : byLeft).get(
24160
+ coordinateKey(side === "left" ? left : right)
24161
+ ) ?? [];
24162
+ return subtractCoveredIntervals(
24163
+ top,
24164
+ bottom,
24165
+ adjacent.flatMap((other) => {
24166
+ if (other === descriptor) return [];
24167
+ return [[other.rect.y, other.rect.y + other.rect.height]];
24168
+ })
24169
+ ).map(([start, end]) => ({
24170
+ startX: x,
24171
+ startY: start + (Math.abs(start - top) < 1e-3 ? 0.5 : 0),
24172
+ endX: x,
24173
+ endY: end - (Math.abs(end - bottom) < 1e-3 ? 0.5 : 0),
24174
+ clipRect
24175
+ }));
24176
+ };
24177
+ return [
24178
+ ...horizontal(top + 0.5, "top"),
24179
+ ...horizontal(bottom - 0.5, "bottom"),
24180
+ ...vertical(left + 0.5, "left"),
24181
+ ...vertical(right - 0.5, "right")
24182
+ ];
24183
+ });
24184
+ }
24185
+ function groupDescriptorsByCoordinate(descriptors, getCoordinate) {
24186
+ const groups = /* @__PURE__ */ new Map();
24187
+ descriptors.forEach((descriptor) => {
24188
+ const key = coordinateKey(getCoordinate(descriptor));
24189
+ const group = groups.get(key) ?? [];
24190
+ group.push(descriptor);
24191
+ groups.set(key, group);
24192
+ });
24193
+ return groups;
24194
+ }
24195
+ function coordinateKey(value) {
24196
+ return String(Math.round(value * 1e3) / 1e3);
24197
+ }
24198
+ function subtractCoveredIntervals(start, end, coveredIntervals) {
24199
+ let visible = [[start, end]];
24200
+ coveredIntervals.forEach(([coveredStart, coveredEnd]) => {
24201
+ visible = visible.flatMap(([currentStart, currentEnd]) => {
24202
+ const overlapStart = Math.max(currentStart, coveredStart);
24203
+ const overlapEnd = Math.min(currentEnd, coveredEnd);
24204
+ if (overlapEnd <= overlapStart) return [[currentStart, currentEnd]];
24205
+ const next = [];
24206
+ if (overlapStart > currentStart) next.push([currentStart, overlapStart]);
24207
+ if (overlapEnd < currentEnd) next.push([overlapEnd, currentEnd]);
24208
+ return next;
24209
+ });
24210
+ });
24211
+ return visible.filter(
24212
+ ([currentStart, currentEnd]) => currentEnd > currentStart
24213
+ );
23867
24214
  }
23868
24215
  function drawRangeHighlightBorder(ctx, rect, edges = {}) {
23869
24216
  ctx.save();
@@ -24126,6 +24473,7 @@ function executeListTableRenderPipeline(params) {
24126
24473
  descriptors,
24127
24474
  selection,
24128
24475
  width,
24476
+ height,
24129
24477
  headerHeight,
24130
24478
  topFrozenHeight,
24131
24479
  scrollBodyTop,
@@ -24153,7 +24501,14 @@ function executeListTableRenderPipeline(params) {
24153
24501
  descriptors,
24154
24502
  theme.borderColor,
24155
24503
  scrollbarOpacity,
24156
- isScrollbarInteractive
24504
+ isScrollbarInteractive,
24505
+ {
24506
+ top: 0,
24507
+ height,
24508
+ headerBottom: headerHeight,
24509
+ headerBackgroundColor: theme.headerBackgroundColor,
24510
+ bodyBackgroundColor: theme.backgroundColor
24511
+ }
24157
24512
  );
24158
24513
  if (headerDraggingIndicator) {
24159
24514
  drawDragOverlayFrame({
@@ -25273,7 +25628,7 @@ var ListTableScrollToController = class {
25273
25628
  });
25274
25629
  const targetTop = visibleRowIndex == null ? null : resolveScrollTopForRowIndex({
25275
25630
  rowIndex: visibleRowIndex,
25276
- rowCount: snapshot.visibleRows.length,
25631
+ rowCount: snapshot.frozenRows.scroll.dataRowIndexAligned ? snapshot.dataRowCount : snapshot.visibleRows.length,
25277
25632
  rowHeight: snapshot.rowHeight,
25278
25633
  maxScrollTop: snapshot.viewport.maxScrollTop,
25279
25634
  frozenRows: snapshot.frozenRows
@@ -26620,7 +26975,7 @@ var ListTableCore = class {
26620
26975
  */
26621
26976
  changeDensity(density) {
26622
26977
  this.headerActionController.changeTableDensity(
26623
- density === 32 ? "compact" : density === 56 ? "comfortable" : "middle"
26978
+ density === "auto" ? "auto" : density === 32 ? "compact" : density === 56 ? "comfortable" : "middle"
26624
26979
  );
26625
26980
  }
26626
26981
  /**