diff --git a/src/components/Portal.web.tsx b/src/components/Portal.web.tsx new file mode 100644 index 0000000000..498e0fdcaf --- /dev/null +++ b/src/components/Portal.web.tsx @@ -0,0 +1,35 @@ +import React, {useContext, useId} from 'react' +import {createPortal} from 'react-dom' + +export function createPortalGroup() { + const Context = React.createContext(null) + + function Provider(props: React.PropsWithChildren<{}>) { + const id = useId() + return {props.children} + } + + function Outlet() { + const id = useContext(Context) + if (!id) throw new Error('Outlet must be used within a Portal Provider') + return
+ } + + function Portal({children}: React.PropsWithChildren<{}>) { + const id = useContext(Context) + if (!id) throw new Error('Portal must be used within a Portal Provider') + const elem = document.getElementById(id) + if (!elem) { + console.error('Portal element not found', id) + return null + } + return createPortal(children, elem) + } + + return {Provider, Outlet, Portal} +} + +const DefaultPortal = createPortalGroup() +export const Provider = DefaultPortal.Provider +export const Outlet = DefaultPortal.Outlet +export const Portal = DefaultPortal.Portal