-
I'm migrating react-bootstrap components such as Modal, Popover to radix-ui primitives. In my project, there are many modal dialogs that hold popover on it. When I migrate component to radix-ui, I noticed that popover content on modal dialog was no longer clickable. sample code is below. In this example, We can't click + button on the popover. const App = () => {
const [count, setCount] = useState(0);
return (
<Modal isOpen onClose={() => {}}>
<div>count: {count}</div>
<MyPopover
content={
<button onClick={() => setCount((prev) => prev + 1)}>+</button>
}
>
show
</MyPopover>
</Modal>
);
}; full codeimport React, { useState, ReactNode, ReactChild } from 'react';
import { render } from 'react-dom';
import styled from 'styled-components';
import * as Dialog from '@radix-ui/react-dialog';
import * as Popover from '@radix-ui/react-popover';
const Styled = {
Content: styled(Dialog.Content)`
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: #ccc;
width: 500px;
aspect-ratio: 1;
padding: 4px;
z-index: 2000;
`,
Overlay: styled(Dialog.Overlay)`
z-index: 2000;
background: rgba(0, 0, 0, 0.5);
position: fixed;
inset: 0;
`,
};
export const Modal = ({
isOpen,
onClose,
children,
}: {
isOpen: boolean;
onClose: () => void;
children: ReactNode;
}) => (
<Dialog.Root
open={isOpen}
onOpenChange={(open) => {
if (!open) onClose();
}}
>
<Dialog.Portal>
<Styled.Overlay>
<Styled.Content>{children}</Styled.Content>
</Styled.Overlay>
</Dialog.Portal>
</Dialog.Root>
);
const PopoverContent = styled(Popover.Content)`
max-width: 276px;
padding: 6px;
font-size: 14px;
font-weight: normal;
text-align: left;
background-color: #fff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, 0.2);
border-radius: 6px;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
z-index: 3000;
`;
export const MyPopover = ({
content,
children,
}: {
content: ReactNode;
children: ReactChild;
}) => {
return (
<Popover.Root>
<Popover.Trigger>{children}</Popover.Trigger>
<Popover.Portal>
<PopoverContent>
{content}
<Popover.Arrow />
</PopoverContent>
</Popover.Portal>
</Popover.Root>
);
};
const App = () => {
const [count, setCount] = useState(0);
return (
<Modal isOpen onClose={() => {}}>
<div>count: {count}</div>
<MyPopover
content={
<button onClick={() => setCount((prev) => prev + 1)}>+</button>
}
>
show
</MyPopover>
</Modal>
);
};
render(<App />, document.getElementById('root')); It seems that DismissableLayer component adds pointer-events style to body node. then elements without So, adding But that solution is not ideal, there are so many components to huddle. So I would like to know if there is any other solution. In fact, this is not limited to popover content, but any other component on the modal dialog especially if it is rendered as a portal (in my project, some date-picker component on the dialog was not clickable too) I'm sorry for my terrible English, but I would appreciate your cooperation. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
I've had no problems clicking popover content on dialogs using other UI frameworks such as Chakra UI. |
Beta Was this translation helpful? Give feedback.
-
Out of curiosity were you running two different versions of dialog and popover? I have a feeling the issue may have been related to this: #1088 |
Beta Was this translation helpful? Give feedback.
-
Hello, something that worked out for me was setting pointer events to auto PopoverContent
className="w-full p-0 pointer-events-auto"
side="top"
> ... </PopoverContent> |
Beta Was this translation helpful? Give feedback.
Out of curiosity were you running two different versions of dialog and popover? I have a feeling the issue may have been related to this: #1088