diff --git a/.babelrc b/.babelrc index facd1809..e68d2fea 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,3 @@ { - "presets": ["es2015", "react"] -} \ No newline at end of file + "presets": ["es2015", "stage-2", "react"] +} diff --git a/examples/basic/app.js b/examples/basic/app.js index d0988f8f..f2953dbe 100644 --- a/examples/basic/app.js +++ b/examples/basic/app.js @@ -1,64 +1,57 @@ -var React = require('react'); -var ReactDOM = require('react-dom'); -var Modal = require('../../lib/index'); -var createReactClass = require('create-react-class'); +import React, { Component } from 'react'; +import ReactDOM from 'react-dom'; +import Modal from '../../lib/index'; -var appElement = document.getElementById('example'); +const appElement = document.getElementById('example'); Modal.setAppElement('#example'); -var App = createReactClass({ - - getInitialState: function() { - return { modalIsOpen: false, modal2: false }; - }, - - openModal: function() { - this.setState(Object.assign({}, this.state, { modalIsOpen: true })); - }, +class App extends Component { + constructor(props) { + super(props); + this.state = { modal1: false, modal2: false }; + } - closeModal: function() { - this.setState(Object.assign({}, this.state, { modalIsOpen: false })); - }, + toggleModal_1 = () => { + this.setState({ ...this.state, modal1: !this.state.modal1 }); + } - openSecondModal: function(event) { + toggleModal_2 = event => { event.preventDefault(); - this.setState(Object.assign ({}, this.state, { modal2: true })); - }, - - closeSecondModal: function() { - this.setState(Object.assign ({}, this.state, { modal2: false })); - }, + this.setState({ ...this.state, modal2: !this.state.modal2 }); + } - handleModalCloseRequest: function() { + handleModalCloseRequest = () => { // opportunity to validate something and keep the modal open even if it // requested to be closed - this.setState(Object.assign ({}, this.state, { modalIsOpen: false })); - }, + this.setState({ ...this.state, modal1: false }); + } - handleInputChange: function() { - this.setState({ foo: 'bar' }); - }, + handleInputChange = () => { + this.setState({ ...this.state, foo: 'bar' }); + } - handleOnAfterOpenModal: function() { + handleOnAfterOpenModal = () => { // when ready, we can access the available refs. this.refs.title.style.color = '#F00'; - }, + } - render: function() { + render() { + const { modal1, modal2 } = this.state; return (
- - + +

Hello

- +
I am a modal
@@ -71,20 +64,21 @@ var App = createReactClass({ - +
{}} - onRequestClose={this.closeSecondModal}> + onRequestClose={this.toggleModal_2}>

test

); } -}); +} ReactDOM.render(, appElement); diff --git a/lib/components/Modal.js b/lib/components/Modal.js index a9d017e1..33d613fd 100644 --- a/lib/components/Modal.js +++ b/lib/components/Modal.js @@ -1,38 +1,33 @@ -var React = require('react'); -var ReactDOM = require('react-dom'); -var DOMFactories = require('react-dom-factories'); -var PropTypes = require('prop-types'); -var ExecutionEnvironment = require('exenv'); -var ModalPortal = React.createFactory(require('./ModalPortal')); -var ariaAppHider = require('../helpers/ariaAppHider'); -var refCount = require('../helpers/refCount'); -var elementClass = require('element-class'); -var renderSubtreeIntoContainer = require("react-dom").unstable_renderSubtreeIntoContainer; -var Assign = require('lodash.assign'); -var createReactClass = require('create-react-class'); - -var SafeHTMLElement = ExecutionEnvironment.canUseDOM ? window.HTMLElement : {}; -var AppElement = ExecutionEnvironment.canUseDOM ? document.body : {appendChild: function() {}}; +import React, { Component } from 'react'; +import ReactDOM from 'react-dom'; +import PropTypes from 'prop-types'; +import ExecutionEnvironment from 'exenv'; +import ModalPortal from './ModalPortal'; +import elementClass from 'element-class'; +import * as ariaAppHider from '../helpers/ariaAppHider'; +import * as refCount from '../helpers/refCount'; + +const renderSubtreeIntoContainer = ReactDOM.unstable_renderSubtreeIntoContainer; + +const SafeHTMLElement = ExecutionEnvironment.canUseDOM ? window.HTMLElement : {}; +let AppElement = ExecutionEnvironment.canUseDOM ? document.body : {appendChild: function() {}}; function getParentElement(parentSelector) { return parentSelector(); } -var Modal = createReactClass({ +export default class Modal extends Component { + static setAppElement = function(element) { + AppElement = ariaAppHider.setElement(element); + }; - displayName: 'Modal', - statics: { - setAppElement: function(element) { - AppElement = ariaAppHider.setElement(element); - }, - injectCSS: function() { - "production" !== process.env.NODE_ENV - && console.warn('React-Modal: injectCSS has been deprecated ' + - 'and no longer has any effect. It will be removed in a later version'); - } - }, + static injectCSS = function() { + "production" !== process.env.NODE_ENV + && console.warn('React-Modal: injectCSS has been deprecated ' + + 'and no longer has any effect. It will be removed in a later version'); + }; - propTypes: { + static propTypes = { isOpen: PropTypes.bool.isRequired, style: PropTypes.shape({ content: PropTypes.object, @@ -49,52 +44,75 @@ var Modal = createReactClass({ parentSelector: PropTypes.func, role: PropTypes.string, contentLabel: PropTypes.string.isRequired - }, - - getDefaultProps: function () { - return { - isOpen: false, - portalClassName: 'ReactModalPortal', - bodyOpenClassName: 'ReactModal__Body--open', - ariaHideApp: true, - closeTimeoutMS: 0, - shouldCloseOnOverlayClick: true, - parentSelector: function () { return document.body; } - }; - }, - - componentDidMount: function() { + }; + + static defaultProps = { + isOpen: false, + portalClassName: 'ReactModalPortal', + bodyOpenClassName: 'ReactModal__Body--open', + ariaHideApp: true, + closeTimeoutMS: 0, + shouldCloseOnOverlayClick: true, + parentSelector: function () { return document.body; } + }; + + static defaultStyles = { + overlay: { + position : 'fixed', + top : 0, + left : 0, + right : 0, + bottom : 0, + backgroundColor : 'rgba(255, 255, 255, 0.75)' + }, + content: { + position : 'absolute', + top : '40px', + left : '40px', + right : '40px', + bottom : '40px', + border : '1px solid #ccc', + background : '#fff', + overflow : 'auto', + WebkitOverflowScrolling : 'touch', + borderRadius : '4px', + outline : 'none', + padding : '20px' + } + }; + + componentDidMount() { this.node = document.createElement('div'); this.node.className = this.props.portalClassName; if (this.props.isOpen) refCount.add(this); - var parent = getParentElement(this.props.parentSelector); + const parent = getParentElement(this.props.parentSelector); parent.appendChild(this.node); this.renderPortal(this.props); - }, + } - componentWillUpdate: function(newProps) { + componentWillUpdate(newProps) { if(newProps.portalClassName !== this.props.portalClassName) { this.node.className = newProps.portalClassName; } - }, + } - componentWillReceiveProps: function(newProps) { + componentWillReceiveProps(newProps) { if (newProps.isOpen) refCount.add(this); if (!newProps.isOpen) refCount.remove(this); - var currentParent = getParentElement(this.props.parentSelector); - var newParent = getParentElement(newProps.parentSelector); + const currentParent = getParentElement(this.props.parentSelector); + const newParent = getParentElement(newProps.parentSelector); - if(newParent !== currentParent) { + if (newParent !== currentParent) { currentParent.removeChild(this.node); newParent.appendChild(this.node); } this.renderPortal(newProps); - }, + } - componentWillUnmount: function() { + componentWillUnmount() { if (!this.node) return; refCount.remove(this); @@ -103,9 +121,9 @@ var Modal = createReactClass({ ariaAppHider.show(this.props.appElement); } - var state = this.portal.state; - var now = Date.now(); - var closesAt = state.isOpen && this.props.closeTimeoutMS + const state = this.portal.state; + const now = Date.now(); + const closesAt = state.isOpen && this.props.closeTimeoutMS && (state.closesAt || now + this.props.closeTimeoutMS); @@ -114,24 +132,24 @@ var Modal = createReactClass({ this.portal.closeWithTimeout(); } - var that = this; + const that = this; setTimeout(function() { that.removePortal(); }, closesAt - now); } else { this.removePortal(); } - }, + } - removePortal: function() { + removePortal = () => { ReactDOM.unmountComponentAtNode(this.node); - var parent = getParentElement(this.props.parentSelector); + const parent = getParentElement(this.props.parentSelector); parent.removeChild(this.node); if (refCount.count() === 0) { elementClass(document.body).remove(this.props.bodyOpenClassName); } - }, + } - renderPortal: function(props) { + renderPortal = props => { if (props.isOpen || refCount.count() > 0) { elementClass(document.body).add(this.props.bodyOpenClassName); } else { @@ -142,37 +160,12 @@ var Modal = createReactClass({ ariaAppHider.toggle(props.isOpen, props.appElement); } - this.portal = renderSubtreeIntoContainer(this, ModalPortal(Assign({}, props, {defaultStyles: Modal.defaultStyles})), this.node); - }, - - render: function () { - return DOMFactories.noscript(); + this.portal = renderSubtreeIntoContainer(this, ( + + ), this.node); } -}); - -Modal.defaultStyles = { - overlay: { - position : 'fixed', - top : 0, - left : 0, - right : 0, - bottom : 0, - backgroundColor : 'rgba(255, 255, 255, 0.75)' - }, - content: { - position : 'absolute', - top : '40px', - left : '40px', - right : '40px', - bottom : '40px', - border : '1px solid #ccc', - background : '#fff', - overflow : 'auto', - WebkitOverflowScrolling : 'touch', - borderRadius : '4px', - outline : 'none', - padding : '20px' + + render() { + return null; } } - -module.exports = Modal diff --git a/lib/components/ModalPortal.js b/lib/components/ModalPortal.js index ec91d852..19f2bed6 100644 --- a/lib/components/ModalPortal.js +++ b/lib/components/ModalPortal.js @@ -1,52 +1,48 @@ -var React = require('react'); -var DOMFactories = require('react-dom-factories'); -var focusManager = require('../helpers/focusManager'); -var scopeTab = require('../helpers/scopeTab'); -var Assign = require('lodash.assign'); -var createReactClass = require('create-react-class'); - -var div = DOMFactories.div; +import React, { Component } from 'react'; +import * as focusManager from '../helpers/focusManager'; +import { scopeTab } from '../helpers/scopeTab'; // so that our CSS is statically analyzable -var CLASS_NAMES = { +const CLASS_NAMES = { overlay: 'ReactModal__Overlay', content: 'ReactModal__Content' }; -var ModalPortal = module.exports = createReactClass({ +const TAB_KEY = 9; +const ESC_KEY = 27; - displayName: 'ModalPortal', - shouldClose: null, +export default class ModalPortal extends Component { + static defaultProps = { + style: { + overlay: {}, + content: {} + } + }; - getDefaultProps: function() { - return { - style: { - overlay: {}, - content: {} - } - }; - }, + constructor(props) { + super(props); - getInitialState: function() { - return { + this.state = { afterOpen: false, beforeClose: false }; - }, - componentDidMount: function() { + this.shouldClose = null; + } + + componentDidMount() { // Focus needs to be set when mounting and already open if (this.props.isOpen) { this.setFocusAfterRender(true); this.open(); } - }, + } - componentWillUnmount: function() { + componentWillUnmount() { clearTimeout(this.closeTimer); - }, + } - componentWillReceiveProps: function(newProps) { + componentWillReceiveProps(newProps) { // Focus only needs to be set once when the modal is being opened if (!this.props.isOpen && newProps.isOpen) { this.setFocusAfterRender(true); @@ -54,150 +50,151 @@ var ModalPortal = module.exports = createReactClass({ } else if (this.props.isOpen && !newProps.isOpen) { this.close(); } - }, + } - componentDidUpdate: function () { + componentDidUpdate() { if (this.focusAfterRender) { this.focusContent(); this.setFocusAfterRender(false); } - }, + } - setFocusAfterRender: function (focus) { + setFocusAfterRender = focus => { this.focusAfterRender = focus; - }, + } - afterClose: function () { + afterClose = () => { focusManager.returnFocus(); focusManager.teardownScopedFocus(); - }, + } - open: function () { + open = () => { if (this.state.afterOpen && this.state.beforeClose) { clearTimeout(this.closeTimer); this.setState({ beforeClose: false }); } else { focusManager.setupScopedFocus(this.node); focusManager.markForFocusLater(); - this.setState({isOpen: true}, function() { - this.setState({afterOpen: true}); + this.setState({ isOpen: true }, () => { + this.setState({ afterOpen: true }); if (this.props.isOpen && this.props.onAfterOpen) { this.props.onAfterOpen(); } - }.bind(this)); + }); } - }, + } - close: function() { - if (this.props.closeTimeoutMS > 0) + close = () => { + if (this.props.closeTimeoutMS > 0) { this.closeWithTimeout(); - else + } else { this.closeWithoutTimeout(); - }, + } + } - focusContent: function() { + focusContent = () => { // Don't steal focus from inner elements if (!this.contentHasFocus()) { this.refs.content.focus(); } - }, + } - closeWithTimeout: function() { - var closesAt = Date.now() + this.props.closeTimeoutMS; - this.setState({beforeClose: true, closesAt: closesAt}, function() { + closeWithTimeout = () => { + const closesAt = Date.now() + this.props.closeTimeoutMS; + this.setState({ beforeClose: true, closesAt: closesAt }, () => { this.closeTimer = setTimeout(this.closeWithoutTimeout, this.state.closesAt - Date.now()); - }.bind(this)); - }, + }); + } - closeWithoutTimeout: function() { + closeWithoutTimeout = () => { this.setState({ beforeClose: false, isOpen: false, afterOpen: false, closesAt: null }, this.afterClose); - }, + } - handleKeyDown: function(event) { - if (event.keyCode == 9 /*tab*/) scopeTab(this.refs.content, event); - if (event.keyCode == 27 /*esc*/) { + handleKeyDown = event => { + if (event.keyCode == TAB_KEY) { + scopeTab(this.refs.content, event); + } + if (event.keyCode == ESC_KEY) { event.preventDefault(); this.requestClose(event); } - }, + } - handleOverlayOnClick: function (event) { + handleOverlayOnClick = event => { if (this.shouldClose === null) { this.shouldClose = true; } if (this.shouldClose && this.props.shouldCloseOnOverlayClick) { - if (this.ownerHandlesClose()) + if (this.ownerHandlesClose()) { this.requestClose(event); - else + } else { this.focusContent(); + } } this.shouldClose = null; - }, + } - handleContentOnClick: function () { + handleContentOnClick = () => { this.shouldClose = false; - }, + } - requestClose: function(event) { - if (this.ownerHandlesClose()) + requestClose = event => { + if (this.ownerHandlesClose()) { this.props.onRequestClose(event); - }, + } + } - ownerHandlesClose: function() { + ownerHandlesClose = () => { return this.props.onRequestClose; - }, + } - shouldBeClosed: function() { + shouldBeClosed = () => { return !this.state.isOpen && !this.state.beforeClose; - }, + } - contentHasFocus: function() { + contentHasFocus = () => { return document.activeElement === this.refs.content || this.refs.content.contains(document.activeElement); - }, + } - buildClassName: function(which, additional) { - var classNames = (typeof additional === 'object') ? additional : { + buildClassName = (which, additional) => { + const classNames = (typeof additional === 'object') ? additional : { base: CLASS_NAMES[which], afterOpen: CLASS_NAMES[which] + "--after-open", beforeClose: CLASS_NAMES[which] + "--before-close" }; - var className = classNames.base; + let className = classNames.base; if (this.state.afterOpen) { className += " " + classNames.afterOpen; } if (this.state.beforeClose) { className += " " + classNames.beforeClose; } return (typeof additional === 'string' && additional) ? [className, additional].join(" ") : className; - }, - - render: function() { - var contentStyles = (this.props.className) ? {} : this.props.defaultStyles.content; - var overlayStyles = (this.props.overlayClassName) ? {} : this.props.defaultStyles.overlay; - - return this.shouldBeClosed() ? div() : ( - div({ - ref: "overlay", - className: this.buildClassName('overlay', this.props.overlayClassName), - style: Assign({}, overlayStyles, this.props.style.overlay || {}), - onClick: this.handleOverlayOnClick - }, - div({ - ref: "content", - style: Assign({}, contentStyles, this.props.style.content || {}), - className: this.buildClassName('content', this.props.className), - tabIndex: "-1", - onKeyDown: this.handleKeyDown, - onClick: this.handleContentOnClick, - role: this.props.role, - "aria-label": this.props.contentLabel - }, - this.props.children - ) - ) + } + + render() { + const contentStyles = this.props.className ? {} : this.props.defaultStyles.content; + const overlayStyles = this.props.overlayClassName ? {} : this.props.defaultStyles.overlay; + + return this.shouldBeClosed() ?
: ( +
+
+ {this.props.children} +
+
); } -}); +} diff --git a/lib/helpers/ariaAppHider.js b/lib/helpers/ariaAppHider.js index 05b4c128..8ade7473 100644 --- a/lib/helpers/ariaAppHider.js +++ b/lib/helpers/ariaAppHider.js @@ -1,42 +1,37 @@ -var _element = typeof document !== 'undefined' ? document.body : null; +let _element = typeof document !== 'undefined' ? document.body : null; -function setElement(element) { +export function setElement(element) { if (typeof element === 'string') { - var el = document.querySelectorAll(element); + const el = document.querySelectorAll(element); element = 'length' in el ? el[0] : el; } _element = element || _element; return _element; } -function hide(appElement) { +export function hide(appElement) { validateElement(appElement); (appElement || _element).setAttribute('aria-hidden', 'true'); } -function show(appElement) { +export function show(appElement) { validateElement(appElement); (appElement || _element).removeAttribute('aria-hidden'); } -function toggle(shouldHide, appElement) { - if (shouldHide) - hide(appElement); - else - show(appElement); +export function toggle(shouldHide, appElement) { + const apply = shouldHide ? hide : show; + apply(appElement); } -function validateElement(appElement) { - if (!appElement && !_element) +export function validateElement(appElement) { + if (!appElement && !_element) { throw new Error('react-modal: You must set an element with `Modal.setAppElement(el)` to make this accessible'); + } } -function resetForTesting() { +export function resetForTesting() { _element = document.body; } -exports.toggle = toggle; -exports.setElement = setElement; -exports.show = show; -exports.hide = hide; -exports.resetForTesting = resetForTesting; + diff --git a/lib/helpers/focusManager.js b/lib/helpers/focusManager.js index 5d32db60..3e8a2564 100644 --- a/lib/helpers/focusManager.js +++ b/lib/helpers/focusManager.js @@ -1,13 +1,14 @@ -var findTabbable = require('../helpers/tabbable'); -var focusLaterElements = []; -var modalElement = null; -var needToFocus = false; +import findTabbable from '../helpers/tabbable'; -function handleBlur(event) { +let focusLaterElements = []; +let modalElement = null; +let needToFocus = false; + +export function handleBlur(event) { needToFocus = true; } -function handleFocus(event) { +export function handleFocus(event) { if (needToFocus) { needToFocus = false; if (!modalElement) { @@ -19,20 +20,21 @@ function handleFocus(event) { // is that the document.body gets focus, and then we focus our element right // after, seems fine. setTimeout(function() { - if (modalElement.contains(document.activeElement)) + if (modalElement.contains(document.activeElement)) { return; - var el = (findTabbable(modalElement)[0] || modalElement); + } + const el = (findTabbable(modalElement)[0] || modalElement); el.focus(); }, 0); } } -exports.markForFocusLater = function() { +export function markForFocusLater() { focusLaterElements.push(document.activeElement); -}; +} -exports.returnFocus = function() { - var toFocus = null; +export function returnFocus() { + let toFocus = null; try { toFocus = focusLaterElements.pop(); toFocus.focus(); @@ -41,9 +43,9 @@ exports.returnFocus = function() { catch (e) { console.warn('You tried to return focus to '+toFocus+' but it is not in the DOM anymore'); } -}; +} -exports.setupScopedFocus = function(element) { +export function setupScopedFocus(element) { modalElement = element; if (window.addEventListener) { @@ -53,9 +55,9 @@ exports.setupScopedFocus = function(element) { window.attachEvent('onBlur', handleBlur); document.attachEvent('onFocus', handleFocus); } -}; +} -exports.teardownScopedFocus = function() { +export function teardownScopedFocus() { modalElement = null; if (window.addEventListener) { @@ -65,4 +67,4 @@ exports.teardownScopedFocus = function() { window.detachEvent('onBlur', handleBlur); document.detachEvent('onFocus', handleFocus); } -}; +} diff --git a/lib/helpers/refCount.js b/lib/helpers/refCount.js index 1b8c4cc6..21df32b4 100644 --- a/lib/helpers/refCount.js +++ b/lib/helpers/refCount.js @@ -1,19 +1,19 @@ -var modals = []; +let modals = []; -module.exports = { - add: function (element) { - if (modals.indexOf(element) === -1) { - modals.push(element); - } - }, - remove: function (element) { - var index = modals.indexOf(element); - if (index === -1) { - return; - } - modals.splice(index, 1); - }, - count: function () { - return modals.length; +export function add(element) { + if (modals.indexOf(element) === -1) { + modals.push(element); } -}; +} + +export function remove(element) { + const index = modals.indexOf(element); + if (index === -1) { + return; + } + modals.splice(index, 1); +} + +export function count() { + return modals.length; +} diff --git a/lib/helpers/scopeTab.js b/lib/helpers/scopeTab.js index d368bd8f..e4b21d6f 100644 --- a/lib/helpers/scopeTab.js +++ b/lib/helpers/scopeTab.js @@ -1,19 +1,19 @@ -var findTabbable = require('../helpers/tabbable'); +import findTabbable from './tabbable'; -module.exports = function(node, event) { - var tabbable = findTabbable(node); +export function scopeTab(node, event) { + const tabbable = findTabbable(node); if (!tabbable.length) { event.preventDefault(); return; } - var finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1]; - var leavingFinalTabbable = ( + const finalTabbable = tabbable[event.shiftKey ? 0 : tabbable.length - 1]; + const leavingFinalTabbable = ( finalTabbable === document.activeElement || // handle immediate shift+tab after opening with mouse node === document.activeElement ); if (!leavingFinalTabbable) return; event.preventDefault(); - var target = tabbable[event.shiftKey ? tabbable.length - 1 : 0]; + const target = tabbable[event.shiftKey ? tabbable.length - 1 : 0]; target.focus(); -}; +} diff --git a/lib/helpers/tabbable.js b/lib/helpers/tabbable.js index 4b04f88b..e10d0d75 100644 --- a/lib/helpers/tabbable.js +++ b/lib/helpers/tabbable.js @@ -11,7 +11,7 @@ */ function focusable(element, isTabIndexNotNaN) { - var nodeName = element.nodeName.toLowerCase(); + const nodeName = element.nodeName.toLowerCase(); return (/input|select|textarea|button|object/.test(nodeName) ? !element.disabled : "a" === nodeName ? @@ -34,17 +34,16 @@ function visible(element) { } function tabbable(element) { - var tabIndex = element.getAttribute('tabindex'); + let tabIndex = element.getAttribute('tabindex'); if (tabIndex === null) tabIndex = undefined; - var isTabIndexNaN = isNaN(tabIndex); + const isTabIndexNaN = isNaN(tabIndex); return (isTabIndexNaN || tabIndex >= 0) && focusable(element, !isTabIndexNaN); } -function findTabbableDescendants(element) { +export default function findTabbableDescendants(element) { return [].slice.call(element.querySelectorAll('*'), 0).filter(function(el) { return tabbable(el); }); } -module.exports = findTabbableDescendants; diff --git a/package.json b/package.json index 738ccf78..bac6098f 100644 --- a/package.json +++ b/package.json @@ -25,6 +25,7 @@ "babel-loader": "^6.2.4", "babel-preset-es2015": "^6.6.0", "babel-preset-react": "^6.5.0", + "babel-preset-stage-2": "^6.24.1", "cross-env": "^5.0.1", "envify": "^3.4.1", "expect": "^1.20.2", diff --git a/yarn.lock b/yarn.lock index b9a43374..4d176502 100644 --- a/yarn.lock +++ b/yarn.lock @@ -211,6 +211,14 @@ babel-code-frame@^6.20.0: esutils "^2.0.2" js-tokens "^2.0.0" +babel-code-frame@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" + dependencies: + chalk "^1.1.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + babel-core@^6.18.0, babel-core@^6.7.4: version "6.21.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.21.0.tgz#75525480c21c803f826ef3867d22c19f080a3724" @@ -247,6 +255,22 @@ babel-generator@^6.21.0: lodash "^4.2.0" source-map "^0.5.0" +babel-helper-bindify-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + babel-helper-builder-react-jsx@^6.8.0: version "6.21.1" resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.21.1.tgz#c4a24208655be9dc1cccf14d366da176f20645e4" @@ -274,6 +298,23 @@ babel-helper-define-map@^6.18.0, babel-helper-define-map@^6.8.0: babel-types "^6.18.0" lodash "^4.2.0" +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-explode-class@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" + dependencies: + babel-helper-bindify-decorators "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babel-helper-function-name@^6.18.0, babel-helper-function-name@^6.8.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.18.0.tgz#68ec71aeba1f3e28b2a6f0730190b754a9bf30e6" @@ -284,6 +325,16 @@ babel-helper-function-name@^6.18.0, babel-helper-function-name@^6.8.0: babel-traverse "^6.18.0" babel-types "^6.18.0" +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babel-helper-get-function-arity@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.18.0.tgz#a5b19695fd3f9cdfc328398b47dafcd7094f9f24" @@ -291,6 +342,13 @@ babel-helper-get-function-arity@^6.18.0: babel-runtime "^6.0.0" babel-types "^6.18.0" +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + babel-helper-hoist-variables@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.18.0.tgz#a835b5ab8b46d6de9babefae4d98ea41e866b82a" @@ -313,6 +371,16 @@ babel-helper-regex@^6.8.0: babel-types "^6.18.0" lodash "^4.2.0" +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + babel-helper-replace-supers@^6.18.0, babel-helper-replace-supers@^6.8.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.18.0.tgz#28ec69877be4144dbd64f4cc3a337e89f29a924e" @@ -340,6 +408,12 @@ babel-loader@^6.2.4: mkdirp "^0.5.1" object-assign "^4.0.1" +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + babel-messages@^6.8.0: version "6.8.0" resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.8.0.tgz#bf504736ca967e6d65ef0adb5a2a5f947c8e0eb9" @@ -352,6 +426,30 @@ babel-plugin-check-es2015-constants@^6.3.13: dependencies: babel-runtime "^6.0.0" +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-async-generators@^6.5.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + +babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + +babel-plugin-syntax-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + babel-plugin-syntax-flow@^6.18.0, babel-plugin-syntax-flow@^6.3.13: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" @@ -360,6 +458,49 @@ babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-generator-functions@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-generators "^6.5.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-class-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + dependencies: + babel-helper-function-name "^6.24.1" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" + dependencies: + babel-helper-explode-class "^6.24.1" + babel-plugin-syntax-decorators "^6.13.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-types "^6.24.1" + babel-plugin-transform-es2015-arrow-functions@^6.3.13: version "6.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.8.0.tgz#5b63afc3181bdc9a8c4d481b5a4f3f7d7fef3d9d" @@ -529,6 +670,14 @@ babel-plugin-transform-es2015-unicode-regex@^6.3.13: babel-runtime "^6.0.0" regexpu-core "^2.0.0" +babel-plugin-transform-exponentiation-operator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + babel-plugin-transform-flow-strip-types@^6.3.13: version "6.21.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.21.0.tgz#2eea3f8b5bb234339b47283feac155cfb237b948" @@ -536,6 +685,13 @@ babel-plugin-transform-flow-strip-types@^6.3.13: babel-plugin-syntax-flow "^6.18.0" babel-runtime "^6.0.0" +babel-plugin-transform-object-rest-spread@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz#875d6bc9be761c58a2ae3feee5dc4895d8c7f921" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.22.0" + babel-plugin-transform-react-display-name@^6.3.13: version "6.8.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.8.0.tgz#f7a084977383d728bdbdc2835bba0159577f660e" @@ -618,6 +774,25 @@ babel-preset-react@^6.5.0: babel-plugin-transform-react-jsx-self "^6.11.0" babel-plugin-transform-react-jsx-source "^6.3.13" +babel-preset-stage-2: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" + dependencies: + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-plugin-transform-class-properties "^6.24.1" + babel-plugin-transform-decorators "^6.24.1" + babel-preset-stage-3 "^6.24.1" + +babel-preset-stage-3@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-generator-functions "^6.24.1" + babel-plugin-transform-async-to-generator "^6.24.1" + babel-plugin-transform-exponentiation-operator "^6.24.1" + babel-plugin-transform-object-rest-spread "^6.22.0" + babel-register@^6.18.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.18.0.tgz#892e2e03865078dd90ad2c715111ec4449b32a68" @@ -630,13 +805,20 @@ babel-register@^6.18.0: mkdirp "^0.5.1" source-map-support "^0.4.2" -babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.18.0, babel-runtime@^6.20.0, babel-runtime@^6.9.0: +babel-runtime@^6.0.0, babel-runtime@^6.11.6, babel-runtime@^6.20.0, babel-runtime@^6.9.0: version "6.20.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.20.0.tgz#87300bdcf4cd770f09bf0048c64204e17806d16f" dependencies: core-js "^2.4.0" regenerator-runtime "^0.10.0" +babel-runtime@^6.18.0, babel-runtime@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + babel-template@^6.14.0, babel-template@^6.15.0, babel-template@^6.16.0, babel-template@^6.8.0: version "6.16.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.16.0.tgz#e149dd1a9f03a35f817ddbc4d0481988e7ebc8ca" @@ -647,6 +829,16 @@ babel-template@^6.14.0, babel-template@^6.15.0, babel-template@^6.16.0, babel-te babylon "^6.11.0" lodash "^4.2.0" +babel-template@^6.24.1: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.25.0.tgz#665241166b7c2aa4c619d71e192969552b10c071" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.25.0" + babel-types "^6.25.0" + babylon "^6.17.2" + lodash "^4.2.0" + babel-traverse@^6.16.0, babel-traverse@^6.18.0, babel-traverse@^6.21.0: version "6.21.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.21.0.tgz#69c6365804f1a4f69eb1213f85b00a818b8c21ad" @@ -661,7 +853,21 @@ babel-traverse@^6.16.0, babel-traverse@^6.18.0, babel-traverse@^6.21.0: invariant "^2.2.0" lodash "^4.2.0" -babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.21.0, babel-types@^6.8.0, babel-types@^6.9.0: +babel-traverse@^6.24.1, babel-traverse@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.25.0.tgz#2257497e2fcd19b89edc13c4c91381f9512496f1" + dependencies: + babel-code-frame "^6.22.0" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.25.0" + babylon "^6.17.2" + debug "^2.2.0" + globals "^9.0.0" + invariant "^2.2.0" + lodash "^4.2.0" + +babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.21.0, babel-types@^6.8.0, babel-types@^6.9.0: version "6.21.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.21.0.tgz#314b92168891ef6d3806b7f7a917fdf87c11a4b2" dependencies: @@ -670,10 +876,23 @@ babel-types@^6.16.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.21 lodash "^4.2.0" to-fast-properties "^1.0.1" +babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.25.0: + version "6.25.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.25.0.tgz#70afb248d5660e5d18f811d91c8303b54134a18e" + dependencies: + babel-runtime "^6.22.0" + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^1.0.1" + babylon@^6.11.0: version "6.14.1" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.14.1.tgz#956275fab72753ad9b3435d7afe58f8bf0a29815" +babylon@^6.17.2: + version "6.17.3" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.3.tgz#1327d709950b558f204e5352587fd0290f8d8e48" + backo2@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947" @@ -2290,6 +2509,10 @@ js-tokens@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-2.0.0.tgz#79903f5563ee778cc1162e6dcf1a0027c97f9cb5" +js-tokens@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" + jsbn@~0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.0.tgz#650987da0dd74f4ebf5a11377a2aa2d273e97dfd"