@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.
Files changed (59) hide show
  1. package/build/main.css +60 -131
  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 +17 -17
  11. package/build/styles/button/Button.vars.css +16 -16
  12. package/build/styles/iconButton/IconButton.css +8 -8
  13. package/build/styles/link/Link.css +1 -0
  14. package/build/styles/main.css +60 -131
  15. package/build/styles/prompt/InlinePrompt/InlinePrompt.css +26 -105
  16. package/build/styles/sentimentSurface/SentimentSurface.css +8 -1
  17. package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts +19 -3
  18. package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts.map +1 -1
  19. package/build/types/sentimentSurface/SentimentSurface.d.ts +5 -4
  20. package/build/types/sentimentSurface/SentimentSurface.d.ts.map +1 -1
  21. package/build/types/sentimentSurface/SentimentSurface.types.d.ts +4 -16
  22. package/build/types/sentimentSurface/SentimentSurface.types.d.ts.map +1 -1
  23. package/build/types/test-utils/story-config.d.ts +24 -0
  24. package/build/types/test-utils/story-config.d.ts.map +1 -1
  25. package/package.json +12 -11
  26. package/src/button/Button.css +17 -17
  27. package/src/button/Button.less +1 -1
  28. package/src/button/Button.story.tsx +75 -110
  29. package/src/button/Button.tests.story.tsx +189 -0
  30. package/src/button/Button.vars.css +16 -16
  31. package/src/button/Button.vars.less +58 -18
  32. package/src/iconButton/IconButton.css +8 -8
  33. package/src/iconButton/IconButton.less +35 -4
  34. package/src/iconButton/IconButton.story.tsx +72 -3
  35. package/src/link/Link.css +1 -0
  36. package/src/link/Link.less +1 -0
  37. package/src/link/Link.story.tsx +28 -0
  38. package/src/main.css +60 -131
  39. package/src/prompt/InlinePrompt/InlinePrompt.css +26 -105
  40. package/src/prompt/InlinePrompt/InlinePrompt.less +31 -119
  41. package/src/prompt/InlinePrompt/InlinePrompt.spec.tsx +87 -29
  42. package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +223 -31
  43. package/src/prompt/InlinePrompt/InlinePrompt.tsx +42 -11
  44. package/src/sentimentSurface/SentimentSurface.css +8 -1
  45. package/src/sentimentSurface/SentimentSurface.docs.mdx +32 -495
  46. package/src/sentimentSurface/SentimentSurface.less +121 -114
  47. package/src/sentimentSurface/SentimentSurface.spec.tsx +31 -11
  48. package/src/sentimentSurface/SentimentSurface.story.tsx +323 -108
  49. package/src/sentimentSurface/SentimentSurface.tests.story.tsx +90 -40
  50. package/src/sentimentSurface/SentimentSurface.tsx +16 -9
  51. package/src/sentimentSurface/SentimentSurface.types.ts +5 -20
  52. package/src/test-utils/story-config.ts +0 -1
  53. package/build/sentimentSurface/classMap.js +0 -17
  54. package/build/sentimentSurface/classMap.js.map +0 -1
  55. package/build/sentimentSurface/classMap.mjs +0 -14
  56. package/build/sentimentSurface/classMap.mjs.map +0 -1
  57. package/build/types/sentimentSurface/classMap.d.ts +0 -4
  58. package/build/types/sentimentSurface/classMap.d.ts.map +0 -1
  59. package/src/sentimentSurface/classMap.ts +0 -15
@@ -19,18 +19,35 @@
19
19
  position: relative;
20
20
  z-index: 1;
21
21
  }
22
+ .wds-inline-prompt:has(a):hover,
23
+ .wds-inline-prompt:has(button):hover {
24
+ background-color: var(--color-sentiment-background-surface-hover);
25
+ }
26
+ .wds-inline-prompt:has(a):active,
27
+ .wds-inline-prompt:has(button):active {
28
+ background-color: var(--color-sentiment-background-surface-active);
29
+ }
22
30
  .wds-inline-prompt--muted {
23
31
  opacity: 0.93;
24
32
  filter: grayscale(1);
25
33
  }
