Backdrop
Example
Steps
Prerequisite
Copy Code
containers/Backdrop/index.tsx
import { useEffect, useState, useCallback } from 'react'
import type { FC } from 'react'
import { Spinner } from 'components'
import { createPortal } from 'react-dom'
import { EventListener } from 'services'
const Backdrop: FC = () => {
const [isOpen, setIsOpen] = useState<boolean>(false)
const onBackdrop = useCallback(
({ detail }: any) => {
setIsOpen(detail)
if (detail) document.body.style.overflow = 'hidden'
else document.body.removeAttribute('style')
},
[isOpen]
)
useEffect(() => {
EventListener.add('backdrop', onBackdrop)
return () => EventListener.remove('backdrop', onBackdrop)
}, [])
if (!isOpen) return null
return createPortal(
<div role="progressbar">
<div className="fixed inset-0 z-40 cursor-progress bg-black opacity-30" />
<span className="fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2 cursor-progress">
<Spinner className="h-10 w-10" />
</span>
</div>,
document.body
)
}
export default Backdrop
services/utils/index.ts
export const backdrop = (open: boolean) => EventListener.emit('backdrop', open)
Usage
pages/_app.tsx
import type { AppProps } from 'next/app'
import { Backdrop } from 'containers'
interface Props {}
interface State {}
function MyApp({ Component, pageProps }: AppProps<Props>) {
return (
<>
<Component {...pageProps} />
<Backdrop />
</>
)
}
export default MyApp
<button onClick={() => backdrop(true)}>Test</button>