@canvas-components/list-table 0.3.30 → 0.3.32

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
@@ -24371,7 +24371,8 @@ function resolveExpandedRowHeight2(height, record, index) {
24371
24371
  // src/services/layout-service.ts
24372
24372
  var AUTO_ROW_HEIGHT_SAMPLE_COUNT = 200;
24373
24373
  function buildListTableRenderSnapshot(params) {
24374
- if (params.cache?.snapshot && params.cache.snapshot.groupIndex === params.cache.groupIndex && isSameRenderCacheInputs(params.cache.inputs, params)) {
24374
+ if (params.cache?.snapshot && // 动画结束后的首帧必须重建,清除上一帧的位移、拖拽残影及插入线。
24375
+ !params.cache.snapshot.swapAnimation && params.cache.snapshot.groupIndex === params.cache.groupIndex && isSameRenderCacheInputs(params.cache.inputs, params)) {
24375
24376
  const snapshotStartedAt2 = resolvePerformanceNow3();
24376
24377
  const cached = params.cache.snapshot;
24377
24378
  const snapshot2 = !cached.swapAnimation && cached.scroll.left === params.scroll.left && cached.scroll.top === params.scroll.top ? cached : updateListTableRenderSnapshotScroll({
@@ -30789,7 +30790,7 @@ var ListTableEventController = class {
30789
30790
  this.host.updateTooltip(result);
30790
30791
  return;
30791
30792
  }
30792
- if ((event.shiftKey || toggleColumn) && (result.area === "body" || result.area === "body-content") && typeof result.rowIndex === "number" && result.columnKey && !isSystemColumnKey(result.columnKey)) {
30793
+ if ((event.shiftKey || toggleColumn) && (result.area === "body" || result.area === "body-content") && !(event.shiftKey && !toggleColumn && this.host.options.rowSelection?.selectRowByClick && this.host.options.rowSelection.type !== "radio") && typeof result.rowIndex === "number" && result.columnKey && !isSystemColumnKey(result.columnKey)) {
30793
30794
  const columnIndex = this.host.leafColumns.findIndex(
30794
30795
  (column) => column.key === result.columnKey
30795
30796
  );
@@ -30935,7 +30936,7 @@ var ListTableEventController = class {
30935
30936
  if ((result.area === "body-control" || result.area === "body") && result.columnKey === ROW_SELECTION_COLUMN_KEY && typeof result.rowIndex === "number") {
30936
30937
  const record = this.resolveBodyRecord(result.rowIndex);
30937
30938
  if (record) {
30938
- this.host.toggleRowSelection(record, result.rowIndex);
30939
+ this.host.toggleRowSelection(record, result.rowIndex, event.shiftKey);
30939
30940
  }
30940
30941
  return;
30941
30942
  }
@@ -30956,9 +30957,13 @@ var ListTableEventController = class {
30956
30957
  }
30957
30958
  );
30958
30959
  if (canOpenEditorByDoubleClick && event.detail === 1) {
30959
- this.scheduleEditableCellRowSelection(record, result.rowIndex);
30960
+ this.scheduleEditableCellRowSelection(
30961
+ record,
30962
+ result.rowIndex,
30963
+ event.shiftKey
30964
+ );
30960
30965
  } else if (!canOpenEditorByDoubleClick || event.detail !== 2) {
30961
- this.host.toggleRowSelection(record, result.rowIndex);
30966
+ this.host.toggleRowSelection(record, result.rowIndex, event.shiftKey);
30962
30967
  }
30963
30968
  }
30964
30969
  }
@@ -31537,11 +31542,11 @@ var ListTableEventController = class {
31537
31542
  event.preventDefault();
31538
31543
  this.host.editingController.open(rowIndex, columnKey, event.key);
31539
31544
  }
31540
- scheduleEditableCellRowSelection(record, rowIndex) {
31545
+ scheduleEditableCellRowSelection(record, rowIndex, shiftKey) {
31541
31546
  this.cancelPendingEditableCellRowSelection();
31542
31547
  this.pendingEditableCellRowSelectionTimer = globalThis.setTimeout(() => {
31543
31548
  this.pendingEditableCellRowSelectionTimer = null;
31544
- this.host.toggleRowSelection(record, rowIndex);
31549
+ this.host.toggleRowSelection(record, rowIndex, shiftKey);
31545
31550
  }, EDITABLE_CELL_ROW_SELECTION_DELAY);
31546
31551
  }
31547
31552
  cancelPendingEditableCellRowSelection() {
@@ -33087,7 +33092,10 @@ function createListTableEventHost(core) {
33087
33092
  clearBodySelection: () => core.selectionController.clearBodySelection(),
33088
33093
  clearSelectedHeader: () => core.selectionController.clearSelectedHeader(),
33089
33094
  selectHeader: (columnKey, rect) => core.selectionController.selectHeader(columnKey, rect),
33090
- resetRangeHighlightForHeaderSelection: (shiftKey, ctrlKey) => core.selectionController.resetRangeHighlightForHeaderSelection(shiftKey, ctrlKey),
33095
+ resetRangeHighlightForHeaderSelection: (shiftKey, ctrlKey) => core.selectionController.resetRangeHighlightForHeaderSelection(
33096
+ shiftKey,
33097
+ ctrlKey
33098
+ ),
33091
33099
  updateRangeHighlightForBodyInteraction: (params) => core.selectionController.updateRangeHighlightForBodyInteraction(params),
33092
33100
  updateRangeHighlightForHeaderClick: (columnKey, shiftKey, ctrlKey) => core.selectionController.updateRangeHighlightForHeaderClick(
33093
33101
  columnKey,
@@ -33106,7 +33114,7 @@ function createListTableEventHost(core) {
33106
33114
  showCellContentPreview: (content) => core.contentActionController.showCellContentPreview(content),
33107
33115
  showDangerConfirmRequest: (request) => core.overlayController.showDangerConfirm(request),
33108
33116
  toggleSelectAllVisibleRows: () => core.rowActionController.toggleSelectAllVisibleRows(),
33109
- toggleRowSelection: (record, rowIndex) => core.rowActionController.toggleRowSelection(record, rowIndex),
33117
+ toggleRowSelection: (record, rowIndex, shiftKey) => core.rowActionController.toggleRowSelection(record, rowIndex, shiftKey),
33110
33118
  toggleRowExpand: (rowIndex) => core.rowActionController.toggleRowExpand(rowIndex),
33111
33119
  expandCollapsedRange: (contentKey) => core.rowActionController.expandCollapsedRange(contentKey),
33112
33120
  expandCollapsedColumnRange: (contentKey) => core.rowActionController.expandCollapsedColumnRange(contentKey),
@@ -34195,14 +34203,35 @@ var ListTablePersistenceController = class {
34195
34203
  __publicField(this, "revision", 0);
34196
34204
  __publicField(this, "pendingWrite");
34197
34205
  __publicField(this, "restoredStorageKey");
34206
+ __publicField(this, "restoredQueryStorageKey");
34198
34207
  __publicField(this, "hasRestoredPreferences", false);
34199
34208
  __publicField(this, "restoring", false);
34209
+ __publicField(this, "initialActions", []);
34200
34210
  this.options = options;
34201
34211
  }
34212
+ /** 初始化期间的重置等待缓存恢复,避免将默认列和空排序写回缓存。 */
34213
+ runAfterInitialRestore(run) {
34214
+ const storageKey = this.options.getOptions().storageKey;
34215
+ if (storageKey && this.needsInitialQueryRestore()) {
34216
+ this.initialActions.push({ storageKey, run });
34217
+ } else {
34218
+ run();
34219
+ }
34220
+ }
34221
+ /** 销毁时丢弃等待中的交互,避免已卸载表格再次写入缓存。 */
34222
+ dispose() {
34223
+ this.invalidate();
34224
+ this.initialActions = [];
34225
+ }
34202
34226
  /** 缓存恢复完成之前保留上一帧,避免默认配置先于缓存绘制。 */
34203
34227
  isRestoring() {
34204
34228
  return this.restoring;
34205
34229
  }
34230
+ /** 首次缓存读取被配置更新打断时,后续读取仍需恢复该表的查询状态。 */
34231
+ needsInitialQueryRestore() {
34232
+ const storageKey = this.options.getOptions().storageKey;
34233
+ return Boolean(storageKey && this.restoredQueryStorageKey !== storageKey);
34234
+ }
34206
34235
  /** 使尚未完成的缓存恢复失效。 */
34207
34236
  invalidate() {
34208
34237
  this.revision += 1;
@@ -34211,6 +34240,9 @@ var ListTablePersistenceController = class {
34211
34240
  async loadStoredConfig(options = {}) {
34212
34241
  const { restoreQueryState = true } = options;
34213
34242
  const tableOptions = this.options.getOptions();
34243
+ this.initialActions = this.initialActions.filter(
34244
+ (action) => action.storageKey === tableOptions.storageKey
34245
+ );
34214
34246
  const revision = ++this.revision;
34215
34247
  this.restoring = Boolean(tableOptions.storageKey);
34216
34248
  if (!this.restoring) return;
@@ -34222,6 +34254,14 @@ var ListTablePersistenceController = class {
34222
34254
  if (revision === this.revision) {
34223
34255
  this.restoring = false;
34224
34256
  if (this.options.getOptions().storageKey === tableOptions.storageKey) {
34257
+ if (restoreQueryState) {
34258
+ this.restoredQueryStorageKey = tableOptions.storageKey;
34259
+ const actions = this.initialActions;
34260
+ this.initialActions = [];
34261
+ actions.forEach((action) => {
34262
+ if (action.storageKey === tableOptions.storageKey) action.run();
34263
+ });
34264
+ }
34225
34265
  this.options.requestRender();
34226
34266
  }
34227
34267
  }
@@ -34242,6 +34282,9 @@ var ListTablePersistenceController = class {
34242
34282
  columns: tableOptions.columns
34243
34283
  });
34244
34284
  if (!stored || !isCurrent()) {
34285
+ if (!stored && isCurrent() && restoreQueryState) {
34286
+ this.restoredQueryStorageKey = storageKey;
34287
+ }
34245
34288
  return;
34246
34289
  }
34247
34290
  this.restoredStorageKey = storageKey;
@@ -34252,6 +34295,7 @@ var ListTablePersistenceController = class {
34252
34295
  if (restoreQueryState && stored.filterState) {
34253
34296
  this.options.setFilterState(stored.filterState);
34254
34297
  }
34298
+ if (restoreQueryState) this.restoredQueryStorageKey = storageKey;
34255
34299
  if (stored.zoom != null) {
34256
34300
  const nextZoom = normalizeContextMenuZoom(stored.zoom);
34257
34301
  this.options.setTableZoom(nextZoom);
@@ -34308,16 +34352,19 @@ var ListTablePersistenceController = class {
34308
34352
  }
34309
34353
  this.options.refreshRuntimeColumns();
34310
34354
  currentOptions.ui?.onColumnSettingsChange?.(
34311
- cloneColumns(currentOptions.columns)
34355
+ cloneColumns(currentOptions.columns),
34356
+ "restore"
34312
34357
  );
34313
34358
  }
34314
34359
  persistColumnConfig() {
34315
34360
  this.invalidate();
34316
34361
  const tableOptions = this.options.getOptions();
34317
34362
  tableOptions.ui?.onColumnSettingsChange?.(
34318
- cloneColumns(tableOptions.columns)
34363
+ cloneColumns(tableOptions.columns),
34364
+ "persist"
34319
34365
  );
34320
34366
  this.restoredStorageKey = tableOptions.storageKey;
34367
+ this.restoredQueryStorageKey = tableOptions.storageKey;
34321
34368
  this.hasRestoredPreferences = true;
34322
34369
  this.pendingWrite = Promise.resolve(
34323
34370
  persistListTableColumnConfig({
@@ -35549,7 +35596,35 @@ function emitSelectionChange(params) {
35549
35596
 
35550
35597
  // src/services/selection-action-service.ts
35551
35598
  function resolveToggleSingleSelectionAction(params) {
35552
- return toggleSingleRowSelection(params);
35599
+ const single = toggleSingleRowSelection(params);
35600
+ const { options, anchorKey, displayData } = params;
35601
+ if (!single || options.rowSelection?.type === "radio" || anchorKey == null || !displayData) {
35602
+ return single;
35603
+ }
35604
+ const targetKey = getRowKey(options, params.record, params.rowIndex);
35605
+ const anchorIndex = displayData.findIndex(
35606
+ (record, index) => getRowKey(options, record, index) === anchorKey
35607
+ );
35608
+ const targetIndex = displayData.findIndex(
35609
+ (record, index) => getRowKey(options, record, index) === targetKey
35610
+ );
35611
+ if (anchorIndex < 0 || targetIndex < 0 || anchorIndex === targetIndex)
35612
+ return single;
35613
+ const keys = new Set(params.selectedRowKeys);
35614
+ for (let index = Math.min(anchorIndex, targetIndex); index <= Math.max(anchorIndex, targetIndex); index += 1) {
35615
+ const record = displayData[index];
35616
+ if (options.rowSelection?.getCheckboxProps?.(record)?.disabled) continue;
35617
+ const key = getRowKey(options, record, index);
35618
+ if (single.selected) keys.delete(key);
35619
+ else keys.add(key);
35620
+ }
35621
+ const nextKeys = [...keys];
35622
+ return {
35623
+ ...single,
35624
+ nextKeys,
35625
+ selectedRows: getSelectedRows(options, nextKeys),
35626
+ multiple: true
35627
+ };
35553
35628
  }
35554
35629
  function resolveToggleAllVisibleSelectionAction(params) {
35555
35630
  return toggleAllVisibleRowSelection(params);
@@ -35609,6 +35684,7 @@ function fromBoundaryRightX(columnKey, positions, widths) {
35609
35684
  var ListTableRowActionController = class {
35610
35685
  constructor(options) {
35611
35686
  __publicField(this, "options");
35687
+ __publicField(this, "selectionAnchorKey");
35612
35688
  this.options = options;
35613
35689
  }
35614
35690
  freezeRow(rowIndex, position) {
@@ -35824,17 +35900,27 @@ var ListTableRowActionController = class {
35824
35900
  this.options.requestRender();
35825
35901
  return true;
35826
35902
  }
35827
- toggleRowSelection(record, rowIndex) {
35903
+ toggleRowSelection(record, rowIndex, shiftKey = false) {
35828
35904
  const resolved = resolveToggleSingleSelectionAction({
35829
35905
  options: this.options.getOptions(),
35830
35906
  selectedRowKeys: this.options.getSelectedRowKeys(),
35831
35907
  record,
35832
- rowIndex
35908
+ rowIndex,
35909
+ anchorKey: shiftKey ? this.selectionAnchorKey : void 0,
35910
+ displayData: shiftKey ? this.options.getDisplayData() : void 0
35833
35911
  });
35834
35912
  if (!resolved) {
35835
35913
  return;
35836
35914
  }
35837
- this.updateSelectedRowKeys(resolved.nextKeys, "single");
35915
+ this.selectionAnchorKey = getRowKey(
35916
+ this.options.getOptions(),
35917
+ record,
35918
+ rowIndex
35919
+ );
35920
+ this.updateSelectedRowKeys(
35921
+ resolved.nextKeys,
35922
+ "multiple" in resolved ? "multiple" : "single"
35923
+ );
35838
35924
  this.options.getOptions().rowSelection?.onSelect?.(
35839
35925
  record,
35840
35926
  !resolved.selected,
@@ -37640,10 +37726,14 @@ var ListTableCore = class {
37640
37726
  if (shouldPersistColumnConfig) {
37641
37727
  this.persistenceController.persistColumnConfig();
37642
37728
  } else {
37643
- this.persistenceController.loadStoredConfig({ restoreQueryState: false });
37729
+ this.persistenceController.loadStoredConfig({
37730
+ restoreQueryState: this.persistenceController.needsInitialQueryRestore()
37731
+ });
37644
37732
  }
37645
37733
  this.renderController.render();
37646
- if (shouldPersistColumnConfig && haveVisibleLeafColumnsChanged(previousLeafColumns, host.leafColumns)) {
37734
+ if (shouldPersistColumnConfig && (haveVisibleLeafColumnsChanged(previousLeafColumns, host.leafColumns) || previousLeafColumns.some(
37735
+ (column, index) => column.key !== host.leafColumns[index]?.key
37736
+ ))) {
37647
37737
  host.rowActionController.startColumnVisibilityAnimation({
37648
37738
  previousLeafColumns,
37649
37739
  previousSegments
@@ -37684,7 +37774,9 @@ var ListTableCore = class {
37684
37774
  * 重置排序状态。
37685
37775
  */
37686
37776
  resetSorter() {
37687
- this.headerActionController.resetSort();
37777
+ this.persistenceController.runAfterInitialRestore(
37778
+ () => this.headerActionController.resetSort()
37779
+ );
37688
37780
  }
37689
37781
  /** 获取当前排序状态,供外部设置面板回显。 */
37690
37782
  getSortState() {
@@ -37698,7 +37790,9 @@ var ListTableCore = class {
37698
37790
  * 重置筛选状态。
37699
37791
  */
37700
37792
  resetFilter() {
37701
- this.headerActionController.resetFilters();
37793
+ this.persistenceController.runAfterInitialRestore(
37794
+ () => this.headerActionController.resetFilters()
37795
+ );
37702
37796
  }
37703
37797
  /** 人工重试最近一次仍有效的本地查询失败。 */
37704
37798
  retryQuery() {
@@ -37723,7 +37817,7 @@ var ListTableCore = class {
37723
37817
  * 销毁实例。
37724
37818
  */
37725
37819
  destroy() {
37726
- this.persistenceController.invalidate();
37820
+ this.persistenceController.dispose();
37727
37821
  this.eventController.destroy();
37728
37822
  this.selectionController.destroy();
37729
37823
  this.asAssemblyHost().rowDragController.destroy();
package/dist/index.d.cts CHANGED
@@ -1987,7 +1987,7 @@ interface ListTableRowSelectionChangeInfo {
1987
1987
  type: "single" | "all" | "invert" | "none" | "multiple";
1988
1988
  }
1989
1989
  /**
1990
- * 行选择配置。
1990
+ * 行选择配置。checkbox 模式支持 Shift 点击,按当前显示顺序批量切换两次点击之间的行。
1991
1991
  */
1992
1992
  interface ListTableRowSelectionOptions<RecordType> {
1993
1993
  type?: "checkbox" | "radio";
@@ -2130,7 +2130,7 @@ interface ListTableUiOptions<RecordType = unknown> {
2130
2130
  /** 恢复持久化滚动条配置后同步到适配层。 */
2131
2131
  onScrollbarChange?: (scrollbar: ListTableScrollbarOptions) => void;
2132
2132
  /** 同步恢复或内部修改后的列设置到适配层。 */
2133
- onColumnSettingsChange?: (columns: ListTableColumn<RecordType>[]) => void;
2133
+ onColumnSettingsChange?: (columns: ListTableColumn<RecordType>[], source?: "restore" | "persist") => void;
2134
2134
  /** 同步列设置缓存开关。 */
2135
2135
  onColumnSettingsCacheChange?: (enabled: boolean) => void;
2136
2136
  /** 同步各类配置的缓存偏好。 */
package/dist/index.d.ts CHANGED
@@ -1987,7 +1987,7 @@ interface ListTableRowSelectionChangeInfo {
1987
1987
  type: "single" | "all" | "invert" | "none" | "multiple";
1988
1988
  }
1989
1989
  /**
1990
- * 行选择配置。
1990
+ * 行选择配置。checkbox 模式支持 Shift 点击,按当前显示顺序批量切换两次点击之间的行。
1991
1991
  */
1992
1992
  interface ListTableRowSelectionOptions<RecordType> {
1993
1993
  type?: "checkbox" | "radio";
@@ -2130,7 +2130,7 @@ interface ListTableUiOptions<RecordType = unknown> {
2130
2130
  /** 恢复持久化滚动条配置后同步到适配层。 */
2131
2131
  onScrollbarChange?: (scrollbar: ListTableScrollbarOptions) => void;
2132
2132
  /** 同步恢复或内部修改后的列设置到适配层。 */
2133
- onColumnSettingsChange?: (columns: ListTableColumn<RecordType>[]) => void;
2133
+ onColumnSettingsChange?: (columns: ListTableColumn<RecordType>[], source?: "restore" | "persist") => void;
2134
2134
  /** 同步列设置缓存开关。 */
2135
2135
  onColumnSettingsCacheChange?: (enabled: boolean) => void;
2136
2136
  /** 同步各类配置的缓存偏好。 */
package/dist/index.js CHANGED
@@ -24349,7 +24349,8 @@ function resolveExpandedRowHeight2(height, record, index) {
24349
24349
  // src/services/layout-service.ts
24350
24350
  var AUTO_ROW_HEIGHT_SAMPLE_COUNT = 200;
24351
24351
  function buildListTableRenderSnapshot(params) {
24352
- if (params.cache?.snapshot && params.cache.snapshot.groupIndex === params.cache.groupIndex && isSameRenderCacheInputs(params.cache.inputs, params)) {
24352
+ if (params.cache?.snapshot && // 动画结束后的首帧必须重建,清除上一帧的位移、拖拽残影及插入线。
24353
+ !params.cache.snapshot.swapAnimation && params.cache.snapshot.groupIndex === params.cache.groupIndex && isSameRenderCacheInputs(params.cache.inputs, params)) {
24353
24354
  const snapshotStartedAt2 = resolvePerformanceNow3();
24354
24355
  const cached = params.cache.snapshot;
24355
24356
  const snapshot2 = !cached.swapAnimation && cached.scroll.left === params.scroll.left && cached.scroll.top === params.scroll.top ? cached : updateListTableRenderSnapshotScroll({
@@ -30767,7 +30768,7 @@ var ListTableEventController = class {
30767
30768
  this.host.updateTooltip(result);
30768
30769
  return;
30769
30770
  }
30770
- if ((event.shiftKey || toggleColumn) && (result.area === "body" || result.area === "body-content") && typeof result.rowIndex === "number" && result.columnKey && !isSystemColumnKey(result.columnKey)) {
30771
+ if ((event.shiftKey || toggleColumn) && (result.area === "body" || result.area === "body-content") && !(event.shiftKey && !toggleColumn && this.host.options.rowSelection?.selectRowByClick && this.host.options.rowSelection.type !== "radio") && typeof result.rowIndex === "number" && result.columnKey && !isSystemColumnKey(result.columnKey)) {
30771
30772
  const columnIndex = this.host.leafColumns.findIndex(
30772
30773
  (column) => column.key === result.columnKey
30773
30774
  );
@@ -30913,7 +30914,7 @@ var ListTableEventController = class {
30913
30914
  if ((result.area === "body-control" || result.area === "body") && result.columnKey === ROW_SELECTION_COLUMN_KEY && typeof result.rowIndex === "number") {
30914
30915
  const record = this.resolveBodyRecord(result.rowIndex);
30915
30916
  if (record) {
30916
- this.host.toggleRowSelection(record, result.rowIndex);
30917
+ this.host.toggleRowSelection(record, result.rowIndex, event.shiftKey);
30917
30918
  }
30918
30919
  return;
30919
30920
  }
@@ -30934,9 +30935,13 @@ var ListTableEventController = class {
30934
30935
  }
30935
30936
  );
30936
30937
  if (canOpenEditorByDoubleClick && event.detail === 1) {
30937
- this.scheduleEditableCellRowSelection(record, result.rowIndex);
30938
+ this.scheduleEditableCellRowSelection(
30939
+ record,
30940
+ result.rowIndex,
30941
+ event.shiftKey
30942
+ );
30938
30943
  } else if (!canOpenEditorByDoubleClick || event.detail !== 2) {
30939
- this.host.toggleRowSelection(record, result.rowIndex);
30944
+ this.host.toggleRowSelection(record, result.rowIndex, event.shiftKey);
30940
30945
  }
30941
30946
  }
30942
30947
  }
@@ -31515,11 +31520,11 @@ var ListTableEventController = class {
31515
31520
  event.preventDefault();
31516
31521
  this.host.editingController.open(rowIndex, columnKey, event.key);
31517
31522
  }
31518
- scheduleEditableCellRowSelection(record, rowIndex) {
31523
+ scheduleEditableCellRowSelection(record, rowIndex, shiftKey) {
31519
31524
  this.cancelPendingEditableCellRowSelection();
31520
31525
  this.pendingEditableCellRowSelectionTimer = globalThis.setTimeout(() => {
31521
31526
  this.pendingEditableCellRowSelectionTimer = null;
31522
- this.host.toggleRowSelection(record, rowIndex);
31527
+ this.host.toggleRowSelection(record, rowIndex, shiftKey);
31523
31528
  }, EDITABLE_CELL_ROW_SELECTION_DELAY);
31524
31529
  }
31525
31530
  cancelPendingEditableCellRowSelection() {
@@ -33065,7 +33070,10 @@ function createListTableEventHost(core) {
33065
33070
  clearBodySelection: () => core.selectionController.clearBodySelection(),
33066
33071
  clearSelectedHeader: () => core.selectionController.clearSelectedHeader(),
33067
33072
  selectHeader: (columnKey, rect) => core.selectionController.selectHeader(columnKey, rect),
33068
- resetRangeHighlightForHeaderSelection: (shiftKey, ctrlKey) => core.selectionController.resetRangeHighlightForHeaderSelection(shiftKey, ctrlKey),
33073
+ resetRangeHighlightForHeaderSelection: (shiftKey, ctrlKey) => core.selectionController.resetRangeHighlightForHeaderSelection(
33074
+ shiftKey,
33075
+ ctrlKey
33076
+ ),
33069
33077
  updateRangeHighlightForBodyInteraction: (params) => core.selectionController.updateRangeHighlightForBodyInteraction(params),
33070
33078
  updateRangeHighlightForHeaderClick: (columnKey, shiftKey, ctrlKey) => core.selectionController.updateRangeHighlightForHeaderClick(
33071
33079
  columnKey,
@@ -33084,7 +33092,7 @@ function createListTableEventHost(core) {
33084
33092
  showCellContentPreview: (content) => core.contentActionController.showCellContentPreview(content),
33085
33093
  showDangerConfirmRequest: (request) => core.overlayController.showDangerConfirm(request),
33086
33094
  toggleSelectAllVisibleRows: () => core.rowActionController.toggleSelectAllVisibleRows(),
33087
- toggleRowSelection: (record, rowIndex) => core.rowActionController.toggleRowSelection(record, rowIndex),
33095
+ toggleRowSelection: (record, rowIndex, shiftKey) => core.rowActionController.toggleRowSelection(record, rowIndex, shiftKey),
33088
33096
  toggleRowExpand: (rowIndex) => core.rowActionController.toggleRowExpand(rowIndex),
33089
33097
  expandCollapsedRange: (contentKey) => core.rowActionController.expandCollapsedRange(contentKey),
33090
33098
  expandCollapsedColumnRange: (contentKey) => core.rowActionController.expandCollapsedColumnRange(contentKey),
@@ -34173,14 +34181,35 @@ var ListTablePersistenceController = class {
34173
34181
  __publicField(this, "revision", 0);
34174
34182
  __publicField(this, "pendingWrite");
34175
34183
  __publicField(this, "restoredStorageKey");
34184
+ __publicField(this, "restoredQueryStorageKey");
34176
34185
  __publicField(this, "hasRestoredPreferences", false);
34177
34186
  __publicField(this, "restoring", false);
34187
+ __publicField(this, "initialActions", []);
34178
34188
  this.options = options;
34179
34189
  }
34190
+ /** 初始化期间的重置等待缓存恢复,避免将默认列和空排序写回缓存。 */
34191
+ runAfterInitialRestore(run) {
34192
+ const storageKey = this.options.getOptions().storageKey;
34193
+ if (storageKey && this.needsInitialQueryRestore()) {
34194
+ this.initialActions.push({ storageKey, run });
34195
+ } else {
34196
+ run();
34197
+ }
34198
+ }
34199
+ /** 销毁时丢弃等待中的交互,避免已卸载表格再次写入缓存。 */
34200
+ dispose() {
34201
+ this.invalidate();
34202
+ this.initialActions = [];
34203
+ }
34180
34204
  /** 缓存恢复完成之前保留上一帧,避免默认配置先于缓存绘制。 */
34181
34205
  isRestoring() {
34182
34206
  return this.restoring;
34183
34207
  }
34208
+ /** 首次缓存读取被配置更新打断时,后续读取仍需恢复该表的查询状态。 */
34209
+ needsInitialQueryRestore() {
34210
+ const storageKey = this.options.getOptions().storageKey;
34211
+ return Boolean(storageKey && this.restoredQueryStorageKey !== storageKey);
34212
+ }
34184
34213
  /** 使尚未完成的缓存恢复失效。 */
34185
34214
  invalidate() {
34186
34215
  this.revision += 1;
@@ -34189,6 +34218,9 @@ var ListTablePersistenceController = class {
34189
34218
  async loadStoredConfig(options = {}) {
34190
34219
  const { restoreQueryState = true } = options;
34191
34220
  const tableOptions = this.options.getOptions();
34221
+ this.initialActions = this.initialActions.filter(
34222
+ (action) => action.storageKey === tableOptions.storageKey
34223
+ );
34192
34224
  const revision = ++this.revision;
34193
34225
  this.restoring = Boolean(tableOptions.storageKey);
34194
34226
  if (!this.restoring) return;
@@ -34200,6 +34232,14 @@ var ListTablePersistenceController = class {
34200
34232
  if (revision === this.revision) {
34201
34233
  this.restoring = false;
34202
34234
  if (this.options.getOptions().storageKey === tableOptions.storageKey) {
34235
+ if (restoreQueryState) {
34236
+ this.restoredQueryStorageKey = tableOptions.storageKey;
34237
+ const actions = this.initialActions;
34238
+ this.initialActions = [];
34239
+ actions.forEach((action) => {
34240
+ if (action.storageKey === tableOptions.storageKey) action.run();
34241
+ });
34242
+ }
34203
34243
  this.options.requestRender();
34204
34244
  }
34205
34245
  }
@@ -34220,6 +34260,9 @@ var ListTablePersistenceController = class {
34220
34260
  columns: tableOptions.columns
34221
34261
  });
34222
34262
  if (!stored || !isCurrent()) {
34263
+ if (!stored && isCurrent() && restoreQueryState) {
34264
+ this.restoredQueryStorageKey = storageKey;
34265
+ }
34223
34266
  return;
34224
34267
  }
34225
34268
  this.restoredStorageKey = storageKey;
@@ -34230,6 +34273,7 @@ var ListTablePersistenceController = class {
34230
34273
  if (restoreQueryState && stored.filterState) {
34231
34274
  this.options.setFilterState(stored.filterState);
34232
34275
  }
34276
+ if (restoreQueryState) this.restoredQueryStorageKey = storageKey;
34233
34277
  if (stored.zoom != null) {
34234
34278
  const nextZoom = normalizeContextMenuZoom(stored.zoom);
34235
34279
  this.options.setTableZoom(nextZoom);
@@ -34286,16 +34330,19 @@ var ListTablePersistenceController = class {
34286
34330
  }
34287
34331
  this.options.refreshRuntimeColumns();
34288
34332
  currentOptions.ui?.onColumnSettingsChange?.(
34289
- cloneColumns(currentOptions.columns)
34333
+ cloneColumns(currentOptions.columns),
34334
+ "restore"
34290
34335
  );
34291
34336
  }
34292
34337
  persistColumnConfig() {
34293
34338
  this.invalidate();
34294
34339
  const tableOptions = this.options.getOptions();
34295
34340
  tableOptions.ui?.onColumnSettingsChange?.(
34296
- cloneColumns(tableOptions.columns)
34341
+ cloneColumns(tableOptions.columns),
34342
+ "persist"
34297
34343
  );
34298
34344
  this.restoredStorageKey = tableOptions.storageKey;
34345
+ this.restoredQueryStorageKey = tableOptions.storageKey;
34299
34346
  this.hasRestoredPreferences = true;
34300
34347
  this.pendingWrite = Promise.resolve(
34301
34348
  persistListTableColumnConfig({
@@ -35527,7 +35574,35 @@ function emitSelectionChange(params) {
35527
35574
 
35528
35575
  // src/services/selection-action-service.ts
35529
35576
  function resolveToggleSingleSelectionAction(params) {
35530
- return toggleSingleRowSelection(params);
35577
+ const single = toggleSingleRowSelection(params);
35578
+ const { options, anchorKey, displayData } = params;
35579
+ if (!single || options.rowSelection?.type === "radio" || anchorKey == null || !displayData) {
35580
+ return single;
35581
+ }
35582
+ const targetKey = getRowKey(options, params.record, params.rowIndex);
35583
+ const anchorIndex = displayData.findIndex(
35584
+ (record, index) => getRowKey(options, record, index) === anchorKey
35585
+ );
35586
+ const targetIndex = displayData.findIndex(
35587
+ (record, index) => getRowKey(options, record, index) === targetKey
35588
+ );
35589
+ if (anchorIndex < 0 || targetIndex < 0 || anchorIndex === targetIndex)
35590
+ return single;
35591
+ const keys = new Set(params.selectedRowKeys);
35592
+ for (let index = Math.min(anchorIndex, targetIndex); index <= Math.max(anchorIndex, targetIndex); index += 1) {
35593
+ const record = displayData[index];
35594
+ if (options.rowSelection?.getCheckboxProps?.(record)?.disabled) continue;
35595
+ const key = getRowKey(options, record, index);
35596
+ if (single.selected) keys.delete(key);
35597
+ else keys.add(key);
35598
+ }
35599
+ const nextKeys = [...keys];
35600
+ return {
35601
+ ...single,
35602
+ nextKeys,
35603
+ selectedRows: getSelectedRows(options, nextKeys),
35604
+ multiple: true
35605
+ };
35531
35606
  }
35532
35607
  function resolveToggleAllVisibleSelectionAction(params) {
35533
35608
  return toggleAllVisibleRowSelection(params);
@@ -35587,6 +35662,7 @@ function fromBoundaryRightX(columnKey, positions, widths) {
35587
35662
  var ListTableRowActionController = class {
35588
35663
  constructor(options) {
35589
35664
  __publicField(this, "options");
35665
+ __publicField(this, "selectionAnchorKey");
35590
35666
  this.options = options;
35591
35667
  }
35592
35668
  freezeRow(rowIndex, position) {
@@ -35802,17 +35878,27 @@ var ListTableRowActionController = class {
35802
35878
  this.options.requestRender();
35803
35879
  return true;
35804
35880
  }
35805
- toggleRowSelection(record, rowIndex) {
35881
+ toggleRowSelection(record, rowIndex, shiftKey = false) {
35806
35882
  const resolved = resolveToggleSingleSelectionAction({
35807
35883
  options: this.options.getOptions(),
35808
35884
  selectedRowKeys: this.options.getSelectedRowKeys(),
35809
35885
  record,
35810
- rowIndex
35886
+ rowIndex,
35887
+ anchorKey: shiftKey ? this.selectionAnchorKey : void 0,
35888
+ displayData: shiftKey ? this.options.getDisplayData() : void 0
35811
35889
  });
35812
35890
  if (!resolved) {
35813
35891
  return;
35814
35892
  }
35815
- this.updateSelectedRowKeys(resolved.nextKeys, "single");
35893
+ this.selectionAnchorKey = getRowKey(
35894
+ this.options.getOptions(),
35895
+ record,
35896
+ rowIndex
35897
+ );
35898
+ this.updateSelectedRowKeys(
35899
+ resolved.nextKeys,
35900
+ "multiple" in resolved ? "multiple" : "single"
35901
+ );
35816
35902
  this.options.getOptions().rowSelection?.onSelect?.(
35817
35903
  record,
35818
35904
  !resolved.selected,
@@ -37618,10 +37704,14 @@ var ListTableCore = class {
37618
37704
  if (shouldPersistColumnConfig) {
37619
37705
  this.persistenceController.persistColumnConfig();
37620
37706
  } else {
37621
- this.persistenceController.loadStoredConfig({ restoreQueryState: false });
37707
+ this.persistenceController.loadStoredConfig({
37708
+ restoreQueryState: this.persistenceController.needsInitialQueryRestore()
37709
+ });
37622
37710
  }
37623
37711
  this.renderController.render();
37624
- if (shouldPersistColumnConfig && haveVisibleLeafColumnsChanged(previousLeafColumns, host.leafColumns)) {
37712
+ if (shouldPersistColumnConfig && (haveVisibleLeafColumnsChanged(previousLeafColumns, host.leafColumns) || previousLeafColumns.some(
37713
+ (column, index) => column.key !== host.leafColumns[index]?.key
37714
+ ))) {
37625
37715
  host.rowActionController.startColumnVisibilityAnimation({
37626
37716
  previousLeafColumns,
37627
37717
  previousSegments
@@ -37662,7 +37752,9 @@ var ListTableCore = class {
37662
37752
  * 重置排序状态。
37663
37753
  */
37664
37754
  resetSorter() {
37665
- this.headerActionController.resetSort();
37755
+ this.persistenceController.runAfterInitialRestore(
37756
+ () => this.headerActionController.resetSort()
37757
+ );
37666
37758
  }
37667
37759
  /** 获取当前排序状态,供外部设置面板回显。 */
37668
37760
  getSortState() {
@@ -37676,7 +37768,9 @@ var ListTableCore = class {
37676
37768
  * 重置筛选状态。
37677
37769
  */
37678
37770
  resetFilter() {
37679
- this.headerActionController.resetFilters();
37771
+ this.persistenceController.runAfterInitialRestore(
37772
+ () => this.headerActionController.resetFilters()
37773
+ );
37680
37774
  }
37681
37775
  /** 人工重试最近一次仍有效的本地查询失败。 */
37682
37776
  retryQuery() {
@@ -37701,7 +37795,7 @@ var ListTableCore = class {
37701
37795
  * 销毁实例。
37702
37796
  */
37703
37797
  destroy() {
37704
- this.persistenceController.invalidate();
37798
+ this.persistenceController.dispose();
37705
37799
  this.eventController.destroy();
37706
37800
  this.selectionController.destroy();
37707
37801
  this.asAssemblyHost().rowDragController.destroy();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canvas-components/list-table",
3
- "version": "0.3.30",
3
+ "version": "0.3.32",
4
4
  "description": "Framework-agnostic list table core engine.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -27,11 +27,11 @@
27
27
  },
28
28
  "dependencies": {
29
29
  "@ant-design/icons-svg": "4.6.0",
30
- "@canvas-components/qrcode": "0.2.2",
31
- "@canvas-components/utils": "0.2.8",
32
30
  "@canvas-components/barcode": "0.2.2",
33
31
  "@canvas-components/chart": "0.3.7",
34
- "@canvas-components/stats": "0.1.4"
32
+ "@canvas-components/stats": "0.1.4",
33
+ "@canvas-components/qrcode": "0.2.2",
34
+ "@canvas-components/utils": "0.2.8"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "tsup --config tsup.config.ts"