@canvas-components/list-table 0.3.22 → 0.3.24

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
@@ -1090,16 +1090,149 @@ function applyInitialColumnVisibility(columns) {
1090
1090
  function replaceColumns(target, source) {
1091
1091
  target.splice(0, target.length, ...cloneColumns(source));
1092
1092
  }
1093
+ function preserveUserAddedColumns(params) {
1094
+ const keys = /* @__PURE__ */ new Set();
1095
+ const collect = (columns) => {
1096
+ columns.forEach((column) => {
1097
+ keys.add(resolveColumnKey(column));
1098
+ if (column.children?.length) collect(column.children);
1099
+ });
1100
+ };
1101
+ collect(params.nextColumns);
1102
+ const preserve = (source, target) => {
1103
+ source.forEach((column) => {
1104
+ const key = resolveColumnKey(column);
1105
+ if (column.userDefined && !keys.has(key)) {
1106
+ target.push({ ...column });
1107
+ keys.add(key);
1108
+ } else if (column.children?.length) {
1109
+ const matching = findColumnNode(params.nextColumns, key);
1110
+ if (matching?.children) preserve(column.children, matching.children);
1111
+ }
1112
+ });
1113
+ };
1114
+ preserve(params.runtimeColumns, params.nextColumns);
1115
+ }
1093
1116
  function buildHeaderSettingsItems(columns) {
1094
1117
  ensureColumnKeysInPlace(columns);
1095
1118
  const totalVisibleLeafCount = countVisibleLeafColumns(columns);
1096
- return columns.flatMap((column) => {
1119
+ return columns.flatMap((column, index) => {
1097
1120
  if (column.hideInSetting) {
1098
1121
  return [];
1099
1122
  }
1100
- return [buildHeaderSettingsItem(column, totalVisibleLeafCount, false)];
1123
+ return [
1124
+ buildHeaderSettingsItem(
1125
+ column,
1126
+ totalVisibleLeafCount,
1127
+ false,
1128
+ index + 1,
1129
+ columns.length
1130
+ )
1131
+ ];
1101
1132
  });
1102
1133
  }
1134
+ function saveHeaderSettingsColumn(columns, draft) {
1135
+ const title = draft.title.trim();
1136
+ if (!title) return "\u8BF7\u8F93\u5165\u5217\u540D\u79F0";
1137
+ const existing = draft.key ? findColumnNode(columns, draft.key) : null;
1138
+ if (draft.key && !existing) return "\u5217\u4E0D\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5217\u663E\u793A\u83DC\u5355";
1139
+ const parent = !existing && draft.parentKey ? findColumnNode(columns, draft.parentKey) : null;
1140
+ if (draft.parentKey && !existing && !parent?.children?.length) {
1141
+ return "\u6240\u5C5E\u591A\u7EA7\u8868\u5934\u4E0D\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5217\u663E\u793A\u83DC\u5355";
1142
+ }
1143
+ const siblings = existing ? findSiblingColumnsByKey(columns, draft.key) : parent?.children ?? columns;
1144
+ if (!siblings) return "\u5217\u4E0D\u5B58\u5728\uFF0C\u8BF7\u91CD\u65B0\u6253\u5F00\u5217\u663E\u793A\u83DC\u5355";
1145
+ const maxOrder = siblings.length + (existing ? 0 : 1);
1146
+ if (draft.order != null && (!Number.isInteger(draft.order) || draft.order < 1 || draft.order > maxOrder)) {
1147
+ return `\u5217\u987A\u5E8F\u987B\u4ECB\u4E8E 1 \u548C ${maxOrder} \u4E4B\u95F4`;
1148
+ }
1149
+ const minWidth = draft.minWidth ?? 40;
1150
+ const maxWidth = draft.maxWidth ?? 2e3;
1151
+ const width = draft.width ?? 160;
1152
+ if (![minWidth, maxWidth, width].every(
1153
+ (value) => Number.isFinite(value) && value > 0
1154
+ ) || minWidth > maxWidth || width < minWidth || width > maxWidth) {
1155
+ return "\u5BBD\u5EA6\u987B\u4ECB\u4E8E\u6700\u5C0F\u5BBD\u5EA6\u548C\u6700\u5927\u5BBD\u5EA6\u4E4B\u95F4";
1156
+ }
1157
+ if (existing && !existing.userDefined) {
1158
+ existing.title = title;
1159
+ existing.settingTitle = title;
1160
+ existing.userTitle = title;
1161
+ existing.width = width;
1162
+ existing.minWidth = minWidth;
1163
+ existing.maxWidth = maxWidth;
1164
+ if (draft.order != null) moveColumnToOrder(siblings, existing, draft.order);
1165
+ return null;
1166
+ }
1167
+ const dataIndex = draft.dataIndex?.trim();
1168
+ if (!dataIndex || dataIndex.split(".").some((part) => !part.trim())) {
1169
+ return "dataIndex \u4E3A\u5FC5\u586B\u9879";
1170
+ }
1171
+ if (isHeaderDataIndexUsed(columns, dataIndex, draft.key)) {
1172
+ return "\u8BE5 dataIndex \u5DF2\u88AB\u5176\u4ED6\u5217\u4F7F\u7528";
1173
+ }
1174
+ const column = existing ?? { key: createUserColumnKey(columns) };
1175
+ column.title = title;
1176
+ column.settingTitle = title;
1177
+ column.dataIndex = dataIndex.split(".");
1178
+ column.width = width;
1179
+ column.minWidth = minWidth;
1180
+ column.maxWidth = maxWidth;
1181
+ column.fixed = draft.fixed;
1182
+ column.userDefined = true;
1183
+ column.allowSort = true;
1184
+ column.sorter = true;
1185
+ if (existing && draft.order != null) {
1186
+ moveColumnToOrder(siblings, existing, draft.order);
1187
+ } else if (!existing) {
1188
+ siblings.splice((draft.order ?? maxOrder) - 1, 0, column);
1189
+ }
1190
+ return null;
1191
+ }
1192
+ function findSiblingColumnsByKey(columns, key) {
1193
+ if (columns.some((column) => resolveColumnKey(column) === key))
1194
+ return columns;
1195
+ for (const column of columns) {
1196
+ if (!column.children?.length) continue;
1197
+ const siblings = findSiblingColumnsByKey(column.children, key);
1198
+ if (siblings) return siblings;
1199
+ }
1200
+ return null;
1201
+ }
1202
+ function moveColumnToOrder(siblings, column, order) {
1203
+ const currentIndex = siblings.indexOf(column);
1204
+ if (currentIndex < 0 || currentIndex === order - 1) return;
1205
+ siblings.splice(currentIndex, 1);
1206
+ siblings.splice(order - 1, 0, column);
1207
+ }
1208
+ function deleteHeaderSettingsColumn(columns, columnKey) {
1209
+ const target = findColumnNode(columns, columnKey);
1210
+ if (!target?.userDefined || countVisibleLeafColumns(columns) <= countVisibleLeafColumns([target]))
1211
+ return false;
1212
+ const remove = (items) => {
1213
+ const index = items.findIndex(
1214
+ (column) => resolveColumnKey(column) === columnKey
1215
+ );
1216
+ if (index >= 0) {
1217
+ items.splice(index, 1);
1218
+ return true;
1219
+ }
1220
+ return items.some(
1221
+ (column) => column.children?.length && remove(column.children)
1222
+ );
1223
+ };
1224
+ return remove(columns);
1225
+ }
1226
+ function createUserColumnKey(columns) {
1227
+ let index = 1;
1228
+ while (findColumnNode(columns, `user-column-${index}`)) index += 1;
1229
+ return `user-column-${index}`;
1230
+ }
1231
+ function isHeaderDataIndexUsed(columns, dataIndex, excludeKey) {
1232
+ return columns.some(
1233
+ (column) => resolveColumnKey(column) !== excludeKey && column.dataIndex != null && stringifyDataIndex(column.dataIndex) === dataIndex || column.children?.length && isHeaderDataIndexUsed(column.children, dataIndex, excludeKey)
1234
+ );
1235
+ }
1103
1236
  function setHeaderColumnVisible(columns, columnKey, visible) {
1104
1237
  if (!visible) {
1105
1238
  const targetLeafCount = getColumnLeafCount(columns, columnKey);
@@ -1298,10 +1431,18 @@ function findColumnNode(columns, columnKey) {
1298
1431
  }
1299
1432
  return null;
1300
1433
  }
1301
- function buildHeaderSettingsItem(column, totalVisibleLeafCount, parentHidden) {
1434
+ function buildHeaderSettingsItem(column, totalVisibleLeafCount, parentHidden, order, siblingCount) {
1302
1435
  const hidden = parentHidden || !!column.hidden;
1303
- const children = column.children?.filter((child) => !child.hideInSetting).map(
1304
- (child) => buildHeaderSettingsItem(child, totalVisibleLeafCount, hidden)
1436
+ const children = column.children?.flatMap(
1437
+ (child, index) => child.hideInSetting ? [] : [
1438
+ buildHeaderSettingsItem(
1439
+ child,
1440
+ totalVisibleLeafCount,
1441
+ hidden,
1442
+ index + 1,
1443
+ column.children.length
1444
+ )
1445
+ ]
1305
1446
  );
1306
1447
  const leafCount = countLeafColumns([column]);
1307
1448
  const visibleLeafCount = hidden ? 0 : countVisibleLeafColumns([column]);
@@ -1313,6 +1454,14 @@ function buildHeaderSettingsItem(column, totalVisibleLeafCount, parentHidden) {
1313
1454
  title: String(
1314
1455
  column.settingTitle ?? column.title ?? resolveColumnKey(column)
1315
1456
  ),
1457
+ dataIndex: column.dataIndex == null ? void 0 : stringifyDataIndex(column.dataIndex),
1458
+ userDefined: column.userDefined === true,
1459
+ width: column.width,
1460
+ minWidth: column.minWidth,
1461
+ maxWidth: column.maxWidth,
1462
+ fixed: column.fixed,
1463
+ order,
1464
+ siblingCount,
1316
1465
  checked,
1317
1466
  indeterminate,
1318
1467
  disabled,
@@ -6489,12 +6638,12 @@ function queryFilterWorkerEntrypoint() {
6489
6638
  let filters = [];
6490
6639
  const matchedIndices = [];
6491
6640
  const now2 = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
6492
- const escapeRegExp2 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6641
+ const escapeRegExp3 = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
6493
6642
  const wildcardToRegExp2 = (value) => {
6494
6643
  const pattern = Array.from(value).map((char) => {
6495
6644
  if (char === "%") return ".*";
6496
6645
  if (char === "_") return ".";
6497
- return escapeRegExp2(char);
6646
+ return escapeRegExp3(char);
6498
6647
  }).join("");
6499
6648
  return new RegExp(`^${pattern}$`, "i");
6500
6649
  };
@@ -11211,7 +11360,6 @@ function roundRectPath3(ctx, x, y, width, height, radius) {
11211
11360
  var TAG_HORIZONTAL_PADDING = 8;
11212
11361
  var TAG_HEIGHT = 22;
11213
11362
  var TAG_RADIUS = 4;
11214
- var TAG_TEXT_OPTICAL_OFFSET_Y = 1;
11215
11363
  var ANT_TAG_PRESET_MAP = {
11216
11364
  default: {
11217
11365
  backgroundColor: "#fafafa",
@@ -11357,7 +11505,7 @@ function drawBodyTagContent(params) {
11357
11505
  textIndent,
11358
11506
  textAlign: resolveContentTextAlign(content, "center")
11359
11507
  });
11360
- const centerY = top + height / 2 + TAG_TEXT_OPTICAL_OFFSET_Y;
11508
+ const centerY = rect.y + rect.height / 2;
11361
11509
  const textY = resolveCenteredTextBaselineY({
11362
11510
  centerY,
11363
11511
  ascent: bounds.ascent,
@@ -11566,7 +11714,7 @@ function drawBodyTextContent(params) {
11566
11714
  textHeight: bounds.height,
11567
11715
  color: theme.textSelectionBackgroundColor ?? "#99c2ff"
11568
11716
  });
11569
- if (searchMatch && searchMatch.rowIndex === rowIndex && searchMatch.columnKey === column.key && searchMatch.keyword) {
11717
+ if (searchMatch && searchMatch.rowIndex === rowIndex && searchMatch.columnKey === column.key && (searchMatch.contentIndex == null || searchMatch.contentIndex === contentIndex) && searchMatch.keyword) {
11570
11718
  const start = Math.max(0, Math.min(searchMatch.start, content.text.length));
11571
11719
  const end = Math.max(start, Math.min(searchMatch.end, content.text.length));
11572
11720
  const prefixWidth = ctx.measureText(content.text.slice(0, start)).width;
@@ -12322,6 +12470,12 @@ function resolveRawBodyCellContents(params) {
12322
12470
  }
12323
12471
  ];
12324
12472
  }
12473
+ if (column.cellType === "emoji") {
12474
+ return normalizeCellContents({
12475
+ type: "emoji",
12476
+ emoji: formattedText ?? String(value ?? "")
12477
+ });
12478
+ }
12325
12479
  if (column.cellType === "money") {
12326
12480
  return [
12327
12481
  {
@@ -12379,6 +12533,21 @@ function normalizeDrawableCellContents(contents) {
12379
12533
  ).map(normalizeCellContentItem);
12380
12534
  }
12381
12535
  function normalizeCellContentItem(content) {
12536
+ if (content.type === "emoji") {
12537
+ const { emoji, size, ...rest } = content;
12538
+ return {
12539
+ ...rest,
12540
+ type: "text",
12541
+ text: emoji,
12542
+ fontSize: size ?? 20,
12543
+ style: {
12544
+ ...content.style,
12545
+ fontSize: content.style?.fontSize ?? size ?? 20,
12546
+ fontWeight: content.style?.fontWeight ?? "normal",
12547
+ fontFamily: content.style?.fontFamily ?? '"Segoe UI Emoji", "Apple Color Emoji", "Noto Color Emoji", "Segoe UI Symbol", sans-serif'
12548
+ }
12549
+ };
12550
+ }
12382
12551
  if (content.type === "timeline") {
12383
12552
  return { ...content, style: { ...content.style, display: "block" } };
12384
12553
  }
@@ -13840,6 +14009,9 @@ function buildBodyContentsPlainText(contents) {
13840
14009
  if (content.type === "icon") {
13841
14010
  return content.icon;
13842
14011
  }
14012
+ if (content.type === "emoji") {
14013
+ return content.emoji;
14014
+ }
13843
14015
  if (content.type === "text" || content.type === "link" || content.type === "tag") {
13844
14016
  return content.text;
13845
14017
  }
@@ -14177,6 +14349,9 @@ function isCellContentDisabled(content) {
14177
14349
  if (content.type === "tag") {
14178
14350
  return false;
14179
14351
  }
14352
+ if (content.type === "emoji") {
14353
+ return false;
14354
+ }
14180
14355
  if (content.type === "money") {
14181
14356
  return false;
14182
14357
  }
@@ -17793,9 +17968,7 @@ async function exportAllRowsTxtContent(params) {
17793
17968
  });
17794
17969
  }
17795
17970
  async function exportAllRowsXlsxContent(params) {
17796
- const columns = params.columns.filter(
17797
- (column) => column.key !== ROW_SELECTION_COLUMN_KEY && column.key !== ROW_SELECTOR_COLUMN_KEY
17798
- );
17971
+ const columns = params.columns.filter(isExportableColumn);
17799
17972
  const footerRows = [];
17800
17973
  if (params.includeSummary) {
17801
17974
  const values = await computeSummaryValuesAsync({
@@ -17894,14 +18067,21 @@ function resolveProgressClipboardPercent(content) {
17894
18067
  return Math.min(Math.max((content.value - min) / range * 100, 0), 100);
17895
18068
  }
17896
18069
  function buildExportColumns(columns) {
17897
- return columns.filter(
17898
- (column) => column.key !== ROW_SELECTION_COLUMN_KEY && column.key !== ROW_SELECTOR_COLUMN_KEY
17899
- ).map((column) => ({
18070
+ return columns.filter(isExportableColumn).map((column) => ({
17900
18071
  key: column.key,
17901
18072
  title: column.title ?? column.key,
17902
18073
  value: (row, rowIndex) => getCellClipboardText(row, rowIndex, column)
17903
18074
  }));
17904
18075
  }
18076
+ function isExportableColumn(column) {
18077
+ if (column.key === ROW_SELECTION_COLUMN_KEY || column.key === ROW_SELECTOR_COLUMN_KEY || column.key === EXPAND_COLUMN_KEY) {
18078
+ return false;
18079
+ }
18080
+ if (column.exportable !== void 0) return column.exportable;
18081
+ return !(/^(?:action|actions|operate|operation|operations)$/i.test(column.key) || /^(?:操作|操作列|操作按钮|action|actions|operation|operations)$/i.test(
18082
+ column.title.trim()
18083
+ ));
18084
+ }
17905
18085
  function buildTableExportFileName(extension) {
17906
18086
  const now2 = /* @__PURE__ */ new Date();
17907
18087
  const stamp = [
@@ -18077,13 +18257,14 @@ var ListTableContentActionController = class {
18077
18257
  * 异步导出全部原始数据为 XLSX。
18078
18258
  */
18079
18259
  exportXlsx(options) {
18260
+ const includeSummary = options?.includeSummary ?? this.options.getSummaryVisible?.() ?? false;
18080
18261
  options = { ...this.options.getOptions().exportOptions, ...options };
18081
18262
  this.startExportTask(
18082
18263
  (fileName) => exportAllRowsXlsxContent({
18083
18264
  rows: this.options.getOptions().dataSource,
18084
18265
  columns: this.options.getLeafColumns(),
18085
18266
  ...options,
18086
- includeSummary: options?.includeSummary ?? this.options.getSummaryVisible?.() ?? false,
18267
+ includeSummary,
18087
18268
  fileName: fileName ?? options?.fileName,
18088
18269
  onProgress: (progress) => {
18089
18270
  const fileLabel = progress.fileCount && progress.fileCount > 1 ? `\uFF08\u7B2C ${progress.fileIndex}/${progress.fileCount} \u4EFD\uFF09` : "";
@@ -18777,7 +18958,7 @@ function openCellEditingSession(params) {
18777
18958
  }
18778
18959
  const editorConfig = resolveEditorConfig(editConfig);
18779
18960
  const editingValue = initialValue === void 0 ? currentValue : initialValue;
18780
- const selectOnFocus = !(initialValue !== void 0 && (currentValue == null || currentValue === ""));
18961
+ const selectOnFocus = initialValue === void 0;
18781
18962
  const hostRect = toHostRect ? toHostRect(descriptor.rect) : descriptor.rect;
18782
18963
  const zoom = typeof theme.contentZoom === "number" && Number.isFinite(theme.contentZoom) && theme.contentZoom > 0 ? theme.contentZoom : 1;
18783
18964
  const paddingInline = (column.cellStyle?.paddingInline ?? DEFAULT_EDITOR_PADDING_INLINE) * zoom;
@@ -26203,6 +26384,134 @@ function measureHeaderWidth(ctx, column, theme) {
26203
26384
  return Math.ceil(contentWidth + HEADER_PADDING_INLINE * 2 + actionWidth);
26204
26385
  }
26205
26386
 
26387
+ // src/features/search/search-matcher.ts
26388
+ function createListTableSearchMatcher(keyword, options) {
26389
+ const pattern = options.mode === "regex" ? keyword : keyword.trim();
26390
+ if (!pattern) {
26391
+ return { findMatches: () => [], error: null, active: false };
26392
+ }
26393
+ if (options.mode === "fuzzy") {
26394
+ const needle = options.caseSensitive ? pattern : pattern.toLocaleLowerCase();
26395
+ return {
26396
+ error: null,
26397
+ active: true,
26398
+ findMatches: (text) => {
26399
+ const source = options.caseSensitive ? text : text.toLocaleLowerCase();
26400
+ const matches = [];
26401
+ let start = source.indexOf(needle);
26402
+ while (start >= 0) {
26403
+ matches.push({ start, end: start + pattern.length });
26404
+ start = source.indexOf(needle, start + needle.length);
26405
+ }
26406
+ return matches;
26407
+ }
26408
+ };
26409
+ }
26410
+ if (options.mode === "exact") {
26411
+ const needle = options.caseSensitive ? pattern : pattern.toLocaleLowerCase();
26412
+ return {
26413
+ error: null,
26414
+ active: true,
26415
+ findMatches: (text) => {
26416
+ const source = options.caseSensitive ? text : text.toLocaleLowerCase();
26417
+ return source === needle ? [{ start: 0, end: text.length }] : [];
26418
+ }
26419
+ };
26420
+ }
26421
+ try {
26422
+ const source = options.mode === "wildcard" ? wildcardToRegExpSource(pattern) : pattern;
26423
+ const expression = new RegExp(source, options.caseSensitive ? "g" : "gi");
26424
+ return {
26425
+ error: null,
26426
+ active: true,
26427
+ findMatches: (text) => {
26428
+ const matches = [];
26429
+ expression.lastIndex = 0;
26430
+ let result;
26431
+ while ((result = expression.exec(text)) !== null) {
26432
+ if (result[0].length > 0) {
26433
+ matches.push({ start: result.index, end: expression.lastIndex });
26434
+ } else {
26435
+ expression.lastIndex += 1;
26436
+ }
26437
+ }
26438
+ return matches;
26439
+ }
26440
+ };
26441
+ } catch {
26442
+ return { findMatches: () => [], error: "\u6B63\u5219\u8868\u8FBE\u5F0F\u65E0\u6548", active: false };
26443
+ }
26444
+ }
26445
+ function wildcardToRegExpSource(pattern) {
26446
+ let source = "";
26447
+ for (let index = 0; index < pattern.length; index += 1) {
26448
+ const char = pattern[index];
26449
+ if (char === "\\" && index + 1 < pattern.length) {
26450
+ source += escapeRegExp2(pattern[++index]);
26451
+ } else if (char === "*") {
26452
+ source += ".*";
26453
+ } else if (char === "?") {
26454
+ source += ".";
26455
+ } else {
26456
+ source += escapeRegExp2(char);
26457
+ }
26458
+ }
26459
+ return source;
26460
+ }
26461
+ function escapeRegExp2(value) {
26462
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
26463
+ }
26464
+ function resolveListTableSearchCellTexts(params) {
26465
+ const { record, rowIndex, column } = params;
26466
+ if (!column.render && !column.dataFormat && !column.cellType) {
26467
+ return [
26468
+ {
26469
+ contentIndex: 0,
26470
+ text: String(getValueByDataIndex(record, column.dataIndex) ?? "")
26471
+ }
26472
+ ];
26473
+ }
26474
+ return resolveBodyCellContents({ record, rowIndex, column }).flatMap(
26475
+ (content, contentIndex) => content.type === "text" ? [{ contentIndex, text: content.text }] : []
26476
+ );
26477
+ }
26478
+ function buildHeaderDataIndexOptions(rows, columns) {
26479
+ const paths = /* @__PURE__ */ new Set();
26480
+ const used = /* @__PURE__ */ new Map();
26481
+ const visitColumns = (items) => {
26482
+ items.forEach((column) => {
26483
+ if (column.dataIndex != null) {
26484
+ const path = stringifyDataIndex(column.dataIndex);
26485
+ if (!used.has(path)) {
26486
+ used.set(
26487
+ path,
26488
+ String(column.settingTitle ?? column.title ?? column.key ?? path)
26489
+ );
26490
+ }
26491
+ }
26492
+ if (column.children?.length) visitColumns(column.children);
26493
+ });
26494
+ };
26495
+ visitColumns(columns);
26496
+ const visitValue = (value, prefix, depth) => {
26497
+ if (!value || typeof value !== "object" || Array.isArray(value) || value instanceof Date)
26498
+ return;
26499
+ Object.entries(value).forEach(([key, child]) => {
26500
+ if (paths.size >= 200) return;
26501
+ const path = prefix ? `${prefix}.${key}` : key;
26502
+ paths.add(path);
26503
+ if (depth < 3) visitValue(child, path, depth + 1);
26504
+ });
26505
+ };
26506
+ rows.slice(0, 50).forEach((row) => visitValue(row, "", 0));
26507
+ used.forEach((_label, path) => paths.add(path));
26508
+ return [...paths].map((value) => ({
26509
+ value,
26510
+ disabled: used.has(value),
26511
+ ...used.has(value) ? { label: used.get(value) } : null
26512
+ }));
26513
+ }
26514
+
26206
26515
  // src/features/overlay/context-menu-builder.ts
26207
26516
  function createListTableContextMenuActions(params) {
26208
26517
  return {
@@ -26365,6 +26674,8 @@ function createListTableContextMenuActions(params) {
26365
26674
  onChangeZoom: params.onChangeZoom,
26366
26675
  onToggleCurrentColumn: params.onToggleCurrentColumn ?? params.onToggleColumn,
26367
26676
  onToggleColumn: params.onToggleColumn,
26677
+ onSaveColumn: params.onSaveColumn,
26678
+ onDeleteColumn: params.onDeleteColumn,
26368
26679
  onChangeCachePreference: params.onChangeCachePreference ? (category, enabled) => {
26369
26680
  params.hideMenu();
26370
26681
  params.onChangeCachePreference?.(category, enabled);
@@ -26433,6 +26744,7 @@ function buildListTableContextMenuConfig(params) {
26433
26744
  x,
26434
26745
  y,
26435
26746
  columns,
26747
+ dataSource,
26436
26748
  columnKey,
26437
26749
  isHeaderArea,
26438
26750
  isSummaryArea = false,
@@ -26457,6 +26769,7 @@ function buildListTableContextMenuConfig(params) {
26457
26769
  const isBodyArea = bodyRowIndex != null;
26458
26770
  const isSelectionColumn = columnKey === ROW_SELECTION_COLUMN_KEY || columnKey === ROW_SELECTOR_COLUMN_KEY;
26459
26771
  const enableCopy = enabledFeatures.has("copy");
26772
+ const enableChart = enabledFeatures.has("chart");
26460
26773
  const enableSearch = enabledFeatures.has("search");
26461
26774
  const enableExport = enabledFeatures.has("export");
26462
26775
  const enableDownloadContent = enabledFeatures.has("downloadContent");
@@ -26504,6 +26817,7 @@ function buildListTableContextMenuConfig(params) {
26504
26817
  return {
26505
26818
  x,
26506
26819
  y,
26820
+ onCreateChart: enableChart && (isBodyArea || isExpandedArea || isHeaderArea && columnKey !== ROW_SELECTION_COLUMN_KEY) ? params.onCreateChart : void 0,
26507
26821
  columns: enableColumnVisibility ? headerItems : void 0,
26508
26822
  density: enableDensity ? density : void 0,
26509
26823
  zoom: enableZoom ? normalizeContextMenuZoom(zoom) : void 0,
@@ -26592,6 +26906,9 @@ function buildListTableContextMenuConfig(params) {
26592
26906
  onChangeDensity: enableDensity ? actions.onChangeDensity : void 0,
26593
26907
  onChangeZoom: enableZoom ? actions.onChangeZoom : void 0,
26594
26908
  onToggleColumn: enableColumnVisibility && isTableSettingsArea ? actions.onToggleColumn : void 0,
26909
+ dataIndexOptions: enableColumnVisibility && isTableSettingsArea ? buildHeaderDataIndexOptions(dataSource ?? [], columns) : void 0,
26910
+ onSaveColumn: enableColumnVisibility && isTableSettingsArea ? actions.onSaveColumn : void 0,
26911
+ onDeleteColumn: enableColumnVisibility && isTableSettingsArea ? actions.onDeleteColumn : void 0,
26595
26912
  columnSettingsCacheAvailable: Boolean(params.storageKey),
26596
26913
  cachePreferences: params.cachePreferences,
26597
26914
  onChangeCachePreference: enabledFeatures.has("cache") ? actions.onChangeCachePreference : void 0,
@@ -26647,6 +26964,7 @@ function findSummaryColumn(columns, columnKey) {
26647
26964
  }
26648
26965
  var DEFAULT_CONTEXT_MENU_FEATURES = [
26649
26966
  "copy",
26967
+ "chart",
26650
26968
  "search",
26651
26969
  "export",
26652
26970
  "downloadContent",
@@ -26803,6 +27121,8 @@ function showHeaderContextMenu(params) {
26803
27121
  onChangeZoom,
26804
27122
  onToggleCurrentColumn,
26805
27123
  onToggleColumn,
27124
+ onSaveColumn,
27125
+ onDeleteColumn,
26806
27126
  onExpandAllCollapsedColumns,
26807
27127
  onClose,
26808
27128
  onToggleSummary,
@@ -26830,7 +27150,8 @@ function showHeaderContextMenu(params) {
26830
27150
  const isSummaryArea = result.area === "summary";
26831
27151
  const isExpandedArea = result.area === "expanded-row" || result.columnKey === "__expanded_row__";
26832
27152
  const isSelectionColumn = result.columnKey === ROW_SELECTION_COLUMN_KEY || result.columnKey === ROW_SELECTOR_COLUMN_KEY;
26833
- if (!isHeaderArea && !isBodyArea && !groupingBarArea && !isExpandedArea || !result.columnKey && !groupingBarArea && !isExpandedArea || isHeaderArea && isSelectionColumn) {
27153
+ const isChartCorner = isHeaderArea && result.columnKey === ROW_SELECTOR_COLUMN_KEY && resolveEnabledContextMenuFeatures(options.contextMenu).has("chart");
27154
+ if (!isHeaderArea && !isBodyArea && !groupingBarArea && !isExpandedArea || !result.columnKey && !groupingBarArea && !isExpandedArea || isHeaderArea && isSelectionColumn && !isChartCorner) {
26834
27155
  headerContextMenu.hide();
26835
27156
  return false;
26836
27157
  }
@@ -26843,7 +27164,7 @@ function showHeaderContextMenu(params) {
26843
27164
  fixedPopup.hide();
26844
27165
  hideBodyTooltip();
26845
27166
  const contextColumnKey = result.columnKey ?? "";
26846
- if (isHeaderArea) {
27167
+ if (isHeaderArea && !isChartCorner) {
26847
27168
  onSelectHeader(contextColumnKey, result.rect);
26848
27169
  }
26849
27170
  const bodyRowIndex = isBodyArea && !isSummaryArea && !isExpandedArea && typeof result.rowIndex === "number" ? result.rowIndex : null;
@@ -26859,11 +27180,13 @@ function showHeaderContextMenu(params) {
26859
27180
  x: event.clientX,
26860
27181
  y: event.clientY,
26861
27182
  columns: options.columns,
27183
+ dataSource: options.dataSource,
26862
27184
  columnKey: result.columnKey ?? "",
26863
27185
  isHeaderArea,
26864
27186
  isSummaryArea,
26865
27187
  isExpandedArea,
26866
27188
  onCopySummaryRowText: params.onCopySummaryRowText,
27189
+ onCreateChart: params.onCreateChart,
26867
27190
  onCopyImage: params.onCopyImage,
26868
27191
  onExportImage: params.onExportImage,
26869
27192
  canCopySelectionImage: params.canCopySelectionImage,
@@ -26915,6 +27238,8 @@ function showHeaderContextMenu(params) {
26915
27238
  onChangeZoom,
26916
27239
  onToggleCurrentColumn,
26917
27240
  onToggleColumn,
27241
+ onSaveColumn,
27242
+ onDeleteColumn,
26918
27243
  onExpandAllCollapsedColumns,
26919
27244
  onClose,
26920
27245
  onToggleSummary,
@@ -26954,6 +27279,77 @@ function resolveContextMenuDensity(rowHeight) {
26954
27279
  return rowHeight === 48 ? "middle" : "compact";
26955
27280
  }
26956
27281
 
27282
+ // src/features/overlay/chart-data.ts
27283
+ function createListTableChartData(params) {
27284
+ const {
27285
+ rows,
27286
+ columns,
27287
+ columnKey,
27288
+ rowIndex,
27289
+ selectionRange,
27290
+ selectedRowRange,
27291
+ selectedColumnRange
27292
+ } = params;
27293
+ const startRow = Math.max(
27294
+ selectionRange?.startRowIndex ?? selectedRowRange?.start ?? Math.max((rowIndex ?? 0) - 10, 0),
27295
+ 0
27296
+ );
27297
+ const endRow = Math.min(
27298
+ selectionRange?.endRowIndex ?? selectedRowRange?.end ?? startRow + 199,
27299
+ rows.length - 1
27300
+ );
27301
+ const selectedColumns = selectionRange ? columns.slice(
27302
+ Math.max(selectionRange.startColumnIndex, 0),
27303
+ selectionRange.endColumnIndex + 1
27304
+ ) : selectedRowRange ? columns : selectedColumnRange ? columns.slice(
27305
+ Math.max(selectedColumnRange.start, 0),
27306
+ selectedColumnRange.end + 1
27307
+ ) : columns.filter((column) => column.key === columnKey);
27308
+ const chartColumns = selectedColumns.filter(
27309
+ (column) => column.key !== ROW_SELECTION_COLUMN_KEY && column.key !== ROW_SELECTOR_COLUMN_KEY && column.key !== EXPAND_COLUMN_KEY
27310
+ ).slice(0, 12);
27311
+ if (startRow > endRow || chartColumns.length === 0) return null;
27312
+ const sampledRows = rows.slice(
27313
+ startRow,
27314
+ Math.min(endRow + 1, startRow + 200)
27315
+ );
27316
+ const values = chartColumns.map(
27317
+ (column) => sampledRows.map(
27318
+ (record, offset) => getCellClipboardText(record, startRow + offset, column)
27319
+ )
27320
+ );
27321
+ const numericColumns = chartColumns.flatMap((column, index) => {
27322
+ const numbers = values[index]?.map(parseChartNumber) ?? [];
27323
+ return numbers.some((value) => value !== null) ? [{ name: column.title, data: numbers.map((value) => value ?? 0) }] : [];
27324
+ });
27325
+ if (numericColumns.length === 0) return null;
27326
+ const labelIndex = chartColumns.findIndex(
27327
+ (_, index) => values[index]?.every((value) => parseChartNumber(value) === null)
27328
+ );
27329
+ if (sampledRows.length === 1 && chartColumns.length > 1) {
27330
+ return {
27331
+ labels: numericColumns.map((series) => series.name),
27332
+ series: [
27333
+ {
27334
+ name: values[labelIndex]?.[0] || String(startRow + 1),
27335
+ data: numericColumns.map((series) => series.data[0] ?? 0)
27336
+ }
27337
+ ]
27338
+ };
27339
+ }
27340
+ const labels = sampledRows.map(
27341
+ (_, index) => labelIndex >= 0 ? values[labelIndex]?.[index] || String(startRow + index + 1) : String(startRow + index + 1)
27342
+ );
27343
+ return { labels, series: numericColumns };
27344
+ }
27345
+ function parseChartNumber(value) {
27346
+ const normalized = value.trim().replace(/[,,\s¥¥$]/g, "");
27347
+ if (!normalized) return null;
27348
+ const percentage = normalized.endsWith("%");
27349
+ const parsed = Number(percentage ? normalized.slice(0, -1) : normalized);
27350
+ return Number.isFinite(parsed) ? parsed : null;
27351
+ }
27352
+
26957
27353
  // src/features/tooltip/tooltip-feature.ts
26958
27354
  function getHeaderActionTooltipText(result, sortState) {
26959
27355
  const area = result.area;
@@ -27975,6 +28371,11 @@ var EDITABLE_CELL_ROW_SELECTION_DELAY = 300;
27975
28371
  var ListTableEventController = class {
27976
28372
  constructor(host) {
27977
28373
  __publicField(this, "searchKeyword", "");
28374
+ __publicField(this, "searchOptions", {
28375
+ mode: "fuzzy",
28376
+ caseSensitive: false
28377
+ });
28378
+ __publicField(this, "searchError", null);
27978
28379
  __publicField(this, "searchMatches", []);
27979
28380
  __publicField(this, "searchCurrentIndex", -1);
27980
28381
  __publicField(this, "textSelectionDrag", null);
@@ -28537,6 +28938,15 @@ var ListTableEventController = class {
28537
28938
  getAllRows: () => this.host.options.dataSource,
28538
28939
  getExportSummaryEnabled: () => Boolean(this.host.currentRenderSnapshot?.hasSummary),
28539
28940
  onCopyImage: (scope) => this.copyImage(scope, event),
28941
+ onCreateChart: () => createListTableChartData({
28942
+ rows: this.host.getDisplayData(),
28943
+ columns: this.host.leafColumns,
28944
+ columnKey: contextResult.columnKey ?? "",
28945
+ rowIndex: typeof contextResult.rowIndex === "number" ? contextResult.rowIndex : null,
28946
+ selectionRange: this.host.rangeHighlight.selectedCellRange,
28947
+ selectedRowRange: this.host.rangeHighlight.selectedRowRange,
28948
+ selectedColumnRange: this.host.rangeHighlight.selectedColumnRange
28949
+ }),
28540
28950
  onExportImage: (scope) => this.copyImage(scope, event, true),
28541
28951
  canCopySelectionImage: resolveImageSelection(this.host) != null,
28542
28952
  onCopySummaryRowText: () => {
@@ -28569,15 +28979,21 @@ var ListTableEventController = class {
28569
28979
  this.host.selectHeader(columnKey, rect);
28570
28980
  },
28571
28981
  onSelectBodyRow: (rowIndex, columnKey) => {
28982
+ const selectedCellRange = this.host.rangeHighlight.selectedCellRange;
28983
+ const columnIndex = this.host.leafColumns.findIndex(
28984
+ (column) => column.key === columnKey
28985
+ );
28572
28986
  this.host.selection = {
28573
28987
  rowIndex,
28574
28988
  columnKey
28575
28989
  };
28576
28990
  this.host.clearSelectedHeader();
28577
- this.host.rangeHighlight = resolveNextRowHighlightForContextMenu({
28578
- current: this.host.rangeHighlight,
28579
- rowIndex
28580
- });
28991
+ if (!selectedCellRange || rowIndex < selectedCellRange.startRowIndex || rowIndex > selectedCellRange.endRowIndex || columnIndex < selectedCellRange.startColumnIndex || columnIndex > selectedCellRange.endColumnIndex) {
28992
+ this.host.rangeHighlight = resolveNextRowHighlightForContextMenu({
28993
+ current: this.host.rangeHighlight,
28994
+ rowIndex
28995
+ });
28996
+ }
28581
28997
  this.host.summarySelected = false;
28582
28998
  },
28583
28999
  getSelectionRange: () => this.host.rangeHighlight.selectedCellRange ?? null,
@@ -28708,6 +29124,8 @@ var ListTableEventController = class {
28708
29124
  onToggleColumn: (columnKey, visible) => {
28709
29125
  this.host.toggleHeaderColumnVisible(columnKey, visible);
28710
29126
  },
29127
+ onSaveColumn: (draft) => this.host.saveHeaderColumn(draft),
29128
+ onDeleteColumn: (columnKey) => this.host.deleteHeaderColumn(columnKey),
28711
29129
  onExpandAllCollapsedColumns: () => {
28712
29130
  this.host.expandAllCollapsedColumns();
28713
29131
  },
@@ -29508,11 +29926,17 @@ var ListTableEventController = class {
29508
29926
  publishSearchRequest() {
29509
29927
  const request = {
29510
29928
  keyword: this.searchKeyword,
29929
+ mode: this.searchOptions.mode,
29930
+ caseSensitive: this.searchOptions.caseSensitive,
29931
+ error: this.searchError,
29511
29932
  matchCount: this.searchMatches.length,
29512
29933
  currentIndex: this.searchCurrentIndex,
29513
- onSubmit: (keyword) => {
29934
+ onSubmit: (keyword, options) => {
29514
29935
  this.searchKeyword = keyword;
29515
- this.searchMatches = this.resolveSearchMatches(keyword);
29936
+ this.searchOptions = options;
29937
+ const matcher = createListTableSearchMatcher(keyword, options);
29938
+ this.searchError = matcher.error;
29939
+ this.searchMatches = matcher.active ? this.resolveSearchMatches(matcher.findMatches) : [];
29516
29940
  this.searchCurrentIndex = this.searchMatches.length > 0 ? 0 : -1;
29517
29941
  this.applyCurrentSearchMatch();
29518
29942
  this.publishSearchRequest();
@@ -29526,6 +29950,7 @@ var ListTableEventController = class {
29526
29950
  },
29527
29951
  onClose: () => {
29528
29952
  this.searchKeyword = "";
29953
+ this.searchError = null;
29529
29954
  this.searchMatches = [];
29530
29955
  this.searchCurrentIndex = -1;
29531
29956
  this.host.rangeHighlight = {
@@ -29538,30 +29963,24 @@ var ListTableEventController = class {
29538
29963
  };
29539
29964
  this.host.options.ui?.onSearchRequest?.(request);
29540
29965
  }
29541
- resolveSearchMatches(keyword) {
29542
- const normalizedKeyword = keyword.trim().toLocaleLowerCase();
29543
- if (!normalizedKeyword) return [];
29966
+ resolveSearchMatches(findMatches) {
29544
29967
  const matches = [];
29545
29968
  this.host.getDisplayData().forEach((record, rowIndex) => {
29546
29969
  this.host.leafColumns.forEach((column) => {
29547
29970
  if (isSystemColumnKey(column.key)) return;
29548
- const text = String(
29549
- getValueByDataIndex(record, column.dataIndex) ?? ""
29971
+ resolveListTableSearchCellTexts({ record, rowIndex, column }).forEach(
29972
+ ({ text, contentIndex }) => {
29973
+ findMatches(text).forEach(({ start, end }) => {
29974
+ matches.push({
29975
+ rowIndex,
29976
+ columnKey: column.key,
29977
+ contentIndex,
29978
+ start,
29979
+ end
29980
+ });
29981
+ });
29982
+ }
29550
29983
  );
29551
- const source = text.toLocaleLowerCase();
29552
- let start = source.indexOf(normalizedKeyword);
29553
- while (start >= 0) {
29554
- matches.push({
29555
- rowIndex,
29556
- columnKey: column.key,
29557
- start,
29558
- end: start + normalizedKeyword.length
29559
- });
29560
- start = source.indexOf(
29561
- normalizedKeyword,
29562
- start + normalizedKeyword.length
29563
- );
29564
- }
29565
29984
  });
29566
29985
  });
29567
29986
  return matches;
@@ -31100,6 +31519,8 @@ function createListTableEventHost(core) {
31100
31519
  changeTableDensity: (density) => core.headerActionController.changeTableDensity(density),
31101
31520
  changeTableZoom: (zoom) => core.headerActionController.changeTableZoom(zoom),
31102
31521
  toggleHeaderColumnVisible: (columnKey, visible) => core.headerActionController.toggleHeaderColumnVisible(columnKey, visible),
31522
+ saveHeaderColumn: (draft) => core.headerActionController.saveHeaderColumn(draft),
31523
+ deleteHeaderColumn: (columnKey) => core.headerActionController.deleteHeaderColumn(columnKey),
31103
31524
  toggleHighlightedHeaderColumns: (columnKey, visible) => core.headerActionController.toggleHighlightedHeaderColumns(
31104
31525
  columnKey,
31105
31526
  visible
@@ -31451,6 +31872,34 @@ var ListTableHeaderActionController = class {
31451
31872
  });
31452
31873
  this.options.headerContextMenu.updateColumns(resolved.menuItems);
31453
31874
  }
31875
+ saveHeaderColumn(draft) {
31876
+ const columns = this.options.getOptions().columns;
31877
+ const error = saveHeaderSettingsColumn(columns, draft);
31878
+ if (error) return error;
31879
+ this.options.refreshRuntimeColumns();
31880
+ this.options.resetSummaryValues();
31881
+ this.options.persistColumnConfig();
31882
+ this.options.headerContextMenu.updateColumns(
31883
+ buildHeaderSettingsItems(columns)
31884
+ );
31885
+ this.options.requestRender();
31886
+ return null;
31887
+ }
31888
+ deleteHeaderColumn(columnKey) {
31889
+ const columns = this.options.getOptions().columns;
31890
+ if (!deleteHeaderSettingsColumn(columns, columnKey)) return false;
31891
+ this.options.setSortState(
31892
+ this.options.getSortState().filter((entry) => entry.key !== columnKey)
31893
+ );
31894
+ this.options.refreshRuntimeColumns();
31895
+ this.options.resetSummaryValues();
31896
+ this.options.persistColumnConfig();
31897
+ this.options.headerContextMenu.updateColumns(
31898
+ buildHeaderSettingsItems(columns)
31899
+ );
31900
+ this.options.requestRender();
31901
+ return true;
31902
+ }
31454
31903
  toggleHighlightedHeaderColumns(columnKey, visible) {
31455
31904
  if (visible) {
31456
31905
  this.toggleHeaderColumnVisible(columnKey, true);
@@ -31775,20 +32224,74 @@ function applyStoredColumnConfig(columns, storedColumns, cacheColumnSettings = t
31775
32224
  return false;
31776
32225
  }
31777
32226
  let columnWidthsChanged = false;
32227
+ if (cacheColumnSettings) {
32228
+ const existingKeys = /* @__PURE__ */ new Set();
32229
+ const collectKeys = (items) => {
32230
+ items.forEach((column) => {
32231
+ if (column.key) existingKeys.add(column.key);
32232
+ if (column.children?.length) collectKeys(column.children);
32233
+ });
32234
+ };
32235
+ collectKeys(columns);
32236
+ const findChildren = (items, parentKey) => {
32237
+ for (const column of items) {
32238
+ if (column.key === parentKey) return column.children ?? null;
32239
+ if (column.children?.length) {
32240
+ const children = findChildren(column.children, parentKey);
32241
+ if (children) return children;
32242
+ }
32243
+ }
32244
+ return null;
32245
+ };
32246
+ Object.entries(storedColumns).forEach(([key, stored]) => {
32247
+ if (!stored.userDefined || existingKeys.has(key) || !stored.dataIndex)
32248
+ return;
32249
+ const target = stored.parentKey ? findChildren(columns, stored.parentKey) : columns;
32250
+ (target ?? columns).push({
32251
+ key,
32252
+ title: stored.title ?? key,
32253
+ settingTitle: stored.title ?? key,
32254
+ dataIndex: stored.dataIndex,
32255
+ width: stored.width,
32256
+ minWidth: stored.minWidth,
32257
+ maxWidth: stored.maxWidth,
32258
+ fixed: stored.fixed,
32259
+ hidden: stored.hidden,
32260
+ userDefined: true,
32261
+ allowSort: true,
32262
+ sorter: true
32263
+ });
32264
+ existingKeys.add(key);
32265
+ });
32266
+ }
31778
32267
  const applyToColumns = (cols) => {
31779
32268
  if (cacheColumnSettings && columnOrder?.length) {
31780
- const rank = new Map(columnOrder.map((key, index) => [key, index]));
31781
- cols.sort(
31782
- (a, b) => (rank.get(a.key ?? "") ?? Infinity) - (rank.get(b.key ?? "") ?? Infinity)
31783
- );
32269
+ const rank = new Map(columnOrder.map((key, index2) => [key, index2]));
32270
+ const ranked = cols.filter((column) => rank.has(column.key ?? "")).sort((a, b) => rank.get(a.key ?? "") - rank.get(b.key ?? ""));
32271
+ let index = 0;
32272
+ cols.forEach((column, position) => {
32273
+ if (rank.has(column.key ?? "")) cols[position] = ranked[index++];
32274
+ });
31784
32275
  }
31785
32276
  for (const col of cols) {
31786
32277
  if (!col.key) {
31787
32278
  continue;
31788
32279
  }
31789
32280
  const stored = storedColumns[col.key];
31790
- if (stored) {
32281
+ if (stored && (!stored.userDefined || col.userDefined)) {
32282
+ if (cacheColumnSettings && stored.userTitle != null) {
32283
+ col.title = stored.userTitle;
32284
+ col.settingTitle = stored.userTitle;
32285
+ col.userTitle = stored.userTitle;
32286
+ }
31791
32287
  if (cacheColumnSettings) {
32288
+ if (col.userDefined && stored.userDefined) {
32289
+ col.title = stored.title ?? col.title;
32290
+ col.settingTitle = stored.title ?? col.settingTitle;
32291
+ col.dataIndex = stored.dataIndex ?? col.dataIndex;
32292
+ }
32293
+ if ("minWidth" in stored) col.minWidth = stored.minWidth;
32294
+ if ("maxWidth" in stored) col.maxWidth = stored.maxWidth;
31792
32295
  if (stored.width != null) {
31793
32296
  if ((col.width ?? 160) !== stored.width) columnWidthsChanged = true;
31794
32297
  col.width = stored.width;
@@ -31851,7 +32354,7 @@ function applyStoredColumnConfig(columns, storedColumns, cacheColumnSettings = t
31851
32354
  function buildStoredColumnConfig(columns, sortState, filterState, zoom, summaryRowHeight, density, cacheColumnSettings = true, cachePreferences) {
31852
32355
  const result = {};
31853
32356
  const columnOrder = [];
31854
- const collectColumns = (cols) => {
32357
+ const collectColumns = (cols, parentKey) => {
31855
32358
  for (const col of cols) {
31856
32359
  if (!col.key) {
31857
32360
  continue;
@@ -31860,8 +32363,19 @@ function buildStoredColumnConfig(columns, sortState, filterState, zoom, summaryR
31860
32363
  result[col.key] = {
31861
32364
  ...cacheColumnSettings ? {
31862
32365
  width: col.width ?? 160,
32366
+ minWidth: col.minWidth,
32367
+ maxWidth: col.maxWidth,
31863
32368
  fixed: col.fixed,
31864
- hidden: !!col.hidden
32369
+ hidden: !!col.hidden,
32370
+ ...col.userTitle ? { userTitle: col.userTitle } : null,
32371
+ ...col.userDefined && col.dataIndex != null ? {
32372
+ userDefined: true,
32373
+ ...parentKey ? { parentKey } : null,
32374
+ title: String(col.settingTitle ?? col.title ?? col.key),
32375
+ dataIndex: col.dataIndex,
32376
+ minWidth: col.minWidth,
32377
+ maxWidth: col.maxWidth
32378
+ } : null
31865
32379
  } : null,
31866
32380
  // IndexedDB 保留 undefined 属性;字段存在即表示显式恢复/清除,避免默认配置回弹。
31867
32381
  align: col.align,
@@ -31885,7 +32399,7 @@ function buildStoredColumnConfig(columns, sortState, filterState, zoom, summaryR
31885
32399
  } : false
31886
32400
  };
31887
32401
  if (col.children?.length) {
31888
- collectColumns(col.children);
32402
+ collectColumns(col.children, col.key);
31889
32403
  }
31890
32404
  }
31891
32405
  };
@@ -35273,6 +35787,12 @@ var ListTableCore = class {
35273
35787
  const incomingColumnsAreRuntimeColumns = options.columns === this.options.columns;
35274
35788
  const nextInitialColumns = incomingColumnsAreRuntimeColumns ? cloneColumns(host.initialColumns) : cloneColumns(options.columns);
35275
35789
  const nextInitialStretchColumns = incomingColumnsAreRuntimeColumns ? host.initialStretchColumns : options.stretchColumns;
35790
+ if (!shouldResetColumnConfig && !incomingColumnsAreRuntimeColumns && this.options.storageKey === options.storageKey) {
35791
+ preserveUserAddedColumns({
35792
+ nextColumns: options.columns,
35793
+ runtimeColumns: this.options.columns
35794
+ });
35795
+ }
35276
35796
  const shouldPreserveRuntimeWidths = !shouldResetColumnConfig && this.options.stretchColumns === false && options.stretchColumns === host.initialStretchColumns;
35277
35797
  if (shouldPreserveRuntimeWidths) {
35278
35798
  preserveRuntimeColumnWidths({