Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[lexical-playground] Bug Fix: Table action menu visibility with cell overflow #7334

Merged
56 changes: 56 additions & 0 deletions packages/lexical-playground/__tests__/e2e/Tables.spec.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6181,4 +6181,60 @@ test.describe.parallel('Tables', () => {
),
);
});

test(`Table action menu is hidden when cell overflows`, async ({
page,
isPlainText,
isCollab,
browserName,
}) => {
// The way that the clicks happen in test doesn't work in firefox for some reason
// but it does seem to work when you do it by hand
test.fixme(browserName === 'firefox');
test.skip(isPlainText || isCollab);
await initialize({isCollab, page});
await focusEditor(page);

// Insert a 2x2 table
await insertTable(page, 2, 2);

// Find and drag the column resize handle
const firstCell = await page.$('th >> nth=0');
const firstCellBox = await firstCell.boundingBox();

// Click the cell in 2nd column
await click(page, 'th >> nth=1');

// Check that the action menu button is visible when no overflow
const menuVisible = await page.evaluate(() => {
const button = document.querySelector('.table-cell-action-button');
// If button exists, menu is visible
return !!button;
});

expect(menuVisible).toBe(true);

// Make the column very wide to ensure overflow
await page.mouse.move(
firstCellBox.x + firstCellBox.width - 5,
firstCellBox.y + firstCellBox.height / 2,
);
await page.mouse.down();
await page.mouse.move(
firstCellBox.x + 2000, // Make column very wide - 2000 for more scroll space
firstCellBox.y + firstCellBox.height / 2,
);
await page.mouse.up();

// Click the cell
await click(page, 'th >> nth=0');

const menuHidden = await page.evaluate(() => {
const button = document.querySelector('.table-cell-action-button');
// If button doesn't exist, menu is hidden
return !button;
});

expect(menuHidden).toBe(true);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -801,6 +801,35 @@ function TableCellActionMenuContainer({

const [colorPickerModal, showColorPickerModal] = useModal();

const checkTableCellOverflow = useCallback(
(tableCellParentNodeDOM: HTMLElement): boolean => {
const scrollableContainer = tableCellParentNodeDOM.closest(
'.PlaygroundEditorTheme__tableScrollableWrapper',
);
if (scrollableContainer) {
const containerRect = (
scrollableContainer as HTMLElement
).getBoundingClientRect();
const cellRect = tableCellParentNodeDOM.getBoundingClientRect();

// Calculate where the action button would be positioned (5px from right edge of cell)
// Also account for the button width and table cell padding (8px)
const actionButtonRight = cellRect.right - 5;
const actionButtonLeft = actionButtonRight - 28; // 20px width + 8px padding

// Only hide if the action button would overflow the container
if (
actionButtonRight > containerRect.right ||
actionButtonLeft < containerRect.left
) {
return true;
}
}
return false;
},
[],
);

const $moveMenu = useCallback(() => {
const menu = menuButtonRef.current;
const selection = $getSelection();
Expand Down Expand Up @@ -847,6 +876,10 @@ function TableCellActionMenuContainer({
return disable();
}

if (checkTableCellOverflow(tableCellParentNodeDOM)) {
return disable();
}

const tableNode = $getTableNodeFromLexicalNodeOrThrow(
tableCellNodeFromSelection,
);
Expand Down Expand Up @@ -881,6 +914,14 @@ function TableCellActionMenuContainer({
);
tableObserver = getTableObserverFromTableElement(tableElement);
tableCellParentNodeDOM = editor.getElementByKey(anchorNode.getKey());

if (tableCellParentNodeDOM === null) {
return disable();
}

if (checkTableCellOverflow(tableCellParentNodeDOM)) {
return disable();
}
} else if (!activeElement) {
return disable();
}
Expand All @@ -903,7 +944,7 @@ function TableCellActionMenuContainer({
const left = tableCellRect.right - anchorRect.left;
menu.style.transform = `translate(${left}px, ${top}px)`;
}
}, [editor, anchorElem]);
}, [editor, anchorElem, checkTableCellOverflow]);

useEffect(() => {
// We call the $moveMenu callback every time the selection changes,
Expand Down
Loading