@transferwise/components 46.116.1 → 46.117.0

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.
Files changed (59) hide show
  1. package/build/main.css +60 -131
  2. package/build/prompt/InlinePrompt/InlinePrompt.js +14 -8
  3. package/build/prompt/InlinePrompt/InlinePrompt.js.map +1 -1
  4. package/build/prompt/InlinePrompt/InlinePrompt.mjs +15 -9
  5. package/build/prompt/InlinePrompt/InlinePrompt.mjs.map +1 -1
  6. package/build/sentimentSurface/SentimentSurface.js +6 -5
  7. package/build/sentimentSurface/SentimentSurface.js.map +1 -1
  8. package/build/sentimentSurface/SentimentSurface.mjs +6 -5
  9. package/build/sentimentSurface/SentimentSurface.mjs.map +1 -1
  10. package/build/styles/button/Button.css +17 -17
  11. package/build/styles/button/Button.vars.css +16 -16
  12. package/build/styles/iconButton/IconButton.css +8 -8
  13. package/build/styles/link/Link.css +1 -0
  14. package/build/styles/main.css +60 -131
  15. package/build/styles/prompt/InlinePrompt/InlinePrompt.css +26 -105
  16. package/build/styles/sentimentSurface/SentimentSurface.css +8 -1
  17. package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts +19 -3
  18. package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts.map +1 -1
  19. package/build/types/sentimentSurface/SentimentSurface.d.ts +5 -4
  20. package/build/types/sentimentSurface/SentimentSurface.d.ts.map +1 -1
  21. package/build/types/sentimentSurface/SentimentSurface.types.d.ts +4 -16
  22. package/build/types/sentimentSurface/SentimentSurface.types.d.ts.map +1 -1
  23. package/build/types/test-utils/story-config.d.ts +24 -0
  24. package/build/types/test-utils/story-config.d.ts.map +1 -1
  25. package/package.json +12 -11
  26. package/src/button/Button.css +17 -17
  27. package/src/button/Button.less +1 -1
  28. package/src/button/Button.story.tsx +75 -110
  29. package/src/button/Button.tests.story.tsx +189 -0
  30. package/src/button/Button.vars.css +16 -16
  31. package/src/button/Button.vars.less +58 -18
  32. package/src/iconButton/IconButton.css +8 -8
  33. package/src/iconButton/IconButton.less +35 -4
  34. package/src/iconButton/IconButton.story.tsx +72 -3
  35. package/src/link/Link.css +1 -0
  36. package/src/link/Link.less +1 -0
  37. package/src/link/Link.story.tsx +28 -0
  38. package/src/main.css +60 -131
  39. package/src/prompt/InlinePrompt/InlinePrompt.css +26 -105
  40. package/src/prompt/InlinePrompt/InlinePrompt.less +31 -119
  41. package/src/prompt/InlinePrompt/InlinePrompt.spec.tsx +87 -29
  42. package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +223 -31
  43. package/src/prompt/InlinePrompt/InlinePrompt.tsx +42 -11
  44. package/src/sentimentSurface/SentimentSurface.css +8 -1
  45. package/src/sentimentSurface/SentimentSurface.docs.mdx +32 -495
  46. package/src/sentimentSurface/SentimentSurface.less +121 -114
  47. package/src/sentimentSurface/SentimentSurface.spec.tsx +31 -11
  48. package/src/sentimentSurface/SentimentSurface.story.tsx +323 -108
  49. package/src/sentimentSurface/SentimentSurface.tests.story.tsx +90 -40
  50. package/src/sentimentSurface/SentimentSurface.tsx +16 -9
  51. package/src/sentimentSurface/SentimentSurface.types.ts +5 -20
  52. package/src/test-utils/story-config.ts +0 -1
  53. package/build/sentimentSurface/classMap.js +0 -17
  54. package/build/sentimentSurface/classMap.js.map +0 -1
  55. package/build/sentimentSurface/classMap.mjs +0 -14
  56. package/build/sentimentSurface/classMap.mjs.map +0 -1
  57. package/build/types/sentimentSurface/classMap.d.ts +0 -4
  58. package/build/types/sentimentSurface/classMap.d.ts.map +0 -1
  59. package/src/sentimentSurface/classMap.ts +0 -15
