-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathBreakpointContext.js
93 lines (80 loc) · 2.27 KB
/
BreakpointContext.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
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import React, { createContext, useState, useEffect, useMemo } from 'react';
import { debounce } from 'lodash-es';
const breakpoints = [{
id: 'xs',
value: 320,
device: 'mobile'
}, {
id: 'sm',
value: 480,
device: 'mobile',
deviceSize: 'lg'
}, {
id: 'md',
value: 760,
device: 'tablet'
}, {
id: 'lg',
value: 960,
device: 'desktop',
deviceSize: 'sm'
}, {
id: 'xl',
value: 1200,
device: 'desktop'
}, {
id: 'xxl',
value: 1600,
device: 'desktop',
deviceSize: 'lg'
}];
// Initializes our "context object" to hold data
export const BreakpointContext = createContext();
BreakpointContext.displayName = 'BreakpointContext';
// Grabs our data and "provides" it to any wrapped child components (see _app.js)
export const BreakpointProvider = ({ children }) => {
const [breakpoint, setBreakpoint] = useState(null);
const [isMobile, setIsMobile] = useState(false);
const [isTablet, setIsTablet] = useState(false);
const [isDesktop, setIsDesktop] = useState(false);
const [deviceSize, setDeviceSize] = useState(null);
const [screenWidth, setScreenWidth] = useState(0);
useEffect(() => {
function handleResize() {
const screenW = document.body.offsetWidth;
breakpoints.every(def => {
if(screenW < def.value || def.id === 'xxl') {
setBreakpoint(def.id);
setIsMobile(def.device === 'mobile');
setIsTablet(def.device === 'tablet');
setIsDesktop(def.device === 'desktop');
setDeviceSize(def.deviceSize || null);
return false;
}
return true;
});
setScreenWidth(screenW);
}
handleResize();
// To help performance, execute this at most once every 200ms
const handleResizeDebounced = debounce(handleResize, 200);
window.addEventListener('resize', handleResizeDebounced, { passive: true });
return () => {
window.removeEventListener('resize', handleResizeDebounced);
};
}, []);
const data = useMemo(() => {
return {
breakpoint,
isMobile,
isTablet,
isDesktop,
deviceSize,
screenWidth,
breakpoints
};
}, [breakpoint, isMobile, isTablet, isDesktop, deviceSize, screenWidth]);
return (
<BreakpointContext.Provider value={data}>{children}</BreakpointContext.Provider>
);
};