@wonderflow/react-components
Version:
UI components from Wonderflow's Wanda design system
87 lines (86 loc) • 3.28 kB
JavaScript
/*
* Copyright 2023 Wonderflow Design Team
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import tkns from '@wonderflow/tokens/platforms/web/tokens.json';
import { useSize } from 'ahooks';
import { useEffect, useState, } from 'react';
import { cssRelativeUnitsToPixel } from '../utils/conversions';
import { useSSR } from './useSSR';
const DefaultBreakpointsSettings = {
xs: cssRelativeUnitsToPixel(tkns.breakpoint['extra-small']),
sm: cssRelativeUnitsToPixel(tkns.breakpoint.small),
md: cssRelativeUnitsToPixel(tkns.breakpoint.medium),
lg: cssRelativeUnitsToPixel(tkns.breakpoint.large),
xl: cssRelativeUnitsToPixel(tkns.breakpoint['extra-large']),
};
const DefaultBreakpointsValues = {
xs: false,
sm: false,
md: false,
lg: false,
xl: false,
};
export const useBreakpoints = (target, settings = DefaultBreakpointsSettings) => {
const { isBrowser } = useSSR();
const [breakpoints, setBreakpoints] = useState(DefaultBreakpointsValues);
const [matches, setMatches] = useState('xs');
const [windowSize, setWindowSize] = useState(0);
const size = useSize(target);
const targetBreakpoints = (size?.width) ? {
xs: size.width <= settings.xs,
sm: size.width > settings.xs && size.width <= settings.sm,
md: size.width > settings.sm && size.width <= settings.md,
lg: size.width > settings.md && size.width <= settings.lg,
xl: size.width > settings.lg,
} : undefined;
const targetMatches = targetBreakpoints
&& Object.keys(targetBreakpoints)
.filter(k => (targetBreakpoints[k]))[0];
const handleResize = () => {
if (isBrowser) {
const w = window.innerWidth;
const v = {
xs: w <= settings.xs,
sm: w > settings.xs && w <= settings.sm,
md: w > settings.sm && w <= settings.md,
lg: w > settings.md && w <= settings.lg,
xl: w > settings.lg,
};
const b = Object.keys(v).filter(k => (v[k]))[0];
setMatches(b);
setBreakpoints(v);
setWindowSize(window.innerWidth);
}
};
useEffect(() => {
if (isBrowser) {
handleResize();
window.addEventListener('resize', handleResize);
}
else {
setBreakpoints(DefaultBreakpointsValues);
}
return () => {
if (isBrowser)
window.removeEventListener('resize', handleResize);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
return {
breakpoints: targetBreakpoints ?? breakpoints,
matches: (targetMatches ?? matches),
size: size?.width ?? windowSize,
};
};