@transferwise/components 0.0.0-experimental-47052c9 → 0.0.0-experimental-b2b287d
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/build/Snackbar/Snackbar.js +178 -102
- package/build/Snackbar/Snackbar.js.map +1 -1
- package/build/Snackbar/Snackbar.messages.js +14 -0
- package/build/Snackbar/Snackbar.messages.js.map +1 -0
- package/build/Snackbar/Snackbar.messages.mjs +10 -0
- package/build/Snackbar/Snackbar.messages.mjs.map +1 -0
- package/build/Snackbar/Snackbar.mjs +180 -101
- package/build/Snackbar/Snackbar.mjs.map +1 -1
- package/build/Snackbar/SnackbarContext.js.map +1 -1
- package/build/Snackbar/SnackbarContext.mjs.map +1 -1
- package/build/Snackbar/SnackbarPortal.js +12 -0
- package/build/Snackbar/SnackbarPortal.js.map +1 -0
- package/build/Snackbar/SnackbarPortal.mjs +8 -0
- package/build/Snackbar/SnackbarPortal.mjs.map +1 -0
- package/build/Snackbar/SnackbarProvider.js +24 -28
- package/build/Snackbar/SnackbarProvider.js.map +1 -1
- package/build/Snackbar/SnackbarProvider.mjs +25 -29
- package/build/Snackbar/SnackbarProvider.mjs.map +1 -1
- package/build/Snackbar/constants.js +17 -0
- package/build/Snackbar/constants.js.map +1 -0
- package/build/Snackbar/constants.mjs +11 -0
- package/build/Snackbar/constants.mjs.map +1 -0
- package/build/Snackbar/useSnackbarAutoDismiss.js +66 -0
- package/build/Snackbar/useSnackbarAutoDismiss.js.map +1 -0
- package/build/Snackbar/useSnackbarAutoDismiss.mjs +62 -0
- package/build/Snackbar/useSnackbarAutoDismiss.mjs.map +1 -0
- package/build/Snackbar/useSnackbarManager.js +153 -0
- package/build/Snackbar/useSnackbarManager.js.map +1 -0
- package/build/Snackbar/useSnackbarManager.mjs +149 -0
- package/build/Snackbar/useSnackbarManager.mjs.map +1 -0
- package/build/Snackbar/useSnackbarSwipeDismiss.js +135 -0
- package/build/Snackbar/useSnackbarSwipeDismiss.js.map +1 -0
- package/build/Snackbar/useSnackbarSwipeDismiss.mjs +131 -0
- package/build/Snackbar/useSnackbarSwipeDismiss.mjs.map +1 -0
- package/build/i18n/en.json +1 -0
- package/build/i18n/en.json.js +1 -0
- package/build/i18n/en.json.js.map +1 -1
- package/build/i18n/en.json.mjs +1 -0
- package/build/i18n/en.json.mjs.map +1 -1
- package/build/index.js +0 -4
- package/build/index.js.map +1 -1
- package/build/index.mjs +0 -2
- package/build/index.mjs.map +1 -1
- package/build/main.css +116 -245
- package/build/styles/Snackbar/Snackbar.css +117 -54
- package/build/styles/main.css +116 -245
- package/build/types/Snackbar/Snackbar.d.ts +55 -9
- package/build/types/Snackbar/Snackbar.d.ts.map +1 -1
- package/build/types/Snackbar/Snackbar.messages.d.ts +9 -0
- package/build/types/Snackbar/Snackbar.messages.d.ts.map +1 -0
- package/build/types/Snackbar/Snackbar.types.d.ts +12 -0
- package/build/types/Snackbar/Snackbar.types.d.ts.map +1 -0
- package/build/types/Snackbar/SnackbarContext.d.ts +2 -2
- package/build/types/Snackbar/SnackbarContext.d.ts.map +1 -1
- package/build/types/Snackbar/SnackbarPortal.d.ts +4 -0
- package/build/types/Snackbar/SnackbarPortal.d.ts.map +1 -0
- package/build/types/Snackbar/SnackbarProvider.d.ts +7 -0
- package/build/types/Snackbar/SnackbarProvider.d.ts.map +1 -1
- package/build/types/Snackbar/constants.d.ts +9 -0
- package/build/types/Snackbar/constants.d.ts.map +1 -0
- package/build/types/Snackbar/index.d.ts +1 -1
- package/build/types/Snackbar/index.d.ts.map +1 -1
- package/build/types/Snackbar/useSnackbar.d.ts +1 -1
- package/build/types/Snackbar/useSnackbar.d.ts.map +1 -1
- package/build/types/Snackbar/useSnackbarAutoDismiss.d.ts +13 -0
- package/build/types/Snackbar/useSnackbarAutoDismiss.d.ts.map +1 -0
- package/build/types/Snackbar/useSnackbarManager.d.ts +20 -0
- package/build/types/Snackbar/useSnackbarManager.d.ts.map +1 -0
- package/build/types/Snackbar/useSnackbarSwipeDismiss.d.ts +22 -0
- package/build/types/Snackbar/useSnackbarSwipeDismiss.d.ts.map +1 -0
- package/build/types/index.d.ts +1 -5
- package/build/types/index.d.ts.map +1 -1
- package/build/types/test-utils/index.d.ts +2 -0
- package/build/types/test-utils/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/FlowNavigation/_stories/FlowNavigation.CriticalBanner.docs.mdx +66 -0
- package/src/Prompt/CriticalBanner/_stories/CriticalBanner.story.tsx +2 -0
- package/src/Snackbar/Snackbar.css +117 -54
- package/src/Snackbar/Snackbar.less +139 -60
- package/src/Snackbar/Snackbar.messages.ts +9 -0
- package/src/Snackbar/Snackbar.test.tsx +989 -119
- package/src/Snackbar/Snackbar.tsx +208 -93
- package/src/Snackbar/Snackbar.types.ts +17 -0
- package/src/Snackbar/SnackbarContext.ts +2 -2
- package/src/Snackbar/SnackbarPortal.tsx +8 -0
- package/src/Snackbar/SnackbarProvider.test.tsx +783 -0
- package/src/Snackbar/SnackbarProvider.tsx +27 -19
- package/src/Snackbar/_stories/Snackbar.accessibility.docs.mdx +58 -0
- package/src/Snackbar/_stories/Snackbar.rtl.test.story.tsx +16 -8
- package/src/Snackbar/_stories/Snackbar.story.tsx +388 -61
- package/src/Snackbar/_stories/Snackbar.test.story.tsx +171 -47
- package/src/Snackbar/constants.ts +10 -0
- package/src/Snackbar/index.ts +1 -1
- package/src/Snackbar/useSnackbarAutoDismiss.ts +74 -0
- package/src/Snackbar/useSnackbarManager.ts +169 -0
- package/src/Snackbar/useSnackbarSwipeDismiss.ts +169 -0
- package/src/i18n/en.json +1 -0
- package/src/index.ts +1 -14
- package/src/main.css +116 -245
- package/src/main.less +0 -2
- package/build/CardContainer/CardContainer.js +0 -34
- package/build/CardContainer/CardContainer.js.map +0 -1
- package/build/CardContainer/CardContainer.mjs +0 -30
- package/build/CardContainer/CardContainer.mjs.map +0 -1
- package/build/CardWidget/CardWidget.js +0 -98
- package/build/CardWidget/CardWidget.js.map +0 -1
- package/build/CardWidget/CardWidget.mjs +0 -94
- package/build/CardWidget/CardWidget.mjs.map +0 -1
- package/build/CardWidget/CardWidgetAction.js +0 -73
- package/build/CardWidget/CardWidgetAction.js.map +0 -1
- package/build/CardWidget/CardWidgetAction.mjs +0 -68
- package/build/CardWidget/CardWidgetAction.mjs.map +0 -1
- package/build/styles/CardContainer/CardContainer.css +0 -108
- package/build/styles/CardWidget/CardWidget.css +0 -84
- package/build/types/CardContainer/CardContainer.d.ts +0 -8
- package/build/types/CardContainer/CardContainer.d.ts.map +0 -1
- package/build/types/CardContainer/CardContainer.types.d.ts +0 -53
- package/build/types/CardContainer/CardContainer.types.d.ts.map +0 -1
- package/build/types/CardContainer/_stories/helpers.d.ts +0 -3
- package/build/types/CardContainer/_stories/helpers.d.ts.map +0 -1
- package/build/types/CardContainer/index.d.ts +0 -3
- package/build/types/CardContainer/index.d.ts.map +0 -1
- package/build/types/CardWidget/CardWidget.d.ts +0 -10
- package/build/types/CardWidget/CardWidget.d.ts.map +0 -1
- package/build/types/CardWidget/CardWidget.types.d.ts +0 -55
- package/build/types/CardWidget/CardWidget.types.d.ts.map +0 -1
- package/build/types/CardWidget/CardWidgetAction.d.ts +0 -54
- package/build/types/CardWidget/CardWidgetAction.d.ts.map +0 -1
- package/build/types/CardWidget/index.d.ts +0 -4
- package/build/types/CardWidget/index.d.ts.map +0 -1
- package/src/CardContainer/CardContainer.css +0 -108
- package/src/CardContainer/CardContainer.less +0 -171
- package/src/CardContainer/CardContainer.test.tsx +0 -150
- package/src/CardContainer/CardContainer.tsx +0 -51
- package/src/CardContainer/CardContainer.types.ts +0 -60
- package/src/CardContainer/_stories/CardContainer.story.tsx +0 -167
- package/src/CardContainer/_stories/CardContainer.test.story.tsx +0 -103
- package/src/CardContainer/_stories/helpers.tsx +0 -50
- package/src/CardContainer/index.ts +0 -6
- package/src/CardWidget/CardWidget.css +0 -84
- package/src/CardWidget/CardWidget.less +0 -110
- package/src/CardWidget/CardWidget.test.tsx +0 -222
- package/src/CardWidget/CardWidget.tsx +0 -83
- package/src/CardWidget/CardWidget.types.ts +0 -63
- package/src/CardWidget/CardWidgetAction.tsx +0 -128
- package/src/CardWidget/_stories/CardWidget.story.tsx +0 -238
- package/src/CardWidget/_stories/CardWidget.test.story.tsx +0 -350
- package/src/CardWidget/index.ts +0 -3
- package/src/Prompt/CriticalBanner/_stories/CriticalBanner.docs.mdx +0 -122
|
@@ -1,129 +1,244 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Tags } from '@transferwise/icons';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
import { useIntl } from 'react-intl';
|
|
2
4
|
import { CSSTransition } from 'react-transition-group';
|
|
3
5
|
|
|
4
|
-
import Button from '../Button';
|
|
6
|
+
import Button, { type ButtonReferenceType } from '../Button';
|
|
5
7
|
import Body from '../Body';
|
|
8
|
+
import { LiveRegion } from '../common';
|
|
6
9
|
import type { ThemeDark, ThemeLight } from '../common';
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
import { PrimitivePrompt } from '../Prompt/PrimitivePrompt';
|
|
11
|
+
import ProcessIndicator from '../ProcessIndicator';
|
|
12
|
+
import type { Sentiment } from '../SentimentSurface';
|
|
13
|
+
import StatusIcon from '../StatusIcon';
|
|
14
|
+
|
|
15
|
+
import { SNACKBAR_ENTER_DURATION, SNACKBAR_EXIT_DURATION } from './constants';
|
|
16
|
+
import messages from './Snackbar.messages';
|
|
17
|
+
import type { SnackbarAction, SnackbarDuration } from './Snackbar.types';
|
|
18
|
+
import useSnackbarAutoDismiss from './useSnackbarAutoDismiss';
|
|
19
|
+
import useSnackbarSwipeDismiss from './useSnackbarSwipeDismiss';
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Props for the controlled Snackbar surface, including provider-managed lifecycle controls.
|
|
23
|
+
* Use SnackbarCreationProps when creating notifications through SnackbarProvider/useSnackbar.
|
|
24
|
+
*/
|
|
11
25
|
export interface SnackbarProps {
|
|
12
|
-
action
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
26
|
+
/** One optional callback or navigation action. Activating it dismisses after its callback runs. */
|
|
27
|
+
action?: SnackbarAction;
|
|
28
|
+
/** Changes for each new Snackbar so LiveRegion re-announces it. */
|
|
29
|
+
announcementKey: number;
|
|
30
|
+
/**
|
|
31
|
+
* Controls auto-dismiss with a four-second, six-second or indefinite duration after entry finishes.
|
|
32
|
+
* Takes precedence over the deprecated `timeout`.
|
|
33
|
+
* When neither option is supplied, the default is 4000ms (previously 4500ms).
|
|
34
|
+
* @default 'default'
|
|
35
|
+
*/
|
|
36
|
+
duration?: SnackbarDuration;
|
|
37
|
+
/**
|
|
38
|
+
* Replaces the media with a progress indicator, uses neutral styling and prevents auto-dismiss.
|
|
39
|
+
* Takes precedence over `media`, `sentiment`, `duration` and the deprecated `timeout`.
|
|
40
|
+
* @default false
|
|
41
|
+
*/
|
|
42
|
+
loading?: boolean;
|
|
43
|
+
/** Overrides sentiment-derived media with content for the 24×24px media slot. */
|
|
44
|
+
media?: React.ReactNode;
|
|
45
|
+
/**
|
|
46
|
+
* Called once after this Snackbar finishes exiting, including after an action (e.g. Undo)
|
|
47
|
+
* or replacement by a newer Snackbar. The action callback runs first.
|
|
48
|
+
* Not called for Snackbars discarded before being shown, such as earlier creates batched
|
|
49
|
+
* before the first render.
|
|
50
|
+
*/
|
|
51
|
+
onDismiss?: () => void;
|
|
52
|
+
/** Requests an exit; the provider retains the surface until onExited confirms it has finished. */
|
|
53
|
+
onDismissRequest: () => void;
|
|
54
|
+
/** Called after the exit animation so the provider can unmount active or show its replacement. */
|
|
55
|
+
onExited: () => void;
|
|
56
|
+
/**
|
|
57
|
+
* Controls the sentiment surface and default media.
|
|
58
|
+
* @default 'neutral'
|
|
59
|
+
*/
|
|
60
|
+
sentiment?: Sentiment;
|
|
61
|
+
/** Message content. Empty strings or absent text dismiss without creating a blank replacement. */
|
|
16
62
|
text: React.ReactNode;
|
|
17
63
|
/** @deprecated Has no effect. Snackbar theming is based on ThemeProvider. */
|
|
18
64
|
theme?: ThemeLight | ThemeDark;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
65
|
+
/**
|
|
66
|
+
* @deprecated Use `duration` instead. Explicit millisecond values remain supported and are not
|
|
67
|
+
* automatically remapped when no `duration` is supplied.
|
|
68
|
+
* To migrate, use `default` for 0–5000ms, `extended` for values above 5000ms, and `indefinite`
|
|
69
|
+
* for intentionally persistent notifications.
|
|
70
|
+
*/
|
|
71
|
+
timeout?: number;
|
|
72
|
+
/** @deprecated Has no effect when using SnackbarProvider, which manages Snackbar identity. */
|
|
73
|
+
timestamp?: number;
|
|
74
|
+
/** Controls entry/exit; the surface does not manage visibility itself. */
|
|
24
75
|
visible: boolean;
|
|
25
76
|
}
|
|
26
77
|
|
|
27
|
-
export const Snackbar = (
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
78
|
+
export const Snackbar = ({
|
|
79
|
+
action,
|
|
80
|
+
announcementKey,
|
|
81
|
+
duration,
|
|
82
|
+
loading = false,
|
|
83
|
+
media,
|
|
84
|
+
onDismissRequest,
|
|
85
|
+
onExited,
|
|
86
|
+
sentiment = 'neutral',
|
|
87
|
+
text,
|
|
88
|
+
timeout,
|
|
89
|
+
visible,
|
|
90
|
+
}: SnackbarProps) => {
|
|
91
|
+
const { formatMessage } = useIntl();
|
|
92
|
+
const {
|
|
93
|
+
handleBlur,
|
|
94
|
+
handleEntered,
|
|
95
|
+
handleFocus,
|
|
96
|
+
handleMouseEnter,
|
|
97
|
+
handleMouseLeave,
|
|
98
|
+
setSwiping,
|
|
99
|
+
surfaceRef,
|
|
100
|
+
} = useSnackbarAutoDismiss({
|
|
101
|
+
duration,
|
|
102
|
+
loading,
|
|
103
|
+
onDismissRequest,
|
|
104
|
+
timeout,
|
|
105
|
+
visible,
|
|
37
106
|
});
|
|
107
|
+
const {
|
|
108
|
+
clearSwipePosition,
|
|
109
|
+
containerRef,
|
|
110
|
+
handleClickCapture,
|
|
111
|
+
handlePointerCancel,
|
|
112
|
+
handlePointerDown,
|
|
113
|
+
handlePointerMove,
|
|
114
|
+
handlePointerUp,
|
|
115
|
+
} = useSnackbarSwipeDismiss({ onDismissRequest, onSwipeChange: setSwiping, visible });
|
|
116
|
+
|
|
117
|
+
useEffect(() => {
|
|
118
|
+
if (!visible) {
|
|
119
|
+
return undefined;
|
|
120
|
+
}
|
|
38
121
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
window.clearTimeout(transitionTimeout.current);
|
|
43
|
-
},
|
|
44
|
-
[],
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
// Runs after every render to mirror the componentDidUpdate lifecycle this component previously
|
|
48
|
-
// relied on, including the shouldComponentUpdate guard that ignored every update without text.
|
|
49
|
-
// Layout, not passive, so a notification is shown or replaced before the browser paints, as
|
|
50
|
-
// componentDidUpdate did. Both rules below are disabled on purpose: the dependency-less effect
|
|
51
|
-
// and its synchronous state updates are what keep this conversion behaviour-identical.
|
|
52
|
-
/* eslint-disable react-hooks/exhaustive-deps, react-hooks/set-state-in-effect */
|
|
53
|
-
useLayoutEffect(() => {
|
|
54
|
-
const previousProps = committedProps.current;
|
|
55
|
-
committedProps.current = props;
|
|
56
|
-
|
|
57
|
-
const { action, text, timestamp } = props;
|
|
58
|
-
|
|
59
|
-
// shouldComponentUpdate bailed out whenever the incoming text was empty. That also blocked the
|
|
60
|
-
// updates scheduled below, so a Snackbar whose text is cleared stays on screen until it is
|
|
61
|
-
// given text again. Preserved here deliberately to keep this refactor behaviour-identical.
|
|
62
|
-
const updateWhileTextIsPresent = (update: () => void) => {
|
|
63
|
-
if (committedProps.current.text) {
|
|
64
|
-
update();
|
|
122
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
123
|
+
if (event.key === 'Escape' && !event.defaultPrevented && !event.isComposing) {
|
|
124
|
+
onDismissRequest();
|
|
65
125
|
}
|
|
66
126
|
};
|
|
67
127
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
};
|
|
128
|
+
// Let document-level overlays consume Escape before this fallback handles it.
|
|
129
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
130
|
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
131
|
+
}, [visible, onDismissRequest]);
|
|
73
132
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
}
|
|
133
|
+
const handleActionClick: React.MouseEventHandler<ButtonReferenceType> = (event) => {
|
|
134
|
+
try {
|
|
135
|
+
action?.onClick?.(event);
|
|
136
|
+
} finally {
|
|
137
|
+
onDismissRequest();
|
|
138
|
+
}
|
|
139
|
+
};
|
|
78
140
|
|
|
79
|
-
|
|
80
|
-
|
|
141
|
+
const renderMedia = () => {
|
|
142
|
+
if (loading) {
|
|
143
|
+
return (
|
|
144
|
+
<ProcessIndicator
|
|
145
|
+
className="wds-Snackbar__process-indicator"
|
|
146
|
+
data-testid="Snackbar_ProcessIndicator"
|
|
147
|
+
size="xs"
|
|
148
|
+
/>
|
|
149
|
+
);
|
|
81
150
|
}
|
|
82
151
|
|
|
83
|
-
if (
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
window.clearTimeout(leaveTimeout.current);
|
|
152
|
+
if (media) {
|
|
153
|
+
return <span className="wds-Snackbar__media-asset">{media}</span>;
|
|
154
|
+
}
|
|
87
155
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
show();
|
|
95
|
-
}
|
|
156
|
+
if (sentiment === 'proposition') {
|
|
157
|
+
return (
|
|
158
|
+
<span className="wds-Snackbar__media-asset">
|
|
159
|
+
<Tags aria-hidden size={24} />
|
|
160
|
+
</span>
|
|
161
|
+
);
|
|
96
162
|
}
|
|
97
|
-
});
|
|
98
|
-
/* eslint-enable react-hooks/exhaustive-deps, react-hooks/set-state-in-effect */
|
|
99
163
|
|
|
100
|
-
|
|
101
|
-
|
|
164
|
+
return <StatusIcon sentiment={sentiment} size={24} />;
|
|
165
|
+
};
|
|
102
166
|
|
|
103
167
|
return (
|
|
104
|
-
<div
|
|
168
|
+
<div
|
|
169
|
+
ref={containerRef}
|
|
170
|
+
className="wds-Snackbar"
|
|
171
|
+
style={
|
|
172
|
+
{
|
|
173
|
+
'--Snackbar-enter-duration': `${SNACKBAR_ENTER_DURATION}ms`,
|
|
174
|
+
'--Snackbar-exit-duration': `${SNACKBAR_EXIT_DURATION}ms`,
|
|
175
|
+
} as React.CSSProperties
|
|
176
|
+
}
|
|
177
|
+
>
|
|
105
178
|
<CSSTransition
|
|
106
|
-
|
|
179
|
+
appear
|
|
180
|
+
nodeRef={surfaceRef}
|
|
107
181
|
in={visible}
|
|
108
|
-
classNames="
|
|
182
|
+
classNames="wds-Snackbar-container"
|
|
109
183
|
timeout={{
|
|
110
|
-
appear:
|
|
111
|
-
enter:
|
|
112
|
-
exit:
|
|
184
|
+
appear: SNACKBAR_ENTER_DURATION,
|
|
185
|
+
enter: SNACKBAR_ENTER_DURATION,
|
|
186
|
+
exit: SNACKBAR_EXIT_DURATION,
|
|
113
187
|
}}
|
|
114
188
|
unmountOnExit
|
|
189
|
+
onEntered={handleEntered}
|
|
190
|
+
onExited={() => {
|
|
191
|
+
clearSwipePosition();
|
|
192
|
+
onExited();
|
|
193
|
+
}}
|
|
115
194
|
>
|
|
116
|
-
<
|
|
117
|
-
{
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
195
|
+
<PrimitivePrompt
|
|
196
|
+
ref={surfaceRef}
|
|
197
|
+
className="wds-Snackbar-container"
|
|
198
|
+
sentiment={loading ? 'neutral' : sentiment}
|
|
199
|
+
emphasis="elevated"
|
|
200
|
+
media={renderMedia()}
|
|
201
|
+
onDismiss={onDismissRequest}
|
|
202
|
+
onMouseEnter={handleMouseEnter}
|
|
203
|
+
onMouseLeave={handleMouseLeave}
|
|
204
|
+
onFocus={handleFocus}
|
|
205
|
+
onBlur={handleBlur}
|
|
206
|
+
onClickCapture={handleClickCapture}
|
|
207
|
+
onDragStart={(event) => event.preventDefault()}
|
|
208
|
+
onPointerDown={visible ? handlePointerDown : undefined}
|
|
209
|
+
onPointerMove={handlePointerMove}
|
|
210
|
+
onPointerUp={handlePointerUp}
|
|
211
|
+
onPointerCancel={handlePointerCancel}
|
|
212
|
+
>
|
|
213
|
+
<div className="wds-Snackbar__content">
|
|
214
|
+
<LiveRegion
|
|
215
|
+
aria-live="polite"
|
|
216
|
+
announceOnChange={announcementKey}
|
|
217
|
+
className="wds-Snackbar__message"
|
|
218
|
+
>
|
|
219
|
+
<Body as="span" className="wds-Snackbar__body">
|
|
220
|
+
{text}
|
|
221
|
+
<span className="sr-only"> {formatMessage(messages.escapeDismissHint)}</span>
|
|
222
|
+
</Body>
|
|
223
|
+
</LiveRegion>
|
|
224
|
+
{action ? (
|
|
225
|
+
<Button
|
|
226
|
+
className="wds-Snackbar__action"
|
|
227
|
+
v2
|
|
228
|
+
size="sm"
|
|
229
|
+
priority="secondary"
|
|
230
|
+
href={action.href}
|
|
231
|
+
target={action.target}
|
|
232
|
+
onClick={handleActionClick}
|
|
233
|
+
>
|
|
234
|
+
{action.label}
|
|
235
|
+
</Button>
|
|
236
|
+
) : null}
|
|
237
|
+
</div>
|
|
238
|
+
</PrimitivePrompt>
|
|
124
239
|
</CSSTransition>
|
|
125
240
|
</div>
|
|
126
241
|
);
|
|
127
242
|
};
|
|
128
243
|
|
|
129
|
-
export default
|
|
244
|
+
export default Snackbar;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ButtonProps, ButtonReferenceType } from '../Button/Button.types';
|
|
2
|
+
import type { SnackbarProps } from './Snackbar';
|
|
3
|
+
|
|
4
|
+
/** Semantic auto-dismiss durations. `indefinite` disables the timer. */
|
|
5
|
+
export type SnackbarDuration = 'default' | 'extended' | 'indefinite';
|
|
6
|
+
|
|
7
|
+
/** One optional action. Supports callbacks and navigation through the Button API. */
|
|
8
|
+
export type SnackbarAction = Pick<ButtonProps, 'href' | 'target'> & {
|
|
9
|
+
label: ButtonProps['children'];
|
|
10
|
+
onClick?: React.MouseEventHandler<ButtonReferenceType>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
/** Props accepted by `createSnackbar` from `useSnackbar()`. */
|
|
14
|
+
export type SnackbarCreationProps = Omit<
|
|
15
|
+
SnackbarProps,
|
|
16
|
+
'announcementKey' | 'onDismissRequest' | 'onExited' | 'timeout' | 'visible'
|
|
17
|
+
>;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { createContext } from 'react';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import type { SnackbarCreationProps } from './Snackbar.types';
|
|
4
4
|
|
|
5
5
|
export type SnackbarContextType = {
|
|
6
|
-
createSnackbar: (props:
|
|
6
|
+
createSnackbar: (props: SnackbarCreationProps) => void;
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
export const SnackbarContext = createContext<SnackbarContextType>({ createSnackbar: () => {} });
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import withNextPortal from '../WithNextPortal/WithNextPortal';
|
|
2
|
+
|
|
3
|
+
import { Snackbar } from './Snackbar';
|
|
4
|
+
|
|
5
|
+
/** Renders the Snackbar into `document.body` after mount, so it's safe for SSR. */
|
|
6
|
+
const SnackbarPortal = withNextPortal(Snackbar);
|
|
7
|
+
|
|
8
|
+
export default SnackbarPortal;
|