@@ -1,462 +1,73 @@
1
- import { Meta, Source, ArgTypes } from '@storybook/addon-docs/blocks';
2
- import * as SentimentSurfaceStories from './SentimentSurface.story';
1
+ import { Meta, Source, Canvas } from '@storybook/addon-docs/blocks';
2
+ import * as stories from './SentimentSurface.story';
3
3
 
4
4
  <Meta title="Content/SentimentSurface/Developer Guide" />
5
5
 
6
- # SentimentSurface Developer Guide
6
+ # Developer Guide
7
7
 
8
- `SentimentSurface` is a polymorphic container component that establishes a semantic colour context by setting CSS custom properties (tokens) based on sentiment types. It does not apply any default background or text styling - instead, it provides access to sentiment-aware tokens that child components can use to style themselves appropriately.
8
+ SentimentSurface is a polymorphic container component that exposes and, optionally, applies contextual colour tokens
9
+ as CSS custom properties, based on sentiment types (`negative`, `warning`, `neutral`, `success`, `proposition`).
9
10
 
10
- ## Basic Usage
11
-
12
- Import and use the component with a required `sentiment` prop:
13
-
14
- <Source dark code={`
15
- import { SentimentSurface } from '@transferwise/components';
16
-
17
- <SentimentSurface sentiment="negative">Your payment has failed</SentimentSurface>
18
- `} />
19
-
20
- ### Props
21
-
22
- <ArgTypes of={SentimentSurfaceStories} />
23
-
24
- ## Sentiment Types
25
-
26
- The component supports five sentiment types (`negative`, `warning`, `neutral`, `proposition` and `success`), each communicating different types of information:
27
-
28
- ```tsx
29
- <SentimentSurface sentiment="negative">
30
- Your payment has failed. Please try again.
31
- </SentimentSurface>
32
-
33
- <SentimentSurface sentiment="warning">
34
- Action required: Please verify your email address.
35
- </SentimentSurface>
36
-
37
- <SentimentSurface sentiment="neutral">
38
- Your account is up to date.
39
- </SentimentSurface>
40
-
41
- <SentimentSurface sentiment="proposition">
42
- Try our new feature and save time on transfers.
43
- </SentimentSurface>
44
-
45
- <SentimentSurface sentiment="success">
46
- Your payment was successful!
47
- </SentimentSurface>
48
- ```
49
-
50
- ---
51
-
52
- ## Emphasis Levels
53
-
54
- Each sentiment type supports two emphasis levels that provide different sets of token values (`base`, `elevated`):
55
-
56
- ```tsx
57
- <SentimentSurface sentiment="success" emphasis="base">
58
- Base emphasis - provides tokens suited for subtle contexts
59
- </SentimentSurface>
60
-
61
- <SentimentSurface sentiment="success" emphasis="elevated">
62
- Elevated emphasis - provides tokens suited for prominent contexts
63
- </SentimentSurface>
64
- ```
65
-
66
- **When to use:**
67
-
68
- - **Base**: For inline notifications, subtle callouts, or when sentiment needs to be communicated without drawing too much attention
69
- - **Elevated**: For prominent banners, critical alerts, or when the sentiment should be immediately noticeable
70
-
71
- Note: The component does not apply background or text colours by default. Use the provided tokens in your styles to achieve the desired visual effect.
72
-
73
- ---
74
-
75
- ## Polymorphic Rendering
76
-
77
- The component is fully polymorphic, meaning it can render as any HTML element using the `as` prop while maintaining full type safety.
78
-
79
- ### Basic Examples
80
-
81
- ```tsx
82
- // Render as div (default)
83
- <SentimentSurface sentiment="neutral">
84
- Default div element
85
- </SentimentSurface>
86
-
87
- // Render as section
88
- <SentimentSurface sentiment="negative" as="section">
89
- Semantic section element
90
- </SentimentSurface>
91
-
92
- // Render as article
93
- <SentimentSurface sentiment="success" as="article">
94
- Article element for standalone content
95
- </SentimentSurface>
96
- ```
97
-
98
- ### With HTML Attributes
99
-
100
- The component accepts all valid HTML attributes for the rendered element:
101
-
102
- ```tsx
103
- // Section with ARIA attributes
104
- <SentimentSurface
105
- sentiment="negative"
106
- as="section"
107
- role="alert"
108
- aria-live="polite"
109
- aria-atomic="true"
110
- >
111
- Critical error message
112
- </SentimentSurface>
113
-
114
- // Article with data attributes
115
- <SentimentSurface
116
- sentiment="proposition"
117
- as="article"
118
- data-tracking-id="promo-banner"
119
- data-position="top"
120
- >
121
- Promotional content
122
- </SentimentSurface>
123
- ```
124
-
125
- ### Type Safety
126
-
127
- TypeScript provides full type checking for HTML attributes based on the `as` prop:
128
-
129
- ```tsx
130
- // ✅ Valid - section supports these attributes
131
- <SentimentSurface as="section" role="region" aria-labelledby="heading">
132
- Content
133
- </SentimentSurface>
134
-
135
- // ❌ TypeScript error - 'href' is not valid for 'div'
136
- <SentimentSurface as="div" href="/link">
137
- Content
138
- </SentimentSurface>
139
- ```
140
-
141
- ---
142
-
143
- ## Nesting Sentiment Surfaces
144
-
145
- Sentiment surfaces can be nested to create layered contexts. Each nested surface establishes its own colour context through CSS custom properties.
146
-
147
- ### Basic Nesting
148
-
149
- ```tsx
150
- <SentimentSurface sentiment="negative" emphasis="base">
151
- <Title size="large">Payment Failed</Title>
152
- <Body>There was an issue processing your payment.</Body>
153
-
154
- <SentimentSurface sentiment="neutral" emphasis="elevated">
155
- <Title size="small">What happened?</Title>
156
- <Body>Your card was declined by your bank.</Body>
157
- </SentimentSurface>
158
- </SentimentSurface>
159
- ```
160
-
161
- ### Multi-Level Nesting
162
-
163
- ```tsx
164
- <SentimentSurface sentiment="success" emphasis="base">
165
- Outer: Payment successful
166
- <SentimentSurface sentiment="neutral" emphasis="elevated">
167
- Inner: Transaction details
168
- <SentimentSurface sentiment="warning" emphasis="base">
169
- Deepest: Additional fees may apply
170
- </SentimentSurface>
171
- </SentimentSurface>
172
- </SentimentSurface>
173
- ```
174
-
175
- ### Nesting with Different Elements
176
-
177
- ```tsx
178
- <SentimentSurface sentiment="negative" as="section">
179
- <Title size="large">Error Section</Title>
180
-
181
- <SentimentSurface sentiment="neutral" as="article">
182
- <Title size="small">Details</Title>
183
- <Body>More information about the error.</Body>
184
- </SentimentSurface>
185
-
186
- <SentimentSurface sentiment="proposition" as="aside">
187
- <Body>Need help? Contact support.</Body>
188
- </SentimentSurface>
189
- </SentimentSurface>
190
- ```
191
-
192
- ---
193
-
194
- ## CSS Custom Properties (Tokens)
195
-
196
- The component sets CSS custom properties (CSS variables) that child components can use to style themselves according to the sentiment context. The component itself does not apply any visual styling - it simply makes these tokens available for use in your own styles or by sentiment-aware child components.
197
-
198
- ### Available Tokens
11
+ ## Available Tokens
199
12
 
