@canvas-components/list-table 0.2.1 → 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
@@ -324,6 +324,7 @@ function normalizeColumn(column, depth, parentKey) {
324
324
  minWidth: Number(column.minWidth) || DEFAULT_MIN_WIDTH,
325
325
  maxWidth: Number(column.maxWidth) || DEFAULT_MAX_WIDTH,
326
326
  align: column.align ?? "left",
327
+ headerAlign: column.headerAlign,
327
328
  fixed: column.fixed,
328
329
  hidden: column.hidden,
329
330
  ellipsis: column.ellipsis,
@@ -343,6 +344,7 @@ function normalizeColumn(column, depth, parentKey) {
343
344
  cellType: column.cellType,
344
345
  cellStyle: column.cellStyle,
345
346
  moneyFormat: column.moneyFormat,
347
+ dataFormat: column.dataFormat,
346
348
  headerStyle: column.headerStyle,
347
349
  summary: column.summary,
348
350
  summaryTitle: column.summaryTitle,
@@ -578,15 +580,28 @@ function cloneColumns(columns) {
578
580
  children: column.children ? cloneColumns(column.children) : void 0
579
581
  }));
580
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
+ }
581
593
  function replaceColumns(target, source) {
582
594
  target.splice(0, target.length, ...cloneColumns(source));
583
595
  }
584
596
  function buildHeaderSettingsItems(columns) {
585
597
  ensureColumnKeysInPlace(columns);
586
598
  const totalVisibleLeafCount = countVisibleLeafColumns(columns);
587
- return columns.map(
588
- (column) => buildHeaderSettingsItem(column, totalVisibleLeafCount, false)
589
- );
599
+ return columns.flatMap((column) => {
600
+ if (column.hideInSetting) {
601
+ return [];
602
+ }
603
+ return [buildHeaderSettingsItem(column, totalVisibleLeafCount, false)];
604
+ });
590
605
  }
