-
Notifications
You must be signed in to change notification settings - Fork 579
/
useMediaQuery.ts
50 lines (42 loc) · 1.75 KB
/
useMediaQuery.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { useEffect, useState } from 'react'
import isClient from './shared/isClient'
import isAPISupported from './shared/isAPISupported'
const errorMessage = 'matchMedia is not supported, this could happen both because window.matchMedia is not supported by'
+ ' your current browser or you\'re using the useMediaQuery hook whilst server side rendering.'
/**
* Accepts a media query string then uses the
* [window.matchMedia](https://developer.mozilla.org/en-US/docs/Web/API/Window/matchMedia) API to determine if it
* matches with the current document.<br />
* It also monitor the document changes to detect when it matches or stops matching the media query.<br />
* Returns the validity state of the given media query.
*
*/
const useMediaQuery = (mediaQuery: string): boolean => {
if (!isClient || !isAPISupported('matchMedia')) {
// eslint-disable-next-line no-console
console.warn(errorMessage)
return null
}
const [isVerified, setIsVerified] = useState(!!window.matchMedia(mediaQuery).matches)
useEffect(() => {
const mediaQueryList = window.matchMedia(mediaQuery)
const documentChangeHandler = () => setIsVerified(!!mediaQueryList.matches)
try {
mediaQueryList.addEventListener('change', documentChangeHandler)
} catch (e) {
// Safari isn't supporting mediaQueryList.addEventListener
mediaQueryList.addListener(documentChangeHandler)
}
documentChangeHandler()
return () => {
try {
mediaQueryList.removeEventListener('change', documentChangeHandler)
} catch (e) {
// Safari isn't supporting mediaQueryList.removeEventListener
mediaQueryList.removeListener(documentChangeHandler)
}
}
}, [mediaQuery])
return isVerified
}
export default useMediaQuery