Responsive React UI components
Clone or download
Latest commit 004793b Jan 18, 2019

README.md

react-responsive-ui

npm version

Responsive React UI components.

See Demo

Install

npm install react-responsive-ui --save

The overall requirement is React >= 16.3, but most of the components only require React >= 0.14, except for a few:

  • <Tooltip/> (requires "React Portals" from React >= 16).
  • <DragAndDrop/> (react-dnd requires React >= 16.3).

For using components with React < 16.3 import them individually like import Select from 'react-responsive-ui/modules/Select' or import Select from 'react-responsive-ui/commonjs/Select' instead of import { Select } from 'react-responsive-ui' because otherwise it would break due to a react-dnd bug.

Use

See the demo page. It has code examples for every component.

CSS

The CSS for this library must be included on a page too.

When using Webpack

require('react-responsive-ui/style.css')

And set up a postcss-loader with a CSS autoprefixer for supporting old web browsers (e.g. last 4 versions, iOS >= 7, Android >= 4).

When not using Webpack

Get the style.css file from this package, process it with a CSS autoprefixer for supporting old web browsers (e.g. last 4 versions, iOS >= 7, Android >= 4), and then include it on a page.

<head>
  <link rel="stylesheet" href="/css/react-responsive-ui/style.css"/>
</head>

Small Screen

The small-screen directory contains "small screen" ("mobile devices") styles for some of the components. E.g. <Select/>s, <Autocomplete/>s, <ExpandableMenu/>s, <DatePicker/>s and <Modal/>s can open in fullscreen and <Snackbar/> are expanded in full screen (not neccessarily a good idea though).

Native CSS @import example:

/* Main style. */
@import url(~react-responsive-ui/style.css)
/* Tweaks `<Modal/>`s for mobile devices a bit. */
@import url(~react-responsive-ui/small-screen/Modal.css) (max-width: 720px)
/* Tweaks `<Snackbar/>`s for mobile devices a bit. */
@import url(~react-responsive-ui/small-screen/Snackbar.css) (max-width: 720px)
/* Places a click-capturing overlay above `<DatePicker/>` input. */
@import url(~react-responsive-ui/small-screen/DatePicker.InputOverlay.css) (max-width: 720px)

SCSS @import example:

@import "~react-responsive-ui/style";

@media (max-width: 720px) {
  @import "~react-responsive-ui/small-screen/Modal";
  @import "~react-responsive-ui/small-screen/Snackbar";
  @import "~react-responsive-ui/small-screen/DatePicker.InputOverlay";
}

Variables

This library uses native CSS variables for easier styling. See variables.css for the list of all available variables. These variables have some sensible defaults which can be overridden in a separate react-responsive-ui-variables.css file (analogous to the original variables.css file).

When not using Webpack

<head>
  <!-- React Responsive UI -->
  <link rel="stylesheet" href="/css/react-responsive-ui/style.css"/>
  <!-- Custom variable values -->
  <link rel="stylesheet" href="/css/react-responsive-ui-variables.css"/>
</head>

When using Webpack

// React Responsive UI.
require('react-responsive-ui/style.css')
// Custom variable values.
require('./src/styles/react-responsive-ui-variables.css')

Native CSS variables work in all modern browsers, but older ones like Internet Explorer wont't support them. For compatibility with such older browsers one can use a CSS transformer like PostCSS with a "CSS custom properties" plugin like postcss-custom-properties. Check that it actually replaces var()s with the actual values in the output CSS.

An example for Webpack and SCSS:

@import "~react-responsive-ui/style";

@media (max-width: 720px) {
  @import "~react-responsive-ui/small-screen/Modal";
  @import "~react-responsive-ui/small-screen/Snackbar";
  @import "~react-responsive-ui/small-screen/DatePicker.InputOverlay";
}

// Replace the default variable values.
:root {
  --rrui-unit               : 12px;
  --rrui-white-color        : #f0f7ff;
  --rrui-black-color        : #112233;
  --rrui-accent-color       : #cc0000;
  --rrui-accent-color-light : #ee0000;
  --rrui-gray-color         : #7f7f7f;
}

