@canvas-components/list-table 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  'use strict';
2
2
 
3
+ var utils = require('@canvas-components/utils');
3
4
  var barcode = require('@canvas-components/barcode');
4
5
  var chart = require('@canvas-components/chart');
5
6
  var qrcode = require('@canvas-components/qrcode');
6
- var utils = require('@canvas-components/utils');
7
7
 
8
8
  var __defProp = Object.defineProperty;
9
9
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -70,13 +70,8 @@ var DebugManager = class {
70
70
  console.info(`[ListTable Debug] ${label}`, payload);
71
71
  }
72
72
  };
73
-
74
- // src/domain/columns/column-key.ts
75
- function stringifyColumnDataIndex(dataIndex) {
76
- return Array.isArray(dataIndex) ? dataIndex.map((item) => String(item)).join(".") : String(dataIndex);
77
- }
78
73
  function resolveColumnKey(column) {
79
- return column.key?.trim() || stringifyColumnDataIndex(column.dataIndex);
74
+ return column.key?.trim() || utils.stringifyDataIndex(column.dataIndex);
80
75
  }
81
76
  function ensureColumnKeysInPlace(columns) {
82
77
  columns.forEach((column) => {
@@ -329,6 +324,7 @@ function normalizeColumn(column, depth, parentKey) {
329
324
  minWidth: Number(column.minWidth) || DEFAULT_MIN_WIDTH,
330
325
  maxWidth: Number(column.maxWidth) || DEFAULT_MAX_WIDTH,
331
326
  align: column.align ?? "left",
327
+ headerAlign: column.headerAlign,
332
328
  fixed: column.fixed,
333
329
  hidden: column.hidden,
334
330
  ellipsis: column.ellipsis,
@@ -348,6 +344,7 @@ function normalizeColumn(column, depth, parentKey) {
348
344
  cellType: column.cellType,
349
345
  cellStyle: column.cellStyle,
350
346
  moneyFormat: column.moneyFormat,
347
+ dataFormat: column.dataFormat,
351
348
  headerStyle: column.headerStyle,
352
349
  summary: column.summary,
353
350
  summaryTitle: column.summaryTitle,
@@ -583,15 +580,28 @@ function cloneColumns(columns) {
583
580
  children: column.children ? cloneColumns(column.children) : void 0
584
581
  }));
585
582
  }
583
+ function applyInitialColumnVisibility(columns) {
584
+ columns.forEach((column) => {
585
+ if (column.hidden === void 0 && column.initialHide) {
586
+ column.hidden = true;
587
+ }
588
+ if (column.children?.length) {
589
+ applyInitialColumnVisibility(column.children);
590
+ }
591
+ });
592
+ }
586
593
  function replaceColumns(target, source) {
587
594
  target.splice(0, target.length, ...cloneColumns(source));
588
595
  }
589
596
  function buildHeaderSettingsItems(columns) {
590
597
  ensureColumnKeysInPlace(columns);
591
598
  const totalVisibleLeafCount = countVisibleLeafColumns(columns);
592
- return columns.map(
593
- (column) => buildHeaderSettingsItem(column, totalVisibleLeafCount, false)
594
- );
599
+ return columns.flatMap((column) => {
600
+ if (column.hideInSetting) {
601
+ return [];
602
+ }
603
+ return [buildHeaderSettingsItem(column, totalVisibleLeafCount, false)];
604
+ });
595
605
  }
596
606
  function setHeaderColumnVisible(columns, columnKey, visible) {
597
607
  if (!visible) {
@@ -651,9 +661,7 @@ function resolveCollapsedHeaderColumnMarkers(params) {
651
661
  if (visibleLeafKeys.length === 0) {
652
662
  return [];
653
663
  }
654
- const leafIndexMap = new Map(
655
- allLeafKeys.map((key, index) => [key, index])
656
- );
664
+ const leafIndexMap = new Map(allLeafKeys.map((key, index) => [key, index]));
657
665
  const markers = [];
658
666
  let previousVisibleIndex = -1;
659
667
  visibleLeafKeys.forEach((columnKey) => {
@@ -719,19 +727,87 @@ function restoreAllHiddenHeaderColumns(columns) {
719
727
  });
720
728
  return updated;
721
729
  }
730
+ function getColumnPresentationConfig(columns, columnKey) {
731
+ const column = findColumnNode(columns, columnKey);
732
+ if (!column) {
733
+ return null;
734
+ }
735
+ const bodyColumn = column.children?.length ? collectLeafColumns([column])[0] : column;
736
+ return {
737
+ headerHorizontal: column.headerAlign ?? column.align ?? "left",
738
+ headerVertical: column.headerStyle?.verticalAlign ?? "middle",
739
+ bodyHorizontal: bodyColumn?.align ?? "left",
740
+ bodyVertical: bodyColumn?.cellStyle?.verticalAlign ?? "middle",
741
+ dataFormat: column.dataFormat ?? "default",
742
+ dataFormatAvailable: !column.children?.length && !column.render && (column.cellType == null || column.cellType === "text" || column.cellType === "money")
743
+ };
744
+ }
745
+ function setColumnAlignment(params) {
746
+ const column = findColumnNode(params.columns, params.columnKey);
747
+ if (!column) {
748
+ return false;
749
+ }
750
+ const targets = params.area === "body" && column.children?.length ? collectLeafColumns([column]) : [column];
751
+ targets.forEach((target) => {
752
+ if (params.area === "header") {
753
+ if (params.axis === "horizontal") {
754
+ target.headerAlign = params.value;
755
+ } else {
756
+ target.headerStyle = {
757
+ ...target.headerStyle,
758
+ verticalAlign: params.value
759
+ };
760
+ }
761
+ return;
762
+ }
763
+ if (params.axis === "horizontal") {
764
+ target.align = params.value;
765
+ } else {
766
+ target.cellStyle = {
767
+ ...target.cellStyle,
768
+ verticalAlign: params.value
769
+ };
770
+ }
771
+ });
772
+ return true;
773
+ }
774
+ function setColumnDataFormat(columns, columnKey, dataFormat) {
775
+ const column = findColumnNode(columns, columnKey);
776
+ if (!column || column.children?.length || column.render) {
777
+ return false;
778
+ }
779
+ column.dataFormat = dataFormat === "default" ? void 0 : dataFormat;
780
+ return true;
781
+ }
782
+ function findColumnNode(columns, columnKey) {
783
+ for (const column of columns) {
784
+ if (resolveColumnKey(column) === columnKey) {
785
+ return column;
786
+ }
787
+ if (column.children?.length) {
788
+ const child = findColumnNode(column.children, columnKey);
789
+ if (child) {
790
+ return child;
791
+ }
792
+ }
793
+ }
794
+ return null;
795
+ }
722
796
  function buildHeaderSettingsItem(column, totalVisibleLeafCount, parentHidden) {
723
797
  const hidden = parentHidden || !!column.hidden;
724
- const children = column.children?.map(
798
+ const children = column.children?.filter((child) => !child.hideInSetting).map(
725
799
  (child) => buildHeaderSettingsItem(child, totalVisibleLeafCount, hidden)
726
800
  );
727
801
  const leafCount = countLeafColumns([column]);
728
802
  const visibleLeafCount = hidden ? 0 : countVisibleLeafColumns([column]);
729
803
  const checked = leafCount > 0 && visibleLeafCount === leafCount;
730
804
  const indeterminate = visibleLeafCount > 0 && visibleLeafCount < leafCount;
731
- const disabled = visibleLeafCount > 0 && visibleLeafCount >= totalVisibleLeafCount;
805
+ const disabled = column.disableHide && checked || visibleLeafCount > 0 && visibleLeafCount >= totalVisibleLeafCount;
732
806
  return {
733
807
  key: resolveColumnKey(column),
734
- title: String(column.title ?? resolveColumnKey(column)),
808
+ title: String(
809
+ column.settingTitle ?? column.title ?? resolveColumnKey(column)
810
+ ),
735
811
  checked,
736
812
  indeterminate,
737
813
  disabled,
@@ -741,6 +817,9 @@ function buildHeaderSettingsItem(column, totalVisibleLeafCount, parentHidden) {
741
817
  function setColumnVisible(columns, columnKey, visible, ancestors = []) {
742
818
  for (const column of columns) {
743
819
  if (column.key === columnKey) {
820
+ if (!visible && column.disableHide) {
821
+ return false;
822
+ }
744
823
  ancestors.forEach((item) => {
745
824
  item.hidden = false;
746
825
  });
@@ -748,12 +827,10 @@ function setColumnVisible(columns, columnKey, visible, ancestors = []) {
748
827
  return true;
749
828
  }
750
829
  if (column.children?.length) {
751
- const updated = setColumnVisible(
752
- column.children,
753
- columnKey,
754
- visible,
755
- [...ancestors, column]
756
- );
830
+ const updated = setColumnVisible(column.children, columnKey, visible, [
831
+ ...ancestors,
832
+ column
833
+ ]);
757
834
  if (updated) {
758
835
  return true;
759
836
  }
@@ -762,6 +839,9 @@ function setColumnVisible(columns, columnKey, visible, ancestors = []) {
762
839
  return false;
763
840
  }
764
841
  function setSubtreeVisible(column, visible) {
842
+ if (!visible && column.disableHide) {
843
+ return;
844
+ }
765
845
  column.hidden = !visible;
766
846
  column.children?.forEach((child) => {
767
847
  setSubtreeVisible(child, visible);
@@ -1603,27 +1683,6 @@ function clampPageNumber(page, totalPages) {
1603
1683
  }
1604
1684
  return Math.min(Math.max(1, Math.floor(page)), totalPages);
1605
1685
  }
1606
-
1607
- // src/domain/data/get-value-by-data-index.ts
1608
- function getValueByDataIndex(record, dataIndex) {
1609
- if (dataIndex == null) {
1610
- return void 0;
1611
- }
1612
- const path = Array.isArray(dataIndex) ? dataIndex : [dataIndex];
1613
- let current = record;
1614
- for (const key of path) {
1615
- if (current == null) {
1616
- return void 0;
1617
- }
1618
- if (typeof current !== "object" && !Array.isArray(current)) {
1619
- return void 0;
1620
- }
1621
- current = current[key];
1622
- }
1623
- return current;
1624
- }
1625
-
1626
- // src/domain/rows/row-selection.ts
1627
1686
  var maximumTreeDepthCache = /* @__PURE__ */ new WeakMap();
1628
1687
  var ROW_SELECTION_COLUMN_KEY = "__row_selection__";
1629
1688
  var EXPAND_COLUMN_KEY = "__row_expand__";
@@ -1655,7 +1714,7 @@ function getRowKey(options, record, index) {
1655
1714
  return rowKey(record, index);
1656
1715
  }
1657
1716
  if (rowKey != null) {
1658
- const resolved = getValueByDataIndex(record, rowKey);
1717
+ const resolved = utils.getValueByDataIndex(record, rowKey);
1659
1718
  if (typeof resolved === "string" || typeof resolved === "number") {
1660
1719
  return resolved;
1661
1720
  }
@@ -3711,8 +3770,6 @@ function resolveLinkTextDecoration(content, hovered = false) {
3711
3770
  }
3712
3771
  return shouldDrawUnderline(content.underline, hovered) ? "underline" : "none";
3713
3772
  }
3714
-
3715
- // src/rendering/cell-content/draw-nested-table-content.ts
3716
3773
  var DEFAULT_COLUMN_WIDTH2 = 140;
3717
3774
  var TABLE_PADDING_X = 12;
3718
3775
  function drawBodyNestedTableContent(params) {
@@ -3826,7 +3883,7 @@ function drawBodyNestedTableContent(params) {
3826
3883
  }
3827
3884
  drawNestedTableText({
3828
3885
  ctx,
3829
- text: String(getValueByDataIndex(record, column.dataIndex) ?? ""),
3886
+ text: String(utils.getValueByDataIndex(record, column.dataIndex) ?? ""),
3830
3887
  x: cellX,
3831
3888
  y: rowY,
3832
3889
  width: columnWidth,
@@ -3932,25 +3989,20 @@ function isNestedTableColumnHighlighted(content, column, columnIndex, highlight)
3932
3989
  return true;
3933
3990
  }
3934
3991
  return content.highlightColumnDataIndexes?.some(
3935
- (dataIndex) => isSameDataIndex(dataIndex, column.dataIndex)
3936
- ) === true || highlight?.columnDataIndex === serializeDataIndex(column.dataIndex) || highlight?.columnIndex === columnIndex;
3992
+ (dataIndex) => utils.isSameDataIndex(dataIndex, column.dataIndex)
3993
+ ) === true || highlight?.columnDataIndex === utils.stringifyDataIndex(column.dataIndex) || highlight?.columnIndex === columnIndex;
3937
3994
  }
3938
3995
  function resolveNestedTableRowKey(content, record, rowIndex) {
3939
3996
  if (typeof content.rowKey === "function") {
3940
3997
  return content.rowKey(record, rowIndex);
3941
3998
  }
3942
3999
  if (content.rowKey != null) {
3943
- const value = getValueByDataIndex(record, content.rowKey);
4000
+ const value = utils.getValueByDataIndex(record, content.rowKey);
3944
4001
  return typeof value === "string" || typeof value === "number" ? value : void 0;
3945
4002
  }
3946
4003
  const fallbackKey = record.key;
3947
4004
  return typeof fallbackKey === "string" || typeof fallbackKey === "number" ? fallbackKey : rowIndex;
3948
4005
  }
3949
- function isSameDataIndex(left, right) {
3950
- const leftPath = Array.isArray(left) ? left : [left];
3951
- const rightPath = Array.isArray(right) ? right : [right];
3952
- return leftPath.length === rightPath.length && leftPath.every((key, index) => key === rightPath[index]);
3953
- }
3954
4006
  function pushNestedTableDescriptor(params) {
3955
4007
  const { column, columnIndex, content, drawParams, record, rect, rowIndex } = params;
3956
4008
  const rowKey = record != null && typeof rowIndex === "number" ? resolveNestedTableRowKey(content, record, rowIndex) : void 0;
@@ -3963,14 +4015,11 @@ function pushNestedTableDescriptor(params) {
3963
4015
  contentKey: "nested-table",
3964
4016
  nestedRowKey: rowKey,
3965
4017
  nestedRowIndex: rowIndex,
3966
- nestedColumnDataIndex: serializeDataIndex(column.dataIndex),
4018
+ nestedColumnDataIndex: utils.stringifyDataIndex(column.dataIndex),
3967
4019
  nestedColumnIndex: columnIndex,
3968
4020
  cursor: "pointer"
3969
4021
  });
3970
4022
  }
3971
- function serializeDataIndex(dataIndex) {
3972
- return (Array.isArray(dataIndex) ? dataIndex : [dataIndex]).map((item) => String(item)).join(".");
3973
- }
3974
4023
  function drawNestedTableText(params) {
3975
4024
  const {
3976
4025
  align = "left",
@@ -5185,8 +5234,6 @@ function applyTextContentStyle(ctx, content, fallbackColor, theme) {
5185
5234
  ctx.textBaseline = "alphabetic";
5186
5235
  ctx.textAlign = "left";
5187
5236
  }
5188
-
5189
- // src/features/editing/editing-utils.ts
5190
5237
  function canEditCell(column, context) {
5191
5238
  if (!column || column.key === ROW_SELECTION_COLUMN_KEY || column.key === EXPAND_COLUMN_KEY) {
5192
5239
  return false;
@@ -5271,7 +5318,7 @@ function resolveNextEditableCell(params) {
5271
5318
  }
5272
5319
  const editableColumns = leafColumns.filter(
5273
5320
  (column) => canEditCell(column, {
5274
- value: column.dataIndex == null ? void 0 : getValueByDataIndex(currentRecord, column.dataIndex),
5321
+ value: column.dataIndex == null ? void 0 : utils.getValueByDataIndex(currentRecord, column.dataIndex),
5275
5322
  record: currentRecord,
5276
5323
  rowIndex
5277
5324
  })
@@ -5348,9 +5395,13 @@ function resolveColumnFormItemProps(column, context) {
5348
5395
  var CONTENT_HORIZONTAL_PADDING = 12;
5349
5396
  var CONTENT_GAP = 8;
5350
5397
  var CONTENT_VERTICAL_PADDING = 6;
5398
+ var THOUSANDS_NUMBER_FORMAT = new Intl.NumberFormat("zh-CN", {
5399
+ useGrouping: true,
5400
+ maximumFractionDigits: 20
5401
+ });
5351
5402
  function resolveBodyCellContents(params) {
5352
5403
  const { record, rowIndex, column } = params;
5353
- const value = getValueByDataIndex(record, column.dataIndex);
5404
+ const value = utils.getValueByDataIndex(record, column.dataIndex);
5354
5405
  const rendered = column.render?.(value, record, rowIndex, column);
5355
5406
  if (rendered != null) {
5356
5407
  return normalizeCellContents(rendered);
@@ -5361,6 +5412,14 @@ function resolveBodyCellContents(params) {
5361
5412
  record,
5362
5413
  rowIndex
5363
5414
  });
5415
+ if (column.dataFormat && column.dataFormat !== "default") {
5416
+ return [
5417
+ {
5418
+ type: "text",
5419
+ text: formattedText ?? formatListTableDataValue(value, column.dataFormat)
5420
+ }
5421
+ ];
5422
+ }
5364
5423
  if (column.cellType === "checkbox" || column.cellType === "radio" || column.cellType === "switch") {
5365
5424
  return [
5366
5425
  {
@@ -5521,6 +5580,26 @@ function formatMoneyValue(value, options) {
5521
5580
  const formattedDecimal = decimalText != null && decimalText.length > 0 ? `.${decimalText}` : "";
5522
5581
  return `${sign}${symbol}${formattedInteger}${formattedDecimal}`;
5523
5582
  }
5583
+ function formatListTableDataValue(value, dataFormat) {
5584
+ if (dataFormat === "number") {
5585
+ const numericValue = parseMoneyNumber(value);
5586
+ return numericValue == null ? String(value ?? "") : String(numericValue);
5587
+ }
5588
+ if (dataFormat === "thousands") {
5589
+ const numericValue = parseMoneyNumber(value);
5590
+ if (numericValue == null) {
5591
+ return String(value ?? "");
5592
+ }
5593
+ return THOUSANDS_NUMBER_FORMAT.format(numericValue);
5594
+ }
5595
+ if (dataFormat === "money") {
5596
+ return formatMoneyValue(value, {
5597
+ thousandsSeparator: true,
5598
+ decimalPlaces: 2
5599
+ });
5600
+ }
5601
+ return String(value ?? "");
5602
+ }
5524
5603
  function parseMoneyNumber(value) {
5525
5604
  if (typeof value === "number") {
5526
5605
  return Number.isFinite(value) ? value : null;
@@ -6658,7 +6737,7 @@ function buildBodyContentsPlainText(contents) {
6658
6737
  if (content.type === "table") {
6659
6738
  return content.dataSource.map(
6660
6739
  (record) => content.columns.map(
6661
- (column) => String(getValueByDataIndex(record, column.dataIndex) ?? "")
6740
+ (column) => String(utils.getValueByDataIndex(record, column.dataIndex) ?? "")
6662
6741
  ).join(" ")
6663
6742
  ).join(" ");
6664
6743
  }
@@ -6745,7 +6824,7 @@ function resolveStickyLineStartX(params) {
6745
6824
  const preferredX = resolveLineStartX(rect, lineWidth, align);
6746
6825
  const minX = visibleRect.x;
6747
6826
  const maxX = visibleRect.x + Math.max(visibleRect.width - lineWidth, 0);
6748
- return clamp(preferredX, minX, maxX);
6827
+ return utils.clamp(preferredX, minX, maxX);
6749
6828
  }
6750
6829
  function intersectRects(left, right) {
6751
6830
  const x = Math.max(left.x, right.x);
@@ -6762,9 +6841,6 @@ function intersectRects(left, right) {
6762
6841
  height: maxY - y
6763
6842
  };
6764
6843
  }
6765
- function clamp(value, min, max) {
6766
- return Math.min(Math.max(value, min), max);
6767
- }
6768
6844
 
6769
6845
  // src/services/cell-content-action-service.ts
6770
6846
  function emitBodyCellContentClick(params) {
@@ -6794,7 +6870,7 @@ function emitBodyCellContentClick(params) {
6794
6870
  record,
6795
6871
  rowIndex: result.rowIndex,
6796
6872
  column,
6797
- value: getValueByDataIndex(record, column.dataIndex),
6873
+ value: utils.getValueByDataIndex(record, column.dataIndex),
6798
6874
  contentIndex,
6799
6875
  nativeEvent: event
6800
6876
  };
@@ -6980,30 +7056,20 @@ function resolveBodyContentIndex(result, contents) {
6980
7056
  }
6981
7057
  return void 0;
6982
7058
  }
6983
-
6984
- // src/domain/layout/geometry.ts
6985
- function clamp2(value, min, max) {
6986
- return Math.min(Math.max(value, min), max);
6987
- }
6988
- function isPointInRect2(x, y, rect) {
6989
- return x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height;
6990
- }
6991
-
6992
- // src/domain/layout/scrollbar.ts
6993
7059
  function isPointInScrollbar(x, y, scrollbar) {
6994
- return isPointInRect2(x, y, scrollbar.decreaseButton) || isPointInRect2(x, y, scrollbar.increaseButton) || isPointInRect2(x, y, scrollbar.track) || isPointInRect2(x, y, scrollbar.thumb);
7060
+ return utils.isPointInRect(x, y, scrollbar.decreaseButton) || utils.isPointInRect(x, y, scrollbar.increaseButton) || utils.isPointInRect(x, y, scrollbar.track) || utils.isPointInRect(x, y, scrollbar.thumb);
6995
7061
  }
6996
7062
  function resolveScrollbarRole(x, y, scrollbar) {
6997
- if (isPointInRect2(x, y, scrollbar.thumb)) {
7063
+ if (utils.isPointInRect(x, y, scrollbar.thumb)) {
6998
7064
  return "thumb";
6999
7065
  }
7000
- if (isPointInRect2(x, y, scrollbar.decreaseButton)) {
7066
+ if (utils.isPointInRect(x, y, scrollbar.decreaseButton)) {
7001
7067
  return "decrease-button";
7002
7068
  }
7003
- if (isPointInRect2(x, y, scrollbar.increaseButton)) {
7069
+ if (utils.isPointInRect(x, y, scrollbar.increaseButton)) {
7004
7070
  return "increase-button";
7005
7071
  }
7006
- if (isPointInRect2(x, y, scrollbar.track)) {
7072
+ if (utils.isPointInRect(x, y, scrollbar.track)) {
7007
7073
  return "track";
7008
7074
  }
7009
7075
  return void 0;
@@ -7102,8 +7168,6 @@ function scaleRectByZoom(rect, zoom) {
7102
7168
  height: rect.height * safeZoom
7103
7169
  };
7104
7170
  }
7105
-
7106
- // src/domain/columns/header-reorder.ts
7107
7171
  function resolveHeaderReorderTarget(pointerX, siblings, getBounds) {
7108
7172
  if (siblings.length === 0) {
7109
7173
  return null;
@@ -7130,7 +7194,7 @@ function resolveHeaderReorderTarget(pointerX, siblings, getBounds) {
7130
7194
  }
7131
7195
  }
7132
7196
  }
7133
- targetSiblingIndex = clamp2(targetSiblingIndex, 0, siblings.length);
7197
+ targetSiblingIndex = utils.clamp(targetSiblingIndex, 0, siblings.length);
7134
7198
  const targetIndicatorX = resolveTargetIndicatorX(
7135
7199
  siblings,
7136
7200
  targetSiblingIndex,
@@ -7721,8 +7785,6 @@ function createListTableAnimationRuntime() {
7721
7785
  carouselScrollAnimation: null
7722
7786
  };
7723
7787
  }
7724
-
7725
- // src/features/scroll/scroll-feature.ts
7726
7788
  var WHEEL_DELTA_MODE_PIXEL = 0;
7727
7789
  var WHEEL_DELTA_MODE_LINE = 1;
7728
7790
  var WHEEL_DELTA_MODE_PAGE = 2;
@@ -7817,7 +7879,7 @@ function stepScrollbarScroll(params) {
7817
7879
  if (area === "horizontal-scrollbar") {
7818
7880
  return {
7819
7881
  ...current,
7820
- left: clamp2(
7882
+ left: utils.clamp(
7821
7883
  current.left + direction * horizontalStep,
7822
7884
  0,
7823
7885
  viewport.maxScrollLeft
@@ -7826,7 +7888,7 @@ function stepScrollbarScroll(params) {
7826
7888
  }
7827
7889
  return {
7828
7890
  ...current,
7829
- top: clamp2(
7891
+ top: utils.clamp(
7830
7892
  current.top + direction * rowHeight,
7831
7893
  0,
7832
7894
  viewport.maxScrollTop
@@ -7836,7 +7898,7 @@ function stepScrollbarScroll(params) {
7836
7898
  function jumpScrollbarScroll(params) {
7837
7899
  const { current, axis, pointerValue, track, thumb, viewport } = params;
7838
7900
  if (axis === "horizontal") {
7839
- const nextThumbX = clamp2(
7901
+ const nextThumbX = utils.clamp(
7840
7902
  pointerValue - thumb.width / 2,
7841
7903
  track.x,
7842
7904
  track.x + track.width - thumb.width
@@ -7847,7 +7909,7 @@ function jumpScrollbarScroll(params) {
7847
7909
  left: ratio2 * viewport.maxScrollLeft
7848
7910
  };
7849
7911
  }
7850
- const nextThumbY = clamp2(
7912
+ const nextThumbY = utils.clamp(
7851
7913
  pointerValue - thumb.height / 2,
7852
7914
  track.y,
7853
7915
  track.y + track.height - thumb.height
@@ -7860,7 +7922,7 @@ function jumpScrollbarScroll(params) {
7860
7922
  }
7861
7923
  function dragScrollbarScroll(params) {
7862
7924
  const { current, dragging, pointerValue } = params;
7863
- const nextThumbValue = clamp2(
7925
+ const nextThumbValue = utils.clamp(
7864
7926
  pointerValue - dragging.pointerOffset,
7865
7927
  dragging.trackStart,
7866
7928
  dragging.trackStart + dragging.trackLength - dragging.thumbLength
@@ -7924,7 +7986,7 @@ function resolveVerticalCarouselScroll(params) {
7924
7986
  return {
7925
7987
  nextScroll: {
7926
7988
  ...current,
7927
- top: clamp2(current.top + Math.max(rowHeight, 1), 0, maxScrollTop)
7989
+ top: utils.clamp(current.top + Math.max(rowHeight, 1), 0, maxScrollTop)
7928
7990
  },
7929
7991
  animate: true,
7930
7992
  shouldStop: false
@@ -7951,7 +8013,7 @@ function resolveHorizontalCarouselScroll(params) {
7951
8013
  return {
7952
8014
  nextScroll: {
7953
8015
  ...current,
7954
- left: clamp2(nextLeft, 0, maxScrollLeft)
8016
+ left: utils.clamp(nextLeft, 0, maxScrollLeft)
7955
8017
  },
7956
8018
  animate: true,
7957
8019
  shouldStop: false
@@ -7962,7 +8024,7 @@ function resolveColumnBoundaries(columns, maxScrollLeft) {
7962
8024
  let offset = 0;
7963
8025
  columns.forEach((column) => {
7964
8026
  offset += Math.max(column.width, 0);
7965
- boundaries.push(clamp2(offset, 0, maxScrollLeft));
8027
+ boundaries.push(utils.clamp(offset, 0, maxScrollLeft));
7966
8028
  });
7967
8029
  return Array.from(new Set(boundaries)).filter((value) => value > 0);
7968
8030
  }
@@ -9246,74 +9308,321 @@ var ListTableCarouselController = class {
9246
9308
  });
9247
9309
  }
9248
9310
  };
9249
- function getCellClipboardText(record, rowIndex, column) {
9250
- const value = getValueByDataIndex(record, column.dataIndex);
9251
- const rendered = column.render?.(value, record, rowIndex, column);
9252
- if (rendered != null) {
9253
- return renderResultToClipboardText(rendered);
9311
+ var SUMMARY_ASYNC_BATCH_SIZE = 2e3;
9312
+ var SUMMARY_ASYNC_FRAME_BUDGET = 8;
9313
+ async function computeSummaryValuesAsync(params) {
9314
+ const { rows, columns, signal } = params;
9315
+ const summaryValues = /* @__PURE__ */ new Map();
9316
+ const accumulators = [];
9317
+ columns.forEach((column) => {
9318
+ const accumulator = createSummaryAccumulator(column);
9319
+ if (accumulator) {
9320
+ accumulators.push(accumulator);
9321
+ }
9322
+ });
9323
+ columns.forEach((column) => {
9324
+ if (column.summaryTitle != null) {
9325
+ summaryValues.set(column.key, column.summaryTitle);
9326
+ }
9327
+ });
9328
+ if (accumulators.length === 0) {
9329
+ return summaryValues;
9254
9330
  }
9255
- if (column.cellType === "checkbox" || column.cellType === "radio") {
9256
- return String(Boolean(value));
9331
+ for (let startIndex = 0; startIndex < rows.length; ) {
9332
+ if (signal?.aborted) {
9333
+ throw new Error("summary computation aborted");
9334
+ }
9335
+ const frameStart = now();
9336
+ let endIndex = startIndex;
9337
+ while (endIndex < rows.length) {
9338
+ if (signal?.aborted) {
9339
+ throw new Error("summary computation aborted");
9340
+ }
9341
+ const batchEndIndex = Math.min(
9342
+ endIndex + SUMMARY_ASYNC_BATCH_SIZE,
9343
+ rows.length
9344
+ );
9345
+ for (let rowIndex = endIndex; rowIndex < batchEndIndex; rowIndex += 1) {
9346
+ const record = rows[rowIndex];
9347
+ if (!record) {
9348
+ continue;
9349
+ }
9350
+ accumulators.forEach((item) => {
9351
+ updateSummaryAccumulator(item, record);
9352
+ });
9353
+ }
9354
+ endIndex = batchEndIndex;
9355
+ if (endIndex >= rows.length) {
9356
+ break;
9357
+ }
9358
+ if (now() - frameStart >= SUMMARY_ASYNC_FRAME_BUDGET) {
9359
+ break;
9360
+ }
9361
+ }
9362
+ if (endIndex < rows.length) {
9363
+ await yieldToMainThread();
9364
+ }
9365
+ startIndex = endIndex;
9257
9366
  }
9258
- return resolveFormattedCellText({
9367
+ accumulators.forEach((item) => {
9368
+ summaryValues.set(
9369
+ item.column.key,
9370
+ finalizeSummaryValue(item, rows)
9371
+ );
9372
+ });
9373
+ return summaryValues;
9374
+ }
9375
+ function createSummaryAccumulator(column) {
9376
+ const config = resolveSummaryConfig(column);
9377
+ if (!config) {
9378
+ return null;
9379
+ }
9380
+ return {
9259
9381
  column,
9260
- value,
9261
- record,
9262
- rowIndex
9263
- }) ?? String(value ?? "");
9382
+ config,
9383
+ type: config.type ?? "sum",
9384
+ valueCount: 0,
9385
+ numericCount: 0,
9386
+ sum: 0,
9387
+ min: null,
9388
+ max: null,
9389
+ uniqueValues: /* @__PURE__ */ new Set()
9390
+ };
9264
9391
  }
9265
- function createListTableSelectionCopyText(params) {
9266
- const columns = params.columns.filter(
9267
- (column2) => column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9392
+ function updateSummaryAccumulator(item, record) {
9393
+ if (item.column.summaryTitle != null) {
9394
+ return;
9395
+ }
9396
+ if (item.type === "rowCount" || item.type === "mergedRowCount") {
9397
+ return;
9398
+ }
9399
+ const rawValue = normalizeSummaryValue(
9400
+ getColumnRawValue(record, item.column, item.config)
9268
9401
  );
9269
- const columnRange = params.rangeHighlight.selectedColumnRange;
9270
- const rowRange = params.rangeHighlight.selectedRowRange;
9271
- const cellRange = params.rangeHighlight.selectedCellRange;
9272
- if (cellRange) {
9273
- const selectedColumns2 = params.columns.filter(
9274
- (column2, index) => index >= cellRange.startColumnIndex && index <= cellRange.endColumnIndex && column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9275
- );
9276
- return params.rows.slice(cellRange.startRowIndex, cellRange.endRowIndex + 1).map(
9277
- (record2, offset) => selectedColumns2.map(
9278
- (column2) => getCellClipboardText(
9279
- record2,
9280
- cellRange.startRowIndex + offset,
9281
- column2
9282
- )
9283
- ).join(" ")
9284
- ).join("\n");
9402
+ if (rawValue == null) {
9403
+ return;
9285
9404
  }
9286
- const mode = params.highlightMode ?? (rowRange && columnRange ? "cross" : rowRange ? "row" : "column");
9287
- const selectedColumns = columnRange ? params.columns.filter(
9288
- (column2, index) => index >= columnRange.start && index <= columnRange.end
9289
- ).filter(
9290
- (column2) => column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9291
- ) : columns;
9292
- rowRange ? Math.max(rowRange.start, 0) : 0;
9293
- rowRange ? Math.min(rowRange.end, params.rows.length - 1) : params.rows.length - 1;
9294
- if (mode === "column" && columnRange && params.selection.rowIndex == null) {
9295
- return params.rows.map(
9296
- (record2, rowIndex2) => selectedColumns.map((column2) => getCellClipboardText(record2, rowIndex2, column2)).join(" ")
9297
- ).join("\n");
9405
+ item.valueCount += 1;
9406
+ if (item.type === "unionCount") {
9407
+ item.uniqueValues.add(String(rawValue));
9408
+ return;
9298
9409
  }
9299
- const { rowIndex, columnKey } = params.selection;
9300
- const record = rowIndex == null ? void 0 : params.rows[rowIndex];
9301
- const column = columns.find((item) => item.key === columnKey);
9302
- return record && column && rowIndex != null ? getCellClipboardText(record, rowIndex, column) : null;
9410
+ if (item.type === "count") {
9411
+ return;
9412
+ }
9413
+ const numericValue = toNumber(rawValue);
9414
+ if (numericValue == null) {
9415
+ return;
9416
+ }
9417
+ item.numericCount += 1;
9418
+ item.sum += numericValue;
9419
+ item.min = item.min == null ? numericValue : Math.min(item.min, numericValue);
9420
+ item.max = item.max == null ? numericValue : Math.max(item.max, numericValue);
9303
9421
  }
9304
- function createListTableRangeCopyText(params) {
9305
- return createListTableSelectionCopyText({
9306
- rows: params.rows,
9307
- columns: params.columns,
9308
- selection: { rowIndex: null, columnKey: null },
9309
- rangeHighlight: {
9310
- selectedCellRange: {
9311
- startRowIndex: Math.max(
9312
- Math.min(params.startRowIndex, params.endRowIndex),
9313
- 0
9314
- ),
9315
- endRowIndex: Math.min(
9316
- Math.max(params.startRowIndex, params.endRowIndex),
9422
+ function finalizeSummaryValue(item, rows) {
9423
+ if (item.column.summaryTitle != null) {
9424
+ return item.column.summaryTitle;
9425
+ }
9426
+ if (item.type === "rowCount") {
9427
+ return formatSummaryOutput(item, String(rows.length), rows);
9428
+ }
9429
+ if (item.type === "mergedRowCount") {
9430
+ return formatSummaryOutput(item, String(countMergedRows(rows)), rows);
9431
+ }
9432
+ if (item.type === "count") {
9433
+ return formatSummaryOutput(item, String(item.valueCount), rows);
9434
+ }
9435
+ if (item.type === "unionCount") {
9436
+ return formatSummaryOutput(item, String(item.uniqueValues.size), rows);
9437
+ }
9438
+ if (item.numericCount === 0) {
9439
+ if (item.type === "min" || item.type === "max") {
9440
+ return formatSummaryOutput(item, "", rows);
9441
+ }
9442
+ return formatSummaryOutput(item, "0", rows);
9443
+ }
9444
+ let result = item.sum;
9445
+ if (item.type === "avg") {
9446
+ result = item.sum / item.numericCount;
9447
+ } else if (item.type === "min") {
9448
+ result = item.min ?? 0;
9449
+ } else if (item.type === "max") {
9450
+ result = item.max ?? 0;
9451
+ }
9452
+ const rounded = roundByPrecision(result, item.config.precision);
9453
+ const formatted = formatNumber(rounded, item.config.precision);
9454
+ return formatSummaryOutput(item, formatted, rows);
9455
+ }
9456
+ function resolveSummaryConfig(column) {
9457
+ if (column.summary == null) {
9458
+ return null;
9459
+ }
9460
+ if (column.summary === true) {
9461
+ return { type: "sum" };
9462
+ }
9463
+ if (column.summary === false) {
9464
+ return null;
9465
+ }
9466
+ return { type: "sum", ...column.summary };
9467
+ }
9468
+ function getColumnRawValue(record, column, config) {
9469
+ if (config.valueGetter) {
9470
+ return config.valueGetter(record);
9471
+ }
9472
+ const sortValue = column.sortValueGetter?.(record);
9473
+ if (sortValue != null && sortValue !== "") {
9474
+ return sortValue;
9475
+ }
9476
+ const filterValue = column.filterValueGetter?.(record);
9477
+ if (filterValue != null && filterValue !== "") {
9478
+ return filterValue;
9479
+ }
9480
+ return utils.getValueByDataIndex(record, column.dataIndex);
9481
+ }
9482
+ function normalizeSummaryValue(value) {
9483
+ if (value == null || value === "") {
9484
+ return null;
9485
+ }
9486
+ if (typeof value === "number" || typeof value === "string") {
9487
+ return value;
9488
+ }
9489
+ return null;
9490
+ }
9491
+ function toNumber(value) {
9492
+ if (value == null) {
9493
+ return null;
9494
+ }
9495
+ if (typeof value === "number") {
9496
+ return Number.isNaN(value) ? null : value;
9497
+ }
9498
+ const parsed = Number(String(value).trim());
9499
+ return Number.isNaN(parsed) ? null : parsed;
9500
+ }
9501
+ function roundByPrecision(value, precision) {
9502
+ if (precision == null) {
9503
+ return value;
9504
+ }
9505
+ return Number(value.toFixed(precision));
9506
+ }
9507
+ function formatNumber(value, precision) {
9508
+ if (precision != null) {
9509
+ return value.toFixed(precision);
9510
+ }
9511
+ if (Number.isInteger(value)) {
9512
+ return String(value);
9513
+ }
9514
+ return value.toFixed(2);
9515
+ }
9516
+ function formatSummaryOutput(item, value, rows) {
9517
+ if (item.config.formatter) {
9518
+ return item.config.formatter(
9519
+ value,
9520
+ rows,
9521
+ item.column
9522
+ );
9523
+ }
9524
+ return value;
9525
+ }
9526
+ function countMergedRows(rows) {
9527
+ return rows.reduce((count, record) => {
9528
+ if (record == null || typeof record !== "object") {
9529
+ return count + 1;
9530
+ }
9531
+ const rowSpan = record.rowSpan;
9532
+ if (typeof rowSpan !== "number") {
9533
+ return count + 1;
9534
+ }
9535
+ return rowSpan > 0 ? count + 1 : count;
9536
+ }, 0);
9537
+ }
9538
+ function yieldToMainThread() {
9539
+ return new Promise((resolve) => {
9540
+ if (typeof requestAnimationFrame === "function") {
9541
+ requestAnimationFrame(() => resolve());
9542
+ return;
9543
+ }
9544
+ setTimeout(resolve, 0);
9545
+ });
9546
+ }
9547
+ function now() {
9548
+ if (typeof performance !== "undefined" && typeof performance.now === "function") {
9549
+ return performance.now();
9550
+ }
9551
+ return Date.now();
9552
+ }
9553
+
9554
+ // src/services/clipboard-service.ts
9555
+ function getCellClipboardText(record, rowIndex, column) {
9556
+ const value = utils.getValueByDataIndex(record, column.dataIndex);
9557
+ const rendered = column.render?.(value, record, rowIndex, column);
9558
+ if (rendered != null) {
9559
+ return renderResultToClipboardText(rendered);
9560
+ }
9561
+ if (column.dataFormat && column.dataFormat !== "default") {
9562
+ return formatListTableDataValue(value, column.dataFormat);
9563
+ }
9564
+ if (column.cellType === "checkbox" || column.cellType === "radio") {
9565
+ return String(Boolean(value));
9566
+ }
9567
+ return resolveFormattedCellText({
9568
+ column,
9569
+ value,
9570
+ record,
9571
+ rowIndex
9572
+ }) ?? String(value ?? "");
9573
+ }
9574
+ function createListTableSelectionCopyText(params) {
9575
+ const columns = params.columns.filter(
9576
+ (column2) => column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9577
+ );
9578
+ const columnRange = params.rangeHighlight.selectedColumnRange;
9579
+ const rowRange = params.rangeHighlight.selectedRowRange;
9580
+ const cellRange = params.rangeHighlight.selectedCellRange;
9581
+ if (cellRange) {
9582
+ const selectedColumns2 = params.columns.filter(
9583
+ (column2, index) => index >= cellRange.startColumnIndex && index <= cellRange.endColumnIndex && column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9584
+ );
9585
+ return params.rows.slice(cellRange.startRowIndex, cellRange.endRowIndex + 1).map(
9586
+ (record2, offset) => selectedColumns2.map(
9587
+ (column2) => getCellClipboardText(
9588
+ record2,
9589
+ cellRange.startRowIndex + offset,
9590
+ column2
9591
+ )
9592
+ ).join(" ")
9593
+ ).join("\n");
9594
+ }
9595
+ const mode = params.highlightMode ?? (rowRange && columnRange ? "cross" : rowRange ? "row" : "column");
9596
+ const selectedColumns = columnRange ? params.columns.filter(
9597
+ (column2, index) => index >= columnRange.start && index <= columnRange.end
9598
+ ).filter(
9599
+ (column2) => column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9600
+ ) : columns;
9601
+ rowRange ? Math.max(rowRange.start, 0) : 0;
9602
+ rowRange ? Math.min(rowRange.end, params.rows.length - 1) : params.rows.length - 1;
9603
+ if (mode === "column" && columnRange && params.selection.rowIndex == null) {
9604
+ return params.rows.map(
9605
+ (record2, rowIndex2) => selectedColumns.map((column2) => getCellClipboardText(record2, rowIndex2, column2)).join(" ")
9606
+ ).join("\n");
9607
+ }
9608
+ const { rowIndex, columnKey } = params.selection;
9609
+ const record = rowIndex == null ? void 0 : params.rows[rowIndex];
9610
+ const column = columns.find((item) => item.key === columnKey);
9611
+ return record && column && rowIndex != null ? getCellClipboardText(record, rowIndex, column) : null;
9612
+ }
9613
+ function createListTableRangeCopyText(params) {
9614
+ return createListTableSelectionCopyText({
9615
+ rows: params.rows,
9616
+ columns: params.columns,
9617
+ selection: { rowIndex: null, columnKey: null },
9618
+ rangeHighlight: {
9619
+ selectedCellRange: {
9620
+ startRowIndex: Math.max(
9621
+ Math.min(params.startRowIndex, params.endRowIndex),
9622
+ 0
9623
+ ),
9624
+ endRowIndex: Math.min(
9625
+ Math.max(params.startRowIndex, params.endRowIndex),
9317
9626
  Math.max(params.rows.length - 1, 0)
9318
9627
  ),
9319
9628
  startColumnIndex: Math.max(
@@ -9412,10 +9721,31 @@ async function exportAllRowsTxtContent(params) {
9412
9721
  });
9413
9722
  }
9414
9723
  async function exportAllRowsXlsxContent(params) {
9724
+ const columns = params.columns.filter(
9725
+ (column) => column.key !== ROW_SELECTION_COLUMN_KEY
9726
+ );
9727
+ const rows = params.rows.map((record, rowIndex) => ({
9728
+ type: "data",
9729
+ record,
9730
+ rowIndex
9731
+ }));
9732
+ if (params.includeSummary) {
9733
+ rows.push({
9734
+ type: "summary",
9735
+ values: await computeSummaryValuesAsync({
9736
+ rows: params.rows,
9737
+ columns
9738
+ })
9739
+ });
9740
+ }
9415
9741
  await utils.exportTableToXlsx({
9416
- fileName: buildTableExportFileName("xlsx"),
9417
- rows: params.rows,
9418
- columns: buildExportColumns(params.columns),
9742
+ fileName: params.fileName?.trim() || buildTableExportFileName("xlsx"),
9743
+ rows,
9744
+ columns: columns.map((column) => ({
9745
+ key: column.key,
9746
+ title: column.title ?? column.key,
9747
+ value: (row) => row.type === "summary" ? row.values.get(column.key) ?? "" : getCellClipboardText(row.record, row.rowIndex, column)
9748
+ })),
9419
9749
  sheetName: "TableData"
9420
9750
  });
9421
9751
  }
@@ -9668,11 +9998,12 @@ var ListTableContentActionController = class {
9668
9998
  /**
9669
9999
  * 异步导出全部原始数据为 XLSX。
9670
10000
  */
9671
- exportXlsx() {
10001
+ exportXlsx(options) {
9672
10002
  this.startExportTask(
9673
10003
  () => exportAllRowsXlsxContent({
9674
10004
  rows: this.options.getOptions().dataSource,
9675
- columns: this.options.getLeafColumns()
10005
+ columns: this.options.getLeafColumns(),
10006
+ ...options
9676
10007
  }),
9677
10008
  "\u6B63\u5728\u5BFC\u51FA XLSX\u2026"
9678
10009
  );
@@ -9832,7 +10163,7 @@ async function validateTableCells(params) {
9832
10163
  continue;
9833
10164
  }
9834
10165
  visited.add(stateKey);
9835
- const value = column.dataIndex == null ? void 0 : getValueByDataIndex(record, column.dataIndex);
10166
+ const value = column.dataIndex == null ? void 0 : utils.getValueByDataIndex(record, column.dataIndex);
9836
10167
  const message = await validateCellValue(column, {
9837
10168
  value,
9838
10169
  record,
@@ -9891,7 +10222,7 @@ function resolveValidationTargetsForChange(params) {
9891
10222
  return;
9892
10223
  }
9893
10224
  const dependencies = resolveFormItemProps(column, {
9894
- value: column.dataIndex == null ? void 0 : getValueByDataIndex(record, column.dataIndex),
10225
+ value: column.dataIndex == null ? void 0 : utils.getValueByDataIndex(record, column.dataIndex),
9895
10226
  record,
9896
10227
  rowIndex
9897
10228
  })?.dependencies;
@@ -9986,7 +10317,7 @@ function openCellEditingSession(params) {
9986
10317
  if (!column || !record) {
9987
10318
  return null;
9988
10319
  }
9989
- const currentValue = column.dataIndex == null ? void 0 : getValueByDataIndex(record, column.dataIndex);
10320
+ const currentValue = column.dataIndex == null ? void 0 : utils.getValueByDataIndex(record, column.dataIndex);
9990
10321
  if (!canEditCell(column, {
9991
10322
  value: currentValue,
9992
10323
  record,
@@ -10518,8 +10849,6 @@ var ListTableEditingController = class {
10518
10849
  this.validationMessages = /* @__PURE__ */ new Map();
10519
10850
  }
10520
10851
  };
10521
-
10522
- // src/features/column-resize/column-resize-feature.ts
10523
10852
  function startColumnResizeDrag(params) {
10524
10853
  const { options, leafColumns, columnKey, pointerX } = params;
10525
10854
  for (const leaf of leafColumns) {
@@ -10541,7 +10870,7 @@ function updateColumnResizeDrag(params) {
10541
10870
  const { dragging, pointerX, leafColumns, options } = params;
10542
10871
  const dx = pointerX - dragging.startX;
10543
10872
  const nextWidth = Math.round(
10544
- clamp2(dragging.startWidth + dx, dragging.minWidth, dragging.maxWidth)
10873
+ utils.clamp(dragging.startWidth + dx, dragging.minWidth, dragging.maxWidth)
10545
10874
  );
10546
10875
  const column = leafColumns.find((item) => item.key === dragging.columnKey);
10547
10876
  if (!column || column.width === nextWidth) {
@@ -10679,6 +11008,14 @@ function createListTableContextMenuActions(params) {
10679
11008
  onChangeSummaryPrecision: params.onChangeSummaryPrecision ? (columnKey, precision) => {
10680
11009
  params.hideMenu();
10681
11010
  params.onChangeSummaryPrecision?.(columnKey, precision);
11011
+ } : void 0,
11012
+ onChangeAlignment: params.onChangeAlignment ? (columnKey, area, axis, value) => {
11013
+ params.hideMenu();
11014
+ params.onChangeAlignment?.(columnKey, area, axis, value);
11015
+ } : void 0,
11016
+ onChangeDataFormat: params.onChangeDataFormat ? (columnKey, dataFormat) => {
11017
+ params.hideMenu();
11018
+ params.onChangeDataFormat?.(columnKey, dataFormat);
10682
11019
  } : void 0
10683
11020
  };
10684
11021
  }
@@ -10715,7 +11052,10 @@ function buildListTableContextMenuConfig(params) {
10715
11052
  const enableReset = enabledFeatures.has("reset");
10716
11053
  const enableDensity = enabledFeatures.has("density");
10717
11054
  const enableZoom = enabledFeatures.has("zoom");
11055
+ const enableAlignment = enabledFeatures.has("alignment");
11056
+ const enableDataFormat = enabledFeatures.has("dataFormat");
10718
11057
  const enableColumnVisibility = enabledFeatures.has("columnVisibility");
11058
+ const presentation = isHeaderArea ? getColumnPresentationConfig(columns, columnKey) : null;
10719
11059
  const headerItems = isHeaderArea && (enableColumnVisibility || enableColumnCollapse) ? buildHeaderSettingsItems(columns) : void 0;
10720
11060
  const currentColumnItem = headerItems ? findHeaderColumnItem(headerItems, columnKey) : null;
10721
11061
  const canToggleCurrentColumn = enableColumnCollapse && isHeaderArea && !isSelectionColumn && currentColumnItem != null && !currentColumnItem.disabled;
@@ -10726,7 +11066,7 @@ function buildListTableContextMenuConfig(params) {
10726
11066
  };
10727
11067
  if (isSummaryArea && !isSelectionColumn && actions.onChangeSummaryType) {
10728
11068
  const column = findSummaryColumn(columns, columnKey);
10729
- const summary = resolveSummaryConfig(column?.summary);
11069
+ const summary = resolveSummaryConfig2(column?.summary);
10730
11070
  summaryConfig.summaryColumnKey = columnKey;
10731
11071
  summaryConfig.summaryType = summary?.type ?? "sum";
10732
11072
  summaryConfig.summaryPrecision = summary?.precision;
@@ -10805,11 +11145,20 @@ function buildListTableContextMenuConfig(params) {
10805
11145
  onChangeDensity: enableDensity ? actions.onChangeDensity : void 0,
10806
11146
  onChangeZoom: enableZoom ? actions.onChangeZoom : void 0,
10807
11147
  onToggleColumn: enableColumnVisibility && isHeaderArea ? actions.onToggleColumn : void 0,
11148
+ alignment: enableAlignment && presentation ? {
11149
+ headerHorizontal: presentation.headerHorizontal,
11150
+ headerVertical: presentation.headerVertical,
11151
+ bodyHorizontal: presentation.bodyHorizontal,
11152
+ bodyVertical: presentation.bodyVertical
11153
+ } : void 0,
11154
+ onChangeAlignment: enableAlignment && isHeaderArea && actions.onChangeAlignment ? (area, axis, value) => actions.onChangeAlignment?.(columnKey, area, axis, value) : void 0,
11155
+ dataFormat: enableDataFormat && presentation?.dataFormatAvailable ? presentation.dataFormat : void 0,
11156
+ onChangeDataFormat: enableDataFormat && presentation?.dataFormatAvailable && actions.onChangeDataFormat ? (dataFormat) => actions.onChangeDataFormat?.(columnKey, dataFormat) : void 0,
10808
11157
  onClose: actions.onClose,
10809
11158
  ...summaryConfig
10810
11159
  };
10811
11160
  }
10812
- function resolveSummaryConfig(summary) {
11161
+ function resolveSummaryConfig2(summary) {
10813
11162
  if (summary === true) {
10814
11163
  return { type: "sum" };
10815
11164
  }
@@ -10840,6 +11189,8 @@ var DEFAULT_CONTEXT_MENU_FEATURES = [
10840
11189
  "reset",
10841
11190
  "density",
10842
11191
  "zoom",
11192
+ "alignment",
11193
+ "dataFormat",
10843
11194
  "columnVisibility"
10844
11195
  ];
10845
11196
  function resolveEnabledContextMenuFeatures(contextMenu) {
@@ -10898,7 +11249,7 @@ function resolveColumnFilterValue(record, column) {
10898
11249
  if (column.filterValueGetter) {
10899
11250
  return column.filterValueGetter(record);
10900
11251
  }
10901
- const value = getValueByDataIndex(record, column.dataIndex);
11252
+ const value = utils.getValueByDataIndex(record, column.dataIndex);
10902
11253
  if (value !== void 0) {
10903
11254
  return value;
10904
11255
  }
@@ -10932,7 +11283,7 @@ function resolveColumnFilterOptionValue(record, column) {
10932
11283
  return serializeFilterOptionValue(column.filterOptionValueGetter(record));
10933
11284
  }
10934
11285
  if (column.filterOptions?.length) {
10935
- const rawValue = getValueByDataIndex(record, column.dataIndex) ?? record[column.key];
11286
+ const rawValue = utils.getValueByDataIndex(record, column.dataIndex) ?? record[column.key];
10936
11287
  if (rawValue !== void 0) {
10937
11288
  return serializeFilterOptionValue(rawValue);
10938
11289
  }
@@ -11247,7 +11598,7 @@ async function filterRowsAsync(params) {
11247
11598
  }
11248
11599
  }
11249
11600
  if (endIndex < rows.length) {
11250
- await yieldToMainThread();
11601
+ await yieldToMainThread2();
11251
11602
  }
11252
11603
  }
11253
11604
  return result;
@@ -11315,7 +11666,7 @@ async function getColumnFilterOptionsAsync(params) {
11315
11666
  optionCountMap.set(value, (optionCountMap.get(value) ?? 0) + 1);
11316
11667
  }
11317
11668
  if (endIndex < dataSource.length) {
11318
- await yieldToMainThread();
11669
+ await yieldToMainThread2();
11319
11670
  }
11320
11671
  }
11321
11672
  const optionItems = explicitOptions.length > 0 ? explicitOptions.map((item) => ({
@@ -11351,7 +11702,7 @@ async function getColumnFilterOptionsAsync(params) {
11351
11702
  ...optionItems
11352
11703
  ];
11353
11704
  }
11354
- function yieldToMainThread() {
11705
+ function yieldToMainThread2() {
11355
11706
  return new Promise((resolve) => {
11356
11707
  setTimeout(resolve, 0);
11357
11708
  });
@@ -11584,6 +11935,8 @@ function showHeaderContextMenu(params) {
11584
11935
  onToggleSummary,
11585
11936
  onChangeSummaryType,
11586
11937
  onChangeSummaryPrecision,
11938
+ onChangeAlignment,
11939
+ onChangeDataFormat,
11587
11940
  summaryVisible,
11588
11941
  getSelectionRange,
11589
11942
  onCopySelection,
@@ -11658,6 +12011,8 @@ function showHeaderContextMenu(params) {
11658
12011
  onToggleSummary,
11659
12012
  onChangeSummaryType,
11660
12013
  onChangeSummaryPrecision,
12014
+ onChangeAlignment,
12015
+ onChangeDataFormat,
11661
12016
  onCopySelection,
11662
12017
  onCopyCustomSelection
11663
12018
  })
@@ -12041,8 +12396,6 @@ function moveRowDrag(params) {
12041
12396
  function endRowDragSession() {
12042
12397
  return createIdleRowDragSession();
12043
12398
  }
12044
-
12045
- // src/features/row-drag/row-drag-insertion.ts
12046
12399
  function resolveRowDragInsertionPosition(params) {
12047
12400
  const bodyTop = Math.max(params.bodyTop, 0);
12048
12401
  const bodyBottom = Math.max(params.bodyBottom, bodyTop);
@@ -12059,15 +12412,15 @@ function resolveRowDragInsertionPosition(params) {
12059
12412
  for (const row of rowRects) {
12060
12413
  if (params.pointerY <= (row.top + row.bottom) / 2) {
12061
12414
  return {
12062
- insertIndex: clamp3(row.rowIndex, 0, rowCount),
12063
- indicatorY: clamp3(row.top, bodyTop, bodyBottom)
12415
+ insertIndex: utils.clamp(row.rowIndex, 0, rowCount),
12416
+ indicatorY: utils.clamp(row.top, bodyTop, bodyBottom)
12064
12417
  };
12065
12418
  }
12066
12419
  }
12067
12420
  const lastRow = rowRects[rowRects.length - 1];
12068
12421
  return {
12069
- insertIndex: clamp3(lastRow.rowIndex + 1, 0, rowCount),
12070
- indicatorY: clamp3(lastRow.bottom, bodyTop, bodyBottom)
12422
+ insertIndex: utils.clamp(lastRow.rowIndex + 1, 0, rowCount),
12423
+ indicatorY: utils.clamp(lastRow.bottom, bodyTop, bodyBottom)
12071
12424
  };
12072
12425
  }
12073
12426
  function resolveVisibleRowRects(descriptors) {
@@ -12090,9 +12443,6 @@ function resolveVisibleRowRects(descriptors) {
12090
12443
  }
12091
12444
  return Array.from(rows.values());
12092
12445
  }
12093
- function clamp3(value, min, max) {
12094
- return Math.min(Math.max(value, min), max);
12095
- }
12096
12446
 
12097
12447
  // src/services/row-drag-bus.ts
12098
12448
  var RowDragBus = class {
@@ -12678,8 +13028,8 @@ var ListTableRowDragController = class {
12678
13028
  const pointer = this.potentialPointer ?? fallbackPointer;
12679
13029
  return {
12680
13030
  dataUrl,
12681
- grabOffsetX: clamp4((pointer.x - rect.x) * zoom, 0, rect.width * zoom),
12682
- grabOffsetY: clamp4((pointer.y - rect.y) * zoom, 0, rect.height * zoom)
13031
+ grabOffsetX: utils.clamp((pointer.x - rect.x) * zoom, 0, rect.width * zoom),
13032
+ grabOffsetY: utils.clamp((pointer.y - rect.y) * zoom, 0, rect.height * zoom)
12683
13033
  };
12684
13034
  }
12685
13035
  showPreview(capture, clientX, clientY) {
@@ -12916,9 +13266,6 @@ function structuredCloneSafe(value) {
12916
13266
  return value;
12917
13267
  }
12918
13268
  }
12919
- function clamp4(value, min, max) {
12920
- return Math.min(Math.max(value, min), max);
12921
- }
12922
13269
  function resolveValidZoom(value) {
12923
13270
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 1;
12924
13271
  }
@@ -13280,7 +13627,7 @@ var ListTableEventController = class {
13280
13627
  (item) => item.key === result.columnKey
13281
13628
  );
13282
13629
  const record = this.host.getDisplayData()[result.rowIndex];
13283
- const value = column && record && column.dataIndex != null ? getValueByDataIndex(record, column.dataIndex) : void 0;
13630
+ const value = column && record && column.dataIndex != null ? utils.getValueByDataIndex(record, column.dataIndex) : void 0;
13284
13631
  if (!record || !shouldOpenCellEditorOnClick(column, 2, {
13285
13632
  value,
13286
13633
  record,
@@ -13429,19 +13776,55 @@ var ListTableEventController = class {
13429
13776
  this.host.render();
13430
13777
  },
13431
13778
  onChangeSummaryType: (columnKey, type) => {
13432
- updateSummaryColumn(this.host.options.columns, columnKey, (summary) => ({
13433
- ...summary,
13434
- type
13435
- }));
13779
+ updateSummaryColumn(
13780
+ this.host.options.columns,
13781
+ columnKey,
13782
+ (summary) => ({
13783
+ ...summary,
13784
+ type
13785
+ })
13786
+ );
13436
13787
  this.host.refreshRuntimeColumns();
13437
13788
  this.host.persistColumnConfig();
13438
13789
  this.host.render();
13439
13790
  },
13440
13791
  onChangeSummaryPrecision: (columnKey, precision) => {
13441
- updateSummaryColumn(this.host.options.columns, columnKey, (summary) => ({
13442
- ...summary,
13443
- precision
13444
- }));
13792
+ updateSummaryColumn(
13793
+ this.host.options.columns,
13794
+ columnKey,
13795
+ (summary) => ({
13796
+ ...summary,
13797
+ precision
13798
+ })
13799
+ );
13800
+ this.host.refreshRuntimeColumns();
13801
+ this.host.persistColumnConfig();
13802
+ this.host.render();
13803
+ },
13804
+ onChangeAlignment: (columnKey, area, axis, value) => {
13805
+ const updated = setColumnAlignment({
13806
+ columns: this.host.options.columns,
13807
+ columnKey,
13808
+ area,
13809
+ axis,
13810
+ value
13811
+ });
13812
+ if (!updated) {
13813
+ return;
13814
+ }
13815
+ this.host.refreshRuntimeColumns();
13816
+ this.host.persistColumnConfig();
13817
+ this.host.render();
13818
+ },
13819
+ onChangeDataFormat: (columnKey, dataFormat) => {
13820
+ const updated = setColumnDataFormat(
13821
+ this.host.options.columns,
13822
+ columnKey,
13823
+ dataFormat
13824
+ );
13825
+ if (!updated) {
13826
+ return;
13827
+ }
13445
13828
  this.host.refreshRuntimeColumns();
13446
13829
  this.host.persistColumnConfig();
13447
13830
  this.host.render();
@@ -13611,7 +13994,7 @@ var ListTableEventController = class {
13611
13994
  (item) => item.key === result.columnKey
13612
13995
  );
13613
13996
  const record = this.host.getDisplayData()[result.rowIndex];
13614
- const value = column && record && column.dataIndex != null ? getValueByDataIndex(record, column.dataIndex) : void 0;
13997
+ const value = column && record && column.dataIndex != null ? utils.getValueByDataIndex(record, column.dataIndex) : void 0;
13615
13998
  if (record && shouldOpenCellEditorOnClick(column, 1, {
13616
13999
  value,
13617
14000
  record,
@@ -13816,7 +14199,7 @@ var ListTableEventController = class {
13816
14199
  const columnKey = this.host.selection.columnKey;
13817
14200
  const column = this.host.leafColumns.find((item) => item.key === columnKey);
13818
14201
  const record = this.host.getDisplayData()[rowIndex];
13819
- const value = column && record && column.dataIndex != null ? getValueByDataIndex(record, column.dataIndex) : void 0;
14202
+ const value = column && record && column.dataIndex != null ? utils.getValueByDataIndex(record, column.dataIndex) : void 0;
13820
14203
  if (!column || !record || !canEditCell(column, { value, record, rowIndex })) {
13821
14204
  return;
13822
14205
  }
@@ -13908,7 +14291,10 @@ var ListTableEventController = class {
13908
14291
  const width = snapshot?.width ?? this.host.canvasElement.width;
13909
14292
  const position = {
13910
14293
  x: Math.min(Math.max(pointer.x, 0), Math.max(width - 1, 0)),
13911
- y: Math.min(Math.max(pointer.y, bodyTop + 1), Math.max(bodyBottom - 1, bodyTop + 1))
14294
+ y: Math.min(
14295
+ Math.max(pointer.y, bodyTop + 1),
14296
+ Math.max(bodyBottom - 1, bodyTop + 1)
14297
+ )
13912
14298
  };
13913
14299
  const result = this.host.resolvePointerHit(position.x, position.y);
13914
14300
  if (result.area !== "body" && result.area !== "body-content" || typeof result.rowIndex !== "number" || !result.columnKey) {
@@ -14893,6 +15279,27 @@ function applyStoredColumnConfig(columns, storedColumns) {
14893
15279
  if (stored) {
14894
15280
  col.width = stored.width;
14895
15281
  col.hidden = !!stored.hidden;
15282
+ if ("align" in stored) {
15283
+ col.align = stored.align;
15284
+ }
15285
+ if ("headerAlign" in stored) {
15286
+ col.headerAlign = stored.headerAlign;
15287
+ }
15288
+ if ("verticalAlign" in stored) {
15289
+ col.cellStyle = {
15290
+ ...col.cellStyle,
15291
+ verticalAlign: stored.verticalAlign
15292
+ };
15293
+ }
15294
+ if ("headerVerticalAlign" in stored) {
15295
+ col.headerStyle = {
15296
+ ...col.headerStyle,
15297
+ verticalAlign: stored.headerVerticalAlign
15298
+ };
15299
+ }
15300
+ if ("dataFormat" in stored) {
15301
+ col.dataFormat = stored.dataFormat;
15302
+ }
14896
15303
  if (stored.fixed) {
14897
15304
  col.fixed = stored.fixed;
14898
15305
  } else {
@@ -14926,6 +15333,11 @@ function buildStoredColumnConfig(columns, sortState, filterState, zoom, summaryR
14926
15333
  width: col.width ?? 160,
14927
15334
  fixed: col.fixed,
14928
15335
  hidden: !!col.hidden,
15336
+ ...col.align ? { align: col.align } : null,
15337
+ ...col.cellStyle?.verticalAlign ? { verticalAlign: col.cellStyle.verticalAlign } : null,
15338
+ ...col.headerAlign ? { headerAlign: col.headerAlign } : null,
15339
+ ...col.headerStyle?.verticalAlign ? { headerVerticalAlign: col.headerStyle.verticalAlign } : null,
15340
+ ...col.dataFormat ? { dataFormat: col.dataFormat } : null,
14929
15341
  summary: col.summary === true ? { type: "sum" } : col.summary ? {
14930
15342
  type: col.summary.type,
14931
15343
  precision: col.summary.precision
@@ -15245,7 +15657,7 @@ function buildHeaderNode(column, leafColumns, maxDepth) {
15245
15657
  rowSpan: 1,
15246
15658
  leafStartIndex,
15247
15659
  leafEndIndex,
15248
- align: column.align ?? "left",
15660
+ align: column.headerAlign ?? column.align ?? "left",
15249
15661
  fixed: column.fixed,
15250
15662
  style: column.headerStyle,
15251
15663
  column,
@@ -15263,7 +15675,7 @@ function buildHeaderNode(column, leafColumns, maxDepth) {
15263
15675
  rowSpan: maxDepth - column.depth + 1,
15264
15676
  leafStartIndex: leafIndex,
15265
15677
  leafEndIndex: leafIndex,
15266
- align: column.align ?? "left",
15678
+ align: column.headerAlign ?? column.align ?? "left",
15267
15679
  fixed: column.fixed,
15268
15680
  style: column.headerStyle,
15269
15681
  column,
@@ -15410,8 +15822,6 @@ function computeScrollbarLayout(params) {
15410
15822
  }
15411
15823
  return layout;
15412
15824
  }
15413
-
15414
- // src/domain/layout/compute-viewport.ts
15415
15825
  function computeViewport(params) {
15416
15826
  const bodyHeight = Math.max(
15417
15827
  params.bodyHeight ?? params.height - params.headerHeight,
@@ -15441,15 +15851,12 @@ function computeViewport(params) {
15441
15851
  return {
15442
15852
  viewport,
15443
15853
  scroll: {
15444
- left: clamp5(params.scroll.left, 0, resolvedMaxScrollLeft),
15445
- top: clamp5(params.scroll.top, 0, resolvedMaxScrollTop)
15854
+ left: utils.clamp(params.scroll.left, 0, resolvedMaxScrollLeft),
15855
+ top: utils.clamp(params.scroll.top, 0, resolvedMaxScrollTop)
15446
15856
  },
15447
15857
  centerVisibleWidth
15448
15858
  };
15449
15859
  }
15450
- function clamp5(value, min, max) {
15451
- return Math.min(Math.max(value, min), max);
15452
- }
15453
15860
 
15454
15861
  // src/domain/rows/body-layout.ts
15455
15862
  function resolveBodyLayout(params) {
@@ -16550,7 +16957,7 @@ function resolveSummaryTextX(params) {
16550
16957
  const maxX = visibleRect.x + visibleRect.width - padding;
16551
16958
  const preferredX = getAlignedTextX(rect, align, padding);
16552
16959
  if (align === "center") {
16553
- return clamp6(preferredX, minX, maxX);
16960
+ return utils.clamp(preferredX, minX, maxX);
16554
16961
  }
16555
16962
  if (align === "right") {
16556
16963
  return Math.max(Math.min(preferredX, maxX), minX);
@@ -16592,9 +16999,6 @@ function intersectRects2(left, right) {
16592
16999
  height: maxY - y
16593
17000
  };
16594
17001
  }
16595
- function clamp6(value, min, max) {
16596
- return Math.min(Math.max(value, min), max);
16597
- }
16598
17002
  function isIndexInHighlightRange2(index, range) {
16599
17003
  return Boolean(range && index >= range.start && index <= range.end);
16600
17004
  }
@@ -17306,7 +17710,7 @@ function buildMergedBodyCells(rows, columns, mergeCell, rowIndexMap) {
17306
17710
  if (!column || covered.has(coverKey)) {
17307
17711
  continue;
17308
17712
  }
17309
- const value = getValueByDataIndex(record, column.dataIndex);
17713
+ const value = utils.getValueByDataIndex(record, column.dataIndex);
17310
17714
  const spanConfig = spanConfigMap.get(getCellCoverKey(rowIndex, column.key)) ?? column.onCell?.(value, record, sourceRowIndex, column);
17311
17715
  const hasExplicitRowSpan = hasExplicitSpan(spanConfig, "rowSpan");
17312
17716
  const hasExplicitColSpan = hasExplicitSpan(spanConfig, "colSpan");
@@ -17397,7 +17801,7 @@ function buildSpanConfigMap(rows, columns, rowIndexMap) {
17397
17801
  rows.forEach((record, rowIndex) => {
17398
17802
  const sourceRowIndex = rowIndexMap?.[rowIndex] ?? rowIndex;
17399
17803
  columns.forEach((column) => {
17400
- const value = getValueByDataIndex(record, column.dataIndex);
17804
+ const value = utils.getValueByDataIndex(record, column.dataIndex);
17401
17805
  spanConfigMap.set(
17402
17806
  getCellCoverKey(rowIndex, column.key),
17403
17807
  column.onCell?.(value, record, sourceRowIndex, column)
@@ -17479,7 +17883,7 @@ function buildAutoColSpanMap(rows, columns, keys, spanConfigMap) {
17479
17883
  columnIndex += 1;
17480
17884
  continue;
17481
17885
  }
17482
- const currentValue = getValueByDataIndex(record, column.dataIndex);
17886
+ const currentValue = utils.getValueByDataIndex(record, column.dataIndex);
17483
17887
  let colSpan = 1;
17484
17888
  for (let index = columnIndex + 1; index < columns.length; index += 1) {
17485
17889
  if (!targetColumnIndexes.has(index)) {
@@ -17493,7 +17897,7 @@ function buildAutoColSpanMap(rows, columns, keys, spanConfigMap) {
17493
17897
  if (hasExplicitSpan(spanConfigMap.get(nextCellKey), "colSpan")) {
17494
17898
  break;
17495
17899
  }
17496
- const nextValue = getValueByDataIndex(record, nextColumn.dataIndex);
17900
+ const nextValue = utils.getValueByDataIndex(record, nextColumn.dataIndex);
17497
17901
  if (!isSameMergeValue(currentValue, nextValue)) {
17498
17902
  break;
17499
17903
  }
@@ -17519,7 +17923,7 @@ function getTargetMergeColumns(columns, keys) {
17519
17923
  return [];
17520
17924
  }
17521
17925
  return columns.filter(
17522
- (column) => keys.some((key) => isSameDataIndex2(column.dataIndex, key))
17926
+ (column) => keys.some((key) => utils.isSameDataIndex(column.dataIndex, key))
17523
17927
  );
17524
17928
  }
17525
17929
  function getCellCoverKey(rowIndex, columnKey) {
@@ -17538,7 +17942,7 @@ function getMergeGroupKey(record, keys) {
17538
17942
  if (!keys?.length) {
17539
17943
  return "";
17540
17944
  }
17541
- return keys.map((key) => normalizeMergeValue(getValueByDataIndex(record, key))).join("|");
17945
+ return keys.map((key) => normalizeMergeValue(utils.getValueByDataIndex(record, key))).join("|");
17542
17946
  }
17543
17947
  function normalizeMergeValue(value) {
17544
17948
  if (value == null) {
@@ -17552,14 +17956,6 @@ function normalizeMergeValue(value) {
17552
17956
  function isSameMergeValue(left, right) {
17553
17957
  return normalizeMergeValue(left) === normalizeMergeValue(right);
17554
17958
  }
17555
- function isSameDataIndex2(left, right) {
17556
- const leftPath = Array.isArray(left) ? left : [left];
17557
- const rightPath = Array.isArray(right) ? right : [right];
17558
- if (leftPath.length !== rightPath.length) {
17559
- return false;
17560
- }
17561
- return leftPath.every((key, index) => key === rightPath[index]);
17562
- }
17563
17959
  function getMergedCellWidth(columns, startIndex, colSpan) {
17564
17960
  let width = 0;
17565
17961
  for (let index = startIndex; index < startIndex + colSpan; index += 1) {
@@ -18324,8 +18720,6 @@ function isDragSourceColumn3(column, dragReorder) {
18324
18720
  }
18325
18721
  return column.leafIndex >= dragReorder.sourceLeafStartIndex && column.leafIndex <= dragReorder.sourceLeafEndIndex;
18326
18722
  }
18327
-
18328
- // src/rendering/primitives/header-text-layout.ts
18329
18723
  var ACTION_GAP = 4;
18330
18724
  var ACTION_SIZE = 14;
18331
18725
  var ACTION_PADDING_INLINE = 10;
@@ -18417,16 +18811,13 @@ function getStickyTextX(rect, visibleRect, align, padding) {
18417
18811
  const maxX = visibleRect.x + visibleRect.width - padding;
18418
18812
  const preferredX = getAlignedTextX2(rect, align, padding);
18419
18813
  if (align === "center") {
18420
- return clamp7(preferredX, minX, maxX);
18814
+ return utils.clamp(preferredX, minX, maxX);
18421
18815
  }
18422
18816
  if (align === "right") {
18423
18817
  return Math.max(Math.min(preferredX, maxX), minX);
18424
18818
  }
18425
18819
  return Math.min(Math.max(preferredX, minX), maxX);
18426
18820
  }
18427
- function clamp7(value, min, max) {
18428
- return Math.min(Math.max(value, min), max);
18429
- }
18430
18821
 
18431
18822
  // src/rendering/primitives/draw-header.ts
18432
18823
  var ACTION_GAP2 = 4;
@@ -18546,7 +18937,13 @@ function drawHeaderCell(params, cell, clipRect) {
18546
18937
  }),
18547
18938
  contentInsetEnd: cell.node.children.length === 0 && collapseMarkerSet.hasRightMarker ? COLLAPSE_TRIGGER_WIDTH / 2 + COLLAPSE_TRIGGER_GAP + ACTION_PADDING_INLINE2 : 0
18548
18939
  });
18549
- const textY = rect.y + rect.height / 2;
18940
+ const textY = resolveHeaderContentCenterY(
18941
+ rect,
18942
+ titleContent,
18943
+ theme.fontSize,
18944
+ cell.node.style?.paddingBlock ?? 6,
18945
+ cell.node.style?.verticalAlign
18946
+ );
18550
18947
  ctx.textAlign = textLayout.align;
18551
18948
  if (params.rowSelection?.columnKey === cell.node.key && cell.node.children.length === 0) {
18552
18949
  descriptors.push({
@@ -18596,6 +18993,21 @@ function drawHeaderCell(params, cell, clipRect) {
18596
18993
  }
18597
18994
  ctx.restore();
18598
18995
  }
18996
+ function resolveHeaderContentCenterY(rect, contents, fontSize, paddingBlock, verticalAlign) {
18997
+ const contentHeight = Math.max(
18998
+ fontSize,
18999
+ ...contents.map(
19000
+ (content) => content.type === "img" ? Math.max(content.height ?? content.width ?? fontSize, 1) : fontSize
19001
+ )
19002
+ );
19003
+ if (verticalAlign === "top") {
19004
+ return rect.y + paddingBlock + contentHeight / 2;
19005
+ }
19006
+ if (verticalAlign === "bottom") {
19007
+ return rect.y + rect.height - paddingBlock - contentHeight / 2;
19008
+ }
19009
+ return rect.y + rect.height / 2;
19010
+ }
18599
19011
  function measureHeaderContentWidth(ctx, contents) {
18600
19012
  const gap = 4;
18601
19013
  return contents.reduce(
@@ -20790,250 +21202,6 @@ var ListTableSelectionController = class {
20790
21202
  }
20791
21203
  };
20792
21204
 
20793
- // src/services/summary-service.ts
20794
- var SUMMARY_ASYNC_BATCH_SIZE = 2e3;
20795
- var SUMMARY_ASYNC_FRAME_BUDGET = 8;
20796
- async function computeSummaryValuesAsync(params) {
20797
- const { rows, columns, signal } = params;
20798
- const summaryValues = /* @__PURE__ */ new Map();
20799
- const accumulators = [];
20800
- columns.forEach((column) => {
20801
- const accumulator = createSummaryAccumulator(column);
20802
- if (accumulator) {
20803
- accumulators.push(accumulator);
20804
- }
20805
- });
20806
- columns.forEach((column) => {
20807
- if (column.summaryTitle != null) {
20808
- summaryValues.set(column.key, column.summaryTitle);
20809
- }
20810
- });
20811
- if (accumulators.length === 0) {
20812
- return summaryValues;
20813
- }
20814
- for (let startIndex = 0; startIndex < rows.length; ) {
20815
- if (signal?.aborted) {
20816
- throw new Error("summary computation aborted");
20817
- }
20818
- const frameStart = now();
20819
- let endIndex = startIndex;
20820
- while (endIndex < rows.length) {
20821
- if (signal?.aborted) {
20822
- throw new Error("summary computation aborted");
20823
- }
20824
- const batchEndIndex = Math.min(
20825
- endIndex + SUMMARY_ASYNC_BATCH_SIZE,
20826
- rows.length
20827
- );
20828
- for (let rowIndex = endIndex; rowIndex < batchEndIndex; rowIndex += 1) {
20829
- const record = rows[rowIndex];
20830
- if (!record) {
20831
- continue;
20832
- }
20833
- accumulators.forEach((item) => {
20834
- updateSummaryAccumulator(item, record);
20835
- });
20836
- }
20837
- endIndex = batchEndIndex;
20838
- if (endIndex >= rows.length) {
20839
- break;
20840
- }
20841
- if (now() - frameStart >= SUMMARY_ASYNC_FRAME_BUDGET) {
20842
- break;
20843
- }
20844
- }
20845
- if (endIndex < rows.length) {
20846
- await yieldToMainThread2();
20847
- }
20848
- startIndex = endIndex;
20849
- }
20850
- accumulators.forEach((item) => {
20851
- summaryValues.set(
20852
- item.column.key,
20853
- finalizeSummaryValue(item, rows)
20854
- );
20855
- });
20856
- return summaryValues;
20857
- }
20858
- function createSummaryAccumulator(column) {
20859
- const config = resolveSummaryConfig2(column);
20860
- if (!config) {
20861
- return null;
20862
- }
20863
- return {
20864
- column,
20865
- config,
20866
- type: config.type ?? "sum",
20867
- valueCount: 0,
20868
- numericCount: 0,
20869
- sum: 0,
20870
- min: null,
20871
- max: null,
20872
- uniqueValues: /* @__PURE__ */ new Set()
20873
- };
20874
- }
20875
- function updateSummaryAccumulator(item, record) {
20876
- if (item.column.summaryTitle != null) {
20877
- return;
20878
- }
20879
- if (item.type === "rowCount" || item.type === "mergedRowCount") {
20880
- return;
20881
- }
20882
- const rawValue = normalizeSummaryValue(
20883
- getColumnRawValue(record, item.column, item.config)
20884
- );
20885
- if (rawValue == null) {
20886
- return;
20887
- }
20888
- item.valueCount += 1;
20889
- if (item.type === "unionCount") {
20890
- item.uniqueValues.add(String(rawValue));
20891
- return;
20892
- }
20893
- if (item.type === "count") {
20894
- return;
20895
- }
20896
- const numericValue = toNumber(rawValue);
20897
- if (numericValue == null) {
20898
- return;
20899
- }
20900
- item.numericCount += 1;
20901
- item.sum += numericValue;
20902
- item.min = item.min == null ? numericValue : Math.min(item.min, numericValue);
20903
- item.max = item.max == null ? numericValue : Math.max(item.max, numericValue);
20904
- }
20905
- function finalizeSummaryValue(item, rows) {
20906
- if (item.column.summaryTitle != null) {
20907
- return item.column.summaryTitle;
20908
- }
20909
- if (item.type === "rowCount") {
20910
- return formatSummaryOutput(item, String(rows.length), rows);
20911
- }
20912
- if (item.type === "mergedRowCount") {
20913
- return formatSummaryOutput(item, String(countMergedRows(rows)), rows);
20914
- }
20915
- if (item.type === "count") {
20916
- return formatSummaryOutput(item, String(item.valueCount), rows);
20917
- }
20918
- if (item.type === "unionCount") {
20919
- return formatSummaryOutput(item, String(item.uniqueValues.size), rows);
20920
- }
20921
- if (item.numericCount === 0) {
20922
- if (item.type === "min" || item.type === "max") {
20923
- return formatSummaryOutput(item, "", rows);
20924
- }
20925
- return formatSummaryOutput(item, "0", rows);
20926
- }
20927
- let result = item.sum;
20928
- if (item.type === "avg") {
20929
- result = item.sum / item.numericCount;
20930
- } else if (item.type === "min") {
20931
- result = item.min ?? 0;
20932
- } else if (item.type === "max") {
20933
- result = item.max ?? 0;
20934
- }
20935
- const rounded = roundByPrecision(result, item.config.precision);
20936
- const formatted = formatNumber(rounded, item.config.precision);
20937
- return formatSummaryOutput(item, formatted, rows);
20938
- }
20939
- function resolveSummaryConfig2(column) {
20940
- if (column.summary == null) {
20941
- return null;
20942
- }
20943
- if (column.summary === true) {
20944
- return { type: "sum" };
20945
- }
20946
- if (column.summary === false) {
20947
- return null;
20948
- }
20949
- return { type: "sum", ...column.summary };
20950
- }
20951
- function getColumnRawValue(record, column, config) {
20952
- if (config.valueGetter) {
20953
- return config.valueGetter(record);
20954
- }
20955
- const sortValue = column.sortValueGetter?.(record);
20956
- if (sortValue != null && sortValue !== "") {
20957
- return sortValue;
20958
- }
20959
- const filterValue = column.filterValueGetter?.(record);
20960
- if (filterValue != null && filterValue !== "") {
20961
- return filterValue;
20962
- }
20963
- return getValueByDataIndex(record, column.dataIndex);
20964
- }
20965
- function normalizeSummaryValue(value) {
20966
- if (value == null || value === "") {
20967
- return null;
20968
- }
20969
- if (typeof value === "number" || typeof value === "string") {
20970
- return value;
20971
- }
20972
- return null;
20973
- }
20974
- function toNumber(value) {
20975
- if (value == null) {
20976
- return null;
20977
- }
20978
- if (typeof value === "number") {
20979
- return Number.isNaN(value) ? null : value;
20980
- }
20981
- const parsed = Number(String(value).trim());
20982
- return Number.isNaN(parsed) ? null : parsed;
20983
- }
20984
- function roundByPrecision(value, precision) {
20985
- if (precision == null) {
20986
- return value;
20987
- }
20988
- return Number(value.toFixed(precision));
20989
- }
20990
- function formatNumber(value, precision) {
20991
- if (precision != null) {
20992
- return value.toFixed(precision);
20993
- }
20994
- if (Number.isInteger(value)) {
20995
- return String(value);
20996
- }
20997
- return value.toFixed(2);
20998
- }
20999
- function formatSummaryOutput(item, value, rows) {
21000
- if (item.config.formatter) {
21001
- return item.config.formatter(
21002
- value,
21003
- rows,
21004
- item.column
21005
- );
21006
- }
21007
- return value;
21008
- }
21009
- function countMergedRows(rows) {
21010
- return rows.reduce((count, record) => {
21011
- if (record == null || typeof record !== "object") {
21012
- return count + 1;
21013
- }
21014
- const rowSpan = record.rowSpan;
21015
- if (typeof rowSpan !== "number") {
21016
- return count + 1;
21017
- }
21018
- return rowSpan > 0 ? count + 1 : count;
21019
- }, 0);
21020
- }
21021
- function yieldToMainThread2() {
21022
- return new Promise((resolve) => {
21023
- if (typeof requestAnimationFrame === "function") {
21024
- requestAnimationFrame(() => resolve());
21025
- return;
21026
- }
21027
- setTimeout(resolve, 0);
21028
- });
21029
- }
21030
- function now() {
21031
- if (typeof performance !== "undefined" && typeof performance.now === "function") {
21032
- return performance.now();
21033
- }
21034
- return Date.now();
21035
- }
21036
-
21037
21205
  // src/domain/summary/summary-interaction.ts
21038
21206
  function isSummaryInteractionActive(params) {
21039
21207
  const now2 = params.now ?? Date.now();
@@ -21842,6 +22010,7 @@ var ListTableCore = class {
21842
22010
  __publicField(this, "debugManager");
21843
22011
  this.container = container;
21844
22012
  this.options = options;
22013
+ applyInitialColumnVisibility(options.columns);
21845
22014
  ensureColumnKeysInPlace(options.columns);
21846
22015
  this.domHost = new ListTableDomHost();
21847
22016
  this.canvasHost = new ListTableCanvasHost();
@@ -21887,6 +22056,7 @@ var ListTableCore = class {
21887
22056
  */
21888
22057
  updateOptions(options) {
21889
22058
  this.animationController.stopCarouselScroll();
22059
+ applyInitialColumnVisibility(options.columns);
21890
22060
  ensureColumnKeysInPlace(options.columns);
21891
22061
  if (options.expandable?.expandedRowKeys !== void 0 && !areSameRowKeySet(
21892
22062
  this.storeFacade.expandedRowKeys,
@@ -21940,8 +22110,8 @@ var ListTableCore = class {
21940
22110
  /**
21941
22111
  * 异步导出全部原始数据为 XLSX。
21942
22112
  */
21943
- exportXlsx() {
21944
- this.contentActionController.exportXlsx();
22113
+ exportXlsx(options) {
22114
+ this.contentActionController.exportXlsx(options);
21945
22115
  }
21946
22116
  /**
21947
22117
  * 滚动到指定行。
@@ -22062,8 +22232,8 @@ var ListTable = class {
22062
22232
  /**
22063
22233
  * 异步导出全部原始数据为 XLSX。
22064
22234
  */
22065
- exportXlsx() {
22066
- this.core?.exportXlsx();
22235
+ exportXlsx(options) {
22236
+ this.core?.exportXlsx(options);
22067
22237
  }
22068
22238
  /**
22069
22239
  * 滚动到指定行。