-
-
Notifications
You must be signed in to change notification settings - Fork 49
Expand file tree
/
Copy pathutils.ts
More file actions
54 lines (48 loc) · 1.78 KB
/
utils.ts
File metadata and controls
54 lines (48 loc) · 1.78 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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { useState, useLayoutEffect, useEffect } from "react";
import { sizeMap, defaultSize } from "./constants.js";
import type { SizeOption } from "./types.js";
/**
* This hook is like useLayoutEffect, but without the SSR warning
* It seems hacky but it's used in many React libs (Redux, Formik...)
* Also mentioned here: https://github.com/facebook/react/issues/16956
* It is useful when you need to update a ref as soon as possible after a React
* render (before `useEffect`)
*/
export const useIsomorphicLayoutEffect =
typeof window !== "undefined" ? useLayoutEffect : useEffect;
// Calculate window width
export function useWindowWidth(): number {
const [width, setWidth] = useState(sizeMap[defaultSize]);
useIsomorphicLayoutEffect(() => {
const updateWidth = () => {
setWidth(window.innerWidth);
};
window.addEventListener("resize", updateWidth);
updateWidth();
return () => window.removeEventListener("resize", updateWidth);
}, []);
return width;
}
// Adjust responsive size
export function responsify(
sizeOption: SizeOption | "responsive" | "responsive-100",
windowWidth: number,
): number {
if (sizeOption === "responsive-100") {
// Make component work in SSR
if (typeof window === "undefined") return sizeMap[defaultSize];
return window.innerWidth;
}
if (sizeOption === "responsive") {
// Make component work in SSR
if (typeof window === "undefined") return sizeMap[defaultSize];
return Math.min(window.innerHeight, window.innerWidth) * 0.75;
}
if (typeof window === "undefined") return sizeMap[sizeOption];
// First size that fits window size
const fittingSize =
Object.values(sizeMap)
.reverse()
.find((size) => size <= windowWidth) ?? sizeMap.sm;
return Math.min(fittingSize, sizeMap[sizeOption]);
}