UNPKG

react-ions

Version:

An open source set of React components that implement Ambassador's Design and UX patterns.

149 lines (119 loc) 5.43 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.Popover = undefined; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _reactClickOutside = require('react-click-outside'); var _reactClickOutside2 = _interopRequireDefault(_reactClickOutside); var _style = require('./style.scss'); var _style2 = _interopRequireDefault(_style); var _bind = require('classnames/bind'); var _bind2 = _interopRequireDefault(_bind); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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 Popover = exports.Popover = function (_React$Component) { _inherits(Popover, _React$Component); function Popover(props) { _classCallCheck(this, Popover); var _this = _possibleConstructorReturn(this, (Popover.__proto__ || Object.getPrototypeOf(Popover)).call(this, props)); _this.state = { position: _this.props.defaultPosition }; _this.shouldComponentUpdate = function (nextProps, nextState) { if (_this.props.showing !== nextProps.showing) return true; if (_this.props.content !== nextProps.content) return true; if (_this.state.position !== nextState.position) return true; return false; }; _this.componentWillReceiveProps = function (nextProps) { if (nextProps.showing) { var popoverRect = _this._popoverElement.getBoundingClientRect(); // If the top position of the bounding rect minus the pageYOffset is < 0 // then the top of the window is clipping the popover and it needs to have // its position switched to bottom if (_this.props.defaultPosition === 'top' && popoverRect.top - window.pageYOffset < 0) { _this.setState({ position: 'bottom' }); } // If the window height minus the bottom position of the bounding rect plus // the pageYOffset is < 0 then the bottom of the window is clipping the popover // and it needs to have its position switched to top else if (_this.props.defaultPosition === 'bottom' && window.innerHeight - popoverRect.bottom + window.pageYOffset < 0) { _this.setState({ position: 'top' }); } } }; _this.handleClickOutside = function () { if (_this.props.showing && _this.props.onRequestClose) _this.props.onRequestClose(); }; _this.getPopover = function () { var cx = _bind2.default.bind(_style2.default); var popoverShowingClass = _this.props.showing ? _style2.default['popover-showing'] : null; var innerClass = cx(_style2.default['popover-inner'], popoverShowingClass, _style2.default[_this.state.position]); return _react2.default.createElement( 'div', { className: innerClass, ref: function ref(c) { return _this._popoverElement = c; } }, _react2.default.createElement( 'div', { className: _style2.default['popover-content'] }, _this.props.content ) ); }; _this.render = function () { var cx = _bind2.default.bind(_style2.default); var popoverClasses = cx(_style2.default['popover'], _this.props.optClass); return _react2.default.createElement( 'div', { className: popoverClasses }, _this.state.position === 'top' && _react2.default.createElement( 'div', { className: _style2.default['popover-wrapper'] }, _this.getPopover() ), _this.props.children, _this.state.position === 'bottom' && _react2.default.createElement( 'div', { className: _style2.default['popover-wrapper'] }, _this.getPopover() ) ); }; return _this; } return Popover; }(_react2.default.Component); Popover.propTypes = { /** * Whether to show the popover. */ showing: _propTypes2.default.bool, /** * The default position of the popover. */ defaultPosition: _propTypes2.default.oneOf(['top', 'bottom']), /** * The content to display inside the popover. */ content: _propTypes2.default.node, /** * Optional styles to add to the checkbox. */ optClass: _propTypes2.default.string, /** * The method to be triggered on close. */ onRequestClose: _propTypes2.default.func }; Popover.defaultProps = { defaultPosition: 'bottom', showing: false }; exports.default = (0, _reactClickOutside2.default)(Popover);