@transferwise/components 0.0.0-experimental-d3e6e9d → 0.0.0-experimental-18b5666

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 (33) hide show
  1. package/build/i18n/uk.json +28 -6
  2. package/build/i18n/uk.json.js +28 -6
  3. package/build/i18n/uk.json.js.map +1 -1
  4. package/build/i18n/uk.json.mjs +28 -6
  5. package/build/i18n/uk.json.mjs.map +1 -1
  6. package/build/listItem/ListItem.js.map +1 -1
  7. package/build/listItem/ListItem.mjs.map +1 -1
  8. package/build/main.css +7 -5
  9. package/build/modal/Modal.js +1 -0
  10. package/build/modal/Modal.js.map +1 -1
  11. package/build/modal/Modal.mjs +1 -0
  12. package/build/modal/Modal.mjs.map +1 -1
  13. package/build/prompt/InlinePrompt/InlinePrompt.js +1 -4
  14. package/build/prompt/InlinePrompt/InlinePrompt.js.map +1 -1
  15. package/build/prompt/InlinePrompt/InlinePrompt.mjs +1 -4
  16. package/build/prompt/InlinePrompt/InlinePrompt.mjs.map +1 -1
  17. package/build/styles/listItem/ListItem.css +7 -5
  18. package/build/styles/main.css +7 -5
  19. package/build/types/listItem/ListItem.d.ts.map +1 -1
  20. package/build/types/modal/Modal.d.ts.map +1 -1
  21. package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts +2 -2
  22. package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts.map +1 -1
  23. package/package.json +15 -15
  24. package/src/i18n/uk.json +28 -6
  25. package/src/listItem/ListItem.css +7 -5
  26. package/src/listItem/ListItem.less +75 -61
  27. package/src/listItem/ListItem.tsx +1 -2
  28. package/src/listItem/_stories/ListItem.disabled.story.tsx +5 -1
  29. package/src/main.css +7 -5
  30. package/src/modal/Modal.tsx +1 -0
  31. package/src/prompt/InlinePrompt/InlinePrompt.spec.tsx +10 -18
  32. package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +9 -6
  33. package/src/prompt/InlinePrompt/InlinePrompt.tsx +4 -7
@@ -12,11 +12,11 @@
12
12
  container-type: inline-size;
13
13
 
14
14
  & + .wds-list-item-spotlight,