200
13
  Each `SentimentSurface` sets tokens for content, interactive elements, and background surfaces. See the [Tokens story](?path=/story/content-sentimentsurface--tokens) for a visual demonstration of all tokens across sentiments and emphasis levels:
201
14
 
202
- #### Content Tokens
203
-
204
- ```css
205
- --color-sentiment-content-primary
206
- --color-sentiment-content-primary-hover
207
- --color-sentiment-content-primary-active
208
- ```
15
+ <Source dark language="html" code={`
16
+ --color-sentiment-content-primary
17
+ --color-sentiment-content-primary-hover
18
+ --color-sentiment-content-primary-active
209
19
 
210
- #### Interactive Primary Tokens
211
-
212
- ```css
213
20
  --color-sentiment-interactive-primary
214
21
  --color-sentiment-interactive-primary-hover
215
22
  --color-sentiment-interactive-primary-active
216
- ```
217
-
218
- #### Interactive Secondary Tokens
219
23
 
220
- ```css
221
24
  --color-sentiment-interactive-secondary
222
25
  --color-sentiment-interactive-secondary-hover
223
26
  --color-sentiment-interactive-secondary-active
224
- ```
225
27
 
226
- #### Interactive Secondary Neutral Tokens
227
-
228
- ```css
229
28
  --color-sentiment-interactive-secondary-neutral
230
29
  --color-sentiment-interactive-secondary-neutral-hover
231
30
  --color-sentiment-interactive-secondary-neutral-active
232
- ```
233
-
234
- #### Interactive Control Tokens
235
31
 
236
- ```css
237
32
  --color-sentiment-interactive-control
238
33
  --color-sentiment-interactive-control-hover
239
34
  --color-sentiment-interactive-control-active
240
- ```
241
-
242
- #### Background Surface Tokens
243
35
 
244
- ```css
245
36
  --color-sentiment-background-surface
246
37
  --color-sentiment-background-surface-hover
247
38
  --color-sentiment-background-surface-active
248
- ```
249
-
250
- ### Using Tokens in Component Styles
251
-
252
- Components can reference these tokens with fallbacks to maintain functionality outside of a `SentimentSurface`:
253
-
254
- ```css
255
- .wds-Button {
256
- /* Primary button uses interactive primary tokens */
257
- --Button-background: var(--color-sentiment-interactive-primary, var(--color-interactive-accent));
258
- --Button-background-hover: var(
259
- --color-sentiment-interactive-primary-hover,
260
- var(--color-interactive-accent-hover)
261
- );
262
- --Button-background-active: var(
263
- --color-sentiment-interactive-primary-active,
264
- var(--color-interactive-accent-active)
265
- );
266
-
267
- /* Button text color uses control tokens */
268
- --Button-color: var(--color-sentiment-interactive-control, var(--color-interactive-control));
269
- --Button-color-hover: var(
270
- --color-sentiment-interactive-control-hover,
271
- var(--color-interactive-control-hover)
272
- );
273
- --Button-color-active: var(
274
- --color-sentiment-interactive-control-active,
275
- var(--color-interactive-control-active)
276
- );
277
- }
278
-
279
- .wds-Button--secondary {
280
- /* Secondary button uses secondary tokens */
281
- --Button-background: var(
282
- --color-sentiment-interactive-secondary,
283
- var(--color-interactive-neutral)
284
- );
285
- --Button-background-hover: var(
286
- --color-sentiment-interactive-secondary-hover,
287
- var(--color-interactive-neutral-hover)
288
- );
289
- --Button-color: var(--color-sentiment-interactive-primary, var(--color-interactive-primary));
290
- }
291
- ```
292
-
293
- ### Example: Button in Sentiment Context
39
+ `} />
294
40
 
