Skip to content

Commit

Permalink
Merge pull request #38 from MailOnline/feat/modal
Browse files Browse the repository at this point in the history
Feat/modal
  • Loading branch information
streamich authored Feb 20, 2018
2 parents 5ee0eee + eea744c commit bba1ef9
Show file tree
Hide file tree
Showing 26 changed files with 364 additions and 118 deletions.
1 change: 0 additions & 1 deletion .nvmrc

This file was deleted.

14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

# libreact

[![][npm-badge]][npm-url] [![][travis-badge]][travis-url]
[![][npm-badge]][npm-url] [![][travis-badge]][travis-url] [![React Universal Interface](https://img.shields.io/badge/React-Universal%20Interface-green.svg)](https://github.com/streamich/react-universal-interface)

React standard library — must-have toolbox for any React project.

Expand Down Expand Up @@ -33,11 +33,11 @@ const MyComponent = mock();

- [Introduction](./docs/en/Introduction.md)
- [Dummies](./docs/en/Dummies.md)
- [`mock()`](./docs/en/mock.md) and [`loadable()`](./docs/en/loadable.md)
- [`mock()`](./docs/en/mock.md) and [`loadable()`](./docs/en/loadable.md) — [*example*](https://codesandbox.io/s/j2ovpr03z3)
- [`lazy()`](./docs/en/lazy.md), [`delayed()`](./docs/en/delayed.md), and [`viewport()`](./docs/en/viewport.md)
- [Inversion](./docs/en/Inversion.md)
- [`<State>`](./docs/en/State.md) and [`withState()`](./docs/en/State.md#withstate-hoc)
- [`<Toggle>`](./docs/en/Toggle.md), [`withToggle()`](./docs/en/Toggle.md#withtoggle-hoc), and [`@withToggle`](./docs/en/Toggle.md#withtoggle-decorator)
- [`<Toggle>`](./docs/en/Toggle.md), [`withToggle()`](./docs/en/Toggle.md#withtoggle-hoc), and [`@withToggle`](./docs/en/Toggle.md#withtoggle-decorator) &mdash; [*example*](https://codesandbox.io/s/zwkl16vv93)
- [`<Flipflop>`](./docs/en/Flipflop.md), [`withFlipflop()`](./docs/en/Flipflop.md#withflipflop-hoc), and [`@withFlipflop`](./docs/en/Flipflop.md#withflipflop-decorator)
- [`<Value>`](./docs/en/Value.md), [`withValue()`](./docs/en/Value.md#withvalue-hoc), and [`@withValue`](./docs/en/Value.md#withvalue-decorator)
- [`<Counter>`](./docs/en/Counter.md), [`withCounter()`](./docs/en/Counter.md#withcounter-hoc) and [`@withCounter`](./docs/en/Counter.md#withcounter-decorator)
Expand All @@ -48,20 +48,20 @@ const MyComponent = mock();
- [Sensors](./docs/en/Sensors.md)
- [`<ActiveSensor>`](./docs/en/ActiveSensor.md), [`withActive()`](./docs/en/ActiveSensor.md#withactive-hoc), and [`@withActive`](./docs/en/ActiveSensor.md#withactive-decorator)
- [`<BatterySensor>`](./docs/en/BatterySensor.md), [`withBattery()`](./docs/en/BatterySensor.md#withbattery), and [`@withBattery`](./docs/en/BatterySensor.md#withbattery-1)
- [`<ExitSensor>`](./docs/en/ExitSensor.md)
- [`<ExitSensor>`](./docs/en/ExitSensor.md) &mdash; [*example*](https://codesandbox.io/s/7437x10z71)
- [`<FocusSensor>`](./docs/en/FocusSensor.md), [`withFocus()`](./docs/en/FocusSensor.md#withfocus-hoc), and [`@withFocus`](./docs/en/FocusSensor.md#withfocus-decorator)
- [`<GeoLocationSensor>`](./docs/en/GeoLocationSensor.md), [`withGeoLocation()`](./docs/en/GeoLocationSensor.md#withgeolocation-hoc), and [`@withGeoLocation`](./docs/en/GeoLocationSensor.md#withgeolocation-decorator)
- [`<HoverSensor>`](./docs/en/HoverSensor.md), [`withHover()`](./docs/en/HoverSensor.md#withhover-hoc), and [`@withHover`](./docs/en/HoverSensor.md#withhover-decorator)
- [`<MediaDeviceSensor>`](./docs/en/MediaDeviceSensor.md), [`withMediaDevices()`](./docs/en/MediaDeviceSensor.md#withmediadevices), and [`@withMediaDevices`](./docs/en/MediaDeviceSensor.md#withmediadevices-1)
- [`<MediaSensor>`](./docs/en/MediaSensor.md), [`withMedia()`](./docs/en/MediaSensor.md#withmedia), and [`@withMedia`](./docs/en/MediaSensor.md#withmedia-1)
- [`<MotionSensor>`](./docs/en/MotionSensor.md), [`withMotion()`](./docs/en/MotionSensor.md#withmotion-hoc), and [`@withMotion`](./docs/en/MotionSensor.md#withmotion-decorator)
- [`<MouseSensor>`](./docs/en/MouseSensor.md), [`withMouse()`](./docs/en/MouseSensor.md#withmouse-hoc), and [`@withMouse`](./docs/en/MouseSensor.md#withmouse-decorator)
- [`<MouseSensor>`](./docs/en/MouseSensor.md), [`withMouse()`](./docs/en/MouseSensor.md#withmouse-hoc), and [`@withMouse`](./docs/en/MouseSensor.md#withmouse-decorator) &mdash; [*example*](https://codesandbox.io/s/k3o16j7n47)
- [`<NetworkSensor>`](./docs/en/NetworkSensor.md), [`withNetwork()`](./docs/en/NetworkSensor.md#withnetwork-hoc), and [`@withNetwork`](./docs/en/NetworkSensor.md#withnetwork-decorator)
- [`<LightSensor>`](./docs/en/LightSensor.md), [`withLight()`](./docs/en/LightSensor.md#withlight-hoc), and [`@withLight`](./docs/en/LightSensor.md#withlight-decorator)
- [`<LocationSensor>`](./docs/en/LocationSensor.md), [`withLocation()`](./docs/en/LocationSensor.md#withlocation-hoc), and [`@withLocation`](./docs/en/LocationSensor.md#withlocation-decora)
- [`<OrientationSensor>`](./docs/en/OrientationSensor.md), [`withOrientation()`](./docs/en/OrientationSensor.md#withorientation-hoc), and [`@withOrientation`](./docs/en/OrientationSensor.md#withorientation-decorator)
- [`<ScrollSensor>`](./docs/en/ScrollSensor.md)
- [`<SizeSensor>`](./docs/en/SizeSensor.md), [`withSize()`](./docs/en/SizeSensor.md#withsize-hoc), and [`@withSize`](./docs/en/SizeSensor.md#withsize-decorator)
- [`<SizeSensor>`](./docs/en/SizeSensor.md), [`withSize()`](./docs/en/SizeSensor.md#withsize-hoc), and [`@withSize`](./docs/en/SizeSensor.md#withsize-decorator) &mdash; [*example*](https://codesandbox.io/s/0y2qjm210p)
- [`<WidthSensor>`](./docs/en/WidthSensor.md), [`withWidth()`](./docs/en/WidthSensor.md#withwidth-hoc-and-withwidth-decorator), and [`@withWidth`](./docs/en/WidthSensor.md#withwidth-hoc-and-withwidth-decorator)
- [`<ViewportSensor>`](./docs/en/ViewportSensor.md), [`withViewport()`](./docs/en/ViewportSensor.md#withviewport-hoc), and [`@withViewport`](./docs/en/ViewportSensor.md#withviewport-decorator)
- [`<ViewportScrollSensor>`](./docs/en/ViewportSensor.md#viewportscrollsensor) and [`<ViewportObserverSensor>`](./docs/en/ViewportSensor.md#viewportobserversensor)
Expand All @@ -74,7 +74,7 @@ const MyComponent = mock();
- [`<Router>`](./docs/en/routing.md#router), [`<Route>`](./docs/en/routing.md#route), [`withRoute()`](./docs/en/routing.md#withroute), `@withRoute`, `go()`, and `<Go>`
- [`<Translations>`](./docs/en/translate.md#translations), [`<Translate>`](./docs/en/translate.md#translate-or-t), [`<T>`](./docs/en/translate.md#translate-or-t), [`withT()`](./docs/en/translate.md#witht-hoc), and [`@withT`](./docs/en/translate.md#witht-decorator)
- [UI](./docs/en/UI.md)
- [`<Portal>`](./docs/en/Portal.md) and [`<Overlay>`](./docs/en/Overlay.md)
- [`<Portal>`](./docs/en/Portal.md), [`<Overlay>`](./docs/en/Overlay.md), and [`<Modal>`](./docs/en/Modal.md)
- [`<FullScreen>`](./docs/en/FullScreen.md)
- [`<Slider>`](./docs/en/Slider.md)
- [`<Audio>`](./docs/en/Audio.md) and [`<Video>`](./docs/en/Video.md)
Expand Down
39 changes: 39 additions & 0 deletions build/gulpfile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
const gulp = require('gulp');
const ts = require('gulp-typescript');
const tsConfig = require('../tsconfig');
const path = require('path');

const ignore = [
'!../src/**/__tests__/**',
'!../src/**/__story__/**',
'!../src/**/__docs__/**',
'!../src/**/story.ts',
'!../src/**/story.tsx'
];

gulp.task('build-ts', () => {
return gulp.src([
'../src/**/*.ts',
...ignore
]).pipe(ts({
...tsConfig.compilerOptions,
target: 'es5',
module: 'commonjs'
})).pipe(gulp.dest('../lib'));
});

gulp.task('build-modules', () => {
return gulp.src([
'../src/**/*.ts',
...ignore
]).pipe(ts({
...tsConfig.compilerOptions,
target: 'ESNext',
module: 'ESNext'
})).pipe(gulp.dest('../modules'));
});

gulp.task('build', () => {
gulp.start('build-ts');
gulp.start('build-modules');
});
57 changes: 57 additions & 0 deletions docs/en/Modal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# `<Modal>`

Creates a modal overlay. This component is similar to [`<Overlay>`](./Overlay.md) but provides the following extras:

- traps tabbing focus inside the overlay.
- makes all other root level elements inert to user input.
- sets aria title and description ids.

### Usage

Basic example.

```jsx
import {Modal} from 'libreact/lib/Modal';

<Modal>
This is modal.
</Modal>
```

Set aria title, description, and close button.

```jsx
<Modal>{({idTitle, idDescription, close}) =>
<div>
<h1 id={idTitle}>My title</h1>
<p id={idDescription}>This is description.</p>

<button onClick={close}>Cancel</button>
</div>
}</Modal>
```

Track when user intends to close the the modal.

```jsx
<Modal onClick={} onEsc={}>
This is modal.
</Modal>
```


## Props

Accepts all [`<Overlay>`](./Overlay.md) props in addition to:

- `onEsc` &mdash; optional, callback, called when user presses `Esc` button.
- `onClose` &mdash; optional, callback, called when `close()` is executed.


## State

`<Modal>` is a render prop that injects its state into the render function. State has the following keys.

- `close()` &mdash; method to calle `onClose` event.
- `idTitle` &mdash; id to set for aria title element.
- `idDescription` &mdash; id to set for aria description element.
2 changes: 2 additions & 0 deletions docs/en/Overlay.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@ import {Overlay} from 'libreact/lib/Overlay';

- `color` &mdash; optional, string, overlay color, defaults to `rgba(0, 0, 0, 0.5)`.
- `time` &mdash; optional, number, entrance opacity animation length in milliseconds, defaults to `300`.
- `onElement` &mdash; optional, callback that receives the DOM element overlay created.
- `onClick` &mdash; optional, callback, which is called when user click on overlay but not on its children.
2 changes: 1 addition & 1 deletion docs/en/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
- [`<Router>`](./routing.md#router), [`<Route>`](./routing.md#route), [`withRoute()`](./routing.md#withroute), `@withRoute`, `go()`, and `<Go>`
- [`<Translations>`](./translate.md#translations), [`<Translate>`](./translate.md#translate-or-t), [`<T>`](./translate.md#translate-or-t), [`withT()`](./translate.md#witht-hoc), and [`@withT`](./translate.md#witht-decorator)
- [UI](./UI.md)
- [`<Portal>`](./Portal.md) and [`<Overlay>`](./Overlay.md)
- [`<Portal>`](./Portal.md), [`<Overlay>`](./Overlay.md), and [`<Modal>`](./Modal.md)
- [`<FullScreen>`](./FullScreen.md)
- [`<Slider>`](./Slider.md)
- [`<Audio>`](./Audio.md) and [`<Video>`](./Video.md)
Expand Down
1 change: 1 addition & 0 deletions docs/en/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
* [UI](UI.md)
* [Portal](Portal.md)
* [Overlay](Overlay.md)
* [Modal](Modal.md)
* [FullScreen](FullScreen.md)
* [Slider](Slider.md)
* [Audio](Audio.md)
Expand Down
2 changes: 1 addition & 1 deletion docs/en/cssvars.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

Use [CSS Custom Properties](https://developer.mozilla.org/en-US/docs/Web/CSS/--*) (aka CSS variables) theming with automatic fallback
to [regular theming](./theme.md). Below components allow you to safely use CSS variables. You simply use `<CssVarsProvider>` similar
to how you use [`<Theme>`](./theme.md#theme), but if CSS variables are supported by user's browser, *all values will be replaces instead
to how you use [`<Theme>`](./theme.md#theme), but if CSS variables are supported by user's browser, *all values will be replaced
by CSS variables* and on subsequent re-renders it will try to *just modify the CSS variables without re-rendering* the children.

> If CSS Custom Properties are not supported, CssVars works like a typical theme provider.
Expand Down
33 changes: 0 additions & 33 deletions gulpfile.js

This file was deleted.

17 changes: 11 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "libreact",
"version": "0.6.3",
"version": "0.6.6",
"description": "React standard library",
"main": "lib/index.js",
"repository": {
Expand All @@ -9,7 +9,7 @@
},
"scripts": {
"start": "npm run test:story",
"build": "npm run clean && gulp build-ts && gulp build-modules",
"build": "npm run clean && gulp --gulpfile build/gulpfile.js build",
"clean": "rimraf lib modules && npm run test:story:clean && npm run docs:clean",
"test": "npm run test:server && npm run test:client",
"test:server": "mocha -r ts-node/register src/**/*.test-server.ts*",
Expand All @@ -28,11 +28,13 @@
},
"dependencies": {
"throttle-debounce": "^1.0.1",
"freestyler-context": "^1.3.3",
"freestyler-renderer": "^1.3.2",
"freestyler": "1.10.0",
"screenfull": "^3.3.2",
"fast-extend": "1.0.2",
"fast-shallow-equal": "0.1.1"
"fast-shallow-equal": "0.1.1",
"tslib": "^1.9.0",
"react-universal-interface": "^0.3.1",
"react-focus-lock": "1.6.5"
},
"peerDependencies": {
"react": "*",
Expand Down Expand Up @@ -165,6 +167,9 @@
"link",
"fullscreen",
"css",
"reset"
"reset",
"portal",
"overlay",
"modal"
]
}
54 changes: 54 additions & 0 deletions src/Modal/__story__/story.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import {createElement as h} from 'react';
import {storiesOf} from '@storybook/react';
import {action} from '@storybook/addon-actions';
import {linkTo} from '@storybook/addon-links';
import {Modal} from '..';
import ShowDocs from '../../../.storybook/ShowDocs'

storiesOf('UI/Modal', module)
.add('Documentation', () => h(ShowDocs, {md: require('../../../docs/en/Modal.md')}))
.add('Basic example', () =>
<div>
<Modal>
foobar
</Modal>
</div>
)
.add('Button underneath', () =>
<div>
<button onClick={() => alert('CLICKED')}>Click me!</button>
<Modal>
foobar
</Modal>
</div>
)
.add('With inputs', () =>
<div>
<button onClick={() => alert('CLICKED')}>Click me!</button>
<Modal>
<div style={{background: 'white'}}>
This is modal...
<button>OK</button>
<button>Cancel</button>
</div>
</Modal>
</div>
)
.add('Modal UI', () =>
<div>
<Modal color='tomato' onClick={action('onClick')} onEsc={action('onEsc')}>
<div
style={{
width: 300,
height: 200,
background: '#fff',
borderRadius: 4,
boxShadow: '0 2px 4px rgba(0,0,0,.3)',
padding: 30,
}}
>
foobar
</div>
</Modal>
</div>
)
Loading

0 comments on commit bba1ef9

Please sign in to comment.