react-responsive-widget
v1.0.6
Published
Responsive grid system similar to bootstrap that scales depending on the container size.
Downloads
28
Readme
ReactJs Responsive Widget
Synopsis
react-responsive-widget
is a tool to help you creating responsive applications with ReactJs by providing a bootstrap grid like syntax allowing you to change a widget layout depending on it's container size.
It can be installed with npm :
$ npm install --save react-responsive-widget
and used as followed :
import React from "react";
import ResponsiveContainer from "react-responsive-widget";
export default class App extends React.Component {
render() {
return (
<ResponsiveContainer>
<div className="app-row">
<div className="app-col-xs-12 app-col-md-4">.app-col-xs-12 .app-col-md-4</div>
<div className="app-col-xs-12 app-col-md-4">.app-col-xs-12 .app-col-md-4</div>
<div className="app-col-xs-12 app-col-md-4">.app-col-xs-12 .app-col-md-4</div>
</div>
</ResponsiveContainer>
)
}
}
Presentation
Making a responsive widget in ReactJS might be complicated if we don't know the size of the container it will fit in.
Using a simple syntax close to bootstrap grid, the react-responsive-widget
module allows you to create ReactJS Responsive Application without caring about it's integration.
Current breakpoint in context
If you wish to use the current breakpoint in your JS code, you may use the available context as followed (inside a ResponsiveContainer):
import React from "react";
import ResponsiveContainer from "react-responsive-widget";
export const DisplayBreakPoint = () => {
const currentBreakPoint = useContext(ResponsiveContainer.context);
return <div>current breakpoint: {currentBreakPoint}</div>;
}
Boostrap
The grid
Bootstrap is a commonly used framework that comes with a grid system used to create responsive, mobile first web pages.
This system is based on a 12 columns grid that allows you to define the witdh an element should have. A component width will then be defined by the number of column (col-*
) it will occupy on a scale from 1 to 12.
As an exemple, a col-12
will fit the full page width while a col-6
element will take only half of it.
To make the layout change depending on the screen resolution, bootstrap uses media query ranges
. There are 4 different configuration that can be setted :
xs
for really small screens (mobiles) resolution less than 768px (default)sm
for small screens(tablette) resolution between 768px and 992px (default)md
for medium screens (desktop) resolution between 992px and 1200px (default)lg
for large screen (desktop) resolution greater than 1200px (default)
To use this system, we only have to add the right class
to selected html component.
Let's say we have 3 blocks and we want them to use the full page width on mobile (.col-xs-12
) and to be on 3 columns on desktop (.col-md-12
), our ReactJs component will looks like this (to make react syntax easier, we are using jsx) :
<div className="row">
<div className="col-xs-12 col-md-4">.col-xs-12 .col-md-4</div>
<div className="col-xs-12 col-md-4">.col-xs-12 .col-md-4</div>
<div className="col-xs-12 col-md-4">.col-xs-12 .col-md-4</div>
</div>
Limitations
Bootstrap grid is easy to setup, but the fact that it is based on media queries
might be a problem when you want your widget to be used in any container for a given resolution.
If for example we created a responsive widget using bootstrap with a structure similar to the previous example :
<div className="row">
<div className="col-xs-6 col-md-3">
<div className="glyphicon glyphicon-camera"></div>
<div>Pictures</div>
</div>
<div className="col-xs-6 col-md-3">
<div className="glyphicon glyphicon-facetime-video"></div>
<div>Videos</div>
</div>
<div className="col-xs-6 col-md-3">
<div className="glyphicon glyphicon-headphones"></div>
<div>Music</div>
</div>
<div className="col-xs-6 col-md-3">
<div className="glyphicon glyphicon-book"></div>
<div>Books</div>
</div>
</div>
For now, everithing works fine, but what would happen if someone decide to use our widget in a sidebar ?
Ugly ... isn't it ? The problem is due to the fact that bootstrap provides only 1 layout for a given screen resolution, no matter what the width of your component if. In that case, the mobile layout would fit perfectly but it wont be used unless the width is less than 768px. It might be easy to fix that page, but as a developper, I would like another solution to create component that will adapt to the space they have rather than a screen resolution.
React Responsive Widget
Presentation
The react-responsive-widget module is a simple ReactJs component, available on npm that allows your components to be organised depending on their container size.
To make it more straightforward, it uses a syntax similat to bootstrap 3.3.7 and to avoid conflicts all classes are prefixed with app-*
.
The layout permutations depends on the container width are as follow :
xs
width less than 768px (default)_sm
width between 768px and 992px (default)_md
width between 992px and 1200px (default)_lg
width greater than 1200px (default)_
Install
As it is a npm module, it is easy to install running :
$ npm install --save react-responsive-widget
Then, all you have to do is to encapsulate your code in a ResponsiveContainer
component that you can import with (if you are using a bundler supporting ES6 syntax):
import ResponsiveContainer from 'react-responsive-widget'
Then with a module bundler like webpack that supports either CommonJS or ES2015 modules, use as with bootstrap grid syntax prefixed with app-*:
import React from "react";
import ResponsiveContainer from "react-responsive-widget";
export default class App extends React.Component {
render() {
return (
<ResponsiveContainer>
<div className="app-row">
<div className="app-col-xs-12 app-col-md-4">.app-col-xs-12 .app-col-md-4</div>
<div className="app-col-xs-12 app-col-md-4">.app-col-xs-12 .app-col-md-4</div>
<div className="app-col-xs-12 app-col-md-4">.app-col-xs-12 .app-col-md-4</div>
</div>
</ResponsiveContainer>
)
}
}
Exemple
Let's go back to our code leading to a layout problem and change the code to use ResponsiveContainer :
<ResponsiveContainer>
<div className="app-row">
<div className="app-col-xs-6 app-col-md-3">
<div className="glyphicon glyphicon-camera"></div>
<div>Pictures</div>
</div>
<div className="app-col-xs-6 app-col-md-3">
<div className="glyphicon glyphicon-facetime-video"></div>
<div>Videos</div>
</div>
<div className="app-col-xs-6 app-col-md-3">
<div className="glyphicon glyphicon-headphones"></div>
<div>Music</div>
</div>
<div className="app-col-xs-6 app-col-md-3">
<div className="glyphicon glyphicon-book"></div>
<div>Books</div>
</div>
</div>
</ResponsiveContainer>
As you can see the component work as we expected on desktop and mobile, but it also solved the issue we had while using it on a sidebar of the desktop layout.
Customization
You can change the layout permutation breakpoints as you like by providing specific props to the ResponsiveContainer
.
<ResponsiveContainer sm="800" md="1000" lg="1400">
...
</ResponsiveContainer>
Cette definition donnera le comportement suivant
xs
width less than 800pxsm
width between 800px and 1000pxmd
width between 1000px and 1400pxlg
width greater than 1400px
How it works
As it is not possible for now to have a media query
equivalent to change layout depending on component width in css, react-responsive-widget
uses a different approach.
The ResponsiveContainer
watch screen resizing events and changes it's own class depending of it's witdh.
If ResponsiveContainer as a width that is less than 768px (xs
), here is the dom that be displayed and the related css
<div className="app-container">
<div className="app-xs">
...
</div>
</div>
In the case the container witdh becomes (sm
) on window resizing or on another device, we will have :
<div className="app-container">
<div className="app-sm">
...
</div>
</div>
As you can see on the following examples