From 31467f2173806c64cd39f7d0fb86b0dc3f5f3c43 Mon Sep 17 00:00:00 2001 From: Abdul Rahman <81605929+abdulrahmancodes@users.noreply.github.com> Date: Mon, 15 Dec 2025 23:06:24 +0530 Subject: [PATCH] Fix action menu modals rendering inside dropdown containers (#16478) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #16363 - Updated modals to open in the full screen by default Screenshot 2025-12-11 at 12 15
15 AM --- .../modal/components/ConfirmationModal.tsx | 1 + .../ui/layout/modal/components/Modal.tsx | 8 +++- .../__stories__/ConfirmationModal.stories.tsx | 37 ++++++++++--------- 3 files changed, 26 insertions(+), 20 deletions(-) diff --git a/packages/twenty-front/src/modules/ui/layout/modal/components/ConfirmationModal.tsx b/packages/twenty-front/src/modules/ui/layout/modal/components/ConfirmationModal.tsx index 5f0a31a750..badaa50186 100644 --- a/packages/twenty-front/src/modules/ui/layout/modal/components/ConfirmationModal.tsx +++ b/packages/twenty-front/src/modules/ui/layout/modal/components/ConfirmationModal.tsx @@ -117,6 +117,7 @@ export const ConfirmationModal = ({ padding="large" modalVariant={modalVariant} dataGloballyPreventClickOutside + ignoreContainer > diff --git a/packages/twenty-front/src/modules/ui/layout/modal/components/Modal.tsx b/packages/twenty-front/src/modules/ui/layout/modal/components/Modal.tsx index 5857f1ff99..8877d4ab0e 100644 --- a/packages/twenty-front/src/modules/ui/layout/modal/components/Modal.tsx +++ b/packages/twenty-front/src/modules/ui/layout/modal/components/Modal.tsx @@ -230,8 +230,12 @@ export const Modal = ({ const isMobile = useIsMobile(); const modalRef = useRef(null); const { container } = useModalContainer(); - const effectiveContainer = ignoreContainer ? null : container; - const isInContainer = isDefined(effectiveContainer); + const effectiveContainer = ignoreContainer + ? isDefined(document) + ? document.body + : null + : container; + const isInContainer = isDefined(container) && !ignoreContainer; const theme = useTheme(); diff --git a/packages/twenty-front/src/modules/ui/layout/modal/components/__stories__/ConfirmationModal.stories.tsx b/packages/twenty-front/src/modules/ui/layout/modal/components/__stories__/ConfirmationModal.stories.tsx index 2a56c76390..5d58fc6e31 100644 --- a/packages/twenty-front/src/modules/ui/layout/modal/components/__stories__/ConfirmationModal.stories.tsx +++ b/packages/twenty-front/src/modules/ui/layout/modal/components/__stories__/ConfirmationModal.stories.tsx @@ -56,6 +56,7 @@ export const Default: Story = { title: 'Pariatur labore.', subtitle: 'Velit dolore aliquip laborum occaecat fugiat.', confirmButtonText: 'Delete', + onConfirmClick: fn(), }, }; @@ -75,10 +76,10 @@ export const CloseOnEscape: Story = { confirmButtonText: 'Confirm', onClose: closeMock, }, - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); + play: async () => { + const body = within(document.body); - await canvas.findByText('Escape Key Test'); + await body.findByText('Escape Key Test'); closeMock.mockClear(); @@ -98,12 +99,12 @@ export const CloseOnClickOutside: Story = { confirmButtonText: 'Confirm', onClose: closeMock, }, - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); + play: async () => { + const body = within(document.body); - await canvas.findByText('Click Outside Test'); + await body.findByText('Click Outside Test'); - const backdrop = await canvas.findByTestId('modal-backdrop'); + const backdrop = await body.findByTestId('modal-backdrop'); // We need to wait for the outside click listener to be registered await sleep(100); @@ -124,10 +125,10 @@ export const ConfirmWithEnterKey: Story = { confirmButtonText: 'Confirm', onConfirmClick: confirmMock, }, - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); + play: async () => { + const body = within(document.body); - await canvas.findByText('Enter Key Test'); + await body.findByText('Enter Key Test'); await userEvent.keyboard('{Enter}'); @@ -145,12 +146,12 @@ export const CancelButtonClick: Story = { confirmButtonText: 'Confirm', onClose: closeMock, }, - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); + play: async () => { + const body = within(document.body); - await canvas.findByText('Cancel Button Test'); + await body.findByText('Cancel Button Test'); - const cancelButton = await canvas.findByRole('button', { + const cancelButton = await body.findByRole('button', { name: /Cancel/, }); await userEvent.click(cancelButton); @@ -169,12 +170,12 @@ export const ConfirmButtonClick: Story = { confirmButtonText: 'Confirm', onConfirmClick: confirmMock, }, - play: async ({ canvasElement }) => { - const canvas = within(canvasElement); + play: async () => { + const body = within(document.body); - await canvas.findByText('Confirm Button Test'); + await body.findByText('Confirm Button Test'); - const confirmButton = await canvas.findByRole('button', { + const confirmButton = await body.findByRole('button', { name: /Confirm/, });