- Notifications
You must be signed in to change notification settings - Fork35
renatorib/react-sizes
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
yarn add react-sizes
npm install react-sizes
React Sizes is a higher-order component with strong performance that transforms window sizes (width and height) into props.
You can check inside your component, for example, if user's window is less than 480 pixels of width, and add a customcontent.
It can be very powerful for when you need to display different content for mobile and desktop.But it's not limited to this case. Just use that at your needs.
importReact,{Component}from'react'importwithSizesfrom'react-sizes'classMyComponentextendsComponent{render(){return<div>{this.props.isMobile ?'Is Mobile' :'Is Not Mobile'}</div>}}constmapSizesToProps=({ width})=>({isMobile:width<480,})exportdefaultwithSizes(mapSizesToProps)(MyComponent)
You can play with this examplehere.
importReactfrom'react'importwithSizesfrom'react-sizes'@withSizes(({ width})=>({isMobile:width<480}))classMyComponentextendsComponent{render(){return<div>{this.props.isMobile ?'Is Mobile' :'Is Not Mobile'}</div>}}exportdefaultMyComponent
importReactfrom'react'importwithSizesfrom'react-sizes'import{withState,compose}from'recompose'constenhancer=compose(withState('counter','setCounter',0),withSizes(({ width})=>({isMobile:width<480})))constMyComponent=enhancer(({ isMobile, counter, setCounter})=>(<div><div> Count:{counter}{' '}<buttononClick={()=>setCounter(n=>n+1)}>Increment</button></div><div>{isMobile ?'Is Mobile' :'Is Not Mobile'}</div></div>))exportdefaultMyComponent
importReactfrom'react'importwithSizesfrom'react-sizes'constMyComponent=({ isMobile})=>(<div>{isMobile ?'Is Mobile' :'Is Not Mobile'}</div>)constmapSizesToProps=({ width})=>({isMobile:width<480,})exportdefaultwithSizes(mapSizesToProps)(MyComponent)
(Added in 0.1.0)
importReactfrom'react'importwithSizesfrom'react-sizes'constMyComponent=({ isMobile})=>(<div>{isMobile ?'Is Mobile' :'Is Not Mobile'}</div>)constmapSizesToProps=({ width},{ mobileBreakpoint})=>({isMobile:width<mobileBreakpoint,})exportdefaultwithSizes(mapSizesToProps)(MyComponent)
then:
<MyComponentmobileBreakpoint={480}/><MyComponentmobileBreakpoint={400}/><MyComponentmobileBreakpoint={600}/>
- const mapSizesToProps = ({ width }) => ({- isMobile: width < 480,- });+ const mapSizesToProps = sizes => ({+ isMobile: withSizes.isMobile(sizes),+ });
You can check allour presets selectors at our main codesrc/withSizes.js
.
withSizes.isMobile=({ width})=>width<480withSizes.isTablet=({ width})=>width>=480&&width<1024withSizes.isDesktop=({ width})=>width>=1024withSizes.isGtMobile=sizes=>!withSizes.isMobile(sizes)withSizes.isGtTablet=sizes=>withSizes.isDesktop(sizes)withSizes.isStTablet=sizes=>withSizes.isMobile(sizes)withSizes.isStDesktop=sizes=>!withSizes.isStDesktop(sizes)withSizes.isTabletAndGreater=sizes=>!withSizes.isMobile(sizes)withSizes.isTabletAndSmaller=sizes=>!withSizes.isStDesktop(sizes)
If it don't fit to your needs, you can create your own selectors.
// utils/sizes/selectors.jsexportconstisntDesktop=({ width})=>width<1024exportconstbackgroundColor=({ width})=>(width<480 ?'red' :'green')// your componentimport{isntDesktop,backgroundColor}from'utils/sizes/selectors'constmapSizesToProps=sizes=>({canDisplayMobileFeature:isntDesktop(sizes),backgroundColor:backgroundColor(sizes),})
sizes
argument is an object withwidth
andheight
properties and represents DOM window width and height.
sizes
argument is an object withwidth
andheight
of DOM window.
constmapSizesToProps=sizes=>{console.log(sizes)// { width: 1200, height: 720 } (example)}
In pratice, it is a callback that return props that will injected into your Component.
constmapSizesToProps=function(sizes){constprops={backgroundColor:sizes.width<700 ?'red' :'green',}returnprops}
But you can simplify this to stay practical and elegant.
constmapSizesToProps=({ width})=>({backgroundColor:width<700 ?'red' :'green',})
Since React Sizes rely on window to computate sizes, we can't computate the values in server enviroment. To try to get around this we canguess user viewport based on your user-agent, and pass values by a Context Provider.
But be careful,user-agent based detection is not a reliable solution. It's a workaround.
// Config can be created based on user-agent. See belowconstconfig={fallbackWidth:360,fallbackHeight:640}return(<SizesProviderconfig={config}><App/></SizesProvider>)
Example:
importMobileDetectfrom'mobile-detect'importExpressfrom'express'import{SizesProvider}from'react-sizes'// All other importsconstgetSizesFallback=userAgent=>{constmd=newMobileDetect(userAgent)if(!!md.mobile()){return{fallbackWidth:360,fallbackHeight:640,}}elseif(!!md.tablet()){return{fallbackWidth:768,fallbackHeight:1024,}}return{fallbackWidth:1280,fallbackHeight:700,}}// Note: you don't need to use express, this is just an exampleconstapp=newExpress()app.use((req,res)=>{// ...constsizesConfig=getSizesFallback(req.headers['user-agent'])constApp=(<AnotherProvider><Routerlocation={req.url}><SizesProviderconfig={sizesConfig}><Root/></SizesProvider></Router></AnotherProvider>)res.status(200)res.send(`<!doctype html>\n${ReactDOM.renderToString(<App/>)}`)res.end()})app.listen(/* ... */)
React Sizes do a shallow compare in props generated frommapSizesToProps
(calledpropsToPass
), so it will only rerender when they really change. If you create a deep data sctructure, this can generate false positives. In these cases, we recommend using immutable for a more reliable shallow compare result. Or just don't use deep data structures, if possible.
You can help improving this project sending PRs and helping with issues.
Also you ping me atTwitter
About
Topics
Resources
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.
Contributors10
Uh oh!
There was an error while loading.Please reload this page.