@transferwise/components 46.105.4 → 46.106.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 (41) hide show
  1. package/build/dateInput/DateInput.js.map +1 -1
  2. package/build/dateInput/DateInput.mjs.map +1 -1
  3. package/build/header/Header.js.map +1 -1
  4. package/build/header/Header.mjs.map +1 -1
  5. package/build/inputs/SelectInput.js.map +1 -1
  6. package/build/inputs/SelectInput.mjs.map +1 -1
  7. package/build/main.css +23 -11
  8. package/build/styles/listItem/ListItem.css +23 -11
  9. package/build/styles/listItem/ListItem.grid.css +23 -9
  10. package/build/styles/main.css +23 -11
  11. package/build/types/dateInput/DateInput.d.ts.map +1 -1
  12. package/build/types/header/Header.d.ts +2 -2
  13. package/build/types/header/Header.d.ts.map +1 -1
  14. package/build/types/inputs/SelectInput.d.ts +2 -1
  15. package/build/types/inputs/SelectInput.d.ts.map +1 -1
  16. package/build/types/listItem/_stories/helpers.d.ts +1 -0
  17. package/build/types/listItem/_stories/helpers.d.ts.map +1 -1
  18. package/build/types/listItem/_stories/subcomponents.d.ts +6 -0
  19. package/build/types/listItem/_stories/subcomponents.d.ts.map +1 -1
  20. package/build/types/listItem/_stories/variants/helpers.d.ts +8 -0
  21. package/build/types/listItem/_stories/variants/helpers.d.ts.map +1 -0
  22. package/package.json +1 -1
  23. package/src/dateInput/DateInput.tsx +1 -3
  24. package/src/header/Header.tsx +2 -2
  25. package/src/inputs/SelectInput.tsx +2 -1
  26. package/src/listItem/ListItem.css +23 -11
  27. package/src/listItem/ListItem.grid.css +23 -9
  28. package/src/listItem/ListItem.grid.less +31 -9
  29. package/src/listItem/ListItem.less +0 -2
  30. package/src/listItem/_stories/helpers.tsx +8 -0
  31. package/src/listItem/_stories/subcomponents.tsx +7 -0
  32. package/src/listItem/_stories/variants/ListItem.brightGreen.test.story.tsx +49 -0
  33. package/src/listItem/_stories/variants/ListItem.dark.test.story.tsx +43 -0
  34. package/src/listItem/_stories/variants/ListItem.forestGreen.test.story.tsx +49 -0
  35. package/src/listItem/_stories/variants/ListItem.medium.test.story.tsx +34 -0
  36. package/src/listItem/_stories/variants/ListItem.personal.test.story.tsx +130 -0
  37. package/src/listItem/_stories/variants/ListItem.rtl.test.story.tsx +43 -0
  38. package/src/listItem/_stories/variants/ListItem.small.test.story.tsx +34 -0
  39. package/src/listItem/_stories/variants/helpers.tsx +127 -0
  40. package/src/main.css +23 -11
  41. package/src/listItem/_stories/ListItem.variants.test.story.tsx +0 -274
