createPortal impl on web for Portal
This commit is contained in:
@@ -0,0 +1,35 @@
|
|||||||
|
import React, {useContext, useId} from 'react'
|
||||||
|
import {createPortal} from 'react-dom'
|
||||||
|
|
||||||
|
export function createPortalGroup() {
|
||||||
|
const Context = React.createContext<string | null>(null)
|
||||||
|
|
||||||
|
function Provider(props: React.PropsWithChildren<{}>) {
|
||||||
|
const id = useId()
|
||||||
|
return <Context.Provider value={id}>{props.children}</Context.Provider>
|
||||||
|
}
|
||||||
|
|
||||||
|
function Outlet() {
|
||||||
|
const id = useContext(Context)
|
||||||
|
if (!id) throw new Error('Outlet must be used within a Portal Provider')
|
||||||
|
return <div id={id} />
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
Reference in New Issue
Block a user