perf(table): помощники columnSizingInfo для перетаскивания ширины

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
This commit is contained in:
Andrey Epifancev 2026-10-28 21:17:15 +04:00
parent b7971e5cd6
commit 61cafb44a6
2 changed files with 57 additions and 0 deletions

View File

@ -0,0 +1,17 @@
// columnSizingInfo для MRT/TanStack при собственном перетаскивании ширины (TableHead/ColumnResizer).
// Пока isResizingColumn !== false, MRT 3.2.1 не пересоздаёт колонки и замораживает тело таблицы
// (openspec/changes/aurora-1839-cell-memo/design.md, «Контекст» п. 3–4, D3).
export const DEFAULT_COLUMN_SIZING_INFO = {
startOffset: null,
startSize: null,
deltaOffset: null,
deltaPercentage: null,
isResizingColumn: false,
columnSizingStart: [],
};
export const startColumnResize = (columnId) => (old) => ({ ...old, isResizingColumn: columnId });
// Идемпотентно: конец перетаскивания приходит из mouseup, blur окна и размонтирования.
export const endColumnResize = (old) => (old.isResizingColumn === false ? old : { ...old, isResizingColumn: false });

View File

@ -0,0 +1,40 @@
import assert from 'node:assert/strict';
import test from 'node:test';
import { createTable, getCoreRowModel } from '@tanstack/table-core';
import { DEFAULT_COLUMN_SIZING_INFO, endColumnResize, startColumnResize } from './columnResizeInfo.js';
test('значение по умолчанию совпадает с table-core', () => {
const table = createTable({ data: [], columns: [{ accessorKey: 'a' }], state: {}, getCoreRowModel: getCoreRowModel() });
assert.deepEqual(DEFAULT_COLUMN_SIZING_INFO, table.initialState.columnSizingInfo);
});
test('startColumnResize ставит id колонки и не трогает остальные поля', () => {
const next = startColumnResize('data.q1')(DEFAULT_COLUMN_SIZING_INFO);
assert.equal(next.isResizingColumn, 'data.q1');
assert.deepEqual({ ...next, isResizingColumn: false }, DEFAULT_COLUMN_SIZING_INFO);
assert.equal(DEFAULT_COLUMN_SIZING_INFO.isResizingColumn, false);
});
test('endColumnResize снимает флаг, повторный вызов возвращает тот же объект', () => {
const ended = endColumnResize(startColumnResize('a')(DEFAULT_COLUMN_SIZING_INFO));
assert.equal(ended.isResizingColumn, false);
assert.equal(endColumnResize(ended), ended);
assert.equal(endColumnResize(DEFAULT_COLUMN_SIZING_INFO), DEFAULT_COLUMN_SIZING_INFO);
});
test('table.setColumnSizingInfo проводит флаг через управляемое состояние', () => {
let info = DEFAULT_COLUMN_SIZING_INFO;
const table = createTable({
data: [{ a: 1 }],
columns: [{ accessorKey: 'a' }],
state: { columnSizingInfo: info },
onColumnSizingInfoChange: (updater) => {
info = typeof updater === 'function' ? updater(info) : updater;
},
getCoreRowModel: getCoreRowModel(),
});
table.setColumnSizingInfo(startColumnResize('a'));
assert.equal(info.isResizingColumn, 'a');
table.setColumnSizingInfo(endColumnResize);
assert.equal(info.isResizingColumn, false);
});