Created
August 31, 2017 08:12
-
-
Save piecyk/46fbcaa84fecf8df924a482fee52e54e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
maybe better would be as a break-point identifier number