26
34
  .wds-inline-prompt a,
27
35
  .wds-inline-prompt button {
36
+ color: var(--color-sentiment-content-primary);
28
37
  text-underline-offset: calc(4px / 2);
29
38
  text-underline-offset: calc(var(--size-4) / 2);
30
39
  }
40
+ .wds-inline-prompt a:hover,
41
+ .wds-inline-prompt button:hover {
42
+ color: var(--color-sentiment-content-primary-hover);
43
+ }
44
+ .wds-inline-prompt a:active,
45
+ .wds-inline-prompt button:active {
46
+ color: var(--color-sentiment-content-primary-active);
47
+ }
31
48
  .wds-inline-prompt a:first-of-type:before,
32
49
  .wds-inline-prompt button:first-of-type:before {
33
- content: '';
50
+ content: "";
34
51
  position: absolute;
35
52
  inset: 0;
36
53
  }
@@ -44,110 +61,14 @@
44
61
  }
45
62
  .wds-inline-prompt__media-wrapper .tw-icon-tags,
46
63
  .wds-inline-prompt__media-wrapper .tw-icon-confetti {
47
- color: var(--color-sentiment-positive-primary);
48
- }
49
- .wds-inline-prompt--negative {
50
- background-color: var(--color-sentiment-negative-secondary);
51
- color: var(--color-sentiment-negative-primary);
52
- }
53
- .wds-inline-prompt--negative a,
54
- .wds-inline-prompt--negative button {
55
- color: var(--color-sentiment-negative-primary);
56
- }
57
- .wds-inline-prompt--negative a:hover,
58
- .wds-inline-prompt--negative button:hover {
59
- color: var(--color-sentiment-negative-primary-hover);
60
- }
61
- .wds-inline-prompt--negative a:active,
62
- .wds-inline-prompt--negative button:active {
63
- color: var(--color-sentiment-negative-primary-active);
64
- }
65
- .wds-inline-prompt.wds-inline-prompt--negative:has(a, button):hover {
66
- background-color: var(--color-sentiment-negative-secondary-hover);
67
- }
68
- .wds-inline-prompt.wds-inline-prompt--negative:has(a, button):active {
69
- background-color: var(--color-sentiment-negative-secondary-active);
70
- }
71
- .wds-inline-prompt--positive {
72
- background-color: var(--color-sentiment-positive-secondary);
73
- color: var(--color-sentiment-positive-primary);
74
- }
75
- .wds-inline-prompt--positive a,
76
- .wds-inline-prompt--positive button {
77
- color: var(--color-sentiment-positive-primary);
78
- }
79
- .wds-inline-prompt--positive a:hover,
80
- .wds-inline-prompt--positive button:hover {
81
- color: var(--color-sentiment-positive-primary-hover);
82
- }
83
- .wds-inline-prompt--positive a:active,
84
- .wds-inline-prompt--positive button:active {
85
- color: var(--color-sentiment-positive-primary-active);
86
- }
87
- .wds-inline-prompt.wds-inline-prompt--positive:has(a, button):hover {
88
- background-color: var(--color-sentiment-positive-secondary-hover);
89
- }
90
- .wds-inline-prompt.wds-inline-prompt--positive:has(a, button):active {
91
- background-color: var(--color-sentiment-positive-secondary-active);
92
- }
93
- .wds-inline-prompt--proposition {
94
- background-color: #D2F9F7;
95
- color: var(--color-interactive-primary);
96
- }
97
- .wds-inline-prompt--proposition a,
98
- .wds-inline-prompt--proposition button {
99
- color: var(--color-interactive-primary);
100
- }
101
- .wds-inline-prompt--proposition a:hover,
102
- .wds-inline-prompt--proposition button:hover {
103
- color: var(--color-interactive-primary-hover);
104
- }
105
- .wds-inline-prompt--proposition a:active,
106
- .wds-inline-prompt--proposition button:active {
107
- color: var(--color-interactive-primary-active);
108
- }
109
- .wds-inline-prompt.wds-inline-prompt--proposition:has(a, button):hover {
110
- background-color: #B2F4F3;
111
- }
112
- .wds-inline-prompt.wds-inline-prompt--proposition:has(a, button):active {
113
- background-color: #91F0EE;
114
- }
115
- .wds-inline-prompt--neutral {
116
- background-color: rgba(134,167,189,0.10196);
117
- background-color: var(--color-background-neutral);
118
- color: #37517e;
119
- color: var(--color-content-primary);
120
- }
121
- .wds-inline-prompt--neutral a,
122
- .wds-inline-prompt--neutral button {
123
- color: #37517e;
124
- color: var(--color-content-primary);
125
- }
126
- .wds-inline-prompt.wds-inline-prompt--neutral:has(a, button):hover {
127
- background-color: var(--color-background-neutral-hover);
128
- }
129
- .wds-inline-prompt.wds-inline-prompt--neutral:has(a, button):active {
130
- background-color: var(--color-background-neutral-active);
131
- }
132
- .wds-inline-prompt--warning {
133
- background-color: var(--color-sentiment-warning-secondary);
134
- color: var(--color-sentiment-warning-content);
135
- }
136
- .wds-inline-prompt--warning a,
137
- .wds-inline-prompt--warning button {
138
- color: var(--color-sentiment-warning-content);
139
- }
140
- .wds-inline-prompt--warning a:hover,
141
- .wds-inline-prompt--warning button:hover {
142
- color: var(--color-sentiment-warning-content-hover);
143
- }
144
- .wds-inline-prompt--warning a:active,
145
- .wds-inline-prompt--warning button:active {
146
- color: var(--color-sentiment-warning-content-active);
64
+ color: var(--color-sentiment-content-primary);
147
65
  }
