@transferwise/components 46.116.0 → 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 (71) hide show
  1. package/build/alert/Alert.js +2 -1
  2. package/build/alert/Alert.js.map +1 -1
  3. package/build/alert/Alert.mjs +2 -1
  4. package/build/alert/Alert.mjs.map +1 -1
  5. package/build/main.css +60 -139
  6. package/build/prompt/InlinePrompt/InlinePrompt.js +14 -8
  7. package/build/prompt/InlinePrompt/InlinePrompt.js.map +1 -1
  8. package/build/prompt/InlinePrompt/InlinePrompt.mjs +15 -9
  9. package/build/prompt/InlinePrompt/InlinePrompt.mjs.map +1 -1
  10. package/build/sentimentSurface/SentimentSurface.js +6 -5
  11. package/build/sentimentSurface/SentimentSurface.js.map +1 -1
  12. package/build/sentimentSurface/SentimentSurface.mjs +6 -5
  13. package/build/sentimentSurface/SentimentSurface.mjs.map +1 -1
  14. package/build/styles/button/Button.css +17 -17
  15. package/build/styles/button/Button.vars.css +16 -16
  16. package/build/styles/iconButton/IconButton.css +8 -8
  17. package/build/styles/inputs/Input.css +2 -4
  18. package/build/styles/inputs/TextArea.css +2 -4
  19. package/build/styles/link/Link.css +1 -0
  20. package/build/styles/main.css +60 -139
  21. package/build/styles/popover/Popover.css +2 -4
  22. package/build/styles/prompt/InlinePrompt/InlinePrompt.css +26 -105
  23. package/build/styles/sentimentSurface/SentimentSurface.css +4 -1
  24. package/build/types/alert/Alert.d.ts.map +1 -1
  25. package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts +19 -3
  26. package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts.map +1 -1
  27. package/build/types/sentimentSurface/SentimentSurface.d.ts +5 -4
  28. package/build/types/sentimentSurface/SentimentSurface.d.ts.map +1 -1
  29. package/build/types/sentimentSurface/SentimentSurface.types.d.ts +4 -16
  30. package/build/types/sentimentSurface/SentimentSurface.types.d.ts.map +1 -1
  31. package/build/types/test-utils/story-config.d.ts +24 -0
  32. package/build/types/test-utils/story-config.d.ts.map +1 -1
  33. package/package.json +13 -12
  34. package/src/alert/Alert.tsx +3 -1
  35. package/src/button/Button.css +17 -17
  36. package/src/button/Button.less +1 -1
  37. package/src/button/Button.story.tsx +75 -110
  38. package/src/button/Button.tests.story.tsx +189 -0
  39. package/src/button/Button.vars.css +16 -16
  40. package/src/button/Button.vars.less +58 -18
  41. package/src/iconButton/IconButton.css +8 -8
  42. package/src/iconButton/IconButton.less +35 -4
  43. package/src/iconButton/IconButton.story.tsx +72 -3
  44. package/src/inputs/Input.css +2 -4
  45. package/src/inputs/TextArea.css +2 -4
  46. package/src/link/Link.css +1 -0
  47. package/src/link/Link.less +1 -0
  48. package/src/link/Link.story.tsx +28 -0
  49. package/src/main.css +60 -139
  50. package/src/popover/Popover.css +2 -4
  51. package/src/prompt/InlinePrompt/InlinePrompt.css +26 -105
  52. package/src/prompt/InlinePrompt/InlinePrompt.less +31 -119
  53. package/src/prompt/InlinePrompt/InlinePrompt.spec.tsx +87 -29
  54. package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +223 -31
  55. package/src/prompt/InlinePrompt/InlinePrompt.tsx +42 -11
  56. package/src/sentimentSurface/SentimentSurface.css +4 -1
  57. package/src/sentimentSurface/SentimentSurface.docs.mdx +37 -478
  58. package/src/sentimentSurface/SentimentSurface.less +118 -114
  59. package/src/sentimentSurface/SentimentSurface.spec.tsx +31 -11
  60. package/src/sentimentSurface/SentimentSurface.story.tsx +325 -147
  61. package/src/sentimentSurface/SentimentSurface.tests.story.tsx +85 -86
  62. package/src/sentimentSurface/SentimentSurface.tsx +16 -9
  63. package/src/sentimentSurface/SentimentSurface.types.ts +5 -20
  64. package/src/test-utils/story-config.ts +0 -1
  65. package/build/sentimentSurface/classMap.js +0 -17
  66. package/build/sentimentSurface/classMap.js.map +0 -1
  67. package/build/sentimentSurface/classMap.mjs +0 -14
  68. package/build/sentimentSurface/classMap.mjs.map +0 -1
  69. package/build/types/sentimentSurface/classMap.d.ts +0 -4
  70. package/build/types/sentimentSurface/classMap.d.ts.map +0 -1
  71. package/src/sentimentSurface/classMap.ts +0 -15
