UNPKG

react-toast-notifications

Version:

A configurable, composable, toast notification system for react.

319 lines (277 loc) 10.2 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.DefaultToast = exports.shrinkKeyframes = exports.toastWidth = exports.gutter = exports.borderRadius = undefined; var _slicedToArray = function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"]) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } }; }(); 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 _templateObject = _taggedTemplateLiteral(['from { height: 100%; } to { height: 0% }'], ['from { height: 100%; } to { height: 0% }']); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _core = require('@emotion/core'); var _icons = require('./icons'); var _colors = require('./colors'); var colors = _interopRequireWildcard(_colors); var _utils = require('./utils'); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } 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 _taggedTemplateLiteral(strings, raw) { return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); } /** @jsx jsx */ // common var borderRadius = exports.borderRadius = 4; var gutter = exports.gutter = 8; var toastWidth = exports.toastWidth = 360; var shrinkKeyframes = exports.shrinkKeyframes = (0, _core.keyframes)(_templateObject); // a11y helper var A11yText = function A11yText(_ref) { var Tag = _ref.tag, props = _objectWithoutProperties(_ref, ['tag']); return (0, _core.jsx)(Tag, _extends({ css: { border: 0, clip: 'rect(1px, 1px, 1px, 1px)', height: 1, overflow: 'hidden', padding: 0, position: 'absolute', whiteSpace: 'nowrap', width: 1 } }, props)); }; A11yText.defaultProps = { tag: 'span' }; // default appearances var appearances = { success: { icon: _icons.CheckIcon, text: colors.G500, fg: colors.G300, bg: colors.G50 }, error: { icon: _icons.FlameIcon, text: colors.R500, fg: colors.R300, bg: colors.R50 }, warning: { icon: _icons.AlertIcon, text: colors.Y500, fg: colors.Y300, bg: colors.Y50 }, info: { icon: _icons.InfoIcon, text: colors.N400, fg: colors.B200, bg: 'white' } }; var Button = function Button(props) { return (0, _core.jsx)('div', _extends({ role: 'button', className: 'react-toast-notifications__toast__dismiss-button', css: { cursor: 'pointer', flexShrink: 0, opacity: 0.5, padding: gutter + 'px ' + gutter * 1.5 + 'px', transition: 'opacity 150ms', ':hover': { opacity: 1 } } }, props)); }; var Content = function Content(props) { return (0, _core.jsx)('div', _extends({ className: 'react-toast-notifications__toast__content', css: { flexGrow: 1, fontSize: 14, lineHeight: 1.4, minHeight: 40, padding: gutter + 'px ' + gutter * 1.5 + 'px' } }, props)); }; // NOTE: invoke animation when NOT `autoDismiss` with opacity of 0 to avoid a // paint bug in FireFox. // https://bugzilla.mozilla.org/show_bug.cgi?id=625289 var Countdown = function Countdown(_ref2) { var autoDismissTimeout = _ref2.autoDismissTimeout, opacity = _ref2.opacity, isRunning = _ref2.isRunning, props = _objectWithoutProperties(_ref2, ['autoDismissTimeout', 'opacity', 'isRunning']); return (0, _core.jsx)('div', _extends({ className: 'react-toast-notifications__toast__countdown', css: { animation: shrinkKeyframes + ' ' + autoDismissTimeout + 'ms linear', animationPlayState: isRunning ? 'running' : 'paused', backgroundColor: 'rgba(0,0,0,0.1)', bottom: 0, height: 0, left: 0, opacity: opacity, position: 'absolute', width: '100%' } }, props)); }; var Icon = function Icon(_ref3) { var appearance = _ref3.appearance, autoDismiss = _ref3.autoDismiss, autoDismissTimeout = _ref3.autoDismissTimeout, isRunning = _ref3.isRunning; var meta = appearances[appearance]; var Glyph = meta.icon; return (0, _core.jsx)( 'div', { className: 'react-toast-notifications__toast__icon-wrapper', css: { backgroundColor: meta.fg, borderTopLeftRadius: borderRadius, borderBottomLeftRadius: borderRadius, color: meta.bg, flexShrink: 0, paddingBottom: gutter, paddingTop: gutter, position: 'relative', overflow: 'hidden', textAlign: 'center', width: 30 } }, (0, _core.jsx)(Countdown, { opacity: autoDismiss ? 1 : 0, autoDismissTimeout: autoDismissTimeout, isRunning: isRunning }), (0, _core.jsx)(Glyph, { className: 'react-toast-notifications__toast__icon', css: { position: 'relative', zIndex: 1 } }) ); }; // Transitions // ------------------------------ function getTranslate(placement) { var pos = placement.split('-'); var relevantPlacement = pos[1] === 'center' ? pos[0] : pos[1]; var translateMap = { right: 'translate3d(120%, 0, 0)', left: 'translate3d(-120%, 0, 0)', bottom: 'translate3d(0, 120%, 0)', top: 'translate3d(0, -120%, 0)' }; return translateMap[relevantPlacement]; } var toastStates = function toastStates(placement) { return { entering: { transform: getTranslate(placement) }, entered: { transform: 'translate3d(0,0,0)' }, exiting: { transform: 'scale(0.66)', opacity: 0 }, exited: { transform: 'scale(0.66)', opacity: 0 } }; }; var ToastElement = function ToastElement(_ref4) { var appearance = _ref4.appearance, placement = _ref4.placement, transitionDuration = _ref4.transitionDuration, transitionState = _ref4.transitionState, props = _objectWithoutProperties(_ref4, ['appearance', 'placement', 'transitionDuration', 'transitionState']); var _useState = (0, _react.useState)('auto'), _useState2 = _slicedToArray(_useState, 2), height = _useState2[0], setHeight = _useState2[1]; var elementRef = (0, _react.useRef)(null); (0, _react.useEffect)(function () { if (transitionState === 'entered') { var el = elementRef.current; setHeight(el.offsetHeight + gutter); } if (transitionState === 'exiting') { setHeight(0); } }, [transitionState]); return (0, _core.jsx)( 'div', { ref: elementRef, style: { height: height }, css: { transition: 'height ' + (transitionDuration - 100) + 'ms 100ms' } }, (0, _core.jsx)('div', _extends({ className: 'react-toast-notifications__toast react-toast-notifications__toast--' + appearance, css: _extends({ backgroundColor: appearances[appearance].bg, borderRadius: borderRadius, boxShadow: '0 3px 8px rgba(0, 0, 0, 0.175)', color: appearances[appearance].text, display: 'flex', marginBottom: gutter, maxWidth: '100%', transition: 'transform ' + transitionDuration + 'ms cubic-bezier(0.2, 0, 0, 1), opacity ' + transitionDuration + 'ms', width: toastWidth }, toastStates(placement)[transitionState]) }, props)) ); }; // ============================== // DefaultToast // ============================== var DefaultToast = function DefaultToast(_ref5) { var _ref5$appearance = _ref5.appearance, appearance = _ref5$appearance === undefined ? 'info' : _ref5$appearance, autoDismiss = _ref5.autoDismiss, autoDismissTimeout = _ref5.autoDismissTimeout, children = _ref5.children, isRunning = _ref5.isRunning, onDismiss = _ref5.onDismiss, placement = _ref5.placement, transitionDuration = _ref5.transitionDuration, transitionState = _ref5.transitionState, onMouseEnter = _ref5.onMouseEnter, onMouseLeave = _ref5.onMouseLeave, otherProps = _objectWithoutProperties(_ref5, ['appearance', 'autoDismiss', 'autoDismissTimeout', 'children', 'isRunning', 'onDismiss', 'placement', 'transitionDuration', 'transitionState', 'onMouseEnter', 'onMouseLeave']); return (0, _core.jsx)( ToastElement, _extends({ appearance: appearance, placement: placement, transitionState: transitionState, transitionDuration: transitionDuration, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave }, otherProps), (0, _core.jsx)(Icon, { appearance: appearance, autoDismiss: autoDismiss, autoDismissTimeout: autoDismissTimeout, isRunning: isRunning }), (0, _core.jsx)( Content, null, children ), onDismiss ? (0, _core.jsx)( Button, { onClick: onDismiss }, (0, _core.jsx)(_icons.CloseIcon, { className: 'react-toast-notifications__toast__dismiss-icon' }), (0, _core.jsx)( A11yText, { className: 'react-toast-notifications__toast__dismiss-text' }, 'Close' ) ) : null ); }; exports.DefaultToast = DefaultToast; DefaultToast.defaultProps = { onDismiss: _utils.NOOP };