A package that provides a responsive context to your application, using React Context API.
It has the same API of redux-responsive
and they are easily interchangeable.
$ yarn add @farfetch/react-context-responsive
$ npm i @farfetch/react-context-responsive
...and include it in your project
import { ResponsiveProvider, useResponsive } from '@farfetch/react-context-responsive';
The app, ideally, should have only one <ResponsiveProvider>
, usually at app.js
, wrapping all the components.
You can have as much consumers (useResponsive
, useIsMobile
, Responsive
, withResponsive
and withIsMobile
) as you need. When the Provider value changes, all the consumers will update.
The hooks (useResponsive
and useIsMobile
) are the preferred method of using the context, when possible.
When possible, use the withIsMobile
and useIsMobile
for mobile devices detection. In the future we might use it to automatically splitting of mobile-only code.
Prop | Type | Description |
---|---|---|
initialMediaType | string | Used to mock a breakpoint in the initial state calculation. Defaults to 'xs'. |
defaultOrientation | string | Used to mock orientation in initial state calculation. Defaults to null. |
Key | Type | Description |
---|---|---|
isCalculated | Boolean | False on first render. Once true, it means all breakpoints values are based on the window. |
mediaType | String | The current media type (breakpoint) name (ex: 'md' ). |
lessThan | Object | Object containing if current window width is less than a breakpoint (usage: lessThan.lg ). |
greaterThan | Object | Object containing if current window width is greater than a breakpoint (usage: greaterThan.lg ). |
is | Object | Object containing if current window width is the at a breakpoint (usage: is.lg ). |
orientation | String | Current browser orientation (portrait, landscape or defined defaultOrientation at ResponsiveProvider, when others not available) |
To use the package, you must embrace your code with the ResponsiveProvider
, following the guidelines.
The component has five different exported consumption APIs:
useResponsive
: A hook which returns the responsive objectuseIsMobile
: A hook which returns an object withisMobile
andisCalculated
Responsive
: A render prop componentwithResponsive
: A HoC which passes the responsive data to theresponsive
propwithIsMobile
: A HoC which passesisMobile
andisCalculated
props only
const Greetings = () => {
const { lessThan } = useResponsive();
if (lessThan.sm) {
return (<p>Hello small screen!</p>);
}
return (<p>Hello medium/big screen!</p>);
};
export default Greetings;
const Greetings = () => {
const { isMobile } = useIsMobile();
if (isMobile) {
return (<p>Hello mobile!</p>);
}
return (<p>Hello desktop!</p>);
};
export default Greetings;
<ResponsiveProvider>
<App>
<Responsive>
{ (responsive) => ( <Component1 currentBreakpoint={ responsive.mediaType } /> ) }
</Responsive>
<Responsive>
{ (responsive) => ( <Component2 orientation={ responsive.orientation } /> ) }
</Responsive>
</App>
</ResponsiveProvider>
class Greetings extends Component {
render() {
return this.props.responsive.lessThan.sm ? <p>Hello small screen!</p> : <p>Hello big/small screen!</p>
}
}
export default withResponsive(Greetings);
class Greetings extends Component {
render() {
return this.props.isMobile ? <p>Hello mobile!</p> : <p>Hello desktop!</p>
}
}
export default withIsMobile(Greetings);
The gap between window width 0 and the first breakpoint is called _initial
media type.
It fixes a problem at redux-responsive
in the calculation:
If the first breakpoint starts in a number bigger than 0 (let's call it X), it considers that everything between 0 and X as the first breakpoint when it's not true.
For example, our breakpoints start at 320 (XS), redux-responsive
considers 270 as XS, a wrong calculation. We call it _initial
.
If you're migration from the 0.X versions, the isPhone
and isDesktop
variables were deprecated.
After some discussions, we decided that maintaining the isMobile
, isPhone
and isDesktop
was useless.
They were always aliases for predefined breakpoints and still can be done manually.
We kept only the isMobile
for some reasons:
- It can be used for mobile/desktop code splitting in the future, optimizing builds for mobile only;
- Per definition, the Mobile Site is just for phones. Tablets are desktop;
- The
isMobile
detection is the most common use-case of the provider; - The
isDesktop
is just a negation of theisMobile
; - They were available just for the
responsive
high-order component; - You can still do the detection of specific breakpoints using the query objects.
React >= 16.8.0
is required to use this package as the ResponsiveProvider
is hook-based.
The non-hook APIs just expose the useResponsive
hook with different APIs, for compatibility with class components.
Read the Contributing guidelines
By sending us your contributions, you are agreeing that your contribution is made subject to the terms of our Contributor Ownership Statement