An example for PostCSS

Asterisk on required fields

/* (when the `value` is empty) */
/* Required input field label asterisk. */
.rrui__input-label--required:after,
.rrui__select__selected-label--required:after
{
  content     : '*';
  margin-left : 0.2em;
}

Reducing footprint

Webpack 4 still can't "tree-shake" simple cases like

import { Modal, Button, TextInput } from 'react-responsive-ui'

So if one's using only a small subset of this library it could be imported like so

import Modal     from 'react-responsive-ui/modules/Modal'
import Button    from 'react-responsive-ui/modules/Button'
import TextInput from 'react-responsive-ui/modules/TextInput'

or for CommonJS

import Modal     from 'react-responsive-ui/commonjs/Modal'
import Button    from 'react-responsive-ui/commonjs/Button'
import TextInput from 'react-responsive-ui/commonjs/TextInput'

Which results in a much smaller bundle size.

The same can be done for CSS: instead of importing the whole react-responsive-ui/style.css bundle one could import only the necessary styles from react-responsive-ui/styles/ like react-responsive-ui/styles/Button.css. There's a catch though: those stylesheets are usually dependent on each other and, for example, the <Button/> component actually requires three different stylesheets to be imported:

  • react-responsive-ui/styles/Button.css
  • react-responsive-ui/styles/ButtonReset.css
  • react-responsive-ui/styles/Input.css

Validation

Each form component receives an error : String error message property.

Outline

By default all buttons and inputs have rrui__outline CSS class attached to them which hides the default browser outline for focused components.

.rrui__outline:not(.rrui__outline--default) {
  outline: none;
}

Instead of using the default browser outline which doesn't look pretty by any standards and which nobody uses (not "Google", not "Apple", not anyone else) the default react-responsive-ui styles define custom :focus styling for most cases (though not for all of them). Still, these default :focus styles are quite subtle and if a developer is implementing a WAI-ARIA-compliant website then they should make sure that those :focus styles are pronounced enough and that the few missing :focus styles are added.

Alternatively, those looking for a very-quick-and-dirty solution can use the same default browser outline, but prettier.

.rrui__outline:focus {
  box-shadow: 0 0 0 0.15rem #00aaff;
}

If a developer still prefers the default browser outline then they still can manually add rrui__outline--default CSS class to buttons and inputs to prevent outline: none CSS rule from being applied.

There's also an exported component called <KeyboardNavigationListener/> which listens to keydown events on document.body, and when it detects a Tab key being pressed it adds rrui__tabbing CSS class to document.body. Any further mouse or touch events reset the rrui__tabbing CSS class. This way rrui__outline can only be shown when the user is actually tabbing. It's still not considered a 100%-formally-correct solution because "screen readers" still emit all kinds of mouse events. It's more of an experimental feature.

Inspecting Expandables

Expandables are implemented in such a way that they collapse when losing focus. This may present difficulties when trying to inspect expandable content via DevTools because switching to DevTools captures focus causing expandables to collapse. For such cases there's a global debug flag window.rruiCollapseOnFocusOut which can be set to false to prevent expandables from collapsing when losing focus.

Supported Browsers

IE 11, Edge, Firefox, Chrome, Safari — have been tested.

Expandable components (Select, Autocomplete, ExpandableMenu, Expandable) require Promise (get a polyfill for IE 11).

Known Issues

An overflown <Modal/> scroll is janky on iOS because it tries to scroll <body/> instead of the <Modal/> contents. That's how it is on iOS.

Contributing

After cloning this repo, ensure dependencies are installed by running:

npm install

This module is written in ES6 and uses Babel for ES5 transpilation. Widely consumable JavaScript can be produced by running:

npm run build

Once npm run build has run, you may import or require() directly from node.

After developing, the full test suite can be evaluated by running:

npm test

When you're ready to test your new functionality on a real project, you can run

npm pack

It will build, test and then create a .tgz archive which you can then install in your project folder

npm install [module name with version].tar.gz

License

MIT