Skip to content

Commit 250ad49

Browse files
committed
Persist resized table column widths
1 parent 9d6f586 commit 250ad49

File tree

1 file changed

+70
-10
lines changed

1 file changed

+70
-10
lines changed

components/RichTextEditor.tsx

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,10 @@ const LinkModal: React.FC<{
274274
);
275275
};
276276

277-
const ensureColGroupWithWidths = (tableElement: HTMLTableElement): HTMLTableColElement[] => {
277+
const ensureColGroupWithWidths = (
278+
tableElement: HTMLTableElement,
279+
preferredWidths: number[] = [],
280+
): HTMLTableColElement[] => {
278281
const firstRow = tableElement.rows[0];
279282
const columnCount = firstRow?.cells.length ?? 0;
280283
if (columnCount === 0) {
@@ -297,21 +300,58 @@ const ensureColGroupWithWidths = (tableElement: HTMLTableElement): HTMLTableColE
297300
}
298301

299302
const colElements = Array.from(colGroup.children) as HTMLTableColElement[];
300-
const existingWidths = colElements.map(col => parseFloat(col.style.width || ''));
301-
const needInitialization = existingWidths.some(width => Number.isNaN(width) || width <= 0);
302303

303-
if (needInitialization) {
304-
const columnWidths = Array.from(firstRow.cells).map(cell => cell.getBoundingClientRect().width || MIN_COLUMN_WIDTH);
304+
if (preferredWidths.length === columnCount && preferredWidths.some(width => width > 0)) {
305305
colElements.forEach((col, index) => {
306-
const width = Math.max(MIN_COLUMN_WIDTH, columnWidths[index] ?? MIN_COLUMN_WIDTH);
307-
col.style.width = `${width}px`;
306+
const width = preferredWidths[index];
307+
if (Number.isFinite(width) && width > 0) {
308+
col.style.width = `${Math.max(MIN_COLUMN_WIDTH, width)}px`;
309+
}
308310
});
311+
} else {
312+
const existingWidths = colElements.map(col => parseFloat(col.style.width || ''));
313+
const needInitialization = existingWidths.some(width => Number.isNaN(width) || width <= 0);
314+
315+
if (needInitialization) {
316+
const columnWidths = Array.from(firstRow.cells).map(cell => cell.getBoundingClientRect().width || MIN_COLUMN_WIDTH);
317+
colElements.forEach((col, index) => {
318+
const width = Math.max(MIN_COLUMN_WIDTH, columnWidths[index] ?? MIN_COLUMN_WIDTH);
319+
col.style.width = `${width}px`;
320+
});
321+
}
309322
}
310323

311324
return colElements;
312325
};
313326

314-
const attachColumnResizeHandles = (tableElement: HTMLTableElement): (() => void) => {
327+
const getColumnWidthsFromState = (editor: LexicalEditor, tableKey: string): number[] => {
328+
let widths: number[] = [];
329+
330+
editor.getEditorState().read(() => {
331+
const tableNode = $getNodeByKey<TableNode>(tableKey);
332+
if (!tableNode) {
333+
return;
334+
}
335+
336+
const firstRow = tableNode.getChildren<TableRowNode>()[0];
337+
if (!firstRow) {
338+
return;
339+
}
340+
341+
widths = firstRow
342+
.getChildren<TableCellNode>()
343+
.map(cell => cell.getWidth())
344+
.filter((width): width is number => Number.isFinite(width));
345+
});
346+
347+
return widths;
348+
};
349+
350+
const attachColumnResizeHandles = (
351+
tableElement: HTMLTableElement,
352+
editor: LexicalEditor,
353+
tableKey: string,
354+
): (() => void) => {
315355
const container = tableElement.parentElement ?? tableElement;
316356
const originalContainerPosition = container.style.position;
317357
const restoreContainerPosition = originalContainerPosition === '' && getComputedStyle(container).position === 'static';
@@ -340,7 +380,8 @@ const attachColumnResizeHandles = (tableElement: HTMLTableElement): (() => void)
340380
return;
341381
}
342382

343-
const cols = ensureColGroupWithWidths(tableElement);
383+
const storedColumnWidths = getColumnWidthsFromState(editor, tableKey);
384+
const cols = ensureColGroupWithWidths(tableElement, storedColumnWidths);
344385
const containerRect = container.getBoundingClientRect();
345386
const cells = Array.from(firstRow.cells);
346387

@@ -378,6 +419,25 @@ const attachColumnResizeHandles = (tableElement: HTMLTableElement): (() => void)
378419
const handleMouseUp = () => {
379420
document.removeEventListener('mousemove', handleMouseMove);
380421
document.removeEventListener('mouseup', handleMouseUp);
422+
423+
const updatedWidths = cols.map(col => parseFloat(col.style.width || ''));
424+
editor.update(() => {
425+
const tableNode = $getNodeByKey<TableNode>(tableKey);
426+
if (!tableNode) {
427+
return;
428+
}
429+
430+
const rows = tableNode.getChildren<TableRowNode>();
431+
rows.forEach(row => {
432+
const cellsInRow = row.getChildren<TableCellNode>();
433+
cellsInRow.forEach((cellNode, cellIndex) => {
434+
const width = updatedWidths[cellIndex];
435+
if (Number.isFinite(width) && width > 0) {
436+
cellNode.setWidth(Math.max(MIN_COLUMN_WIDTH, width));
437+
}
438+
});
439+
});
440+
});
381441
};
382442

383443
const handleMouseDown = (event: MouseEvent) => {
@@ -431,7 +491,7 @@ const TableColumnResizePlugin: React.FC = () => {
431491
const tableElement = editor.getElementByKey(tableKey);
432492
if (tableElement instanceof HTMLTableElement) {
433493
cleanupTable(tableKey);
434-
cleanupMap.set(tableKey, attachColumnResizeHandles(tableElement));
494+
cleanupMap.set(tableKey, attachColumnResizeHandles(tableElement, editor, tableKey));
435495
}
436496
};
437497

0 commit comments

Comments
 (0)