148
- .wds-inline-prompt.wds-inline-prompt--warning:has(a, button):hover {
149
- background-color: color-mix(in srgb, var(--color-sentiment-warning-secondary) 92%, var(--color-sentiment-warning-primary));
66
+ .wds-inline-prompt .wds-inline-prompt-process-indicator {
67
+ width: 16px;
68
+ width: var(--size-16);
69
+ height: 16px;
70
+ height: var(--size-16);
150
71
  }
151
- .wds-inline-prompt.wds-inline-prompt--warning:has(a, button):active {
152
- background-color: color-mix(in srgb, var(--color-sentiment-warning-secondary) 84%, var(--color-sentiment-warning-primary));
72
+ .wds-inline-prompt .wds-inline-prompt-process-indicator .process-circle {
73
+ stroke: currentColor;
153
74
  }
@@ -1,6 +1,3 @@
1
- /// @FIXME all tokens here need to be adjusted after
2
- /// the new sentiment tokens land
3
-
4
1
  .wds-inline-prompt {
5
2
  display: inline-flex;
6
3
  text-align: left;
@@ -16,18 +13,37 @@
16
13
  &:has(button) {
17
14
  position: relative;
18
15
  z-index: 1;
16
+
17
+ &:hover {
18
+ background-color: var(--color-sentiment-background-surface-hover);
19
+ }
20
+
21
+ &:active {
22
+ background-color: var(--color-sentiment-background-surface-active);
23
+ }
19
24
  }
20
25
 
21
26
  &--muted {
22
- opacity: .93;
27
+ opacity: 0.93;
23
28
  filter: grayscale(1);
24
29
  }
25
30
 
26
- a, button {
31
+ a,
32
+ button {
33
+ color: var(--color-sentiment-content-primary);
27
34
  text-underline-offset: calc(var(--size-4) / 2);
35
+
36
+ &:hover {
37
+ color: var(--color-sentiment-content-primary-hover);
38
+ }
39
+
40
+ &:active {
41
+ color: var(--color-sentiment-content-primary-active);
42
+ }
43
+
28
44
  &:first-of-type {
29
45
  &:before {
30
- content: '';
46
+ content: "";
31
47
  position: absolute;
32
48
  inset: 0;
33
49
  }
@@ -41,122 +57,18 @@
41
57
 
42
58
  .tw-icon-tags,
43
59
  .tw-icon-confetti {
44
- color: var(--color-sentiment-positive-primary);
45
- }
46
- }
47
-
48
- &--negative {
49
- background-color: var(--color-sentiment-negative-secondary);
50
- color: var(--color-sentiment-negative-primary);
51
-
52
- a, button {
53
- color: var(--color-sentiment-negative-primary);
54
-
55
- &:hover {
56
- color: var(--color-sentiment-negative-primary-hover);
57
- }
58
-
59
- &:active {
60
- color: var(--color-sentiment-negative-primary-active);
61
- }
62
- }
63
-
64
- .wds-inline-prompt&:has(a, button) {
65
- &:hover {
66
- background-color: var(--color-sentiment-negative-secondary-hover);
67
- }
68
- &:active {
69
- background-color: var(--color-sentiment-negative-secondary-active);
70
- }
71
- }
72
- }
73
-
74
- &--positive {
75
- background-color: var(--color-sentiment-positive-secondary);
76
- color: var(--color-sentiment-positive-primary);
77
- a, button {
78
- color: var(--color-sentiment-positive-primary);
79
- &:hover {
80
- color: var(--color-sentiment-positive-primary-hover);
81
- }
82
- &:active {
83
- color: var(--color-sentiment-positive-primary-active);
84
- }
85
- }
86
- .wds-inline-prompt&:has(a, button) {
87
- &:hover {
88
- background-color: var(--color-sentiment-positive-secondary-hover);
89
- }
90
- &:active {
91
- background-color: var(--color-sentiment-positive-secondary-active);
92
- }
93
- }
94
- }
95
-
96
- &--proposition {
97
- background-color: #D2F9F7;
98
-
99
- color: var(--color-interactive-primary);
100
-
101
- a, button {
102
- color: var(--color-interactive-primary);
103
- &:hover {
104
- color: var(--color-interactive-primary-hover);
105
- }
106
- &:active {
107
- color: var(--color-interactive-primary-active);
108
- }
109
- }
110
-
111
- .wds-inline-prompt&:has(a, button) {
112
- &:hover {
113
- background-color: #B2F4F3;
114
- }
115
- &:active {
116
- background-color: #91F0EE;
117
- }
118
- }
119
- }
120
-
121
- &--neutral {
122
- background-color: var(--color-background-neutral);
123
- color: var(--color-content-primary);
124
-
125
- a, button {
126
- color: var(--color-content-primary);
127
- }
128
-
129
- .wds-inline-prompt&:has(a, button) {
130
- &:hover {
131
- background-color: var(--color-background-neutral-hover);
132
- }
133
- &:active {
134
- background-color: var(--color-background-neutral-active);
135
- }
60
+ color: var(--color-sentiment-content-primary);
136
61
  }
137
62
  }
138
63
 
139
- &--warning {
140
- background-color: var(--color-sentiment-warning-secondary);
141
- color: var(--color-sentiment-warning-content);
64
+ .wds-inline-prompt-process-indicator {
65
+ width: var(--size-16);
66
+ height: var(--size-16);
142
67
 
143
- a, button {
144
- color: var(--color-sentiment-warning-content);
145
- &:hover {
146
- color: var(--color-sentiment-warning-content-hover);
147
- }
148
- &:active {
149
- color: var(--color-sentiment-warning-content-active);
150
- }
151
- }
152
-
153
- .wds-inline-prompt&:has(a, button) {
154
- &:hover {
155
- background-color: color-mix(in srgb, var(--color-sentiment-warning-secondary) 92%, var(--color-sentiment-warning-primary));
156
- }
157
- &:active {
158
- background-color: color-mix(in srgb, var(--color-sentiment-warning-secondary) 84%, var(--color-sentiment-warning-primary));
159
- }
160
- }
68
+ // This belongs in ProcessIndicator but there are many conflicting
69
+ // styles in the CSS package, so keeping it colocated for now.
70
+ .process-circle {
71
+ stroke: currentColor;
72
+ };
161
73
  }
162
74
  }
@@ -1,10 +1,11 @@
1
- import React from 'react';
2
1
  import { mockMatchMedia, render, screen } from '../../test-utils';
3
2
  import { InlinePrompt, InlinePromptProps } from './InlinePrompt';
4
3
  import { Sentiment } from '../../common';
5
4
 
6
5
  mockMatchMedia();
7
6
 
7
+ const MEDIA = <span data-testid="custom-media">Custom Media</span>;
8
+
8
9
  describe('InlinePrompt', () => {
9
10
  const defaultProps: InlinePromptProps = {
10
11
  children: 'Prompt message',
@@ -21,39 +22,75 @@ describe('InlinePrompt', () => {
21
22
  expect(screen.getByTestId('gift-box-icon')).toBeInTheDocument();
22
23
  });
23
24
 
24
- describe('renders with each sentiment', () => {
25
- it.each([Sentiment.POSITIVE, Sentiment.NEUTRAL, Sentiment.NEGATIVE, Sentiment.WARNING])(
26
- 'renders with sentiment %s',
27
- (sentiment) => {
28
- render(
29
- <InlinePrompt
30
- {...defaultProps}
31
- sentiment={sentiment as InlinePromptProps['sentiment']}
32
- />,
33
- );
25
+ [
26
+ { sentiment: Sentiment.NEGATIVE as const, acceptsMedia: false, statusIconLabel: 'Error:' },
27
+ { sentiment: Sentiment.WARNING as const, acceptsMedia: false, statusIconLabel: 'Warning:' },
28
+ { sentiment: Sentiment.NEUTRAL as const, acceptsMedia: false, statusIconLabel: 'Information:' },
29
+ { sentiment: Sentiment.POSITIVE as const, acceptsMedia: true, statusIconLabel: '' },
30
+ { sentiment: 'proposition' as const, acceptsMedia: true, statusIconLabel: '' },
31
+ ].forEach(({ sentiment, statusIconLabel, acceptsMedia }) => {
32
+ describe(sentiment, () => {
33
+ it('should apply correct styles', () => {
34
+ render(<InlinePrompt {...defaultProps} sentiment={sentiment} />);
34
35
  expect(screen.getByText('Prompt message').parentElement).toHaveClass(
35
36
  `wds-inline-prompt--${sentiment}`,
36
37
  );
37
- },
38
- );
39
- });
38
+ });
40
39
 
41
- it('renders muted state', () => {
42
- render(<InlinePrompt {...defaultProps} muted />);
43
- screen.debug(undefined, 99999999);
44
- expect(screen.getByText('Prompt message').parentElement).toHaveClass(
45
- 'wds-inline-prompt--muted',
46
- );
47
- expect(screen.getByTestId('InlinePrompt_Muted')).toBeInTheDocument();
48
- });
40
+ if (statusIconLabel) {
41
+ it('should render StatusIcon', () => {
42
+ render(<InlinePrompt {...defaultProps} sentiment={sentiment} />);
43
+ expect(screen.getByLabelText(statusIconLabel)).toBeInTheDocument();
44
+ });
45
+ }
49
46
 
50
- it('renders loading state', () => {
51
- render(<InlinePrompt {...defaultProps} loading />);
52
- screen.debug(undefined, 99999999);
53
- expect(screen.getByText('Prompt message').parentElement).toHaveClass(
54
- 'wds-inline-prompt--loading',
55
- );
56
- expect(screen.getByTestId('InlinePrompt_ProcessIndicator')).toBeInTheDocument();
47
+ describe('muted state', () => {
48
+ it('should render icon and apply css', () => {
49
+ render(<InlinePrompt {...defaultProps} muted sentiment={sentiment} />);
50
+ expect(screen.getByText('Prompt message').parentElement).toHaveClass(
51
+ 'wds-inline-prompt--muted',
52
+ );
53
+ expect(screen.getByTestId('InlinePrompt_Muted')).toBeInTheDocument();
54
+ });
55
+
56
+ it('should trump `media`', () => {
57
+ render(<InlinePrompt {...defaultProps} muted sentiment={sentiment} media={MEDIA} />);
58
+ expect(screen.getByTestId('InlinePrompt_Muted')).toBeInTheDocument();
59
+ expect(screen.queryByTestId('custom-media')).not.toBeInTheDocument();
60
+ });
61
+ });
62
+
63
+ describe('loading state', () => {
64
+ it('should render icon and apply css', () => {
65
+ render(<InlinePrompt {...defaultProps} sentiment={sentiment} loading />);
66
+ expect(screen.getByText('Prompt message').parentElement).toHaveClass(
67
+ 'wds-inline-prompt--loading',
68
+ );
69
+ expect(screen.getByTestId('InlinePrompt_ProcessIndicator')).toBeInTheDocument();
70
+ });
71
+
72
+ it('should trump `media`', () => {
73
+ render(<InlinePrompt {...defaultProps} sentiment={sentiment} loading media={MEDIA} />);
74
+ expect(screen.getByTestId('InlinePrompt_ProcessIndicator')).toBeInTheDocument();
75
+ expect(screen.queryByTestId('custom-media')).not.toBeInTheDocument();
76
+ });
77
+ });
78
+
79
+ describe('custom media', () => {
80
+ if (acceptsMedia) {
81
+ it('should respect `media`', () => {
82
+ render(<InlinePrompt {...defaultProps} sentiment={sentiment} media={MEDIA} />);
83
+ expect(screen.getByTestId('custom-media')).toBeInTheDocument();
84
+ });
85
+ } else {
86
+ it('should ignore `media`', () => {
87
+ render(<InlinePrompt {...defaultProps} sentiment={sentiment} media={MEDIA} />);
88
+ expect(screen.getByLabelText(statusIconLabel)).toBeInTheDocument();
89
+ expect(screen.queryByTestId('custom-media')).not.toBeInTheDocument();
90
+ });
91
+ }
92
+ });
93
+ });
57
94
  });
58
95
 
59
96
  it('applies custom className, id, and data-testid', () => {
@@ -69,4 +106,25 @@ describe('InlinePrompt', () => {
69
106
  expect(el).toHaveClass('custom-class');
70
107
  expect(el).toHaveAttribute('id', 'custom-id');
71
108
  });
109
+
110
+ describe('SentimentSurface integration', () => {
111
+ it('maps positive sentiment to success for SentimentSurface', () => {
112
+ render(
113
+ <InlinePrompt {...defaultProps} sentiment={Sentiment.POSITIVE} data-testid="prompt" />,
114
+ );
115
+ const el = screen.getByTestId('prompt');
116
+ // The component should have both the original class and the SentimentSurface class
117
+ expect(el).toHaveClass('wds-inline-prompt--positive');
118
+ expect(el).toHaveClass('wds-sentiment-surface');
119
+ });
120
+
121
+ it('passes through other sentiments unchanged', () => {
122
+ render(
123
+ <InlinePrompt {...defaultProps} sentiment={Sentiment.NEGATIVE} data-testid="prompt" />,
124
+ );
125
+ const el = screen.getByTestId('prompt');
126
+ expect(el).toHaveClass('wds-inline-prompt--negative');
127
+ expect(el).toHaveClass('wds-sentiment-surface');
128
+ });
129
+ });
72
130
  });