295
- ```tsx
296
- import { Button, Body } from '@transferwise/components';
41
+ ## Using Tokens in Components
297
42
 
298
- // Button automatically adapts to the sentiment context
299
- <SentimentSurface sentiment="success">
300
- <Body>Your payment was successful!</Body>
301
- <Button v2 priority="primary">View Receipt</Button>
302
- <Button v2 priority="secondary">Send Another</Button>
303
- </SentimentSurface>
43
+ When building `SentimentSurface`-aware components, the exposed tokens should be [referenced with fallbacks](https://developer.mozilla.org/en-US/docs/Web/CSS/Guides/Cascading_variables/Using_custom_properties#custom_property_fallback_values) to maintain functionality outside a said surfaces.
304
44
 
305
- // Same buttons in different sentiment context
306
- <SentimentSurface sentiment="negative">
307
- <Body>Payment failed</Body>
308
- <Button v2 priority="primary">Try Again</Button>
309
- <Button v2 priority="secondary">Cancel</Button>
310
- </SentimentSurface>
311
- ```
45
+ <Canvas of={stories.CustomComponents} />
312
46
 
313
- The buttons will automatically use appropriate colours based on the sentiment context.
314
-
315
- ### Applying Sentiment Tokens
47
+ ## Polymorphic Rendering
316
48
 
