Skip to content

Instantly share code, notes, and snippets.

@piecyk
Created August 31, 2017 08:12
Show Gist options
  • Save piecyk/46fbcaa84fecf8df924a482fee52e54e to your computer and use it in GitHub Desktop.
Save piecyk/46fbcaa84fecf8df924a482fee52e54e to your computer and use it in GitHub Desktop.
import {React} from 'lib/vendor/react';
import _ from 'lib/vendor/lodash';
import {withContentRect} from 'lib/vendor/react-measure/Measure';
import {pure, compose} from 'lib/vendor/recompose';
type ComponentType<P = {}> = React.ComponentClass<P> | React.StatelessComponent<P>;
export type Breakpoint =
| 'small'
| 'medium'
| 'large'
| 'extraLarge'
| 'extraExtraLarge'
| 'extraExtraExtraLarge';
type Range = [number, number];
type BreakpointRange = [Breakpoint, Range];
export const BreakpointRanges: BreakpointRange[] = [
['small', [1, 479]],
['medium', [480, 639]],
['large', [640, 1023]],
['extraLarge', [1024, 1365]],
['extraExtraLarge', [1366, 1919]],
['extraExtraExtraLarge', [1920, Infinity]],
];
interface Bounds {
top: number;
right: number;
bottom: number;
left: number;
width: number;
height: number;
}
interface ContentRect {
bounds?: Bounds;
}
interface ReactMeasure {
measure: any;
measureRef: (ref: HTMLElement | null) => void;
contentRect: ContentRect;
}
export const applyBreakpoint = <P extends {}>(Comp: ComponentType<P>) =>
withContentRect(['bounds'])((props: P & ReactMeasure) => {
// note: we can pass prop to disable finding breakpoint, push down width, height etc
const width = _.get(props, 'contentRect.bounds.width', 0);
const breakpoint = _.find(BreakpointRanges, breakpointRange => {
const [from, to] = breakpointRange[1];
return width >= from && width <= to;
});
const nextProps = {
breakpoint: breakpoint ? breakpoint[0] : undefined,
..._.omit(props, ['measure', 'contentRect']),
} as {};
return <Comp {...nextProps} />;
});
export interface WithBreakpoint {
breakpoint?: Breakpoint;
measureRef?: (ref: HTMLElement | null) => void;
}
export const withBreakpoint = <P extends {}>(Comp: ComponentType<P>, isPure = true) =>
compose<P, P>(applyBreakpoint, ..._.compact([isPure ? pure : undefined]))(Comp);
@piecyk
Copy link
Author

piecyk commented Aug 31, 2017

maybe better would be as a break-point identifier number

export const BreakpointRanges: BreakpointRange[] = [
  [1, [1, 479]],
  [2, [480, 639]],
  [3, [640, 1023]],
  [4, [1024, 1365]],
  [5, [1366, 1919]],
  [6, [1920, Infinity]],
];

// then we could write, add :label-small from medium small, and from large show image 

const A = ({label, uri, measureRef, breakpoint}: Props) => (
  <div ref={measureRef} className={cln(':label', breakpoint <= 2 && ':label-small')}>
    {label}
    {breakpoint > 2 && <img src={"awesome.png"}/>}
  </div>
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment