@transferwise/components 46.116.1 → 46.117.1
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 +145 -156
- package/build/prompt/InlinePrompt/InlinePrompt.js +14 -8
- package/build/prompt/InlinePrompt/InlinePrompt.js.map +1 -1
- package/build/prompt/InlinePrompt/InlinePrompt.mjs +15 -9
- package/build/prompt/InlinePrompt/InlinePrompt.mjs.map +1 -1
- package/build/sentimentSurface/SentimentSurface.js +6 -5
- package/build/sentimentSurface/SentimentSurface.js.map +1 -1
- package/build/sentimentSurface/SentimentSurface.mjs +6 -5
- package/build/sentimentSurface/SentimentSurface.mjs.map +1 -1
- package/build/styles/button/Button.css +22 -22
- package/build/styles/button/Button.vars.css +21 -21
- package/build/styles/iconButton/IconButton.css +8 -8
- package/build/styles/link/Link.css +1 -0
- package/build/styles/main.css +145 -156
- package/build/styles/prompt/InlinePrompt/InlinePrompt.css +26 -105
- package/build/styles/sentimentSurface/SentimentSurface.css +88 -21
- package/build/types/button/_stories/helpers.d.ts +11 -0
- package/build/types/button/_stories/helpers.d.ts.map +1 -0
- package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts +19 -3
- package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts.map +1 -1
- package/build/types/sentimentSurface/SentimentSurface.d.ts +5 -4
- package/build/types/sentimentSurface/SentimentSurface.d.ts.map +1 -1
- package/build/types/sentimentSurface/SentimentSurface.types.d.ts +4 -16
- package/build/types/sentimentSurface/SentimentSurface.types.d.ts.map +1 -1
- package/build/types/test-utils/story-config.d.ts +25 -1
- package/build/types/test-utils/story-config.d.ts.map +1 -1
- package/package.json +13 -12
- package/src/button/Button.css +22 -22
- package/src/button/Button.less +1 -1
- package/src/button/Button.vars.css +21 -21
- package/src/button/Button.vars.less +63 -23
- package/src/button/{Button.accessibility.docs.mdx → _stories/Button.accessibility.docs.mdx} +1 -1
- package/src/button/_stories/Button.brightGreen.tests.story.tsx +31 -0
- package/src/button/_stories/Button.dark.tests.story.tsx +25 -0
- package/src/button/_stories/Button.default.tests.story.tsx +25 -0
- package/src/button/_stories/Button.forestGreen.tests.story.tsx +28 -0
- package/src/button/{Button.story.tsx → _stories/Button.story.tsx} +78 -113
- package/src/button/_stories/Button.tests.story.tsx +139 -0
- package/src/button/_stories/helpers.tsx +118 -0
- package/src/iconButton/IconButton.css +8 -8
- package/src/iconButton/IconButton.less +35 -4
- package/src/iconButton/IconButton.story.tsx +72 -3
- package/src/link/Link.css +1 -0
- package/src/link/Link.less +1 -0
- package/src/link/Link.story.tsx +28 -0
- package/src/main.css +145 -156
- package/src/prompt/InlinePrompt/InlinePrompt.css +26 -105
- package/src/prompt/InlinePrompt/InlinePrompt.less +31 -119
- package/src/prompt/InlinePrompt/InlinePrompt.spec.tsx +87 -29
- package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +223 -31
- package/src/prompt/InlinePrompt/InlinePrompt.tsx +42 -11
- package/src/sentimentSurface/SentimentSurface.css +88 -21
- package/src/sentimentSurface/SentimentSurface.docs.mdx +32 -495
- package/src/sentimentSurface/SentimentSurface.less +151 -114
- package/src/sentimentSurface/SentimentSurface.spec.tsx +31 -11
- package/src/sentimentSurface/SentimentSurface.story.tsx +323 -108
- package/src/sentimentSurface/SentimentSurface.tests.story.tsx +90 -40
- package/src/sentimentSurface/SentimentSurface.tsx +16 -9
- package/src/sentimentSurface/SentimentSurface.types.ts +5 -20
- package/src/test-utils/story-config.ts +5 -1
- package/build/sentimentSurface/classMap.js +0 -17
- package/build/sentimentSurface/classMap.js.map +0 -1
- package/build/sentimentSurface/classMap.mjs +0 -14
- package/build/sentimentSurface/classMap.mjs.map +0 -1
- package/build/types/sentimentSurface/classMap.d.ts +0 -4
- package/build/types/sentimentSurface/classMap.d.ts.map +0 -1
- package/src/button/Button.tests.story.tsx +0 -27
- package/src/sentimentSurface/classMap.ts +0 -15
|
@@ -1,462 +1,73 @@
|
|
|
1
|
-
import { Meta, Source,
|
|
2
|
-
import * as
|
|
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
|
-
#
|
|
6
|
+
# Developer Guide
|
|
7
7
|
|
|
8
|
-
|
|
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
|
-
##
|
|
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
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
296
|
-
import { Button, Body } from '@transferwise/components';
|
|
41
|
+
## Using Tokens in Components
|
|
297
42
|
|
|
298
|
-
|
|
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
|
-
|
|
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
|
-
|
|
314
|
-
|
|
315
|
-
### Applying Sentiment Tokens
|
|
47
|
+
## Polymorphic Rendering
|
|
316
48
|
|
|
317
|
-
|
|
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
|
-
|
|
320
|
-
//
|
|
321
|
-
<SentimentSurface
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
-
|
|
331
|
-
</
|
|
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
|
-
//
|
|
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
|
-
|
|
448
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
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)
|