UNPKG

ndla-ui

Version:

UI component library for NDLA.

188 lines (170 loc) 7.82 kB
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 _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } 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; } /** * Copyright (c) 2016-present, NDLA. * * This source code is licensed under the GPLv3 license found in the * LICENSE file in the root directory of this source tree. * */ import React from 'react'; import PropTypes from 'prop-types'; import { noScroll } from 'ndla-util'; import elementType from 'react-prop-types/lib/elementType'; import FocusTrap from 'focus-trap-react'; import Button from 'ndla-button'; import Dialog from '../Dialog'; var ClickToggle = function (_React$Component) { _inherits(ClickToggle, _React$Component); function ClickToggle(props) { _classCallCheck(this, ClickToggle); var _this = _possibleConstructorReturn(this, (ClickToggle.__proto__ || Object.getPrototypeOf(ClickToggle)).call(this, props)); _this.state = { isOpen: false }; _this.handleClick = _this.handleClick.bind(_this); _this.handleOnClose = _this.handleOnClose.bind(_this); _this.unmountTrap = _this.unmountTrap.bind(_this); return _this; } _createClass(ClickToggle, [{ key: 'unmountTrap', value: function unmountTrap() { if (this.props.onToggle) { this.handleOnClose(); } else { noScroll(false); this.setState({ isOpen: false }); } } }, { key: 'handleClick', value: function handleClick() { var useState = this.props.isOpen === null; var isOpen = useState ? !this.state.isOpen : !this.props.isOpen; if (this.props.onToggle) { this.props.onToggle(isOpen); } else { noScroll(this.props.noScrollDisabled ? false : isOpen); this.setState({ isOpen: isOpen }); } } }, { key: 'handleOnClose', value: function handleOnClose() { this.props.onToggle(false); } }, { key: 'render', value: function render() { var _props = this.props, title = _props.title, id = _props.id, labelledby = _props.labelledby, openTitle = _props.openTitle, buttonClassName = _props.buttonClassName, noScrollDisabled = _props.noScrollDisabled, Component = _props.containerClass, renderAsLink = _props.renderAsLink, renderAsLightButton = _props.renderAsLightButton, stripped = _props.stripped, dialogModifier = _props.dialogModifier, isOpen = _props.isOpen, alwaysRenderChildren = _props.alwaysRenderChildren, disablePortal = _props.disablePortal, children = _props.children, rest = _objectWithoutProperties(_props, ['title', 'id', 'labelledby', 'openTitle', 'buttonClassName', 'noScrollDisabled', 'containerClass', 'renderAsLink', 'renderAsLightButton', 'stripped', 'dialogModifier', 'isOpen', 'alwaysRenderChildren', 'disablePortal', 'children']); var showDialog = isOpen === null ? this.state.isOpen : isOpen; var useDialog = typeof children !== 'function'; return React.createElement( Component, rest, React.createElement( Button, { stripped: stripped, link: renderAsLink, lighter: renderAsLightButton, className: '' + (showDialog ? 'active ' : '') + buttonClassName, onClick: this.handleClick }, title ), React.createElement( FocusTrap, { active: showDialog, focusTrapOptions: { onDeactivate: this.unmountTrap, clickOutsideDeactivates: true // Only works when click on scrollbar } }, useDialog && (alwaysRenderChildren || showDialog) && React.createElement( Dialog, { id: id, labelledby: labelledby, hidden: !showDialog, onClose: this.handleClick, disablePortal: disablePortal, messages: { close: openTitle || 'lukk' }, modifier: showDialog ? ['active', dialogModifier] : dialogModifier }, children ), !useDialog && (isOpen || alwaysRenderChildren) && children(this.handleOnClose, isOpen) ) ); } }]); return ClickToggle; }(React.Component); export default ClickToggle; ClickToggle.propTypes = { id: function id(props, propName, componentName) { if (typeof props[propName] !== 'string' && props[propName] !== undefined) { return new Error('Invalid prop ' + propName + ' supplied to ' + componentName + '. Type must be a string.'); } if (typeof props.children !== 'function' && typeof props[propName] !== 'string') { return new Error('Invalid prop ' + propName + ' supplied to ' + componentName + '. When children prop is a node, id prop is isRequired.'); } return null; }, labelledby: PropTypes.string, containerClass: elementType, title: PropTypes.node.isRequired, openTitle: PropTypes.node, buttonClassName: PropTypes.string, className: PropTypes.string, children: PropTypes.oneOfType([PropTypes.node, PropTypes.func]).isRequired, noScrollDisabled: PropTypes.bool, isOpen: PropTypes.bool, onToggle: function onToggle(props, propName, componentName) { if (typeof props[propName] !== 'function' && props[propName] !== null) { return new Error('Invalid prop ' + propName + ' supplied to ' + componentName + '. Type must be a function.'); } if (typeof props.children === 'function' && typeof props[propName] !== 'function') { return new Error('Invalid prop ' + propName + ' supplied to ' + componentName + '. When children prop is a function, onToggle prop is isRequired.'); } return null; }, renderAsLink: PropTypes.bool, renderAsLightButton: PropTypes.bool, stripped: PropTypes.bool, dialogModifier: PropTypes.oneOfType([PropTypes.string, PropTypes.array]), alwaysRenderChildren: PropTypes.bool, disablePortal: PropTypes.bool }; ClickToggle.defaultProps = { containerClass: 'div', renderAsLink: false, renderAsLightButton: false, stripped: false, isOpen: null, onToggle: null, id: undefined, alwaysRenderChildren: false, disablePortal: true };