317
- To visually style content within a SentimentSurface, use the provided tokens in your styles:
49
+ The component is fully polymorphic, meaning it can render as any HTML element using the `as` prop while maintaining full type safety, accepting all valid HTML attributes for the rendered element:
318
50
 
319
- ```tsx
320
- // Apply tokens via inline styles
321
- <SentimentSurface sentiment="warning">
322
- <div
323
- style={{
324
- padding: '24px',
325
- borderRadius: '16px',
326
- backgroundColor: 'var(--color-sentiment-background-surface)',
327
- color: 'var(--color-sentiment-content-primary)',
328
- }}
51
+ <Source dark language="tsx" code={`
52
+ // Renders as HTML 'section' with valid HTML attributes
53
+ <SentimentSurface
54
+ sentiment="negative"
55
+ as="section"
56
+ role="alert"
57
+ aria-live="polite"
58
+ data-position="top"
329
59
  >
330
- This content uses the sentiment tokens for styling
331
- </div>
332
- </SentimentSurface>
333
- ```
334
-
335
- ### Creating Custom Components with Sentiment Tokens
336
-
337
- You can create your own components that respect sentiment context:
338
-
339
- ```tsx
340
- // CustomCard.css
341
- .custom-card {
342
- background-color: var(
343
- --color-sentiment-background-surface,
344
- var(--color-background-surface)
345
- );
346
- color: var(
347
- --color-sentiment-content-primary,
348
- var(--color-content-primary)
349
- );
350
- border: 1px solid var(
351
- --color-sentiment-interactive-secondary,
352
- var(--color-border-neutral)
353
- );
354
- }
355
-
356
- .custom-card:hover {
357
- background-color: var(
358
- --color-sentiment-background-surface-hover,
359
- var(--color-background-surface-hover)
360
- );
361
- }
362
-
363
- .custom-card-link {
364
- color: var(
365
- --color-sentiment-interactive-primary,
366
- var(--color-interactive-primary)
367
- );
368
- }
369
-
370
- .custom-card-link:hover {
371
- color: var(
372
- --color-sentiment-interactive-primary-hover,
373
- var(--color-interactive-primary-hover)
374
- );
375
- }
376
- ```
377
-
378
- ```tsx
379
- // CustomCard.tsx
380
- function CustomCard({ children }) {
381
- return (
382
- <div className="custom-card">
383
- {children}
384
- <a href="#" className="custom-card-link">
385
- Learn more
386
- </a>
387
- </div>
388
- );
389
- }
390
-
391
- // Usage
392
- <SentimentSurface sentiment="warning">
393
- <CustomCard>This card adapts to the warning sentiment</CustomCard>
394
- </SentimentSurface>;
395
- ```
396
-
397
- ---
398
-
399
- ## Accessibility Considerations
400
-
401
- ### Semantic HTML
402
-
403
- Use appropriate HTML elements via the `as` prop to ensure proper document structure:
404
-
405
- ```tsx
406
- // ✅ Good - semantic HTML for alerts
407
- <SentimentSurface
408
- sentiment="negative"
409
- as="section"
410
- role="alert"
411
- aria-live="assertive"
412
- >
413
- Critical error: Payment failed
414
- </SentimentSurface>
415
-
416
- // ✅ Good - article for standalone content
417
- <SentimentSurface sentiment="proposition" as="article">
418
- <Title size="large">New Feature Available</Title>
419
- <Body>Try our new instant transfer feature...</Body>
420
- </SentimentSurface>
421
- ```
422
-
423
- ### ARIA Attributes
424
-
425
- Add appropriate ARIA attributes for screen readers:
426
-
427
- ```tsx
428
- // For errors or critical warnings
429
- <SentimentSurface
430
- sentiment="negative"
431
- role="alert"
432
- aria-live="assertive"
433
- aria-atomic="true"
434
- >
435
- Error: Your session has expired
436
- </SentimentSurface>
60
+ Critical error message
61
+ </SentimentSurface>
437
62
 
