@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.
- package/build/main.css +60 -131
- 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 +17 -17
- package/build/styles/button/Button.vars.css +16 -16
- package/build/styles/iconButton/IconButton.css +8 -8
- package/build/styles/link/Link.css +1 -0
- package/build/styles/main.css +60 -131
- package/build/styles/prompt/InlinePrompt/InlinePrompt.css +26 -105
- package/build/styles/sentimentSurface/SentimentSurface.css +8 -1
- 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 +24 -0
- package/build/types/test-utils/story-config.d.ts.map +1 -1
- package/package.json +12 -11
- package/src/button/Button.css +17 -17
- package/src/button/Button.less +1 -1
- package/src/button/Button.story.tsx +75 -110
- package/src/button/Button.tests.story.tsx +189 -0
- package/src/button/Button.vars.css +16 -16
- package/src/button/Button.vars.less +58 -18
- 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 +60 -131
- 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 +8 -1
- package/src/sentimentSurface/SentimentSurface.docs.mdx +32 -495
- package/src/sentimentSurface/SentimentSurface.less +121 -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 +0 -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/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
|
|
28
|
-
*
|
|
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,45 +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: '
|
|
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
|
-
|
|
48
|
-
control: '
|
|
49
|
-
description:
|
|
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: '
|
|
56
|
+
defaultValue: { summary: 'true' },
|
|
52
57
|
},
|
|
53
58
|
},
|
|
54
|
-
|
|
59
|
+
as: {
|
|
55
60
|
control: 'text',
|
|
56
|
-
description: '
|
|
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
|
-
|
|
81
|
+
'data-testid': {
|
|
67
82
|
control: 'text',
|
|
68
|
-
|
|
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
103
|
},
|
|
76
|
-
decorators: [withContainer],
|
|
77
104
|
parameters: {
|
|
78
105
|
docs: {
|
|
79
106
|
toc: true,
|
|
@@ -94,75 +121,14 @@ export const Playground: Story = {
|
|
|
94
121
|
sentiment: 'negative',
|
|
95
122
|
emphasis: 'base',
|
|
96
123
|
children: (
|
|
97
|
-
<div
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
color: 'var(--color-sentiment-content-primary)',
|
|
102
|
-
}}
|
|
103
|
-
>
|
|
104
|
-
This is a custom div demostrating a sentiment surface.
|
|
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.
|
|
105
128
|
</div>
|
|
106
129
|
),
|
|
107
130
|
},
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Each sentiment type has two emphasis levels – base and elevated – to provide different levels of visual prominence.
|
|
112
|
-
*/
|
|
113
|
-
export const EmphasisLevels: Story = {
|
|
114
|
-
render: (args) => (
|
|
115
|
-
<>
|
|
116
|
-
<SentimentSurface {...args} sentiment="negative" emphasis="base">
|
|
117
|
-
<div
|
|
118
|
-
style={{
|
|
119
|
-
padding: '24px',
|
|
120
|
-
backgroundColor: 'var(--color-sentiment-background-surface)',
|
|
121
|
-
color: 'var(--color-sentiment-content-primary)',
|
|
122
|
-
}}
|
|
123
|
-
>
|
|
124
|
-
Negative - Base emphasis
|
|
125
|
-
</div>
|
|
126
|
-
</SentimentSurface>
|
|
127
|
-
<SentimentSurface {...args} sentiment="negative" emphasis="elevated">
|
|
128
|
-
<div
|
|
129
|
-
style={{
|
|
130
|
-
padding: '24px',
|
|
131
|
-
backgroundColor: 'var(--color-sentiment-background-surface)',
|
|
132
|
-
color: 'var(--color-sentiment-content-primary)',
|
|
133
|
-
}}
|
|
134
|
-
>
|
|
135
|
-
Negative - Elevated emphasis
|
|
136
|
-
</div>
|
|
137
|
-
</SentimentSurface>
|
|
138
|
-
<SentimentSurface {...args} sentiment="success" emphasis="base">
|
|
139
|
-
<div
|
|
140
|
-
style={{
|
|
141
|
-
padding: '24px',
|
|
142
|
-
backgroundColor: 'var(--color-sentiment-background-surface)',
|
|
143
|
-
color: 'var(--color-sentiment-content-primary)',
|
|
144
|
-
}}
|
|
145
|
-
>
|
|
146
|
-
Success - Base emphasis
|
|
147
|
-
</div>
|
|
148
|
-
</SentimentSurface>
|
|
149
|
-
<SentimentSurface {...args} sentiment="success" emphasis="elevated">
|
|
150
|
-
<div
|
|
151
|
-
style={{
|
|
152
|
-
padding: '24px',
|
|
153
|
-
backgroundColor: 'var(--color-sentiment-background-surface)',
|
|
154
|
-
color: 'var(--color-sentiment-content-primary)',
|
|
155
|
-
}}
|
|
156
|
-
>
|
|
157
|
-
Success - Elevated emphasis
|
|
158
|
-
</div>
|
|
159
|
-
</SentimentSurface>
|
|
160
|
-
</>
|
|
161
|
-
),
|
|
162
|
-
parameters: {
|
|
163
|
-
controls: { disable: true },
|
|
164
|
-
},
|
|
165
|
-
decorators: [withComponentGrid],
|
|
131
|
+
tags: ['!autodocs'],
|
|
166
132
|
};
|
|
167
133
|
|
|
168
134
|
const sentiments: Sentiment[] = ['negative', 'warning', 'neutral', 'success', 'proposition'];
|
|
@@ -229,12 +195,83 @@ const TokenSwatch = ({ token }: { token: string }) => (
|
|
|
229
195
|
);
|
|
230
196
|
|
|
231
197
|
/**
|
|
232
|
-
*
|
|
233
|
-
*
|
|
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
|
+
*
|
|
234
205
|
*/
|
|
235
|
-
export const
|
|
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`).
|
|
271
|
+
*/
|
|
272
|
+
export const ExposedTokens: Story = {
|
|
236
273
|
render: () => (
|
|
237
|
-
<
|
|
274
|
+
<section style={{ display: 'flex', flexDirection: 'column', gap: '32px', maxWidth: '100%' }}>
|
|
238
275
|
{sentiments.map((sentiment) =>
|
|
239
276
|
emphasisLevels.map((emphasis) => (
|
|
240
277
|
<SentimentSurface
|
|
@@ -244,20 +281,16 @@ export const Tokens: Story = {
|
|
|
244
281
|
style={{
|
|
245
282
|
padding: '24px',
|
|
246
283
|
borderRadius: '16px',
|
|
247
|
-
backgroundColor: 'var(--color-sentiment-background-surface)',
|
|
248
|
-
color: 'var(--color-sentiment-content-primary)',
|
|
249
284
|
}}
|
|
250
285
|
>
|
|
251
|
-
<
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
</strong>
|
|
260
|
-
</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>
|
|
261
294
|
<div
|
|
262
295
|
style={{
|
|
263
296
|
display: 'grid',
|
|
@@ -267,18 +300,19 @@ export const Tokens: Story = {
|
|
|
267
300
|
>
|
|
268
301
|
{tokenCategories.map((category) => (
|
|
269
302
|
<div key={category.name}>
|
|
270
|
-
<
|
|
303
|
+
<h5
|
|
271
304
|
style={{
|
|
305
|
+
color: 'inherit',
|
|
272
306
|
fontSize: '12px',
|
|
273
307
|
fontWeight: 600,
|
|
274
308
|
marginBottom: '8px',
|
|
275
309
|
textTransform: 'uppercase',
|
|
276
310
|
letterSpacing: '0.5px',
|
|
277
|
-
opacity: 0.
|
|
311
|
+
opacity: 0.8,
|
|
278
312
|
}}
|
|
279
313
|
>
|
|
280
314
|
{category.name}
|
|
281
|
-
</
|
|
315
|
+
</h5>
|
|
282
316
|
{category.tokens.map((token) => (
|
|
283
317
|
<TokenSwatch key={token} token={token} />
|
|
284
318
|
))}
|
|
@@ -288,10 +322,15 @@ export const Tokens: Story = {
|
|
|
288
322
|
</SentimentSurface>
|
|
289
323
|
)),
|
|
290
324
|
)}
|
|
291
|
-
</
|
|
325
|
+
</section>
|
|
292
326
|
),
|
|
293
327
|
parameters: {
|
|
294
328
|
controls: { disable: true },
|
|
329
|
+
docs: {
|
|
330
|
+
canvas: {
|
|
331
|
+
sourceState: 'hidden',
|
|
332
|
+
},
|
|
333
|
+
},
|
|
295
334
|
},
|
|
296
335
|
decorators: [
|
|
297
336
|
(Story: () => JSX.Element) => (
|
|
@@ -301,3 +340,179 @@ export const Tokens: Story = {
|
|
|
301
340
|
),
|
|
302
341
|
],
|
|
303
342
|
};
|
|
343
|
+
|
|
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
|
+
},
|
|
377
|
+
},
|
|
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>
|
|
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
|
+
</>
|
|
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
|
+
},
|
|
517
|
+
},
|
|
518
|
+
};
|
|
@@ -1,9 +1,28 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
+
import { ThemeProvider, type Theming } from '@wise/components-theming';
|
|
2
3
|
import SentimentSurface from './SentimentSurface';
|
|
4
|
+
import Button from '../button';
|
|
5
|
+
import type { Sentiment, Emphasis } from './SentimentSurface.types';
|
|
6
|
+
|
|
7
|
+
const sentiments: Sentiment[] = ['negative', 'success', 'proposition', 'warning', 'neutral'];
|
|
8
|
+
const emphasisLevels: Emphasis[] = ['base', 'elevated'];
|
|
9
|
+
|
|
10
|
+
// Themes that support light/dark screen modes
|
|
11
|
+
const themesWithScreenModes: Theming['theme'][] = ['personal', 'business', 'platform'];
|
|
12
|
+
// Themes that don't have light/dark variants
|
|
13
|
+
const themesWithoutScreenModes: Theming['theme'][] = [
|
|
14
|
+
'forest-green',
|
|
15
|
+
'bright-green',
|
|
16
|
+
'business--forest-green',
|
|
17
|
+
'business--bright-green',
|
|
18
|
+
'platform--forest-green',
|
|
19
|
+
];
|
|
20
|
+
const screenModes: Theming['screenMode'][] = ['light', 'dark'];
|
|
3
21
|
|
|
4
22
|
export default {
|
|
5
23
|
component: SentimentSurface,
|
|
6
24
|
title: 'Content/SentimentSurface/Tests',
|
|
25
|
+
tags: ['!autodocs'],
|
|
7
26
|
} satisfies Meta<typeof SentimentSurface>;
|
|
8
27
|
|
|
9
28
|
type Story = StoryObj<typeof SentimentSurface>;
|
|
@@ -11,58 +30,23 @@ type Story = StoryObj<typeof SentimentSurface>;
|
|
|
11
30
|
export const NestedSentiments: Story = {
|
|
12
31
|
render: () => (
|
|
13
32
|
<div style={{ display: 'flex', flexDirection: 'column', gap: '24px' }}>
|
|
14
|
-
<SentimentSurface
|
|
15
|
-
sentiment="negative"
|
|
16
|
-
emphasis="base"
|
|
17
|
-
style={{
|
|
18
|
-
backgroundColor: 'var(--color-sentiment-background-surface)',
|
|
19
|
-
color: 'var(--color-sentiment-content-primary)',
|
|
20
|
-
}}
|
|
21
|
-
>
|
|
33
|
+
<SentimentSurface sentiment="negative" emphasis="base">
|
|
22
34
|
Outer: Negative, base
|
|
23
35
|
<div style={{ margin: '16px 0 0 16px' }}>
|
|
24
|
-
<SentimentSurface
|
|
25
|
-
sentiment="success"
|
|
26
|
-
emphasis="elevated"
|
|
27
|
-
style={{
|
|
28
|
-
backgroundColor: 'var(--color-sentiment-background-surface)',
|
|
29
|
-
color: 'var(--color-sentiment-content-primary)',
|
|
30
|
-
}}
|
|
31
|
-
>
|
|
36
|
+
<SentimentSurface sentiment="success" emphasis="elevated">
|
|
32
37
|
Inner: Success, elevated
|
|
33
38
|
<div style={{ margin: '12px 0 0 12px' }}>
|
|
34
|
-
<SentimentSurface
|
|
35
|
-
sentiment="warning"
|
|
36
|
-
emphasis="base"
|
|
37
|
-
style={{
|
|
38
|
-
backgroundColor: 'var(--color-sentiment-background-surface)',
|
|
39
|
-
color: 'var(--color-sentiment-content-primary)',
|
|
40
|
-
}}
|
|
41
|
-
>
|
|
39
|
+
<SentimentSurface sentiment="warning" emphasis="base">
|
|
42
40
|
Deepest: Warning, base
|
|
43
41
|
</SentimentSurface>
|
|
44
42
|
</div>
|
|
45
43
|
</SentimentSurface>
|
|
46
44
|
</div>
|
|
47
45
|
</SentimentSurface>
|
|
48
|
-
<SentimentSurface
|
|
49
|
-
sentiment="proposition"
|
|
50
|
-
emphasis="elevated"
|
|
51
|
-
style={{
|
|
52
|
-
backgroundColor: 'var(--color-sentiment-background-surface)',
|
|
53
|
-
color: 'var(--color-sentiment-content-primary)',
|
|
54
|
-
}}
|
|
55
|
-
>
|
|
46
|
+
<SentimentSurface sentiment="proposition" emphasis="elevated">
|
|
56
47
|
Outer: Proposition, elevated
|
|
57
48
|
<div style={{ margin: '16px 0 0 16px' }}>
|
|
58
|
-
<SentimentSurface
|
|
59
|
-
sentiment="neutral"
|
|
60
|
-
emphasis="base"
|
|
61
|
-
style={{
|
|
62
|
-
backgroundColor: 'var(--color-sentiment-background-surface)',
|
|
63
|
-
color: 'var(--color-sentiment-content-primary)',
|
|
64
|
-
}}
|
|
65
|
-
>
|
|
49
|
+
<SentimentSurface sentiment="neutral" emphasis="base">
|
|
66
50
|
Inner: Neutral, base
|
|
67
51
|
</SentimentSurface>
|
|
68
52
|
</div>
|
|
@@ -70,3 +54,69 @@ export const NestedSentiments: Story = {
|
|
|
70
54
|
</div>
|
|
71
55
|
),
|
|
72
56
|
};
|
|
57
|
+
|
|
58
|
+
const ButtonsGrid = () => (
|
|
59
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px' }}>
|
|
60
|
+
{emphasisLevels.map((emphasis) =>
|
|
61
|
+
sentiments.map((sentiment) => (
|
|
62
|
+
<SentimentSurface
|
|
63
|
+
key={`${sentiment}-${emphasis}`}
|
|
64
|
+
sentiment={sentiment}
|
|
65
|
+
emphasis={emphasis}
|
|
66
|
+
style={{
|
|
67
|
+
backgroundColor: 'var(--color-sentiment-background-surface)',
|
|
68
|
+
color: 'var(--color-sentiment-content-primary)',
|
|
69
|
+
padding: '16px',
|
|
70
|
+
}}
|
|
71
|
+
>
|
|
72
|
+
<span
|
|
73
|
+
style={{
|
|
74
|
+
marginRight: '16px',
|
|
75
|
+
textTransform: 'capitalize',
|
|
76
|
+
minWidth: '150px',
|
|
77
|
+
display: 'inline-block',
|
|
78
|
+
}}
|
|
79
|
+
>
|
|
80
|
+
{sentiment} ({emphasis})
|
|
81
|
+
</span>
|
|
82
|
+
<Button v2>Primary</Button>
|
|
83
|
+
<Button v2 priority="secondary" style={{ marginLeft: '8px' }}>
|
|
84
|
+
Secondary
|
|
85
|
+
</Button>
|
|
86
|
+
<Button v2 priority="secondary-neutral" style={{ marginLeft: '8px' }}>
|
|
87
|
+
Secondary Neutral
|
|
88
|
+
</Button>
|
|
89
|
+
</SentimentSurface>
|
|
90
|
+
)),
|
|
91
|
+
)}
|
|
92
|
+
</div>
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
export const ButtonsAcrossThemes: Story = {
|
|
96
|
+
render: () => (
|
|
97
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '32px' }}>
|
|
98
|
+
{/* Themes with light/dark screen modes */}
|
|
99
|
+
{themesWithScreenModes.map((theme) =>
|
|
100
|
+
screenModes.map((screenMode) => (
|
|
101
|
+
<ThemeProvider key={`${theme}-${screenMode}`} theme={theme} screenMode={screenMode}>
|
|
102
|
+
<div style={{ padding: '16px' }}>
|
|
103
|
+
<h3 style={{ margin: '0 0 16px 0', textTransform: 'capitalize' }}>
|
|
104
|
+
{theme} - {screenMode}
|
|
105
|
+
</h3>
|
|
106
|
+
<ButtonsGrid />
|
|
107
|
+
</div>
|
|
108
|
+
</ThemeProvider>
|
|
109
|
+
)),
|
|
110
|
+
)}
|
|
111
|
+
{/* Themes without light/dark variants */}
|
|
112
|
+
{themesWithoutScreenModes.map((theme) => (
|
|
113
|
+
<ThemeProvider key={theme} theme={theme}>
|
|
114
|
+
<div style={{ padding: '16px' }}>
|
|
115
|
+
<h3 style={{ margin: '0 0 16px 0', textTransform: 'capitalize' }}>{theme}</h3>
|
|
116
|
+
<ButtonsGrid />
|
|
117
|
+
</div>
|
|
118
|
+
</ThemeProvider>
|
|
119
|
+
))}
|
|
120
|
+
</div>
|
|
121
|
+
),
|
|
122
|
+
};
|