@@ -0,0 +1,127 @@
1
+ import { StoryObj } from '@storybook/react-webpack5';
2
+ import { StoryConfig, storyConfig } from '../../../test-utils';
3
+ import List from '../../../list';
4
+ import { ListItem, type ListItemProps } from '../../ListItem';
5
+ import {
6
+ SB_LIST_ITEM_ADDITIONAL_INFO as INFO,
7
+ SB_LIST_ITEM_CONTROLS as CONTROLS,
8
+ SB_LIST_ITEM_MEDIA as MEDIA,
9
+ SB_LIST_ITEM_PROMPTS as PROMPT,
10
+ SB_LIST_ITEM_TEXT as TEXT,
11
+ SB_ListItem_ControlType as ControlType,
12
+ } from '../subcomponents';
13
+
14
+ type Story = StoryObj<ListItemProps>;
15
+ type VariantPartial = { title: string } & Partial<ListItemProps>;
16
+
17
+ const { title, subtitle, valueTitle, valueSubtitle } = TEXT;
18
+ const prompt = PROMPT.nonInteractive;
19
+ const media = MEDIA.avatarSingle;
20
+
21
+ export const generateVariantsForControl = (
22
+ controlType: ControlType,
23
+ variant: NonNullable<StoryConfig['variants']>[number] = 'default',
24
+ ): Story => {
25
+ const control = CONTROLS[controlType];
26
+ const isInteractive = [
27
+ 'partialButton',
28
+ 'partialButtonAsLink',
29
+ 'partialIconButton',
30
+ 'partialIconButtonAsLink',
31
+ ].includes(controlType);
32
+ const additionalInfo = isInteractive ? INFO.interactive : INFO.nonInteractive;
33
+ const instances = [
34
+ { title },
35
+ { title, valueTitle },
36
+ { title, subtitle },
37
+ { title, additionalInfo },
38
+ { title, valueTitle, valueSubtitle },
39
+ { title, subtitle, inverted: true },
40
+ { title, subtitle, valueTitle },
41
+ { title, subtitle, valueTitle, inverted: true },
42
+ { title, subtitle, valueTitle, valueSubtitle },
43
+ { title, subtitle, valueTitle, valueSubtitle, inverted: true },
44
+ { media, title },
45
+ { media, title, valueTitle },
46
+ { media, title, subtitle },
47
+ { media, title, valueTitle, valueSubtitle },
48
+ { media, title, valueTitle },
49
+ { media, title, valueSubtitle },
50
+ { media, title, subtitle },
51
+ { media, title, additionalInfo },
52
+ { media, title, subtitle, valueTitle },
53
+ { media, title, subtitle, valueTitle, valueSubtitle },
54
+ { media, title, subtitle, additionalInfo: INFO.nonInteractive },
55
+ isInteractive ? { media, title, subtitle, additionalInfo: INFO.interactive } : null,
56
+ { media, title, subtitle, additionalInfo, valueTitle },
57
+ { media, title, subtitle, additionalInfo, valueTitle, valueSubtitle },
58
+ { media, title, subtitle, additionalInfo, valueTitle, valueSubtitle, prompt },
59
+ {
60
+ media,
61
+ title,
62
+ subtitle,
63
+ additionalInfo,
64
+ valueTitle,
65
+ valueSubtitle,
66
+ prompt: PROMPT.interactive,
67
+ },
68
+ {
69
+ media,
70
+ title,
71
+ subtitle,
72
+ additionalInfo,
73
+ valueTitle,
74
+ valueSubtitle,
75
+ prompt: PROMPT.interactive,
76
+ inverted: true,
77
+ },
78
+ {
79
+ media,
80
+ title,
81
+ subtitle,
82
+ additionalInfo,
83
+ valueTitle,
84
+ valueSubtitle,
85
+ prompt: PROMPT.interactive,
86
+ spotlight: 'active',
87
+ },
88
+ {
89
+ media,
90
+ title,
91
+ subtitle,
92
+ additionalInfo,
93
+ valueTitle,
94
+ valueSubtitle,
95
+ prompt: PROMPT.interactive,
96
+ spotlight: 'inactive',
97
+ },
98
+ {
99
+ media,
100
+ title,
101
+ subtitle,
102
+ additionalInfo,
103
+ valueTitle,
104
+ valueSubtitle,
105
+ prompt: PROMPT.interactive,
106
+ spotlight: 'inactive',
107
+ disabled: true,
108
+ },
109
+ ].filter(Boolean) as VariantPartial[];
110
+
111
+ return storyConfig(
112
+ {
113
+ render: () => (
114
+ <List>
115
+ {instances.map((instance, instanceIndex) => (
116
+ <ListItem
117
+ key={`${variant}-${controlType}-${instanceIndex}`}
118
+ control={control}
119
+ {...instance}
120
+ />
121
+ ))}
122
+ </List>
123
+ ),
124
+ },
125
+ { variants: [variant] },
126
+ );
127
+ };
package/src/main.css CHANGED
@@ -2649,7 +2649,15 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
2649
2649
  gap: 4px 16px;
2650
2650
  gap: var(--size-4) var(--size-16);
