@transferwise/components 46.103.1 → 46.105.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.
- package/build/header/Header.js +60 -43
- package/build/header/Header.js.map +1 -1
- package/build/header/Header.mjs +57 -43
- package/build/header/Header.mjs.map +1 -1
- package/build/i18n/cs.json +2 -0
- package/build/i18n/cs.json.js +2 -0
- package/build/i18n/cs.json.js.map +1 -1
- package/build/i18n/cs.json.mjs +2 -0
- package/build/i18n/cs.json.mjs.map +1 -1
- package/build/i18n/es.json +2 -0
- package/build/i18n/es.json.js +2 -0
- package/build/i18n/es.json.js.map +1 -1
- package/build/i18n/es.json.mjs +2 -0
- package/build/i18n/es.json.mjs.map +1 -1
- package/build/i18n/th.json +2 -0
- package/build/i18n/th.json.js +2 -0
- package/build/i18n/th.json.js.map +1 -1
- package/build/i18n/th.json.mjs +2 -0
- package/build/i18n/th.json.mjs.map +1 -1
- package/build/index.js +3 -1
- package/build/index.js.map +1 -1
- package/build/index.mjs +2 -1
- package/build/index.mjs.map +1 -1
- package/build/inputs/SelectInput.js +1 -1
- package/build/inputs/SelectInput.js.map +1 -1
- package/build/inputs/SelectInput.mjs +1 -1
- package/build/listItem/AdditionalInfo/ListItemAdditionalInfo.js +56 -0
- package/build/listItem/AdditionalInfo/ListItemAdditionalInfo.js.map +1 -0
- package/build/listItem/AdditionalInfo/ListItemAdditionalInfo.mjs +54 -0
- package/build/listItem/AdditionalInfo/ListItemAdditionalInfo.mjs.map +1 -0
- package/build/listItem/AvatarLayout/ListItemAvatarLayout.js +23 -0
- package/build/listItem/AvatarLayout/ListItemAvatarLayout.js.map +1 -0
- package/build/listItem/AvatarLayout/ListItemAvatarLayout.mjs +21 -0
- package/build/listItem/AvatarLayout/ListItemAvatarLayout.mjs.map +1 -0
- package/build/listItem/AvatarView/ListItemAvatarView.js +23 -0
- package/build/listItem/AvatarView/ListItemAvatarView.js.map +1 -0
- package/build/listItem/AvatarView/ListItemAvatarView.mjs +21 -0
- package/build/listItem/AvatarView/ListItemAvatarView.mjs.map +1 -0
- package/build/listItem/Button/ListItemButton.js +43 -0
- package/build/listItem/Button/ListItemButton.js.map +1 -0
- package/build/listItem/Button/ListItemButton.mjs +41 -0
- package/build/listItem/Button/ListItemButton.mjs.map +1 -0
- package/build/listItem/Checkbox/ListItemCheckbox.js +30 -0
- package/build/listItem/Checkbox/ListItemCheckbox.js.map +1 -0
- package/build/listItem/Checkbox/ListItemCheckbox.mjs +28 -0
- package/build/listItem/Checkbox/ListItemCheckbox.mjs.map +1 -0
- package/build/listItem/IconButton/ListItemIconButton.js +56 -0
- package/build/listItem/IconButton/ListItemIconButton.js.map +1 -0
- package/build/listItem/IconButton/ListItemIconButton.mjs +54 -0
- package/build/listItem/IconButton/ListItemIconButton.mjs.map +1 -0
- package/build/listItem/Image/ListItemImage.js +31 -0
- package/build/listItem/Image/ListItemImage.js.map +1 -0
- package/build/listItem/Image/ListItemImage.mjs +29 -0
- package/build/listItem/Image/ListItemImage.mjs.map +1 -0
- package/build/listItem/ListItem.js +311 -0
- package/build/listItem/ListItem.js.map +1 -0
- package/build/listItem/ListItem.mjs +306 -0
- package/build/listItem/ListItem.mjs.map +1 -0
- package/build/listItem/ListItemContext.js +8 -0
- package/build/listItem/ListItemContext.js.map +1 -0
- package/build/listItem/ListItemContext.mjs +6 -0
- package/build/listItem/ListItemContext.mjs.map +1 -0
- package/build/listItem/Navigation/ListItemNavigation.js +44 -0
- package/build/listItem/Navigation/ListItemNavigation.js.map +1 -0
- package/build/listItem/Navigation/ListItemNavigation.mjs +42 -0
- package/build/listItem/Navigation/ListItemNavigation.mjs.map +1 -0
- package/build/listItem/Prompt/ListItemPrompt.js +59 -0
- package/build/listItem/Prompt/ListItemPrompt.js.map +1 -0
- package/build/listItem/Prompt/ListItemPrompt.mjs +54 -0
- package/build/listItem/Prompt/ListItemPrompt.mjs.map +1 -0
- package/build/listItem/Radio/ListItemRadio.js +30 -0
- package/build/listItem/Radio/ListItemRadio.js.map +1 -0
- package/build/listItem/Radio/ListItemRadio.mjs +28 -0
- package/build/listItem/Radio/ListItemRadio.mjs.map +1 -0
- package/build/listItem/Switch/ListItemSwitch.js +30 -0
- package/build/listItem/Switch/ListItemSwitch.js.map +1 -0
- package/build/listItem/Switch/ListItemSwitch.mjs +28 -0
- package/build/listItem/Switch/ListItemSwitch.mjs.map +1 -0
- package/build/listItem/useListItemControl.js +22 -0
- package/build/listItem/useListItemControl.js.map +1 -0
- package/build/listItem/useListItemControl.mjs +20 -0
- package/build/listItem/useListItemControl.mjs.map +1 -0
- package/build/listItem/useListItemMedia.js +21 -0
- package/build/listItem/useListItemMedia.js.map +1 -0
- package/build/listItem/useListItemMedia.mjs +19 -0
- package/build/listItem/useListItemMedia.mjs.map +1 -0
- package/build/main.css +794 -14
- package/build/styles/header/Header.css +21 -14
- package/build/styles/listItem/ListItem.css +773 -0
- package/build/styles/listItem/ListItem.grid.css +370 -0
- package/build/styles/listItem/Prompt/ListItemPrompt.css +157 -0
- package/build/styles/main.css +794 -14
- package/build/title/Title.js +10 -4
- package/build/title/Title.js.map +1 -1
- package/build/title/Title.mjs +6 -4
- package/build/title/Title.mjs.map +1 -1
- package/build/types/header/Header.d.ts +27 -11
- package/build/types/header/Header.d.ts.map +1 -1
- package/build/types/header/index.d.ts +1 -0
- package/build/types/header/index.d.ts.map +1 -1
- package/build/types/index.d.ts +3 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/types/listItem/AdditionalInfo/ListItemAdditionalInfo.d.ts +15 -0
- package/build/types/listItem/AdditionalInfo/ListItemAdditionalInfo.d.ts.map +1 -0
- package/build/types/listItem/AdditionalInfo/index.d.ts +3 -0
- package/build/types/listItem/AdditionalInfo/index.d.ts.map +1 -0
- package/build/types/listItem/AvatarLayout/ListItemAvatarLayout.d.ts +18 -0
- package/build/types/listItem/AvatarLayout/ListItemAvatarLayout.d.ts.map +1 -0
- package/build/types/listItem/AvatarLayout/index.d.ts +3 -0
- package/build/types/listItem/AvatarLayout/index.d.ts.map +1 -0
- package/build/types/listItem/AvatarView/ListItemAvatarView.d.ts +16 -0
- package/build/types/listItem/AvatarView/ListItemAvatarView.d.ts.map +1 -0
- package/build/types/listItem/AvatarView/index.d.ts +3 -0
- package/build/types/listItem/AvatarView/index.d.ts.map +1 -0
- package/build/types/listItem/Button/ListItemButton.d.ts +20 -0
- package/build/types/listItem/Button/ListItemButton.d.ts.map +1 -0
- package/build/types/listItem/Button/index.d.ts +3 -0
- package/build/types/listItem/Button/index.d.ts.map +1 -0
- package/build/types/listItem/Checkbox/ListItemCheckbox.d.ts +14 -0
- package/build/types/listItem/Checkbox/ListItemCheckbox.d.ts.map +1 -0
- package/build/types/listItem/Checkbox/index.d.ts +3 -0
- package/build/types/listItem/Checkbox/index.d.ts.map +1 -0
- package/build/types/listItem/IconButton/ListItemIconButton.d.ts +18 -0
- package/build/types/listItem/IconButton/ListItemIconButton.d.ts.map +1 -0
- package/build/types/listItem/IconButton/index.d.ts +3 -0
- package/build/types/listItem/IconButton/index.d.ts.map +1 -0
- package/build/types/listItem/Image/ListItemImage.d.ts +25 -0
- package/build/types/listItem/Image/ListItemImage.d.ts.map +1 -0
- package/build/types/listItem/Image/index.d.ts +3 -0
- package/build/types/listItem/Image/index.d.ts.map +1 -0
- package/build/types/listItem/ListItem.d.ts +111 -0
- package/build/types/listItem/ListItem.d.ts.map +1 -0
- package/build/types/listItem/ListItemContext.d.ts +21 -0
- package/build/types/listItem/ListItemContext.d.ts.map +1 -0
- package/build/types/listItem/Navigation/ListItemNavigation.d.ts +15 -0
- package/build/types/listItem/Navigation/ListItemNavigation.d.ts.map +1 -0
- package/build/types/listItem/Navigation/index.d.ts +3 -0
- package/build/types/listItem/Navigation/index.d.ts.map +1 -0
- package/build/types/listItem/Prompt/ListItemPrompt.d.ts +16 -0
- package/build/types/listItem/Prompt/ListItemPrompt.d.ts.map +1 -0
- package/build/types/listItem/Prompt/index.d.ts +3 -0
- package/build/types/listItem/Prompt/index.d.ts.map +1 -0
- package/build/types/listItem/Radio/ListItemRadio.d.ts +14 -0
- package/build/types/listItem/Radio/ListItemRadio.d.ts.map +1 -0
- package/build/types/listItem/Radio/index.d.ts +3 -0
- package/build/types/listItem/Radio/index.d.ts.map +1 -0
- package/build/types/listItem/Switch/ListItemSwitch.d.ts +14 -0
- package/build/types/listItem/Switch/ListItemSwitch.d.ts.map +1 -0
- package/build/types/listItem/Switch/index.d.ts +3 -0
- package/build/types/listItem/Switch/index.d.ts.map +1 -0
- package/build/types/listItem/_stories/helpers.d.ts +27 -0
- package/build/types/listItem/_stories/helpers.d.ts.map +1 -0
- package/build/types/listItem/_stories/subcomponents.d.ts +18 -0
- package/build/types/listItem/_stories/subcomponents.d.ts.map +1 -0
- package/build/types/listItem/index.d.ts +14 -0
- package/build/types/listItem/index.d.ts.map +1 -0
- package/build/types/listItem/test-utils.d.ts +7 -0
- package/build/types/listItem/test-utils.d.ts.map +1 -0
- package/build/types/listItem/useListItemControl.d.ts +5 -0
- package/build/types/listItem/useListItemControl.d.ts.map +1 -0
- package/build/types/listItem/useListItemMedia.d.ts +6 -0
- package/build/types/listItem/useListItemMedia.d.ts.map +1 -0
- package/build/types/title/Title.d.ts +4 -5
- package/build/types/title/Title.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/button/Button.spec.tsx +25 -1
- package/src/button/Button.story.tsx +1 -0
- package/src/header/Header.accessibility.docs.mdx +85 -0
- package/src/header/Header.css +21 -14
- package/src/header/Header.less +17 -10
- package/src/header/Header.spec.tsx +68 -50
- package/src/header/Header.story.tsx +190 -36
- package/src/header/Header.tsx +96 -65
- package/src/header/index.ts +1 -0
- package/src/i18n/cs.json +2 -0
- package/src/i18n/es.json +2 -0
- package/src/i18n/th.json +2 -0
- package/src/iconButton/iconButton.spec.tsx +31 -0
- package/src/index.ts +16 -0
- package/src/legacylistItem/LegacyListItem.story.tsx +1 -1
- package/src/legacylistItem/LegacyListItem.tests.story.tsx +2 -1
- package/src/list/List.story.tsx +13 -3
- package/src/listItem/AdditionalInfo/ListItemAdditionalInfo.spec.tsx +56 -0
- package/src/listItem/AdditionalInfo/ListItemAdditionalInfo.story.tsx +198 -0
- package/src/listItem/AdditionalInfo/ListItemAdditionalInfo.tsx +36 -0
- package/src/listItem/AdditionalInfo/index.ts +2 -0
- package/src/listItem/AvatarLayout/ListItemAvatarLayout.spec.tsx +59 -0
- package/src/listItem/AvatarLayout/ListItemAvatarLayout.story.tsx +124 -0
- package/src/listItem/AvatarLayout/ListItemAvatarLayout.tsx +27 -0
- package/src/listItem/AvatarLayout/index.ts +2 -0
- package/src/listItem/AvatarView/ListItemAvatarView.spec.tsx +75 -0
- package/src/listItem/AvatarView/ListItemAvatarView.story.tsx +339 -0
- package/src/listItem/AvatarView/ListItemAvatarView.tsx +27 -0
- package/src/listItem/AvatarView/index.ts +2 -0
- package/src/listItem/Button/ListItemButton.spec.tsx +90 -0
- package/src/listItem/Button/ListItemButton.story.tsx +473 -0
- package/src/listItem/Button/ListItemButton.tsx +56 -0
- package/src/listItem/Button/index.ts +2 -0
- package/src/listItem/Checkbox/ListItemCheckbox.spec.tsx +82 -0
- package/src/listItem/Checkbox/ListItemCheckbox.story.tsx +128 -0
- package/src/listItem/Checkbox/ListItemCheckbox.tsx +33 -0
- package/src/listItem/Checkbox/index.ts +2 -0
- package/src/listItem/IconButton/ListItemIconButton.spec.tsx +131 -0
- package/src/listItem/IconButton/ListItemIconButton.story.tsx +284 -0
- package/src/listItem/IconButton/ListItemIconButton.tsx +73 -0
- package/src/listItem/IconButton/index.ts +2 -0
- package/src/listItem/Image/ListItemImage.spec.tsx +30 -0
- package/src/listItem/Image/ListItemImage.story.tsx +80 -0
- package/src/listItem/Image/ListItemImage.tsx +46 -0
- package/src/listItem/Image/index.ts +2 -0
- package/src/listItem/ListItem.css +773 -0
- package/src/listItem/ListItem.grid.css +370 -0
- package/src/listItem/ListItem.grid.less +622 -0
- package/src/listItem/ListItem.less +291 -0
- package/src/listItem/ListItem.spec.tsx +1511 -0
- package/src/listItem/ListItem.tsx +440 -0
- package/src/listItem/ListItemContext.tsx +26 -0
- package/src/listItem/Navigation/ListItemNavigation.spec.tsx +67 -0
- package/src/listItem/Navigation/ListItemNavigation.story.tsx +114 -0
- package/src/listItem/Navigation/ListItemNavigation.tsx +39 -0
- package/src/listItem/Navigation/index.ts +2 -0
- package/src/listItem/Prompt/ListItemPrompt.css +157 -0
- package/src/listItem/Prompt/ListItemPrompt.less +134 -0
- package/src/listItem/Prompt/ListItemPrompt.spec.tsx +36 -0
- package/src/listItem/Prompt/ListItemPrompt.story.tsx +204 -0
- package/src/listItem/Prompt/ListItemPrompt.tsx +32 -0
- package/src/listItem/Prompt/index.ts +2 -0
- package/src/listItem/Radio/ListItemRadio.spec.tsx +66 -0
- package/src/listItem/Radio/ListItemRadio.story.tsx +111 -0
- package/src/listItem/Radio/ListItemRadio.tsx +33 -0
- package/src/listItem/Radio/index.ts +2 -0
- package/src/listItem/Switch/ListItemSwitch.spec.tsx +47 -0
- package/src/listItem/Switch/ListItemSwitch.story.tsx +79 -0
- package/src/listItem/Switch/ListItemSwitch.tsx +33 -0
- package/src/listItem/Switch/index.ts +2 -0
- package/src/listItem/_stories/ListItem.focus.test.story.tsx +265 -0
- package/src/listItem/_stories/ListItem.layout.test.story.tsx +374 -0
- package/src/listItem/_stories/ListItem.scenarios.story.tsx +228 -0
- package/src/listItem/_stories/ListItem.story.tsx +774 -0
- package/src/listItem/_stories/ListItem.variants.test.story.tsx +274 -0
- package/src/listItem/_stories/helpers.tsx +53 -0
- package/src/listItem/_stories/subcomponents.tsx +141 -0
- package/src/listItem/index.ts +14 -0
- package/src/listItem/test-utils.tsx +33 -0
- package/src/listItem/useListItemControl.tsx +18 -0
- package/src/listItem/useListItemMedia.tsx +16 -0
- package/src/main.css +794 -14
- package/src/main.less +1 -0
- package/src/primitives/PrimitiveAnchor/test/PrimitiveAnchor.spec.tsx +15 -4
- package/src/title/Title.tsx +25 -12
|
@@ -0,0 +1,274 @@
|
|
|
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
|
+
};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { StoryObj, type Decorator } from '@storybook/react-webpack5';
|
|
2
|
+
import type { ListItemProps } from '../ListItem';
|
|
3
|
+
|
|
4
|
+
type Story = StoryObj<ListItemProps>;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Recent storybook versions render the full source including all story parameters which
|
|
8
|
+
* creates noise, this simple workaround only shows the render function.
|
|
9
|
+
* This is a workaround for the issue.
|
|
10
|
+
* @see https://github.com/storybookjs/storybook/issues/22281
|
|
11
|
+
*/
|
|
12
|
+
export const storySourceWithoutNoise = (config: Story): Story => {
|
|
13
|
+
const newConfig: Story = {
|
|
14
|
+
...config,
|
|
15
|
+
parameters: {
|
|
16
|
+
...config.parameters,
|
|
17
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
18
|
+
docs: {
|
|
19
|
+
...config.parameters?.docs,
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
21
|
+
source: {
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
23
|
+
...config.parameters?.docs?.source,
|
|
24
|
+
type: 'code',
|
|
25
|
+
transform: (code: string) =>
|
|
26
|
+
code
|
|
27
|
+
// eslint-disable-next-line regexp/no-super-linear-backtracking
|
|
28
|
+
.replace(/storySourceWithoutNoise\(\{.+render\s?:\s+(.*)\}\)$/gms, '$1'),
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return newConfig;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* In order to make preview controls work correctly, we have to refresh the render
|
|
39
|
+
* by swapping the `key`. This is a workaround for the Storybook's limitation.
|
|
40
|
+
*/
|
|
41
|
+
export const withoutKey: Decorator = (Story, { args }) => (
|
|
42
|
+
<Story key={args?.disabled ? 'disabled' : 'enabled'} />
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Not all stories need access to all controls as it causes unnecessary UI noise.
|
|
47
|
+
*/
|
|
48
|
+
export const disableControls =
|
|
49
|
+
(hiddenByDefault: string[] = []) =>
|
|
50
|
+
(hiddenForStory: string[] = []) => {
|
|
51
|
+
const hiddenControls = hiddenByDefault.concat(hiddenForStory);
|
|
52
|
+
return Object.fromEntries(hiddenControls.map((item) => [item, { table: { disable: true } }]));
|
|
53
|
+
};
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { Edit, Briefcase, Plane } from '@transferwise/icons';
|
|
3
|
+
import { ListItem } from '../ListItem';
|
|
4
|
+
import { fn } from 'storybook/test';
|
|
5
|
+
import Link from '../../link';
|
|
6
|
+
import { Flag } from '@wise/art';
|
|
7
|
+
|
|
8
|
+
export type SB_ListItem_ControlType =
|
|
9
|
+
| 'non-interactive'
|
|
10
|
+
| 'button'
|
|
11
|
+
| 'buttonAsLink'
|
|
12
|
+
| 'partialButton'
|
|
13
|
+
| 'partialButtonAsLink'
|
|
14
|
+
| 'iconButton'
|
|
15
|
+
| 'iconButtonAsLink'
|
|
16
|
+
| 'iconButtonWithLabel'
|
|
17
|
+
| 'iconButtonAsLinkWithLabel'
|
|
18
|
+
| 'partialIconButton'
|
|
19
|
+
| 'partialIconButtonAsLink'
|
|
20
|
+
| 'partialIconButtonWithLabel'
|
|
21
|
+
| 'partialIconButtonAsLinkWithLabel'
|
|
22
|
+
| 'navigation'
|
|
23
|
+
| 'navigationAsButton'
|
|
24
|
+
| 'checkbox'
|
|
25
|
+
| 'radio'
|
|
26
|
+
| 'switch';
|
|
27
|
+
|
|
28
|
+
export const SB_LIST_ITEM_CONTROLS: Record<SB_ListItem_ControlType, ReactNode> = {
|
|
29
|
+
'non-interactive': null,
|
|
30
|
+
button: <ListItem.Button onClick={() => {}}>Click me</ListItem.Button>,
|
|
31
|
+
buttonAsLink: <ListItem.Button href="https://wise.com">Click me</ListItem.Button>,
|
|
32
|
+
partialButton: (
|
|
33
|
+
<ListItem.Button partiallyInteractive onClick={() => {}}>
|
|
34
|
+
Click me
|
|
35
|
+
</ListItem.Button>
|
|
36
|
+
),
|
|
37
|
+
partialButtonAsLink: (
|
|
38
|
+
<ListItem.Button partiallyInteractive href="https://wise.com">
|
|
39
|
+
Click me
|
|
40
|
+
</ListItem.Button>
|
|
41
|
+
),
|
|
42
|
+
navigation: <ListItem.Navigation href="https://wise.com" />,
|
|
43
|
+
navigationAsButton: <ListItem.Navigation onClick={fn()} />,
|
|
44
|
+
checkbox: <ListItem.Checkbox onChange={() => {}} />,
|
|
45
|
+
radio: <ListItem.Radio name="radio" value={Math.random().toString()} onChange={() => {}} />,
|
|
46
|
+
switch: <ListItem.Switch onClick={() => {}} />,
|
|
47
|
+
iconButton: (
|
|
48
|
+
<ListItem.IconButton onClick={() => {}}>
|
|
49
|
+
<Edit />
|
|
50
|
+
</ListItem.IconButton>
|
|
51
|
+
),
|
|
52
|
+
iconButtonAsLink: (
|
|
53
|
+
<ListItem.IconButton href="https://wise.com">
|
|
54
|
+
<Edit />
|
|
55
|
+
</ListItem.IconButton>
|
|
56
|
+
),
|
|
57
|
+
iconButtonWithLabel: (
|
|
58
|
+
<ListItem.IconButton aria-label="Edit" onClick={() => {}}>
|
|
59
|
+
<Edit />
|
|
60
|
+
</ListItem.IconButton>
|
|
61
|
+
),
|
|
62
|
+
iconButtonAsLinkWithLabel: (
|
|
63
|
+
<ListItem.IconButton href="https://wise.com" aria-label="Edit">
|
|
64
|
+
<Edit />
|
|
65
|
+
</ListItem.IconButton>
|
|
66
|
+
),
|
|
67
|
+
partialIconButton: (
|
|
68
|
+
<ListItem.IconButton partiallyInteractive onClick={() => {}}>
|
|
69
|
+
<Edit />
|
|
70
|
+
</ListItem.IconButton>
|
|
71
|
+
),
|
|
72
|
+
partialIconButtonAsLink: (
|
|
73
|
+
<ListItem.IconButton partiallyInteractive href="https://wise.com">
|
|
74
|
+
<Edit />
|
|
75
|
+
</ListItem.IconButton>
|
|
76
|
+
),
|
|
77
|
+
partialIconButtonWithLabel: (
|
|
78
|
+
<ListItem.IconButton partiallyInteractive aria-label="Edit" onClick={() => {}}>
|
|
79
|
+
<Edit />
|
|
80
|
+
</ListItem.IconButton>
|
|
81
|
+
),
|
|
82
|
+
partialIconButtonAsLinkWithLabel: (
|
|
83
|
+
<ListItem.IconButton partiallyInteractive aria-label="Edit" href="https://wise.com">
|
|
84
|
+
<Edit />
|
|
85
|
+
</ListItem.IconButton>
|
|
86
|
+
),
|
|
87
|
+
} as const;
|
|
88
|
+
|
|
89
|
+
export const SB_LIST_ITEM_ADDITIONAL_INFO = {
|
|
90
|
+
interactive: (
|
|
91
|
+
<ListItem.AdditionalInfo
|
|
92
|
+
action={{
|
|
93
|
+
label: 'Details about the subject.',
|
|
94
|
+
href: 'https://wise.com',
|
|
95
|
+
target: '_blank',
|
|
96
|
+
}}
|
|
97
|
+
>
|
|
98
|
+
Which is augmented with additional info.
|
|
99
|
+
</ListItem.AdditionalInfo>
|
|
100
|
+
),
|
|
101
|
+
nonInteractive: (
|
|
102
|
+
<ListItem.AdditionalInfo>Which is augmented with additional info.</ListItem.AdditionalInfo>
|
|
103
|
+
),
|
|
104
|
+
} as const;
|
|
105
|
+
|
|
106
|
+
export const SB_LIST_ITEM_PROMPTS = {
|
|
107
|
+
interactive: (
|
|
108
|
+
<ListItem.Prompt sentiment="positive">
|
|
109
|
+
Finally, there is a prompt{' '}
|
|
110
|
+
<Link href="https://wise.com" target="_blank" rel="noreferrer">
|
|
111
|
+
referencing some details
|
|
112
|
+
</Link>{' '}
|
|
113
|
+
for your convenience.
|
|
114
|
+
</ListItem.Prompt>
|
|
115
|
+
),
|
|
116
|
+
nonInteractive: (
|
|
117
|
+
<ListItem.Prompt sentiment="positive">Finally, there is a prompt.</ListItem.Prompt>
|
|
118
|
+
),
|
|
119
|
+
} as const;
|
|
120
|
+
|
|
121
|
+
export const SB_LIST_ITEM_MEDIA = {
|
|
122
|
+
image: (
|
|
123
|
+
<ListItem.Image
|
|
124
|
+
alt="An illustration of a multi-currency account"
|
|
125
|
+
src="https://wise.com/public-resources/assets/spend/card-asset/medium/v2/personal_green_wise_2023_active.svg"
|
|
126
|
+
/>
|
|
127
|
+
),
|
|
128
|
+
avatarSingle: (
|
|
129
|
+
<ListItem.AvatarView>
|
|
130
|
+
<Briefcase />
|
|
131
|
+
</ListItem.AvatarView>
|
|
132
|
+
),
|
|
133
|
+
avatarDouble: <ListItem.AvatarLayout avatars={[{ asset: <Plane /> }, { asset: '7+' }]} />,
|
|
134
|
+
avatarDiagonal: (
|
|
135
|
+
<ListItem.AvatarLayout
|
|
136
|
+
size={56}
|
|
137
|
+
orientation="diagonal"
|
|
138
|
+
avatars={[{ asset: <Flag code="gb" /> }, { asset: <Flag code="pl" /> }]}
|
|
139
|
+
/>
|
|
140
|
+
),
|
|
141
|
+
} as const;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type { ListItemProps } from './ListItem';
|
|
2
|
+
export type { ListItemAdditionalInfoProps } from './AdditionalInfo';
|
|
3
|
+
export type { ListItemAvatarLayoutProps } from './AvatarLayout';
|
|
4
|
+
export type { ListItemAvatarViewProps } from './AvatarView';
|
|
5
|
+
export type { ListItemButtonProps } from './Button';
|
|
6
|
+
export type { ListItemCheckboxProps } from './Checkbox';
|
|
7
|
+
export type { ListItemIconButtonProps } from './IconButton';
|
|
8
|
+
export type { ListItemImageProps } from './Image';
|
|
9
|
+
export type { ListItemNavigationProps } from './Navigation';
|
|
10
|
+
export type { ListItemPromptProps } from './Prompt';
|
|
11
|
+
export type { ListItemRadioProps } from './Radio';
|
|
12
|
+
export type { ListItemSwitchProps } from './Switch';
|
|
13
|
+
|
|
14
|
+
export { default } from './ListItem';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { render, type RenderResult } from '../test-utils';
|
|
2
|
+
import { ListItemContext } from './ListItemContext';
|
|
3
|
+
|
|
4
|
+
export const mockSetControlType = jest.fn();
|
|
5
|
+
export const mockSetControlProps = jest.fn();
|
|
6
|
+
export const mockSetMediaSize = jest.fn();
|
|
7
|
+
|
|
8
|
+
export const renderWithListItemContext = (ui: React.ReactNode): RenderResult => {
|
|
9
|
+
return render(
|
|
10
|
+
<ListItemContext.Provider
|
|
11
|
+
value={{
|
|
12
|
+
setControlType: mockSetControlType,
|
|
13
|
+
setControlProps: mockSetControlProps,
|
|
14
|
+
setMediaSize: mockSetMediaSize,
|
|
15
|
+
ids: {
|
|
16
|
+
title: 'title',
|
|
17
|
+
additionalInfo: 'additional-info',
|
|
18
|
+
valueTitle: 'value-title',
|
|
19
|
+
control: 'control',
|
|
20
|
+
prompt: 'prompt',
|
|
21
|
+
},
|
|
22
|
+
props: { disabled: false, inverted: false },
|
|
23
|
+
describedByIds: 'described-by-ids',
|
|
24
|
+
}}
|
|
25
|
+
>
|
|
26
|
+
{ui}
|
|
27
|
+
</ListItemContext.Provider>,
|
|
28
|
+
);
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
export const clearListItemMocks = () => {
|
|
32
|
+
jest.clearAllMocks();
|
|
33
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { useContext, useEffect } from 'react';
|
|
2
|
+
import { ListItemContext, type ListItemContextData } from './ListItemContext';
|
|
3
|
+
import type { ListItemTypes, ListItemControlProps } from './ListItem';
|
|
4
|
+
|
|
5
|
+
export function useListItemControl(controlType: ListItemTypes, controlProps: ListItemControlProps) {
|
|
6
|
+
const {
|
|
7
|
+
setControlType,
|
|
8
|
+
setControlProps,
|
|
9
|
+
props: baseItemProps,
|
|
10
|
+
} = useContext<ListItemContextData>(ListItemContext);
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
setControlType(controlType);
|
|
14
|
+
setControlProps(controlProps);
|
|
15
|
+
}, [controlType, controlProps, setControlType, setControlProps]);
|
|
16
|
+
|
|
17
|
+
return { baseItemProps };
|
|
18
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useContext, useEffect } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
ListItemContext,
|
|
4
|
+
type ListItemContextData,
|
|
5
|
+
type ListItemMediaSize,
|
|
6
|
+
} from './ListItemContext';
|
|
7
|
+
|
|
8
|
+
export function useListItemMedia(size?: ListItemMediaSize) {
|
|
9
|
+
const { setMediaSize, mediaSize } = useContext<ListItemContextData>(ListItemContext);
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
setMediaSize(size);
|
|
13
|
+
}, [size, setMediaSize]);
|
|
14
|
+
|
|
15
|
+
return { mediaSize, setMediaSize };
|
|
16
|
+
}
|