UNPKG

baseui

Version:

A React Component library implementing the Base design language

219 lines (209 loc) • 7.49 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.SnackbarContext = void 0; exports.default = SnackbarProvider; exports.useSnackbar = useSnackbar; var React = _interopRequireWildcard(require("react")); var _layer = require("../layer"); var _overrides = require("../helpers/overrides"); var _styles = require("../styles"); var _constants = require("./constants"); var _snackbarElement = _interopRequireDefault(require("./snackbar-element")); var _styledComponents = require("./styled-components"); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); } function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; } function _extends() { _extends = Object.assign ? Object.assign.bind() : 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; }; return _extends.apply(this, arguments); } /* Copyright (c) Uber Technologies, Inc. This source code is licensed under the MIT license found in the LICENSE file in the root directory of this source tree. */ function fallbackHandler() { if (process.env.NODE_ENV !== "production") { console.warn('Snackbar context not found.'); } } // @ts-ignore const SnackbarContext = exports.SnackbarContext = /*#__PURE__*/React.createContext({ enqueue: fallbackHandler, dequeue: fallbackHandler }); function useSnackbar() { const { enqueue, dequeue } = React.useContext(SnackbarContext); /* We use an empty dependency array because `enquque` and `dequeue` never change. Ideally we'd memoize these functions and include them in the dependency array, but that would require us to memoize many more functions in the SnackbarProvider, and those functions depend on eachother in a circular way. */ // eslint-disable-next-line react-hooks/exhaustive-deps return React.useMemo(() => ({ enqueue, dequeue }), []); } // @ts-ignore function usePrevious(value) { const ref = React.useRef(); React.useEffect(() => { ref.current = value; }); return ref.current; } function SnackbarProvider({ children, overrides = {}, placement, defaultDuration = _constants.DURATION.short }) { const [css] = (0, _styles.useStyletron)(); const [snackbars, setSnackbars] = React.useState([]); const [animating, setAnimating] = React.useState(false); const timeoutRef = React.useRef(null); const [containerHeight, setContainerHeight] = React.useState(0); const containerRef = React.useRef(null); // @ts-ignore function enqueue(elementProps, duration = defaultDuration) { // @ts-ignore setSnackbars(prev => { return [...prev, { elementProps, duration }]; }); } // @ts-ignore const prevSnackbars = usePrevious(snackbars) || []; React.useEffect(() => { if (prevSnackbars.length === 0 && snackbars.length >= 1) { // @ts-ignore enter(snackbars[0].duration); } }, [snackbars, prevSnackbars]); // @ts-ignore function enter(duration) { setAnimating(true); setTimeout(() => { setAnimating(false); display(duration); }, 0); } function dequeue() { setAnimating(true); setTimeout(() => { setAnimating(false); setContainerHeight(0); setSnackbars(prev => { const next = prev.slice(1); if (next.length > 0) { // @ts-ignore enter(next[0].duration); } return next; }); }, 1000); } // @ts-ignore function display(duration) { if (duration === _constants.DURATION.infinite) { return; } // @ts-ignore timeoutRef.current = setTimeout(() => { dequeue(); }, duration); } function handleMouseEnter() { // @ts-ignore clearTimeout(timeoutRef.current); } // @ts-ignore function handleMouseLeave(duration) { display(duration); } function handleActionClick() { // @ts-ignore clearTimeout(timeoutRef.current); dequeue(); } React.useEffect(() => { if (typeof document !== 'undefined') { if (window.ResizeObserver) { const observer = new window.ResizeObserver(([entry]) => setContainerHeight(entry.contentRect.height)); if (containerRef.current) { observer.observe(containerRef.current); } return () => observer.disconnect(); } } }, [snackbars.length, animating]); const translateHeight = React.useMemo(() => { const value = containerHeight * 2 + 24; if (!placement || placement === _constants.PLACEMENT.top || placement === _constants.PLACEMENT.topLeft || placement === _constants.PLACEMENT.topRight) { return -1 * value; } return value; }, [placement, containerHeight]); const { PlacementContainer: PlacementContainerOverrides, ...snackbarOverrides } = overrides; const [PlacementContainer, placementContainerProps] = (0, _overrides.getOverrides)(PlacementContainerOverrides, _styledComponents.StyledPlacementContainer); return /*#__PURE__*/React.createElement(SnackbarContext.Provider, { value: { enqueue, dequeue } }, /*#__PURE__*/React.createElement("div", { className: css({ boxSizing: 'border-box', position: 'absolute', top: '-10000px', left: '-10000px' }), ref: containerRef }, snackbars[0] && /*#__PURE__*/React.createElement(_snackbarElement.default // @ts-ignore , _extends({}, snackbars[0].elementProps, { overrides: { ...snackbarOverrides, // @ts-ignore ...snackbars[0].elementProps.overrides }, focus: false }))), snackbars.length > 0 && containerHeight !== 0 && /*#__PURE__*/React.createElement(_layer.Layer, null, /*#__PURE__*/React.createElement(PlacementContainer, _extends({ $animating: animating, $placement: placement, $translateHeight: translateHeight }, placementContainerProps), /*#__PURE__*/React.createElement("div", { role: "alert", onMouseEnter: handleMouseEnter // @ts-ignore , onMouseLeave: () => handleMouseLeave(snackbars[0].duration), className: css({ display: 'inline', pointerEvents: 'all' }) }, /*#__PURE__*/React.createElement(_snackbarElement.default // @ts-ignore , _extends({}, snackbars[0].elementProps, { actionOnClick: event => { // @ts-ignore if (snackbars[0].elementProps.actionOnClick) { // @ts-ignore snackbars[0].elementProps.actionOnClick(event); } handleActionClick(); }, overrides: { ...snackbarOverrides, // @ts-ignore ...snackbars[0].elementProps.overrides } }))))), children); }