Skip to content

Instantly share code, notes, and snippets.

@LeeCheneler
Last active September 12, 2019 07:01
Show Gist options
  • Save LeeCheneler/457612be54bac4ffce516a12ae9ab841 to your computer and use it in GitHub Desktop.
Save LeeCheneler/457612be54bac4ffce516a12ae9ab841 to your computer and use it in GitHub Desktop.
useBreakpoint hook experiment
import React from "react";
import styled from "styled-components";
import { Box } "./some-styled-system";
import { useBreakpoints } from "./use-breakpoints";
// Very contrived example
const ColoredBox = styled.div<{ isRed: Boolean; isBlue: boolean }>`
width: 100px;
height: 100px;
${props => {
if (props.isBlue) return "background-color: blue;";
if (props.isRed) return "background-color: red;";
return "background-color: yellow;";
}}
`;
// Perhaps a little overkill with the memo, but it does prevent extra renders
const ResponsiveComponent = () => {
const [ref, br, [isRed, isBlue]] = useBreakpoints(300, 700);
const padding = br(4, 9);
return React.useMemo(
() => (
<Box ref={ref} p={padding}>
<ColoredBox isRed={isRed} isBlue={isBlue} />
</Box>
),
[ref, padding, isRed, isBlue],
);
};
import React from "react";
import ResizeObserver from "@juggle/resize-observer";
export const useBreakpoints = (
...breakpoints: number[]
): [
React.MutableRefObject<any>,
<T = any>(defaultValue: T, ...values: T[]) => T,
boolean[],
] => {
const elementRef = React.useRef<any>();
const [width, setWidth] = React.useState(0);
const resizeObserver = new ResizeObserver(entries => {
for (const entry of entries) {
setWidth(entry.borderBoxSize.inlineSize);
}
});
React.useEffect(() => {
resizeObserver.observe(elementRef.current);
return () => {
resizeObserver.unobserve(elementRef.current);
};
}, []);
const breakpointFlags = breakpoints.map(b => {
return width >= b;
});
const getBreakpointValue = <T = any>(defaultValue: T, ...values: T[]): T => {
return values.reduce((currentValue, possibleValue, index) => {
return breakpointFlags[index] ? possibleValue : currentValue;
}, defaultValue);
};
return [elementRef, getBreakpointValue, breakpointFlags];
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment