@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
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { ThemeProvider, type ThemeProviderProps } from '@wise/components-theming';
|
|
2
|
+
import { ChevronRight, Freeze } from '@transferwise/icons';
|
|
3
|
+
import { Flag } from '@wise/art';
|
|
4
|
+
import SentimentSurface from '../../sentimentSurface';
|
|
5
|
+
import Header from '../../header';
|
|
6
|
+
import Button from '../Button';
|
|
7
|
+
|
|
8
|
+
interface GenerateSurfaceVariantProps {
|
|
9
|
+
theme?: 'forest-green' | 'bright-green' | 'dark';
|
|
10
|
+
sentiment: 'success' | 'warning' | 'negative' | 'neutral' | 'proposition';
|
|
11
|
+
}
|
|
12
|
+
export const generateSurfaceVariant = ({ theme, sentiment }: GenerateSurfaceVariantProps) => ({
|
|
13
|
+
storyName: '',
|
|
14
|
+
render: () => {
|
|
15
|
+
const PERMUTATIONS = {
|
|
16
|
+
emphasis: ['base', 'elevated'] as const,
|
|
17
|
+
disabled: [false, true] as const,
|
|
18
|
+
others: [
|
|
19
|
+
{
|
|
20
|
+
addonStart: { type: 'avatar' as const, value: [{ asset: <Freeze /> }] },
|
|
21
|
+
addonEnd: { type: 'icon' as const, value: <ChevronRight /> },
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
addonStart: { type: 'avatar' as const, value: [{ profileName: 'John Doe' }] },
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
addonStart: {
|
|
28
|
+
type: 'avatar' as const,
|
|
29
|
+
value: [
|
|
30
|
+
{
|
|
31
|
+
asset: <Flag code="gb" />,
|
|
32
|
+
},
|
|
33
|
+
{ asset: <Freeze /> },
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
loading: true,
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
priority: ['primary', 'secondary', 'secondary-neutral', 'tertiary'] as const,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const story = PERMUTATIONS.emphasis.map((emphasis) => (
|
|
45
|
+
<SentimentSurface
|
|
46
|
+
key={`${emphasis}-${sentiment}`}
|
|
47
|
+
sentiment={sentiment}
|
|
48
|
+
emphasis={emphasis}
|
|
49
|
+
style={{
|
|
50
|
+
padding: 'var(--size-8)',
|
|
51
|
+
display: 'grid',
|
|
52
|
+
gridTemplateColumns: 'repeat(1, min-content)',
|
|
53
|
+
gap: 'var(--size-8)',
|
|
54
|
+
}}
|
|
55
|
+
>
|
|
56
|
+
{PERMUTATIONS.disabled.map((disabled) =>
|
|
57
|
+
PERMUTATIONS.others.map((media, mediaVariant) =>
|
|
58
|
+
PERMUTATIONS.priority.map((priority) => (
|
|
59
|
+
<div key={`${emphasis}-${sentiment}-${disabled}-${priority}-${mediaVariant}`}>
|
|
60
|
+
<Button v2 size="md" disabled={disabled} priority={priority} {...media}>
|
|
61
|
+
{priority}
|
|
62
|
+
</Button>
|
|
63
|
+
</div>
|
|
64
|
+
)),
|
|
65
|
+
),
|
|
66
|
+
)}
|
|
67
|
+
</SentimentSurface>
|
|
68
|
+
));
|
|
69
|
+
|
|
70
|
+
if (theme === 'dark') {
|
|
71
|
+
return (
|
|
72
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, min-content)' }}>
|
|
73
|
+
<ThemeProvider theme="personal" screenMode="dark" className="p-a-2 p-l-4">
|
|
74
|
+
<Header title="Personal brand" />
|
|
75
|
+
{story}
|
|
76
|
+
</ThemeProvider>
|
|
77
|
+
<ThemeProvider theme="business" screenMode="dark" className="p-a-2 p-r-4">
|
|
78
|
+
<Header title="Business brand" />
|
|
79
|
+
{story}
|
|
80
|
+
</ThemeProvider>
|
|
81
|
+
</div>
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const personalVariant = (theme || 'personal') as ThemeProviderProps['theme'];
|
|
86
|
+
const businessVariant = (
|
|
87
|
+
theme ? (`business--${theme}` as const) : 'business'
|
|
88
|
+
) as ThemeProviderProps['theme'];
|
|
89
|
+
const platformVariant = (
|
|
90
|
+
theme ? (`platform--${theme}` as const) : 'platform'
|
|
91
|
+
) as ThemeProviderProps['theme'];
|
|
92
|
+
return (
|
|
93
|
+
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, min-content)' }}>
|
|
94
|
+
<ThemeProvider theme={personalVariant} screenMode="light" className="p-a-2 p-l-4">
|
|
95
|
+
<Header title="Personal brand" />
|
|
96
|
+
{story}
|
|
97
|
+
</ThemeProvider>
|
|
98
|
+
<ThemeProvider theme={businessVariant} screenMode="light" className="p-a-2">
|
|
99
|
+
<Header title="Business brand" />
|
|
100
|
+
{story}
|
|
101
|
+
</ThemeProvider>
|
|
102
|
+
{theme === 'bright-green' ? null : (
|
|
103
|
+
<ThemeProvider theme={platformVariant} screenMode="light" className="p-a-2 p-r-4">
|
|
104
|
+
<Header title="Platform brand" />
|
|
105
|
+
{story}
|
|
106
|
+
</ThemeProvider>
|
|
107
|
+
)}
|
|
108
|
+
</div>
|
|
109
|
+
);
|
|
110
|
+
},
|
|
111
|
+
decorators: [
|
|
112
|
+
(Story: React.ComponentType) => (
|
|
113
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
114
|
+
<Story />
|
|
115
|
+
</div>
|
|
116
|
+
),
|
|
117
|
+
],
|
|
118
|
+
});
|
|
@@ -13,17 +13,17 @@
|
|
|
13
13
|
background-color: var(--color-background-neutral-active);
|
|
14
14
|
}
|
|
15
15
|
.np-icon-button-primary-default {
|
|
16
|
-
color: var(--color-interactive-control);
|
|
16
|
+
color: var(--color-sentiment-interactive-control, var(--color-interactive-control));
|
|
17
17
|
background-color: #00a2dd;
|
|
18
|
-
background-color: var(--color-interactive-accent);
|
|
18
|
+
background-color: var(--color-sentiment-interactive-primary, var(--color-interactive-accent));
|
|
19
19
|
}
|
|
20
20
|
.np-icon-button-primary-default:not(.disabled):not(:disabled):hover {
|
|
21
21
|
background-color: #008fc9;
|
|
22
|
-
background-color: var(--color-interactive-accent-hover);
|
|
22
|
+
background-color: var(--color-sentiment-interactive-primary-hover, var(--color-interactive-accent-hover));
|
|
23
23
|
}
|
|
24
24
|
.np-icon-button-primary-default:not(.disabled):not(:disabled):active {
|
|
25
25
|
background-color: #0081ba;
|
|
26
|
-
background-color: var(--color-interactive-accent-active);
|
|
26
|
+
background-color: var(--color-sentiment-interactive-primary-active, var(--color-interactive-accent-active));
|
|
27
27
|
}
|
|
28
28
|
.np-icon-button-primary-negative {
|
|
29
29
|
color: var(--color-contrast-overlay);
|
|
@@ -51,14 +51,14 @@
|
|
|
51
51
|
background-color: var(--color-background-screen-active);
|
|
52
52
|
}
|
|
53
53
|
.np-icon-button-secondary-default {
|
|
54
|
-
color: var(--color-interactive-primary);
|
|
55
|
-
background-color: var(--color-interactive-neutral);
|
|
54
|
+
color: var(--color-sentiment-content-primary, var(--color-interactive-primary));
|
|
55
|
+
background-color: var(--color-sentiment-interactive-secondary-neutral, var(--color-interactive-neutral));
|
|
56
56
|
}
|
|
57
57
|
.np-icon-button-secondary-default:not(.disabled):not(:disabled):hover {
|
|
58
|
-
background-color: var(--color-interactive-neutral-hover);
|
|
58
|
+
background-color: var(--color-sentiment-interactive-secondary-neutral-hover, var(--color-interactive-neutral-hover));
|
|
59
59
|
}
|
|
60
60
|
.np-icon-button-secondary-default:not(.disabled):not(:disabled):active {
|
|
61
|
-
background-color: var(--color-interactive-neutral-active);
|
|
61
|
+
background-color: var(--color-sentiment-interactive-secondary-neutral-active, var(--color-interactive-neutral-active));
|
|
62
62
|
}
|
|
63
63
|
.np-theme-personal--bright-green .np-icon-button-secondary-default,
|
|
64
64
|
.np-theme-personal--forest-green .np-icon-button-secondary-default {
|
|
@@ -5,7 +5,21 @@
|
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
&-primary-default {
|
|
8
|
-
|
|
8
|
+
color: var(--color-sentiment-interactive-control, var(--color-interactive-control));
|
|
9
|
+
background-color: var(--color-sentiment-interactive-primary, var(--color-interactive-accent));
|
|
10
|
+
|
|
11
|
+
&:not(.disabled, :disabled):hover {
|
|
12
|
+
background-color: var(
|
|
13
|
+
--color-sentiment-interactive-primary-hover,
|
|
14
|
+
var(--color-interactive-accent-hover)
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
&:not(.disabled, :disabled):active {
|
|
18
|
+
background-color: var(
|
|
19
|
+
--color-sentiment-interactive-primary-active,
|
|
20
|
+
var(--color-interactive-accent-active)
|
|
21
|
+
);
|
|
22
|
+
}
|
|
9
23
|
}
|
|
10
24
|
|
|
11
25
|
&-primary-negative {
|
|
@@ -22,7 +36,24 @@
|
|
|
22
36
|
}
|
|
23
37
|
|
|
24
38
|
&-secondary-default {
|
|
25
|
-
|
|
39
|
+
color: var(--color-sentiment-content-primary, var(--color-interactive-primary));
|
|
40
|
+
background-color: var(
|
|
41
|
+
--color-sentiment-interactive-secondary-neutral,
|
|
42
|
+
var(--color-interactive-neutral)
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
&:not(.disabled, :disabled):hover {
|
|
46
|
+
background-color: var(
|
|
47
|
+
--color-sentiment-interactive-secondary-neutral-hover,
|
|
48
|
+
var(--color-interactive-neutral-hover)
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
&:not(.disabled, :disabled):active {
|
|
52
|
+
background-color: var(
|
|
53
|
+
--color-sentiment-interactive-secondary-neutral-active,
|
|
54
|
+
var(--color-interactive-neutral-active)
|
|
55
|
+
);
|
|
56
|
+
}
|
|
26
57
|
|
|
27
58
|
.np-theme-personal--bright-green &,
|
|
28
59
|
.np-theme-personal--forest-green & {
|
|
@@ -46,10 +77,10 @@
|
|
|
46
77
|
background-color: var(@bg-color);
|
|
47
78
|
|
|
48
79
|
&:not(.disabled, :disabled):hover {
|
|
49
|
-
background-color
|
|
80
|
+
background-color: ~"var(@{bg-color}-hover)";
|
|
50
81
|
}
|
|
51
82
|
&:not(.disabled, :disabled):active {
|
|
52
|
-
background-color
|
|
83
|
+
background-color: ~"var(@{bg-color}-active)";
|
|
53
84
|
}
|
|
54
85
|
}
|
|
55
86
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
/* eslint-disable react/jsx-key */
|
|
2
1
|
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
3
2
|
import { ArrowLeft, Cross, Defrost, Edit, Menu, Plus } from '@transferwise/icons';
|
|
4
3
|
import IconButton, { Props } from './IconButton';
|
|
5
4
|
import { action } from 'storybook/actions';
|
|
6
5
|
import Body from '../body';
|
|
6
|
+
import SentimentSurface from '../sentimentSurface';
|
|
7
7
|
|
|
8
8
|
export default {
|
|
9
9
|
title: 'Actions/IconButton',
|
|
@@ -94,14 +94,83 @@ export const Basic: Story = {
|
|
|
94
94
|
>
|
|
95
95
|
{['Primary', 'Secondary', 'Tertiary', 'Minimal', 'Neg primary', 'Neg secondary'].map(
|
|
96
96
|
(variant) => (
|
|
97
|
-
<Body type="body-default-bold">
|
|
97
|
+
<Body key={variant} type="body-default-bold">
|
|
98
|
+
{variant}
|
|
99
|
+
</Body>
|
|
98
100
|
),
|
|
99
101
|
)}
|
|
100
102
|
{sizes.map((size) => (
|
|
101
|
-
<Template size={size} />
|
|
103
|
+
<Template key={size} size={size} />
|
|
102
104
|
))}
|
|
103
105
|
<Template size={72} disabled />
|
|
104
106
|
</div>
|
|
105
107
|
);
|
|
106
108
|
},
|
|
107
109
|
};
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* `IconButton` is sentiment-aware and will automatically adjust its
|
|
113
|
+
* colours if wrapped inside the [SentimentSurface](/?path=/docs/content-sentimentsurface--docs) component
|
|
114
|
+
*/
|
|
115
|
+
export const SentimentAwareness: Story = {
|
|
116
|
+
render: () => {
|
|
117
|
+
return (
|
|
118
|
+
<>
|
|
119
|
+
{(['success', 'warning', 'negative', 'neutral', 'proposition'] as const).map(
|
|
120
|
+
(sentiment) => (
|
|
121
|
+
<SentimentSurface
|
|
122
|
+
key={sentiment}
|
|
123
|
+
sentiment={sentiment}
|
|
124
|
+
className="p-a-1 d-flex align-items-center"
|
|
125
|
+
style={{ gap: 'var(--size-8)' }}
|
|
126
|
+
>
|
|
127
|
+
<IconButton
|
|
128
|
+
size={32}
|
|
129
|
+
aria-label="Primary action"
|
|
130
|
+
priority="primary"
|
|
131
|
+
type="default"
|
|
132
|
+
onClick={action('button click')}
|
|
133
|
+
>
|
|
134
|
+
<Plus />
|
|
135
|
+
</IconButton>
|
|
136
|
+
<IconButton
|
|
137
|
+
size={32}
|
|
138
|
+
aria-label="Secondary action"
|
|
139
|
+
priority="secondary"
|
|
140
|
+
type="default"
|
|
141
|
+
onClick={action('button click')}
|
|
142
|
+
>
|
|
143
|
+
<Defrost />
|
|
144
|
+
</IconButton>
|
|
145
|
+
<IconButton
|
|
146
|
+
size={32}
|
|
147
|
+
aria-label="Disabled action"
|
|
148
|
+
priority="primary"
|
|
149
|
+
type="default"
|
|
150
|
+
disabled
|
|
151
|
+
onClick={action('button click')}
|
|
152
|
+
>
|
|
153
|
+
<Menu />
|
|
154
|
+
</IconButton>
|
|
155
|
+
</SentimentSurface>
|
|
156
|
+
),
|
|
157
|
+
)}
|
|
158
|
+
</>
|
|
159
|
+
);
|
|
160
|
+
},
|
|
161
|
+
parameters: {
|
|
162
|
+
docs: {
|
|
163
|
+
source: { type: 'dynamic' },
|
|
164
|
+
canvas: {
|
|
165
|
+
sourceState: 'hidden',
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
decorators: [
|
|
170
|
+
(Story) => (
|
|
171
|
+
<div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
|
|
172
|
+
<Story />
|
|
173
|
+
</div>
|
|
174
|
+
),
|
|
175
|
+
],
|
|
176
|
+
};
|
package/src/link/Link.css
CHANGED
package/src/link/Link.less
CHANGED
package/src/link/Link.story.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import Body from '../body/Body';
|
|
|
2
2
|
import { Typography } from '../common';
|
|
3
3
|
import Title from '../title/Title';
|
|
4
4
|
|
|
5
|
+
import SentimentSurface from '../sentimentSurface';
|
|
5
6
|
import Link from '.';
|
|
6
7
|
|
|
7
8
|
export default {
|
|
@@ -158,3 +159,30 @@ export const Basic = () => {
|
|
|
158
159
|
</>
|
|
159
160
|
);
|
|
160
161
|
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* `Link` is sentiment-aware and will automatically adjust its
|
|
165
|
+
* colours if wrapped inside the [SentimentSurface](/?path=/docs/content-sentimentsurface--docs) component
|
|
166
|
+
*/
|
|
167
|
+
export const SentimentAwareness = function Render() {
|
|
168
|
+
return (['success', 'warning', 'negative'] as const).map((sentiment) => (
|
|
169
|
+
<SentimentSurface key={sentiment} sentiment={sentiment} className="p-a-1">
|
|
170
|
+
{'Some text with an '}
|
|
171
|
+
<Link href="#">inline link</Link>
|
|
172
|
+
{' adjusted to match the current colour scheme. It also works with '}
|
|
173
|
+
<Link href="#" target="_blank">
|
|
174
|
+
external
|
|
175
|
+
</Link>
|
|
176
|
+
{' and '}
|
|
177
|
+
<Link href="#" target="_blank" disabled>
|
|
178
|
+
disabled links
|
|
179
|
+
</Link>
|
|
180
|
+
.
|
|
181
|
+
</SentimentSurface>
|
|
182
|
+
));
|
|
183
|
+
};
|
|
184
|
+
SentimentAwareness.parameters = {
|
|
185
|
+
docs: {
|
|
186
|
+
source: { type: 'dynamic' },
|
|
187
|
+
},
|
|
188
|
+
};
|