15
- .wds-list-item-spotlight + &{
15
+ .wds-list-item-spotlight + & {
16
16
  margin-top: var(--size-16);
17
17
  }
18
18
 
19
- &:focus-within{
19
+ &:focus-within {
20
20
  z-index: 1;
21
21
  }
22
22
 
@@ -30,7 +30,7 @@
30
30
  &.fullyInteractive {
31
31
  margin-bottom: 0;
32
32
  &:before {
33
- content: '';
33
+ content: "";
34
34
  position: absolute;
35
35
  inset: 0;
36
36
  }
@@ -40,7 +40,7 @@
40
40
  a {
41
41
  text-underline-offset: calc(var(--size-4) / 2);
42
42
 
43
- .wds-list-item-subtitle,
43
+ .wds-list-item-subtitle,
44
44
  .wds-list-item-subtitle-value {
45
45
  color: var(--color-content-secondary);
46
46
  }
@@ -54,11 +54,13 @@
54
54
  }
55
55
 
56
56
  .wds-list-item-additional-info {
57
- .ring-offset-0
57
+ .ring-offset-0;
58
58
  }
59
59
 
60
60
  a.wds-list-item-control {
61
- &, &:hover, &:focus {
61
+ &,
62
+ &:hover,
63
+ &:focus {
62
64
  text-decoration: none;
63
65
  }
64
66
 
@@ -69,7 +71,7 @@
69
71
 
70
72
  &.wds-list-item-control_pseudo-element {
71
73
  &:before {
72
- content: '';
74
+ content: "";
73
75
  position: absolute;
74
76
  inset: 0;
75
77
  }
@@ -99,7 +101,7 @@
99
101
  &:has(input[type="checkbox"]:focus-visible) {
100
102
  &:before {
101
103
  .ring();
102
- content: '';
104
+ content: "";
103
105
  position: absolute;
104
106
  inset: 0 -8px;
105
107
  border-radius: var(--radius-medium);
@@ -111,7 +113,7 @@
111
113
  &:hover,
112
114
  &:active {
113
115
  &:before {
114
- content: '';
116
+ content: "";
115
117
  position: absolute;
116
118
  inset: 0 -8px;
117
119
  border-radius: var(--radius-medium);
@@ -145,9 +147,9 @@
145
147
  }
146
148
 
147
149
  .wds-list-item-button-control {
148
- .wds-Button {
149
- transition: none;
150
- }
150
+ .wds-Button {
151
+ transition: none;
152
+ }
151
153
  }
152
154
  }
153
155
 
@@ -173,13 +175,16 @@
173
175
  align-items: start;
174
176
  width: 100%;
175
177
  display: grid;
176
- grid-template-columns: var(--wds-list-item-body-left, 1fr) var(--wds-list-item-body-right, max-content);
178
+ grid-template-columns: var(--wds-list-item-body-left, 1fr) var(
179
+ --wds-list-item-body-right,
180
+ max-content
181
+ );
177
182
  gap: var(--size-16);
178
183
  word-break: break-word;
179
184
  }
180
185
 
181
186
  &-titles,
182
- &-value{
187
+ &-value {
183
188
  display: flex;
184
189
  flex-direction: column;
185
190
  justify-content: center;
@@ -193,8 +198,9 @@
193
198
  text-align: right;
194
199
  }
195
200
 
196
- &-title, &-title-value {
197
- color: var(--color-content-primary);
201
+ &-title,
202
+ &-title-value {
203
+ color: var(--color-content-primary);
198
204
  }
199
205
 
200
206
  &-body-center {
@@ -204,17 +210,17 @@
204
210
  }
205
211
 
206
212
  &-additional-info {
207
- grid-area: info;
208
- color: var(--color-content-tertiary);
209
- margin-top: calc(var(--size-4) * -1);
213
+ grid-area: info;
214
+ color: var(--color-content-tertiary);
215
+ margin-top: calc(var(--size-4) * -1);
210
216
 
211
- button.np-link {
212
- text-align: start;
213
- }
217
+ button.np-link {
218
+ text-align: start;
219
+ }
214
220
  }
215
221
 
216
222
  &-control-wrapper {
217
- grid-area: control;
223
+ grid-area: control;
218
224
  }
219
225
 
220
226
  &-navigation {
@@ -224,80 +230,89 @@
224
230
  }
225
231
 
226
232
  &-control {
227
- flex: 0 0 auto;
233
+ flex: 0 0 auto;
228
234
  }
229
235
 
230
236
  &.disabled {
231
237
  opacity: unset;
232
238
 
233
- &, label {
239
+ &,
240
+ label {
234
241
  cursor: not-allowed;
235
242
  }
236
243
 
237
- .wds-list-item-media, .np-avatar-view-content,
244
+ .wds-list-item-media,
245
+ .np-avatar-view-content,
238
246
  .wds-list-item-title,
239
247
  .wds-list-item-title-value,
240
248
  .wds-list-item-subtitle,
241
249
  .wds-list-item-subtitle-value,
242
- .wds-list-item-additional-info {
250
+ .wds-list-item-additional-info,
251
+ .wds-list-item-additional-info :is(strong, b) {
243
252
  color: var(--color-content-tertiary);
244
253
  }
245
254
 
246
255
  .wds-list-item-media,
247
256
  .wds-list-item-body,
248
257
  .wds-list-item-additional-info {
249
- opacity: .93;
258
+ opacity: 0.93;
250
259
  }
251
260
  }
252
261
 
253
262
  &.disabled--has-prompt-reason {
254
- .wds-list-item-prompt{
255
- opacity: .93;
263
+ .wds-list-item-prompt {
264
+ opacity: 0.93;
256
265
  }
257
266
  }
258
267
 
259
268
  &-spotlight {
260
- padding-left: var(--size-12);
261
- padding-right: var(--size-12);
262
-
263
- &-active {
264
- background-color: var(--color-background-neutral);
265
- &:not(.disabled, :disabled) {
266
- &:hover {
267
- background-color: var(--color-background-neutral-hover);
268
- }
269
- &:active {
270
- background-color: var(--color-background-neutral-active);
271
- }
272
- }
273
- }
274
-
275
- &-inactive {
276
- background-color: color-mix(in srgb, var(--color-background-neutral) 25%, transparent);
269
+ padding-left: var(--size-12);
270
+ padding-right: var(--size-12);
277
271
 
278
- &:not(.disabled, :disabled) {
279
- &:hover {
280
- background-color: color-mix(in srgb, var(--color-background-neutral-hover) 35%, transparent);
281
- }
282
- &:active {
283
- background-color: color-mix(in srgb, var(--color-background-neutral-active) 45%, transparent);
284
- }
285
- }
272
+ &-active {
273
+ background-color: var(--color-background-neutral);
274
+ &:not(.disabled, :disabled) {
275
+ &:hover {
276
+ background-color: var(--color-background-neutral-hover);
277
+ }
278
+ &:active {
279
+ background-color: var(--color-background-neutral-active);
280
+ }
286
281
  }
282
+ }
287
283
 
284
+ &-inactive {
285
+ background-color: color-mix(in srgb, var(--color-background-neutral) 25%, transparent);
288
286
 
287
+ &:not(.disabled, :disabled) {
288
+ &:hover {
289
+ background-color: color-mix(
290
+ in srgb,
291
+ var(--color-background-neutral-hover) 35%,
292
+ transparent
293
+ );
294
+ }
295
+ &:active {
296
+ background-color: color-mix(
297
+ in srgb,
298
+ var(--color-background-neutral-active) 45%,
299
+ transparent
300
+ );
301
+ }
302
+ }
303
+ }
289
304
  }
290
305
 
291
- .wds-list-item-spotlight__border{
306
+ .wds-list-item-spotlight__border {
292
307
  position: absolute;
293
- inset:0;
308
+ inset: 0;
294
309
  width: 100%;
295
310
  height: 100%;
296
311
 
297
312
  rect {
298
313
  --wds-list-item-spotlight-borderWidth: 1px;
299
- --wds-list-item-spotlight-borderWidthOffset: .5px; // half of the border width to center the border
300
- --wds-list-item-spotlight-strokeDashSize: calc(var(--size-12) * .5);
314
+ --wds-list-item-spotlight-borderWidthOffset: 0.5px; // half of the border width to center the border
315
+ --wds-list-item-spotlight-strokeDashSize: calc(var(--size-12) * 0.5);
301
316
 
302
317
  fill: none;
303
318
  stroke: var(--color-border-neutral);
@@ -307,8 +322,7 @@
307
322
  y: var(--wds-list-item-spotlight-borderWidthOffset);
308
323
  rx: calc(var(--radius-medium) - var(--wds-list-item-spotlight-borderWidthOffset));
309
324
  ry: calc(var(--radius-medium) - var(--wds-list-item-spotlight-borderWidthOffset));
310
- stroke-dasharray:
311
- var(--wds-list-item-spotlight-strokeDashSize)
325
+ stroke-dasharray: var(--wds-list-item-spotlight-strokeDashSize)
312
326
  var(--wds-list-item-spotlight-strokeDashSize);
313
327
  }
314
328
  }
@@ -142,7 +142,7 @@ export const ListItem = ({
142
142
 
143
143
  const isPartiallyInteractive = Boolean(
144
144
  (controlType === 'button' || controlType === 'icon-button') &&
145
- (controlProps as ListItemButtonProps | ListItemIconButtonProps)?.partiallyInteractive,
145
+ (controlProps as ListItemButtonProps | ListItemIconButtonProps)?.partiallyInteractive,
146
146
  );
147
147
  const isFullyInteractive = controlType !== 'non-interactive' && !isPartiallyInteractive;
148
148
  const isButtonAsLink =
@@ -162,7 +162,6 @@ export const ListItem = ({
162
162
  ? additionalInfoPrompt
163
163
  : `${titlesAndValues} ${additionalInfoPrompt}`;
164
164
  }, [isFullyInteractive]);
165
-
166
165
  const listItemContext = useMemo(
167
166
  () => ({
168
167
  setControlType,
@@ -426,7 +426,11 @@ export const AllControls: Story = {
426
426
  }
427
427
  title="Non-interactive"
428
428
  subtitle={lorem10}
429
- additionalInfo={INFO.nonInteractive}
429
+ additionalInfo={
430
+ <ListItem.AdditionalInfo>
431
+ Which has <b>bold,</b> <strong>strong,</strong> <em>emphasis</em>
432
+ </ListItem.AdditionalInfo>
433
+ }
430
434
  />
431
435
  </List>
432
436
  ),
package/src/main.css CHANGED
@@ -3585,7 +3585,7 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3585
3585
  margin-bottom: 0;
3586
3586
  }
3587
3587
  .wds-list-item-view.fullyInteractive:before {
3588
- content: '';
3588
+ content: "";
3589
3589
  position: absolute;
3590
3590
  inset: 0;
3591
3591
  }
@@ -3616,7 +3616,7 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3616
3616
  z-index: 1;
3617
3617
  }
3618
3618
  .wds-list-item-interactive a.wds-list-item-control.wds-list-item-control_pseudo-element:before {
3619
- content: '';
3619
+ content: "";
3620
3620
  position: absolute;
3621
3621
  inset: 0;
3622
3622
  }
@@ -3634,7 +3634,7 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3634
3634
  .wds-list-item-interactive:not(.wds-list-item-spotlight):has(input[type="checkbox"]:focus-visible):before {
3635
3635
  outline: var(--ring-outline-color) solid var(--ring-outline-width);
3636
3636
  outline-offset: var(--ring-outline-offset);
3637
- content: '';
3637
+ content: "";
3638
3638
  position: absolute;
3639
3639
  inset: 0 -8px;
3640
3640
  border-radius: 16px;
@@ -3643,7 +3643,7 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3643
3643
  }
3644
3644
  .wds-list-item-interactive:not(.wds-list-item-spotlight):not(.disabled):not(:disabled):hover:before,
3645
3645
  .wds-list-item-interactive:not(.wds-list-item-spotlight):not(.disabled):not(:disabled):active:before {
3646
- content: '';
3646
+ content: "";
3647
3647
  position: absolute;
3648
3648
  inset: 0 -8px;
3649
3649
  border-radius: 16px;
@@ -3755,7 +3755,9 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3755
3755
  .wds-list-item.disabled .wds-list-item-title-value,
3756
3756
  .wds-list-item.disabled .wds-list-item-subtitle,
3757
3757
  .wds-list-item.disabled .wds-list-item-subtitle-value,
3758
- .wds-list-item.disabled .wds-list-item-additional-info {
3758
+ .wds-list-item.disabled .wds-list-item-additional-info,
3759
+ .wds-list-item.disabled .wds-list-item-additional-info strong,
3760
+ .wds-list-item.disabled .wds-list-item-additional-info b {
3759
3761
  color: #768e9c;
3760
3762
  color: var(--color-content-tertiary);
3761
3763
  }
@@ -67,6 +67,7 @@ const Modal = ({
67
67
  return !isMedium ? (
68
68
  <Drawer
69
69
  open={open}
70
+ className={className}
70
71
  headerTitle={title}
71
72
  footerContent={footer}
72
73
  position={Position.BOTTOM}
@@ -23,12 +23,12 @@ describe('InlinePrompt', () => {
23
23
  });
24
24
 
25
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: 'Success:' },
30
- { sentiment: 'proposition' as const, acceptsMedia: true, statusIconLabel: '' },
31
- ].forEach(({ sentiment, statusIconLabel, acceptsMedia }) => {
26
+ { sentiment: Sentiment.NEGATIVE as const, statusIconLabel: 'Error:' },
27
+ { sentiment: Sentiment.WARNING as const, statusIconLabel: 'Warning:' },
28
+ { sentiment: Sentiment.NEUTRAL as const, statusIconLabel: 'Information:' },
29
+ { sentiment: Sentiment.POSITIVE as const, statusIconLabel: 'Success:' },
30
+ { sentiment: 'proposition' as const, statusIconLabel: '' },
31
+ ].forEach(({ sentiment, statusIconLabel }) => {
32
32
  describe(sentiment, () => {
33
33
  it('should apply correct styles', () => {
34
34
  render(<InlinePrompt {...defaultProps} sentiment={sentiment} />);
@@ -77,18 +77,10 @@ describe('InlinePrompt', () => {
77
77
  });
78
78
 
79
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
- }
80
+ it('should respect `media`', () => {
81
+ render(<InlinePrompt {...defaultProps} sentiment={sentiment} media={MEDIA} />);
82
+ expect(screen.getByTestId('custom-media')).toBeInTheDocument();
83
+ });
92
84
  });
93
85
 
94
86
  describe('mediaLabel', () => {
@@ -1,7 +1,7 @@
1
1
  import type { ReactElement } from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react-webpack5';
3
3
  import { action } from 'storybook/actions';
4
- import { Taxi, Travel } from '@transferwise/icons';
4
+ import { Clock, Id, Taxi, Travel } from '@transferwise/icons';
5
5
  import { lorem5 } from '../../test-utils';
6
6
  import Link from '../../link';
7
7
  import { InlinePrompt, InlinePromptProps } from './InlinePrompt';
@@ -222,8 +222,8 @@ export const Muted: StoryObj<PreviewStoryArgs> = {
222
222
  };
223
223
 
224
224
  /**
225
- * While main sentiments (`warning`, `negative`, `neutral`) must retain their associated
226
- * `StatusIcons`, the `positive` and `proposition` ones allow for Icon overrides to bring it
225
+ * While all main sentiments (`warning`, `negative`, `positive` and`neutral`) are associated with a
226
+ * default `StatusIcon`s, we also allow for Icon overrides to bring the prompt's visual language
227
227
  * closer to the prompt's content. <br /><br />
228
228
  * It's also possible to override the default icon's accessible name announced by screen readers
229
229
  * via `mediaLabel` prop, which is especially useful for the `proposition` sentiment.
@@ -232,14 +232,17 @@ export const IconOverrides: StoryObj<PreviewStoryArgs> = {
232
232
  render: (args: PreviewStoryArgs) => {
233
233
  return (
234
234
  <>
235
- <InlinePrompt {...args} media={<Travel />} sentiment="positive">
235
+ <InlinePrompt {...args} media={<Travel />} sentiment="positive" mediaLabel="Success: ">
236
236
  Your travel account is set up and ready to use.
237
237
  </InlinePrompt>
238
238
  <InlinePrompt {...args} media={<Taxi />} sentiment="proposition" mediaLabel="Taxi addon: ">
239
239
  Connect Wise with your taxi app to get exclusive discounts.
240
240
  </InlinePrompt>
241
- <InlinePrompt {...args} media={<Taxi />} sentiment="negative">
242
- This icon override is ignored.
241
+ <InlinePrompt {...args} media={<Clock />} sentiment="warning" mediaLabel="Processing: ">
242
+ The account verification is taking longer than usual.
243
+ </InlinePrompt>
244
+ <InlinePrompt {...args} media={<Id />} sentiment="negative" mediaLabel="Error: ">
245
+ The identity document you provided has expired.
243
246
  </InlinePrompt>
244
247
  </>
245
248
  );
@@ -25,12 +25,12 @@ export type InlinePromptProps = {
25
25
  */
26
26
  muted?: boolean;
27
27
  /**
28
- * Icon override for `proposition` and `positive` sentiments. Unsupported for remaining ones.
28
+ * Icon override for all sentiments. If the sentiment uses StatusIcon by default, it will be
29
+ * replaced by a plain icon.
29
30
  */
30
31
  media?: React.ReactNode;
31
32
  /**
32
33
  * Override for the sentiment's-derived, default, accessible name announced by the screen readers.
33
- * To be used primarily for `proposition` sentiment.
34
34
  */
35
35
  mediaLabel?: string;
36
36
  /**
@@ -68,6 +68,7 @@ export const InlinePrompt = ({
68
68
  if (muted) {
69
69
  return <BackslashCircle size={16} data-testid="InlinePrompt_Muted" title={mediaLabel} />;
70
70
  }
71
+
71
72
  if (loading) {
72
73
  return (
73
74
  <ProcessIndicator
@@ -78,15 +79,11 @@ export const InlinePrompt = ({
78
79
  );
79
80
  }
80
81
 
81
- if (sentiment === 'positive' && media) {
82
- return media;
83
- }
84
-
85
82
  if (sentiment === 'proposition') {
86
83
  return media || <GiftBox title={mediaLabel} />;
87
84
  }
88
85
 
89
- return <StatusIcon size={16} sentiment={sentiment} iconLabel={mediaLabel} />;
86
+ return media || <StatusIcon size={16} sentiment={sentiment} iconLabel={mediaLabel} />;
90
87
  };
91
88
 
92
89
  return (