438
- // For important but not critical information
439
- <SentimentSurface
440
- sentiment="warning"
441
- role="status"
442
- aria-live="polite"
443
- >
444
- Please verify your email address
445
- </SentimentSurface>
63
+ // TypeScript error - 'href' is not a valid attribute for a 'div'
446
64
 
447
- // For regions with headings
448
- <SentimentSurface
449
- sentiment="success"
450
- as="section"
451
- role="region"
452
- aria-labelledby="success-heading"
453
- >
454
- <Title id="success-heading" size="large">Payment Successful</Title>
455
- <Body>Your payment has been processed.</Body>
65
+ <SentimentSurface as="div" href="/link">
66
+ Content
456
67
  </SentimentSurface>
457
- ```
68
+ `} />
458
69
 
459
- ### Color Contrast
70
+ ## Accessibility Considerations
460
71
 
461
72
  The tokens provided by the component are designed with WCAG AA contrast ratios in mind:
462
73
 
@@ -469,81 +80,7 @@ Always test your content for contrast compliance, especially when:
469
80
  - Using small text sizes
470
81
  - Displaying important information
471
82
 
472
- ### Don't Rely on Color Alone
473
-
474
- Sentiment should not be conveyed through colour alone. Always include:
475
-
476
- ```tsx
477
- // ✅ Good - includes text and icons
478
- <SentimentSurface sentiment="negative">
479
- <ErrorIcon aria-hidden="true" />
480
- <strong>Error:</strong> Payment failed
481
- </SentimentSurface>
482
-
483
- // ❌ Bad - relies only on colour
484
- <SentimentSurface sentiment="negative">
485
- Payment failed
486
- </SentimentSurface>
487
- ```
488
-
489
- ### Focus Management
490
-
491
- When using for alerts, consider focus management:
492
-
493
- ```tsx
494
- function ErrorBanner({ error }) {
495
- const errorRef = useRef<HTMLElement>(null);
496
-
497
- useEffect(() => {
498
- if (error && errorRef.current) {
499
- errorRef.current.focus();
500
- }
501
- }, [error]);
502
-
503
- if (!error) return null;
504
-
505
- return (
506
- <SentimentSurface
507
- ref={errorRef}
508
- sentiment="negative"
509
- as="section"
510
- role="alert"
511
- tabIndex={-1}
512
- aria-live="assertive"
513
- >
514
- {error.message}
515
- </SentimentSurface>
516
- );
517
- }
518
- ```
519
-
520
- ---
521
-
522
- ## Best Practices
523
-
524
- ### Do's
525
-
526
- ✅ Use semantic HTML elements via the `as` prop
527
- ✅ Include ARIA attributes for screen readers
528
- ✅ Combine colour with icons and text for clarity
529
- ✅ Use appropriate sentiment types for the content
530
- ✅ Leverage CSS tokens for consistent theming
531
- ✅ Test contrast ratios for accessibility
532
- ✅ Provide focus management for critical alerts
533
-
534
- ### Don'ts
535
-
536
- ❌ Don't rely solely on colour to convey meaning
537
- ❌ Don't nest too many levels (3+ levels can be confusing)
538
- ❌ Don't override sentiment tokens without good reason
539
- ❌ Don't use `sentiment="negative"` for informational content
540
- ❌ Don't forget to test with screen readers
541
-
542
- ---
543
-
544
- ## Further Reading
83
+ ### Further Reading
545
84
 
546
- - [Component Source Code](./SentimentSurface.tsx)
547
- - [Storybook Examples](?path=/docs/content-sentimentsurface--docs)
548
85
  - [WCAG Color Contrast Guidelines](https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum.html)
549
86
  - [ARIA Live Regions](https://www.w3.org/WAI/WCAG21/Understanding/status-messages.html)