UNPKG

sc-react-ions

Version:

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

246 lines (201 loc) 9.04 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.ButtonConfirmation = undefined; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _bind = require('classnames/bind'); var _bind2 = _interopRequireDefault(_bind); var _OptClass = require('../internal/OptClass'); var _OptClass2 = _interopRequireDefault(_OptClass); var _Button = require('./Button'); var _Button2 = _interopRequireDefault(_Button); var _style = require('./style.scss'); var _style2 = _interopRequireDefault(_style); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } 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; } var ButtonConfirmation = exports.ButtonConfirmation = function (_Component) { _inherits(ButtonConfirmation, _Component); function ButtonConfirmation(props) { _classCallCheck(this, ButtonConfirmation); var _this = _possibleConstructorReturn(this, (ButtonConfirmation.__proto__ || Object.getPrototypeOf(ButtonConfirmation)).call(this, props)); _this.state = { confirmationOverlayOpen: false, confirmationOverlayOffset: 0, hasBeenOpened: false, wide: false }; _this.handleOpen = function () { if (!_this.props.hasBeenOpened) { _this.setState({ hasBeenOpened: true }, function () { _this.handleSetup(); }); } _this.setState({ confirmationOverlayOpen: !_this.state.confirmationOverlayOpen }); }; _this.handleConfirmation = function (confirm) { _this.setState({ confirmationOverlayOpen: false }, function () { if (typeof _this.props.handleConfirmation === 'function' && confirm) { _this.props.handleConfirmation(confirm); } }); }; _this.handleSetup = function () { var triggerRect = _this._trigger.children[0].getBoundingClientRect(); var overlayRect = _this._trigger.querySelector("[class*='confirmation-overlay']").getBoundingClientRect(); _this.setState({ triggerWidth: triggerRect.width, overlayWidth: overlayRect.width }); }; _this.handleWide = function () { if (_this.props.prompt.length > 25) { _this.setState({ wide: true }); } }; _this.getStyles = function () { if (_this.props.position === 'right') { return { right: _this.state.confirmationOverlayOffset + 'px' }; } if (_this.props.position === 'left') { return { left: _this.state.confirmationOverlayOffset + 'px' }; } // https://developers.google.com/web/updates/2016/06/absolute-positioned-children // Once ^ is supported in Safari and Firefox we can remove this and allow flex box to do its thing return { left: '-' + (_this.state.overlayWidth - _this.state.triggerWidth) / 2 + 'px' }; }; _this.getCaretStyles = function () { if (_this.props.position === 'right') { return { right: 'calc(' + (_this.state.triggerWidth / 2 + 7.5) + 'px)' }; } if (_this.props.position === 'left') { return { left: 'calc(' + (_this.state.triggerWidth / 2 - 5) + 'px)' }; } return _this.state.wide ? { left: '95px' } : { left: '75px' }; }; _this.handleMediaChange = function () { _this.handleSetup(); }; _this.componentDidMount = function () { _this.mql.addListener(_this.handleMediaChange); _this.handleSetup(); _this.handleWide(); }; _this.componentWillUnmount = function () { _this.mql.removeListener(_this.handleMediaChange); }; _this.shouldComponentUpdate = function (nextProps, nextState) { if (nextProps.position !== _this.props.position) return true; if (nextState.wide !== _this.state.wide) return true; if (nextState.triggerWidth !== _this.state.triggerWidth) return true; if (nextState.overlayWidth !== _this.state.overlayWidth) return true; if (nextState.confirmationOverlayOpen !== _this.state.confirmationOverlayOpen) return true; if (nextProps.prompt !== _this.props.prompt) return true; if (nextProps.loading !== _this.props.loading) return true; return false; }; _this.render = function () { var cx = _bind2.default.bind(_style2.default); var other = _objectWithoutProperties(_this.props, []); var buttonClass = (0, _OptClass2.default)(_style2.default, ['confirmation-approve-btn']); var overlayPositionClass = _this.props.position ? _style2.default[_this.props.position] : null; var overlayVisibleClass = _this.state.confirmationOverlayOpen ? _style2.default['visible'] : null; var overlayWideClass = _this.state.wide ? _style2.default['wide'] : null; var confirmationOverlayClasses = cx(overlayVisibleClass, overlayPositionClass, overlayWideClass, _style2.default['confirmation-overlay']); return _react2.default.createElement( 'div', { ref: function ref(trigger) { return _this._trigger = trigger; }, className: _style2.default['confirmation-wrapper'] }, _react2.default.createElement( _Button2.default, _extends({}, other, { disabled: _this.state.confirmationOverlayOpen, onClick: _this.handleOpen }), _this.props.children ), _react2.default.createElement( 'div', { className: confirmationOverlayClasses, style: _this.getStyles() }, _react2.default.createElement('em', { style: _this.getCaretStyles() }), _react2.default.createElement( 'span', { className: _style2.default['confirmation-text'] }, _this.props.prompt ), _react2.default.createElement( 'div', { className: _style2.default['button-wrapper'] }, _react2.default.createElement( _Button2.default, { onClick: _this.handleConfirmation.bind(_this, false), optClass: 'danger-alt' }, 'Cancel' ), _react2.default.createElement( _Button2.default, { onClick: _this.handleConfirmation.bind(_this, true), optClass: buttonClass }, 'Yes' ) ) ) ); }; _this.mql = window.matchMedia('(max-width: 992px)'); return _this; } /** * To trigger JavaScript changes on a breakpoint * @param {Object} mediaQueryList * @return {Boolean} whether the viewport is < or > than max-width 768px */ return ButtonConfirmation; }(_react.Component); ButtonConfirmation.defaultProps = { prompt: 'Are you sure?' }; ButtonConfirmation.propTypes = { /** * Optional styles to add to the button. */ optClass: _propTypes2.default.oneOfType([_propTypes2.default.array, _propTypes2.default.string]), /** * The size of button. */ size: _propTypes2.default.string, /** * Whether the button is disabled. */ disabled: _propTypes2.default.bool, /** * Whether to display only an icon on small screens */ collapse: _propTypes2.default.bool, /** * Position of the button on the page for overlay caret orientation when the screen size is tablet-sized or smaller */ position: _propTypes2.default.oneOf(['left', 'right']), /** * Text that will appear in the overlay prompt. */ prompt: _propTypes2.default.string, /** * Function used to pass up the confirmation to the parent component */ handleConfirmation: _propTypes2.default.func }; exports.default = ButtonConfirmation;