2651
2651
  }
2652
+ .wds-list-item-gridWrapper.wds-list-item-hasMedia-hasControl.wds-list-item-noInfo-hasPrompt:not(:has(.wds-list-item-subtitle-value, .wds-list-item-subtitle)) .wds-list-item-prompt,
2653
+ .wds-list-item-gridWrapper.wds-list-item-hasMedia-noControl.wds-list-item-noInfo-hasPrompt:not(:has(.wds-list-item-subtitle-value, .wds-list-item-subtitle)) .wds-list-item-prompt {
2654
+ margin-top: -2px;
2655
+ }
2652
2656
  @container (min-width: 375px) {
2657
+ .wds-list-item-gridWrapper .wds-list-item-control-wrapper {
2658
+ height: var(--wds-list-item-control-wrapper-height);
2659
+ align-content: center;
2660
+ }
2653
2661
  .wds-list-item-gridWrapper .wds-list-item-media-image {
2654
2662
  -o-object-position: center;
2655
2663
  object-position: center;
@@ -2746,6 +2754,9 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
2746
2754
  -o-object-position: bottom left;
2747
2755
  object-position: bottom left;
2748
2756
  }
2757
+ .wds-list-item-gridWrapper .wds-list-item-control-wrapper {
2758
+ align-content: start;
2759
+ }
2749
2760
  .wds-list-item-gridWrapper.wds-list-item-hasMedia-hasControl.wds-list-item-hasInfo-hasPrompt {
2750
2761
  grid-template-columns: 1fr auto;
2751
2762
  grid-template-rows: auto auto auto auto;
@@ -2866,8 +2877,11 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
2866
2877
  }
2867
2878
  }
2868
2879
  @container (max-width: 297px) {
2880
+ .wds-list-item-gridWrapper .wds-list-item-control-wrapper {
2881
+ align-content: start;
2882
+ }
2869
2883
  .wds-list-item-gridWrapper.wds-list-item-hasMedia-hasControl.wds-list-item-hasInfo-hasPrompt {
2870
- grid-template-columns: auto 1fr;
2884
+ grid-template-columns: 1fr auto;
2871
2885
  grid-template-rows: auto auto auto;
2872
2886
  grid-template-areas: "body control" "info control" "prompt prompt";
2873
2887
  }
@@ -2877,7 +2891,7 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
2877
2891
  grid-template-areas: "body" "info" "prompt" "control";
2878
2892
  }
2879
2893
  .wds-list-item-gridWrapper.wds-list-item-hasMedia-hasControl.wds-list-item-hasInfo-noPrompt {
2880
- grid-template-columns: auto 1fr;
2894
+ grid-template-columns: 1fr auto;
2881
2895
  grid-template-rows: auto auto;
2882
2896
  grid-template-areas: "body control" "info control";
2883
2897
  }
@@ -2886,7 +2900,7 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
2886
2900
  grid-template-areas: "body" "info" "control";
2887
2901
  }
2888
2902
  .wds-list-item-gridWrapper.wds-list-item-hasMedia-hasControl.wds-list-item-noInfo-hasPrompt {
2889
- grid-template-columns: auto 1fr;
2903
+ grid-template-columns: 1fr auto;
2890
2904
  grid-template-rows: auto auto;
2891
2905
  grid-template-areas: "body control" "prompt prompt";
2892
2906
  }
@@ -2895,7 +2909,7 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
2895
2909
  grid-template-areas: "body" "prompt" "control";
2896
2910
  }
2897
2911
  .wds-list-item-gridWrapper.wds-list-item-hasMedia-hasControl.wds-list-item-noInfo-noPrompt {
2898
- grid-template-columns: auto 1fr;
2912
+ grid-template-columns: 1fr auto;
2899
2913
  grid-template-rows: auto;
2900
2914
  grid-template-areas: "body control";
2901
2915
  }
@@ -2904,17 +2918,17 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
2904
2918
  grid-template-areas: "body" "control";
2905
2919
  }
