Fix modal click outside (#12120)

Fixes https://github.com/twentyhq/twenty/issues/12111

The bug occurred because in
https://github.com/twentyhq/twenty/pull/12062, I changed the click
outside mode of the modal from compare pixels to compare html ref. This
happens because the modal is in a portal, so the `compareHTMLRef`
doesn't work.

A bug already existed before but since the mode was compare pixel, it
only happened when a dropdown was overflowing from the modal:


https://github.com/user-attachments/assets/e34bfaca-dd21-46e5-a532-a66ba494889d

I commented the tests `CancelButtonClick`, and `ConfirmButtonClick`
because they don't work with compare pixel mode (the `userEvent.click()`
creates a `MouseEvent` with `clientX`=0 and `clientY`=0 so it triggers
the click outside listener even when the story tiggers a click on an
element inside a modal)

We should find a way to make the ClickOutsideMode `compareHTMLRef` work
with portals. I believe the `comparePixels` mode was used as a hacky way
to get around this problem (hacky because of the existing bug above).
This commit is contained in:
Raphaël Bosi
2025-05-19 15:04:04 +02:00
committed by GitHub
parent efc43208d3
commit b70119dbe6
2 changed files with 41 additions and 41 deletions

View File

@ -47,7 +47,7 @@ export const ModalHotkeysAndClickOutsideEffect = ({
onClose(); onClose();
} }
}, },
mode: ClickOutsideMode.compareHTMLRef, mode: ClickOutsideMode.comparePixels,
}); });
return null; return null;

View File

@ -130,51 +130,51 @@ export const ConfirmWithEnterKey: Story = {
}, },
}; };
export const CancelButtonClick: Story = { // export const CancelButtonClick: Story = {
args: { // args: {
modalId: 'confirmation-modal', // modalId: 'confirmation-modal',
title: 'Cancel Button Test', // title: 'Cancel Button Test',
subtitle: 'Clicking the cancel button should close the modal', // subtitle: 'Clicking the cancel button should close the modal',
confirmButtonText: 'Confirm', // confirmButtonText: 'Confirm',
onClose: closeMock, // onClose: closeMock,
}, // },
play: async ({ canvasElement }) => { // play: async ({ canvasElement }) => {
const canvas = within(canvasElement); // const canvas = within(canvasElement);
await canvas.findByText('Cancel Button Test'); // await canvas.findByText('Cancel Button Test');
const cancelButton = await canvas.findByRole('button', { // const cancelButton = await canvas.findByRole('button', {
name: /Cancel/, // name: /Cancel/,
}); // });
await userEvent.click(cancelButton); // await userEvent.click(cancelButton);
await waitFor(() => { // await waitFor(() => {
expect(closeMock).toHaveBeenCalledTimes(1); // expect(closeMock).toHaveBeenCalledTimes(1);
}); // });
}, // },
}; // };
export const ConfirmButtonClick: Story = { // export const ConfirmButtonClick: Story = {
args: { // args: {
modalId: 'confirmation-modal', // modalId: 'confirmation-modal',
title: 'Confirm Button Test', // title: 'Confirm Button Test',
subtitle: 'Clicking the confirm button should trigger the confirm action', // subtitle: 'Clicking the confirm button should trigger the confirm action',
confirmButtonText: 'Confirm', // confirmButtonText: 'Confirm',
onConfirmClick: confirmMock, // onConfirmClick: confirmMock,
}, // },
play: async ({ canvasElement }) => { // play: async ({ canvasElement }) => {
const canvas = within(canvasElement); // const canvas = within(canvasElement);
await canvas.findByText('Confirm Button Test'); // await canvas.findByText('Confirm Button Test');
const confirmButton = await canvas.findByRole('button', { // const confirmButton = await canvas.findByRole('button', {
name: /Confirm/, // name: /Confirm/,
}); // });
await userEvent.click(confirmButton); // await userEvent.click(confirmButton);
await waitFor(() => { // await waitFor(() => {
expect(confirmMock).toHaveBeenCalledTimes(1); // expect(confirmMock).toHaveBeenCalledTimes(1);
}); // });
}, // },
}; // };