fix(table): ресайз завершается при потерянном mouseup; тест-характеристики table-core; комментарии
- ColumnResizer: handleMouseMove завершает перетаскивание, если левая кнопка не зажата - cellMemoReset.test: убран дубль теста columnSizing, добавлены характеристики закрепления второй колонки и скрытия закреплённой - комментарии к columnFilters (триггер React.memo(TableHead)) и ссылки на архивную спеку Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
651d71f7c0
commit
e0e460b6c2
@ -847,6 +847,7 @@ const RealtimeTable = ({ formType, formId, sheetName, direction, year }) => {
|
||||
columnPinning={columnPinning}
|
||||
columnSizing={columnSizing}
|
||||
columnVisibility={columnVisibility}
|
||||
// Проп нужен как триггер React.memo(TableHead): фильтры шапка читает из table.getState().
|
||||
columnFilters={columnFilters}
|
||||
showColumnFilters={showColumnFilters}
|
||||
selectedColumnId={selectedColumnId}
|
||||
|
||||
@ -28,6 +28,11 @@ const ColumnResizer = ({ columnId, reportDragDeltaX, onDragStart, onDragEnd }) =
|
||||
const handleMouseMove = useCallback(
|
||||
(e) => {
|
||||
if (!isDragging) return;
|
||||
// Потерянный mouseup (отпустили вне окна без blur): кнопка уже не зажата.
|
||||
if ((e.buttons & 1) === 0) {
|
||||
finishDrag();
|
||||
return;
|
||||
}
|
||||
|
||||
const deltaX = e.clientX - lastXRef.current;
|
||||
|
||||
@ -36,7 +41,7 @@ const ColumnResizer = ({ columnId, reportDragDeltaX, onDragStart, onDragEnd }) =
|
||||
lastXRef.current = e.clientX;
|
||||
}
|
||||
},
|
||||
[isDragging, reportDragDeltaX],
|
||||
[isDragging, reportDragDeltaX, finishDrag],
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
// Ключ явного сброса мемоизации ячеек MRT (memoMode: 'cells') в таблице листа.
|
||||
// Обоснование и контракт: openspec/changes/aurora-1839-cell-memo/ (design.md D1, D2; specs/sheet-table).
|
||||
// Обоснование и контракт: openspec/changes/aurora-1839-cell-memo/ (design.md D1, D2; specs/sheet-table; после архивации — openspec/specs/sheet-table/spec.md).
|
||||
// Новое состояние, которое меняет определения колонок или стили закрепления, добавляется сюда и в cellMemoReset.test.js.
|
||||
|
||||
const getPinnedSide = (ids, columnVisibility, columnSizing) =>
|
||||
|
||||
@ -110,7 +110,9 @@ test('пока ширину тянут, ключ прежний; после от
|
||||
|
||||
// Допущение @tanstack/table-core 8.20.5, на котором стоит явный сброс
|
||||
// (openspec/changes/aurora-1839-cell-memo/design.md, «Контекст», п. 3; D1).
|
||||
// Первые два теста держат допущение: ячейки пересоздаются при смене массива columns и не пересоздаются при смене ширин.
|
||||
// Тесты ниже фиксируют характеристику table-core 8.20.5 (упадут при обновлении библиотеки):
|
||||
// новый массив columns даёт новые ячейки; смена columnSizing ячейки не пересоздаёт (поэтому ключ нужен для ширины
|
||||
// закреплённой колонки); смена columnPinning пересоздаёт ячейки закреплённых сторон, центральные те же.
|
||||
const createFixture = () =>
|
||||
createTable({
|
||||
data: [{ a: 1, b: 2, c: 3 }],
|
||||
@ -131,13 +133,6 @@ const cellsById = (table) =>
|
||||
.map((cell) => [cell.id, cell]),
|
||||
);
|
||||
|
||||
test('table-core: при прежних columns и data объекты ячеек те же', () => {
|
||||
const table = createFixture();
|
||||
const before = cellsById(table);
|
||||
updateState(table, { columnSizing: { a: 80 } });
|
||||
for (const [id, cell] of cellsById(table)) assert.equal(cell, before.get(id));
|
||||
});
|
||||
|
||||
test('table-core: новый массив columns с теми же определениями даёт новые ячейки', () => {
|
||||
const table = createFixture();
|
||||
const before = cellsById(table);
|
||||
@ -147,12 +142,11 @@ test('table-core: новый массив columns с теми же опреде
|
||||
for (const [id, cell] of after) assert.notEqual(cell, before.get(id));
|
||||
});
|
||||
|
||||
// Допущение дизайна «ячейки пересоздаются только при смене columns/data» неверно для columnPinning:
|
||||
// в table-core 8.20.5 getLeftVisibleCells/getRightVisibleCells (features/ColumnPinning.js) возвращают
|
||||
// поверхностные копии `{...cell, position}`, поэтому при смене закрепления объект ячейки закрепляемой колонки
|
||||
// новый при прежнем массиве columns. Ячейки остальных колонок (центр) остаются теми же объектами.
|
||||
// Ключ сброса по закреплению остаётся как защита: он нужен для ячеек, которые table-core не пересоздаёт,
|
||||
// и сработает как страховка, если поведение сменится. Тест фиксирует факт и упадёт при обновлении table-core.
|
||||
// В table-core 8.20.5 getLeftVisibleCells/getRightVisibleCells (features/ColumnPinning.js) возвращают
|
||||
// поверхностные копии `{...cell, position}`, поэтому при смене закрепления пересоздаются ячейки закреплённых
|
||||
// колонок при прежнем массиве columns; центральные остаются теми же объектами.
|
||||
// Ключ сброса по закреплению нужен из-за ширины закреплённой колонки (смена columnSizing ячейки не пересоздаёт)
|
||||
// и как страховка на случай смены поведения библиотеки.
|
||||
test('table-core: смена columnPinning при прежнем массиве columns пересоздаёт ячейку закреплённой колонки, остальные те же', () => {
|
||||
const table = createFixture();
|
||||
const before = cellsById(table);
|
||||
@ -163,8 +157,6 @@ test('table-core: смена columnPinning при прежнем массиве
|
||||
for (const id of ['0_a', '0_b']) assert.equal(after.get(id), before.get(id));
|
||||
});
|
||||
|
||||
// Характеристика, а не ожидание дизайна: фиксирует поведение table-core 8.20.5 при смене columnSizing,
|
||||
// чтобы обновление библиотеки показало смену поведения.
|
||||
test('table-core: смена columnSizing при прежнем массиве columns оставляет те же ячейки', () => {
|
||||
const table = createFixture();
|
||||
const before = cellsById(table);
|
||||
@ -173,3 +165,24 @@ test('table-core: смена columnSizing при прежнем массиве c
|
||||
assert.equal(after.size, before.size);
|
||||
for (const [id, cell] of after) assert.equal(cell, before.get(id));
|
||||
});
|
||||
|
||||
test('table-core: закрепление второй колонки слева пересоздаёт все закреплённые ячейки, центральная та же', () => {
|
||||
const table = createFixture();
|
||||
updateState(table, { columnPinning: { left: ['a'], right: [] } });
|
||||
const before = cellsById(table);
|
||||
updateState(table, { columnPinning: { left: ['a', 'c'], right: [] } });
|
||||
const after = cellsById(table);
|
||||
assert.notEqual(after.get('0_a'), before.get('0_a'));
|
||||
assert.notEqual(after.get('0_c'), before.get('0_c'));
|
||||
assert.equal(after.get('0_b'), before.get('0_b'));
|
||||
});
|
||||
|
||||
test('table-core: скрытие закреплённой колонки пересоздаёт ячейки оставшейся закреплённой стороны', () => {
|
||||
const table = createFixture();
|
||||
updateState(table, { columnPinning: { left: ['a', 'c'], right: [] } });
|
||||
const before = cellsById(table);
|
||||
updateState(table, { columnVisibility: { a: false } });
|
||||
const after = cellsById(table);
|
||||
assert.equal(after.has('0_a'), false);
|
||||
assert.notEqual(after.get('0_c'), before.get('0_c'));
|
||||
});
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
// columnSizingInfo для MRT/TanStack при собственном перетаскивании ширины (TableHead/ColumnResizer).
|
||||
// Пока isResizingColumn !== false, MRT 3.2.1 не пересоздаёт колонки и замораживает тело таблицы
|
||||
// (openspec/changes/aurora-1839-cell-memo/design.md, «Контекст» п. 3–4, D3).
|
||||
// (openspec/changes/aurora-1839-cell-memo/design.md, «Контекст» п. 3–4, D3; после архивации — openspec/specs/sheet-table/spec.md).
|
||||
|
||||
export const DEFAULT_COLUMN_SIZING_INFO = {
|
||||
startOffset: null,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user