forked from koshikraj/ottopus
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuse-media-query.ts
More file actions
33 lines (31 loc) · 1.16 KB
/
Copy pathuse-media-query.ts
File metadata and controls
33 lines (31 loc) · 1.16 KB
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
'use client'
import { useCallback, useSyncExternalStore } from 'react'
/**
* Whether a media query matches, kept live.
*
* `false` on the server and during hydration: the server has no viewport, and
* guessing "phone" would render a sheet-shaped control into HTML a desktop then
* has to unpick. useSyncExternalStore re-renders with the real answer as soon
* as the client has one, without a hydration mismatch, because hydration is
* done against the server snapshot rather than the live one.
*
* Callers should only let this change what happens on interaction, never what
* is on screen at rest — a trigger that looks the same in both modes and only
* opens something different is safe; one that renders a different trigger
* flashes on every phone load.
*/
export function useMediaQuery(query: string): boolean {
const subscribe = useCallback(
(onChange: () => void) => {
const list = window.matchMedia(query)
list.addEventListener('change', onChange)
return () => list.removeEventListener('change', onChange)
},
[query],
)
return useSyncExternalStore(
subscribe,
() => window.matchMedia(query).matches,
() => false,
)
}