-
Notifications
You must be signed in to change notification settings - Fork 5.1k
/
Copy pathuseBreakpointValue.ts
51 lines (38 loc) · 1.21 KB
/
useBreakpointValue.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
51
import { screens } from "@/lib/utils/screen"
import { useMediaQuery } from "./useMediaQuery"
const breakpointMap = {
// Essentially to query from no width if smaller than "sm"
base: "0px",
...screens,
}
type BreakpointKeys = keyof typeof breakpointMap
export const useBreakpointValue = <T = unknown>(
values: Partial<Record<BreakpointKeys, T>>,
fallbackBreakpoint?: BreakpointKeys
): T => {
const breakpointKeys = Object.keys(values) as BreakpointKeys[]
let fallbackPassed = false
const setBreakpoints = Object.entries(breakpointMap)
.map(([breakpoint, value]) => {
const item = {
breakpoint,
query: `(min-width: ${value})`,
fallback: !fallbackPassed,
}
if (breakpoint === fallbackBreakpoint) {
fallbackPassed = true
}
return item
})
.filter(({ breakpoint }) =>
breakpointKeys.includes(breakpoint as BreakpointKeys)
)
const fallbackQueries = setBreakpoints.map(({ fallback }) => fallback)
const queryValues = useMediaQuery(
setBreakpoints.map((bp) => bp.query),
fallbackQueries
)
const index = queryValues.lastIndexOf(true)
const breakpointPicked = breakpointKeys[index]
return values[breakpointPicked] as T
}