@@ -1,14 +1,14 @@
1
1
  import { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { Defrost } from '@transferwise/icons';
3
+ import Body from '../body';
4
+ import Button from '../button';
5
+ import Header from '../header';
6
+ import Link from '../link';
7
+ import IconButton from '../iconButton';
8
+ import StatusIcon from '../statusIcon';
2
9
  import SentimentSurface from './SentimentSurface';
3
- import { storyConfig } from '../test-utils';
4
10
  import type { Sentiment, Emphasis } from './SentimentSurface.types';
5
11
 
6
- const withContainer = (Story: () => JSX.Element) => (
7
- <div style={{ display: 'flex', justifyContent: 'center', padding: '2rem' }}>
8
- <Story />
9
- </div>
10
- );
11
-
12
12
  const withComponentGrid = (Story: () => JSX.Element) => (
13
13
  <div
14
14
  style={{
@@ -24,8 +24,9 @@ const withComponentGrid = (Story: () => JSX.Element) => (
24
24
  );
25
25
 
26
26
  /**
27
- * SentimentSurface is a polymorphic container component that applies contextual background colours
28
- * and text styling based on sentiment types.
27
+ * SentimentSurface is a polymorphic container component that exposes and, optionally, applies
28
+ * contextual colour tokens as CSS custom properties, based on sentiment types (`negative`,
29
+ * `warning`, `neutral`, `success`, `proposition`).
29
30
  */
30
31
  const meta: Meta<typeof SentimentSurface> = {
31
32
  component: SentimentSurface,
@@ -35,46 +36,71 @@ const meta: Meta<typeof SentimentSurface> = {
35
36
  control: 'select',
36
37
  options: ['negative', 'warning', 'neutral', 'success', 'proposition'],
37
38
  description: 'The sentiment type that determines the colour scheme',
39
+ table: {
40
+ type: { summary: 'Sentiment' },
41
+ },
38
42
  },
39
43
  emphasis: {
40
- control: 'select',
44
+ control: 'inline-radio',
41
45
  options: ['base', 'elevated'],
42
46
  description: 'The emphasis level affecting background and text contrast',
43
47
  table: {
44
- defaultValue: { summary: 'base' },
48
+ defaultValue: { summary: '"base"' },
45
49
  },
46
50
  },
47
- as: {
48
- control: 'text',
49
- description: 'The underlying HTML element to render',
51
+ hasBaseStyles: {
52
+ control: 'boolean',
53
+ description:
54
+ 'If true, sets the `background-color` and `color` on the container. Otherwise, only exposes the tokens as CSS custom properties without rendering.',
50
55
  table: {
51
- defaultValue: { summary: 'div' },
56
+ defaultValue: { summary: 'true' },
52
57
  },
53
58
  },
54
- children: {
59
+ as: {
55
60
  control: 'text',
56
- description: 'Content to render inside the surface',
61
+ description: 'The underlying HTML element to render.',
62
+ table: {
63
+ defaultValue: {
64
+ summary: '"div"',
65
+ },
66
+ type: { summary: 'string' },
67
+ },
57
68
  },
58
69
  className: {
70
+ table: {
71
+ type: { summary: 'string' },
72
+ },
59
73
  control: 'text',
60
- description: 'Additional CSS classes',
61
74
  },
62
75
  id: {
76
+ table: {
77
+ type: { summary: 'string' },
78
+ },
63
79
  control: 'text',
64
- description: 'Unique identifier for the component',
65
80
  },
66
- testId: {
81
+ 'data-testid': {
67
82
  control: 'text',
68
- description: 'Test ID for React Testing Library',
83
+ table: {
84
+ type: { summary: 'string' },
85
+ },
86
+ },
87
+ children: {
88
+ table: {
89
+ type: { summary: 'ReactNode' },
90
+ },
91
+ control: false,
69
92
  },
70
93
  },
71
94
  args: {
72
95
  sentiment: 'neutral',
73
96
  emphasis: 'base',
97
+ hasBaseStyles: undefined,
98
+ as: undefined,
99
+ className: undefined,
100
+ id: undefined,
101
+ 'data-testid': undefined,
74
102
  children: 'This is a sentiment surface',
75
- style: { padding: '24px', borderRadius: '16px' },
76
103
  },
77
- decorators: [withContainer],
78
104
  parameters: {
79
105
  docs: {
80
106
  toc: true,
@@ -94,86 +120,15 @@ export const Playground: Story = {
94
120
  args: {
95
121
  sentiment: 'negative',
96
122
  emphasis: 'base',
97
- children: 'Customise the sentiment and emphasis using the controls below',
98
- },
99
- };
100
-
101
- /**
102
- * There are five different sentiment types that communicate different types of information or states.
103
- */
104
- export const Sentiments: Story = {
105
- render: (args) => (
106
- <>
107
- <SentimentSurface {...args} sentiment="negative">
108
- Negative: Your payment has failed
109
- </SentimentSurface>
110
- <SentimentSurface {...args} sentiment="warning">
111
- Warning: Action required on your account
112
- </SentimentSurface>
113
- <SentimentSurface {...args} sentiment="neutral">
114
- Neutral: Your account is up to date
115
- </SentimentSurface>
116
- <SentimentSurface {...args} sentiment="success">
117
- Success: Your payment was successful
118
- </SentimentSurface>
119
- <SentimentSurface {...args} sentiment="proposition">
120
- Proposition: Try our new feature
121
- </SentimentSurface>
122
- </>
123
- ),
124
- parameters: {
125
- controls: { disable: true },
126
- },
127
- decorators: [withComponentGrid],
128
- };
129
-
130
- /**
131
- * Each sentiment type has two emphasis levels – base and elevated – to provide different levels of visual prominence.
132
- */
133
- export const EmphasisLevels: Story = {
134
- render: (args) => (
135
- <>
136
- <SentimentSurface {...args} sentiment="negative" emphasis="base">
137
- Negative - Base emphasis
138
- </SentimentSurface>
139
- <SentimentSurface {...args} sentiment="negative" emphasis="elevated">
140
- Negative - Elevated emphasis
141
- </SentimentSurface>
142
- <SentimentSurface {...args} sentiment="success" emphasis="base">
143
- Success - Base emphasis
144
- </SentimentSurface>
145
- <SentimentSurface {...args} sentiment="success" emphasis="elevated">
146
- Success - Elevated emphasis
147
- </SentimentSurface>
148
- </>
149
- ),
150
- parameters: {
151
- controls: { disable: true },
152
- },
153
- decorators: [withComponentGrid],
154
- };
155
-
156
- /**
157
- * The component can be rendered as any HTML element using the `as` prop.
158
- */
159
- export const PolymorphicRendering: Story = {
160
- render: (args) => (
161
- <>
162
- <SentimentSurface {...args} sentiment="negative">
163
- Rendered as div (default)
164
- </SentimentSurface>
165
- <SentimentSurface {...args} sentiment="negative" as="section">
166
- Rendered as section
167
- </SentimentSurface>
168
- <SentimentSurface {...args} sentiment="negative" as="article">
169
- Rendered as article
170
- </SentimentSurface>
171
- </>
172
- ),
173
- parameters: {
174
- controls: { disable: true },
123
+ children: (
124
+ <div className="p-a-2">
125
+ This is a custom div demonstrating a sentiment surface. It exposes CSS custom properties for
126
+ the selected sentiment type and emphasis level and, optionally, applies background and text
127
+ colours.
128
+ </div>
129
+ ),
175
130
  },
176
- decorators: [withComponentGrid],
131
+ tags: ['!autodocs'],
177
132
  };
178
133
 
179
134
  const sentiments: Sentiment[] = ['negative', 'warning', 'neutral', 'success', 'proposition'];
@@ -240,31 +195,102 @@ const TokenSwatch = ({ token }: { token: string }) => (
240
195
  );
241
196
 
242
197
  /**
243
- * Visual demonstration of the CSS custom properties (tokens) set by each sentiment and emphasis combination.
244
- * These tokens enable child components to automatically adapt their styling to the sentiment context.
198
+ * Each sentiment type has two emphasis levels `base` and `elevated` to provide different levels of visual prominence.
199
+ *
200
+ * **When to use:**
201
+ *
202
+ * - `Base`: For inline notifications, subtle callouts, or when sentiment needs to be communicated without drawing too much attention
203
+ * - `Elevated`: For prominent banners, critical alerts, or when the sentiment should be immediately noticeable
204
+ *
205
+ */
206
+ export const EmphasisLevels: Story = {
207
+ render: (args) => (
208
+ <>
209
+ <SentimentSurface {...args} sentiment="negative" emphasis="base">
210
+ <div className="p-a-2">Negative - Base emphasis</div>
211
+ </SentimentSurface>
212
+ <SentimentSurface {...args} sentiment="negative" emphasis="elevated">
213
+ <div className="p-a-2">Negative - Elevated emphasis</div>
214
+ </SentimentSurface>
215
+ <SentimentSurface {...args} sentiment="success" emphasis="base">
216
+ <div className="p-a-2">Success - Base emphasis</div>
217
+ </SentimentSurface>
218
+ <SentimentSurface {...args} sentiment="success" emphasis="elevated">
219
+ <div className="p-a-2">Success - Elevated emphasis</div>
220
+ </SentimentSurface>
221
+ </>
222
+ ),
223
+ parameters: {
224
+ controls: { disable: true },
225
+ },
226
+ decorators: [withComponentGrid],
227
+ };
228
+
229
+ /**
230
+ * By default, `SentimentSurface` exposes the tokens as CSS custom properties and also applies
231
+ * the base styles for `background-color` and `color`.
232
+ * However, you can choose to only expose the CSS custom properties by setting the `hasBaseStyles`
233
+ * prop to `false`. This is useful when you want to create custom components that adapt to the
234
+ * sentiment context without applying default styles.
235
+ */
236
+ export const BaseStyles: Story = {
237
+ render: (args) => (
238
+ <>
239
+ <SentimentSurface
240
+ sentiment="success"
241
+ style={{ border: `1px dashed var(--color-sentiment-content-primary)` }}
242
+ >
243
+ <div className="p-a-2">This example exposes and applies the tokens.</div>
244
+ </SentimentSurface>
245
+ <SentimentSurface
246
+ hasBaseStyles={false}
247
+ sentiment="success"
248
+ style={{ border: `1px dashed var(--color-sentiment-content-primary)` }}
249
+ >
250
+ <div className="p-a-2">This example only exposes the tokens without applying them.</div>
251
+ <div
252
+ className="p-a-2"
253
+ style={{
254
+ backgroundColor: 'var(--color-sentiment-background-surface)',
255
+ color: 'var(--color-sentiment-content-primary)',
256
+ }}
257
+ >
258
+ Which means you have to apply them yourself.
259
+ </div>
260
+ </SentimentSurface>
261
+ </>
262
+ ),
263
+ parameters: {
264
+ controls: { disable: true },
265
+ },
266
+ decorators: [withComponentGrid],
267
+ };
268
+
269
+ /**
270
+ * The component exposes token groups for all 5 sentiment types (`negative`, `warning`, `neutral`, `proposition` and `success`) each of them with two emphasis levels (`base` and `elevated`).
245
271
  */
246
- export const Tokens: Story = {
272
+ export const ExposedTokens: Story = {
247
273
  render: () => (
248
- <div style={{ display: 'flex', flexDirection: 'column', gap: '32px', maxWidth: '100%' }}>
274
+ <section style={{ display: 'flex', flexDirection: 'column', gap: '32px', maxWidth: '100%' }}>
249
275
  {sentiments.map((sentiment) =>
250
276
  emphasisLevels.map((emphasis) => (
251
277
  <SentimentSurface
252
278
  key={`${sentiment}-${emphasis}`}
253
279
  sentiment={sentiment}
254
280
  emphasis={emphasis}
255
- style={{ padding: '24px', borderRadius: '16px' }}
281
+ style={{
282
+ padding: '24px',
283
+ borderRadius: '16px',
284
+ }}
256
285
  >
257
- <div style={{ marginBottom: '16px' }}>
258
- <strong
259
- style={{
260
- fontSize: '16px',
261
- textTransform: 'capitalize',
262
- color: 'var(--color-sentiment-content-primary)',
263
- }}
264
- >
265
- {sentiment} - {emphasis}
266
- </strong>
267
- </div>
286
+ <h4
287
+ className="d-block m-b-2 text-capitalize np-text-title-body"
288
+ style={{
289
+ color: 'inherit',
290
+ }}
291
+ >
292
+ {sentiment} - {emphasis}
293
+ </h4>
268
294
  <div
269
295
  style={{
270
296
  display: 'grid',
@@ -274,18 +300,19 @@ export const Tokens: Story = {
274
300
  >
275
301
  {tokenCategories.map((category) => (
276
302
  <div key={category.name}>
277
- <div
303
+ <h5
278
304
  style={{
305
+ color: 'inherit',
279
306
  fontSize: '12px',
280
307
  fontWeight: 600,
281
308
  marginBottom: '8px',
282
309
  textTransform: 'uppercase',
283
310
  letterSpacing: '0.5px',
284
- opacity: 0.7,
311
+ opacity: 0.8,
285
312
  }}
286
313
  >
287
314
  {category.name}
288
- </div>
315
+ </h5>
289
316
  {category.tokens.map((token) => (
290
317
  <TokenSwatch key={token} token={token} />
291
318
  ))}
@@ -295,10 +322,15 @@ export const Tokens: Story = {
295
322
  </SentimentSurface>
296
323
  )),
297
324
  )}
298
- </div>
325
+ </section>
299
326
  ),
300
327
  parameters: {
301
328
  controls: { disable: true },
329
+ docs: {
330
+ canvas: {
331
+ sourceState: 'hidden',
332
+ },
333
+ },
302
334
  },
303
335
  decorators: [
304
336
  (Story: () => JSX.Element) => (
@@ -309,32 +341,178 @@ export const Tokens: Story = {
309
341
  ],
310
342
  };
311
343
 
312
- export const AllVariants = storyConfig(
313
- {
314
- tags: ['!autodocs'],
315
- parameters: {
316
- padding: '0',
317
- controls: { disable: true },
344
+ /**
345
+ * Sentiment surfaces can be nested to create layered contexts. Each nested surface establishes its own colour context through CSS custom properties.
346
+ */
347
+ export const NestingSurfaces: Story = {
348
+ parameters: {
349
+ controls: { disable: true },
350
+ },
351
+ render: (args) => {
352
+ return (
353
+ <SentimentSurface sentiment="success" emphasis="base" className="p-a-1">
354
+ Success base sentiment surface
355
+ <SentimentSurface sentiment="neutral" emphasis="elevated" className="p-a-1 m-t-1">
356
+ Neutral elevated sentiment surface
357
+ <SentimentSurface sentiment="warning" emphasis="base" className="p-a-1 m-t-1">
358
+ Warning base sentiment surface
359
+ </SentimentSurface>
360
+ </SentimentSurface>
361
+ </SentimentSurface>
362
+ );
363
+ },
364
+ };
365
+
366
+ /**
367
+ * Some DS components (namely `Button`, `StatusIcon`, and `IconButton`) automatically adapt to the sentiment context when used within a `SentimentSurface`.
368
+ */
369
+ export const SentimentAwareComponents: Story = {
370
+ name: 'Sentiment-aware Components',
371
+ parameters: {
372
+ controls: { disable: true },
373
+ docs: {
374
+ canvas: {
375
+ sourceState: 'hidden',
376
+ },
318
377
  },
319
- render: () => (
320
- <div
321
- className="sentiment-surface-variants"
322
- style={{ display: 'flex', flexDirection: 'column', gap: '16px', maxWidth: '800px' }}
323
- >
324
- {sentiments.map((sentiment) =>
325
- emphasisLevels.map((emphasis) => (
326
- <SentimentSurface
327
- key={`${sentiment}-${emphasis}`}
328
- sentiment={sentiment}
329
- emphasis={emphasis}
330
- style={{ padding: '24px', borderRadius: '16px' }}
331
- >
332
- {sentiment} - {emphasis} emphasis
333
- </SentimentSurface>
334
- )),
335
- )}
378
+ },
379
+ render: function Render(args) {
380
+ const inner = (
381
+ <div className="p-a-2 m-b-2 sentimentAwareComponent">
382
+ <Body>
383
+ This text and its <Link href="#">inline links</Link> should use sentiment-matched colour.
384
+ </Body>
385
+ <IconButton size={32}>
386
+ <Defrost />
387
+ </IconButton>
388
+ <StatusIcon size={32} sentiment="positive" />
389
+ <Button v2 priority="primary" size="sm">
390
+ Primary
391
+ </Button>
392
+ <Button v2 priority="secondary" size="sm">
393
+ Secondary
394
+ </Button>
336
395
  </div>
396
+ );
397
+
398
+ return (
399
+ <>
400
+ <Header level="group" title="No sentiment surface" />
401
+ {inner}
402
+
403
+ <Header level="group" title="Success sentiment surface" />
404
+ <SentimentSurface sentiment="success">{inner}</SentimentSurface>
405
+
406
+ <Header level="group" title="Negative sentiment surface" />
407
+ <SentimentSurface sentiment="negative">{inner}</SentimentSurface>
408
+ </>
409
+ );
410
+ },
411
+ decorators: [
412
+ withComponentGrid,
413
+ (Story) => (
414
+ <>
415
+ <style>
416
+ {`
417
+ .sentimentAwareComponent {
418
+ display: flex;
419
+ flex-wrap: wrap;
420
+ gap: var(--size-8);
421
+
422
+ >:first-child {
423
+ width: 100%;
424
+ }
425
+ }
426
+ `}
427
+ </style>
428
+ <Story />
429
+ </>
337
430
  ),
431
+ ],
432
+ };
433
+
434
+ function CustomCard({ children, className }: { className?: string; children: React.ReactNode }) {
435
+ return (
436
+ <div
437
+ className={`p-a-1 d-flex align-items-center justify-content-between custom-card ${className}`}
438
+ >
439
+ {children}
440
+ <Button v2 size="sm">
441
+ Interact with me
442
+ </Button>
443
+ </div>
444
+ );
445
+ }
446
+
447
+ export const CustomComponents: Story = {
448
+ tags: ['!autodocs', '!dev'],
449
+ render: (args) => (
450
+ <>
451
+ <style>{`
452
+ .custom-card {
453
+ background-color: var(
454
+ --color-sentiment-background-surface,
455
+ var(--color-background-surface)
456
+ );
457
+
458
+ color: var(
459
+ --color-sentiment-content-primary,
460
+ var(--color-content-primary)
461
+ );
462
+
463
+ gap: var(--size-16);
464
+ }
465
+ `}</style>
466
+
467
+ <CustomCard className="m-b-2">This component works outside a SentimentSurface</CustomCard>
468
+
469
+ <SentimentSurface sentiment="negative">
470
+ <CustomCard>This component adapts to the context of the SentimentSurface</CustomCard>
471
+ </SentimentSurface>
472
+ </>
473
+ ),
474
+ parameters: {
475
+ docs: {
476
+ source: {
477
+ code: `
478
+ // CSS
479
+ .custom-card {
480
+ color: var(
481
+ --color-sentiment-content-primary,
482
+ var(--color-content-primary)
483
+ );
484
+ border: 1px solid var(
485
+ --color-sentiment-interactive-secondary,
486
+ var(--color-border-neutral)
487
+ );
488
+ gap: var(--size-16);
489
+ }
490
+
491
+ // JSX
492
+ function CustomCard({ children }) {
493
+ return (
494
+ <div className="p-a-1 d-flex align-items-center justify-content-between custom-card">
495
+ {children}
496
+ <Button v2 size="sm">
497
+ Interact with me
498
+ </Button>
499
+ </div>
500
+ );
501
+ }
502
+
503
+ function View() {
504
+ return (
505
+ <>
506
+ <CustomCard>This card works outside a SentimentSurface</CustomCard>
507
+
508
+ <SentimentSurface sentiment="negative">
509
+ <CustomCard>This card adapts to the warning sentiment</CustomCard>
510
+ </SentimentSurface>
511
+ </>
512
+ );
513
+ }
514
+ `,
515
+ },
516
+ },
338
517
  },
339
- { variants: ['default', 'dark', 'bright-green', 'forest-green'] },
340
- );
518
+ };