'use strict'; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } var React = require('react'); var createFocusTrap = require('focus-trap'); var checkedProps = ['active', 'paused', 'tag', 'focusTrapOptions', '_createFocusTrap']; var FocusTrap = function (_React$Component) { _inherits(FocusTrap, _React$Component); function FocusTrap(props) { _classCallCheck(this, FocusTrap); var _this = _possibleConstructorReturn(this, (FocusTrap.__proto__ || Object.getPrototypeOf(FocusTrap)).call(this, props)); _this.setNode = function (el) { _this.node = el; }; if (typeof document !== 'undefined') { _this.previouslyFocusedElement = document.activeElement; } return _this; } _createClass(FocusTrap, [{ key: 'componentDidMount', value: function componentDidMount() { // We need to hijack the returnFocusOnDeactivate option, // because React can move focus into the element before we arrived at // this lifecycle hook (e.g. with autoFocus inputs). So the component // captures the previouslyFocusedElement in componentWillMount, // then (optionally) returns focus to it in componentWillUnmount. var specifiedFocusTrapOptions = this.props.focusTrapOptions; var tailoredFocusTrapOptions = { returnFocusOnDeactivate: false }; for (var optionName in specifiedFocusTrapOptions) { if (!specifiedFocusTrapOptions.hasOwnProperty(optionName)) continue; if (optionName === 'returnFocusOnDeactivate') continue; tailoredFocusTrapOptions[optionName] = specifiedFocusTrapOptions[optionName]; } this.focusTrap = this.props._createFocusTrap(this.node, tailoredFocusTrapOptions); if (this.props.active) { this.focusTrap.activate(); } if (this.props.paused) { this.focusTrap.pause(); } } }, { key: 'componentDidUpdate', value: function componentDidUpdate(prevProps) { if (prevProps.active && !this.props.active) { var returnFocusOnDeactivate = this.props.focusTrapOptions.returnFocusOnDeactivate; var returnFocus = returnFocusOnDeactivate || false; var config = { returnFocus: returnFocus }; this.focusTrap.deactivate(config); } else if (!prevProps.active && this.props.active) { this.focusTrap.activate(); } if (prevProps.paused && !this.props.paused) { this.focusTrap.unpause(); } else if (!prevProps.paused && this.props.paused) { this.focusTrap.pause(); } } }, { key: 'componentWillUnmount', value: function componentWillUnmount() { this.focusTrap.deactivate(); if (this.props.focusTrapOptions.returnFocusOnDeactivate !== false && this.previouslyFocusedElement && this.previouslyFocusedElement.focus) { this.previouslyFocusedElement.focus(); } } }, { key: 'render', value: function render() { var elementProps = { ref: this.setNode }; // This will get id, className, style, etc. -- arbitrary element props for (var prop in this.props) { if (!this.props.hasOwnProperty(prop)) continue; if (checkedProps.indexOf(prop) !== -1) continue; elementProps[prop] = this.props[prop]; } return React.createElement(this.props.tag, elementProps, this.props.children); } }]); return FocusTrap; }(React.Component); FocusTrap.defaultProps = { active: true, tag: 'div', paused: false, focusTrapOptions: {}, _createFocusTrap: createFocusTrap }; module.exports = FocusTrap;