@transferwise/components 0.0.0-experimental-63c3fc6 → 0.0.0-experimental-5f03867
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 -191
- package/build/styles/Snackbar/Snackbar.css +117 -54
- package/build/styles/main.css +116 -191
- 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/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 +66 -0
- package/src/Snackbar/_stories/Snackbar.migration.docs.mdx +64 -0
- package/src/Snackbar/_stories/Snackbar.rtl.test.story.tsx +16 -8
- package/src/Snackbar/_stories/Snackbar.story.tsx +389 -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 -191
- package/src/main.less +0 -2
- package/build/CardContainer/CardContainer.js +0 -33
- package/build/CardContainer/CardContainer.js.map +0 -1
- package/build/CardContainer/CardContainer.mjs +0 -29
- package/build/CardContainer/CardContainer.mjs.map +0 -1
- package/build/CardWidget/CardWidget.js +0 -94
- package/build/CardWidget/CardWidget.js.map +0 -1
- package/build/CardWidget/CardWidget.mjs +0 -90
- package/build/CardWidget/CardWidget.mjs.map +0 -1
- package/build/CardWidget/CardWidgetAction.js +0 -70
- package/build/CardWidget/CardWidgetAction.js.map +0 -1
- package/build/CardWidget/CardWidgetAction.mjs +0 -65
- package/build/CardWidget/CardWidgetAction.mjs.map +0 -1
- package/build/styles/CardContainer/CardContainer.css +0 -74
- package/build/styles/CardWidget/CardWidget.css +0 -64
- 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 -44
- 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 -8
- package/build/types/CardWidget/CardWidget.d.ts.map +0 -1
- package/build/types/CardWidget/CardWidget.types.d.ts +0 -52
- 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 -74
- package/src/CardContainer/CardContainer.less +0 -112
- package/src/CardContainer/CardContainer.test.tsx +0 -118
- package/src/CardContainer/CardContainer.tsx +0 -39
- package/src/CardContainer/CardContainer.types.ts +0 -50
- package/src/CardContainer/_stories/CardContainer.story.tsx +0 -136
- 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 -64
- package/src/CardWidget/CardWidget.less +0 -82
- package/src/CardWidget/CardWidget.test.tsx +0 -189
- package/src/CardWidget/CardWidget.tsx +0 -74
- package/src/CardWidget/CardWidget.types.ts +0 -60
- package/src/CardWidget/CardWidgetAction.tsx +0 -126
- package/src/CardWidget/_stories/CardWidget.story.tsx +0 -209
- package/src/CardWidget/_stories/CardWidget.test.story.tsx +0 -350
- package/src/CardWidget/index.ts +0 -3
|
@@ -1,32 +1,40 @@
|
|
|
1
|
-
import { useMemo
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
2
|
|
|
3
|
-
import SnackbarPortal
|
|
3
|
+
import SnackbarPortal from './SnackbarPortal';
|
|
4
4
|
import { SnackbarContext } from './SnackbarContext';
|
|
5
|
+
import useSnackbarManager from './useSnackbarManager';
|
|
5
6
|
|
|
6
7
|
export interface SnackbarProviderProps {
|
|
8
|
+
/**
|
|
9
|
+
* @deprecated Use per-Snackbar `duration` instead. Explicit millisecond values remain supported
|
|
10
|
+
* and are not automatically remapped when no `duration` is supplied.
|
|
11
|
+
* When neither option is supplied, the default is 4000ms (previously 4500ms), after entry finishes.
|
|
12
|
+
* To migrate, use `default` for 0–5000ms, `extended` for values above 5000ms, and `indefinite`
|
|
13
|
+
* for intentionally persistent notifications.
|
|
14
|
+
*/
|
|
7
15
|
timeout?: number;
|
|
8
16
|
children?: React.ReactNode;
|
|
9
17
|
}
|
|
10
18
|
|
|
11
|
-
export default function SnackbarProvider({ timeout
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
});
|
|
16
|
-
const { action, text, timestamp } = state;
|
|
19
|
+
export default function SnackbarProvider({ timeout, children }: SnackbarProviderProps) {
|
|
20
|
+
const { active, announcementKey, createSnackbar, dismissSnackbar, handleExited, visible } =
|
|
21
|
+
useSnackbarManager();
|
|
22
|
+
const contextValue = useMemo(() => ({ createSnackbar }), [createSnackbar]);
|
|
17
23
|
|
|
18
24
|
return (
|
|
19
|
-
<SnackbarContext.Provider
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
<SnackbarContext.Provider value={contextValue}>
|
|
26
|
+
{active ? (
|
|
27
|
+
<SnackbarPortal
|
|
28
|
+
// Each instance gets a fresh appear transition and live-region announcement.
|
|
29
|
+
key={active.id}
|
|
30
|
+
{...active.props}
|
|
31
|
+
announcementKey={announcementKey}
|
|
32
|
+
timeout={timeout}
|
|
33
|
+
visible={visible}
|
|
34
|
+
onDismissRequest={dismissSnackbar}
|
|
35
|
+
onExited={handleExited}
|
|
36
|
+
/>
|
|
37
|
+
) : null}
|
|
30
38
|
{children}
|
|
31
39
|
</SnackbarContext.Provider>
|
|
32
40
|
);
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { Meta, Source } from '@storybook/addon-docs/blocks';
|
|
2
|
+
|
|
3
|
+
<Meta title="Prompts/Snackbar/Accessibility" />
|
|
4
|
+
|
|
5
|
+
# Accessibility
|
|
6
|
+
|
|
7
|
+
## Announcements
|
|
8
|
+
|
|
9
|
+
Snackbar uses `role="status"`, `aria-live="polite"` and `aria-atomic="true"` for every sentiment,
|
|
10
|
+
including negative. Showing a message requests a polite announcement without moving focus.
|
|
11
|
+
There is no live region while the Provider is idle.
|
|
12
|
+
|
|
13
|
+
The localised hint “Press Escape to dismiss.” follows the message, including on touch-only devices.
|
|
14
|
+
Touch-specific wording and a small-screen close button are follow-up work in
|
|
15
|
+
[DS-8650](https://transferwise.atlassian.net/browse/DS-8650).
|
|
16
|
+
|
|
17
|
+
## Keyboard and dismissal
|
|
18
|
+
|
|
19
|
+
- The action follows normal tab order. Buttons support Enter and Space; links support Enter.
|
|
20
|
+
- Escape dismisses unless another overlay has already handled it.
|
|
21
|
+
- Desktop has a close IconButton labelled “Close”. On small screens it is hidden and not focusable.
|
|
22
|
+
- Swipe or drag down at least half the surface height to dismiss. Shorter or cancelled gestures return to place.
|
|
23
|
+
|
|
24
|
+
There is no shortcut to reach the action. Do not make Snackbar the only way to access an essential action;
|
|
25
|
+
focus management is tracked in [DS-8622](https://transferwise.atlassian.net/browse/DS-8622).
|
|
26
|
+
|
|
27
|
+
## Timing and motion
|
|
28
|
+
|
|
29
|
+
Timed messages start counting after entry and pause during hover, keyboard focus or a swipe.
|
|
30
|
+
Use `extended` for additional reading time or an action, and `indefinite` for persistent feedback.
|
|
31
|
+
Loading always prevents auto-dismiss; describe the progress in the message, not just the spinner.
|
|
32
|
+
|
|
33
|
+
Reduced motion removes entry/exit movement and scale, and swipe transitions. Check zoom/reflow and RTL
|
|
34
|
+
with your content; the visual test stories provide examples.
|
|
35
|
+
|
|
36
|
+
## Media
|
|
37
|
+
|
|
38
|
+
Include essential meaning in the message: custom media is outside its live region.
|
|
39
|
+
Hide decorative icons from assistive technology:
|
|
40
|
+
|
|
41
|
+
<Source
|
|
42
|
+
dark
|
|
43
|
+
code={`import { Button, SnackbarProvider, useSnackbar } from '@transferwise/components';
|
|
44
|
+
import { Card } from '@transferwise/icons';
|
|
45
|
+
|
|
46
|
+
function CardFeedback() {
|
|
47
|
+
const createSnackbar = useSnackbar();
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<Button v2 size="md" onClick={() => createSnackbar({
|
|
51
|
+
text: 'Card added to your wallet',
|
|
52
|
+
media: <Card aria-hidden />,
|
|
53
|
+
})}>
|
|
54
|
+
Show card confirmation
|
|
55
|
+
</Button>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export default function App() {
|
|
60
|
+
return (
|
|
61
|
+
<SnackbarProvider>
|
|
62
|
+
<CardFeedback />
|
|
63
|
+
</SnackbarProvider>
|
|
64
|
+
);
|
|
65
|
+
}`}
|
|
66
|
+
/>
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { Meta, Source } from '@storybook/addon-docs/blocks';
|
|
2
|
+
|
|
3
|
+
<Meta title="Prompts/Snackbar/Migration" />
|
|
4
|
+
|
|
5
|
+
# Migration
|
|
6
|
+
|
|
7
|
+
Existing `createSnackbar({ text, action })` calls continue to work with the updated design.
|
|
8
|
+
|
|
9
|
+
## Imports
|
|
10
|
+
|
|
11
|
+
- Replace the public `SnackbarProps` type with `SnackbarCreationProps`.
|
|
12
|
+
- Direct `Snackbar` and `SnackbarPortal` exports are removed. Use `SnackbarProvider` and `useSnackbar()` instead.
|
|
13
|
+
- The Provider, hook, Consumer, Context and their existing public types remain supported.
|
|
14
|
+
The hook still returns `createSnackbar` directly, not an object.
|
|
15
|
+
|
|
16
|
+
Wrap your app in one Provider and call the hook from a component inside it:
|
|
17
|
+
|
|
18
|
+
<Source
|
|
19
|
+
dark
|
|
20
|
+
code={`import { Button, SnackbarProvider, useSnackbar } from '@transferwise/components';
|
|
21
|
+
import type { SnackbarCreationProps } from '@transferwise/components';
|
|
22
|
+
|
|
23
|
+
const savedMessage: SnackbarCreationProps = {
|
|
24
|
+
text: 'Changes saved',
|
|
25
|
+
sentiment: 'success',
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
function SaveButton() {
|
|
29
|
+
const createSnackbar = useSnackbar();
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<Button v2 size="md" onClick={() => createSnackbar(savedMessage)}>
|
|
33
|
+
Show confirmation
|
|
34
|
+
</Button>
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export default function App() {
|
|
39
|
+
return (
|
|
40
|
+
<SnackbarProvider>
|
|
41
|
+
<SaveButton />
|
|
42
|
+
</SnackbarProvider>
|
|
43
|
+
);
|
|
44
|
+
}`}
|
|
45
|
+
/>
|
|
46
|
+
|
|
47
|
+
## Duration
|
|
48
|
+
|
|
49
|
+
The default changes from **4500ms to 4000ms**, counted after entry finishes.
|
|
50
|
+
Replace deprecated Provider `timeout` values with a per-message `duration`:
|
|
51
|
+
|
|
52
|
+
- `default`: 4 seconds, generally replacing 0–5000ms.
|
|
53
|
+
- `extended`: 6 seconds, for more reading time or an action, generally replacing values above 5000ms.
|
|
54
|
+
- `indefinite`: no timer, for intentionally persistent messages, including very large timeouts used to avoid expiry.
|
|
55
|
+
|
|
56
|
+
Explicit Provider timeouts still work and are **not automatically remapped**. A message's `duration`
|
|
57
|
+
takes precedence; `loading: true` always prevents auto-dismiss.
|
|
58
|
+
|
|
59
|
+
## Other changes
|
|
60
|
+
|
|
61
|
+
- `theme` and `timestamp` remain accepted but are deprecated and have no effect with the Provider.
|
|
62
|
+
- An empty string clears the current message and any waiting replacement.
|
|
63
|
+
- Review CSS and tests targeting the old `snackbar` DOM/classes: these now use `wds-Snackbar` and the shared prompt structure.
|
|
64
|
+
- Announcements change from assertive alerts to polite status messages. See [Accessibility](?path=/docs/prompts-snackbar-accessibility--docs).
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
-
import { useEffect
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
3
3
|
|
|
4
4
|
import { useRtlDiffI18n, withRTLDiff } from '../../../.storybook/decorators/RtlDiffDecorator';
|
|
5
5
|
import { Snackbar } from '../Snackbar';
|
|
6
|
+
import type { SnackbarCreationProps } from '../Snackbar.types';
|
|
7
|
+
import SnackbarProvider from '../SnackbarProvider';
|
|
8
|
+
import useSnackbar from '../useSnackbar';
|
|
6
9
|
|
|
7
10
|
export default {
|
|
8
11
|
component: Snackbar,
|
|
@@ -12,18 +15,23 @@ export default {
|
|
|
12
15
|
|
|
13
16
|
type Story = StoryObj<typeof Snackbar>;
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
function SnackbarStory({ text, action }: { text: string; action?: { label: string } }) {
|
|
18
|
-
const [timestamp, setTimestamp] = useState(0);
|
|
18
|
+
function ShowOnMount(props: SnackbarCreationProps) {
|
|
19
|
+
const createSnackbar = useSnackbar();
|
|
19
20
|
|
|
20
21
|
useEffect(() => {
|
|
21
|
-
|
|
22
|
-
|
|
22
|
+
createSnackbar(props);
|
|
23
|
+
// This visual fixture creates once per mount, not on every render of its props.
|
|
24
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
23
25
|
}, []);
|
|
24
26
|
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function SnackbarStory({ text, action }: { text: string; action?: { label: string } }) {
|
|
25
31
|
return (
|
|
26
|
-
<
|
|
32
|
+
<SnackbarProvider>
|
|
33
|
+
<ShowOnMount text={<span>{text}</span>} action={action} duration="indefinite" />
|
|
34
|
+
</SnackbarProvider>
|
|
27
35
|
);
|
|
28
36
|
}
|
|
29
37
|
|