2906
2920
  .wds-list-item-gridWrapper.wds-list-item-hasMedia-noControl.wds-list-item-hasInfo-hasPrompt {
2907
- grid-template-columns: auto;
2908
- grid-template-rows: auto auto;
2921
+ grid-template-columns: 1fr;
2922
+ grid-template-rows: auto auto auto;
2909
2923
  grid-template-areas: "body" "info" "prompt";
2910
2924
  }
2911
2925
  .wds-list-item-gridWrapper.wds-list-item-hasMedia-noControl.wds-list-item-hasInfo-noPrompt {
2912
- grid-template-columns: auto;
2913
- grid-template-rows: auto auto auto;
2926
+ grid-template-columns: 1fr;
2927
+ grid-template-rows: auto auto;
2914
2928
  grid-template-areas: "body" "info";
2915
2929
  }
2916
2930
  .wds-list-item-gridWrapper.wds-list-item-hasMedia-noControl.wds-list-item-noInfo-hasPrompt {
2917
- grid-template-columns: auto;
2931
+ grid-template-columns: 1fr;
2918
2932
  grid-template-rows: auto auto;
2919
2933
  grid-template-areas: "body" "prompt";
2920
2934
  }
@@ -3320,8 +3334,6 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
3320
3334
  }
3321
3335
  .wds-list-item-control-wrapper {
3322
3336
  grid-area: control;
3323
- align-content: center;
3324
- height: var(--wds-list-item-control-wrapper-height);
3325
3337
  }
