@sprinklrjs/spaceweb 14.12.2 → 14.12.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/a11y/StatusMessage.d.ts +1 -1
- package/a11y/StatusMessage.js +2 -2
- package/a11y/types.d.ts +5 -0
- package/esm/a11y/StatusMessage.d.ts +1 -1
- package/esm/a11y/StatusMessage.js +2 -2
- package/esm/a11y/types.d.ts +5 -0
- package/esm/menu/menu-item.js +1 -1
- package/esm/snackbar/Snackbar.d.ts +1 -1
- package/esm/snackbar/Snackbar.js +5 -10
- package/esm/snackbar/snackbarContext.d.ts +1 -1
- package/esm/snackbar/snackbarContext.js +7 -2
- package/esm/snackbar/types.d.ts +6 -0
- package/esm/snackbar/useSnackbar.d.ts +2 -1
- package/esm/snackbar/useSnackbar.js +12 -5
- package/menu/menu-item.js +1 -1
- package/package.json +2 -2
- package/snackbar/Snackbar.d.ts +1 -1
- package/snackbar/Snackbar.js +5 -10
- package/snackbar/snackbarContext.d.ts +1 -1
- package/snackbar/snackbarContext.js +7 -2
- package/snackbar/types.d.ts +6 -0
- package/snackbar/useSnackbar.d.ts +2 -1
- package/snackbar/useSnackbar.js +12 -5
- package/tsconfig.build.tsbuildinfo +1 -1
package/a11y/StatusMessage.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { StatusMessageProps } from './types';
|
|
2
2
|
export declare const StatusMessage: {
|
|
3
|
-
({ children, politeness, timeout }: StatusMessageProps): null;
|
|
3
|
+
({ children, politeness, timeout, id }: StatusMessageProps): null;
|
|
4
4
|
displayName: string;
|
|
5
5
|
__standard: string;
|
|
6
6
|
};
|
package/a11y/StatusMessage.js
CHANGED
|
@@ -4,12 +4,12 @@ exports.StatusMessage = void 0;
|
|
|
4
4
|
var react_1 = require("react");
|
|
5
5
|
var LiveAnnouncer_1 = require("./LiveAnnouncer");
|
|
6
6
|
var StatusMessage = function (_a) {
|
|
7
|
-
var children = _a.children, politeness = _a.politeness, timeout = _a.timeout;
|
|
7
|
+
var children = _a.children, politeness = _a.politeness, timeout = _a.timeout, id = _a.id;
|
|
8
8
|
(0, react_1.useEffect)(function () {
|
|
9
9
|
if (children) {
|
|
10
10
|
(0, LiveAnnouncer_1.announce)(children, { politeness: politeness, timeout: timeout });
|
|
11
11
|
}
|
|
12
|
-
}, [children, politeness, timeout]);
|
|
12
|
+
}, [children, politeness, timeout, id]);
|
|
13
13
|
return null;
|
|
14
14
|
};
|
|
15
15
|
exports.StatusMessage = StatusMessage;
|
package/a11y/types.d.ts
CHANGED
|
@@ -20,4 +20,9 @@ export type StatusMessageProps = AnnounceOptions & {
|
|
|
20
20
|
* visible output and adds nothing to the layout.
|
|
21
21
|
*/
|
|
22
22
|
children?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Opaque instance identity. Bump this when re-announcing the same `children`
|
|
25
|
+
* string (e.g. increment a counter on each copy action).
|
|
26
|
+
*/
|
|
27
|
+
id?: string | number;
|
|
23
28
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { StatusMessageProps } from './types';
|
|
2
2
|
export declare const StatusMessage: {
|
|
3
|
-
({ children, politeness, timeout }: StatusMessageProps): null;
|
|
3
|
+
({ children, politeness, timeout, id }: StatusMessageProps): null;
|
|
4
4
|
displayName: string;
|
|
5
5
|
__standard: string;
|
|
6
6
|
};
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { useEffect } from 'react';
|
|
2
2
|
import { announce } from './LiveAnnouncer';
|
|
3
3
|
export var StatusMessage = function (_a) {
|
|
4
|
-
var children = _a.children, politeness = _a.politeness, timeout = _a.timeout;
|
|
4
|
+
var children = _a.children, politeness = _a.politeness, timeout = _a.timeout, id = _a.id;
|
|
5
5
|
useEffect(function () {
|
|
6
6
|
if (children) {
|
|
7
7
|
announce(children, { politeness: politeness, timeout: timeout });
|
|
8
8
|
}
|
|
9
|
-
}, [children, politeness, timeout]);
|
|
9
|
+
}, [children, politeness, timeout, id]);
|
|
10
10
|
return null;
|
|
11
11
|
};
|
|
12
12
|
StatusMessage.displayName = 'StatusMessage';
|
package/esm/a11y/types.d.ts
CHANGED
|
@@ -20,4 +20,9 @@ export type StatusMessageProps = AnnounceOptions & {
|
|
|
20
20
|
* visible output and adds nothing to the layout.
|
|
21
21
|
*/
|
|
22
22
|
children?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Opaque instance identity. Bump this when re-announcing the same `children`
|
|
25
|
+
* string (e.g. increment a counter on each copy action).
|
|
26
|
+
*/
|
|
27
|
+
id?: string | number;
|
|
23
28
|
};
|
package/esm/menu/menu-item.js
CHANGED
|
@@ -81,7 +81,7 @@ function MenuActionContainer(_a) {
|
|
|
81
81
|
// Only show actions that are always visible or whose parent item is highlighted
|
|
82
82
|
className: [
|
|
83
83
|
index === 0 ? 'ml-0' : 'ml-1',
|
|
84
|
-
alwaysVisible || sharedProps.$highlighted ? 'visible' : 'invisible w-0 ml-0',
|
|
84
|
+
alwaysVisible || sharedProps.$highlighted ? 'visible' : 'invisible w-0 overflow-hidden ml-0',
|
|
85
85
|
] }, { children: React.cloneElement(actionEl, { tabIndex: -1 }) }), (_a = actionEl.key) !== null && _a !== void 0 ? _a : "menu-action-".concat(index)));
|
|
86
86
|
}) })));
|
|
87
87
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import type { SnackbarProps } from './types';
|
|
3
3
|
declare const Snackbar: {
|
|
4
|
-
({ intent: _intent, message: _message, disableManualClose, placement, autoHide, autoHideDuration, hideOnClickAway, overrides: _overrides, onClose, }: SnackbarProps): ReactElement | null;
|
|
4
|
+
({ intent: _intent, message: _message, id, disableManualClose, placement, autoHide, autoHideDuration, hideOnClickAway, overrides: _overrides, onClose, }: SnackbarProps): ReactElement | null;
|
|
5
5
|
__standard: string;
|
|
6
6
|
};
|
|
7
7
|
export default Snackbar;
|
package/esm/snackbar/Snackbar.js
CHANGED
|
@@ -19,11 +19,12 @@ import { useLocale } from '../locale';
|
|
|
19
19
|
import { useStyle } from '../style';
|
|
20
20
|
import { ThemeProvider } from '../theme';
|
|
21
21
|
var Snackbar = function (_a) {
|
|
22
|
-
var _b = _a.intent, _intent = _b === void 0 ? 'success' : _b, _message = _a.message, _c = _a.disableManualClose, disableManualClose = _c === void 0 ? false : _c, _d = _a.placement, placement = _d === void 0 ? 'bottom' : _d, _e = _a.autoHide, autoHide = _e === void 0 ? true : _e, _f = _a.autoHideDuration, autoHideDuration = _f === void 0 ? TYPE_TO_HIDE_DURATION[_intent] : _f, _g = _a.hideOnClickAway, hideOnClickAway = _g === void 0 ? true : _g, _overrides = _a.overrides, _h = _a.onClose, onClose = _h === void 0 ? _noop : _h;
|
|
22
|
+
var _b = _a.intent, _intent = _b === void 0 ? 'success' : _b, _message = _a.message, id = _a.id, _c = _a.disableManualClose, disableManualClose = _c === void 0 ? false : _c, _d = _a.placement, placement = _d === void 0 ? 'bottom' : _d, _e = _a.autoHide, autoHide = _e === void 0 ? true : _e, _f = _a.autoHideDuration, autoHideDuration = _f === void 0 ? TYPE_TO_HIDE_DURATION[_intent] : _f, _g = _a.hideOnClickAway, hideOnClickAway = _g === void 0 ? true : _g, _overrides = _a.overrides, _h = _a.onClose, onClose = _h === void 0 ? _noop : _h;
|
|
23
23
|
var outerTheme = useStyle().theme;
|
|
24
24
|
var inverseTheme = useMemo(function () { return (isDarkTheme(outerTheme) ? hyperspaceLight : hyperspaceDark); }, [outerTheme]);
|
|
25
25
|
var _j = useSnackbar({
|
|
26
26
|
intent: _intent,
|
|
27
|
+
id: id,
|
|
27
28
|
message: _message,
|
|
28
29
|
overrides: _overrides,
|
|
29
30
|
autoHide: autoHide,
|
|
@@ -52,18 +53,12 @@ var Snackbar = function (_a) {
|
|
|
52
53
|
var _s = __read(useOverrides(overrides === null || overrides === void 0 ? void 0 : overrides.CloseIcon, CloseIcon), 2), Close = _s[0], closeProps = _s[1];
|
|
53
54
|
var _t = __read(useOverrides(overrides === null || overrides === void 0 ? void 0 : overrides.CloseIconButton, IconButton), 2), CloseIconButton = _t[0], closeIconButtonProps = _t[1];
|
|
54
55
|
var locale = useLocale();
|
|
55
|
-
var role = INTENT_TO_ROLE[intent];
|
|
56
|
-
// We don't know if the message contains any interactive elements, so we only
|
|
57
|
-
// delegate to the shared screen-reader announcer when the message is a string.
|
|
58
56
|
var isStringMessage = typeof message === 'string';
|
|
59
|
-
// Announce string messages through the shared global live region instead of
|
|
60
|
-
// hand-rolling sr-only regions here. The announcer keeps a single source of
|
|
61
|
-
// truth for status messages (WCAG 4.1.3) and re-announces repeated text.
|
|
62
57
|
useEffect(function () {
|
|
63
|
-
if (
|
|
64
|
-
announce(
|
|
58
|
+
if (typeof _message === 'string' && _message) {
|
|
59
|
+
announce(_message, { politeness: INTENT_TO_ROLE[_intent] === 'alert' ? 'assertive' : 'polite' });
|
|
65
60
|
}
|
|
66
|
-
}, [
|
|
61
|
+
}, [_message, _intent, id]);
|
|
67
62
|
return (_jsx(_Fragment, { children: shouldRender ? (_jsx(LayersManager, __assign({ zIndex: Z_INDEX.SNACKBAR }, { children: _jsx(Layer, __assign({}, sharedProps, layerProps, { children: _jsx(PlacementContainer, __assign({ "data-spaceweb": "snackbar", "data-testid": "snackbar" }, sharedProps, placementContainerProps, { children: _jsx(SnackbarContainer, __assign({}, snackbarContainerProps, { ref: snackbarContainerRef }, sharedProps, snackbarContainerOverrideProps, { style: [getSnackbarContainerAnimationStyle, snackbarContainerOverrideProps.style] }, { children: _jsx(ThemeProvider, __assign({ theme: inverseTheme }, { children: _jsxs(ContentContainer, __assign({}, sharedProps, contentContainerProps, { children: [_jsx(IconsContainer, __assign({}, sharedProps, iconsContainerProps, { children: _jsx(IntentIcon, __assign({ size: 20, className: getIconStyles }, sharedProps, intentIconProps)) })), _jsx(Message
|
|
68
63
|
// The sr-only region handles screen reader announcements
|
|
69
64
|
// to prevent the message from being read twice
|
|
@@ -10,14 +10,19 @@ export var SnackbarProvider = function (_a) {
|
|
|
10
10
|
var children = _a.children;
|
|
11
11
|
var _b = __read(useState(''), 2), message = _b[0], setMessage = _b[1];
|
|
12
12
|
var _c = __read(useState('success'), 2), intent = _c[0], setIntent = _c[1];
|
|
13
|
+
var _d = __read(useState(0), 2), id = _d[0], setId = _d[1];
|
|
13
14
|
var notify = useCallback(function (_a) {
|
|
14
15
|
var _b = _a.intent, _intent = _b === void 0 ? 'success' : _b, _message = _a.message;
|
|
16
|
+
setId(function (prev) { return prev + 1; });
|
|
15
17
|
setMessage(_message);
|
|
16
18
|
setIntent(_intent);
|
|
17
19
|
}, []);
|
|
18
|
-
var onClose = useCallback(function () {
|
|
20
|
+
var onClose = useCallback(function (reason) {
|
|
21
|
+
// Keep content when swapping instances; only clear on real dismiss.
|
|
22
|
+
if (reason === 'messageChange')
|
|
23
|
+
return;
|
|
19
24
|
setMessage('');
|
|
20
25
|
setIntent('success');
|
|
21
26
|
}, []);
|
|
22
|
-
return (_jsxs(_Fragment, { children: [_jsx(SnackbarContext.Provider, __assign({ value: notify }, { children: children })), message && intent ? _jsx(Snackbar, { message: message, intent: intent, onClose: onClose }) : null] }));
|
|
27
|
+
return (_jsxs(_Fragment, { children: [_jsx(SnackbarContext.Provider, __assign({ value: notify }, { children: children })), message && intent ? _jsx(Snackbar, { id: id, message: message, intent: intent, onClose: onClose }) : null] }));
|
|
23
28
|
};
|
package/esm/snackbar/types.d.ts
CHANGED
|
@@ -26,6 +26,12 @@ export type SnackbarOverrides = {
|
|
|
26
26
|
};
|
|
27
27
|
export type SnackbarProps = {
|
|
28
28
|
message?: React.ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* Opaque instance identity. Bump this (e.g. increment a counter) when re-showing
|
|
31
|
+
* the same `message` so the snackbar re-opens and re-announces for screen readers.
|
|
32
|
+
* `SnackbarProvider` / `useNotification` set this automatically on every `notify()`.
|
|
33
|
+
*/
|
|
34
|
+
id?: string | number;
|
|
29
35
|
intent?: Intent;
|
|
30
36
|
hideOnClickAway?: boolean;
|
|
31
37
|
disableManualClose?: boolean;
|
|
@@ -5,6 +5,7 @@ type UseSnackbarParams = {
|
|
|
5
5
|
autoHideDuration: number;
|
|
6
6
|
hideOnClickAway: boolean;
|
|
7
7
|
intent: Intent;
|
|
8
|
+
id?: string | number;
|
|
8
9
|
message?: React.ReactNode;
|
|
9
10
|
onClose?: (reason: HideReason) => void;
|
|
10
11
|
overrides?: SnackbarOverrides;
|
|
@@ -23,5 +24,5 @@ type UseSnackbarReturnValue = {
|
|
|
23
24
|
intent: Intent;
|
|
24
25
|
overrides?: SnackbarOverrides;
|
|
25
26
|
};
|
|
26
|
-
declare const useSnackbar: ({ autoHide, autoHideDuration, hideOnClickAway, intent: nextIntent, message: nextMessage, onClose, overrides: nextOverrides, }: UseSnackbarParams) => UseSnackbarReturnValue;
|
|
27
|
+
declare const useSnackbar: ({ autoHide, autoHideDuration, hideOnClickAway, intent: nextIntent, id, message: nextMessage, onClose, overrides: nextOverrides, }: UseSnackbarParams) => UseSnackbarReturnValue;
|
|
27
28
|
export default useSnackbar;
|
|
@@ -33,10 +33,10 @@ var useAutoHide = function (_a) {
|
|
|
33
33
|
}, [open, autoHide, autoHideDuration, autoHideTimeoutRef]);
|
|
34
34
|
};
|
|
35
35
|
var useDomVisibility = function (_a) {
|
|
36
|
-
var message = _a.message, open = _a.open, enter = _a.enter, handleClose = _a.handleClose, intent = _a.intent;
|
|
36
|
+
var message = _a.message, open = _a.open, enter = _a.enter, handleClose = _a.handleClose, intent = _a.intent, id = _a.id;
|
|
37
37
|
var _b = __read(useState(false), 2), domVisibility = _b[0], setDomVisibility = _b[1];
|
|
38
38
|
var removeFromDomTimeoutRef = useRef();
|
|
39
|
-
// handle exit, enter on message change
|
|
39
|
+
// handle exit, enter on message / intent / id change
|
|
40
40
|
useEffect(function () {
|
|
41
41
|
if (!message)
|
|
42
42
|
return undefined;
|
|
@@ -51,7 +51,7 @@ var useDomVisibility = function (_a) {
|
|
|
51
51
|
open && handleClose('messageChange');
|
|
52
52
|
return function () { return window.clearTimeout(timeoutId); };
|
|
53
53
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- handleClose not required
|
|
54
|
-
}, [message, intent]);
|
|
54
|
+
}, [message, intent, id]);
|
|
55
55
|
// remove from DOM, once transition is over
|
|
56
56
|
useUpdateEffect(function () {
|
|
57
57
|
if (open)
|
|
@@ -64,7 +64,7 @@ var useDomVisibility = function (_a) {
|
|
|
64
64
|
return domVisibility;
|
|
65
65
|
};
|
|
66
66
|
var useSnackbar = function (_a) {
|
|
67
|
-
var autoHide = _a.autoHide, autoHideDuration = _a.autoHideDuration, hideOnClickAway = _a.hideOnClickAway, nextIntent = _a.intent, nextMessage = _a.message, onClose = _a.onClose, nextOverrides = _a.overrides;
|
|
67
|
+
var autoHide = _a.autoHide, autoHideDuration = _a.autoHideDuration, hideOnClickAway = _a.hideOnClickAway, nextIntent = _a.intent, id = _a.id, nextMessage = _a.message, onClose = _a.onClose, nextOverrides = _a.overrides;
|
|
68
68
|
var _b = __read(useState(false), 2), open = _b[0], setOpen = _b[1];
|
|
69
69
|
var _c = __read(useState({
|
|
70
70
|
intent: nextIntent,
|
|
@@ -89,7 +89,14 @@ var useSnackbar = function (_a) {
|
|
|
89
89
|
};
|
|
90
90
|
useAutoHide({ open: open, handleClose: handleClose, autoHideTimeoutRef: autoHideTimeoutRef, autoHideDuration: autoHideDuration, autoHide: autoHide });
|
|
91
91
|
var snackbarContainerRef = useHideOnClickAway({ hideOnClickAway: hideOnClickAway, handleClose: handleClose, open: open });
|
|
92
|
-
var shouldRender = useDomVisibility({
|
|
92
|
+
var shouldRender = useDomVisibility({
|
|
93
|
+
handleClose: handleClose,
|
|
94
|
+
open: open,
|
|
95
|
+
intent: nextIntent,
|
|
96
|
+
id: id,
|
|
97
|
+
message: nextMessage,
|
|
98
|
+
enter: enter,
|
|
99
|
+
});
|
|
93
100
|
var handleMouseEnter = function () {
|
|
94
101
|
window.clearTimeout(autoHideTimeoutRef.current);
|
|
95
102
|
};
|
package/menu/menu-item.js
CHANGED
|
@@ -83,7 +83,7 @@ function MenuActionContainer(_a) {
|
|
|
83
83
|
// Only show actions that are always visible or whose parent item is highlighted
|
|
84
84
|
className: [
|
|
85
85
|
index === 0 ? 'ml-0' : 'ml-1',
|
|
86
|
-
alwaysVisible || sharedProps.$highlighted ? 'visible' : 'invisible w-0 ml-0',
|
|
86
|
+
alwaysVisible || sharedProps.$highlighted ? 'visible' : 'invisible w-0 overflow-hidden ml-0',
|
|
87
87
|
] }, { children: React.cloneElement(actionEl, { tabIndex: -1 }) }), (_a = actionEl.key) !== null && _a !== void 0 ? _a : "menu-action-".concat(index)));
|
|
88
88
|
}) })));
|
|
89
89
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sprinklrjs/spaceweb",
|
|
3
|
-
"version": "14.12.
|
|
3
|
+
"version": "14.12.3",
|
|
4
4
|
"description": "Components for SpaceWeb",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"module": "./esm/index.js",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"ts-node": "^10.4.0"
|
|
101
101
|
},
|
|
102
102
|
"peerDependencies": {
|
|
103
|
-
"@sprinklrjs/spaceweb-themes": "14.12.
|
|
103
|
+
"@sprinklrjs/spaceweb-themes": "14.12.3",
|
|
104
104
|
"react": ">=17.0.2 <19.0.0",
|
|
105
105
|
"react-dom": ">=17.0.2 <19.0.0"
|
|
106
106
|
}
|
package/snackbar/Snackbar.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import type { SnackbarProps } from './types';
|
|
3
3
|
declare const Snackbar: {
|
|
4
|
-
({ intent: _intent, message: _message, disableManualClose, placement, autoHide, autoHideDuration, hideOnClickAway, overrides: _overrides, onClose, }: SnackbarProps): ReactElement | null;
|
|
4
|
+
({ intent: _intent, message: _message, id, disableManualClose, placement, autoHide, autoHideDuration, hideOnClickAway, overrides: _overrides, onClose, }: SnackbarProps): ReactElement | null;
|
|
5
5
|
__standard: string;
|
|
6
6
|
};
|
|
7
7
|
export default Snackbar;
|
package/snackbar/Snackbar.js
CHANGED
|
@@ -21,11 +21,12 @@ var locale_1 = require("../locale");
|
|
|
21
21
|
var style_1 = require("../style");
|
|
22
22
|
var theme_1 = require("../theme");
|
|
23
23
|
var Snackbar = function (_a) {
|
|
24
|
-
var _b = _a.intent, _intent = _b === void 0 ? 'success' : _b, _message = _a.message, _c = _a.disableManualClose, disableManualClose = _c === void 0 ? false : _c, _d = _a.placement, placement = _d === void 0 ? 'bottom' : _d, _e = _a.autoHide, autoHide = _e === void 0 ? true : _e, _f = _a.autoHideDuration, autoHideDuration = _f === void 0 ? constants_1.TYPE_TO_HIDE_DURATION[_intent] : _f, _g = _a.hideOnClickAway, hideOnClickAway = _g === void 0 ? true : _g, _overrides = _a.overrides, _h = _a.onClose, onClose = _h === void 0 ? noop_1.default : _h;
|
|
24
|
+
var _b = _a.intent, _intent = _b === void 0 ? 'success' : _b, _message = _a.message, id = _a.id, _c = _a.disableManualClose, disableManualClose = _c === void 0 ? false : _c, _d = _a.placement, placement = _d === void 0 ? 'bottom' : _d, _e = _a.autoHide, autoHide = _e === void 0 ? true : _e, _f = _a.autoHideDuration, autoHideDuration = _f === void 0 ? constants_1.TYPE_TO_HIDE_DURATION[_intent] : _f, _g = _a.hideOnClickAway, hideOnClickAway = _g === void 0 ? true : _g, _overrides = _a.overrides, _h = _a.onClose, onClose = _h === void 0 ? noop_1.default : _h;
|
|
25
25
|
var outerTheme = (0, style_1.useStyle)().theme;
|
|
26
26
|
var inverseTheme = (0, react_1.useMemo)(function () { return ((0, themeHelpers_1.isDarkTheme)(outerTheme) ? light_1.default : dark_1.default); }, [outerTheme]);
|
|
27
27
|
var _j = (0, useSnackbar_1.default)({
|
|
28
28
|
intent: _intent,
|
|
29
|
+
id: id,
|
|
29
30
|
message: _message,
|
|
30
31
|
overrides: _overrides,
|
|
31
32
|
autoHide: autoHide,
|
|
@@ -54,18 +55,12 @@ var Snackbar = function (_a) {
|
|
|
54
55
|
var _s = tslib_1.__read((0, overrides_1.useOverrides)(overrides === null || overrides === void 0 ? void 0 : overrides.CloseIcon, close_1.default), 2), Close = _s[0], closeProps = _s[1];
|
|
55
56
|
var _t = tslib_1.__read((0, overrides_1.useOverrides)(overrides === null || overrides === void 0 ? void 0 : overrides.CloseIconButton, button_1.IconButton), 2), CloseIconButton = _t[0], closeIconButtonProps = _t[1];
|
|
56
57
|
var locale = (0, locale_1.useLocale)();
|
|
57
|
-
var role = constants_1.INTENT_TO_ROLE[intent];
|
|
58
|
-
// We don't know if the message contains any interactive elements, so we only
|
|
59
|
-
// delegate to the shared screen-reader announcer when the message is a string.
|
|
60
58
|
var isStringMessage = typeof message === 'string';
|
|
61
|
-
// Announce string messages through the shared global live region instead of
|
|
62
|
-
// hand-rolling sr-only regions here. The announcer keeps a single source of
|
|
63
|
-
// truth for status messages (WCAG 4.1.3) and re-announces repeated text.
|
|
64
59
|
(0, react_1.useEffect)(function () {
|
|
65
|
-
if (
|
|
66
|
-
(0, a11y_1.announce)(
|
|
60
|
+
if (typeof _message === 'string' && _message) {
|
|
61
|
+
(0, a11y_1.announce)(_message, { politeness: constants_1.INTENT_TO_ROLE[_intent] === 'alert' ? 'assertive' : 'polite' });
|
|
67
62
|
}
|
|
68
|
-
}, [
|
|
63
|
+
}, [_message, _intent, id]);
|
|
69
64
|
return ((0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: shouldRender ? ((0, jsx_runtime_1.jsx)(layer_2.LayersManager, tslib_1.__assign({ zIndex: layer_2.Z_INDEX.SNACKBAR }, { children: (0, jsx_runtime_1.jsx)(Layer, tslib_1.__assign({}, sharedProps, layerProps, { children: (0, jsx_runtime_1.jsx)(PlacementContainer, tslib_1.__assign({ "data-spaceweb": "snackbar", "data-testid": "snackbar" }, sharedProps, placementContainerProps, { children: (0, jsx_runtime_1.jsx)(SnackbarContainer, tslib_1.__assign({}, snackbarContainerProps, { ref: snackbarContainerRef }, sharedProps, snackbarContainerOverrideProps, { style: [styled_component_1.getSnackbarContainerAnimationStyle, snackbarContainerOverrideProps.style] }, { children: (0, jsx_runtime_1.jsx)(theme_1.ThemeProvider, tslib_1.__assign({ theme: inverseTheme }, { children: (0, jsx_runtime_1.jsxs)(ContentContainer, tslib_1.__assign({}, sharedProps, contentContainerProps, { children: [(0, jsx_runtime_1.jsx)(IconsContainer, tslib_1.__assign({}, sharedProps, iconsContainerProps, { children: (0, jsx_runtime_1.jsx)(IntentIcon, tslib_1.__assign({ size: 20, className: styled_component_1.getIconStyles }, sharedProps, intentIconProps)) })), (0, jsx_runtime_1.jsx)(Message
|
|
70
65
|
// The sr-only region handles screen reader announcements
|
|
71
66
|
// to prevent the message from being read twice
|
|
@@ -14,15 +14,20 @@ var SnackbarProvider = function (_a) {
|
|
|
14
14
|
var children = _a.children;
|
|
15
15
|
var _b = tslib_1.__read((0, react_1.useState)(''), 2), message = _b[0], setMessage = _b[1];
|
|
16
16
|
var _c = tslib_1.__read((0, react_1.useState)('success'), 2), intent = _c[0], setIntent = _c[1];
|
|
17
|
+
var _d = tslib_1.__read((0, react_1.useState)(0), 2), id = _d[0], setId = _d[1];
|
|
17
18
|
var notify = (0, react_1.useCallback)(function (_a) {
|
|
18
19
|
var _b = _a.intent, _intent = _b === void 0 ? 'success' : _b, _message = _a.message;
|
|
20
|
+
setId(function (prev) { return prev + 1; });
|
|
19
21
|
setMessage(_message);
|
|
20
22
|
setIntent(_intent);
|
|
21
23
|
}, []);
|
|
22
|
-
var onClose = (0, react_1.useCallback)(function () {
|
|
24
|
+
var onClose = (0, react_1.useCallback)(function (reason) {
|
|
25
|
+
// Keep content when swapping instances; only clear on real dismiss.
|
|
26
|
+
if (reason === 'messageChange')
|
|
27
|
+
return;
|
|
23
28
|
setMessage('');
|
|
24
29
|
setIntent('success');
|
|
25
30
|
}, []);
|
|
26
|
-
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(SnackbarContext.Provider, tslib_1.__assign({ value: notify }, { children: children })), message && intent ? (0, jsx_runtime_1.jsx)(_1.Snackbar, { message: message, intent: intent, onClose: onClose }) : null] }));
|
|
31
|
+
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(SnackbarContext.Provider, tslib_1.__assign({ value: notify }, { children: children })), message && intent ? (0, jsx_runtime_1.jsx)(_1.Snackbar, { id: id, message: message, intent: intent, onClose: onClose }) : null] }));
|
|
27
32
|
};
|
|
28
33
|
exports.SnackbarProvider = SnackbarProvider;
|
package/snackbar/types.d.ts
CHANGED
|
@@ -26,6 +26,12 @@ export type SnackbarOverrides = {
|
|
|
26
26
|
};
|
|
27
27
|
export type SnackbarProps = {
|
|
28
28
|
message?: React.ReactNode;
|
|
29
|
+
/**
|
|
30
|
+
* Opaque instance identity. Bump this (e.g. increment a counter) when re-showing
|
|
31
|
+
* the same `message` so the snackbar re-opens and re-announces for screen readers.
|
|
32
|
+
* `SnackbarProvider` / `useNotification` set this automatically on every `notify()`.
|
|
33
|
+
*/
|
|
34
|
+
id?: string | number;
|
|
29
35
|
intent?: Intent;
|
|
30
36
|
hideOnClickAway?: boolean;
|
|
31
37
|
disableManualClose?: boolean;
|
|
@@ -5,6 +5,7 @@ type UseSnackbarParams = {
|
|
|
5
5
|
autoHideDuration: number;
|
|
6
6
|
hideOnClickAway: boolean;
|
|
7
7
|
intent: Intent;
|
|
8
|
+
id?: string | number;
|
|
8
9
|
message?: React.ReactNode;
|
|
9
10
|
onClose?: (reason: HideReason) => void;
|
|
10
11
|
overrides?: SnackbarOverrides;
|
|
@@ -23,5 +24,5 @@ type UseSnackbarReturnValue = {
|
|
|
23
24
|
intent: Intent;
|
|
24
25
|
overrides?: SnackbarOverrides;
|
|
25
26
|
};
|
|
26
|
-
declare const useSnackbar: ({ autoHide, autoHideDuration, hideOnClickAway, intent: nextIntent, message: nextMessage, onClose, overrides: nextOverrides, }: UseSnackbarParams) => UseSnackbarReturnValue;
|
|
27
|
+
declare const useSnackbar: ({ autoHide, autoHideDuration, hideOnClickAway, intent: nextIntent, id, message: nextMessage, onClose, overrides: nextOverrides, }: UseSnackbarParams) => UseSnackbarReturnValue;
|
|
27
28
|
export default useSnackbar;
|
package/snackbar/useSnackbar.js
CHANGED
|
@@ -35,10 +35,10 @@ var useAutoHide = function (_a) {
|
|
|
35
35
|
}, [open, autoHide, autoHideDuration, autoHideTimeoutRef]);
|
|
36
36
|
};
|
|
37
37
|
var useDomVisibility = function (_a) {
|
|
38
|
-
var message = _a.message, open = _a.open, enter = _a.enter, handleClose = _a.handleClose, intent = _a.intent;
|
|
38
|
+
var message = _a.message, open = _a.open, enter = _a.enter, handleClose = _a.handleClose, intent = _a.intent, id = _a.id;
|
|
39
39
|
var _b = tslib_1.__read((0, react_1.useState)(false), 2), domVisibility = _b[0], setDomVisibility = _b[1];
|
|
40
40
|
var removeFromDomTimeoutRef = (0, react_1.useRef)();
|
|
41
|
-
// handle exit, enter on message change
|
|
41
|
+
// handle exit, enter on message / intent / id change
|
|
42
42
|
(0, react_1.useEffect)(function () {
|
|
43
43
|
if (!message)
|
|
44
44
|
return undefined;
|
|
@@ -53,7 +53,7 @@ var useDomVisibility = function (_a) {
|
|
|
53
53
|
open && handleClose('messageChange');
|
|
54
54
|
return function () { return window.clearTimeout(timeoutId); };
|
|
55
55
|
// eslint-disable-next-line react-hooks/exhaustive-deps -- handleClose not required
|
|
56
|
-
}, [message, intent]);
|
|
56
|
+
}, [message, intent, id]);
|
|
57
57
|
// remove from DOM, once transition is over
|
|
58
58
|
(0, useUpdateEffect_1.default)(function () {
|
|
59
59
|
if (open)
|
|
@@ -66,7 +66,7 @@ var useDomVisibility = function (_a) {
|
|
|
66
66
|
return domVisibility;
|
|
67
67
|
};
|
|
68
68
|
var useSnackbar = function (_a) {
|
|
69
|
-
var autoHide = _a.autoHide, autoHideDuration = _a.autoHideDuration, hideOnClickAway = _a.hideOnClickAway, nextIntent = _a.intent, nextMessage = _a.message, onClose = _a.onClose, nextOverrides = _a.overrides;
|
|
69
|
+
var autoHide = _a.autoHide, autoHideDuration = _a.autoHideDuration, hideOnClickAway = _a.hideOnClickAway, nextIntent = _a.intent, id = _a.id, nextMessage = _a.message, onClose = _a.onClose, nextOverrides = _a.overrides;
|
|
70
70
|
var _b = tslib_1.__read((0, react_1.useState)(false), 2), open = _b[0], setOpen = _b[1];
|
|
71
71
|
var _c = tslib_1.__read((0, react_1.useState)({
|
|
72
72
|
intent: nextIntent,
|
|
@@ -91,7 +91,14 @@ var useSnackbar = function (_a) {
|
|
|
91
91
|
};
|
|
92
92
|
useAutoHide({ open: open, handleClose: handleClose, autoHideTimeoutRef: autoHideTimeoutRef, autoHideDuration: autoHideDuration, autoHide: autoHide });
|
|
93
93
|
var snackbarContainerRef = useHideOnClickAway({ hideOnClickAway: hideOnClickAway, handleClose: handleClose, open: open });
|
|
94
|
-
var shouldRender = useDomVisibility({
|
|
94
|
+
var shouldRender = useDomVisibility({
|
|
95
|
+
handleClose: handleClose,
|
|
96
|
+
open: open,
|
|
97
|
+
intent: nextIntent,
|
|
98
|
+
id: id,
|
|
99
|
+
message: nextMessage,
|
|
100
|
+
enter: enter,
|
|
101
|
+
});
|
|
95
102
|
var handleMouseEnter = function () {
|
|
96
103
|
window.clearTimeout(autoHideTimeoutRef.current);
|
|
97
104
|
};
|