2022-07-14 16:36:31 -07:00
|
|
|
import {
|
|
|
|
createContext,
|
|
|
|
ReactNode,
|
2022-09-13 23:24:26 -07:00
|
|
|
useCallback,
|
2022-07-14 16:36:31 -07:00
|
|
|
useContext,
|
|
|
|
useEffect,
|
|
|
|
useState,
|
|
|
|
} from 'react'
|
|
|
|
|
|
|
|
type ViewportContextProps = {
|
|
|
|
width: number
|
2022-09-13 23:24:26 -07:00
|
|
|
height: number
|
2022-07-14 16:36:31 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
const ViewportContext = createContext({} as ViewportContextProps)
|
|
|
|
|
|
|
|
export const ViewportProvider = ({ children }: { children: ReactNode }) => {
|
|
|
|
const [mounted, setMounted] = useState(false)
|
|
|
|
const [width, setWidth] = useState<number>(0)
|
2022-09-13 23:24:26 -07:00
|
|
|
const [height, setHeight] = useState<number>(0)
|
2022-07-14 16:36:31 -07:00
|
|
|
|
2022-09-13 23:24:26 -07:00
|
|
|
const handleWindowResize = useCallback(() => {
|
2022-07-14 16:36:31 -07:00
|
|
|
if (typeof window !== 'undefined') {
|
|
|
|
setWidth(window.innerWidth)
|
2022-09-13 23:24:26 -07:00
|
|
|
setHeight(window.innerHeight)
|
2022-07-14 16:36:31 -07:00
|
|
|
}
|
2022-09-13 23:24:26 -07:00
|
|
|
}, [])
|
2022-07-14 16:36:31 -07:00
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
handleWindowResize()
|
|
|
|
window.addEventListener('resize', handleWindowResize)
|
|
|
|
return () => window.removeEventListener('resize', handleWindowResize)
|
2022-09-13 23:24:26 -07:00
|
|
|
}, [handleWindowResize])
|
2022-07-14 16:36:31 -07:00
|
|
|
|
|
|
|
useEffect(() => setMounted(true), [])
|
|
|
|
if (!mounted) return null
|
|
|
|
|
|
|
|
return (
|
2022-09-13 23:24:26 -07:00
|
|
|
<ViewportContext.Provider value={{ width, height }}>
|
2022-07-14 16:36:31 -07:00
|
|
|
{children}
|
|
|
|
</ViewportContext.Provider>
|
|
|
|
)
|
|
|
|
}
|
|
|
|
|
|
|
|
export const useViewport = () => {
|
2022-09-13 23:24:26 -07:00
|
|
|
const { width, height } = useContext(ViewportContext)
|
|
|
|
return { width, height }
|
2022-07-14 16:36:31 -07:00
|
|
|
}
|