import { useState , useEffect , useCallback } from 'react' ; import { BreakpointValues } from '@material-ui/core/styles/createBreakpoints' ; import useMediaQuery from '@material-ui/core/useMediaQuery' ; type BreakpointKeys = 'small' | 'medium' | 'large' | 'extra-large' ; type BreakpointsList = { [ key ] : number ; } ; class BreakpointProvider { breakpoints : Record < 'values' , BreakpointValues > = { values : { xs : 0 , sm : 576 , md : 768 , lg : 992 , xl : 1920 } } ; mediaQueries : { [ key ] : string ; } ; constructor ( ) { const { sm , md , lg } = this . breakpoints . values ; this . mediaQueries = { small : `(max-width: ${ sm }px)` , medium : `(min-width: ${ sm }px) and (max-width: ${ md }px)` , large : `(min-width: ${ md }px) and (max-width: ${ lg }px)` , 'extra-large' : `(min-width: ${ lg }px)` } ; } disableMobileBreakpoints ( ) { this . breakpoints . values . xs = 768 ; this . breakpoints . values . sm = 768 ; this . mediaQueries . small = '' ; this . mediaQueries . medium = '' ; } } export const PicassoBreakpoints = new BreakpointProvider ( ) ; export const breakpointsList = { small : PicassoBreakpoints . breakpoints . values . sm , medium : PicassoBreakpoints . breakpoints . values . md , large : PicassoBreakpoints . breakpoints . values . lg , 'extra-large' : PicassoBreakpoints . breakpoints . values . xl } ; export const screens = ( ... sizes ) => { const validSizes = sizes . filter ( size => PicassoBreakpoints . mediaQueries [ size ] ) ; if ( validSizes . length === 0 ) { return '' ; } const mediaQueries = validSizes . map ( size => PicassoBreakpoints . mediaQueries [ size ] ) . join ( ', ' ) ; return `@media ${ mediaQueries }` ; } ; const screenSizeToBreakpointKey = ( size ) : BreakpointKeys => { param { number } size const { sm , md , lg } = PicassoBreakpoints . breakpoints . values ; if ( size < sm ) { return 'small' ; } else if ( size >= sm && size < md ) { return 'medium' ; } else if ( size >= md && size < lg ) { return 'large' ; } return 'extra-large' ; } ; export const isScreenSize = ( size , currentSize ? ) : boolean => { const sizeToUse = currentSize || window . innerWidth ; const foundBreakpoint = screenSizeToBreakpointKey ( sizeToUse ) ; return size === foundBreakpoint ; } ; export const useScreenSize = ( ) => { const [ size , setSize ] = useState ( window . innerWidth ) ; const updateSize = ( ) => setSize ( window . innerWidth ) ; useEffect ( ( ) => { window . addEventListener ( 'resize' , updateSize ) ; return ( ) => { window . removeEventListener ( 'resize' , updateSize ) ; } ; } , [ ] ) ; return size ; } ; export const useBreakpoint = ( sizes ) => { const mediaQueryString = screens ( ... ( [ ] as BreakpointKeys [ ] ) . concat ( sizes ) ) ; const mediaQuery = useMediaQuery ( mediaQueryString , { noSsr : true } ) ; if ( ! mediaQueryString ) { return false ; } return mediaQuery ; } ; example export const useScreens = < T = unknown > ( ) => { const currentSize = useScreenSize ( ) ; const screenKey = screenSizeToBreakpointKey ( currentSize ) ; return useCallback ( ( valuesByScreen , defaultValue = undefined ) => { if ( screenKey in valuesByScreen ) { return valuesByScreen [ screenKey ] ; } return defaultValue ; } , [ screenKey ] ) ; } ; export default PicassoBreakpoints . breakpoints ;