@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.js CHANGED
@@ -1,7 +1,7 @@
1
+ import { stringifyDataIndex, getValueByDataIndex, clamp, copyTextSync, copyText, exportTableToXlsx, exportTableToTxt, exportTableToCsv, downloadJsonFile, mapRowsToExportRecords, copyJson, copyRows, isSameDataIndex, isPointInRect as isPointInRect$1 } from '@canvas-components/utils';
1
2
  import { drawBarcodeToCanvas } from '@canvas-components/barcode';
2
3
  import { drawCanvasChartToCanvas, getCanvasChartRenderer, resolveCanvasChartTooltipText } from '@canvas-components/chart';
3
4
  import { drawQrCodeToCanvas } from '@canvas-components/qrcode';
4
- import { copyTextSync, copyText, exportTableToXlsx, exportTableToTxt, exportTableToCsv, downloadJsonFile, mapRowsToExportRecords, copyJson, copyRows } from '@canvas-components/utils';
5
5
 
6
6
  var __defProp = Object.defineProperty;
7
7
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -68,13 +68,8 @@ var DebugManager = class {
68
68
  console.info(`[ListTable Debug] ${label}`, payload);
69
69
  }
70
70
  };
71
-
72
- // src/domain/columns/column-key.ts
73
- function stringifyColumnDataIndex(dataIndex) {
74
- return Array.isArray(dataIndex) ? dataIndex.map((item) => String(item)).join(".") : String(dataIndex);
75
- }
76
71
  function resolveColumnKey(column) {
77
- return column.key?.trim() || stringifyColumnDataIndex(column.dataIndex);
72
+ return column.key?.trim() || stringifyDataIndex(column.dataIndex);
78
73
  }
