-
Notifications
You must be signed in to change notification settings - Fork 0
/
useRootHeight.js
56 lines (46 loc) · 1.43 KB
/
useRootHeight.js
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
52
53
54
55
56
import { useLayoutEffect, useEffect, useState } from "react";
// SSR support
const useIsomorphicLayoutEffect =
typeof window !== "undefined" ? useLayoutEffect : useEffect;
const BREAKPOINTS = [
{ name: "2xl", value: 1536 },
{ name: "xl", value: 1280 },
{ name: "lg", value: 1024 },
{ name: "md", value: 768 },
{ name: "sm", value: 640 },
];
const getRootHeight = (heightProp) => {
if (!heightProp) {
throw new Error("'height' prop is required");
}
if (typeof heightProp === "number") {
return heightProp;
}
for (const breakpoint of BREAKPOINTS) {
const mediaQuery = window.matchMedia(
`(min-width: ${breakpoint.value}px)`
);
if (mediaQuery.matches) {
const regex = new RegExp(`${breakpoint.name}:(\\d+)`);
const matches = regex.exec(heightProp);
if (matches) {
return matches[1];
}
}
}
// fallback to default
const defaultHeightMatch = heightProp.match(/^(\d+)/);
if (defaultHeightMatch) {
return defaultHeightMatch[1];
} else {
throw new Error(`Invalid height prop: ${heightProp}`);
}
};
export const useRootHeight = (heightProp) => {
const [height, setHeight] = useState(0);
useIsomorphicLayoutEffect(() => {
const height = Number(getRootHeight(heightProp));
setHeight(height);
}, [heightProp]);
return height;
};