UNPKG

5.46 kBJavaScriptView Raw
1import _extends from "@babel/runtime/helpers/esm/extends";
2import * as React from 'react';
3import { unstable_useEventCallback as useEventCallback } from '@mui/utils';
4import extractEventHandlers from '../utils/extractEventHandlers';
5
6/**
7 * The basic building block for creating custom snackbar.
8 *
9 * Demos:
10 *
11 * - [Snackbar](https://mui.com/base/react-snackbar/#hook)
12 *
13 * API:
14 *
15 * - [useSnackbar API](https://mui.com/base/react-snackbar/hooks-api/#use-snackbar)
16 */
17export default function useSnackbar(parameters) {
18 var _parameters$autoHideD = parameters.autoHideDuration,
19 autoHideDuration = _parameters$autoHideD === void 0 ? null : _parameters$autoHideD,
20 _parameters$disableWi = parameters.disableWindowBlurListener,
21 disableWindowBlurListener = _parameters$disableWi === void 0 ? false : _parameters$disableWi,
22 onClose = parameters.onClose,
23 open = parameters.open,
24 resumeHideDuration = parameters.resumeHideDuration;
25 var timerAutoHide = React.useRef();
26 React.useEffect(function () {
27 if (!open) {
28 return undefined;
29 }
30
31 /**
32 * @param {KeyboardEvent} nativeEvent
33 */
34 function handleKeyDown(nativeEvent) {
35 if (!nativeEvent.defaultPrevented) {
36 // IE11, Edge (prior to using Blink?) use 'Esc'
37 if (nativeEvent.key === 'Escape' || nativeEvent.key === 'Esc') {
38 // not calling `preventDefault` since we don't know if people may ignore this event e.g. a permanently open snackbar
39 onClose == null ? void 0 : onClose(nativeEvent, 'escapeKeyDown');
40 }
41 }
42 }
43 document.addEventListener('keydown', handleKeyDown);
44 return function () {
45 document.removeEventListener('keydown', handleKeyDown);
46 };
47 }, [open, onClose]);
48 var handleClose = useEventCallback(function (event, reason) {
49 onClose == null ? void 0 : onClose(event, reason);
50 });
51 var setAutoHideTimer = useEventCallback(function (autoHideDurationParam) {
52 if (!onClose || autoHideDurationParam == null) {
53 return;
54 }
55 clearTimeout(timerAutoHide.current);
56 timerAutoHide.current = setTimeout(function () {
57 handleClose(null, 'timeout');
58 }, autoHideDurationParam);
59 });
60 React.useEffect(function () {
61 if (open) {
62 setAutoHideTimer(autoHideDuration);
63 }
64 return function () {
65 clearTimeout(timerAutoHide.current);
66 };
67 }, [open, autoHideDuration, setAutoHideTimer]);
68 var handleClickAway = function handleClickAway(event) {
69 onClose == null ? void 0 : onClose(event, 'clickaway');
70 };
71
72 // Pause the timer when the user is interacting with the Snackbar
73 // or when the user hide the window.
74 var handlePause = function handlePause() {
75 clearTimeout(timerAutoHide.current);
76 };
77
78 // Restart the timer when the user is no longer interacting with the Snackbar
79 // or when the window is shown back.
80 var handleResume = React.useCallback(function () {
81 if (autoHideDuration != null) {
82 setAutoHideTimer(resumeHideDuration != null ? resumeHideDuration : autoHideDuration * 0.5);
83 }
84 }, [autoHideDuration, resumeHideDuration, setAutoHideTimer]);
85 var createHandleBlur = function createHandleBlur(otherHandlers) {
86 return function (event) {
87 var onBlurCallback = otherHandlers.onBlur;
88 onBlurCallback == null ? void 0 : onBlurCallback(event);
89 handleResume();
90 };
91 };
92 var createHandleFocus = function createHandleFocus(otherHandlers) {
93 return function (event) {
94 var onFocusCallback = otherHandlers.onFocus;
95 onFocusCallback == null ? void 0 : onFocusCallback(event);
96 handlePause();
97 };
98 };
99 var createMouseEnter = function createMouseEnter(otherHandlers) {
100 return function (event) {
101 var onMouseEnterCallback = otherHandlers.onMouseEnter;
102 onMouseEnterCallback == null ? void 0 : onMouseEnterCallback(event);
103 handlePause();
104 };
105 };
106 var createMouseLeave = function createMouseLeave(otherHandlers) {
107 return function (event) {
108 var onMouseLeaveCallback = otherHandlers.onMouseLeave;
109 onMouseLeaveCallback == null ? void 0 : onMouseLeaveCallback(event);
110 handleResume();
111 };
112 };
113 React.useEffect(function () {
114 // TODO: window global should be refactored here
115 if (!disableWindowBlurListener && open) {
116 window.addEventListener('focus', handleResume);
117 window.addEventListener('blur', handlePause);
118 return function () {
119 window.removeEventListener('focus', handleResume);
120 window.removeEventListener('blur', handlePause);
121 };
122 }
123 return undefined;
124 }, [disableWindowBlurListener, handleResume, open]);
125 var getRootProps = function getRootProps() {
126 var otherHandlers = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
127 var propsEventHandlers = extractEventHandlers(parameters);
128 var externalEventHandlers = _extends({}, propsEventHandlers, otherHandlers);
129 return _extends({
130 // ClickAwayListener adds an `onClick` prop which results in the alert not being announced.
131 // See https://github.com/mui/material-ui/issues/29080
132 role: 'presentation'
133 }, externalEventHandlers, {
134 onBlur: createHandleBlur(externalEventHandlers),
135 onFocus: createHandleFocus(externalEventHandlers),
136 onMouseEnter: createMouseEnter(externalEventHandlers),
137 onMouseLeave: createMouseLeave(externalEventHandlers)
138 });
139 };
140 return {
141 getRootProps: getRootProps,
142 onClickAway: handleClickAway
143 };
144}
\No newline at end of file