@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.js CHANGED
@@ -980,6 +980,7 @@ function collectLeafColumns(columns) {
980
980
  // src/domain/constants.ts
981
981
  var DEFAULT_ROW_HEIGHT = 32;
982
982
  var DEFAULT_HEADER_ROW_HEIGHT = DEFAULT_ROW_HEIGHT;
983
+ var DEFAULT_SCROLLBAR_THICKNESS = 10;
983
984
  var HORIZONTAL_SCROLL_STEP = 120;
984
985
  var DEFAULT_SUMMARY_ROW_HEIGHT = DEFAULT_ROW_HEIGHT;
985
986
  var DEFAULT_EMPTY_BODY_HEIGHT = 96;
@@ -988,6 +989,7 @@ var FALLBACK_TABLE_WIDTH = 320;
988
989
  var FALLBACK_TABLE_HEIGHT = 240;
989
990
  var BODY_TOOLTIP_DELAY = 1e3;
990
991
  var TABLE_CONTENT_BORDER_SIZE = 2;
992
+ var TABLE_CONTENT_BORDER_RADIUS = 8;
991
993
  var SCROLL_OVERFLOW_EPSILON = 1;
992
994
  function resolveTableSize(value, fallback) {
993
995
  if (value == null) {
@@ -1048,6 +1050,7 @@ var ListTableDomHost = class {
1048
1050
  return this.nodes;
1049
1051
  }
1050
1052
  const wrapper = document.createElement("div");
1053
+ wrapper.className = "canvas-list-table-root";
1051
1054
  wrapper.style.position = "relative";
1052
1055
  wrapper.style.display = "flex";
1053
1056
  wrapper.style.flexDirection = "column";
@@ -1112,7 +1115,7 @@ var ListTableDomHost = class {
1112
1115
  );
1113
1116
  this.applyWrapperHeight();
1114
1117
  this.nodes.contentLayerElement.style.border = `1px solid ${theme.borderColor}`;
1115
- this.nodes.contentLayerElement.style.borderRadius = "0";
1118
+ this.nodes.contentLayerElement.style.borderRadius = `${TABLE_CONTENT_BORDER_RADIUS}px`;
1116
1119
  this.nodes.contentLayerElement.style.background = theme.backgroundColor;
1117
1120
  this.nodes.paginationElement.style.borderTop = `1px solid ${theme.borderColor}`;
1118
1121
  this.nodes.paginationElement.style.background = theme.backgroundColor;
@@ -1759,7 +1762,7 @@ var headerSelectionStateCache = /* @__PURE__ */ new WeakMap();
1759
1762
  var ROW_SELECTION_COLUMN_KEY = "__row_selection__";
1760
1763
  var ROW_SELECTOR_COLUMN_KEY = "__row_selector__";
1761
1764
  var EXPAND_COLUMN_KEY = "__row_expand__";
1762
- var DEFAULT_ROW_SELECTOR_WIDTH = 12;
1765
+ var DEFAULT_ROW_SELECTOR_WIDTH = DEFAULT_SCROLLBAR_THICKNESS;
1763
1766
  function getInitialSelectedRowKeys(options) {
1764
1767
  const rowSelection = options.rowSelection;
1765
1768
  if (!rowSelection) {
@@ -2548,8 +2551,14 @@ function getPriority(descriptor) {
2548
2551
  if (descriptor.kind === "body" && descriptor.fixed) {
2549
2552
  priority += 1;
2550
2553
  }
2554
+ if (isHeaderDescriptor(descriptor.kind) && descriptor.fixed) {
2555
+ priority += 3;
2556
+ }
2551
2557
  return priority;
2552
2558
  }
2559
+ function isHeaderDescriptor(kind) {
2560
+ return kind === "header" || kind === "header-selection" || kind === "header-action" || kind === "column-collapse-trigger" || kind === "resize-handle";
2561
+ }
2553
2562
  function getBasePriority(kind) {
2554
2563
  switch (kind) {
2555
2564
  case "grouping-remove":
@@ -6623,10 +6632,7 @@ function drawBodyCellContents(params) {
6623
6632
  return void 0;
6624
6633
  }
6625
6634
  const tooltipText = column.ellipsis === true && layout.truncated ? buildBodyContentsPlainText(contents) : void 0;
6626
- const blockHeight = Math.min(
6627
- layout.lines.length * lineHeight,
6628
- availableHeight
6629
- );
6635
+ const blockHeight = layout.lines.length * lineHeight;
6630
6636
  const contentTop = resolveContentTop(
6631
6637
  rect,
6632
6638
  blockHeight,
@@ -6635,9 +6641,9 @@ function drawBodyCellContents(params) {
6635
6641
  );
6636
6642
  const contentRect = {
6637
6643
  x: rect.x + paddingInline,
6638
- y: rect.y + paddingBlock,
6644
+ y: rect.y,
6639
6645
  width: availableWidth,
6640
- height: availableHeight
6646
+ height: rect.height
6641
6647
  };
6642
6648
  const contentVisibleRect = visibleRect ? intersectRects(contentRect, visibleRect) : contentRect;
6643
6649
  if (!contentVisibleRect) {
@@ -8040,23 +8046,24 @@ function resolveScrollbarRole(x, y, scrollbar) {
8040
8046
 
8041
8047
  // src/services/scrollbar-service.ts
8042
8048
  function resolvePointerHitWithScrollbars(result, x, y, scrollbarLayout) {
8043
- if (result.area !== "empty") {
8044
- return result;
8045
- }
8046
8049
  const horizontalScrollbar = scrollbarLayout.horizontal;
8047
8050
  if (horizontalScrollbar && isPointInScrollbar(x, y, horizontalScrollbar)) {
8051
+ const scrollbarRole = resolveScrollbarRole(x, y, horizontalScrollbar);
8048
8052
  return {
8049
8053
  area: "horizontal-scrollbar",
8050
8054
  columnKey: "__horizontal_scrollbar__",
8051
- scrollbarRole: resolveScrollbarRole(x, y, horizontalScrollbar)
8055
+ scrollbarRole,
8056
+ cursor: scrollbarRole === "thumb" ? "grab" : "pointer"
8052
8057
  };
8053
8058
  }
8054
8059
  const verticalScrollbar = scrollbarLayout.vertical;
8055
8060
  if (verticalScrollbar && isPointInScrollbar(x, y, verticalScrollbar)) {
8061
+ const scrollbarRole = resolveScrollbarRole(x, y, verticalScrollbar);
8056
8062
  return {
8057
8063
  area: "vertical-scrollbar",
8058
8064
  columnKey: "__vertical_scrollbar__",
8059
- scrollbarRole: resolveScrollbarRole(x, y, verticalScrollbar)
8065
+ scrollbarRole,
8066
+ cursor: scrollbarRole === "thumb" ? "grab" : "pointer"
8060
8067
  };
8061
8068
  }
8062
8069
  return result;
@@ -11575,6 +11582,9 @@ function resolveVisibleRowIndexForDataRow(params) {
11575
11582
  if (rowIndex >= params.rowCount) {
11576
11583
  return null;
11577
11584
  }
11585
+ if (params.frozenRows.scroll.dataRowIndexAligned) {
11586
+ return rowIndex;
11587
+ }
11578
11588
  for (const section of [
11579
11589
  params.frozenRows.top,
11580
11590
  params.frozenRows.scroll,
@@ -11598,7 +11608,7 @@ function resolveScrollTopForRowIndex(params) {
11598
11608
  if (frozenRows.top.rowIndexMap?.includes(rowIndex) || frozenRows.bottom.rowIndexMap?.includes(rowIndex)) {
11599
11609
  return null;
11600
11610
  }
11601
- const scrollSectionIndex = frozenRows.scroll.rowIndexMap ? frozenRows.scroll.rowIndexMap.indexOf(rowIndex) : rowIndex;
11611
+ const scrollSectionIndex = frozenRows.scroll.dataRowIndexAligned ? rowIndex : frozenRows.scroll.rowIndexMap ? frozenRows.scroll.rowIndexMap.indexOf(rowIndex) : rowIndex;
11602
11612
  if (scrollSectionIndex < 0) {
11603
11613
  return null;
11604
11614
  }
@@ -12947,69 +12957,55 @@ function matchFilterValue(rawValue, filterValue, optionValue = serializeFilterOp
12947
12957
  }
12948
12958
  function isMeaningfulFilterValue(value) {
12949
12959
  if ((value.filterType ?? "value") === "condition") {
12950
- return isSingleConditionActive(
12951
- value.conditionOperator ?? "none",
12952
- value.conditionValue?.trim() ?? "",
12953
- value.conditionSecondValue?.trim() ?? ""
12954
- ) || isSingleConditionActive(
12955
- value.secondConditionOperator ?? "none",
12956
- value.secondConditionValue?.trim() ?? "",
12957
- value.secondConditionSecondValue?.trim() ?? ""
12960
+ return resolveFilterConditions(value).some(
12961
+ (condition) => isSingleConditionActive(
12962
+ condition.operator,
12963
+ condition.value,
12964
+ condition.secondValue
12965
+ )
12958
12966
  );
12959
12967
  }
12960
12968
  return value.keyword.trim().length > 0 || (value.selectedKeys?.filter(Boolean).length ?? 0) > 0;
12961
12969
  }
12962
12970
  function matchConditionFilterValue(rawValue, filterValue) {
12963
12971
  const sourceText = stringifyFilterValue(rawValue).toLowerCase();
12964
- const firstOperator = filterValue.conditionOperator ?? "none";
12965
- const firstValue = filterValue.conditionValue?.trim().toLowerCase() ?? "";
12966
- const firstSecondValue = filterValue.conditionSecondValue?.trim().toLowerCase() ?? "";
12967
- const secondOperator = filterValue.secondConditionOperator ?? "none";
12968
- const secondValue = filterValue.secondConditionValue?.trim().toLowerCase() ?? "";
12969
- const secondSecondValue = filterValue.secondConditionSecondValue?.trim().toLowerCase() ?? "";
12970
- const relation = filterValue.conditionRelation ?? "and";
12971
- const hasFirst = isSingleConditionActive(
12972
- firstOperator,
12973
- firstValue,
12974
- firstSecondValue
12975
- );
12976
- const hasSecond = isSingleConditionActive(
12977
- secondOperator,
12978
- secondValue,
12979
- secondSecondValue
12972
+ const conditions = resolveFilterConditions(filterValue).filter(
12973
+ (condition) => isSingleConditionActive(
12974
+ condition.operator,
12975
+ condition.value,
12976
+ condition.secondValue
12977
+ )
12980
12978
  );
12981
- if (!hasFirst && !hasSecond) {
12979
+ const relation = filterValue.conditionRelation ?? "and";
12980
+ if (conditions.length === 0) {
12982
12981
  return true;
12983
12982
  }
12984
- if (!hasFirst) {
12985
- return evaluateCondition(
12986
- sourceText,
12987
- secondOperator,
12988
- secondValue,
12989
- secondSecondValue
12990
- );
12991
- }
12992
- if (!hasSecond) {
12993
- return evaluateCondition(
12994
- sourceText,
12995
- firstOperator,
12996
- firstValue,
12997
- firstSecondValue
12998
- );
12999
- }
13000
- const primaryResult = evaluateCondition(
13001
- sourceText,
13002
- firstOperator,
13003
- firstValue,
13004
- firstSecondValue
13005
- );
13006
- const secondaryResult = evaluateCondition(
12983
+ const matches = (condition) => evaluateCondition(
13007
12984
  sourceText,
13008
- secondOperator,
13009
- secondValue,
13010
- secondSecondValue
12985
+ condition.operator,
12986
+ condition.value,
12987
+ condition.secondValue
13011
12988
  );
13012
- return relation === "or" ? primaryResult || secondaryResult : primaryResult && secondaryResult;
12989
+ return relation === "or" ? conditions.some(matches) : conditions.every(matches);
12990
+ }
12991
+ function resolveFilterConditions(filterValue) {
12992
+ const source = filterValue.conditions?.length ? filterValue.conditions : [
12993
+ {
12994
+ operator: filterValue.conditionOperator ?? "none",
12995
+ value: filterValue.conditionValue,
12996
+ secondValue: filterValue.conditionSecondValue
12997
+ },
12998
+ {
12999
+ operator: filterValue.secondConditionOperator ?? "none",
13000
+ value: filterValue.secondConditionValue,
13001
+ secondValue: filterValue.secondConditionSecondValue
13002
+ }
13003
+ ];
13004
+ return source.map((condition) => ({
13005
+ operator: condition.operator,
13006
+ value: condition.value?.trim().toLowerCase() ?? "",
13007
+ secondValue: condition.secondValue?.trim().toLowerCase() ?? ""
13008
+ }));
13013
13009
  }
13014
13010
  function isSingleConditionActive(operator, conditionValue, conditionSecondValue) {
13015
13011
  if (!operator || operator === "none") {
@@ -13138,7 +13134,10 @@ var FILTER_PANEL_TEXTS = {
13138
13134
  relationAndLabel: "\u5E76\u4E14",
13139
13135
  relationOrLabel: "\u6216\u8005",
13140
13136
  resetAction: "\u91CD\u7F6E",
13141
- applyAction: "\u5E94\u7528"
13137
+ applyAction: "\u5E94\u7528",
13138
+ conditionLabel: "\u6761\u4EF6",
13139
+ addConditionAction: "\u65B0\u589E\u6761\u4EF6",
13140
+ deleteConditionAction: "\u5220\u9664\u6761\u4EF6"
13142
13141
  };
13143
13142
  var ASYNC_FILTER_OPTION_BATCH_SIZE = 2e4;
13144
13143
  function sortRows(rows, sortState, leafColumns) {
@@ -13236,7 +13235,8 @@ function buildFilterPanelValue(currentValue) {
13236
13235
  conditionRelation: currentValue.conditionRelation,
13237
13236
  secondConditionOperator: currentValue.secondConditionOperator,
13238
13237
  secondConditionValue: currentValue.secondConditionValue,
13239
- secondConditionSecondValue: currentValue.secondConditionSecondValue
13238
+ secondConditionSecondValue: currentValue.secondConditionSecondValue,
13239
+ conditions: currentValue.conditions
13240
13240
  };
13241
13241
  }
13242
13242
  function resolveFilterModes(column) {
@@ -13361,7 +13361,12 @@ function buildFilterStateValue(value) {
13361
13361
  conditionRelation: value.conditionRelation,
13362
13362
  secondConditionOperator: value.secondConditionOperator,
13363
13363
  secondConditionValue: value.secondConditionValue,
13364
- secondConditionSecondValue: value.secondConditionSecondValue
13364
+ secondConditionSecondValue: value.secondConditionSecondValue,
13365
+ conditions: value.conditions?.map((condition) => ({
13366
+ operator: condition.operator,
13367
+ value: condition.value,
13368
+ secondValue: condition.secondValue
13369
+ }))
13365
13370
  };
13366
13371
  }
13367
13372
  function toQueryFilters(filters) {
@@ -13682,6 +13687,9 @@ function showHeaderContextMenu(params) {
13682
13687
  return true;
13683
13688
  }
13684
13689
  function resolveContextMenuDensity(rowHeight) {
13690
+ if (rowHeight === "auto") {
13691
+ return "auto";
13692
+ }
13685
13693
  if (rowHeight === 56) {
13686
13694
  return "comfortable";
13687
13695
  }
@@ -15121,6 +15129,9 @@ var ListTableEventController = class {
15121
15129
  event.clientY
15122
15130
  );
15123
15131
  const result = this.host.resolvePointerHit(position.x, position.y);
15132
+ this.host.canvasHost.setCursor(
15133
+ result.area === "resize-handle" ? "col-resize" : result.cursor ?? ""
15134
+ );
15124
15135
  const nextHover = {
15125
15136
  rowIndex: result.rowIndex ?? null,
15126
15137
  columnKey: result.columnKey ?? null,
@@ -15143,9 +15154,6 @@ var ListTableEventController = class {
15143
15154
  result,
15144
15155
  () => this.host.updateTooltip(result)
15145
15156
  );
15146
- this.host.canvasHost.setCursor(
15147
- result.area === "resize-handle" ? "col-resize" : result.cursor ?? ""
15148
- );
15149
15157
  this.host.scheduleRender(result);
15150
15158
  });
15151
15159
  __publicField(this, "handleMouseDown", (event) => {
@@ -15316,6 +15324,9 @@ var ListTableEventController = class {
15316
15324
  if (!viewport) {
15317
15325
  return;
15318
15326
  }
15327
+ this.host.canvasHost.setCursor(
15328
+ result.scrollbarRole === "thumb" ? "grabbing" : "pointer"
15329
+ );
15319
15330
  if (result.scrollbarRole === "decrease-button") {
15320
15331
  this.stepScrollbar(result.area, -1, viewport);
15321
15332
  this.startContinuousScroll(result.area, -1, viewport);
@@ -15406,6 +15417,7 @@ var ListTableEventController = class {
15406
15417
  columnKey: null,
15407
15418
  area: "empty"
15408
15419
  };
15420
+ this.host.canvasHost.setCursor("");
15409
15421
  this.host.render();
15410
15422
  });
15411
15423
  __publicField(this, "handleContextMenu", (event) => {
@@ -16551,6 +16563,7 @@ var ListTableEventController = class {
16551
16563
  this.host.setGroupingBarDropActive?.(false);
16552
16564
  this.stopContinuousScroll();
16553
16565
  this.host.tooltip.hide();
16566
+ this.host.canvasHost.setCursor("");
16554
16567
  if (options?.unbindWindowEvents !== false) {
16555
16568
  this.host.canvasHost.unbindWindowDragEvents();
16556
16569
  }
@@ -17458,6 +17471,13 @@ function resolveToggleHeaderColumnVisibilityAction(params) {
17458
17471
 
17459
17472
  // src/shared/theme/density.ts
17460
17473
  function resolveDensitySizes(density) {
17474
+ if (density === "auto") {
17475
+ return {
17476
+ rowHeight: "auto",
17477
+ headerRowHeight: void 0,
17478
+ summaryRowHeight: void 0
17479
+ };
17480
+ }
17461
17481
  if (density === "comfortable") {
17462
17482
  return {
17463
17483
  rowHeight: 56,
@@ -18134,7 +18154,7 @@ function buildStoredColumnConfig(columns, sortState, filterState, zoom, summaryR
18134
18154
  filters: filterState,
18135
18155
  ...typeof zoom === "number" && Number.isFinite(zoom) && zoom > 0 ? { zoom } : null,
18136
18156
  ...typeof summaryRowHeight === "number" && Number.isFinite(summaryRowHeight) && summaryRowHeight >= 0 ? { summaryRowHeight } : null,
18137
- ...density === 32 || density === 48 || density === 56 ? { density } : null
18157
+ ...density === 32 || density === 48 || density === 56 || density === "auto" ? { density } : null
18138
18158
  };
18139
18159
  }
18140
18160
 
@@ -18184,7 +18204,7 @@ async function loadListTableStoredConfig(params) {
18184
18204
  filterState: stored.filters ? stored.filters : null,
18185
18205
  zoom: typeof stored.zoom === "number" && Number.isFinite(stored.zoom) && stored.zoom > 0 ? stored.zoom : null,
18186
18206
  summaryRowHeight: typeof stored.summaryRowHeight === "number" && Number.isFinite(stored.summaryRowHeight) && stored.summaryRowHeight >= 0 ? stored.summaryRowHeight : null,
18187
- density: stored.density === 32 || stored.density === 48 || stored.density === 56 ? stored.density : null
18207
+ density: stored.density === 32 || stored.density === 48 || stored.density === 56 || stored.density === "auto" ? stored.density : null
18188
18208
  };
18189
18209
  }
18190
18210
 
@@ -18217,11 +18237,12 @@ var ListTablePersistenceController = class {
18217
18237
  }
18218
18238
  let currentOptions = this.options.getOptions();
18219
18239
  if (stored.density != null) {
18240
+ const densitySizes = resolveDensitySizes(
18241
+ stored.density === "auto" ? "auto" : stored.density === 32 ? "compact" : stored.density === 56 ? "comfortable" : "middle"
18242
+ );
18220
18243
  currentOptions = {
18221
18244
  ...currentOptions,
18222
- rowHeight: stored.density,
18223
- headerRowHeight: stored.density,
18224
- summaryRowHeight: stored.density
18245
+ ...densitySizes
18225
18246
  };
18226
18247
  }
18227
18248
  if (stored.summaryRowHeight != null) {
@@ -18526,7 +18547,6 @@ function getMaxDepth(columns) {
18526
18547
  }
18527
18548
 
18528
18549
  // src/domain/layout/compute-scrollbar-layout.ts
18529
- var DEFAULT_SCROLLBAR_THICKNESS = 10;
18530
18550
  var DEFAULT_HORIZONTAL_LEFT = 0;
18531
18551
  var DEFAULT_HORIZONTAL_RIGHT = 0;
18532
18552
  var DEFAULT_HORIZONTAL_BOTTOM = 0;
@@ -20101,7 +20121,10 @@ function buildListTableRenderSnapshot(params) {
20101
20121
  baseRowsOverride,
20102
20122
  displayRowsOverride
20103
20123
  } = params;
20104
- const scrollbarThickness = options.scrollbar?.visible === false ? 0 : Math.max(options.scrollbar?.thickness ?? 10, 6);
20124
+ const scrollbarThickness = options.scrollbar?.visible === false ? 0 : Math.max(
20125
+ options.scrollbar?.thickness ?? DEFAULT_SCROLLBAR_THICKNESS,
20126
+ 6
20127
+ );
20105
20128
  let width = hostWidth;
20106
20129
  let height = hostHeight;
20107
20130
  const sourceNormalizedColumns = normalizeColumns(
@@ -20148,7 +20171,11 @@ function buildListTableRenderSnapshot(params) {
20148
20171
  theme,
20149
20172
  cache: params.cache
20150
20173
  }) : options.rowHeight ?? DEFAULT_ROW_HEIGHT;
20151
- const headerRowHeight = options.headerRowHeight ?? rowHeight;
20174
+ const headerRowHeight = resolveListTableHeaderRowHeight({
20175
+ rowHeight: options.rowHeight,
20176
+ resolvedRowHeight: rowHeight,
20177
+ headerRowHeight: options.headerRowHeight
20178
+ });
20152
20179
  const summaryRowHeight = options.summaryRowHeight ?? rowHeight;
20153
20180
  const groupingBarHeight = params.groupBarVisible ? rowHeight : 0;
20154
20181
  const columnHeaderHeight = (headerInfo.maxDepth + 1) * headerRowHeight;
@@ -20319,6 +20346,7 @@ function buildListTableRenderSnapshot(params) {
20319
20346
  let bodyState = resolveCurrentBodyState();
20320
20347
  if (plainRowWindow) {
20321
20348
  bodyState.frozenRows.scroll.windowed = true;
20349
+ bodyState.frozenRows.scroll.dataRowIndexAligned = true;
20322
20350
  bodyState.frozenRows.scroll.rowIndexMap = plainRowWindow.rowIndexMap;
20323
20351
  bodyState.frozenRows.scroll.rowOffsetMap = plainRowWindow.rowOffsetMap;
20324
20352
  bodyState.bodyLayout = resolveBodyLayout({
@@ -20342,6 +20370,7 @@ function buildListTableRenderSnapshot(params) {
20342
20370
  bodyState = resolveCurrentBodyState();
20343
20371
  if (plainRowWindow) {
20344
20372
  bodyState.frozenRows.scroll.windowed = true;
20373
+ bodyState.frozenRows.scroll.dataRowIndexAligned = true;
20345
20374
  bodyState.frozenRows.scroll.rowIndexMap = plainRowWindow.rowIndexMap;
20346
20375
  bodyState.frozenRows.scroll.rowOffsetMap = plainRowWindow.rowOffsetMap;
20347
20376
  bodyState.bodyLayout = resolveBodyLayout({
@@ -20388,6 +20417,7 @@ function buildListTableRenderSnapshot(params) {
20388
20417
  bodyState = resolveCurrentBodyState();
20389
20418
  if (plainRowWindow) {
20390
20419
  bodyState.frozenRows.scroll.windowed = true;
20420
+ bodyState.frozenRows.scroll.dataRowIndexAligned = true;
20391
20421
  bodyState.frozenRows.scroll.rowIndexMap = plainRowWindow.rowIndexMap;
20392
20422
  bodyState.frozenRows.scroll.rowOffsetMap = plainRowWindow.rowOffsetMap;
20393
20423
  bodyState.bodyLayout = resolveBodyLayout({
@@ -20907,6 +20937,9 @@ function resolveAutoRowHeightMeasureRows(rows, sampleCount = AUTO_ROW_HEIGHT_SAM
20907
20937
  }
20908
20938
  return rows.slice(0, sampleCount);
20909
20939
  }
20940
+ function resolveListTableHeaderRowHeight(params) {
20941
+ return params.headerRowHeight ?? params.resolvedRowHeight;
20942
+ }
20910
20943
  function buildListTableDebugSnapshot(params) {
20911
20944
  const {
20912
20945
  snapshot,
@@ -21067,13 +21100,28 @@ function resolveListTableRenderHostSize(params) {
21067
21100
  }
21068
21101
 
21069
21102
  // src/rendering/primitives/draw-scrollbars.ts
21070
- function drawScrollbars(ctx, layout, descriptors, borderColor, opacity = 1, interactive = true) {
21103
+ function drawScrollbars(ctx, layout, descriptors, borderColor, opacity = 1, interactive = true, verticalFrame) {
21071
21104
  const alpha = Number.isFinite(opacity) ? Math.min(Math.max(opacity, 0), 1) : 1;
21072
21105
  if (alpha <= 1e-3) {
21073
21106
  return;
21074
21107
  }
21075
21108
  ctx.save();
21076
21109
  ctx.globalAlpha = alpha;
21110
+ if (layout.horizontal && verticalFrame) {
21111
+ drawHorizontalScrollbarMask(
21112
+ ctx,
21113
+ layout.horizontal,
21114
+ verticalFrame.bodyBackgroundColor
21115
+ );
21116
+ }
21117
+ if (layout.vertical && verticalFrame) {
21118
+ drawVerticalScrollbarFrame(
21119
+ ctx,
21120
+ layout.vertical,
21121
+ verticalFrame,
21122
+ borderColor
21123
+ );
21124
+ }
21077
21125
  if (layout.horizontal) {
21078
21126
  drawAxisScrollbar(
21079
21127
  ctx,
@@ -21094,6 +21142,45 @@ function drawScrollbars(ctx, layout, descriptors, borderColor, opacity = 1, inte
21094
21142
  interactive
21095
21143
  );
21096
21144
  }
21145
+ if (layout.horizontal) {
21146
+ drawHorizontalScrollbarTopBorder(
21147
+ ctx,
21148
+ layout.horizontal,
21149
+ layout.vertical,
21150
+ borderColor
21151
+ );
21152
+ }
21153
+ ctx.restore();
21154
+ }
21155
+ function drawHorizontalScrollbarMask(ctx, layout, backgroundColor) {
21156
+ const left = layout.decreaseButton.x;
21157
+ const right = layout.increaseButton.x + layout.increaseButton.width;
21158
+ const top = layout.decreaseButton.y;
21159
+ const height = layout.decreaseButton.height;
21160
+ if (right <= left || height <= 0) {
21161
+ return;
21162
+ }
21163
+ ctx.save();
21164
+ ctx.fillStyle = backgroundColor;
21165
+ ctx.fillRect(left, top, right - left, height);
21166
+ ctx.restore();
21167
+ }
21168
+ function drawHorizontalScrollbarTopBorder(ctx, horizontal, vertical, borderColor) {
21169
+ const left = Math.round(horizontal.decreaseButton.x) + 0.5;
21170
+ const horizontalRight = horizontal.increaseButton.x + horizontal.increaseButton.width;
21171
+ const verticalRight = vertical ? vertical.decreaseButton.x + vertical.decreaseButton.width : horizontalRight;
21172
+ const right = Math.round(Math.max(horizontalRight, verticalRight)) - 0.5;
21173
+ const top = Math.round(horizontal.decreaseButton.y) + 0.5;
21174
+ if (right <= left) {
21175
+ return;
21176
+ }
21177
+ ctx.save();
21178
+ ctx.strokeStyle = borderColor;
21179
+ ctx.lineWidth = 1;
21180
+ ctx.beginPath();
21181
+ ctx.moveTo(left, top);
21182
+ ctx.lineTo(right, top);
21183
+ ctx.stroke();
21097
21184
  ctx.restore();
21098
21185
  }
21099
21186
  function drawAxisScrollbar(ctx, layout, axis, descriptors, borderColor, interactive) {
@@ -21124,19 +21211,69 @@ function drawAxisScrollbar(ctx, layout, axis, descriptors, borderColor, interact
21124
21211
  scrollbarRole: "increase-button"
21125
21212
  });
21126
21213
  }
21127
- drawTrack(ctx, layout.track, borderColor);
21128
21214
  drawButton(ctx, layout.decreaseButton, axis, "decrease");
21129
21215
  drawButton(ctx, layout.increaseButton, axis, "increase");
21130
21216
  drawThumb(ctx, layout.thumb);
21217
+ drawTrackBorder(ctx, layout.track, axis, borderColor);
21218
+ }
21219
+ function drawTrackBorder(ctx, rect, axis, borderColor) {
21220
+ const left = Math.round(rect.x) + 0.5;
21221
+ const right = Math.round(rect.x + rect.width) - 0.5;
21222
+ const top = Math.round(rect.y) + 0.5;
21223
+ const bottom = Math.round(rect.y + rect.height) - 0.5;
21224
+ if (right <= left || bottom <= top) {
21225
+ return;
21226
+ }
21227
+ ctx.save();
21228
+ ctx.strokeStyle = borderColor;
21229
+ ctx.lineWidth = 1;
21230
+ ctx.beginPath();
21231
+ if (axis === "horizontal") {
21232
+ ctx.moveTo(left, top);
21233
+ ctx.lineTo(right, top);
21234
+ } else {
21235
+ ctx.moveTo(left, top);
21236
+ ctx.lineTo(left, bottom);
21237
+ }
21238
+ ctx.stroke();
21239
+ ctx.restore();
21131
21240
  }
21132
- function drawTrack(ctx, rect, borderColor) {
21241
+ function drawVerticalScrollbarFrame(ctx, layout, frame, borderColor) {
21242
+ const left = Math.round(layout.decreaseButton.x) + 0.5;
21243
+ const right = Math.round(layout.decreaseButton.x + layout.decreaseButton.width) - 0.5;
21244
+ const top = Math.round(frame.top) + 0.5;
21245
+ const bottom = Math.round(frame.top + frame.height) - 0.5;
21246
+ const headerBottom = Math.round(frame.headerBottom) + 0.5;
21247
+ if (right <= left || bottom <= top) {
21248
+ return;
21249
+ }
21133
21250
  ctx.save();
21134
- ctx.fillStyle = "rgba(148, 163, 184, 0.16)";
21251
+ ctx.fillStyle = frame.headerBackgroundColor;
21252
+ ctx.fillRect(
21253
+ layout.decreaseButton.x,
21254
+ frame.top,
21255
+ layout.decreaseButton.width,
21256
+ Math.max(frame.headerBottom - frame.top, 0)
21257
+ );
21258
+ ctx.fillStyle = frame.bodyBackgroundColor;
21259
+ ctx.fillRect(
21260
+ layout.decreaseButton.x,
21261
+ frame.headerBottom,
21262
+ layout.decreaseButton.width,
21263
+ Math.max(frame.top + frame.height - frame.headerBottom, 0)
21264
+ );
21135
21265
  ctx.strokeStyle = borderColor;
21136
21266
  ctx.lineWidth = 1;
21137
- roundRect(ctx, rect.x, rect.y, rect.width, rect.height, rect.height / 2);
21138
- ctx.fill();
21267
+ ctx.beginPath();
21268
+ ctx.moveTo(left, top);
21269
+ ctx.lineTo(left, bottom);
21139
21270
  ctx.stroke();
21271
+ if (headerBottom > top && headerBottom < bottom) {
21272
+ ctx.beginPath();
21273
+ ctx.moveTo(left, headerBottom);
21274
+ ctx.lineTo(right, headerBottom);
21275
+ ctx.stroke();
21276
+ }
21140
21277
  ctx.restore();
21141
21278
  }
21142
21279
  function drawThumb(ctx, rect) {
@@ -21148,34 +21285,25 @@ function drawThumb(ctx, rect) {
21148
21285
  }
21149
21286
  function drawButton(ctx, rect, axis, direction) {
21150
21287
  ctx.save();
21151
- ctx.fillStyle = "rgba(226, 232, 240, 0.92)";
21152
- ctx.strokeStyle = "rgba(148, 163, 184, 0.65)";
21153
- ctx.lineWidth = 1;
21154
- roundRect(ctx, rect.x, rect.y, rect.width, rect.height, rect.height / 2);
21155
- ctx.fill();
21156
- ctx.stroke();
21157
21288
  ctx.fillStyle = "rgba(71, 85, 105, 0.88)";
21158
21289
  ctx.beginPath();
21290
+ const centerX = rect.x + rect.width / 2;
21291
+ const centerY = rect.y + rect.height / 2;
21292
+ const iconSize = Math.min(rect.width, rect.height) * 0.64;
21293
+ const directionOffset = iconSize * 0.4;
21294
+ const crossAxisOffset = iconSize / 2;
21159
21295
  if (axis === "horizontal") {
21160
- const centerY = rect.y + rect.height / 2;
21161
- const iconWidth = rect.width * 0.28;
21162
- const iconHeight = rect.height * 0.22;
21163
- const centerX = rect.x + rect.width / 2;
21164
- const tipX = direction === "decrease" ? centerX - iconWidth / 2 : centerX + iconWidth / 2;
21165
- const tailX = direction === "decrease" ? centerX + iconWidth / 2 : centerX - iconWidth / 2;
21296
+ const tipX = centerX + (direction === "decrease" ? -1 : 1) * directionOffset;
21297
+ const tailX = centerX + (direction === "decrease" ? 1 : -1) * directionOffset;
21166
21298
  ctx.moveTo(tipX, centerY);
21167
- ctx.lineTo(tailX, centerY - iconHeight);
21168
- ctx.lineTo(tailX, centerY + iconHeight);
21299
+ ctx.lineTo(tailX, centerY - crossAxisOffset);
21300
+ ctx.lineTo(tailX, centerY + crossAxisOffset);
21169
21301
  } else {
21170
- const centerX = rect.x + rect.width / 2;
21171
- const iconWidth = rect.width * 0.22;
21172
- const iconHeight = rect.height * 0.28;
21173
- const centerY = rect.y + rect.height / 2;
21174
- const tipY = direction === "decrease" ? centerY - iconHeight / 2 : centerY + iconHeight / 2;
21175
- const tailY = direction === "decrease" ? centerY + iconHeight / 2 : centerY - iconHeight / 2;
21302
+ const tipY = centerY + (direction === "decrease" ? -1 : 1) * directionOffset;
21303
+ const tailY = centerY + (direction === "decrease" ? 1 : -1) * directionOffset;
21176
21304
  ctx.moveTo(centerX, tipY);
21177
- ctx.lineTo(centerX - iconWidth, tailY);
21178
- ctx.lineTo(centerX + iconWidth, tailY);
21305
+ ctx.lineTo(centerX - crossAxisOffset, tailY);
21306
+ ctx.lineTo(centerX + crossAxisOffset, tailY);
21179
21307
  }
21180
21308
  ctx.closePath();
21181
21309
  ctx.fill();
@@ -23103,7 +23231,8 @@ function drawHeaderCell(params, cell, clipRect) {
23103
23231
  descriptors.push({
23104
23232
  kind: "header",
23105
23233
  rect,
23106
- columnKey: cell.node.key
23234
+ columnKey: cell.node.key,
23235
+ fixed: cell.node.fixed
23107
23236
  });
23108
23237
  if (params.rowSelection.type === "checkbox") {
23109
23238
  drawHeaderSelectionControl(params, rect);
@@ -23111,7 +23240,8 @@ function drawHeaderCell(params, cell, clipRect) {
23111
23240
  kind: "header-selection",
23112
23241
  rect: getHeaderSelectionRect(rect),
23113
23242
  columnKey: cell.node.key,
23114
- controlType: params.rowSelection.type
23243
+ controlType: params.rowSelection.type,
23244
+ fixed: cell.node.fixed
23115
23245
  });
23116
23246
  }
23117
23247
  ctx.restore();
@@ -23121,7 +23251,8 @@ function drawHeaderCell(params, cell, clipRect) {
23121
23251
  descriptors.push({
23122
23252
  kind: "header",
23123
23253
  rect,
23124
- columnKey: cell.node.key
23254
+ columnKey: cell.node.key,
23255
+ fixed: cell.node.fixed
23125
23256
  });
23126
23257
  ctx.restore();
23127
23258
  return;
@@ -23170,12 +23301,25 @@ function drawHeaderCell(params, cell, clipRect) {
23170
23301
  textLayout,
23171
23302
  titleContent,
23172
23303
  ctx
23173
- )
23304
+ ),
23305
+ fixed: cell.node.fixed
23174
23306
  });
23175
23307
  if (cell.node.children.length === 0) {
23176
- drawCollapsedColumnMarkers(params, rect, cell.node.key, collapseMarkerSet);
23177
- drawHeaderActions(params, rect, cell.node.key, visibleState);
23178
- drawResizeHandles(params, rect, cell.node.key);
23308
+ drawCollapsedColumnMarkers(
23309
+ params,
23310
+ rect,
23311
+ cell.node.key,
23312
+ collapseMarkerSet,
23313
+ cell.node.fixed
23314
+ );
23315
+ drawHeaderActions(
23316
+ params,
23317
+ rect,
23318
+ cell.node.key,
23319
+ visibleState,
23320
+ cell.node.fixed
23321
+ );
23322
+ drawResizeHandles(params, rect, cell.node.key, cell.node.fixed);
23179
23323
  }
23180
23324
  ctx.restore();
23181
23325
  }
@@ -23213,7 +23357,7 @@ function measureHeaderContentWidth(ctx, contents) {
23213
23357
  0
23214
23358
  ) + Math.max(contents.length - 1, 0) * gap;
23215
23359
  }
23216
- function drawHeaderActions(params, rect, columnKey, visibilityState) {
23360
+ function drawHeaderActions(params, rect, columnKey, visibilityState, fixed) {
23217
23361
  if (!visibilityState.visible) {
23218
23362
  return;
23219
23363
  }
@@ -23266,7 +23410,8 @@ function drawHeaderActions(params, rect, columnKey, visibilityState) {
23266
23410
  rect: actionRect,
23267
23411
  columnKey,
23268
23412
  actionType,
23269
- visibilityState
23413
+ visibilityState,
23414
+ fixed
23270
23415
  });
23271
23416
  });
23272
23417
  }
@@ -23288,15 +23433,15 @@ function resolveCollapsedColumnMarkerSet(markers, columnKey) {
23288
23433
  hasRightMarker: !!right
23289
23434
  };
23290
23435
  }
23291
- function drawCollapsedColumnMarkers(params, rect, columnKey, markerSet) {
23436
+ function drawCollapsedColumnMarkers(params, rect, columnKey, markerSet, fixed) {
23292
23437
  if (markerSet.left) {
23293
- drawCollapsedColumnMarker(params, rect, columnKey, markerSet.left);
23438
+ drawCollapsedColumnMarker(params, rect, columnKey, markerSet.left, fixed);
23294
23439
  }
23295
23440
  if (markerSet.right) {
23296
- drawCollapsedColumnMarker(params, rect, columnKey, markerSet.right);
23441
+ drawCollapsedColumnMarker(params, rect, columnKey, markerSet.right, fixed);
23297
23442
  }
23298
23443
  }
23299
- function drawCollapsedColumnMarker(params, rect, columnKey, marker) {
23444
+ function drawCollapsedColumnMarker(params, rect, columnKey, marker, fixed) {
23300
23445
  const triggerRect = {
23301
23446
  x: marker.align === "left" ? rect.x + GRID_LINE_OFFSET2 - COLLAPSE_TRIGGER_WIDTH / 2 : rect.x + rect.width + GRID_LINE_OFFSET2 - COLLAPSE_TRIGGER_WIDTH / 2,
23302
23447
  y: rect.y + (rect.height - COLLAPSE_TRIGGER_HEIGHT) / 2,
@@ -23310,7 +23455,8 @@ function drawCollapsedColumnMarker(params, rect, columnKey, marker) {
23310
23455
  rect: triggerRect,
23311
23456
  columnKey,
23312
23457
  cursor: "pointer",
23313
- contentKey: `${marker.rangeStart}:${marker.rangeEnd}`
23458
+ contentKey: `${marker.rangeStart}:${marker.rangeEnd}`,
23459
+ fixed
23314
23460
  });
23315
23461
  }
23316
23462
  function isHeaderCellSelected(params, columnKey, rect) {
@@ -23332,13 +23478,14 @@ function isHeaderCellInRange(rangeHighlight, cell) {
23332
23478
  function isSameRect(left, right) {
23333
23479
  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;
23334
23480
  }
23335
- function drawResizeHandles(params, rect, columnKey) {
23481
+ function drawResizeHandles(params, rect, columnKey, fixed) {
23336
23482
  if (params.isResizable(columnKey)) {
23337
23483
  params.descriptors.push({
23338
23484
  kind: "resize-handle",
23339
23485
  rect: getResizeHandleRect(params, rect, "right"),
23340
23486
  columnKey,
23341
- resizeEdge: "right"
23487
+ resizeEdge: "right",
23488
+ fixed
23342
23489
  });
23343
23490
  }
23344
23491
  const leafIndex = params.leafColumnKeys?.indexOf(columnKey) ?? -1;
@@ -23348,7 +23495,8 @@ function drawResizeHandles(params, rect, columnKey) {
23348
23495
  kind: "resize-handle",
23349
23496
  rect: getResizeHandleRect(params, rect, "left"),
23350
23497
  columnKey: previousColumnKey,
23351
- resizeEdge: "left"
23498
+ resizeEdge: "left",
23499
+ fixed
23352
23500
  });
23353
23501
  }
23354
23502
  }
@@ -23742,15 +23890,18 @@ function resolveActiveCellOverlayLayout(params) {
23742
23890
  const descriptor = selection.rowIndex != null && selection.columnKey != null ? params.descriptors.find(
23743
23891
  (item) => item.kind === "body" && item.rowIndex === selection.rowIndex && item.columnKey === selection.columnKey
23744
23892
  ) : void 0;
23745
- const rangeRects = resolveRangeHighlightLayouts({
23893
+ const rangeLayout = resolveRangeHighlightLayouts({
23746
23894
  descriptors: params.descriptors,
23747
23895
  rangeHighlight: params.rangeHighlight,
23748
23896
  highlightMode: params.highlightMode,
23749
23897
  columnKeys: params.columnKeys ?? [],
23750
23898
  allowColumnRange: selection.rowIndex == null,
23751
23899
  allowRowRange: selection.columnKey === ROW_SELECTOR_COLUMN_KEY,
23752
- resolveClipRect: (item) => resolveActiveCellSectionClipRect(item, params)
23900
+ resolveClipRect: (item) => resolveActiveCellSectionClipRect(item, params),
23901
+ width: params.width,
23902
+ height: params.height
23753
23903
  });
23904
+ const rangeRects = rangeLayout.rects;
23754
23905
  if (!descriptor && rangeRects.length === 0) {
23755
23906
  return null;
23756
23907
  }
@@ -23761,6 +23912,7 @@ function resolveActiveCellOverlayLayout(params) {
23761
23912
  return {
23762
23913
  rect: descriptor?.rect ?? { x: 0, y: 0, width: 0, height: 0 },
23763
23914
  clipRect,
23915
+ rangeSegments: rangeLayout.segments,
23764
23916
  rangeRects
23765
23917
  };
23766
23918
  }
@@ -23769,14 +23921,44 @@ function drawActiveCellOverlay(params) {
23769
23921
  return;
23770
23922
  }
23771
23923
  const { ctx, layout } = params;
23772
- layout.rangeRects.forEach(({ rect, clipRect, omitLeft, omitRight }) => {
23773
- ctx.save();
23774
- ctx.beginPath();
23775
- ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
23776
- ctx.clip();
23777
- drawRangeHighlightBorder(ctx, rect, { omitLeft, omitRight });
23778
- ctx.restore();
23779
- });
23924
+ if (layout.rangeSegments?.length) {
23925
+ layout.rangeSegments.forEach((segment) => {
23926
+ ctx.save();
23927
+ ctx.beginPath();
23928
+ ctx.rect(
23929
+ segment.clipRect.x,
23930
+ segment.clipRect.y,
23931
+ segment.clipRect.width,
23932
+ segment.clipRect.height
23933
+ );
23934
+ ctx.clip();
23935
+ ctx.strokeStyle = "#1677ff";
23936
+ ctx.lineWidth = 1;
23937
+ ctx.beginPath();
23938
+ ctx.moveTo(segment.startX, segment.startY);
23939
+ if (segment.controlX != null && segment.controlY != null) {
23940
+ ctx.quadraticCurveTo(
23941
+ segment.controlX,
23942
+ segment.controlY,
23943
+ segment.endX,
23944
+ segment.endY
23945
+ );
23946
+ } else {
23947
+ ctx.lineTo(segment.endX, segment.endY);
23948
+ }
23949
+ ctx.stroke();
23950
+ ctx.restore();
23951
+ });
23952
+ } else {
23953
+ layout.rangeRects.forEach(({ rect, clipRect, omitLeft, omitRight }) => {
23954
+ ctx.save();
23955
+ ctx.beginPath();
23956
+ ctx.rect(clipRect.x, clipRect.y, clipRect.width, clipRect.height);
23957
+ ctx.clip();
23958
+ drawRangeHighlightBorder(ctx, rect, { omitLeft, omitRight });
23959
+ ctx.restore();
23960
+ });
23961
+ }
23780
23962
  if (layout.rangeRects.length === 0 && layout.rect.width > 0 && layout.rect.height > 0) {
23781
23963
  ctx.save();
23782
23964
  ctx.beginPath();
@@ -23797,17 +23979,19 @@ function resolveRangeHighlightLayouts(params) {
23797
23979
  const cellRange = params.rangeHighlight?.selectedCellRange;
23798
23980
  const rowSelectorRange = rowRange && params.allowRowRange;
23799
23981
  if (!cellRange && !rowSelectorRange && (!columnRange || !params.allowColumnRange)) {
23800
- return [];
23982
+ return { rects: [], segments: [] };
23801
23983
  }
23802
23984
  const bodyDescriptors = params.descriptors.filter(
23803
23985
  (item) => item.kind === "body" && item.columnKey != null && item.rowIndex != null
23804
23986
  );
23805
23987
  const selected = bodyDescriptors.filter((item) => {
23806
- const rowSelected = rowRange != null && item.rowIndex >= rowRange.start && item.rowIndex <= rowRange.end;
23988
+ const itemRowStart = item.rowIndex;
23989
+ const itemRowEnd = itemRowStart + Math.max(item.rowSpan ?? 1, 1) - 1;
23990
+ const rowSelected = rowRange != null && itemRowEnd >= rowRange.start && itemRowStart <= rowRange.end;
23807
23991
  const columnIndex = params.columnKeys.indexOf(item.columnKey);
23808
23992
  const columnSelected = columnRange != null && columnIndex >= columnRange.start && columnIndex <= columnRange.end;
23809
23993
  if (cellRange) {
23810
- return item.rowIndex >= cellRange.startRowIndex && item.rowIndex <= cellRange.endRowIndex && columnIndex >= cellRange.startColumnIndex && columnIndex <= cellRange.endColumnIndex;
23994
+ return itemRowEnd >= cellRange.startRowIndex && itemRowStart <= cellRange.endRowIndex && columnIndex >= cellRange.startColumnIndex && columnIndex <= cellRange.endColumnIndex;
23811
23995
  }
23812
23996
  if (rowSelectorRange) {
23813
23997
  return rowSelected;
@@ -23843,7 +24027,7 @@ function resolveRangeHighlightLayouts(params) {
23843
24027
  layer.push(range);
23844
24028
  groupedByLayer.set(key, layer);
23845
24029
  });
23846
- return ranges.map((range) => {
24030
+ const rects = ranges.map((range) => {
23847
24031
  const layer = groupedByLayer.get(`${range.rect.y}:${range.rect.height}`) ?? [];
23848
24032
  const minX = Math.min(...layer.map((item) => item.rect.x));
23849
24033
  const maxX = Math.max(
@@ -23855,6 +24039,172 @@ function resolveRangeHighlightLayouts(params) {
23855
24039
  omitRight: range.rect.x + range.rect.width < maxX
23856
24040
  };
23857
24041
  });
24042
+ return {
24043
+ rects,
24044
+ segments: roundRangeBorderAtTableBottom(
24045
+ resolveRangeBorderSegments(selected, params.resolveClipRect),
24046
+ params.width,
24047
+ params.height
24048
+ )
24049
+ };
24050
+ }
24051
+ function roundRangeBorderAtTableBottom(segments, width, height) {
24052
+ const inset = 0.5;
24053
+ const left = inset;
24054
+ const right = width - inset;
24055
+ const bottom = height - inset;
24056
+ const radius = Math.max(
24057
+ TABLE_CONTENT_BORDER_RADIUS - TABLE_CONTENT_BORDER_SIZE / 2,
24058
+ 0
24059
+ );
24060
+ if (radius <= 0) return segments;
24061
+ const rounded = segments.map((segment) => ({ ...segment }));
24062
+ const curves = [];
24063
+ const bottomSegments = rounded.filter(
24064
+ (segment) => nearlyEqual(segment.startY, bottom) && nearlyEqual(segment.endY, bottom)
24065
+ );
24066
+ const leftBottom = bottomSegments.find(
24067
+ (segment) => nearlyEqual(segment.startX, left)
24068
+ );
24069
+ const leftSide = rounded.find(
24070
+ (segment) => nearlyEqual(segment.startX, left) && nearlyEqual(segment.endX, left) && nearlyEqual(segment.endY, bottom)
24071
+ );
24072
+ if (leftBottom && leftSide) {
24073
+ leftBottom.startX = Math.min(left + radius, leftBottom.endX);
24074
+ leftSide.endY = Math.max(bottom - radius, leftSide.startY);
24075
+ curves.push({
24076
+ startX: leftSide.endX,
24077
+ startY: leftSide.endY,
24078
+ controlX: left,
24079
+ controlY: bottom,
24080
+ endX: leftBottom.startX,
24081
+ endY: leftBottom.startY,
24082
+ clipRect: leftSide.clipRect
24083
+ });
24084
+ }
24085
+ const rightBottom = bottomSegments.find(
24086
+ (segment) => nearlyEqual(segment.endX, right)
24087
+ );
24088
+ const rightSide = rounded.find(
24089
+ (segment) => nearlyEqual(segment.startX, right) && nearlyEqual(segment.endX, right) && nearlyEqual(segment.endY, bottom)
24090
+ );
24091
+ if (rightBottom && rightSide) {
24092
+ rightBottom.endX = Math.max(right - radius, rightBottom.startX);
24093
+ rightSide.endY = Math.max(bottom - radius, rightSide.startY);
24094
+ curves.push({
24095
+ startX: rightBottom.endX,
24096
+ startY: rightBottom.endY,
24097
+ controlX: right,
24098
+ controlY: bottom,
24099
+ endX: rightSide.endX,
24100
+ endY: rightSide.endY,
24101
+ clipRect: rightSide.clipRect
24102
+ });
24103
+ }
24104
+ return [...rounded, ...curves];
24105
+ }
24106
+ function nearlyEqual(left, right) {
24107
+ return Math.abs(left - right) < 1e-3;
24108
+ }
24109
+ function resolveRangeBorderSegments(descriptors, resolveClipRect) {
24110
+ const byLeft = groupDescriptorsByCoordinate(
24111
+ descriptors,
24112
+ (descriptor) => descriptor.rect.x
24113
+ );
24114
+ const byRight = groupDescriptorsByCoordinate(
24115
+ descriptors,
24116
+ (descriptor) => descriptor.rect.x + descriptor.rect.width
24117
+ );
24118
+ const byTop = groupDescriptorsByCoordinate(
24119
+ descriptors,
24120
+ (descriptor) => descriptor.rect.y
24121
+ );
24122
+ const byBottom = groupDescriptorsByCoordinate(
24123
+ descriptors,
24124
+ (descriptor) => descriptor.rect.y + descriptor.rect.height
24125
+ );
24126
+ return descriptors.flatMap((descriptor) => {
24127
+ const { rect } = descriptor;
24128
+ const left = rect.x;
24129
+ const right = rect.x + rect.width;
24130
+ const top = rect.y;
24131
+ const bottom = rect.y + rect.height;
24132
+ const clipRect = resolveClipRect(descriptor);
24133
+ const horizontal = (y, side) => {
24134
+ const adjacent = (side === "top" ? byBottom : byTop).get(
24135
+ coordinateKey(side === "top" ? top : bottom)
24136
+ ) ?? [];
24137
+ return subtractCoveredIntervals(
24138
+ left,
24139
+ right,
24140
+ adjacent.flatMap((other) => {
24141
+ if (other === descriptor) return [];
24142
+ return [[other.rect.x, other.rect.x + other.rect.width]];
24143
+ })
24144
+ ).map(([start, end]) => ({
24145
+ startX: start + (Math.abs(start - left) < 1e-3 ? 0.5 : 0),
24146
+ startY: y,
24147
+ endX: end - (Math.abs(end - right) < 1e-3 ? 0.5 : 0),
24148
+ endY: y,
24149
+ clipRect
24150
+ }));
24151
+ };
24152
+ const vertical = (x, side) => {
24153
+ const adjacent = (side === "left" ? byRight : byLeft).get(
24154
+ coordinateKey(side === "left" ? left : right)
24155
+ ) ?? [];
24156
+ return subtractCoveredIntervals(
24157
+ top,
24158
+ bottom,
24159
+ adjacent.flatMap((other) => {
24160
+ if (other === descriptor) return [];
24161
+ return [[other.rect.y, other.rect.y + other.rect.height]];
24162
+ })
24163
+ ).map(([start, end]) => ({
24164
+ startX: x,
24165
+ startY: start + (Math.abs(start - top) < 1e-3 ? 0.5 : 0),
24166
+ endX: x,
24167
+ endY: end - (Math.abs(end - bottom) < 1e-3 ? 0.5 : 0),
24168
+ clipRect
24169
+ }));
24170
+ };
24171
+ return [
24172
+ ...horizontal(top + 0.5, "top"),
24173
+ ...horizontal(bottom - 0.5, "bottom"),
24174
+ ...vertical(left + 0.5, "left"),
24175
+ ...vertical(right - 0.5, "right")
24176
+ ];
24177
+ });
24178
+ }
24179
+ function groupDescriptorsByCoordinate(descriptors, getCoordinate) {
24180
+ const groups = /* @__PURE__ */ new Map();
24181
+ descriptors.forEach((descriptor) => {
24182
+ const key = coordinateKey(getCoordinate(descriptor));
24183
+ const group = groups.get(key) ?? [];
24184
+ group.push(descriptor);
24185
+ groups.set(key, group);
24186
+ });
24187
+ return groups;
24188
+ }
24189
+ function coordinateKey(value) {
24190
+ return String(Math.round(value * 1e3) / 1e3);
24191
+ }
24192
+ function subtractCoveredIntervals(start, end, coveredIntervals) {
24193
+ let visible = [[start, end]];
24194
+ coveredIntervals.forEach(([coveredStart, coveredEnd]) => {
24195
+ visible = visible.flatMap(([currentStart, currentEnd]) => {
24196
+ const overlapStart = Math.max(currentStart, coveredStart);
24197
+ const overlapEnd = Math.min(currentEnd, coveredEnd);
24198
+ if (overlapEnd <= overlapStart) return [[currentStart, currentEnd]];
24199
+ const next = [];
24200
+ if (overlapStart > currentStart) next.push([currentStart, overlapStart]);
24201
+ if (overlapEnd < currentEnd) next.push([overlapEnd, currentEnd]);
24202
+ return next;
24203
+ });
24204
+ });
24205
+ return visible.filter(
24206
+ ([currentStart, currentEnd]) => currentEnd > currentStart
24207
+ );
23858
24208
  }
23859
24209
  function drawRangeHighlightBorder(ctx, rect, edges = {}) {
23860
24210
  ctx.save();
@@ -24117,6 +24467,7 @@ function executeListTableRenderPipeline(params) {
24117
24467
  descriptors,
24118
24468
  selection,
24119
24469
  width,
24470
+ height,
24120
24471
  headerHeight,
24121
24472
  topFrozenHeight,
24122
24473
  scrollBodyTop,
@@ -24144,7 +24495,14 @@ function executeListTableRenderPipeline(params) {
24144
24495
  descriptors,
24145
24496
  theme.borderColor,
24146
24497
  scrollbarOpacity,
24147
- isScrollbarInteractive
24498
+ isScrollbarInteractive,
24499
+ {
24500
+ top: 0,
24501
+ height,
24502
+ headerBottom: headerHeight,
24503
+ headerBackgroundColor: theme.headerBackgroundColor,
24504
+ bodyBackgroundColor: theme.backgroundColor
24505
+ }
24148
24506
  );
24149
24507
  if (headerDraggingIndicator) {
24150
24508
  drawDragOverlayFrame({
@@ -25264,7 +25622,7 @@ var ListTableScrollToController = class {
25264
25622
  });
25265
25623
  const targetTop = visibleRowIndex == null ? null : resolveScrollTopForRowIndex({
25266
25624
  rowIndex: visibleRowIndex,
25267
- rowCount: snapshot.visibleRows.length,
25625
+ rowCount: snapshot.frozenRows.scroll.dataRowIndexAligned ? snapshot.dataRowCount : snapshot.visibleRows.length,
25268
25626
  rowHeight: snapshot.rowHeight,
25269
25627
  maxScrollTop: snapshot.viewport.maxScrollTop,
25270
25628
  frozenRows: snapshot.frozenRows
@@ -26611,7 +26969,7 @@ var ListTableCore = class {
26611
26969
  */
26612
26970
  changeDensity(density) {
26613
26971
  this.headerActionController.changeTableDensity(
26614
- density === 32 ? "compact" : density === 56 ? "comfortable" : "middle"
26972
+ density === "auto" ? "auto" : density === 32 ? "compact" : density === 56 ? "comfortable" : "middle"
26615
26973
  );
26616
26974
  }
26617
26975
  /**