@drivy/cobalt
Version:
Opinionated design system for Drivy's projects.
77 lines (74 loc) • 3.11 kB
JavaScript
import { useState, useEffect } from 'react';
import { breakpoints } from '../tokens/index.js';
const defaultBreakpoint = "md";
const breakpointsArray = Object.keys(breakpoints)
.map((bp) => ({
name: bp,
value: parseInt(breakpoints[bp].slice(0, -2), 10),
}))
.sort((a, b) => a.value - b.value);
const cobaltBreakpoints = breakpointsArray.map((breakpoint, index) => {
// lowest limit
if (index === 0) {
return [breakpoint.name, `(max-width: ${breakpoint.value - 1}px)`];
}
else {
return [
breakpoint.name,
`(min-width: ${breakpointsArray[index - 1].value}px) and (max-width: ${breakpoint.value - 1}px)`,
];
}
});
// highest limit
cobaltBreakpoints.push([
"over",
`(min-width: ${breakpointsArray[breakpointsArray.length - 1].value}px)`,
]);
/**
* Hook to get the current Cobalt breakpoint according to the viewport size
*/
const useBreakpoint = () => {
const getMediaQueriesList = () => cobaltBreakpoints.map((b) => window.matchMedia(b[1]));
const getBreakpoint = () => {
const matchIndex = getMediaQueriesList().findIndex((media) => media.matches);
return matchIndex !== -1
? cobaltBreakpoints[matchIndex][0]
: defaultBreakpoint;
};
const isMobileBreakpoint = (bp) => bp === "sm" || bp === "xs";
const isTabletBreakpoint = (bp) => bp === "md";
const isDesktopBreakpoint = (bp) => bp === "lg" || bp === "over";
const initialBreakpoint = getBreakpoint();
const [breakpoint, setBreakpoint] = useState(initialBreakpoint);
const [isMobile, setIsMobile] = useState(isMobileBreakpoint(initialBreakpoint));
const [isTablet, setIsTablet] = useState(isTabletBreakpoint(initialBreakpoint));
const [isDesktop, setIsDesktop] = useState(
// Be careful: isDesktop != !isMobile
isDesktopBreakpoint(initialBreakpoint));
useEffect(() => {
const handleMediaChange = () => {
const newBreakpoint = getBreakpoint();
setBreakpoint(newBreakpoint);
setIsMobile(isMobileBreakpoint(newBreakpoint));
setIsTablet(isTabletBreakpoint(newBreakpoint));
setIsDesktop(isDesktopBreakpoint(newBreakpoint));
};
const mediaQueriesList = getMediaQueriesList();
mediaQueriesList.forEach((mq) => {
// Safari < 14 only supports addListener
mq.addEventListener
? mq.addEventListener("change", handleMediaChange)
: mq.addListener(handleMediaChange);
});
// Remove listeners on cleanup
return () => mediaQueriesList.forEach((mq) => {
// Safari < 14 only supports removeListener
mq.removeEventListener
? mq.removeEventListener("change", handleMediaChange)
: mq.removeListener(handleMediaChange);
});
}, []); // Empty array ensures effect is only run on mount and unmount
return { breakpoint, isMobile, isTablet, isDesktop };
};
export { cobaltBreakpoints, useBreakpoint as default };
//# sourceMappingURL=useBreakpoint.js.map