@transferwise/components 0.0.0-experimental-276a15d → 0.0.0-experimental-dd4f4a5
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/main.css +1 -3
- package/build/prompt/ActionPrompt/ActionPrompt.js +4 -4
- package/build/prompt/ActionPrompt/ActionPrompt.js.map +1 -1
- package/build/prompt/ActionPrompt/ActionPrompt.mjs +4 -4
- package/build/prompt/ActionPrompt/ActionPrompt.mjs.map +1 -1
- package/build/prompt/InfoPrompt/InfoPrompt.js.map +1 -1
- package/build/prompt/InfoPrompt/InfoPrompt.mjs.map +1 -1
- package/build/styles/main.css +1 -3
- package/build/styles/prompt/InfoPrompt/InfoPrompt.css +1 -3
- package/build/types/prompt/ActionPrompt/ActionPrompt.d.ts +0 -7
- package/build/types/prompt/ActionPrompt/ActionPrompt.d.ts.map +1 -1
- package/build/types/prompt/InfoPrompt/InfoPrompt.d.ts +2 -4
- package/build/types/prompt/InfoPrompt/InfoPrompt.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/iconButton/IconButton.story.tsx +48 -173
- package/src/listItem/_stories/ListItem.story.tsx +1 -0
- package/src/main.css +1 -3
- package/src/prompt/ActionPrompt/ActionPrompt.accessibility.docs.mdx +17 -1
- package/src/prompt/ActionPrompt/ActionPrompt.story.tsx +107 -299
- package/src/prompt/ActionPrompt/ActionPrompt.test.story.tsx +3 -86
- package/src/prompt/ActionPrompt/ActionPrompt.tsx +4 -11
- package/src/prompt/InfoPrompt/InfoPrompt.css +1 -3
- package/src/prompt/InfoPrompt/InfoPrompt.less +4 -4
- package/src/prompt/InfoPrompt/InfoPrompt.story.tsx +86 -93
- package/src/prompt/InfoPrompt/InfoPrompt.test.story.tsx +1 -54
- package/src/prompt/InfoPrompt/InfoPrompt.tsx +2 -4
- package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +29 -24
- package/src/sentimentSurface/SentimentSurface.docs.mdx +1 -1
- package/src/sentimentSurface/SentimentSurface.story.tsx +1 -1
- package/src/sentimentSurface/SentimentSurface.test.story.tsx +1 -1
- package/src/iconButton/IconButton.test.story.tsx +0 -194
- package/src/prompt/InfoPrompt/InfoPrompt.accessibility.docs.mdx +0 -79
- package/src/prompt/InlinePrompt/InlinePrompt.accessibility.docs.mdx +0 -63
- package/src/prompt/InlinePrompt/InlinePrompt.test.story.tsx +0 -21
|
@@ -1,194 +0,0 @@
|
|
|
1
|
-
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
-
import { Menu, Plus, Settings, Star, Travel } from '@transferwise/icons';
|
|
3
|
-
import { action } from 'storybook/actions';
|
|
4
|
-
import IconButton from './IconButton';
|
|
5
|
-
import SentimentSurface from '../sentimentSurface';
|
|
6
|
-
import { allModes } from '../../.storybook/modes';
|
|
7
|
-
|
|
8
|
-
export default {
|
|
9
|
-
title: 'Actions/IconButton/Tests',
|
|
10
|
-
component: IconButton,
|
|
11
|
-
tags: ['!autodocs', '!manifest'],
|
|
12
|
-
} satisfies Meta<typeof IconButton>;
|
|
13
|
-
|
|
14
|
-
type Story = StoryObj<typeof IconButton>;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* IconButton displayed across all themes and sentiments for visual regression testing.
|
|
18
|
-
*/
|
|
19
|
-
export const AllThemesAndSentiments: Story = {
|
|
20
|
-
render: () => {
|
|
21
|
-
const priorities = ['primary', 'secondary', 'tertiary', 'minimal', 'disabled'] as const;
|
|
22
|
-
const sentiments = ['negative', 'warning', 'neutral', 'success', 'proposition'] as const;
|
|
23
|
-
const icons = [Plus, Settings, Star, Travel];
|
|
24
|
-
|
|
25
|
-
return (
|
|
26
|
-
<div style={{ display: 'flex', flexDirection: 'column' }}>
|
|
27
|
-
{/* Header row with priority labels */}
|
|
28
|
-
<div style={{ display: 'flex', alignItems: 'flex-end', marginBottom: '4px', gap: '8px' }}>
|
|
29
|
-
<div style={{ width: '82px', paddingLeft: '8px' }} />
|
|
30
|
-
{priorities.map((priority) => (
|
|
31
|
-
<div
|
|
32
|
-
key={priority}
|
|
33
|
-
style={{
|
|
34
|
-
width: '32px',
|
|
35
|
-
textAlign: 'center',
|
|
36
|
-
fontSize: '11px',
|
|
37
|
-
fontWeight: 'bold',
|
|
38
|
-
writingMode: 'vertical-rl',
|
|
39
|
-
transform: 'rotate(180deg)',
|
|
40
|
-
height: '60px',
|
|
41
|
-
display: 'flex',
|
|
42
|
-
alignItems: 'center',
|
|
43
|
-
justifyContent: 'center',
|
|
44
|
-
}}
|
|
45
|
-
>
|
|
46
|
-
{priority}
|
|
47
|
-
</div>
|
|
48
|
-
))}
|
|
49
|
-
</div>
|
|
50
|
-
|
|
51
|
-
{/* Rows for each sentiment with base and elevated emphasis */}
|
|
52
|
-
{sentiments.flatMap((sentiment) => [
|
|
53
|
-
<SentimentSurface
|
|
54
|
-
key={`${sentiment}-base`}
|
|
55
|
-
sentiment={sentiment}
|
|
56
|
-
emphasis="base"
|
|
57
|
-
style={{ display: 'flex', alignItems: 'center', padding: '8px 0', gap: '8px' }}
|
|
58
|
-
>
|
|
59
|
-
<div
|
|
60
|
-
style={{
|
|
61
|
-
width: '82px',
|
|
62
|
-
fontSize: '11px',
|
|
63
|
-
fontWeight: 'bold',
|
|
64
|
-
textAlign: 'left',
|
|
65
|
-
paddingLeft: '8px',
|
|
66
|
-
}}
|
|
67
|
-
>
|
|
68
|
-
{sentiment} (base)
|
|
69
|
-
</div>
|
|
70
|
-
<IconButton
|
|
71
|
-
size={32}
|
|
72
|
-
aria-label="Primary action"
|
|
73
|
-
priority="primary"
|
|
74
|
-
type="default"
|
|
75
|
-
onClick={action('button click')}
|
|
76
|
-
>
|
|
77
|
-
<Plus />
|
|
78
|
-
</IconButton>
|
|
79
|
-
<IconButton
|
|
80
|
-
size={32}
|
|
81
|
-
aria-label="Secondary action"
|
|
82
|
-
priority="secondary"
|
|
83
|
-
type="default"
|
|
84
|
-
onClick={action('button click')}
|
|
85
|
-
>
|
|
86
|
-
<Settings />
|
|
87
|
-
</IconButton>
|
|
88
|
-
<IconButton
|
|
89
|
-
size={32}
|
|
90
|
-
aria-label="Tertiary action"
|
|
91
|
-
priority="tertiary"
|
|
92
|
-
type="default"
|
|
93
|
-
onClick={action('button click')}
|
|
94
|
-
>
|
|
95
|
-
<Star />
|
|
96
|
-
</IconButton>
|
|
97
|
-
<IconButton
|
|
98
|
-
size={32}
|
|
99
|
-
aria-label="Minimal action"
|
|
100
|
-
priority="minimal"
|
|
101
|
-
type="default"
|
|
102
|
-
onClick={action('button click')}
|
|
103
|
-
>
|
|
104
|
-
<Travel />
|
|
105
|
-
</IconButton>
|
|
106
|
-
<IconButton
|
|
107
|
-
size={32}
|
|
108
|
-
aria-label="Disabled action"
|
|
109
|
-
priority="primary"
|
|
110
|
-
type="default"
|
|
111
|
-
disabled
|
|
112
|
-
onClick={action('button click')}
|
|
113
|
-
>
|
|
114
|
-
<Menu />
|
|
115
|
-
</IconButton>
|
|
116
|
-
</SentimentSurface>,
|
|
117
|
-
<SentimentSurface
|
|
118
|
-
key={`${sentiment}-elevated`}
|
|
119
|
-
sentiment={sentiment}
|
|
120
|
-
emphasis="elevated"
|
|
121
|
-
style={{ display: 'flex', alignItems: 'center', padding: '8px 0', gap: '8px' }}
|
|
122
|
-
>
|
|
123
|
-
<div
|
|
124
|
-
style={{
|
|
125
|
-
width: '82px',
|
|
126
|
-
fontSize: '11px',
|
|
127
|
-
fontWeight: 'bold',
|
|
128
|
-
textAlign: 'left',
|
|
129
|
-
paddingLeft: '8px',
|
|
130
|
-
}}
|
|
131
|
-
>
|
|
132
|
-
{sentiment} (elevated)
|
|
133
|
-
</div>
|
|
134
|
-
<IconButton
|
|
135
|
-
size={32}
|
|
136
|
-
aria-label="Primary action"
|
|
137
|
-
priority="primary"
|
|
138
|
-
type="default"
|
|
139
|
-
onClick={action('button click')}
|
|
140
|
-
>
|
|
141
|
-
<Plus />
|
|
142
|
-
</IconButton>
|
|
143
|
-
<IconButton
|
|
144
|
-
size={32}
|
|
145
|
-
aria-label="Secondary action"
|
|
146
|
-
priority="secondary"
|
|
147
|
-
type="default"
|
|
148
|
-
onClick={action('button click')}
|
|
149
|
-
>
|
|
150
|
-
<Settings />
|
|
151
|
-
</IconButton>
|
|
152
|
-
<IconButton
|
|
153
|
-
size={32}
|
|
154
|
-
aria-label="Tertiary action"
|
|
155
|
-
priority="tertiary"
|
|
156
|
-
type="default"
|
|
157
|
-
onClick={action('button click')}
|
|
158
|
-
>
|
|
159
|
-
<Star />
|
|
160
|
-
</IconButton>
|
|
161
|
-
<IconButton
|
|
162
|
-
size={32}
|
|
163
|
-
aria-label="Minimal action"
|
|
164
|
-
priority="minimal"
|
|
165
|
-
type="default"
|
|
166
|
-
onClick={action('button click')}
|
|
167
|
-
>
|
|
168
|
-
<Travel />
|
|
169
|
-
</IconButton>
|
|
170
|
-
<IconButton
|
|
171
|
-
size={32}
|
|
172
|
-
aria-label="Disabled action"
|
|
173
|
-
priority="primary"
|
|
174
|
-
type="default"
|
|
175
|
-
disabled
|
|
176
|
-
onClick={action('button click')}
|
|
177
|
-
>
|
|
178
|
-
<Menu />
|
|
179
|
-
</IconButton>
|
|
180
|
-
</SentimentSurface>,
|
|
181
|
-
])}
|
|
182
|
-
</div>
|
|
183
|
-
);
|
|
184
|
-
},
|
|
185
|
-
parameters: {
|
|
186
|
-
padding: '16px',
|
|
187
|
-
variants: ['default', 'dark', 'bright-green', 'forest-green'],
|
|
188
|
-
chromatic: {
|
|
189
|
-
dark: allModes.dark,
|
|
190
|
-
brightGreen: allModes.brightGreen,
|
|
191
|
-
forestGreen: allModes.forestGreen,
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
};
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { Meta, Source } from '@storybook/addon-docs/blocks';
|
|
2
|
-
|
|
3
|
-
<Meta title="Prompts/InfoPrompt/Accessibility" />
|
|
4
|
-
|
|
5
|
-
# Accessibility
|
|
6
|
-
|
|
7
|
-
Under the hood, `InfoPrompt` is marked as `role="region"` for a section of content that users might want to navigate to directly.
|
|
8
|
-
|
|
9
|
-
By default, it's labelled by the `title` and described by the `description`.
|
|
10
|
-
|
|
11
|
-
## Announcement Behaviour
|
|
12
|
-
|
|
13
|
-
`InfoPrompt` is designed for contextual messages that appear within a screen. Unlike `ActionPrompt`, it can be configured to announce to screen readers using ARIA roles:
|
|
14
|
-
|
|
15
|
-
- **`role="status"`**: Politely announces updates when the screen reader is idle. Use for non-critical success messages or informational updates (e.g., "Your profile has been saved").
|
|
16
|
-
- **`role="alert"`**: Immediately interrupts to announce urgent messages. Use for time-sensitive information that requires immediate attention (e.g., errors, warnings, deadlines).
|
|
17
|
-
|
|
18
|
-
**Default behavior:** Without a role, the prompt won't be announced automatically. Users will encounter it when navigating the page.
|
|
19
|
-
|
|
20
|
-
<Source
|
|
21
|
-
dark
|
|
22
|
-
code={`
|
|
23
|
-
// Polite announcement for non-critical updates
|
|
24
|
-
<InfoPrompt
|
|
25
|
-
sentiment="success"
|
|
26
|
-
description="Your profile has been saved"
|
|
27
|
-
role="status"
|
|
28
|
-
/>
|
|
29
|
-
|
|
30
|
-
// Immediate announcement for urgent messages
|
|
31
|
-
|
|
32
|
-
<InfoPrompt
|
|
33
|
-
sentiment="negative"
|
|
34
|
-
title="Session expired"
|
|
35
|
-
description="Your session has expired. Please log in again."
|
|
36
|
-
role="alert"
|
|
37
|
-
/>
|
|
38
|
-
`}
|
|
39
|
-
/>
|
|
40
|
-
|
|
41
|
-
## Custom Labels
|
|
42
|
-
|
|
43
|
-
If you want to provide a custom label for screen readers, you can use the `aria-label` prop. Make sure to include all necessary information in it, because when provided, the default labelling will be removed.
|
|
44
|
-
|
|
45
|
-
<Source
|
|
46
|
-
dark
|
|
47
|
-
code={`
|
|
48
|
-
<InfoPrompt
|
|
49
|
-
sentiment="negative"
|
|
50
|
-
title="Payment failed"
|
|
51
|
-
description="Unable to process payment."
|
|
52
|
-
aria-label="Critical error: Your payment could not be processed. Please update your payment method and try again within 24 hours."
|
|
53
|
-
/>
|
|
54
|
-
`}
|
|
55
|
-
/>
|
|
56
|
-
|
|
57
|
-
## Media
|
|
58
|
-
|
|
59
|
-
Custom media icons should include their own accessibility attributes. Use the `title` prop on icons to provide accessible names for screen readers:
|
|
60
|
-
|
|
61
|
-
<Source
|
|
62
|
-
dark
|
|
63
|
-
code={`
|
|
64
|
-
<InfoPrompt
|
|
65
|
-
sentiment="success"
|
|
66
|
-
description="Your travel account is ready!"
|
|
67
|
-
media={{ asset: <Travel title="Travel feature" /> }}
|
|
68
|
-
/>
|
|
69
|
-
|
|
70
|
-
<InfoPrompt
|
|
71
|
-
sentiment="warning"
|
|
72
|
-
title="Business travel"
|
|
73
|
-
description="Book your business trip with Wise."
|
|
74
|
-
media={{ asset: <Briefcase title="Business" /> }}
|
|
75
|
-
/>
|
|
76
|
-
`}
|
|
77
|
-
/>
|
|
78
|
-
|
|
79
|
-
**Note:** Unlike `ActionPrompt` (which uses `media['aria-label']`) and `InlinePrompt` (which uses `mediaLabel`), `InfoPrompt` requires you to add accessibility attributes directly to the icon component you pass.
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { Meta, Source } from '@storybook/addon-docs/blocks';
|
|
2
|
-
|
|
3
|
-
<Meta title="Prompts/InlinePrompt/Accessibility" />
|
|
4
|
-
|
|
5
|
-
# Accessibility
|
|
6
|
-
|
|
7
|
-
Under the hood, `InlinePrompt` is marked as `role="region"` for a section of content that users might want to navigate to directly.
|
|
8
|
-
|
|
9
|
-
By default, it's labelled by the `media` icon and the prompt's text content.
|
|
10
|
-
|
|
11
|
-
## Announcement Behaviour
|
|
12
|
-
|
|
13
|
-
`InlinePrompt` appears alongside a specific component on the screen (e.g., input fields, list items). It should not be announced via screen reader—neither assertively (`role="alert"`) nor politely (`role="status"`).
|
|
14
|
-
|
|
15
|
-
**Note:** For immediate user feedback that requires announcement, use [InfoPrompt](?path=/docs/prompts-infoprompt--docs) instead.
|
|
16
|
-
|
|
17
|
-
## Media Label
|
|
18
|
-
|
|
19
|
-
You can use the `mediaLabel` prop to override the icon's accessible name announced by screen readers. This is especially useful for custom icons or when you want to provide more context than the default sentiment label.
|
|
20
|
-
|
|
21
|
-
By default, sentiment icons have these labels:
|
|
22
|
-
|
|
23
|
-
- `positive`: "Success:"
|
|
24
|
-
- `negative`: "Error:"
|
|
25
|
-
- `warning`: "Warning:"
|
|
26
|
-
- `neutral`: "Information:"
|
|
27
|
-
- `proposition`: No label (GiftBox icon is decorative by default)
|
|
28
|
-
|
|
29
|
-
<Source
|
|
30
|
-
dark
|
|
31
|
-
code={`
|
|
32
|
-
<InlinePrompt
|
|
33
|
-
media={<Travel />}
|
|
34
|
-
sentiment="positive"
|
|
35
|
-
mediaLabel="Travel feature enabled: "
|
|
36
|
-
>
|
|
37
|
-
Your travel account is set up and ready to use.
|
|
38
|
-
</InlinePrompt>
|
|
39
|
-
|
|
40
|
-
<InlinePrompt
|
|
41
|
-
media={<Clock />}
|
|
42
|
-
sentiment="warning"
|
|
43
|
-
mediaLabel="Delayed processing: "
|
|
44
|
-
>
|
|
45
|
-
The account verification is taking longer than usual.
|
|
46
|
-
</InlinePrompt>
|
|
47
|
-
`}
|
|
48
|
-
/>
|
|
49
|
-
|
|
50
|
-
## Muted State
|
|
51
|
-
|
|
52
|
-
When a prompt is associated with a disabled component, use the `muted` prop to visually indicate the relationship while keeping the prompt accessible and interactive. The prompt remains keyboard accessible and can include interactive elements like links.
|
|
53
|
-
|
|
54
|
-
<Source
|
|
55
|
-
dark
|
|
56
|
-
code={`
|
|
57
|
-
<InlinePrompt muted sentiment="warning" mediaLabel="Feature locked: ">
|
|
58
|
-
Please <Link href="#">confirm your residential address</Link> to activate this feature.
|
|
59
|
-
</InlinePrompt>
|
|
60
|
-
`}
|
|
61
|
-
/>
|
|
62
|
-
|
|
63
|
-
The muted state uses a special backslash circle icon to indicate the disabled relationship, but the prompt itself remains fully accessible to screen readers and keyboard users.
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { StoryObj } from '@storybook/react-webpack5';
|
|
2
|
-
import { Travel } from '@transferwise/icons';
|
|
3
|
-
import { InlinePrompt } from './InlinePrompt';
|
|
4
|
-
import { withVariantConfig } from '../../../.storybook/helpers';
|
|
5
|
-
|
|
6
|
-
export default {
|
|
7
|
-
title: 'Prompts/InlinePrompt/Tests',
|
|
8
|
-
component: InlinePrompt,
|
|
9
|
-
tags: ['!autodocs'],
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
type Story = StoryObj<typeof InlinePrompt>;
|
|
13
|
-
|
|
14
|
-
export const TinyScreen: Story = {
|
|
15
|
-
render: () => (
|
|
16
|
-
<InlinePrompt sentiment="positive" media={<Travel />}>
|
|
17
|
-
Your travel money account is now active and ready to use for international transactions.
|
|
18
|
-
</InlinePrompt>
|
|
19
|
-
),
|
|
20
|
-
...withVariantConfig(['400%']),
|
|
21
|
-
};
|