591
606
  function setHeaderColumnVisible(columns, columnKey, visible) {
592
607
  if (!visible) {
@@ -646,9 +661,7 @@ function resolveCollapsedHeaderColumnMarkers(params) {
646
661
  if (visibleLeafKeys.length === 0) {
647
662
  return [];
648
663
  }
649
- const leafIndexMap = new Map(
650
- allLeafKeys.map((key, index) => [key, index])
651
- );
664
+ const leafIndexMap = new Map(allLeafKeys.map((key, index) => [key, index]));
652
665
  const markers = [];
653
666
  let previousVisibleIndex = -1;
654
667
  visibleLeafKeys.forEach((columnKey) => {
@@ -714,19 +727,87 @@ function restoreAllHiddenHeaderColumns(columns) {
714
727
  });
715
728
  return updated;
716
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
+ }
717
796
  function buildHeaderSettingsItem(column, totalVisibleLeafCount, parentHidden) {
718
797
  const hidden = parentHidden || !!column.hidden;
719
- const children = column.children?.map(
798
+ const children = column.children?.filter((child) => !child.hideInSetting).map(
720
799
  (child) => buildHeaderSettingsItem(child, totalVisibleLeafCount, hidden)
721
800
  );
722
801
  const leafCount = countLeafColumns([column]);
723
802
  const visibleLeafCount = hidden ? 0 : countVisibleLeafColumns([column]);
724
803
  const checked = leafCount > 0 && visibleLeafCount === leafCount;
725
804
  const indeterminate = visibleLeafCount > 0 && visibleLeafCount < leafCount;
726
- const disabled = visibleLeafCount > 0 && visibleLeafCount >= totalVisibleLeafCount;
805
+ const disabled = column.disableHide && checked || visibleLeafCount > 0 && visibleLeafCount >= totalVisibleLeafCount;
727
806
  return {
728
807
  key: resolveColumnKey(column),
729
- title: String(column.title ?? resolveColumnKey(column)),
808
+ title: String(
809
+ column.settingTitle ?? column.title ?? resolveColumnKey(column)
810
+ ),
730
811
  checked,
731
812
  indeterminate,
732
813
  disabled,
@@ -736,6 +817,9 @@ function buildHeaderSettingsItem(column, totalVisibleLeafCount, parentHidden) {
736
817
  function setColumnVisible(columns, columnKey, visible, ancestors = []) {
737
818
  for (const column of columns) {
738
819
  if (column.key === columnKey) {
820
+ if (!visible && column.disableHide) {
821
+ return false;
822
+ }
739
823
  ancestors.forEach((item) => {
740
824
  item.hidden = false;
741
825
  });
@@ -743,12 +827,10 @@ function setColumnVisible(columns, columnKey, visible, ancestors = []) {
743
827
  return true;
744
828
  }
745
829
  if (column.children?.length) {
746
- const updated = setColumnVisible(
747
- column.children,
748
- columnKey,
749
- visible,
750
- [...ancestors, column]
751
- );
830
+ const updated = setColumnVisible(column.children, columnKey, visible, [
831
+ ...ancestors,
832
+ column
833
+ ]);
752
834
  if (updated) {
753
835
  return true;
754
836
  }
@@ -757,6 +839,9 @@ function setColumnVisible(columns, columnKey, visible, ancestors = []) {
757
839
  return false;
758
840
  }
759
841
  function setSubtreeVisible(column, visible) {
842
+ if (!visible && column.disableHide) {
843
+ return;
844
+ }
760
845
  column.hidden = !visible;
761
846
  column.children?.forEach((child) => {
762
847
  setSubtreeVisible(child, visible);
@@ -5310,6 +5395,10 @@ function resolveColumnFormItemProps(column, context) {
5310
5395
  var CONTENT_HORIZONTAL_PADDING = 12;
5311
5396
  var CONTENT_GAP = 8;
5312
5397
  var CONTENT_VERTICAL_PADDING = 6;
5398
+ var THOUSANDS_NUMBER_FORMAT = new Intl.NumberFormat("zh-CN", {
5399
+ useGrouping: true,
5400
+ maximumFractionDigits: 20
5401
+ });
5313
5402
  function resolveBodyCellContents(params) {
5314
5403
  const { record, rowIndex, column } = params;
5315
5404
  const value = utils.getValueByDataIndex(record, column.dataIndex);
@@ -5323,6 +5412,14 @@ function resolveBodyCellContents(params) {
5323
5412
  record,
5324
5413
  rowIndex
5325
5414
  });
5415
+ if (column.dataFormat && column.dataFormat !== "default") {
5416
+ return [
5417
+ {
5418
+ type: "text",
5419
+ text: formattedText ?? formatListTableDataValue(value, column.dataFormat)
5420
+ }
5421
+ ];
5422
+ }
5326
5423
  if (column.cellType === "checkbox" || column.cellType === "radio" || column.cellType === "switch") {
5327
5424
  return [
5328
5425
  {
@@ -5483,6 +5580,26 @@ function formatMoneyValue(value, options) {
5483
5580
  const formattedDecimal = decimalText != null && decimalText.length > 0 ? `.${decimalText}` : "";
5484
5581
  return `${sign}${symbol}${formattedInteger}${formattedDecimal}`;
5485
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
+ }
5486
5603
  function parseMoneyNumber(value) {
5487
5604
  if (typeof value === "number") {
5488
5605
  return Number.isFinite(value) ? value : null;
@@ -9191,116 +9308,363 @@ var ListTableCarouselController = class {
9191
9308
  });
9192
9309
  }
9193
9310
  };
9194
- function getCellClipboardText(record, rowIndex, column) {
9195
- const value = utils.getValueByDataIndex(record, column.dataIndex);
9196
- const rendered = column.render?.(value, record, rowIndex, column);
9197
- if (rendered != null) {
9198
- 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;
9199
9330
  }
9200
- if (column.cellType === "checkbox" || column.cellType === "radio") {
9201
- 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;
9202
9366
  }
9203
- 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 {
9204
9381
  column,
9205
- value,
9206
- record,
9207
- rowIndex
9208
- }) ?? 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
+ };
9209
9391
  }
9210
- function createListTableSelectionCopyText(params) {
9211
- const columns = params.columns.filter(
9212
- (column2) => column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9213
- );
9214
- const columnRange = params.rangeHighlight.selectedColumnRange;
9215
- const rowRange = params.rangeHighlight.selectedRowRange;
9216
- const cellRange = params.rangeHighlight.selectedCellRange;
9217
- if (cellRange) {
9218
- const selectedColumns2 = params.columns.filter(
9219
- (column2, index) => index >= cellRange.startColumnIndex && index <= cellRange.endColumnIndex && column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9220
- );
9221
- return params.rows.slice(cellRange.startRowIndex, cellRange.endRowIndex + 1).map(
9222
- (record2, offset) => selectedColumns2.map(
9223
- (column2) => getCellClipboardText(
9224
- record2,
9225
- cellRange.startRowIndex + offset,
9226
- column2
9227
- )
9228
- ).join(" ")
9229
- ).join("\n");
9392
+ function updateSummaryAccumulator(item, record) {
9393
+ if (item.column.summaryTitle != null) {
9394
+ return;
9230
9395
  }
9231
- const mode = params.highlightMode ?? (rowRange && columnRange ? "cross" : rowRange ? "row" : "column");
9232
- const selectedColumns = columnRange ? params.columns.filter(
9233
- (column2, index) => index >= columnRange.start && index <= columnRange.end
9234
- ).filter(
9235
- (column2) => column2.key !== ROW_SELECTION_COLUMN_KEY && column2.key !== EXPAND_COLUMN_KEY
9236
- ) : columns;
9237
- rowRange ? Math.max(rowRange.start, 0) : 0;
9238
- rowRange ? Math.min(rowRange.end, params.rows.length - 1) : params.rows.length - 1;
9239
- if (mode === "column" && columnRange && params.selection.rowIndex == null) {
9240
- return params.rows.map(
9241
- (record2, rowIndex2) => selectedColumns.map((column2) => getCellClipboardText(record2, rowIndex2, column2)).join(" ")
9242
- ).join("\n");
9396
+ if (item.type === "rowCount" || item.type === "mergedRowCount") {
9397
+ return;
9243
9398
  }
9244
- const { rowIndex, columnKey } = params.selection;
9245
- const record = rowIndex == null ? void 0 : params.rows[rowIndex];
9246
- const column = columns.find((item) => item.key === columnKey);
9247
- return record && column && rowIndex != null ? getCellClipboardText(record, rowIndex, column) : null;
9248
- }
9249
- function createListTableRangeCopyText(params) {
9250
- return createListTableSelectionCopyText({
9251
- rows: params.rows,
9252
- columns: params.columns,
9253
- selection: { rowIndex: null, columnKey: null },
9254
- rangeHighlight: {
9255
- selectedCellRange: {
9256
- startRowIndex: Math.max(
9257
- Math.min(params.startRowIndex, params.endRowIndex),
9258
- 0
9259
- ),
9260
- endRowIndex: Math.min(
9261
- Math.max(params.startRowIndex, params.endRowIndex),
9262
- Math.max(params.rows.length - 1, 0)
9263
- ),
9264
- startColumnIndex: Math.max(
9265
- Math.min(params.startColumnIndex, params.endColumnIndex),
9266
- 0
9267
- ),
9268
- endColumnIndex: Math.min(
9269
- Math.max(params.startColumnIndex, params.endColumnIndex),
9270
- Math.max(params.columns.length - 1, 0)
9271
- )
9272
- }
9273
- }
9274
- });
9275
- }
9276
- async function copyBodyCellContent(params) {
9277
- const { rows, columns, rowIndex, columnKey } = params;
9278
- const record = rows[rowIndex];
9279
- const column = columns.find((item) => item.key === columnKey);
9280
- if (!record || !column) {
9399
+ const rawValue = normalizeSummaryValue(
9400
+ getColumnRawValue(record, item.column, item.config)
9401
+ );
9402
+ if (rawValue == null) {
9281
9403
  return;
9282
9404
  }
9283
- try {
9284
- await utils.copyText(getCellClipboardText(record, rowIndex, column));
9285
- } catch (error) {
9286
- console.error("[ListTable] Failed to copy cell:", error);
9405
+ item.valueCount += 1;
9406
+ if (item.type === "unionCount") {
9407
+ item.uniqueValues.add(String(rawValue));
9408
+ return;
9287
9409
  }
9288
- }
9289
- async function copyHeaderCellContent(params) {
9290
- const headerNode = findHeaderNodeByKey(params.headerTree, params.columnKey);
9291
- try {
9292
- await utils.copyText(headerNode?.title ?? params.columnKey);
9293
- } catch (error) {
9294
- console.error("[ListTable] Failed to copy header cell:", error);
9410
+ if (item.type === "count") {
9411
+ return;
9295
9412
  }
9296
- }
9297
- async function copyColumnContent(params) {
9298
- const { rows, columns, columnKey } = params;
9299
- const column = columns.find((item) => item.key === columnKey);
9300
- if (!column) {
9413
+ const numericValue = toNumber(rawValue);
9414
+ if (numericValue == null) {
9301
9415
  return;
9302
9416
  }
9303
- const values = rows.map((record, rowIndex) => [
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);
9421
+ }
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),
9626
+ Math.max(params.rows.length - 1, 0)
9627
+ ),
9628
+ startColumnIndex: Math.max(
9629
+ Math.min(params.startColumnIndex, params.endColumnIndex),
9630
+ 0
9631
+ ),
9632
+ endColumnIndex: Math.min(
9633
+ Math.max(params.startColumnIndex, params.endColumnIndex),
9634
+ Math.max(params.columns.length - 1, 0)
9635
+ )
9636
+ }
9637
+ }
9638
+ });
9639
+ }
9640
+ async function copyBodyCellContent(params) {
9641
+ const { rows, columns, rowIndex, columnKey } = params;
9642
+ const record = rows[rowIndex];
9643
+ const column = columns.find((item) => item.key === columnKey);
9644
+ if (!record || !column) {
9645
+ return;
9646
+ }
9647
+ try {
9648
+ await utils.copyText(getCellClipboardText(record, rowIndex, column));
9649
+ } catch (error) {
9650
+ console.error("[ListTable] Failed to copy cell:", error);
9651
+ }
9652
+ }
9653
+ async function copyHeaderCellContent(params) {
9654
+ const headerNode = findHeaderNodeByKey(params.headerTree, params.columnKey);
9655
+ try {
9656
+ await utils.copyText(headerNode?.title ?? params.columnKey);
9657
+ } catch (error) {
9658
+ console.error("[ListTable] Failed to copy header cell:", error);
9659
+ }
9660
+ }
9661
+ async function copyColumnContent(params) {
9662
+ const { rows, columns, columnKey } = params;
9663
+ const column = columns.find((item) => item.key === columnKey);
9664
+ if (!column) {
9665
+ return;
9666
+ }
9667
+ const values = rows.map((record, rowIndex) => [
9304
9668
  getCellClipboardText(record, rowIndex, column)
9305
9669
  ]);
9306
9670
  try {
@@ -9357,10 +9721,31 @@ async function exportAllRowsTxtContent(params) {
9357
9721
  });
9358
9722
  }
9359
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
+ }
9360
9741
  await utils.exportTableToXlsx({
9361
- fileName: buildTableExportFileName("xlsx"),
9362
- rows: params.rows,
9363
- 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
+ })),
9364
9749
  sheetName: "TableData"
9365
9750
  });
9366
9751
  }
@@ -9613,11 +9998,12 @@ var ListTableContentActionController = class {
9613
9998
  /**
9614
9999
  * 异步导出全部原始数据为 XLSX。
9615
10000
  */
9616
- exportXlsx() {
10001
+ exportXlsx(options) {
9617
10002
  this.startExportTask(
9618
10003
  () => exportAllRowsXlsxContent({
9619
10004
  rows: this.options.getOptions().dataSource,
9620
- columns: this.options.getLeafColumns()
10005
+ columns: this.options.getLeafColumns(),
10006
+ ...options
9621
10007
  }),
9622
10008
  "\u6B63\u5728\u5BFC\u51FA XLSX\u2026"
9623
10009
  );
@@ -10622,6 +11008,14 @@ function createListTableContextMenuActions(params) {
10622
11008
  onChangeSummaryPrecision: params.onChangeSummaryPrecision ? (columnKey, precision) => {
10623
11009
  params.hideMenu();
10624
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);
10625
11019
  } : void 0
10626
11020
  };
10627
11021
  }
@@ -10658,7 +11052,10 @@ function buildListTableContextMenuConfig(params) {
10658
11052
  const enableReset = enabledFeatures.has("reset");
10659
11053
  const enableDensity = enabledFeatures.has("density");
10660
11054
  const enableZoom = enabledFeatures.has("zoom");
11055
+ const enableAlignment = enabledFeatures.has("alignment");
11056
+ const enableDataFormat = enabledFeatures.has("dataFormat");
10661
11057
  const enableColumnVisibility = enabledFeatures.has("columnVisibility");
11058
+ const presentation = isHeaderArea ? getColumnPresentationConfig(columns, columnKey) : null;
10662
11059
  const headerItems = isHeaderArea && (enableColumnVisibility || enableColumnCollapse) ? buildHeaderSettingsItems(columns) : void 0;
10663
11060
  const currentColumnItem = headerItems ? findHeaderColumnItem(headerItems, columnKey) : null;
10664
11061
  const canToggleCurrentColumn = enableColumnCollapse && isHeaderArea && !isSelectionColumn && currentColumnItem != null && !currentColumnItem.disabled;
@@ -10669,7 +11066,7 @@ function buildListTableContextMenuConfig(params) {
10669
11066
  };
10670
11067
  if (isSummaryArea && !isSelectionColumn && actions.onChangeSummaryType) {
10671
11068
  const column = findSummaryColumn(columns, columnKey);
10672
- const summary = resolveSummaryConfig(column?.summary);
11069
+ const summary = resolveSummaryConfig2(column?.summary);
10673
11070
  summaryConfig.summaryColumnKey = columnKey;
10674
11071
  summaryConfig.summaryType = summary?.type ?? "sum";
10675
11072
  summaryConfig.summaryPrecision = summary?.precision;
@@ -10748,11 +11145,20 @@ function buildListTableContextMenuConfig(params) {
10748
11145
  onChangeDensity: enableDensity ? actions.onChangeDensity : void 0,
10749
11146
  onChangeZoom: enableZoom ? actions.onChangeZoom : void 0,
10750
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,
10751
11157
  onClose: actions.onClose,
10752
11158
  ...summaryConfig
10753
11159
  };
10754
11160
  }
10755
- function resolveSummaryConfig(summary) {
11161
+ function resolveSummaryConfig2(summary) {
10756
11162
  if (summary === true) {
10757
11163
  return { type: "sum" };
10758
11164
  }
@@ -10783,6 +11189,8 @@ var DEFAULT_CONTEXT_MENU_FEATURES = [
10783
11189
  "reset",
10784
11190
  "density",
10785
11191
  "zoom",
11192
+ "alignment",
11193
+ "dataFormat",
10786
11194
  "columnVisibility"
10787
11195
  ];
10788
11196
  function resolveEnabledContextMenuFeatures(contextMenu) {
@@ -11190,7 +11598,7 @@ async function filterRowsAsync(params) {
11190
11598
  }
11191
11599
  }
11192
11600
  if (endIndex < rows.length) {
11193
- await yieldToMainThread();
11601
+ await yieldToMainThread2();
11194
11602
  }
11195
11603
  }
11196
11604
  return result;
@@ -11258,7 +11666,7 @@ async function getColumnFilterOptionsAsync(params) {
11258
11666
  optionCountMap.set(value, (optionCountMap.get(value) ?? 0) + 1);
11259
11667
  }
11260
11668
  if (endIndex < dataSource.length) {
11261
- await yieldToMainThread();
11669
+ await yieldToMainThread2();
11262
11670
  }
11263
11671
  }
11264
11672
  const optionItems = explicitOptions.length > 0 ? explicitOptions.map((item) => ({
@@ -11294,7 +11702,7 @@ async function getColumnFilterOptionsAsync(params) {
11294
11702
  ...optionItems
11295
11703
  ];
11296
11704
  }
11297
- function yieldToMainThread() {
11705
+ function yieldToMainThread2() {
11298
11706
  return new Promise((resolve) => {
11299
11707
  setTimeout(resolve, 0);
11300
11708
  });
@@ -11527,6 +11935,8 @@ function showHeaderContextMenu(params) {
11527
11935
  onToggleSummary,
11528
11936
  onChangeSummaryType,
11529
11937
  onChangeSummaryPrecision,
11938
+ onChangeAlignment,
11939
+ onChangeDataFormat,
11530
11940
  summaryVisible,
11531
11941
  getSelectionRange,
11532
11942
  onCopySelection,
@@ -11601,6 +12011,8 @@ function showHeaderContextMenu(params) {
11601
12011
  onToggleSummary,
11602
12012
  onChangeSummaryType,
11603
12013
  onChangeSummaryPrecision,
12014
+ onChangeAlignment,
12015
+ onChangeDataFormat,
11604
12016
  onCopySelection,
11605
12017
  onCopyCustomSelection
11606
12018
  })
@@ -13364,19 +13776,55 @@ var ListTableEventController = class {
13364
13776
  this.host.render();
13365
13777
  },
13366
13778
  onChangeSummaryType: (columnKey, type) => {
13367
- updateSummaryColumn(this.host.options.columns, columnKey, (summary) => ({
13368
- ...summary,
13369
- type
13370
- }));
13779
+ updateSummaryColumn(
13780
+ this.host.options.columns,
13781
+ columnKey,
13782
+ (summary) => ({
13783
+ ...summary,
13784
+ type
13785
+ })
13786
+ );
13371
13787
  this.host.refreshRuntimeColumns();
13372
13788
  this.host.persistColumnConfig();
13373
13789
  this.host.render();
13374
13790
  },
13375
13791
  onChangeSummaryPrecision: (columnKey, precision) => {
13376
- updateSummaryColumn(this.host.options.columns, columnKey, (summary) => ({
13377
- ...summary,
13378
- precision
13379
- }));
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
+ }
13380
13828
  this.host.refreshRuntimeColumns();
13381
13829
  this.host.persistColumnConfig();
13382
13830
  this.host.render();
@@ -13843,7 +14291,10 @@ var ListTableEventController = class {
13843
14291
  const width = snapshot?.width ?? this.host.canvasElement.width;
13844
14292
  const position = {
13845
14293
  x: Math.min(Math.max(pointer.x, 0), Math.max(width - 1, 0)),
13846
- 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
+ )
13847
14298
  };
13848
14299
  const result = this.host.resolvePointerHit(position.x, position.y);
13849
14300
  if (result.area !== "body" && result.area !== "body-content" || typeof result.rowIndex !== "number" || !result.columnKey) {
@@ -14828,6 +15279,27 @@ function applyStoredColumnConfig(columns, storedColumns) {
14828
15279
  if (stored) {
14829
15280
  col.width = stored.width;
14830
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
+ }
14831
15303
  if (stored.fixed) {
14832
15304
  col.fixed = stored.fixed;
14833
15305
  } else {
@@ -14861,6 +15333,11 @@ function buildStoredColumnConfig(columns, sortState, filterState, zoom, summaryR
14861
15333
  width: col.width ?? 160,
14862
15334
  fixed: col.fixed,
14863
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,
14864
15341
  summary: col.summary === true ? { type: "sum" } : col.summary ? {
14865
15342
  type: col.summary.type,
14866
15343
  precision: col.summary.precision
@@ -15180,7 +15657,7 @@ function buildHeaderNode(column, leafColumns, maxDepth) {
15180
15657
  rowSpan: 1,
15181
15658
  leafStartIndex,
15182
15659
  leafEndIndex,
15183
- align: column.align ?? "left",
15660
+ align: column.headerAlign ?? column.align ?? "left",
15184
15661
  fixed: column.fixed,
15185
15662
  style: column.headerStyle,
15186
15663
  column,
@@ -15198,7 +15675,7 @@ function buildHeaderNode(column, leafColumns, maxDepth) {
15198
15675
  rowSpan: maxDepth - column.depth + 1,
15199
15676
  leafStartIndex: leafIndex,
15200
15677
  leafEndIndex: leafIndex,
15201
- align: column.align ?? "left",
15678
+ align: column.headerAlign ?? column.align ?? "left",
15202
15679
  fixed: column.fixed,
15203
15680
  style: column.headerStyle,
15204
15681
  column,
@@ -18460,7 +18937,13 @@ function drawHeaderCell(params, cell, clipRect) {
18460
18937
  }),
18461
18938
  contentInsetEnd: cell.node.children.length === 0 && collapseMarkerSet.hasRightMarker ? COLLAPSE_TRIGGER_WIDTH / 2 + COLLAPSE_TRIGGER_GAP + ACTION_PADDING_INLINE2 : 0
18462
18939
  });
18463
- 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
+ );
18464
18947
  ctx.textAlign = textLayout.align;
18465
18948
  if (params.rowSelection?.columnKey === cell.node.key && cell.node.children.length === 0) {
18466
18949
  descriptors.push({
@@ -18510,6 +18993,21 @@ function drawHeaderCell(params, cell, clipRect) {
18510
18993
  }
18511
18994
  ctx.restore();
18512
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
+ }
18513
19011
  function measureHeaderContentWidth(ctx, contents) {
18514
19012
  const gap = 4;
18515
19013
  return contents.reduce(
@@ -20703,248 +21201,6 @@ var ListTableSelectionController = class {
20703
21201
  this.summarySelected = false;
20704
21202
  }
20705
21203
  };
20706
- var SUMMARY_ASYNC_BATCH_SIZE = 2e3;
20707
- var SUMMARY_ASYNC_FRAME_BUDGET = 8;
20708
- async function computeSummaryValuesAsync(params) {
20709
- const { rows, columns, signal } = params;
20710
- const summaryValues = /* @__PURE__ */ new Map();
20711
- const accumulators = [];
20712
- columns.forEach((column) => {
20713
- const accumulator = createSummaryAccumulator(column);
20714
- if (accumulator) {
20715
- accumulators.push(accumulator);
20716
- }
20717
- });
20718
- columns.forEach((column) => {
20719
- if (column.summaryTitle != null) {
20720
- summaryValues.set(column.key, column.summaryTitle);
20721
- }
20722
- });
20723
- if (accumulators.length === 0) {
20724
- return summaryValues;
20725
- }
20726
- for (let startIndex = 0; startIndex < rows.length; ) {
20727
- if (signal?.aborted) {
20728
- throw new Error("summary computation aborted");
20729
- }
20730
- const frameStart = now();
20731
- let endIndex = startIndex;
20732
- while (endIndex < rows.length) {
20733
- if (signal?.aborted) {
20734
- throw new Error("summary computation aborted");
20735
- }
20736
- const batchEndIndex = Math.min(
20737
- endIndex + SUMMARY_ASYNC_BATCH_SIZE,
20738
- rows.length
20739
- );
20740
- for (let rowIndex = endIndex; rowIndex < batchEndIndex; rowIndex += 1) {
20741
- const record = rows[rowIndex];
20742
- if (!record) {
20743
- continue;
20744
- }
20745
- accumulators.forEach((item) => {
20746
- updateSummaryAccumulator(item, record);
20747
- });
20748
- }
20749
- endIndex = batchEndIndex;
20750
- if (endIndex >= rows.length) {
20751
- break;
20752
- }
20753
- if (now() - frameStart >= SUMMARY_ASYNC_FRAME_BUDGET) {
20754
- break;
20755
- }
20756
- }
20757
- if (endIndex < rows.length) {
20758
- await yieldToMainThread2();
20759
- }
20760
- startIndex = endIndex;
20761
- }
20762
- accumulators.forEach((item) => {
20763
- summaryValues.set(
20764
- item.column.key,
20765
- finalizeSummaryValue(item, rows)
20766
- );
20767
- });
20768
- return summaryValues;
20769
- }
20770
- function createSummaryAccumulator(column) {
20771
- const config = resolveSummaryConfig2(column);
20772
- if (!config) {
20773
- return null;
20774
- }
20775
- return {
20776
- column,
20777
- config,
20778
- type: config.type ?? "sum",
20779
- valueCount: 0,
20780
- numericCount: 0,
20781
- sum: 0,
20782
- min: null,
20783
- max: null,
20784
- uniqueValues: /* @__PURE__ */ new Set()
20785
- };
20786
- }
20787
- function updateSummaryAccumulator(item, record) {
20788
- if (item.column.summaryTitle != null) {
20789
- return;
20790
- }
20791
- if (item.type === "rowCount" || item.type === "mergedRowCount") {
20792
- return;
20793
- }
20794
- const rawValue = normalizeSummaryValue(
20795
- getColumnRawValue(record, item.column, item.config)
20796
- );
20797
- if (rawValue == null) {
20798
- return;
20799
- }
20800
- item.valueCount += 1;
20801
- if (item.type === "unionCount") {
20802
- item.uniqueValues.add(String(rawValue));
20803
- return;
20804
- }
20805
- if (item.type === "count") {
20806
- return;
20807
- }
20808
- const numericValue = toNumber(rawValue);
20809
- if (numericValue == null) {
20810
- return;
20811
- }
20812
- item.numericCount += 1;
20813
- item.sum += numericValue;
20814
- item.min = item.min == null ? numericValue : Math.min(item.min, numericValue);
20815
- item.max = item.max == null ? numericValue : Math.max(item.max, numericValue);
20816
- }
20817
- function finalizeSummaryValue(item, rows) {
20818
- if (item.column.summaryTitle != null) {
20819
- return item.column.summaryTitle;
20820
- }
20821
- if (item.type === "rowCount") {
20822
- return formatSummaryOutput(item, String(rows.length), rows);
20823
- }
20824
- if (item.type === "mergedRowCount") {
20825
- return formatSummaryOutput(item, String(countMergedRows(rows)), rows);
20826
- }
20827
- if (item.type === "count") {
20828
- return formatSummaryOutput(item, String(item.valueCount), rows);
20829
- }
20830
- if (item.type === "unionCount") {
20831
- return formatSummaryOutput(item, String(item.uniqueValues.size), rows);
20832
- }
20833
- if (item.numericCount === 0) {
20834
- if (item.type === "min" || item.type === "max") {
20835
- return formatSummaryOutput(item, "", rows);
20836
- }
20837
- return formatSummaryOutput(item, "0", rows);
20838
- }
20839
- let result = item.sum;
20840
- if (item.type === "avg") {
20841
- result = item.sum / item.numericCount;
20842
- } else if (item.type === "min") {
20843
- result = item.min ?? 0;
20844
- } else if (item.type === "max") {
20845
- result = item.max ?? 0;
20846
- }
20847
- const rounded = roundByPrecision(result, item.config.precision);
20848
- const formatted = formatNumber(rounded, item.config.precision);
20849
- return formatSummaryOutput(item, formatted, rows);
20850
- }
20851
- function resolveSummaryConfig2(column) {
20852
- if (column.summary == null) {
20853
- return null;
20854
- }
20855
- if (column.summary === true) {
20856
- return { type: "sum" };
20857
- }
20858
- if (column.summary === false) {
20859
- return null;
20860
- }
20861
- return { type: "sum", ...column.summary };
20862
- }
20863
- function getColumnRawValue(record, column, config) {
20864
- if (config.valueGetter) {
20865
- return config.valueGetter(record);
20866
- }
20867
- const sortValue = column.sortValueGetter?.(record);
20868
- if (sortValue != null && sortValue !== "") {
20869
- return sortValue;
20870
- }
20871
- const filterValue = column.filterValueGetter?.(record);
20872
- if (filterValue != null && filterValue !== "") {
20873
- return filterValue;
20874
- }
20875
- return utils.getValueByDataIndex(record, column.dataIndex);
20876
- }
20877
- function normalizeSummaryValue(value) {
20878
- if (value == null || value === "") {
20879
- return null;
20880
- }
20881
- if (typeof value === "number" || typeof value === "string") {
20882
- return value;
20883
- }
20884
- return null;
20885
- }
20886
- function toNumber(value) {
20887
- if (value == null) {
20888
- return null;
20889
- }
20890
- if (typeof value === "number") {
20891
- return Number.isNaN(value) ? null : value;
20892
- }
20893
- const parsed = Number(String(value).trim());
20894
- return Number.isNaN(parsed) ? null : parsed;
20895
- }
20896
- function roundByPrecision(value, precision) {
20897
- if (precision == null) {
20898
- return value;
20899
- }
20900
- return Number(value.toFixed(precision));
20901
- }
20902
- function formatNumber(value, precision) {
20903
- if (precision != null) {
20904
- return value.toFixed(precision);
20905
- }
20906
- if (Number.isInteger(value)) {
20907
- return String(value);
20908
- }
20909
- return value.toFixed(2);
20910
- }
20911
- function formatSummaryOutput(item, value, rows) {
20912
- if (item.config.formatter) {
20913
- return item.config.formatter(
20914
- value,
20915
- rows,
20916
- item.column
20917
- );
20918
- }
20919
- return value;
20920
- }
20921
- function countMergedRows(rows) {
20922
- return rows.reduce((count, record) => {
20923
- if (record == null || typeof record !== "object") {
20924
- return count + 1;
20925
- }
20926
- const rowSpan = record.rowSpan;
20927
- if (typeof rowSpan !== "number") {
20928
- return count + 1;
20929
- }
20930
- return rowSpan > 0 ? count + 1 : count;
20931
- }, 0);
20932
- }
20933
- function yieldToMainThread2() {
20934
- return new Promise((resolve) => {
20935
- if (typeof requestAnimationFrame === "function") {
20936
- requestAnimationFrame(() => resolve());
20937
- return;
20938
- }
20939
- setTimeout(resolve, 0);
20940
- });
20941
- }
20942
- function now() {
20943
- if (typeof performance !== "undefined" && typeof performance.now === "function") {
20944
- return performance.now();
20945
- }
20946
- return Date.now();
20947
- }
20948
21204
 
20949
21205
  // src/domain/summary/summary-interaction.ts
20950
21206
  function isSummaryInteractionActive(params) {
@@ -21754,6 +22010,7 @@ var ListTableCore = class {
21754
22010
  __publicField(this, "debugManager");
21755
22011
  this.container = container;
21756
22012
  this.options = options;
22013
+ applyInitialColumnVisibility(options.columns);
21757
22014
  ensureColumnKeysInPlace(options.columns);
21758
22015
  this.domHost = new ListTableDomHost();
21759
22016
  this.canvasHost = new ListTableCanvasHost();
@@ -21799,6 +22056,7 @@ var ListTableCore = class {
21799
22056
  */
21800
22057
  updateOptions(options) {
21801
22058
  this.animationController.stopCarouselScroll();
22059
+ applyInitialColumnVisibility(options.columns);
21802
22060
  ensureColumnKeysInPlace(options.columns);
21803
22061
  if (options.expandable?.expandedRowKeys !== void 0 && !areSameRowKeySet(
21804
22062
  this.storeFacade.expandedRowKeys,
@@ -21852,8 +22110,8 @@ var ListTableCore = class {
21852
22110
  /**
21853
22111
  * 异步导出全部原始数据为 XLSX。
21854
22112
  */
21855
- exportXlsx() {
21856
- this.contentActionController.exportXlsx();
22113
+ exportXlsx(options) {
22114
+ this.contentActionController.exportXlsx(options);
21857
22115
  }
21858
22116
  /**
21859
22117
  * 滚动到指定行。
@@ -21974,8 +22232,8 @@ var ListTable = class {
21974
22232
  /**
21975
22233
  * 异步导出全部原始数据为 XLSX。
21976
22234
  */
21977
- exportXlsx() {
21978
- this.core?.exportXlsx();
22235
+ exportXlsx(options) {
22236
+ this.core?.exportXlsx(options);
21979
22237
  }
21980
22238
  /**
21981
22239
  * 滚动到指定行。