primitives
primitives copied to clipboard
Triggering Dialog raise error when using nested component from React.Children
Bug report
Current Behavior
I'm building Modal component, using Dialog primitive from radix-ui. Everything worked amazing until i decided that our Modal component will use React.Children to map nested component to proper places inside Dialog.Root wrapper.
The problem is, that there is an error showing app in console when triggering modal/dialog (everything on frontend seems to work as expected but.. well error is happening :)
Here is the repository where there is example of what i'm talking about:
- https://github.com/marckraw/slot-issue-radix
(While writing this issue, found out that it doesnt happen after deployed to production version of Next.js, but is happening locally)
Here is the main part of component
const Modal: FC<ModalProps> = ({ children }) => {
const childrenArray = React.Children.toArray(children);
console.log(childrenArray);
const toSlots = childrenArray.reduce((prev: any, next: any) => {
return {
...prev,
[next.type.displayName]: next,
};
}, {});
console.log(toSlots);
return (
<Dialog.Root>
{toSlots.ModalTrigger}
<Dialog.Portal>
<Dialog.Overlay className={styles.modalOverlay} />
{toSlots.ModalContent}
</Dialog.Portal>
</Dialog.Root>
);
};
And part where we use this component:
<Modal>
<ModalTrigger>Trigger my modal</ModalTrigger>
<ModalContent>
<h2 style={{ marginTop: 0 }}>Demo</h2>
<p>
Pellentesque habitant morbi tristique senectus et netus et malesuada
fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae,
ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam
egestas semper. Aenean ultricies mi vitae est. Mauris placerat
eleifend leo.
</p>
<p>
Pellentesque habitant morbi tristique senectus et netus et malesuada
fames ac turpis egestas. Vestibulum tortor quam, feugiat vitae,
ultricies eget, tempor sit amet, ante. Donec eu libero sit amet quam
egestas semper. Aenean ultricies mi vitae est. Mauris placerat
eleifend leo.
</p>
</ModalContent>
</Modal>
Expected behavior
Should not raise an error.
Reproducible example
https://github.com/marckraw/slot-issue-radix
Your environment
React, Next.js, newest Radix Dialog component
@marckraw Seems this approach is attempting to pass refs to your standard function comps, the message wouldn't appear in prod as it's a dev only warning afaik.
One solution would be to simply ensure all of you recomposition's forward a ref correctly, eg:
const ModalContent = React.forwardRef(({ children, ...rest }, forwardedRef) => {
return (
<Dialog.Content {...rest} className={styles.modalContent} ref={forwardedRef}>
{children}
<Dialog.Close>Exit</Dialog.Close>
</Dialog.Content>
);
});
Though I'm curious on this approach, why not simply close over the Portal and Overlay inside ModalContent?
@andy-hook ah yeah, now it works perfectly fine in dev and prod, when passing refs :)
Thx!