3326
3338
  .wds-list-item-navigation .tw-icon-chevron-right {
3327
3339
  color: #c9cbce;
@@ -1,274 +0,0 @@
1
- import { Meta, StoryObj } from '@storybook/react-webpack5';
2
- import { MultiCurrency } from '@transferwise/icons';
3
- import { storyConfig } from '../../test-utils';
4
- import Link from '../../link';
5
- import List from '../../list';
6
- import { ListItem, type ListItemProps } from '../ListItem';
7
- import {
8
- SB_LIST_ITEM_ADDITIONAL_INFO as ADDITIONAL_INFO,
9
- SB_LIST_ITEM_CONTROLS as CONTROLS,
10
- SB_LIST_ITEM_PROMPTS as PROMPTS,
11
- type SB_ListItem_ControlType as ControlType,
12
- } from './subcomponents';
13
-
14
- export default {
15
- component: ListItem,
16
- title: 'Content/ListItem/tests/variants',
17
- tags: ['!autodocs'],
18
- parameters: {
19
- controls: { disable: true },
20
- actions: { disable: true },
21
- knobs: { disable: true },
22
- },
23
- } satisfies Meta<ListItemProps>;
24
-
25
- type Story = StoryObj<ListItemProps>;
26
- type VariantPartial = { title: string } & Partial<ListItemProps>;
27
-
28
- const title = 'This is a title';
29
- const subtitle = 'And it also has a subtitle';
30
- const infoWithoutLink = (
31
- <ListItem.AdditionalInfo>Which is augmented with additional info.</ListItem.AdditionalInfo>
32
- );
33
- const infoWithLink = (
34
- <ListItem.AdditionalInfo
35
- action={{
36
- label: 'Details about the subject.',
37
- href: 'https://wise.com',
38
- target: '_blank',
39
- }}
40
- >
41
- Which is augmented with additional info.
42
- </ListItem.AdditionalInfo>
43
- );
44
-
45
- const valueTitle = '100 GBP';
46
- const valueSubtitle = '200 USD';
47
- const prompt = <ListItem.Prompt sentiment="positive">Finally, there is a prompt.</ListItem.Prompt>;
48
- const promptWithLink = (
49
- <ListItem.Prompt sentiment="positive">
50
- Finally, there is a prompt{' '}
51
- <Link href="https://wise.com" target="_blank" rel="noreferrer">
52
- referencing some details
53
- </Link>{' '}
54
- for your convenience.
55
- </ListItem.Prompt>
56
- );
57
- const media = (
58
- <ListItem.AvatarView>
59
- <MultiCurrency />
60
- </ListItem.AvatarView>
61
- );
62
-
63
- const generateVariantsForControl = (controlType: ControlType): Story => {
64
- const control = CONTROLS[controlType];
65
- const isInteractive = [
66
- 'partialButton',
67
- 'partialButtonAsLink',
68
- 'partialIconButton',
69
- 'partialIconButtonAsLink',
70
- ].includes(controlType);
71
- const additionalInfo = isInteractive ? infoWithLink : infoWithoutLink;
72
- const variants = [
73
- { title },
74
- { title, valueTitle },
75
- { title, subtitle },
76
- { title, additionalInfo },
77
- { title, valueTitle, valueSubtitle },
78
- { title, subtitle, inverted: true },
79
- { title, subtitle, valueTitle },
80
- { title, subtitle, valueTitle, inverted: true },
81
- { title, subtitle, valueTitle, valueSubtitle },
82
- { title, subtitle, valueTitle, valueSubtitle, inverted: true },
83
- { media, title },
84
- { media, title, valueTitle },
85
- { media, title, subtitle },
86
- { media, title, valueTitle, valueSubtitle },
87
- { media, title, valueTitle },
88
- { media, title, valueSubtitle },
89
- { media, title, subtitle },
90
- { media, title, additionalInfo },
91
- { media, title, subtitle, valueTitle },
92
- { media, title, subtitle, valueTitle, valueSubtitle },
93
- { media, title, subtitle, additionalInfo: infoWithoutLink },
94
- isInteractive ? { media, title, subtitle, additionalInfo: infoWithLink } : null,
95
- { media, title, subtitle, additionalInfo, valueTitle },
96
- { media, title, subtitle, additionalInfo, valueTitle, valueSubtitle },
97
- { media, title, subtitle, additionalInfo, valueTitle, valueSubtitle, prompt },
98
- {
99
- media,
100
- title,
101
- subtitle,
102
- additionalInfo,
103
- valueTitle,
104
- valueSubtitle,
105
- prompt: promptWithLink,
106
- },
107
- {
108
- media,
109
- title,
110
- subtitle,
111
- additionalInfo,
112
- valueTitle,
113
- valueSubtitle,
114
- prompt: promptWithLink,
115
- inverted: true,
116
- },
117
- {
118
- media,
119
- title,
120
- subtitle,
121
- additionalInfo,
122
- valueTitle,
123
- valueSubtitle,
124
- prompt: promptWithLink,
125
- spotlight: 'active',
126
- },
127
- {
128
- media,
129
- title,
130
- subtitle,
131
- additionalInfo,
132
- valueTitle,
133
- valueSubtitle,
134
- prompt: promptWithLink,
135
- spotlight: 'inactive',
136
- },
137
- {
138
- media,
139
- title,
140
- subtitle,
141
- additionalInfo,
142
- valueTitle,
143
- valueSubtitle,
144
- prompt: promptWithLink,
145
- spotlight: 'inactive',
146
- disabled: true,
147
- },
148
- ].filter(Boolean) as VariantPartial[];
149
-
150
- return storyConfig(
151
- {
152
- render: () => (
153
- <List>
154
- {variants.map((variant, variantIndex) => (
155
- <ListItem
156
- key={`${controlType}-${variantIndex}-${Math.random()}`}
157
- control={control}
158
- {...variant}
159
- />
160
- ))}
161
- </List>
162
- ),
163
- },
164
- { variants: ['default', 'dark', 'bright-green', 'forest-green', 'rtl'] },
165
- );
166
- };
167
-
168
- export const Button = generateVariantsForControl('button');
169
- export const ButtonAsLink = generateVariantsForControl('buttonAsLink');
170
- export const ButtonPartiallyInteractive = generateVariantsForControl('partialButton');
171
- export const ButtonAsLinkPartiallyInteractive = generateVariantsForControl('partialButtonAsLink');
172
- export const IconButton = generateVariantsForControl('iconButton');
173
- export const IconButtonAsLink = generateVariantsForControl('iconButtonAsLink');
174
- export const IconButtonWithLabel = generateVariantsForControl('iconButtonWithLabel');
175
- export const IconButtonAsLinkWithLabel = generateVariantsForControl('iconButtonAsLinkWithLabel');
176
- export const IconButtonPartiallyInteractive = generateVariantsForControl('partialIconButton');
177
- export const IconButtonAsLinkPartiallyInteractive =
178
- generateVariantsForControl('partialIconButtonAsLink');
179
- export const Navigation = generateVariantsForControl('navigation');
180
- export const NavigationAsButton = generateVariantsForControl('navigationAsButton');
181
- export const Checkbox = generateVariantsForControl('checkbox');
182
- export const Radio = generateVariantsForControl('radio');
183
- export const Switch = generateVariantsForControl('switch');
184
- export const NonInteractive = generateVariantsForControl('non-interactive');
185
-
186
- export const ButtonControlLabel: Story = {
187
- render: () => (
188
- <List>
189
- <ListItem
190
- title="Fully interactive button."
191
- subtitle="It uses default content hierarchy."
192
- valueTitle="100 GBP"
193
- valueSubtitle="200 USD"
194
- additionalInfo={ADDITIONAL_INFO.nonInteractive}
195
- control={CONTROLS.button}
196
- prompt={PROMPTS.nonInteractive}
197
- />
198
-
199
- <ListItem
200
- inverted
201
- title="Fully interactive button."
202
- subtitle="It uses inverted content hierarchy."
203
- valueTitle="100 GBP"
204
- valueSubtitle="200 USD"
205
- additionalInfo={ADDITIONAL_INFO.nonInteractive}
206
- control={CONTROLS.button}
207
- prompt={PROMPTS.nonInteractive}
208
- />
209
-
210
- <ListItem
211
- title="Fully interactive button as HTML anchor."
212
- subtitle="It uses default content hierarchy."
213
- valueTitle="100 GBP"
214
- valueSubtitle="200 USD"
215
- additionalInfo={ADDITIONAL_INFO.nonInteractive}
216
- control={CONTROLS.buttonAsLink}
217
- prompt={PROMPTS.nonInteractive}
218
- />
219
-
220
- <ListItem
221
- inverted
222
- title="Fully interactive button as HTML anchor."
223
- subtitle="It uses inverted content hierarchy."
224
- valueTitle="100 GBP"
225
- valueSubtitle="200 USD"
226
- additionalInfo={ADDITIONAL_INFO.nonInteractive}
227
- control={CONTROLS.buttonAsLink}
228
- prompt={PROMPTS.nonInteractive}
229
- />
230
-
231
- <ListItem
232
- title="Partially interactive button."
233
- subtitle="It uses default content hierarchy."
234
- valueTitle="100 GBP"
235
- valueSubtitle="200 USD"
236
- additionalInfo={ADDITIONAL_INFO.nonInteractive}
237
- control={CONTROLS.partialButton}
238
- prompt={PROMPTS.nonInteractive}
239
- />
240
-
241
- <ListItem
242
- inverted
243
- title="Partially interactive button."
244
- subtitle="It uses inverted content hierarchy."
245
- valueTitle="100 GBP"
246
- valueSubtitle="200 USD"
247
- additionalInfo={ADDITIONAL_INFO.nonInteractive}
248
- control={CONTROLS.partialButton}
249
- prompt={PROMPTS.nonInteractive}
250
- />
251
-
252
- <ListItem
253
- title="Partially interactive button as HTML anchor."
254
- subtitle="It uses default content hierarchy."
255
- valueTitle="100 GBP"
256
- valueSubtitle="200 USD"
257
- additionalInfo={ADDITIONAL_INFO.nonInteractive}
258
- control={CONTROLS.buttonAsLink}
259
- prompt={PROMPTS.nonInteractive}
260
- />
261
-
262
- <ListItem
263
- inverted
264
- title="Partially interactive button as HTML anchor."
265
- subtitle="It uses inverted content hierarchy."
266
- valueTitle="100 GBP"
267
- valueSubtitle="200 USD"
268
- additionalInfo={ADDITIONAL_INFO.nonInteractive}
269
- control={CONTROLS.buttonAsLink}
270
- prompt={PROMPTS.nonInteractive}
271
- />
272
- </List>
273
- ),
274
- };