@canvas-components/list-table 0.2.6 → 0.3.1

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":
@@ -6625,10 +6634,7 @@ function drawBodyCellContents(params) {
6625
6634
  return void 0;
6626
6635
  }
6627
6636
  const tooltipText = column.ellipsis === true && layout.truncated ? buildBodyContentsPlainText(contents) : void 0;
6628
- const blockHeight = Math.min(
6629
- layout.lines.length * lineHeight,
6630
- availableHeight
6631
- );
6637
+ const blockHeight = layout.lines.length * lineHeight;
6632
6638
  const contentTop = resolveContentTop(
6633
6639
  rect,
6634
6640
  blockHeight,
@@ -6637,9 +6643,9 @@ function drawBodyCellContents(params) {
6637
6643
  );
6638
6644
  const contentRect = {
6639
6645
  x: rect.x + paddingInline,
6640
- y: rect.y + paddingBlock,
6646
+ y: rect.y,
6641
6647
  width: availableWidth,
6642
- height: availableHeight
6648
+ height: rect.height
6643
6649
  };
6644
6650
  const contentVisibleRect = visibleRect ? intersectRects(contentRect, visibleRect) : contentRect;
6645
6651
  if (!contentVisibleRect) {
@@ -8042,23 +8048,24 @@ function resolveScrollbarRole(x, y, scrollbar) {
8042
8048
 
8043
8049
  // src/services/scrollbar-service.ts
8044
8050
  function resolvePointerHitWithScrollbars(result, x, y, scrollbarLayout) {
8045
- if (result.area !== "empty") {
8046
- return result;
8047
- }
8048
8051
  const horizontalScrollbar = scrollbarLayout.horizontal;
8049
8052
  if (horizontalScrollbar && isPointInScrollbar(x, y, horizontalScrollbar)) {
8053
+ const scrollbarRole = resolveScrollbarRole(x, y, horizontalScrollbar);
8050
8054
  return {
8051
8055
  area: "horizontal-scrollbar",
8052
8056
  columnKey: "__horizontal_scrollbar__",
8053
- scrollbarRole: resolveScrollbarRole(x, y, horizontalScrollbar)
8057
+ scrollbarRole,
8058
+ cursor: scrollbarRole === "thumb" ? "grab" : "pointer"
8054
8059
  };
8055
8060
  }
8056
8061
  const verticalScrollbar = scrollbarLayout.vertical;
8057
8062
  if (verticalScrollbar && isPointInScrollbar(x, y, verticalScrollbar)) {
8063
+ const scrollbarRole = resolveScrollbarRole(x, y, verticalScrollbar);
8058
8064
  return {
8059
8065
  area: "vertical-scrollbar",
8060
8066
  columnKey: "__vertical_scrollbar__",
8061
- scrollbarRole: resolveScrollbarRole(x, y, verticalScrollbar)
8067
+ scrollbarRole,
8068
+ cursor: scrollbarRole === "thumb" ? "grab" : "pointer"
8062
8069
  };
8063
8070
  }
8064
8071
  return result;
@@ -11577,6 +11584,9 @@ function resolveVisibleRowIndexForDataRow(params) {
11577
11584
  if (rowIndex >= params.rowCount) {
11578
11585
  return null;
11579
11586
  }
11587
+ if (params.frozenRows.scroll.dataRowIndexAligned) {
11588
+ return rowIndex;
11589
+ }
11580
11590
  for (const section of [
11581
11591
  params.frozenRows.top,
11582
11592
  params.frozenRows.scroll,
@@ -11600,7 +11610,7 @@ function resolveScrollTopForRowIndex(params) {
11600
11610
  if (frozenRows.top.rowIndexMap?.includes(rowIndex) || frozenRows.bottom.rowIndexMap?.includes(rowIndex)) {
11601
11611
  return null;
11602
11612
  }
11603
- const scrollSectionIndex = frozenRows.scroll.rowIndexMap ? frozenRows.scroll.rowIndexMap.indexOf(rowIndex) : rowIndex;
11613
+ const scrollSectionIndex = frozenRows.scroll.dataRowIndexAligned ? rowIndex : frozenRows.scroll.rowIndexMap ? frozenRows.scroll.rowIndexMap.indexOf(rowIndex) : rowIndex;
11604
11614
  if (scrollSectionIndex < 0) {
11605
11615
  return null;
11606
11616
  }
@@ -12949,69 +12959,55 @@ function matchFilterValue(rawValue, filterValue, optionValue = serializeFilterOp
12949
12959
  }
12950
12960
  function isMeaningfulFilterValue(value) {
12951
12961
  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() ?? ""
12962
+ return resolveFilterConditions(value).some(
12963
+ (condition) => isSingleConditionActive(
12964
+ condition.operator,
12965
+ condition.value,
12966
+ condition.secondValue
12967
+ )
12960
12968
  );
12961
12969
  }
12962
12970
  return value.keyword.trim().length > 0 || (value.selectedKeys?.filter(Boolean).length ?? 0) > 0;
12963
12971
  }
12964
12972
  function matchConditionFilterValue(rawValue, filterValue) {
12965
12973
  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
12974
+ const conditions = resolveFilterConditions(filterValue).filter(
12975
+ (condition) => isSingleConditionActive(
12976
+ condition.operator,
12977
+ condition.value,
12978
+ condition.secondValue
12979
+ )
12982
12980
  );
12983
- if (!hasFirst && !hasSecond) {
12981
+ const relation = filterValue.conditionRelation ?? "and";
12982
+ if (conditions.length === 0) {
12984
12983
  return true;
12985
12984
  }
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(
12985
+ const matches = (condition) => evaluateCondition(
13009
12986
  sourceText,
13010
- secondOperator,
13011
- secondValue,
13012
- secondSecondValue
12987
+ condition.operator,
12988
+ condition.value,
12989
+ condition.secondValue
13013
12990
  );
13014
- return relation === "or" ? primaryResult || secondaryResult : primaryResult && secondaryResult;
12991
+ return relation === "or" ? conditions.some(matches) : conditions.every(matches);
12992
+ }
12993
+ function resolveFilterConditions(filterValue) {
12994
+ const source = filterValue.conditions?.length ? filterValue.conditions : [
12995
+ {
12996
+ operator: filterValue.conditionOperator ?? "none",
12997
+ value: filterValue.conditionValue,
12998
+ secondValue: filterValue.conditionSecondValue
12999
+ },
13000
+ {
13001
+ operator: filterValue.secondConditionOperator ?? "none",
13002
+ value: filterValue.secondConditionValue,
13003
+ secondValue: filterValue.secondConditionSecondValue
13004
+ }
13005
+ ];
13006
+ return source.map((condition) => ({
13007
+ operator: condition.operator,
13008
+ value: condition.value?.trim().toLowerCase() ?? "",
13009
+ secondValue: condition.secondValue?.trim().toLowerCase() ?? ""
13010
+ }));
13015
13011
  }
13016
13012
  function isSingleConditionActive(operator, conditionValue, conditionSecondValue) {
13017
13013
  if (!operator || operator === "none") {
@@ -13140,7 +13136,10 @@ var FILTER_PANEL_TEXTS = {
13140
13136
  relationAndLabel: "\u5E76\u4E14",
13141
13137
  relationOrLabel: "\u6216\u8005",
13142
13138
  resetAction: "\u91CD\u7F6E",
13143
- applyAction: "\u5E94\u7528"
13139
+ applyAction: "\u5E94\u7528",
13140
+ conditionLabel: "\u6761\u4EF6",
13141
+ addConditionAction: "\u65B0\u589E\u6761\u4EF6",
13142
+ deleteConditionAction: "\u5220\u9664\u6761\u4EF6"
13144
13143
  };
13145
13144
  var ASYNC_FILTER_OPTION_BATCH_SIZE = 2e4;
13146
13145
  function sortRows(rows, sortState, leafColumns) {
@@ -13238,7 +13237,8 @@ function buildFilterPanelValue(currentValue) {
13238
13237
  conditionRelation: currentValue.conditionRelation,
13239
13238
  secondConditionOperator: currentValue.secondConditionOperator,
13240
13239
  secondConditionValue: currentValue.secondConditionValue,
13241
- secondConditionSecondValue: currentValue.secondConditionSecondValue
13240
+ secondConditionSecondValue: currentValue.secondConditionSecondValue,
13241
+ conditions: currentValue.conditions
13242
13242
  };
13243
13243
  }
13244
13244
  function resolveFilterModes(column) {
@@ -13363,7 +13363,12 @@ function buildFilterStateValue(value) {
13363
13363
  conditionRelation: value.conditionRelation,
13364
13364
  secondConditionOperator: value.secondConditionOperator,
13365
13365
  secondConditionValue: value.secondConditionValue,
13366
- secondConditionSecondValue: value.secondConditionSecondValue
13366
+ secondConditionSecondValue: value.secondConditionSecondValue,
13367
+ conditions: value.conditions?.map((condition) => ({
13368
+ operator: condition.operator,
13369
+ value: condition.value,
13370
+ secondValue: condition.secondValue
13371
+ }))
13367
13372
  };
13368
13373
  }
13369
13374
  function toQueryFilters(filters) {
@@ -13684,6 +13689,9 @@ function showHeaderContextMenu(params) {
13684
13689
  return true;
13685
13690
  }
13686
13691
  function resolveContextMenuDensity(rowHeight) {
13692
+ if (rowHeight === "auto") {
13693
+ return "auto";
13694
+ }
13687
13695
  if (rowHeight === 56) {
13688
13696
  return "comfortable";
13689
13697
  }
@@ -15123,6 +15131,9 @@ var ListTableEventController = class {
15123
15131
  event.clientY
15124
15132
  );
15125
15133
  const result = this.host.resolvePointerHit(position.x, position.y);
15134
+ this.host.canvasHost.setCursor(
15135
+ result.area === "resize-handle" ? "col-resize" : result.cursor ?? ""
15136
+ );
15126
15137
  const nextHover = {
15127
15138
  rowIndex: result.rowIndex ?? null,
15128
15139
  columnKey: result.columnKey ?? null,
@@ -15145,9 +15156,6 @@ var ListTableEventController = class {
15145
15156
  result,
15146
15157
  () => this.host.updateTooltip(result)
15147
15158
  );
15148
- this.host.canvasHost.setCursor(
15149
- result.area === "resize-handle" ? "col-resize" : result.cursor ?? ""
15150
- );
15151
15159
  this.host.scheduleRender(result);
15152
15160
  });
15153
15161
  __publicField(this, "handleMouseDown", (event) => {
@@ -15318,6 +15326,9 @@ var ListTableEventController = class {
15318
15326
  if (!viewport) {
15319
15327
  return;
15320
15328
  }
15329
+ this.host.canvasHost.setCursor(
15330
+ result.scrollbarRole === "thumb" ? "grabbing" : "pointer"
15331
+ );
15321
15332
  if (result.scrollbarRole === "decrease-button") {
15322
15333
  this.stepScrollbar(result.area, -1, viewport);
15323
15334
  this.startContinuousScroll(result.area, -1, viewport);
@@ -15408,6 +15419,7 @@ var ListTableEventController = class {
15408
15419
  columnKey: null,
15409
15420
  area: "empty"
15410
15421
  };
15422
+ this.host.canvasHost.setCursor("");
15411
15423
  this.host.render();
15412
15424
  });
15413
15425
  __publicField(this, "handleContextMenu", (event) => {
@@ -16553,6 +16565,7 @@ var ListTableEventController = class {
16553
16565
  this.host.setGroupingBarDropActive?.(false);
16554
16566
  this.stopContinuousScroll();
16555
16567
  this.host.tooltip.hide();
16568
+ this.host.canvasHost.setCursor("");
16556
16569
  if (options?.unbindWindowEvents !== false) {
16557
16570
  this.host.canvasHost.unbindWindowDragEvents();
16558
16571
  }
@@ -17460,6 +17473,13 @@ function resolveToggleHeaderColumnVisibilityAction(params) {
17460
17473
 
17461
17474
  // src/shared/theme/density.ts
17462
17475
  function resolveDensitySizes(density) {
17476
+ if (density === "auto") {
17477
+ return {
17478
+ rowHeight: "auto",
17479
+ headerRowHeight: void 0,
17480
+ summaryRowHeight: void 0
17481
+ };
17482
+ }
17463
17483
  if (density === "comfortable") {
17464
17484
  return {
17465
17485
  rowHeight: 56,
@@ -18136,7 +18156,7 @@ function buildStoredColumnConfig(columns, sortState, filterState, zoom, summaryR
18136
18156
  filters: filterState,
18137
18157
  ...typeof zoom === "number" && Number.isFinite(zoom) && zoom > 0 ? { zoom } : null,
18138
18158
  ...typeof summaryRowHeight === "number" && Number.isFinite(summaryRowHeight) && summaryRowHeight >= 0 ? { summaryRowHeight } : null,
18139
- ...density === 32 || density === 48 || density === 56 ? { density } : null
18159
+ ...density === 32 || density === 48 || density === 56 || density === "auto" ? { density } : null
18140
18160
  };
18141
18161
  }
18142
18162
 
@@ -18186,7 +18206,7 @@ async function loadListTableStoredConfig(params) {
18186
18206
  filterState: stored.filters ? stored.filters : null,
18187
18207
  zoom: typeof stored.zoom === "number" && Number.isFinite(stored.zoom) && stored.zoom > 0 ? stored.zoom : null,
18188
18208
  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
18209
+ density: stored.density === 32 || stored.density === 48 || stored.density === 56 || stored.density === "auto" ? stored.density : null
18190
18210
  };
18191
18211
  }
18192
18212
 
@@ -18219,11 +18239,12 @@ var ListTablePersistenceController = class {
18219
18239
  }
18220
18240
  let currentOptions = this.options.getOptions();
18221
18241
  if (stored.density != null) {
18242
+ const densitySizes = resolveDensitySizes(
18243
+ stored.density === "auto" ? "auto" : stored.density === 32 ? "compact" : stored.density === 56 ? "comfortable" : "middle"
18244
+ );
18222
18245
  currentOptions = {
18223
18246
  ...currentOptions,
18224
- rowHeight: stored.density,
18225
- headerRowHeight: stored.density,
18226
- summaryRowHeight: stored.density
18247
+ ...densitySizes
18227
18248
  };
18228
18249
  }
18229
18250
  if (stored.summaryRowHeight != null) {
@@ -18528,7 +18549,6 @@ function getMaxDepth(columns) {
18528
18549
  }
18529
18550
 
18530
18551
  // src/domain/layout/compute-scrollbar-layout.ts
18531
- var DEFAULT_SCROLLBAR_THICKNESS = 10;
18532
18552
  var DEFAULT_HORIZONTAL_LEFT = 0;
18533
18553
  var DEFAULT_HORIZONTAL_RIGHT = 0;
18534
18554
  var DEFAULT_HORIZONTAL_BOTTOM = 0;
@@ -20103,7 +20123,10 @@ function buildListTableRenderSnapshot(params) {
20103
20123
  baseRowsOverride,
20104
20124
  displayRowsOverride
20105
20125
  } = params;
20106
- const scrollbarThickness = options.scrollbar?.visible === false ? 0 : Math.max(options.scrollbar?.thickness ?? 10, 6);
20126
+ const scrollbarThickness = options.scrollbar?.visible === false ? 0 : Math.max(
20127
+ options.scrollbar?.thickness ?? DEFAULT_SCROLLBAR_THICKNESS,
20128
+ 6
20129
+ );
20107
20130
  let width = hostWidth;
20108
20131
  let height = hostHeight;
20109
20132
  const sourceNormalizedColumns = normalizeColumns(
@@ -20150,7 +20173,11 @@ function buildListTableRenderSnapshot(params) {
20150
20173
  theme,
20151
20174
  cache: params.cache
20152
20175
  }) : options.rowHeight ?? DEFAULT_ROW_HEIGHT;
20153
- const headerRowHeight = options.headerRowHeight ?? rowHeight;
20176
+ const headerRowHeight = resolveListTableHeaderRowHeight({
20177
+ rowHeight: options.rowHeight,
20178
+ resolvedRowHeight: rowHeight,
20179
+ headerRowHeight: options.headerRowHeight
20180
+ });
20154
20181
  const summaryRowHeight = options.summaryRowHeight ?? rowHeight;
20155
20182
  const groupingBarHeight = params.groupBarVisible ? rowHeight : 0;
20156
20183
  const columnHeaderHeight = (headerInfo.maxDepth + 1) * headerRowHeight;
@@ -20321,6 +20348,7 @@ function buildListTableRenderSnapshot(params) {
20321
20348
  let bodyState = resolveCurrentBodyState();
20322
20349
  if (plainRowWindow) {
20323
20350
  bodyState.frozenRows.scroll.windowed = true;
20351
+ bodyState.frozenRows.scroll.dataRowIndexAligned = true;
20324
20352
  bodyState.frozenRows.scroll.rowIndexMap = plainRowWindow.rowIndexMap;
20325
20353
  bodyState.frozenRows.scroll.rowOffsetMap = plainRowWindow.rowOffsetMap;
20326
20354
  bodyState.bodyLayout = resolveBodyLayout({
@@ -20344,6 +20372,7 @@ function buildListTableRenderSnapshot(params) {
20344
20372
  bodyState = resolveCurrentBodyState();
20345
20373
  if (plainRowWindow) {
20346
20374
  bodyState.frozenRows.scroll.windowed = true;
20375
+ bodyState.frozenRows.scroll.dataRowIndexAligned = true;
20347
20376
  bodyState.frozenRows.scroll.rowIndexMap = plainRowWindow.rowIndexMap;
20348
20377
  bodyState.frozenRows.scroll.rowOffsetMap = plainRowWindow.rowOffsetMap;
20349
20378
  bodyState.bodyLayout = resolveBodyLayout({
@@ -20390,6 +20419,7 @@ function buildListTableRenderSnapshot(params) {
20390
20419
  bodyState = resolveCurrentBodyState();
20391
20420
  if (plainRowWindow) {
20392
20421
  bodyState.frozenRows.scroll.windowed = true;
20422
+ bodyState.frozenRows.scroll.dataRowIndexAligned = true;
20393
20423
  bodyState.frozenRows.scroll.rowIndexMap = plainRowWindow.rowIndexMap;
20394
20424
  bodyState.frozenRows.scroll.rowOffsetMap = plainRowWindow.rowOffsetMap;
20395
20425
  bodyState.bodyLayout = resolveBodyLayout({
@@ -20909,6 +20939,9 @@ function resolveAutoRowHeightMeasureRows(rows, sampleCount = AUTO_ROW_HEIGHT_SAM
20909
20939
  }
20910
20940
  return rows.slice(0, sampleCount);
20911
20941
  }
20942
+ function resolveListTableHeaderRowHeight(params) {
20943
+ return params.headerRowHeight ?? params.resolvedRowHeight;
20944
+ }
20912
20945
  function buildListTableDebugSnapshot(params) {
20913
20946
  const {
20914
20947
  snapshot,
@@ -21069,13 +21102,28 @@ function resolveListTableRenderHostSize(params) {
21069
21102
  }
21070
21103
 
21071
21104
  // src/rendering/primitives/draw-scrollbars.ts
21072
- function drawScrollbars(ctx, layout, descriptors, borderColor, opacity = 1, interactive = true) {
21105
+ function drawScrollbars(ctx, layout, descriptors, borderColor, opacity = 1, interactive = true, verticalFrame) {
21073
21106
  const alpha = Number.isFinite(opacity) ? Math.min(Math.max(opacity, 0), 1) : 1;
21074
21107
  if (alpha <= 1e-3) {
21075
21108
  return;
21076
21109
  }
21077
21110
  ctx.save();
21078
21111
  ctx.globalAlpha = alpha;
21112
+ if (layout.horizontal && verticalFrame) {
21113
+ drawHorizontalScrollbarMask(
21114
+ ctx,
21115
+ layout.horizontal,
21116
+ verticalFrame.bodyBackgroundColor
21117
+ );
21118
+ }
21119
+ if (layout.vertical && verticalFrame) {
21120
+ drawVerticalScrollbarFrame(
21121
+ ctx,
21122
+ layout.vertical,
21123
+ verticalFrame,
21124
+ borderColor
21125
+ );
21126
+ }
21079
21127
  if (layout.horizontal) {
21080
21128
  drawAxisScrollbar(
21081
21129
  ctx,
@@ -21096,6 +21144,45 @@ function drawScrollbars(ctx, layout, descriptors, borderColor, opacity = 1, inte
21096
21144
  interactive
21097
21145
  );
21098
21146
  }
21147
+ if (layout.horizontal) {
21148
+ drawHorizontalScrollbarTopBorder(
21149
+ ctx,
21150
+ layout.horizontal,
21151
+ layout.vertical,
21152
+ borderColor
21153
+ );
21154
+ }
21155
+ ctx.restore();
21156
+ }
21157
+ function drawHorizontalScrollbarMask(ctx, layout, backgroundColor) {
21158
+ const left = layout.decreaseButton.x;
21159
+ const right = layout.increaseButton.x + layout.increaseButton.width;
21160
+ const top = layout.decreaseButton.y;
21161
+ const height = layout.decreaseButton.height;
21162
+ if (right <= left || height <= 0) {
21163
+ return;
21164
+ }
21165
+ ctx.save();
21166
+ ctx.fillStyle = backgroundColor;
21167
+ ctx.fillRect(left, top, right - left, height);
21168
+ ctx.restore();
21169
+ }
21170
+ function drawHorizontalScrollbarTopBorder(ctx, horizontal, vertical, borderColor) {
21171
+ const left = Math.round(horizontal.decreaseButton.x) + 0.5;
21172
+ const horizontalRight = horizontal.increaseButton.x + horizontal.increaseButton.width;
21173
+ const verticalRight = vertical ? vertical.decreaseButton.x + vertical.decreaseButton.width : horizontalRight;
21174
+ const right = Math.round(Math.max(horizontalRight, verticalRight)) - 0.5;
21175
+ const top = Math.round(horizontal.decreaseButton.y) + 0.5;
21176
+ if (right <= left) {
21177
+ return;
21178
+ }
21179
+ ctx.save();
21180
+ ctx.strokeStyle = borderColor;
21181
+ ctx.lineWidth = 1;
21182
+ ctx.beginPath();
21183
+ ctx.moveTo(left, top);
21184
+ ctx.lineTo(right, top);
21185
+ ctx.stroke();
21099
21186
  ctx.restore();
21100
21187
  }
21101
21188
  function drawAxisScrollbar(ctx, layout, axis, descriptors, borderColor, interactive) {
@@ -21126,19 +21213,69 @@ function drawAxisScrollbar(ctx, layout, axis, descriptors, borderColor, interact
21126
21213
  scrollbarRole: "increase-button"
21127
21214
  });
21128
21215
  }
21129
- drawTrack(ctx, layout.track, borderColor);
21130
21216
  drawButton(ctx, layout.decreaseButton, axis, "decrease");
21131
21217
  drawButton(ctx, layout.increaseButton, axis, "increase");
21132
21218
  drawThumb(ctx, layout.thumb);
21219
+ drawTrackBorder(ctx, layout.track, axis, borderColor);
21220
+ }
21221
+ function drawTrackBorder(ctx, rect, axis, borderColor) {
21222
+ const left = Math.round(rect.x) + 0.5;
21223
+ const right = Math.round(rect.x + rect.width) - 0.5;
21224
+ const top = Math.round(rect.y) + 0.5;
21225
+ const bottom = Math.round(rect.y + rect.height) - 0.5;
21226
+ if (right <= left || bottom <= top) {
21227
+ return;
21228
+ }
21229
+ ctx.save();
21230
+ ctx.strokeStyle = borderColor;
21231
+ ctx.lineWidth = 1;
21232
+ ctx.beginPath();
21233
+ if (axis === "horizontal") {
21234
+ ctx.moveTo(left, top);
21235
+ ctx.lineTo(right, top);
21236
+ } else {
21237
+ ctx.moveTo(left, top);
21238
+ ctx.lineTo(left, bottom);
21239
+ }
21240
+ ctx.stroke();
21241
+ ctx.restore();
21133
21242
  }
21134
- function drawTrack(ctx, rect, borderColor) {
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;
21246
+ const top = Math.round(frame.top) + 0.5;
21247
+ const bottom = Math.round(frame.top + frame.height) - 0.5;
21248
+ const headerBottom = Math.round(frame.headerBottom) + 0.5;
21249
+ if (right <= left || bottom <= top) {
21250
+ return;
21251
+ }
21135
21252
  ctx.save();
21136
- ctx.fillStyle = "rgba(148, 163, 184, 0.16)";
21253
+ ctx.fillStyle = frame.headerBackgroundColor;
21254
+ ctx.fillRect(
21255
+ layout.decreaseButton.x,
21256
+ frame.top,
21257
+ layout.decreaseButton.width,
21258
+ Math.max(frame.headerBottom - frame.top, 0)
21259
+ );
21260
+ ctx.fillStyle = frame.bodyBackgroundColor;
21261
+ ctx.fillRect(
21262
+ layout.decreaseButton.x,
21263
+ frame.headerBottom,
21264
+ layout.decreaseButton.width,
21265
+ Math.max(frame.top + frame.height - frame.headerBottom, 0)
21266
+ );
21137
21267
  ctx.strokeStyle = borderColor;
21138
21268
  ctx.lineWidth = 1;
21139
- roundRect(ctx, rect.x, rect.y, rect.width, rect.height, rect.height / 2);
21140
- ctx.fill();
21269
+ ctx.beginPath();
21270
+ ctx.moveTo(left, top);
21271
+ ctx.lineTo(left, bottom);
21141
21272
  ctx.stroke();
21273
+ if (headerBottom > top && headerBottom < bottom) {
21274
+ ctx.beginPath();
21275
+ ctx.moveTo(left, headerBottom);
21276
+ ctx.lineTo(right, headerBottom);
21277
+ ctx.stroke();
21278
+ }
21142
21279
  ctx.restore();
21143
21280
  }
21144
21281
  function drawThumb(ctx, rect) {
@@ -21150,34 +21287,25 @@ function drawThumb(ctx, rect) {
21150
21287
  }
21151
21288
  function drawButton(ctx, rect, axis, direction) {
21152
21289
  ctx.save();
21153
- ctx.fillStyle = "rgba(226, 232, 240, 0.92)";
21154
- ctx.strokeStyle = "rgba(148, 163, 184, 0.65)";
21155
- ctx.lineWidth = 1;
21156
- roundRect(ctx, rect.x, rect.y, rect.width, rect.height, rect.height / 2);
21157
- ctx.fill();
21158
- ctx.stroke();
21159
21290
  ctx.fillStyle = "rgba(71, 85, 105, 0.88)";
21160
21291
  ctx.beginPath();
21292
+ const centerX = rect.x + rect.width / 2;
21293
+ const centerY = rect.y + rect.height / 2;
21294
+ const iconSize = Math.min(rect.width, rect.height) * 0.64;
21295
+ const directionOffset = iconSize * 0.4;
21296
+ const crossAxisOffset = iconSize / 2;
21161
21297
  if (axis === "horizontal") {
21162
- const centerY = rect.y + rect.height / 2;
21163
- const iconWidth = rect.width * 0.28;
21164
- const iconHeight = rect.height * 0.22;
21165
- const centerX = rect.x + rect.width / 2;
21166
- const tipX = direction === "decrease" ? centerX - iconWidth / 2 : centerX + iconWidth / 2;
21167
- const tailX = direction === "decrease" ? centerX + iconWidth / 2 : centerX - iconWidth / 2;
21298
+ const tipX = centerX + (direction === "decrease" ? -1 : 1) * directionOffset;
21299
+ const tailX = centerX + (direction === "decrease" ? 1 : -1) * directionOffset;
21168
21300
  ctx.moveTo(tipX, centerY);
21169
- ctx.lineTo(tailX, centerY - iconHeight);
21170
- ctx.lineTo(tailX, centerY + iconHeight);
21301
+ ctx.lineTo(tailX, centerY - crossAxisOffset);
21302
+ ctx.lineTo(tailX, centerY + crossAxisOffset);
21171
21303
  } else {
21172
- const centerX = rect.x + rect.width / 2;
21173
- const iconWidth = rect.width * 0.22;
21174
- const iconHeight = rect.height * 0.28;
21175
- const centerY = rect.y + rect.height / 2;
21176
- const tipY = direction === "decrease" ? centerY - iconHeight / 2 : centerY + iconHeight / 2;
21177
- const tailY = direction === "decrease" ? centerY + iconHeight / 2 : centerY - iconHeight / 2;
21304
+ const tipY = centerY + (direction === "decrease" ? -1 : 1) * directionOffset;
21305
+ const tailY = centerY + (direction === "decrease" ? 1 : -1) * directionOffset;
21178
21306
  ctx.moveTo(centerX, tipY);
21179
- ctx.lineTo(centerX - iconWidth, tailY);
21180
- ctx.lineTo(centerX + iconWidth, tailY);
21307
+ ctx.lineTo(centerX - crossAxisOffset, tailY);
21308
+ ctx.lineTo(centerX + crossAxisOffset, tailY);
21181
21309
  }
21182
21310
  ctx.closePath();
21183
21311
  ctx.fill();
@@ -23105,7 +23233,8 @@ function drawHeaderCell(params, cell, clipRect) {
23105
23233
  descriptors.push({
23106
23234
  kind: "header",
23107
23235
  rect,
23108
- columnKey: cell.node.key
23236
+ columnKey: cell.node.key,
23237
+ fixed: cell.node.fixed
23109
23238
  });
23110
23239
  if (params.rowSelection.type === "checkbox") {
23111
23240
  drawHeaderSelectionControl(params, rect);
@@ -23113,7 +23242,8 @@ function drawHeaderCell(params, cell, clipRect) {
23113
23242
  kind: "header-selection",
23114
23243
  rect: getHeaderSelectionRect(rect),
23115
23244
  columnKey: cell.node.key,
23116
- controlType: params.rowSelection.type
23245
+ controlType: params.rowSelection.type,
23246
+ fixed: cell.node.fixed
23117
23247
  });
23118
23248
  }
23119
23249
  ctx.restore();
@@ -23123,7 +23253,8 @@ function drawHeaderCell(params, cell, clipRect) {
23123
23253
  descriptors.push({
23124
23254
  kind: "header",
23125
23255
  rect,
23126
- columnKey: cell.node.key
23256
+ columnKey: cell.node.key,
23257
+ fixed: cell.node.fixed
23127
23258
  });
23128
23259
  ctx.restore();
23129
23260
  return;
@@ -23172,12 +23303,25 @@ function drawHeaderCell(params, cell, clipRect) {
23172
23303
  textLayout,
23173
23304
  titleContent,
23174
23305
  ctx
23175
- )
23306
+ ),
23307
+ fixed: cell.node.fixed
23176
23308
  });
23177
23309
  if (cell.node.children.length === 0) {
23178
- drawCollapsedColumnMarkers(params, rect, cell.node.key, collapseMarkerSet);
23179
- drawHeaderActions(params, rect, cell.node.key, visibleState);
23180
- drawResizeHandles(params, rect, cell.node.key);
23310
+ drawCollapsedColumnMarkers(
23311
+ params,
23312
+ rect,
23313
+ cell.node.key,
23314
+ collapseMarkerSet,
23315
+ cell.node.fixed
23316
+ );
23317
+ drawHeaderActions(
23318
+ params,
23319
+ rect,
23320
+ cell.node.key,
23321
+ visibleState,
23322
+ cell.node.fixed
23323
+ );
23324
+ drawResizeHandles(params, rect, cell.node.key, cell.node.fixed);
23181
23325
  }
23182
23326
  ctx.restore();
23183
23327
  }
@@ -23215,7 +23359,7 @@ function measureHeaderContentWidth(ctx, contents) {
23215
23359
  0
23216
23360
  ) + Math.max(contents.length - 1, 0) * gap;
23217
23361
  }
23218
- function drawHeaderActions(params, rect, columnKey, visibilityState) {
23362
+ function drawHeaderActions(params, rect, columnKey, visibilityState, fixed) {
23219
23363
  if (!visibilityState.visible) {
23220
23364
  return;
23221
23365
  }
@@ -23268,7 +23412,8 @@ function drawHeaderActions(params, rect, columnKey, visibilityState) {
23268
23412
  rect: actionRect,
23269
23413
  columnKey,
23270
23414
  actionType,
23271
- visibilityState
23415
+ visibilityState,
23416
+ fixed
23272
23417
  });
23273
23418
  });
23274
23419
  }
@@ -23290,15 +23435,15 @@ function resolveCollapsedColumnMarkerSet(markers, columnKey) {
23290
23435
  hasRightMarker: !!right
23291
23436
  };
23292
23437
  }
23293
- function drawCollapsedColumnMarkers(params, rect, columnKey, markerSet) {
23438
+ function drawCollapsedColumnMarkers(params, rect, columnKey, markerSet, fixed) {
23294
23439
  if (markerSet.left) {
23295
- drawCollapsedColumnMarker(params, rect, columnKey, markerSet.left);
23440
+ drawCollapsedColumnMarker(params, rect, columnKey, markerSet.left, fixed);
23296
23441
  }
23297
23442
  if (markerSet.right) {
23298
- drawCollapsedColumnMarker(params, rect, columnKey, markerSet.right);
23443
+ drawCollapsedColumnMarker(params, rect, columnKey, markerSet.right, fixed);
23299
23444
  }
23300
23445
  }
23301
- function drawCollapsedColumnMarker(params, rect, columnKey, marker) {
23446
+ function drawCollapsedColumnMarker(params, rect, columnKey, marker, fixed) {
23302
23447
  const triggerRect = {
23303
23448
  x: marker.align === "left" ? rect.x + GRID_LINE_OFFSET2 - COLLAPSE_TRIGGER_WIDTH / 2 : rect.x + rect.width + GRID_LINE_OFFSET2 - COLLAPSE_TRIGGER_WIDTH / 2,
23304
23449
  y: rect.y + (rect.height - COLLAPSE_TRIGGER_HEIGHT) / 2,
@@ -23312,7 +23457,8 @@ function drawCollapsedColumnMarker(params, rect, columnKey, marker) {
23312
23457
  rect: triggerRect,
23313
23458
  columnKey,
23314
23459
  cursor: "pointer",
23315
- contentKey: `${marker.rangeStart}:${marker.rangeEnd}`
23460
+ contentKey: `${marker.rangeStart}:${marker.rangeEnd}`,
23461
+ fixed
23316
23462
  });
23317
23463
  }
23318
23464
  function isHeaderCellSelected(params, columnKey, rect) {
@@ -23334,13 +23480,14 @@ function isHeaderCellInRange(rangeHighlight, cell) {
23334
23480
  function isSameRect(left, right) {
23335
23481
  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;
23336
23482
  }
23337
- function drawResizeHandles(params, rect, columnKey) {
23483
+ function drawResizeHandles(params, rect, columnKey, fixed) {
23338
23484
  if (params.isResizable(columnKey)) {
23339
23485
  params.descriptors.push({
23340
23486
  kind: "resize-handle",
23341
23487
  rect: getResizeHandleRect(params, rect, "right"),
23342
23488
  columnKey,
23343
- resizeEdge: "right"
23489
+ resizeEdge: "right",
23490
+ fixed
23344
23491
  });
23345
23492
  }
23346
23493
  const leafIndex = params.leafColumnKeys?.indexOf(columnKey) ?? -1;
@@ -23350,7 +23497,8 @@ function drawResizeHandles(params, rect, columnKey) {
23350
23497
  kind: "resize-handle",
23351
23498
  rect: getResizeHandleRect(params, rect, "left"),
23352
23499
  columnKey: previousColumnKey,
23353
- resizeEdge: "left"
23500
+ resizeEdge: "left",
23501
+ fixed
23354
23502
  });
23355
23503
  }
23356
23504
  }
@@ -23744,15 +23892,18 @@ function resolveActiveCellOverlayLayout(params) {
23744
23892
  const descriptor = selection.rowIndex != null && selection.columnKey != null ? params.descriptors.find(
23745
23893
  (item) => item.kind === "body" && item.rowIndex === selection.rowIndex && item.columnKey === selection.columnKey
23746
23894
  ) : void 0;
23747
- const rangeRects = resolveRangeHighlightLayouts({
23895
+ const rangeLayout = resolveRangeHighlightLayouts({
23748
23896
  descriptors: params.descriptors,
23749
23897
  rangeHighlight: params.rangeHighlight,
23750
23898
  highlightMode: params.highlightMode,
23751
23899
  columnKeys: params.columnKeys ?? [],
23752
23900
  allowColumnRange: selection.rowIndex == null,
23753
23901
  allowRowRange: selection.columnKey === ROW_SELECTOR_COLUMN_KEY,
23754
- resolveClipRect: (item) => resolveActiveCellSectionClipRect(item, params)
23902
+ resolveClipRect: (item) => resolveActiveCellSectionClipRect(item, params),
23903
+ width: params.width,
23904
+ height: params.height
23755
23905
  });
23906
+ const rangeRects = rangeLayout.rects;
23756
23907
  if (!descriptor && rangeRects.length === 0) {
23757
23908
  return null;
23758
23909
  }
@@ -23763,6 +23914,7 @@ function resolveActiveCellOverlayLayout(params) {
23763
23914
  return {
23764
23915
  rect: descriptor?.rect ?? { x: 0, y: 0, width: 0, height: 0 },
23765
23916
  clipRect,
23917
+ rangeSegments: rangeLayout.segments,
23766
23918
  rangeRects
23767
23919
  };
23768
23920
  }
@@ -23771,14 +23923,44 @@ function drawActiveCellOverlay(params) {
23771
23923
  return;
23772
23924
  }
23773
23925
  const { ctx, layout } = params;
23774
- layout.rangeRects.forEach(({ rect, clipRect, omitLeft, omitRight }) => {
23775
- ctx.save();
23776
- ctx.beginPath();
23777
- ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
23778
- ctx.clip();
23779
- drawRangeHighlightBorder(ctx, rect, { omitLeft, omitRight });
23780
- ctx.restore();
23781
- });
23926
+ if (layout.rangeSegments?.length) {
23927
+ layout.rangeSegments.forEach((segment) => {
23928
+ ctx.save();
23929
+ ctx.beginPath();
23930
+ ctx.rect(
23931
+ segment.clipRect.x,
23932
+ segment.clipRect.y,
23933
+ segment.clipRect.width,
23934
+ segment.clipRect.height
23935
+ );
23936
+ ctx.clip();
23937
+ ctx.strokeStyle = "#1677ff";
23938
+ ctx.lineWidth = 1;
23939
+ ctx.beginPath();
23940
+ ctx.moveTo(segment.startX, segment.startY);
23941
+ if (segment.controlX != null && segment.controlY != null) {
23942
+ ctx.quadraticCurveTo(
23943
+ segment.controlX,
23944
+ segment.controlY,
23945
+ segment.endX,
23946
+ segment.endY
23947
+ );
23948
+ } else {
23949
+ ctx.lineTo(segment.endX, segment.endY);
23950
+ }
23951
+ ctx.stroke();
23952
+ ctx.restore();
23953
+ });
23954
+ } else {
23955
+ layout.rangeRects.forEach(({ rect, clipRect, omitLeft, omitRight }) => {
23956
+ ctx.save();
23957
+ ctx.beginPath();
23958
+ ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
23959
+ ctx.clip();
23960
+ drawRangeHighlightBorder(ctx, rect, { omitLeft, omitRight });
23961
+ ctx.restore();
23962
+ });
23963
+ }
23782
23964
  if (layout.rangeRects.length === 0 && layout.rect.width > 0 && layout.rect.height > 0) {
23783
23965
  ctx.save();
23784
23966
  ctx.beginPath();
@@ -23799,17 +23981,19 @@ function resolveRangeHighlightLayouts(params) {
23799
23981
  const cellRange = params.rangeHighlight?.selectedCellRange;
23800
23982
  const rowSelectorRange = rowRange && params.allowRowRange;
23801
23983
  if (!cellRange && !rowSelectorRange && (!columnRange || !params.allowColumnRange)) {
23802
- return [];
23984
+ return { rects: [], segments: [] };
23803
23985
  }
23804
23986
  const bodyDescriptors = params.descriptors.filter(
23805
23987
  (item) => item.kind === "body" && item.columnKey != null && item.rowIndex != null
23806
23988
  );
23807
23989
  const selected = bodyDescriptors.filter((item) => {
23808
- const rowSelected = rowRange != null && item.rowIndex >= rowRange.start && item.rowIndex <= rowRange.end;
23990
+ const itemRowStart = item.rowIndex;
23991
+ const itemRowEnd = itemRowStart + Math.max(item.rowSpan ?? 1, 1) - 1;
23992
+ const rowSelected = rowRange != null && itemRowEnd >= rowRange.start && itemRowStart <= rowRange.end;
23809
23993
  const columnIndex = params.columnKeys.indexOf(item.columnKey);
23810
23994
  const columnSelected = columnRange != null && columnIndex >= columnRange.start && columnIndex <= columnRange.end;
23811
23995
  if (cellRange) {
23812
- return item.rowIndex >= cellRange.startRowIndex && item.rowIndex <= cellRange.endRowIndex && columnIndex >= cellRange.startColumnIndex && columnIndex <= cellRange.endColumnIndex;
23996
+ return itemRowEnd >= cellRange.startRowIndex && itemRowStart <= cellRange.endRowIndex && columnIndex >= cellRange.startColumnIndex && columnIndex <= cellRange.endColumnIndex;
23813
23997
  }
23814
23998
  if (rowSelectorRange) {
23815
23999
  return rowSelected;
@@ -23845,7 +24029,7 @@ function resolveRangeHighlightLayouts(params) {
23845
24029
  layer.push(range);
23846
24030
  groupedByLayer.set(key, layer);
23847
24031
  });
23848
- return ranges.map((range) => {
24032
+ const rects = ranges.map((range) => {
23849
24033
  const layer = groupedByLayer.get(`${range.rect.y}:${range.rect.height}`) ?? [];
23850
24034
  const minX = Math.min(...layer.map((item) => item.rect.x));
23851
24035
  const maxX = Math.max(
@@ -23857,6 +24041,172 @@ function resolveRangeHighlightLayouts(params) {
23857
24041
  omitRight: range.rect.x + range.rect.width < maxX
23858
24042
  };
23859
24043
  });
24044
+ return {
24045
+ rects,
24046
+ segments: roundRangeBorderAtTableBottom(
24047
+ resolveRangeBorderSegments(selected, params.resolveClipRect),
24048
+ params.width,
24049
+ params.height
24050
+ )
24051
+ };
24052
+ }
24053
+ function roundRangeBorderAtTableBottom(segments, width, height) {
24054
+ const inset = 0.5;
24055
+ const left = inset;
24056
+ const right = width - inset;
24057
+ const bottom = height - inset;
24058
+ const radius = Math.max(
24059
+ TABLE_CONTENT_BORDER_RADIUS - TABLE_CONTENT_BORDER_SIZE / 2,
24060
+ 0
24061
+ );
24062
+ if (radius <= 0) return segments;
24063
+ const rounded = segments.map((segment) => ({ ...segment }));
24064
+ const curves = [];
24065
+ const bottomSegments = rounded.filter(
24066
+ (segment) => nearlyEqual(segment.startY, bottom) && nearlyEqual(segment.endY, bottom)
24067
+ );
24068
+ const leftBottom = bottomSegments.find(
24069
+ (segment) => nearlyEqual(segment.startX, left)
24070
+ );
24071
+ const leftSide = rounded.find(
24072
+ (segment) => nearlyEqual(segment.startX, left) && nearlyEqual(segment.endX, left) && nearlyEqual(segment.endY, bottom)
24073
+ );
24074
+ if (leftBottom && leftSide) {
24075
+ leftBottom.startX = Math.min(left + radius, leftBottom.endX);
24076
+ leftSide.endY = Math.max(bottom - radius, leftSide.startY);
24077
+ curves.push({
24078
+ startX: leftSide.endX,
24079
+ startY: leftSide.endY,
24080
+ controlX: left,
24081
+ controlY: bottom,
24082
+ endX: leftBottom.startX,
24083
+ endY: leftBottom.startY,
24084
+ clipRect: leftSide.clipRect
24085
+ });
24086
+ }
24087
+ const rightBottom = bottomSegments.find(
24088
+ (segment) => nearlyEqual(segment.endX, right)
24089
+ );
24090
+ const rightSide = rounded.find(
24091
+ (segment) => nearlyEqual(segment.startX, right) && nearlyEqual(segment.endX, right) && nearlyEqual(segment.endY, bottom)
24092
+ );
24093
+ if (rightBottom && rightSide) {
24094
+ rightBottom.endX = Math.max(right - radius, rightBottom.startX);
24095
+ rightSide.endY = Math.max(bottom - radius, rightSide.startY);
24096
+ curves.push({
24097
+ startX: rightBottom.endX,
24098
+ startY: rightBottom.endY,
24099
+ controlX: right,
24100
+ controlY: bottom,
24101
+ endX: rightSide.endX,
24102
+ endY: rightSide.endY,
24103
+ clipRect: rightSide.clipRect
24104
+ });
24105
+ }
24106
+ return [...rounded, ...curves];
24107
+ }
24108
+ function nearlyEqual(left, right) {
24109
+ return Math.abs(left - right) < 1e-3;
24110
+ }
24111
+ function resolveRangeBorderSegments(descriptors, resolveClipRect) {
24112
+ const byLeft = groupDescriptorsByCoordinate(
24113
+ descriptors,
24114
+ (descriptor) => descriptor.rect.x
24115
+ );
24116
+ const byRight = groupDescriptorsByCoordinate(
24117
+ descriptors,
24118
+ (descriptor) => descriptor.rect.x + descriptor.rect.width
24119
+ );
24120
+ const byTop = groupDescriptorsByCoordinate(
24121
+ descriptors,
24122
+ (descriptor) => descriptor.rect.y
24123
+ );
24124
+ const byBottom = groupDescriptorsByCoordinate(
24125
+ descriptors,
24126
+ (descriptor) => descriptor.rect.y + descriptor.rect.height
24127
+ );
24128
+ return descriptors.flatMap((descriptor) => {
24129
+ const { rect } = descriptor;
24130
+ const left = rect.x;
24131
+ const right = rect.x + rect.width;
24132
+ const top = rect.y;
24133
+ const bottom = rect.y + rect.height;
24134
+ const clipRect = resolveClipRect(descriptor);
24135
+ const horizontal = (y, side) => {
24136
+ const adjacent = (side === "top" ? byBottom : byTop).get(
24137
+ coordinateKey(side === "top" ? top : bottom)
24138
+ ) ?? [];
24139
+ return subtractCoveredIntervals(
24140
+ left,
24141
+ right,
24142
+ adjacent.flatMap((other) => {
24143
+ if (other === descriptor) return [];
24144
+ return [[other.rect.x, other.rect.x + other.rect.width]];
24145
+ })
24146
+ ).map(([start, end]) => ({
24147
+ startX: start + (Math.abs(start - left) < 1e-3 ? 0.5 : 0),
24148
+ startY: y,
24149
+ endX: end - (Math.abs(end - right) < 1e-3 ? 0.5 : 0),
24150
+ endY: y,
24151
+ clipRect
24152
+ }));
24153
+ };
24154
+ const vertical = (x, side) => {
24155
+ const adjacent = (side === "left" ? byRight : byLeft).get(
24156
+ coordinateKey(side === "left" ? left : right)
24157
+ ) ?? [];
24158
+ return subtractCoveredIntervals(
24159
+ top,
24160
+ bottom,
24161
+ adjacent.flatMap((other) => {
24162
+ if (other === descriptor) return [];
24163
+ return [[other.rect.y, other.rect.y + other.rect.height]];
24164
+ })
24165
+ ).map(([start, end]) => ({
24166
+ startX: x,
24167
+ startY: start + (Math.abs(start - top) < 1e-3 ? 0.5 : 0),
24168
+ endX: x,
24169
+ endY: end - (Math.abs(end - bottom) < 1e-3 ? 0.5 : 0),
24170
+ clipRect
24171
+ }));
24172
+ };
24173
+ return [
24174
+ ...horizontal(top + 0.5, "top"),
24175
+ ...horizontal(bottom - 0.5, "bottom"),
24176
+ ...vertical(left + 0.5, "left"),
24177
+ ...vertical(right - 0.5, "right")
24178
+ ];
24179
+ });
24180
+ }
24181
+ function groupDescriptorsByCoordinate(descriptors, getCoordinate) {
24182
+ const groups = /* @__PURE__ */ new Map();
24183
+ descriptors.forEach((descriptor) => {
24184
+ const key = coordinateKey(getCoordinate(descriptor));
24185
+ const group = groups.get(key) ?? [];
24186
+ group.push(descriptor);
24187
+ groups.set(key, group);
24188
+ });
24189
+ return groups;
24190
+ }
24191
+ function coordinateKey(value) {
24192
+ return String(Math.round(value * 1e3) / 1e3);
24193
+ }
24194
+ function subtractCoveredIntervals(start, end, coveredIntervals) {
24195
+ let visible = [[start, end]];
24196
+ coveredIntervals.forEach(([coveredStart, coveredEnd]) => {
24197
+ visible = visible.flatMap(([currentStart, currentEnd]) => {
24198
+ const overlapStart = Math.max(currentStart, coveredStart);
24199
+ const overlapEnd = Math.min(currentEnd, coveredEnd);
24200
+ if (overlapEnd <= overlapStart) return [[currentStart, currentEnd]];
24201
+ const next = [];
24202
+ if (overlapStart > currentStart) next.push([currentStart, overlapStart]);
24203
+ if (overlapEnd < currentEnd) next.push([overlapEnd, currentEnd]);
24204
+ return next;
24205
+ });
24206
+ });
24207
+ return visible.filter(
24208
+ ([currentStart, currentEnd]) => currentEnd > currentStart
24209
+ );
23860
24210
  }
23861
24211
  function drawRangeHighlightBorder(ctx, rect, edges = {}) {
23862
24212
  ctx.save();
@@ -24119,6 +24469,7 @@ function executeListTableRenderPipeline(params) {
24119
24469
  descriptors,
24120
24470
  selection,
24121
24471
  width,
24472
+ height,
24122
24473
  headerHeight,
24123
24474
  topFrozenHeight,
24124
24475
  scrollBodyTop,
@@ -24146,7 +24497,14 @@ function executeListTableRenderPipeline(params) {
24146
24497
  descriptors,
24147
24498
  theme.borderColor,
24148
24499
  scrollbarOpacity,
24149
- isScrollbarInteractive
24500
+ isScrollbarInteractive,
24501
+ {
24502
+ top: 0,
24503
+ height,
24504
+ headerBottom: headerHeight,
24505
+ headerBackgroundColor: theme.headerBackgroundColor,
24506
+ bodyBackgroundColor: theme.backgroundColor
24507
+ }
24150
24508
  );
24151
24509
  if (headerDraggingIndicator) {
24152
24510
  drawDragOverlayFrame({
@@ -25266,7 +25624,7 @@ var ListTableScrollToController = class {
25266
25624
  });
25267
25625
  const targetTop = visibleRowIndex == null ? null : resolveScrollTopForRowIndex({
25268
25626
  rowIndex: visibleRowIndex,
25269
- rowCount: snapshot.visibleRows.length,
25627
+ rowCount: snapshot.frozenRows.scroll.dataRowIndexAligned ? snapshot.dataRowCount : snapshot.visibleRows.length,
25270
25628
  rowHeight: snapshot.rowHeight,
25271
25629
  maxScrollTop: snapshot.viewport.maxScrollTop,
25272
25630
  frozenRows: snapshot.frozenRows
@@ -26613,7 +26971,7 @@ var ListTableCore = class {
26613
26971
  */
26614
26972
  changeDensity(density) {
26615
26973
  this.headerActionController.changeTableDensity(
26616
- density === 32 ? "compact" : density === 56 ? "comfortable" : "middle"
26974
+ density === "auto" ? "auto" : density === 32 ? "compact" : density === 56 ? "comfortable" : "middle"
26617
26975
  );
26618
26976
  }
26619
26977
  /**