1 import { useEffect, useMemo, useState } from 'react';
3 import debounce from '@proton/utils/debounce';
5 type ActiveBreakpoint = 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge' | '2xlarge';
7 const getActiveBreakpoint = (): ActiveBreakpoint | '' => {
8 const bodyEl = document.querySelector('body');
13 .getComputedStyle(bodyEl, ':before')
14 .getPropertyValue('content')
15 .replace(/['"]+/g, '') as ActiveBreakpoint;
18 /** Contains React state setter of each instantiated hooks */
19 const callbackStack: Set<Function> = new Set();
20 const onResize = () => {
21 const result = getActiveBreakpoint();
22 for (let callback of callbackStack.values()) {
26 const onResizeDebounced = debounce(onResize, 250, { leading: true });
28 export interface Breakpoints {
29 activeBreakpoint: ActiveBreakpoint;
46 const useActiveBreakpoint = () => {
47 const [activeBreakpoint, setActiveBreakpoint] = useState(() => getActiveBreakpoint() as ActiveBreakpoint);
50 if (callbackStack.size === 0) {
51 window.addEventListener('load', onResize);
52 window.addEventListener('resize', onResizeDebounced);
54 callbackStack.add(setActiveBreakpoint);
56 callbackStack.delete(setActiveBreakpoint);
57 if (callbackStack.size === 0) {
58 window.removeEventListener('load', onResize);
59 window.removeEventListener('resize', onResizeDebounced);
64 return useMemo((): Breakpoints => {
66 isLargeDesktop = 2xlarge
67 isMediumDesktop = xlarge
68 isSmallDesktop = large
76 const viewportWidth = {
78 xsmall: activeBreakpoint === 'xsmall',
79 small: activeBreakpoint === 'small',
80 medium: activeBreakpoint === 'medium',
81 large: activeBreakpoint === 'large',
82 xlarge: activeBreakpoint === 'xlarge',
83 '2xlarge': activeBreakpoint === '2xlarge',
91 viewportWidth['<=small'] = viewportWidth.small || viewportWidth.xsmall;
92 viewportWidth['<=medium'] = viewportWidth.small || viewportWidth.xsmall || viewportWidth.medium;
93 viewportWidth['>=large'] = viewportWidth['2xlarge'] || viewportWidth.xlarge || viewportWidth.large;
99 }, [activeBreakpoint]);
102 export default useActiveBreakpoint;