@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.
Files changed (68) hide show
  1. package/build/main.css +145 -156
  2. package/build/prompt/InlinePrompt/InlinePrompt.js +14 -8
  3. package/build/prompt/InlinePrompt/InlinePrompt.js.map +1 -1
  4. package/build/prompt/InlinePrompt/InlinePrompt.mjs +15 -9
  5. package/build/prompt/InlinePrompt/InlinePrompt.mjs.map +1 -1
  6. package/build/sentimentSurface/SentimentSurface.js +6 -5
  7. package/build/sentimentSurface/SentimentSurface.js.map +1 -1
  8. package/build/sentimentSurface/SentimentSurface.mjs +6 -5
  9. package/build/sentimentSurface/SentimentSurface.mjs.map +1 -1
  10. package/build/styles/button/Button.css +22 -22
  11. package/build/styles/button/Button.vars.css +21 -21
  12. package/build/styles/iconButton/IconButton.css +8 -8
  13. package/build/styles/link/Link.css +1 -0
  14. package/build/styles/main.css +145 -156
  15. package/build/styles/prompt/InlinePrompt/InlinePrompt.css +26 -105
  16. package/build/styles/sentimentSurface/SentimentSurface.css +88 -21
  17. package/build/types/button/_stories/helpers.d.ts +11 -0
  18. package/build/types/button/_stories/helpers.d.ts.map +1 -0
  19. package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts +19 -3
  20. package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts.map +1 -1
  21. package/build/types/sentimentSurface/SentimentSurface.d.ts +5 -4
  22. package/build/types/sentimentSurface/SentimentSurface.d.ts.map +1 -1
  23. package/build/types/sentimentSurface/SentimentSurface.types.d.ts +4 -16
  24. package/build/types/sentimentSurface/SentimentSurface.types.d.ts.map +1 -1
  25. package/build/types/test-utils/story-config.d.ts +25 -1
  26. package/build/types/test-utils/story-config.d.ts.map +1 -1
  27. package/package.json +13 -12
  28. package/src/button/Button.css +22 -22
  29. package/src/button/Button.less +1 -1
  30. package/src/button/Button.vars.css +21 -21
  31. package/src/button/Button.vars.less +63 -23
  32. package/src/button/{Button.accessibility.docs.mdx → _stories/Button.accessibility.docs.mdx} +1 -1
  33. package/src/button/_stories/Button.brightGreen.tests.story.tsx +31 -0
  34. package/src/button/_stories/Button.dark.tests.story.tsx +25 -0
  35. package/src/button/_stories/Button.default.tests.story.tsx +25 -0
  36. package/src/button/_stories/Button.forestGreen.tests.story.tsx +28 -0
  37. package/src/button/{Button.story.tsx → _stories/Button.story.tsx} +78 -113
  38. package/src/button/_stories/Button.tests.story.tsx +139 -0
  39. package/src/button/_stories/helpers.tsx +118 -0
  40. package/src/iconButton/IconButton.css +8 -8
  41. package/src/iconButton/IconButton.less +35 -4
  42. package/src/iconButton/IconButton.story.tsx +72 -3
  43. package/src/link/Link.css +1 -0
  44. package/src/link/Link.less +1 -0
  45. package/src/link/Link.story.tsx +28 -0
  46. package/src/main.css +145 -156
  47. package/src/prompt/InlinePrompt/InlinePrompt.css +26 -105
  48. package/src/prompt/InlinePrompt/InlinePrompt.less +31 -119
  49. package/src/prompt/InlinePrompt/InlinePrompt.spec.tsx +87 -29
  50. package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +223 -31
  51. package/src/prompt/InlinePrompt/InlinePrompt.tsx +42 -11
  52. package/src/sentimentSurface/SentimentSurface.css +88 -21
  53. package/src/sentimentSurface/SentimentSurface.docs.mdx +32 -495
  54. package/src/sentimentSurface/SentimentSurface.less +151 -114
  55. package/src/sentimentSurface/SentimentSurface.spec.tsx +31 -11
  56. package/src/sentimentSurface/SentimentSurface.story.tsx +323 -108
  57. package/src/sentimentSurface/SentimentSurface.tests.story.tsx +90 -40
  58. package/src/sentimentSurface/SentimentSurface.tsx +16 -9
  59. package/src/sentimentSurface/SentimentSurface.types.ts +5 -20
  60. package/src/test-utils/story-config.ts +5 -1
  61. package/build/sentimentSurface/classMap.js +0 -17
  62. package/build/sentimentSurface/classMap.js.map +0 -1
  63. package/build/sentimentSurface/classMap.mjs +0 -14
  64. package/build/sentimentSurface/classMap.mjs.map +0 -1
  65. package/build/types/sentimentSurface/classMap.d.ts +0 -4
  66. package/build/types/sentimentSurface/classMap.d.ts.map +0 -1
  67. package/src/button/Button.tests.story.tsx +0 -27
  68. 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
- .colors(--color-interactive-control, --color-interactive-accent);
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
- .colors(--color-interactive-primary, --color-interactive-neutral);
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:~"var(@{bg-color}-hover)";
80
+ background-color: ~"var(@{bg-color}-hover)";
50
81
  }
51
82
  &:not(.disabled, :disabled):active {
52
- background-color:~"var(@{bg-color}-active)";
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">{variant}</Body>
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
@@ -1,6 +1,7 @@
1
1
  a,
2
2
  button.np-link {
3
3
  border-radius: 2px;
4
+ color: var(--color-sentiment-content-primary, var(--color-content-link));
4
5
  }
5
6
  .np-link .tw-icon {
6
7
  display: flex;
@@ -3,6 +3,7 @@
3
3
 
4
4
  a, button.np-link {
5
5
  border-radius: 2px;
6
+ color: var(--color-sentiment-content-primary, var(--color-content-link));
6
7
  }
7
8
 
8
9
  .np-link {
@@ -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
+ };