baseui
Version:
A React Component library implementing the Base design language
219 lines (209 loc) • 7.49 kB
JavaScript
;
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);
}