79
74
  function ensureColumnKeysInPlace(columns) {
80
75
  columns.forEach((column) => {
@@ -327,6 +322,7 @@ function normalizeColumn(column, depth, parentKey) {
327
322
  minWidth: Number(column.minWidth) || DEFAULT_MIN_WIDTH,
328
323
  maxWidth: Number(column.maxWidth) || DEFAULT_MAX_WIDTH,
329
324
  align: column.align ?? "left",
325
+ headerAlign: column.headerAlign,
330
326
  fixed: column.fixed,
331
327
  hidden: column.hidden,
332
328
  ellipsis: column.ellipsis,
@@ -346,6 +342,7 @@ function normalizeColumn(column, depth, parentKey) {
346
342
  cellType: column.cellType,
347
343
  cellStyle: column.cellStyle,
348
344
  moneyFormat: column.moneyFormat,
345
+ dataFormat: column.dataFormat,
349
346
  headerStyle: column.headerStyle,
350
347
  summary: column.summary,
351
348
  summaryTitle: column.summaryTitle,
@@ -581,15 +578,28 @@ function cloneColumns(columns) {
581
578
  children: column.children ? cloneColumns(column.children) : void 0
582
579
  }));
583
580
  }
581
+ function applyInitialColumnVisibility(columns) {
582
+ columns.forEach((column) => {
583
+ if (column.hidden === void 0 && column.initialHide) {
584
+ column.hidden = true;
585
+ }
586
+ if (column.children?.length) {
587
+ applyInitialColumnVisibility(column.children);
588
+ }
589
+ });
590
+ }
584
591
  function replaceColumns(target, source) {
585
592
  target.splice(0, target.length, ...cloneColumns(source));
586
593
  }
587
594
  function buildHeaderSettingsItems(columns) {
588
595
  ensureColumnKeysInPlace(columns);
589
596
  const totalVisibleLeafCount = countVisibleLeafColumns(columns);
590
- return columns.map(
591
- (column) => buildHeaderSettingsItem(column, totalVisibleLeafCount, false)
592
- );
597
+ return columns.flatMap((column) => {
598
+ if (column.hideInSetting) {
599
+ return [];
600
+ }
601
+ return [buildHeaderSettingsItem(column, totalVisibleLeafCount, false)];
602
+ });
593
603
  }
594
604
  function setHeaderColumnVisible(columns, columnKey, visible) {
595
605
  if (!visible) {
@@ -649,9 +659,7 @@ function resolveCollapsedHeaderColumnMarkers(params) {
649
659
  if (visibleLeafKeys.length === 0) {
650
660
  return [];
651
661
  }
652
- const leafIndexMap = new Map(
653
- allLeafKeys.map((key, index) => [key, index])
654
- );
662
+ const leafIndexMap = new Map(allLeafKeys.map((key, index) => [key, index]));
655
663
  const markers = [];
656
664
  let previousVisibleIndex = -1;
657
665
  visibleLeafKeys.forEach((columnKey) => {
@@ -717,19 +725,87 @@ function restoreAllHiddenHeaderColumns(columns) {
717
725
  });
718
726
  return updated;
719
727
  }
728
+ function getColumnPresentationConfig(columns, columnKey) {
729
+ const column = findColumnNode(columns, columnKey);
730
+ if (!column) {
731
+ return null;
732
+ }
733
+ const bodyColumn = column.children?.length ? collectLeafColumns([column])[0] : column;
734
+ return {
735
+ headerHorizontal: column.headerAlign ?? column.align ?? "left",
736
+ headerVertical: column.headerStyle?.verticalAlign ?? "middle",
737
+ bodyHorizontal: bodyColumn?.align ?? "left",
738
+ bodyVertical: bodyColumn?.cellStyle?.verticalAlign ?? "middle",
739
+ dataFormat: column.dataFormat ?? "default",
740
+ dataFormatAvailable: !column.children?.length && !column.render && (column.cellType == null || column.cellType === "text" || column.cellType === "money")
741
+ };
742
+ }
743
+ function setColumnAlignment(params) {
744
+ const column = findColumnNode(params.columns, params.columnKey);
745
+ if (!column) {
746
+ return false;
747
+ }
748
+ const targets = params.area === "body" && column.children?.length ? collectLeafColumns([column]) : [column];
749
+ targets.forEach((target) => {
750
+ if (params.area === "header") {
751
+ if (params.axis === "horizontal") {
752
+ target.headerAlign = params.value;
753
+ } else {
754
+ target.headerStyle = {
755
+ ...target.headerStyle,
756
+ verticalAlign: params.value
757
+ };
758
+ }
759
+ return;
760
+ }
761
+ if (params.axis === "horizontal") {
762
+ target.align = params.value;
763
+ } else {
764
+ target.cellStyle = {
765
+ ...target.cellStyle,
766
+ verticalAlign: params.value
767
+ };
768
+ }
769
+ });
770
+ return true;
771
+ }
772
+ function setColumnDataFormat(columns, columnKey, dataFormat) {
773
+ const column = findColumnNode(columns, columnKey);
774
+ if (!column || column.children?.length || column.render) {
775
+ return false;
776
+ }
777
+ column.dataFormat = dataFormat === "default" ? void 0 : dataFormat;
778
+ return true;
779
+ }
780
+ function findColumnNode(columns, columnKey) {
781
+ for (const column of columns) {
782
+ if (resolveColumnKey(column) === columnKey) {
783
+ return column;
784
+ }
785
+ if (column.children?.length) {
786
+ const child = findColumnNode(column.children, columnKey);
787
+ if (child) {
788
+ return child;
789
+ }
790
+ }
791
+ }
792
+ return null;
793
+ }
720
794
  function buildHeaderSettingsItem(column, totalVisibleLeafCount, parentHidden) {
721
795
  const hidden = parentHidden || !!column.hidden;
722
- const children = column.children?.map(
796
+ const children = column.children?.filter((child) => !child.hideInSetting).map(
723
797
  (child) => buildHeaderSettingsItem(child, totalVisibleLeafCount, hidden)
724
798
  );
725
799
  const leafCount = countLeafColumns([column]);
726
800
  const visibleLeafCount = hidden ? 0 : countVisibleLeafColumns([column]);
727
801
  const checked = leafCount > 0 && visibleLeafCount === leafCount;
728
802
  const indeterminate = visibleLeafCount > 0 && visibleLeafCount < leafCount;
729
- const disabled = visibleLeafCount > 0 && visibleLeafCount >= totalVisibleLeafCount;
803
+ const disabled = column.disableHide && checked || visibleLeafCount > 0 && visibleLeafCount >= totalVisibleLeafCount;
730
804
  return {
731
805
  key: resolveColumnKey(column),
732
- title: String(column.title ?? resolveColumnKey(column)),
806
+ title: String(
807
+ column.settingTitle ?? column.title ?? resolveColumnKey(column)
808
+ ),
733
809
  checked,
734
810
  indeterminate,
735
811
  disabled,
@@ -739,6 +815,9 @@ function buildHeaderSettingsItem(column, totalVisibleLeafCount, parentHidden) {
739
815
  function setColumnVisible(columns, columnKey, visible, ancestors = []) {
740
816
  for (const column of columns) {
741
817
  if (column.key === columnKey) {
818
+ if (!visible && column.disableHide) {
819
+ return false;
820
+ }
742
821
  ancestors.forEach((item) => {
743
822
  item.hidden = false;
744
823
  });
@@ -746,12 +825,10 @@ function setColumnVisible(columns, columnKey, visible, ancestors = []) {
746
825
  return true;
747
826
  }
748
827
  if (column.children?.length) {
749
- const updated = setColumnVisible(
750
- column.children,
751
- columnKey,
752
- visible,
753
- [...ancestors, column]
754
- );
828
+ const updated = setColumnVisible(column.children, columnKey, visible, [
829
+ ...ancestors,
830
+ column
831
+ ]);
755
832
  if (updated) {
756
833
  return true;
757
834
  }
@@ -760,6 +837,9 @@ function setColumnVisible(columns, columnKey, visible, ancestors = []) {
760
837
  return false;
761
838
  }
762
839
  function setSubtreeVisible(column, visible) {
840
+ if (!visible && column.disableHide) {
841
+ return;
842
+ }
763
843
  column.hidden = !visible;
764
844
  column.children?.forEach((child) => {
765
845
  setSubtreeVisible(child, visible);
@@ -1601,27 +1681,6 @@ function clampPageNumber(page, totalPages) {
1601
1681
  }
1602
1682
  return Math.min(Math.max(1, Math.floor(page)), totalPages);
1603
1683
  }
1604
-
1605
- // src/domain/data/get-value-by-data-index.ts
1606
- function getValueByDataIndex(record, dataIndex) {
1607
- if (dataIndex == null) {
1608
- return void 0;
1609
- }
1610
- const path = Array.isArray(dataIndex) ? dataIndex : [dataIndex];
1611
- let current = record;
1612
- for (const key of path) {
1613
- if (current == null) {
1614
- return void 0;
1615
- }
1616
- if (typeof current !== "object" && !Array.isArray(current)) {
1617
- return void 0;
1618
- }
1619
- current = current[key];
1620
- }
1621
- return current;
1622
- }
1623
-
1624
- // src/domain/rows/row-selection.ts
1625
1684
  var maximumTreeDepthCache = /* @__PURE__ */ new WeakMap();
1626
1685
  var ROW_SELECTION_COLUMN_KEY = "__row_selection__";
1627
1686
  var EXPAND_COLUMN_KEY = "__row_expand__";
@@ -3709,8 +3768,6 @@ function resolveLinkTextDecoration(content, hovered = false) {
3709
3768
  }
3710
3769
  return shouldDrawUnderline(content.underline, hovered) ? "underline" : "none";
3711
3770
  }
3712
-
3713
- // src/rendering/cell-content/draw-nested-table-content.ts
3714
3771
  var DEFAULT_COLUMN_WIDTH2 = 140;
3715
3772
  var TABLE_PADDING_X = 12;
3716
3773
  function drawBodyNestedTableContent(params) {
@@ -3931,7 +3988,7 @@ function isNestedTableColumnHighlighted(content, column, columnIndex, highlight)
3931
3988
  }
3932
3989
  return content.highlightColumnDataIndexes?.some(
3933
3990
  (dataIndex) => isSameDataIndex(dataIndex, column.dataIndex)
3934
- ) === true || highlight?.columnDataIndex === serializeDataIndex(column.dataIndex) || highlight?.columnIndex === columnIndex;
3991
+ ) === true || highlight?.columnDataIndex === stringifyDataIndex(column.dataIndex) || highlight?.columnIndex === columnIndex;
3935
3992
  }
3936
3993
  function resolveNestedTableRowKey(content, record, rowIndex) {
3937
3994
  if (typeof content.rowKey === "function") {
@@ -3944,11 +4001,6 @@ function resolveNestedTableRowKey(content, record, rowIndex) {
3944
4001
  const fallbackKey = record.key;
3945
4002
  return typeof fallbackKey === "string" || typeof fallbackKey === "number" ? fallbackKey : rowIndex;
3946
4003
  }
3947
- function isSameDataIndex(left, right) {
3948
- const leftPath = Array.isArray(left) ? left : [left];
3949
- const rightPath = Array.isArray(right) ? right : [right];
3950
- return leftPath.length === rightPath.length && leftPath.every((key, index) => key === rightPath[index]);
3951
- }
3952
4004
  function pushNestedTableDescriptor(params) {
3953
4005
  const { column, columnIndex, content, drawParams, record, rect, rowIndex } = params;
3954
4006
  const rowKey = record != null && typeof rowIndex === "number" ? resolveNestedTableRowKey(content, record, rowIndex) : void 0;
@@ -3961,14 +4013,11 @@ function pushNestedTableDescriptor(params) {
3961
4013
  contentKey: "nested-table",
3962
4014
  nestedRowKey: rowKey,
3963
4015
  nestedRowIndex: rowIndex,
3964
- nestedColumnDataIndex: serializeDataIndex(column.dataIndex),
4016
+ nestedColumnDataIndex: stringifyDataIndex(column.dataIndex),
3965
4017
  nestedColumnIndex: columnIndex,
3966
4018
  cursor: "pointer"
3967
4019
  });
3968
4020
  }
3969
- function serializeDataIndex(dataIndex) {
3970
- return (Array.isArray(dataIndex) ? dataIndex : [dataIndex]).map((item) => String(item)).join(".");
3971
- }
3972
4021
  function drawNestedTableText(params) {
3973
4022
  const {
3974
4023
  align = "left",
@@ -5183,8 +5232,6 @@ function applyTextContentStyle(ctx, content, fallbackColor, theme) {
5183
5232
  ctx.textBaseline = "alphabetic";
5184
5233
  ctx.textAlign = "left";
5185
5234
  }
5186
-
5187
- // src/features/editing/editing-utils.ts
5188
5235
  function canEditCell(column, context) {
5189
5236
  if (!column || column.key === ROW_SELECTION_COLUMN_KEY || column.key === EXPAND_COLUMN_KEY) {
5190
5237
  return false;
@@ -5346,6 +5393,10 @@ function resolveColumnFormItemProps(column, context) {
5346
5393
  var CONTENT_HORIZONTAL_PADDING = 12;
5347
5394
  var CONTENT_GAP = 8;
5348
5395
  var CONTENT_VERTICAL_PADDING = 6;
5396
+ var THOUSANDS_NUMBER_FORMAT = new Intl.NumberFormat("zh-CN", {
5397
+ useGrouping: true,
5398
+ maximumFractionDigits: 20
5399
+ });
5349
5400
  function resolveBodyCellContents(params) {
5350
5401
  const { record, rowIndex, column } = params;
5351
5402
  const value = getValueByDataIndex(record, column.dataIndex);
@@ -5359,6 +5410,14 @@ function resolveBodyCellContents(params) {
5359
5410
  record,
5360
5411
  rowIndex
5361
5412
  });
5413
+ if (column.dataFormat && column.dataFormat !== "default") {
5414
+ return [
5415
+ {
5416
+ type: "text",
5417
+ text: formattedText ?? formatListTableDataValue(value, column.dataFormat)
5418
+ }
5419
+ ];
5420
+ }
5362
5421
  if (column.cellType === "checkbox" || column.cellType === "radio" || column.cellType === "switch") {
5363
5422
  return [
5364
5423
  {
@@ -5519,6 +5578,26 @@ function formatMoneyValue(value, options) {
5519
5578
  const formattedDecimal = decimalText != null && decimalText.length > 0 ? `.${decimalText}` : "";
5520
5579
  return `${sign}${symbol}${formattedInteger}${formattedDecimal}`;
5521
5580
  }
5581
+ function formatListTableDataValue(value, dataFormat) {
5582
+ if (dataFormat === "number") {
5583
+ const numericValue = parseMoneyNumber(value);
5584
+ return numericValue == null ? String(value ?? "") : String(numericValue);
5585
+ }
5586
+ if (dataFormat === "thousands") {
5587
+ const numericValue = parseMoneyNumber(value);
5588
+ if (numericValue == null) {
5589
+ return String(value ?? "");
5590
+ }
5591
+ return THOUSANDS_NUMBER_FORMAT.format(numericValue);
5592
+ }
5593
+ if (dataFormat === "money") {
5594
+ return formatMoneyValue(value, {
5595
+ thousandsSeparator: true,
5596
+ decimalPlaces: 2
5597
+ });
5598
+ }
5599
+ return String(value ?? "");
5600
+ }
5522
5601
  function parseMoneyNumber(value) {
5523
5602
  if (typeof value === "number") {
5524
5603
  return Number.isFinite(value) ? value : null;
@@ -6760,9 +6839,6 @@ function intersectRects(left, right) {
6760
6839
  height: maxY - y
6761
6840
  };
6762
6841
  }
6763
- function clamp(value, min, max) {
6764
- return Math.min(Math.max(value, min), max);
6765
- }
6766
6842
 
6767
6843
  // src/services/cell-content-action-service.ts
6768
6844
  function emitBodyCellContentClick(params) {
@@ -6978,30 +7054,20 @@ function resolveBodyContentIndex(result, contents) {
6978
7054
  }
6979
7055
  return void 0;
6980
7056
  }
6981
-
6982
- // src/domain/layout/geometry.ts
6983
- function clamp2(value, min, max) {
6984
- return Math.min(Math.max(value, min), max);
6985
- }
6986
- function isPointInRect2(x, y, rect) {
6987
- return x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height;
6988
- }
6989
-
6990
- // src/domain/layout/scrollbar.ts
6991
7057
  function isPointInScrollbar(x, y, scrollbar) {
6992
- return isPointInRect2(x, y, scrollbar.decreaseButton) || isPointInRect2(x, y, scrollbar.increaseButton) || isPointInRect2(x, y, scrollbar.track) || isPointInRect2(x, y, scrollbar.thumb);
7058
+ return isPointInRect$1(x, y, scrollbar.decreaseButton) || isPointInRect$1(x, y, scrollbar.increaseButton) || isPointInRect$1(x, y, scrollbar.track) || isPointInRect$1(x, y, scrollbar.thumb);
6993
7059
  }
6994
7060
  function resolveScrollbarRole(x, y, scrollbar) {
6995
- if (isPointInRect2(x, y, scrollbar.thumb)) {
7061
+ if (isPointInRect$1(x, y, scrollbar.thumb)) {
6996
7062
  return "thumb";
6997
7063
  }
6998
- if (isPointInRect2(x, y, scrollbar.decreaseButton)) {
7064
+ if (isPointInRect$1(x, y, scrollbar.decreaseButton)) {
6999
7065
  return "decrease-button";
7000
7066
  }
7001
- if (isPointInRect2(x, y, scrollbar.increaseButton)) {
7067
+ if (isPointInRect$1(x, y, scrollbar.increaseButton)) {
7002
7068
  return "increase-button";
7003
7069
  }
7004
- if (isPointInRect2(x, y, scrollbar.track)) {
7070
+ if (isPointInRect$1(x, y, scrollbar.track)) {
7005
7071
  return "track";
7006
7072
  }
7007
7073
  return void 0;
@@ -7100,8 +7166,6 @@ function scaleRectByZoom(rect, zoom) {
7100
7166
  height: rect.height * safeZoom
7101
7167
  };
7102
7168
  }
7103
-
7104
- // src/domain/columns/header-reorder.ts
7105
7169
  function resolveHeaderReorderTarget(pointerX, siblings, getBounds) {
7106
7170
  if (siblings.length === 0) {
7107
7171
  return null;
@@ -7128,7 +7192,7 @@ function resolveHeaderReorderTarget(pointerX, siblings, getBounds) {
7128
7192
  }
7129
7193
  }
7130
7194
  }
7131
- targetSiblingIndex = clamp2(targetSiblingIndex, 0, siblings.length);
7195
+ targetSiblingIndex = clamp(targetSiblingIndex, 0, siblings.length);
7132
7196
  const targetIndicatorX = resolveTargetIndicatorX(
7133
7197
  siblings,
7134
7198
  targetSiblingIndex,
@@ -7719,8 +7783,6 @@ function createListTableAnimationRuntime() {
7719
7783
  carouselScrollAnimation: null
7720
7784
  };
7721
7785
  }
7722
-
7723
- // src/features/scroll/scroll-feature.ts
7724
7786
  var WHEEL_DELTA_MODE_PIXEL = 0;
7725
7787
  var WHEEL_DELTA_MODE_LINE = 1;
7726
7788
  var WHEEL_DELTA_MODE_PAGE = 2;
@@ -7815,7 +7877,7 @@ function stepScrollbarScroll(params) {
7815
7877
  if (area === "horizontal-scrollbar") {
7816
7878
  return {
7817
7879
  ...current,
7818
- left: clamp2(
7880
+ left: clamp(
7819
7881
  current.left + direction * horizontalStep,
7820
7882
  0,
7821
7883
  viewport.maxScrollLeft
@@ -7824,7 +7886,7 @@ function stepScrollbarScroll(params) {
7824
7886
  }
7825
7887
  return {
7826
7888
  ...current,
7827
- top: clamp2(
7889
+ top: clamp(
7828
7890
  current.top + direction * rowHeight,
7829
7891
  0,
7830
7892
  viewport.maxScrollTop
@@ -7834,7 +7896,7 @@ function stepScrollbarScroll(params) {
7834
7896
  function jumpScrollbarScroll(params) {
7835
7897
  const { current, axis, pointerValue, track, thumb, viewport } = params;
7836
7898
  if (axis === "horizontal") {
7837
- const nextThumbX = clamp2(
7899
+ const nextThumbX = clamp(
7838
7900
  pointerValue - thumb.width / 2,
7839
7901
  track.x,
7840
7902
  track.x + track.width - thumb.width
@@ -7845,7 +7907,7 @@ function jumpScrollbarScroll(params) {
7845
7907
  left: ratio2 * viewport.maxScrollLeft
7846
7908
  };
7847
7909
  }
7848
- const nextThumbY = clamp2(
7910
+ const nextThumbY = clamp(
7849
7911
  pointerValue - thumb.height / 2,
7850
7912
  track.y,
7851
7913
  track.y + track.height - thumb.height
@@ -7858,7 +7920,7 @@ function jumpScrollbarScroll(params) {
7858
7920
  }
7859
7921
  function dragScrollbarScroll(params) {
7860
7922
  const { current, dragging, pointerValue } = params;
7861
- const nextThumbValue = clamp2(
7923
+ const nextThumbValue = clamp(
7862
7924
  pointerValue - dragging.pointerOffset,
7863
7925
  dragging.trackStart,
7864
7926
  dragging.trackStart + dragging.trackLength - dragging.thumbLength
@@ -7922,7 +7984,7 @@ function resolveVerticalCarouselScroll(params) {
7922
7984
  return {
7923
7985
  nextScroll: {
7924
7986
  ...current,
7925
- top: clamp2(current.top + Math.max(rowHeight, 1), 0, maxScrollTop)
7987
+ top: clamp(current.top + Math.max(rowHeight, 1), 0, maxScrollTop)
7926
7988
  },
7927
7989
  animate: true,
7928
7990
  shouldStop: false
@@ -7949,7 +8011,7 @@ function resolveHorizontalCarouselScroll(params) {
7949
8011
  return {
7950
8012
  nextScroll: {
7951
8013
  ...current,
7952
- left: clamp2(nextLeft, 0, maxScrollLeft)
8014
+ left: clamp(nextLeft, 0, maxScrollLeft)
7953
8015
  },
7954
8016
  animate: true,
7955
8017
  shouldStop: false
@@ -7960,7 +8022,7 @@ function resolveColumnBoundaries(columns, maxScrollLeft) {
7960
8022
  let offset = 0;
7961
8023
  columns.forEach((column) => {
7962
8024
  offset += Math.max(column.width, 0);
7963
- boundaries.push(clamp2(offset, 0, maxScrollLeft));
8025
+ boundaries.push(clamp(offset, 0, maxScrollLeft));
7964
8026
  });
7965
8027
  return Array.from(new Set(boundaries)).filter((value) => value > 0);
7966
8028
  }
@@ -9244,75 +9306,322 @@ var ListTableCarouselController = class {
9244
9306
  });
9245
9307
  }
9246
9308
  };
9247
- function getCellClipboardText(record, rowIndex, column) {
9248
- const value = getValueByDataIndex(record, column.dataIndex);
9249
- const rendered = column.render?.(value, record, rowIndex, column);
9250
- if (rendered != null) {
9251
- return renderResultToClipboardText(rendered);
9309
+ var SUMMARY_ASYNC_BATCH_SIZE = 2e3;
9310
+ var SUMMARY_ASYNC_FRAME_BUDGET = 8;
9311
+ async function computeSummaryValuesAsync(params) {
9312
+ const { rows, columns, signal } = params;
9313
+ const summaryValues = /* @__PURE__ */ new Map();
9314
+ const accumulators = [];
9315
+ columns.forEach((column) => {
9316
+ const accumulator = createSummaryAccumulator(column);
9317
+ if (accumulator) {
9318
+ accumulators.push(accumulator);
9319
+ }
9320
+ });
9321
+ columns.forEach((column) => {
9322
+ if (column.summaryTitle != null) {
9323
+ summaryValues.set(column.key, column.summaryTitle);
9324
+ }
9325
+ });
9326
+ if (accumulators.length === 0) {
9327
+ return summaryValues;
9252
9328
  }
9253
- if (column.cellType === "checkbox" || column.cellType === "radio") {
9254
- return String(Boolean(value));
9329
+ for (let startIndex = 0; startIndex < rows.length; ) {
9330
+ if (signal?.aborted) {
9331
+ throw new Error("summary computation aborted");
9332
+ }
9333
+ const frameStart = now();
9334
+ let endIndex = startIndex;
9335
+ while (endIndex < rows.length) {
9336
+ if (signal?.aborted) {
9337
+ throw new Error("summary computation aborted");
9338
+ }
9339
+ const batchEndIndex = Math.min(
9340
+ endIndex + SUMMARY_ASYNC_BATCH_SIZE,
9341
+ rows.length
9342
+ );
9343
+ for (let rowIndex = endIndex; rowIndex < batchEndIndex; rowIndex += 1) {
9344
+ const record = rows[rowIndex];
9345
+ if (!record) {
9346
+ continue;
9347
+ }
9348
+ accumulators.forEach((item) => {
9349
+ updateSummaryAccumulator(item, record);
9350
+ });
9351
+ }
9352
+ endIndex = batchEndIndex;
9353
+ if (endIndex >= rows.length) {
9354
+ break;
9355
+ }
9356
+ if (now() - frameStart >= SUMMARY_ASYNC_FRAME_BUDGET) {
9357
+ break;
9358
+ }
9359
+ }
9360
+ if (endIndex < rows.length) {
9361
+ await yieldToMainThread();
9362
+ }
9363
+ startIndex = endIndex;
9255
9364
  }
9256
- return resolveFormattedCellText({
9365
+ accumulators.forEach((item) => {
9366
+ summaryValues.set(
9367
+ item.column.key,
9368
+ finalizeSummaryValue(item, rows)
9369
+ );
9370
+ });
9371
+ return summaryValues;
9372
+ }
9373
+ function createSummaryAccumulator(column) {
9374
+ const config = resolveSummaryConfig(column);
9375
+ if (!config) {
9376
+ return null;
9377
+ }
9378
+ return {
9257
9379
  column,
9258
- value,
9259
- record,
9260
- rowIndex
9261
- }) ?? String(value ?? "");
9380
+ config,
9381
+ type: config.type ?? "sum",
9382
+ valueCount: 0,
9383
+ numericCount: 0,
9384
+ sum: 0,
9385
+ min: null,
9386
+ max: null,
9387
+ uniqueValues: /* @__PURE__ */ new Set()
9388
+ };
9262
9389
  }
9263
- function createListTableSelectionCopyText(params) {
9264
- const columns = params.columns.filter(
9265
- (column2) => column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9390
+ function updateSummaryAccumulator(item, record) {
9391
+ if (item.column.summaryTitle != null) {
9392
+ return;
9393
+ }
9394
+ if (item.type === "rowCount" || item.type === "mergedRowCount") {
9395
+ return;
9396
+ }
9397
+ const rawValue = normalizeSummaryValue(
9398
+ getColumnRawValue(record, item.column, item.config)
9266
9399
  );
9267
- const columnRange = params.rangeHighlight.selectedColumnRange;
9268
- const rowRange = params.rangeHighlight.selectedRowRange;
9269
- const cellRange = params.rangeHighlight.selectedCellRange;
9270
- if (cellRange) {
9271
- const selectedColumns2 = params.columns.filter(
9272
- (column2, index) => index >= cellRange.startColumnIndex && index <= cellRange.endColumnIndex && column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9273
- );
9274
- return params.rows.slice(cellRange.startRowIndex, cellRange.endRowIndex + 1).map(
9275
- (record2, offset) => selectedColumns2.map(
9276
- (column2) => getCellClipboardText(
9277
- record2,
9278
- cellRange.startRowIndex + offset,
9279
- column2
9280
- )
9281
- ).join(" ")
9282
- ).join("\n");
9400
+ if (rawValue == null) {
9401
+ return;
9283
9402
  }
9284
- const mode = params.highlightMode ?? (rowRange && columnRange ? "cross" : rowRange ? "row" : "column");
9285
- const selectedColumns = columnRange ? params.columns.filter(
9286
- (column2, index) => index >= columnRange.start && index <= columnRange.end
9287
- ).filter(
9288
- (column2) => column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9289
- ) : columns;
9290
- rowRange ? Math.max(rowRange.start, 0) : 0;
9291
- rowRange ? Math.min(rowRange.end, params.rows.length - 1) : params.rows.length - 1;
9292
- if (mode === "column" && columnRange && params.selection.rowIndex == null) {
9293
- return params.rows.map(
9294
- (record2, rowIndex2) => selectedColumns.map((column2) => getCellClipboardText(record2, rowIndex2, column2)).join(" ")
9295
- ).join("\n");
9403
+ item.valueCount += 1;
9404
+ if (item.type === "unionCount") {
9405
+ item.uniqueValues.add(String(rawValue));
9406
+ return;
9296
9407
  }
9297
- const { rowIndex, columnKey } = params.selection;
9298
- const record = rowIndex == null ? void 0 : params.rows[rowIndex];
9299
- const column = columns.find((item) => item.key === columnKey);
9300
- return record && column && rowIndex != null ? getCellClipboardText(record, rowIndex, column) : null;
9408
+ if (item.type === "count") {
9409
+ return;
9410
+ }
9411
+ const numericValue = toNumber(rawValue);
9412
+ if (numericValue == null) {
9413
+ return;
9414
+ }
9415
+ item.numericCount += 1;
9416
+ item.sum += numericValue;
9417
+ item.min = item.min == null ? numericValue : Math.min(item.min, numericValue);
9418
+ item.max = item.max == null ? numericValue : Math.max(item.max, numericValue);
9301
9419
  }
9302
- function createListTableRangeCopyText(params) {
9303
- return createListTableSelectionCopyText({
9304
- rows: params.rows,
9305
- columns: params.columns,
9306
- selection: { rowIndex: null, columnKey: null },
9307
- rangeHighlight: {
9308
- selectedCellRange: {
9309
- startRowIndex: Math.max(
9310
- Math.min(params.startRowIndex, params.endRowIndex),
9311
- 0
9312
- ),
9313
- endRowIndex: Math.min(
9314
- Math.max(params.startRowIndex, params.endRowIndex),
9315
- Math.max(params.rows.length - 1, 0)
9420
+ function finalizeSummaryValue(item, rows) {
9421
+ if (item.column.summaryTitle != null) {
9422
+ return item.column.summaryTitle;
9423
+ }
9424
+ if (item.type === "rowCount") {
9425
+ return formatSummaryOutput(item, String(rows.length), rows);
9426
+ }
9427
+ if (item.type === "mergedRowCount") {
9428
+ return formatSummaryOutput(item, String(countMergedRows(rows)), rows);
9429
+ }
9430
+ if (item.type === "count") {
9431
+ return formatSummaryOutput(item, String(item.valueCount), rows);
9432
+ }
9433
+ if (item.type === "unionCount") {
9434
+ return formatSummaryOutput(item, String(item.uniqueValues.size), rows);
9435
+ }
9436
+ if (item.numericCount === 0) {
9437
+ if (item.type === "min" || item.type === "max") {
9438
+ return formatSummaryOutput(item, "", rows);
9439
+ }
9440
+ return formatSummaryOutput(item, "0", rows);
9441
+ }
9442
+ let result = item.sum;
9443
+ if (item.type === "avg") {
9444
+ result = item.sum / item.numericCount;
9445
+ } else if (item.type === "min") {
9446
+ result = item.min ?? 0;
9447
+ } else if (item.type === "max") {
9448
+ result = item.max ?? 0;
9449
+ }
9450
+ const rounded = roundByPrecision(result, item.config.precision);
9451
+ const formatted = formatNumber(rounded, item.config.precision);
9452
+ return formatSummaryOutput(item, formatted, rows);
9453
+ }
9454
+ function resolveSummaryConfig(column) {
9455
+ if (column.summary == null) {
9456
+ return null;
9457
+ }
9458
+ if (column.summary === true) {
9459
+ return { type: "sum" };
9460
+ }
9461
+ if (column.summary === false) {
9462
+ return null;
9463
+ }
9464
+ return { type: "sum", ...column.summary };
9465
+ }
9466
+ function getColumnRawValue(record, column, config) {
9467
+ if (config.valueGetter) {
9468
+ return config.valueGetter(record);
9469
+ }
9470
+ const sortValue = column.sortValueGetter?.(record);
9471
+ if (sortValue != null && sortValue !== "") {
9472
+ return sortValue;
9473
+ }
9474
+ const filterValue = column.filterValueGetter?.(record);
9475
+ if (filterValue != null && filterValue !== "") {
9476
+ return filterValue;
9477
+ }
9478
+ return getValueByDataIndex(record, column.dataIndex);
9479
+ }
9480
+ function normalizeSummaryValue(value) {
9481
+ if (value == null || value === "") {
9482
+ return null;
9483
+ }
9484
+ if (typeof value === "number" || typeof value === "string") {
9485
+ return value;
9486
+ }
9487
+ return null;
9488
+ }
9489
+ function toNumber(value) {
9490
+ if (value == null) {
9491
+ return null;
9492
+ }
9493
+ if (typeof value === "number") {
9494
+ return Number.isNaN(value) ? null : value;
9495
+ }
9496
+ const parsed = Number(String(value).trim());
9497
+ return Number.isNaN(parsed) ? null : parsed;
9498
+ }
9499
+ function roundByPrecision(value, precision) {
9500
+ if (precision == null) {
9501
+ return value;
9502
+ }
9503
+ return Number(value.toFixed(precision));
9504
+ }
9505
+ function formatNumber(value, precision) {
9506
+ if (precision != null) {
9507
+ return value.toFixed(precision);
9508
+ }
9509
+ if (Number.isInteger(value)) {
9510
+ return String(value);
9511
+ }
9512
+ return value.toFixed(2);
9513
+ }
9514
+ function formatSummaryOutput(item, value, rows) {
9515
+ if (item.config.formatter) {
9516
+ return item.config.formatter(
9517
+ value,
9518
+ rows,
9519
+ item.column
9520
+ );
9521
+ }
9522
+ return value;
9523
+ }
9524
+ function countMergedRows(rows) {
9525
+ return rows.reduce((count, record) => {
9526
+ if (record == null || typeof record !== "object") {
9527
+ return count + 1;
9528
+ }
9529
+ const rowSpan = record.rowSpan;
9530
+ if (typeof rowSpan !== "number") {
9531
+ return count + 1;
9532
+ }
9533
+ return rowSpan > 0 ? count + 1 : count;
9534
+ }, 0);
9535
+ }
9536
+ function yieldToMainThread() {
9537
+ return new Promise((resolve) => {
9538
+ if (typeof requestAnimationFrame === "function") {
9539
+ requestAnimationFrame(() => resolve());
9540
+ return;
9541
+ }
9542
+ setTimeout(resolve, 0);
9543
+ });
9544
+ }
9545
+ function now() {
9546
+ if (typeof performance !== "undefined" && typeof performance.now === "function") {
9547
+ return performance.now();
9548
+ }
9549
+ return Date.now();
9550
+ }
9551
+
9552
+ // src/services/clipboard-service.ts
9553
+ function getCellClipboardText(record, rowIndex, column) {
9554
+ const value = getValueByDataIndex(record, column.dataIndex);
9555
+ const rendered = column.render?.(value, record, rowIndex, column);
9556
+ if (rendered != null) {
9557
+ return renderResultToClipboardText(rendered);
9558
+ }
9559
+ if (column.dataFormat && column.dataFormat !== "default") {
9560
+ return formatListTableDataValue(value, column.dataFormat);
9561
+ }
9562
+ if (column.cellType === "checkbox" || column.cellType === "radio") {
9563
+ return String(Boolean(value));
9564
+ }
9565
+ return resolveFormattedCellText({
9566
+ column,
9567
+ value,
9568
+ record,
9569
+ rowIndex
9570
+ }) ?? String(value ?? "");
9571
+ }
9572
+ function createListTableSelectionCopyText(params) {
9573
+ const columns = params.columns.filter(
9574
+ (column2) => column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9575
+ );
9576
+ const columnRange = params.rangeHighlight.selectedColumnRange;
9577
+ const rowRange = params.rangeHighlight.selectedRowRange;
9578
+ const cellRange = params.rangeHighlight.selectedCellRange;
9579
+ if (cellRange) {
9580
+ const selectedColumns2 = params.columns.filter(
9581
+ (column2, index) => index >= cellRange.startColumnIndex && index <= cellRange.endColumnIndex && column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9582
+ );
9583
+ return params.rows.slice(cellRange.startRowIndex, cellRange.endRowIndex + 1).map(
9584
+ (record2, offset) => selectedColumns2.map(
9585
+ (column2) => getCellClipboardText(
9586
+ record2,
9587
+ cellRange.startRowIndex + offset,
9588
+ column2
9589
+ )
9590
+ ).join(" ")
9591
+ ).join("\n");
9592
+ }
9593
+ const mode = params.highlightMode ?? (rowRange && columnRange ? "cross" : rowRange ? "row" : "column");
9594
+ const selectedColumns = columnRange ? params.columns.filter(
9595
+ (column2, index) => index >= columnRange.start && index <= columnRange.end
9596
+ ).filter(
9597
+ (column2) => column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9598
+ ) : columns;
9599
+ rowRange ? Math.max(rowRange.start, 0) : 0;
9600
+ rowRange ? Math.min(rowRange.end, params.rows.length - 1) : params.rows.length - 1;
9601
+ if (mode === "column" && columnRange && params.selection.rowIndex == null) {
9602
+ return params.rows.map(
9603
+ (record2, rowIndex2) => selectedColumns.map((column2) => getCellClipboardText(record2, rowIndex2, column2)).join(" ")
9604
+ ).join("\n");
9605
+ }
9606
+ const { rowIndex, columnKey } = params.selection;
9607
+ const record = rowIndex == null ? void 0 : params.rows[rowIndex];
9608
+ const column = columns.find((item) => item.key === columnKey);
9609
+ return record && column && rowIndex != null ? getCellClipboardText(record, rowIndex, column) : null;
9610
+ }
9611
+ function createListTableRangeCopyText(params) {
9612
+ return createListTableSelectionCopyText({
9613
+ rows: params.rows,
9614
+ columns: params.columns,
9615
+ selection: { rowIndex: null, columnKey: null },
9616
+ rangeHighlight: {
9617
+ selectedCellRange: {
9618
+ startRowIndex: Math.max(
9619
+ Math.min(params.startRowIndex, params.endRowIndex),
9620
+ 0
9621
+ ),
9622
+ endRowIndex: Math.min(
9623
+ Math.max(params.startRowIndex, params.endRowIndex),
9624
+ Math.max(params.rows.length - 1, 0)
9316
9625
  ),
9317
9626
  startColumnIndex: Math.max(
9318
9627
  Math.min(params.startColumnIndex, params.endColumnIndex),
@@ -9410,10 +9719,31 @@ async function exportAllRowsTxtContent(params) {
9410
9719
  });
9411
9720
  }
9412
9721
  async function exportAllRowsXlsxContent(params) {
9722
+ const columns = params.columns.filter(
9723
+ (column) => column.key !== ROW_SELECTION_COLUMN_KEY
9724
+ );
9725
+ const rows = params.rows.map((record, rowIndex) => ({
9726
+ type: "data",
9727
+ record,
9728
+ rowIndex
9729
+ }));
9730
+ if (params.includeSummary) {
9731
+ rows.push({
9732
+ type: "summary",
9733
+ values: await computeSummaryValuesAsync({
9734
+ rows: params.rows,
9735
+ columns
9736
+ })
9737
+ });
9738
+ }
9413
9739
  await exportTableToXlsx({
9414
- fileName: buildTableExportFileName("xlsx"),
9415
- rows: params.rows,
9416
- columns: buildExportColumns(params.columns),
9740
+ fileName: params.fileName?.trim() || buildTableExportFileName("xlsx"),
9741
+ rows,
9742
+ columns: columns.map((column) => ({
9743
+ key: column.key,
9744
+ title: column.title ?? column.key,
9745
+ value: (row) => row.type === "summary" ? row.values.get(column.key) ?? "" : getCellClipboardText(row.record, row.rowIndex, column)
9746
+ })),
9417
9747
  sheetName: "TableData"
9418
9748
  });
9419
9749
  }
@@ -9666,11 +9996,12 @@ var ListTableContentActionController = class {
9666
9996
  /**
9667
9997
  * 异步导出全部原始数据为 XLSX。
9668
9998
  */
9669
- exportXlsx() {
9999
+ exportXlsx(options) {
9670
10000
  this.startExportTask(
9671
10001
  () => exportAllRowsXlsxContent({
9672
10002
  rows: this.options.getOptions().dataSource,
9673
- columns: this.options.getLeafColumns()
10003
+ columns: this.options.getLeafColumns(),
10004
+ ...options
9674
10005
  }),
9675
10006
  "\u6B63\u5728\u5BFC\u51FA XLSX\u2026"
9676
10007
  );
@@ -10516,8 +10847,6 @@ var ListTableEditingController = class {
10516
10847
  this.validationMessages = /* @__PURE__ */ new Map();
10517
10848
  }
10518
10849
  };
10519
-
10520
- // src/features/column-resize/column-resize-feature.ts
10521
10850
  function startColumnResizeDrag(params) {
10522
10851
  const { options, leafColumns, columnKey, pointerX } = params;
10523
10852
  for (const leaf of leafColumns) {
@@ -10539,7 +10868,7 @@ function updateColumnResizeDrag(params) {
10539
10868
  const { dragging, pointerX, leafColumns, options } = params;
10540
10869
  const dx = pointerX - dragging.startX;
10541
10870
  const nextWidth = Math.round(
10542
- clamp2(dragging.startWidth + dx, dragging.minWidth, dragging.maxWidth)
10871
+ clamp(dragging.startWidth + dx, dragging.minWidth, dragging.maxWidth)
10543
10872
  );
10544
10873
  const column = leafColumns.find((item) => item.key === dragging.columnKey);
10545
10874
  if (!column || column.width === nextWidth) {
@@ -10677,6 +11006,14 @@ function createListTableContextMenuActions(params) {
10677
11006
  onChangeSummaryPrecision: params.onChangeSummaryPrecision ? (columnKey, precision) => {
10678
11007
  params.hideMenu();
10679
11008
  params.onChangeSummaryPrecision?.(columnKey, precision);
11009
+ } : void 0,
11010
+ onChangeAlignment: params.onChangeAlignment ? (columnKey, area, axis, value) => {
11011
+ params.hideMenu();
11012
+ params.onChangeAlignment?.(columnKey, area, axis, value);
11013
+ } : void 0,
11014
+ onChangeDataFormat: params.onChangeDataFormat ? (columnKey, dataFormat) => {
11015
+ params.hideMenu();
11016
+ params.onChangeDataFormat?.(columnKey, dataFormat);
10680
11017
  } : void 0
10681
11018
  };
10682
11019
  }
@@ -10713,7 +11050,10 @@ function buildListTableContextMenuConfig(params) {
10713
11050
  const enableReset = enabledFeatures.has("reset");
10714
11051
  const enableDensity = enabledFeatures.has("density");
10715
11052
  const enableZoom = enabledFeatures.has("zoom");
11053
+ const enableAlignment = enabledFeatures.has("alignment");
11054
+ const enableDataFormat = enabledFeatures.has("dataFormat");
10716
11055
  const enableColumnVisibility = enabledFeatures.has("columnVisibility");
11056
+ const presentation = isHeaderArea ? getColumnPresentationConfig(columns, columnKey) : null;
10717
11057
  const headerItems = isHeaderArea && (enableColumnVisibility || enableColumnCollapse) ? buildHeaderSettingsItems(columns) : void 0;
10718
11058
  const currentColumnItem = headerItems ? findHeaderColumnItem(headerItems, columnKey) : null;
10719
11059
  const canToggleCurrentColumn = enableColumnCollapse && isHeaderArea && !isSelectionColumn && currentColumnItem != null && !currentColumnItem.disabled;
@@ -10724,7 +11064,7 @@ function buildListTableContextMenuConfig(params) {
10724
11064
  };
10725
11065
  if (isSummaryArea && !isSelectionColumn && actions.onChangeSummaryType) {
10726
11066
  const column = findSummaryColumn(columns, columnKey);
10727
- const summary = resolveSummaryConfig(column?.summary);
11067
+ const summary = resolveSummaryConfig2(column?.summary);
10728
11068
  summaryConfig.summaryColumnKey = columnKey;
10729
11069
  summaryConfig.summaryType = summary?.type ?? "sum";
10730
11070
  summaryConfig.summaryPrecision = summary?.precision;
@@ -10803,11 +11143,20 @@ function buildListTableContextMenuConfig(params) {
10803
11143
  onChangeDensity: enableDensity ? actions.onChangeDensity : void 0,
10804
11144
  onChangeZoom: enableZoom ? actions.onChangeZoom : void 0,
10805
11145
  onToggleColumn: enableColumnVisibility && isHeaderArea ? actions.onToggleColumn : void 0,
11146
+ alignment: enableAlignment && presentation ? {
11147
+ headerHorizontal: presentation.headerHorizontal,
11148
+ headerVertical: presentation.headerVertical,
11149
+ bodyHorizontal: presentation.bodyHorizontal,
11150
+ bodyVertical: presentation.bodyVertical
11151
+ } : void 0,
11152
+ onChangeAlignment: enableAlignment && isHeaderArea && actions.onChangeAlignment ? (area, axis, value) => actions.onChangeAlignment?.(columnKey, area, axis, value) : void 0,
11153
+ dataFormat: enableDataFormat && presentation?.dataFormatAvailable ? presentation.dataFormat : void 0,
11154
+ onChangeDataFormat: enableDataFormat && presentation?.dataFormatAvailable && actions.onChangeDataFormat ? (dataFormat) => actions.onChangeDataFormat?.(columnKey, dataFormat) : void 0,
10806
11155
  onClose: actions.onClose,
10807
11156
  ...summaryConfig
10808
11157
  };
10809
11158
  }
10810
- function resolveSummaryConfig(summary) {
11159
+ function resolveSummaryConfig2(summary) {
10811
11160
  if (summary === true) {
10812
11161
  return { type: "sum" };
10813
11162
  }
@@ -10838,6 +11187,8 @@ var DEFAULT_CONTEXT_MENU_FEATURES = [
10838
11187
  "reset",
10839
11188
  "density",
10840
11189
  "zoom",
11190
+ "alignment",
11191
+ "dataFormat",
10841
11192
  "columnVisibility"
10842
11193
  ];
10843
11194
  function resolveEnabledContextMenuFeatures(contextMenu) {
@@ -11245,7 +11596,7 @@ async function filterRowsAsync(params) {
11245
11596
  }
11246
11597
  }
11247
11598
  if (endIndex < rows.length) {
11248
- await yieldToMainThread();
11599
+ await yieldToMainThread2();
11249
11600
  }
11250
11601
  }
11251
11602
  return result;
@@ -11313,7 +11664,7 @@ async function getColumnFilterOptionsAsync(params) {
11313
11664
  optionCountMap.set(value, (optionCountMap.get(value) ?? 0) + 1);
11314
11665
  }
11315
11666
  if (endIndex < dataSource.length) {
11316
- await yieldToMainThread();
11667
+ await yieldToMainThread2();
11317
11668
  }
11318
11669
  }
11319
11670
  const optionItems = explicitOptions.length > 0 ? explicitOptions.map((item) => ({
@@ -11349,7 +11700,7 @@ async function getColumnFilterOptionsAsync(params) {
11349
11700
  ...optionItems
11350
11701
  ];
11351
11702
  }
11352
- function yieldToMainThread() {
11703
+ function yieldToMainThread2() {
11353
11704
  return new Promise((resolve) => {
11354
11705
  setTimeout(resolve, 0);
11355
11706
  });
@@ -11582,6 +11933,8 @@ function showHeaderContextMenu(params) {
11582
11933
  onToggleSummary,
11583
11934
  onChangeSummaryType,
11584
11935
  onChangeSummaryPrecision,
11936
+ onChangeAlignment,
11937
+ onChangeDataFormat,
11585
11938
  summaryVisible,
11586
11939
  getSelectionRange,
11587
11940
  onCopySelection,
@@ -11656,6 +12009,8 @@ function showHeaderContextMenu(params) {
11656
12009
  onToggleSummary,
11657
12010
  onChangeSummaryType,
11658
12011
  onChangeSummaryPrecision,
12012
+ onChangeAlignment,
12013
+ onChangeDataFormat,
11659
12014
  onCopySelection,
11660
12015
  onCopyCustomSelection
11661
12016
  })
@@ -12039,8 +12394,6 @@ function moveRowDrag(params) {
12039
12394
  function endRowDragSession() {
12040
12395
  return createIdleRowDragSession();
12041
12396
  }
12042
-
12043
- // src/features/row-drag/row-drag-insertion.ts
12044
12397
  function resolveRowDragInsertionPosition(params) {
12045
12398
  const bodyTop = Math.max(params.bodyTop, 0);
12046
12399
  const bodyBottom = Math.max(params.bodyBottom, bodyTop);
@@ -12057,15 +12410,15 @@ function resolveRowDragInsertionPosition(params) {
12057
12410
  for (const row of rowRects) {
12058
12411
  if (params.pointerY <= (row.top + row.bottom) / 2) {
12059
12412
  return {
12060
- insertIndex: clamp3(row.rowIndex, 0, rowCount),
12061
- indicatorY: clamp3(row.top, bodyTop, bodyBottom)
12413
+ insertIndex: clamp(row.rowIndex, 0, rowCount),
12414
+ indicatorY: clamp(row.top, bodyTop, bodyBottom)
12062
12415
  };
12063
12416
  }
12064
12417
  }
12065
12418
  const lastRow = rowRects[rowRects.length - 1];
12066
12419
  return {
12067
- insertIndex: clamp3(lastRow.rowIndex + 1, 0, rowCount),
12068
- indicatorY: clamp3(lastRow.bottom, bodyTop, bodyBottom)
12420
+ insertIndex: clamp(lastRow.rowIndex + 1, 0, rowCount),
12421
+ indicatorY: clamp(lastRow.bottom, bodyTop, bodyBottom)
12069
12422
  };
12070
12423
  }
12071
12424
  function resolveVisibleRowRects(descriptors) {
@@ -12088,9 +12441,6 @@ function resolveVisibleRowRects(descriptors) {
12088
12441
  }
12089
12442
  return Array.from(rows.values());
12090
12443
  }
12091
- function clamp3(value, min, max) {
12092
- return Math.min(Math.max(value, min), max);
12093
- }
12094
12444
 
12095
12445
  // src/services/row-drag-bus.ts
12096
12446
  var RowDragBus = class {
@@ -12676,8 +13026,8 @@ var ListTableRowDragController = class {
12676
13026
  const pointer = this.potentialPointer ?? fallbackPointer;
12677
13027
  return {
12678
13028
  dataUrl,
12679
- grabOffsetX: clamp4((pointer.x - rect.x) * zoom, 0, rect.width * zoom),
12680
- grabOffsetY: clamp4((pointer.y - rect.y) * zoom, 0, rect.height * zoom)
13029
+ grabOffsetX: clamp((pointer.x - rect.x) * zoom, 0, rect.width * zoom),
13030
+ grabOffsetY: clamp((pointer.y - rect.y) * zoom, 0, rect.height * zoom)
12681
13031
  };
12682
13032
  }
12683
13033
  showPreview(capture, clientX, clientY) {
@@ -12914,9 +13264,6 @@ function structuredCloneSafe(value) {
12914
13264
  return value;
12915
13265
  }
12916
13266
  }
12917
- function clamp4(value, min, max) {
12918
- return Math.min(Math.max(value, min), max);
12919
- }
12920
13267
  function resolveValidZoom(value) {
12921
13268
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? value : 1;
12922
13269
  }
@@ -13427,19 +13774,55 @@ var ListTableEventController = class {
13427
13774
  this.host.render();
13428
13775
  },
13429
13776
  onChangeSummaryType: (columnKey, type) => {
13430
- updateSummaryColumn(this.host.options.columns, columnKey, (summary) => ({
13431
- ...summary,
13432
- type
13433
- }));
13777
+ updateSummaryColumn(
13778
+ this.host.options.columns,
13779
+ columnKey,
13780
+ (summary) => ({
13781
+ ...summary,
13782
+ type
13783
+ })
13784
+ );
13434
13785
  this.host.refreshRuntimeColumns();
13435
13786
  this.host.persistColumnConfig();
13436
13787
  this.host.render();
13437
13788
  },
13438
13789
  onChangeSummaryPrecision: (columnKey, precision) => {
13439
- updateSummaryColumn(this.host.options.columns, columnKey, (summary) => ({
13440
- ...summary,
13441
- precision
13442
- }));
13790
+ updateSummaryColumn(
13791
+ this.host.options.columns,
13792
+ columnKey,
13793
+ (summary) => ({
13794
+ ...summary,
13795
+ precision
13796
+ })
13797
+ );
13798
+ this.host.refreshRuntimeColumns();
13799
+ this.host.persistColumnConfig();
13800
+ this.host.render();
13801
+ },
13802
+ onChangeAlignment: (columnKey, area, axis, value) => {
13803
+ const updated = setColumnAlignment({
13804
+ columns: this.host.options.columns,
13805
+ columnKey,
13806
+ area,
13807
+ axis,
13808
+ value
13809
+ });
13810
+ if (!updated) {
13811
+ return;
13812
+ }
13813
+ this.host.refreshRuntimeColumns();
13814
+ this.host.persistColumnConfig();
13815
+ this.host.render();
13816
+ },
13817
+ onChangeDataFormat: (columnKey, dataFormat) => {
13818
+ const updated = setColumnDataFormat(
13819
+ this.host.options.columns,
13820
+ columnKey,
13821
+ dataFormat
13822
+ );
13823
+ if (!updated) {
13824
+ return;
13825
+ }
13443
13826
  this.host.refreshRuntimeColumns();
13444
13827
  this.host.persistColumnConfig();
13445
13828
  this.host.render();
@@ -13906,7 +14289,10 @@ var ListTableEventController = class {
13906
14289
  const width = snapshot?.width ?? this.host.canvasElement.width;
13907
14290
  const position = {
13908
14291
  x: Math.min(Math.max(pointer.x, 0), Math.max(width - 1, 0)),
13909
- y: Math.min(Math.max(pointer.y, bodyTop + 1), Math.max(bodyBottom - 1, bodyTop + 1))
14292
+ y: Math.min(
14293
+ Math.max(pointer.y, bodyTop + 1),
14294
+ Math.max(bodyBottom - 1, bodyTop + 1)
14295
+ )
13910
14296
  };
13911
14297
  const result = this.host.resolvePointerHit(position.x, position.y);
13912
14298
  if (result.area !== "body" && result.area !== "body-content" || typeof result.rowIndex !== "number" || !result.columnKey) {
@@ -14891,12 +15277,33 @@ function applyStoredColumnConfig(columns, storedColumns) {
14891
15277
  if (stored) {
14892
15278
  col.width = stored.width;
14893
15279
  col.hidden = !!stored.hidden;
14894
- if (stored.fixed) {
14895
- col.fixed = stored.fixed;
14896
- } else {
14897
- delete col.fixed;
15280
+ if ("align" in stored) {
15281
+ col.align = stored.align;
14898
15282
  }
14899
- if (stored.summary === false) {
15283
+ if ("headerAlign" in stored) {
15284
+ col.headerAlign = stored.headerAlign;
15285
+ }
15286
+ if ("verticalAlign" in stored) {
15287
+ col.cellStyle = {
15288
+ ...col.cellStyle,
15289
+ verticalAlign: stored.verticalAlign
15290
+ };
15291
+ }
15292
+ if ("headerVerticalAlign" in stored) {
15293
+ col.headerStyle = {
15294
+ ...col.headerStyle,
15295
+ verticalAlign: stored.headerVerticalAlign
15296
+ };
15297
+ }
15298
+ if ("dataFormat" in stored) {
15299
+ col.dataFormat = stored.dataFormat;
15300
+ }
15301
+ if (stored.fixed) {
15302
+ col.fixed = stored.fixed;
15303
+ } else {
15304
+ delete col.fixed;
15305
+ }
15306
+ if (stored.summary === false) {
14900
15307
  delete col.summary;
14901
15308
  } else if (stored.summary) {
14902
15309
  col.summary = {
@@ -14924,6 +15331,11 @@ function buildStoredColumnConfig(columns, sortState, filterState, zoom, summaryR
14924
15331
  width: col.width ?? 160,
14925
15332
  fixed: col.fixed,
14926
15333
  hidden: !!col.hidden,
15334
+ ...col.align ? { align: col.align } : null,
15335
+ ...col.cellStyle?.verticalAlign ? { verticalAlign: col.cellStyle.verticalAlign } : null,
15336
+ ...col.headerAlign ? { headerAlign: col.headerAlign } : null,
15337
+ ...col.headerStyle?.verticalAlign ? { headerVerticalAlign: col.headerStyle.verticalAlign } : null,
15338
+ ...col.dataFormat ? { dataFormat: col.dataFormat } : null,
14927
15339
  summary: col.summary === true ? { type: "sum" } : col.summary ? {
14928
15340
  type: col.summary.type,
14929
15341
  precision: col.summary.precision
@@ -15243,7 +15655,7 @@ function buildHeaderNode(column, leafColumns, maxDepth) {
15243
15655
  rowSpan: 1,
15244
15656
  leafStartIndex,
15245
15657
  leafEndIndex,
15246
- align: column.align ?? "left",
15658
+ align: column.headerAlign ?? column.align ?? "left",
15247
15659
  fixed: column.fixed,
15248
15660
  style: column.headerStyle,
15249
15661
  column,
@@ -15261,7 +15673,7 @@ function buildHeaderNode(column, leafColumns, maxDepth) {
15261
15673
  rowSpan: maxDepth - column.depth + 1,
15262
15674
  leafStartIndex: leafIndex,
15263
15675
  leafEndIndex: leafIndex,
15264
- align: column.align ?? "left",
15676
+ align: column.headerAlign ?? column.align ?? "left",
15265
15677
  fixed: column.fixed,
15266
15678
  style: column.headerStyle,
15267
15679
  column,
@@ -15408,8 +15820,6 @@ function computeScrollbarLayout(params) {
15408
15820
  }
15409
15821
  return layout;
15410
15822
  }
15411
-
15412
- // src/domain/layout/compute-viewport.ts
15413
15823
  function computeViewport(params) {
15414
15824
  const bodyHeight = Math.max(
15415
15825
  params.bodyHeight ?? params.height - params.headerHeight,
@@ -15439,15 +15849,12 @@ function computeViewport(params) {
15439
15849
  return {
15440
15850
  viewport,
15441
15851
  scroll: {
15442
- left: clamp5(params.scroll.left, 0, resolvedMaxScrollLeft),
15443
- top: clamp5(params.scroll.top, 0, resolvedMaxScrollTop)
15852
+ left: clamp(params.scroll.left, 0, resolvedMaxScrollLeft),
15853
+ top: clamp(params.scroll.top, 0, resolvedMaxScrollTop)
15444
15854
  },
15445
15855
  centerVisibleWidth
15446
15856
  };
15447
15857
  }
15448
- function clamp5(value, min, max) {
15449
- return Math.min(Math.max(value, min), max);
15450
- }
15451
15858
 
15452
15859
  // src/domain/rows/body-layout.ts
15453
15860
  function resolveBodyLayout(params) {
@@ -16548,7 +16955,7 @@ function resolveSummaryTextX(params) {
16548
16955
  const maxX = visibleRect.x + visibleRect.width - padding;
16549
16956
  const preferredX = getAlignedTextX(rect, align, padding);
16550
16957
  if (align === "center") {
16551
- return clamp6(preferredX, minX, maxX);
16958
+ return clamp(preferredX, minX, maxX);
16552
16959
  }
16553
16960
  if (align === "right") {
16554
16961
  return Math.max(Math.min(preferredX, maxX), minX);
@@ -16590,9 +16997,6 @@ function intersectRects2(left, right) {
16590
16997
  height: maxY - y
16591
16998
  };
16592
16999
  }
16593
- function clamp6(value, min, max) {
16594
- return Math.min(Math.max(value, min), max);
16595
- }
16596
17000
  function isIndexInHighlightRange2(index, range) {
16597
17001
  return Boolean(range && index >= range.start && index <= range.end);
16598
17002
  }
@@ -17517,7 +17921,7 @@ function getTargetMergeColumns(columns, keys) {
17517
17921
  return [];
17518
17922
  }
17519
17923
  return columns.filter(
17520
- (column) => keys.some((key) => isSameDataIndex2(column.dataIndex, key))
17924
+ (column) => keys.some((key) => isSameDataIndex(column.dataIndex, key))
17521
17925
  );
17522
17926
  }
17523
17927
  function getCellCoverKey(rowIndex, columnKey) {
@@ -17550,14 +17954,6 @@ function normalizeMergeValue(value) {
17550
17954
  function isSameMergeValue(left, right) {
17551
17955
  return normalizeMergeValue(left) === normalizeMergeValue(right);
17552
17956
  }
17553
- function isSameDataIndex2(left, right) {
17554
- const leftPath = Array.isArray(left) ? left : [left];
17555
- const rightPath = Array.isArray(right) ? right : [right];
17556
- if (leftPath.length !== rightPath.length) {
17557
- return false;
17558
- }
17559
- return leftPath.every((key, index) => key === rightPath[index]);
17560
- }
17561
17957
  function getMergedCellWidth(columns, startIndex, colSpan) {
17562
17958
  let width = 0;
17563
17959
  for (let index = startIndex; index < startIndex + colSpan; index += 1) {
@@ -18322,8 +18718,6 @@ function isDragSourceColumn3(column, dragReorder) {
18322
18718
  }
18323
18719
  return column.leafIndex >= dragReorder.sourceLeafStartIndex && column.leafIndex <= dragReorder.sourceLeafEndIndex;
18324
18720
  }
18325
-
18326
- // src/rendering/primitives/header-text-layout.ts
18327
18721
  var ACTION_GAP = 4;
18328
18722
  var ACTION_SIZE = 14;
18329
18723
  var ACTION_PADDING_INLINE = 10;
@@ -18415,16 +18809,13 @@ function getStickyTextX(rect, visibleRect, align, padding) {
18415
18809
  const maxX = visibleRect.x + visibleRect.width - padding;
18416
18810
  const preferredX = getAlignedTextX2(rect, align, padding);
18417
18811
  if (align === "center") {
18418
- return clamp7(preferredX, minX, maxX);
18812
+ return clamp(preferredX, minX, maxX);
18419
18813
  }
18420
18814
  if (align === "right") {
18421
18815
  return Math.max(Math.min(preferredX, maxX), minX);
18422
18816
  }
18423
18817
  return Math.min(Math.max(preferredX, minX), maxX);
18424
18818
  }
18425
- function clamp7(value, min, max) {
18426
- return Math.min(Math.max(value, min), max);
18427
- }
18428
18819
 
18429
18820
  // src/rendering/primitives/draw-header.ts
18430
18821
  var ACTION_GAP2 = 4;
@@ -18544,7 +18935,13 @@ function drawHeaderCell(params, cell, clipRect) {
18544
18935
  }),
18545
18936
  contentInsetEnd: cell.node.children.length === 0 && collapseMarkerSet.hasRightMarker ? COLLAPSE_TRIGGER_WIDTH / 2 + COLLAPSE_TRIGGER_GAP + ACTION_PADDING_INLINE2 : 0
18546
18937
  });
18547
- const textY = rect.y + rect.height / 2;
18938
+ const textY = resolveHeaderContentCenterY(
18939
+ rect,
18940
+ titleContent,
18941
+ theme.fontSize,
18942
+ cell.node.style?.paddingBlock ?? 6,
18943
+ cell.node.style?.verticalAlign
18944
+ );
18548
18945
  ctx.textAlign = textLayout.align;
18549
18946
  if (params.rowSelection?.columnKey === cell.node.key && cell.node.children.length === 0) {
18550
18947
  descriptors.push({
@@ -18594,6 +18991,21 @@ function drawHeaderCell(params, cell, clipRect) {
18594
18991
  }
18595
18992
  ctx.restore();
18596
18993
  }
18994
+ function resolveHeaderContentCenterY(rect, contents, fontSize, paddingBlock, verticalAlign) {
18995
+ const contentHeight = Math.max(
18996
+ fontSize,
18997
+ ...contents.map(
18998
+ (content) => content.type === "img" ? Math.max(content.height ?? content.width ?? fontSize, 1) : fontSize
18999
+ )
19000
+ );
19001
+ if (verticalAlign === "top") {
19002
+ return rect.y + paddingBlock + contentHeight / 2;
19003
+ }
19004
+ if (verticalAlign === "bottom") {
19005
+ return rect.y + rect.height - paddingBlock - contentHeight / 2;
19006
+ }
19007
+ return rect.y + rect.height / 2;
19008
+ }
18597
19009
  function measureHeaderContentWidth(ctx, contents) {
18598
19010
  const gap = 4;
18599
19011
  return contents.reduce(
@@ -20788,250 +21200,6 @@ var ListTableSelectionController = class {
20788
21200
  }
20789
21201
  };
20790
21202
 
20791
- // src/services/summary-service.ts
20792
- var SUMMARY_ASYNC_BATCH_SIZE = 2e3;
20793
- var SUMMARY_ASYNC_FRAME_BUDGET = 8;
20794
- async function computeSummaryValuesAsync(params) {
20795
- const { rows, columns, signal } = params;
20796
- const summaryValues = /* @__PURE__ */ new Map();
20797
- const accumulators = [];
20798
- columns.forEach((column) => {
20799
- const accumulator = createSummaryAccumulator(column);
20800
- if (accumulator) {
20801
- accumulators.push(accumulator);
20802
- }
20803
- });
20804
- columns.forEach((column) => {
20805
- if (column.summaryTitle != null) {
20806
- summaryValues.set(column.key, column.summaryTitle);
20807
- }
20808
- });
20809
- if (accumulators.length === 0) {
20810
- return summaryValues;
20811
- }
20812
- for (let startIndex = 0; startIndex < rows.length; ) {
20813
- if (signal?.aborted) {
20814
- throw new Error("summary computation aborted");
20815
- }
20816
- const frameStart = now();
20817
- let endIndex = startIndex;
20818
- while (endIndex < rows.length) {
20819
- if (signal?.aborted) {
20820
- throw new Error("summary computation aborted");
20821
- }
20822
- const batchEndIndex = Math.min(
20823
- endIndex + SUMMARY_ASYNC_BATCH_SIZE,
20824
- rows.length
20825
- );
20826
- for (let rowIndex = endIndex; rowIndex < batchEndIndex; rowIndex += 1) {
20827
- const record = rows[rowIndex];
20828
- if (!record) {
20829
- continue;
20830
- }
20831
- accumulators.forEach((item) => {
20832
- updateSummaryAccumulator(item, record);
20833
- });
20834
- }
20835
- endIndex = batchEndIndex;
20836
- if (endIndex >= rows.length) {
20837
- break;
20838
- }
20839
- if (now() - frameStart >= SUMMARY_ASYNC_FRAME_BUDGET) {
20840
- break;
20841
- }
20842
- }
20843
- if (endIndex < rows.length) {
20844
- await yieldToMainThread2();
20845
- }
20846
- startIndex = endIndex;
20847
- }
20848
- accumulators.forEach((item) => {
20849
- summaryValues.set(
20850
- item.column.key,
20851
- finalizeSummaryValue(item, rows)
20852
- );
20853
- });
20854
- return summaryValues;
20855
- }
20856
- function createSummaryAccumulator(column) {
20857
- const config = resolveSummaryConfig2(column);
20858
- if (!config) {
20859
- return null;
20860
- }
20861
- return {
20862
- column,
20863
- config,
20864
- type: config.type ?? "sum",
20865
- valueCount: 0,
20866
- numericCount: 0,
20867
- sum: 0,
20868
- min: null,
20869
- max: null,
20870
- uniqueValues: /* @__PURE__ */ new Set()
20871
- };
20872
- }
20873
- function updateSummaryAccumulator(item, record) {
20874
- if (item.column.summaryTitle != null) {
20875
- return;
20876
- }
20877
- if (item.type === "rowCount" || item.type === "mergedRowCount") {
20878
- return;
20879
- }
20880
- const rawValue = normalizeSummaryValue(
20881
- getColumnRawValue(record, item.column, item.config)
20882
- );
20883
- if (rawValue == null) {
20884
- return;
20885
- }
20886
- item.valueCount += 1;
20887
- if (item.type === "unionCount") {
20888
- item.uniqueValues.add(String(rawValue));
20889
- return;
20890
- }
20891
- if (item.type === "count") {
20892
- return;
20893
- }
20894
- const numericValue = toNumber(rawValue);
20895
- if (numericValue == null) {
20896
- return;
20897
- }
20898
- item.numericCount += 1;
20899
- item.sum += numericValue;
20900
- item.min = item.min == null ? numericValue : Math.min(item.min, numericValue);
20901
- item.max = item.max == null ? numericValue : Math.max(item.max, numericValue);
20902
- }
20903
- function finalizeSummaryValue(item, rows) {
20904
- if (item.column.summaryTitle != null) {
20905
- return item.column.summaryTitle;
20906
- }
20907
- if (item.type === "rowCount") {
20908
- return formatSummaryOutput(item, String(rows.length), rows);
20909
- }
20910
- if (item.type === "mergedRowCount") {
20911
- return formatSummaryOutput(item, String(countMergedRows(rows)), rows);
20912
- }
20913
- if (item.type === "count") {
20914
- return formatSummaryOutput(item, String(item.valueCount), rows);
20915
- }
20916
- if (item.type === "unionCount") {
20917
- return formatSummaryOutput(item, String(item.uniqueValues.size), rows);
20918
- }
20919
- if (item.numericCount === 0) {
20920
- if (item.type === "min" || item.type === "max") {
20921
- return formatSummaryOutput(item, "", rows);
20922
- }
20923
- return formatSummaryOutput(item, "0", rows);
20924
- }
20925
- let result = item.sum;
20926
- if (item.type === "avg") {
20927
- result = item.sum / item.numericCount;
20928
- } else if (item.type === "min") {
20929
- result = item.min ?? 0;
20930
- } else if (item.type === "max") {
20931
- result = item.max ?? 0;
20932
- }
20933
- const rounded = roundByPrecision(result, item.config.precision);
20934
- const formatted = formatNumber(rounded, item.config.precision);
20935
- return formatSummaryOutput(item, formatted, rows);
20936
- }
20937
- function resolveSummaryConfig2(column) {
20938
- if (column.summary == null) {
20939
- return null;
20940
- }
20941
- if (column.summary === true) {
20942
- return { type: "sum" };
20943
- }
20944
- if (column.summary === false) {
20945
- return null;
20946
- }
20947
- return { type: "sum", ...column.summary };
20948
- }
20949
- function getColumnRawValue(record, column, config) {
20950
- if (config.valueGetter) {
20951
- return config.valueGetter(record);
20952
- }
20953
- const sortValue = column.sortValueGetter?.(record);
20954
- if (sortValue != null && sortValue !== "") {
20955
- return sortValue;
20956
- }
20957
- const filterValue = column.filterValueGetter?.(record);
20958
- if (filterValue != null && filterValue !== "") {
20959
- return filterValue;
20960
- }
20961
- return getValueByDataIndex(record, column.dataIndex);
20962
- }
20963
- function normalizeSummaryValue(value) {
20964
- if (value == null || value === "") {
20965
- return null;
20966
- }
20967
- if (typeof value === "number" || typeof value === "string") {
20968
- return value;
20969
- }
20970
- return null;
20971
- }
20972
- function toNumber(value) {
20973
- if (value == null) {
20974
- return null;
20975
- }
20976
- if (typeof value === "number") {
20977
- return Number.isNaN(value) ? null : value;
20978
- }
20979
- const parsed = Number(String(value).trim());
20980
- return Number.isNaN(parsed) ? null : parsed;
20981
- }
20982
- function roundByPrecision(value, precision) {
20983
- if (precision == null) {
20984
- return value;
20985
- }
20986
- return Number(value.toFixed(precision));
20987
- }
20988
- function formatNumber(value, precision) {
20989
- if (precision != null) {
20990
- return value.toFixed(precision);
20991
- }
20992
- if (Number.isInteger(value)) {
20993
- return String(value);
20994
- }
20995
- return value.toFixed(2);
20996
- }
20997
- function formatSummaryOutput(item, value, rows) {
20998
- if (item.config.formatter) {
20999
- return item.config.formatter(
21000
- value,
21001
- rows,
21002
- item.column
21003
- );
21004
- }
21005
- return value;
21006
- }
21007
- function countMergedRows(rows) {
21008
- return rows.reduce((count, record) => {
21009
- if (record == null || typeof record !== "object") {
21010
- return count + 1;
21011
- }
21012
- const rowSpan = record.rowSpan;
21013
- if (typeof rowSpan !== "number") {
21014
- return count + 1;
21015
- }
21016
- return rowSpan > 0 ? count + 1 : count;
21017
- }, 0);
21018
- }
21019
- function yieldToMainThread2() {
21020
- return new Promise((resolve) => {
21021
- if (typeof requestAnimationFrame === "function") {
21022
- requestAnimationFrame(() => resolve());
21023
- return;
21024
- }
21025
- setTimeout(resolve, 0);
21026
- });
21027
- }
21028
- function now() {
21029
- if (typeof performance !== "undefined" && typeof performance.now === "function") {
21030
- return performance.now();
21031
- }
21032
- return Date.now();
21033
- }
21034
-
21035
21203
  // src/domain/summary/summary-interaction.ts
21036
21204
  function isSummaryInteractionActive(params) {
21037
21205
  const now2 = params.now ?? Date.now();
@@ -21840,6 +22008,7 @@ var ListTableCore = class {
21840
22008
  __publicField(this, "debugManager");
21841
22009
  this.container = container;
21842
22010
  this.options = options;
22011
+ applyInitialColumnVisibility(options.columns);
21843
22012
  ensureColumnKeysInPlace(options.columns);
21844
22013
  this.domHost = new ListTableDomHost();
21845
22014
  this.canvasHost = new ListTableCanvasHost();
@@ -21885,6 +22054,7 @@ var ListTableCore = class {
21885
22054
  */
21886
22055
  updateOptions(options) {
21887
22056
  this.animationController.stopCarouselScroll();
22057
+ applyInitialColumnVisibility(options.columns);
21888
22058
  ensureColumnKeysInPlace(options.columns);
21889
22059
  if (options.expandable?.expandedRowKeys !== void 0 && !areSameRowKeySet(
21890
22060
  this.storeFacade.expandedRowKeys,
@@ -21938,8 +22108,8 @@ var ListTableCore = class {
21938
22108
  /**
21939
22109
  * 异步导出全部原始数据为 XLSX。
21940
22110
  */
21941
- exportXlsx() {
21942
- this.contentActionController.exportXlsx();
22111
+ exportXlsx(options) {
22112
+ this.contentActionController.exportXlsx(options);
21943
22113
  }
21944
22114
  /**
21945
22115
  * 滚动到指定行。
@@ -22060,8 +22230,8 @@ var ListTable = class {
22060
22230
  /**
22061
22231
  * 异步导出全部原始数据为 XLSX。
22062
22232
  */
22063
- exportXlsx() {
22064
- this.core?.exportXlsx();
22233
+ exportXlsx(options) {
22234
+ this.core?.exportXlsx(options);
22065
22235
  }
22066
22236
  /**
22067
22237
  * 滚动到指定行。