@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.
Files changed (250) hide show
  1. package/build/header/Header.js +60 -43
  2. package/build/header/Header.js.map +1 -1
  3. package/build/header/Header.mjs +57 -43
  4. package/build/header/Header.mjs.map +1 -1
  5. package/build/i18n/cs.json +2 -0
  6. package/build/i18n/cs.json.js +2 -0
  7. package/build/i18n/cs.json.js.map +1 -1
  8. package/build/i18n/cs.json.mjs +2 -0
  9. package/build/i18n/cs.json.mjs.map +1 -1
  10. package/build/i18n/es.json +2 -0
  11. package/build/i18n/es.json.js +2 -0
  12. package/build/i18n/es.json.js.map +1 -1
  13. package/build/i18n/es.json.mjs +2 -0
  14. package/build/i18n/es.json.mjs.map +1 -1
  15. package/build/i18n/th.json +2 -0
  16. package/build/i18n/th.json.js +2 -0
  17. package/build/i18n/th.json.js.map +1 -1
  18. package/build/i18n/th.json.mjs +2 -0
  19. package/build/i18n/th.json.mjs.map +1 -1
  20. package/build/index.js +3 -1
  21. package/build/index.js.map +1 -1
  22. package/build/index.mjs +2 -1
  23. package/build/index.mjs.map +1 -1
  24. package/build/inputs/SelectInput.js +1 -1
  25. package/build/inputs/SelectInput.js.map +1 -1
  26. package/build/inputs/SelectInput.mjs +1 -1
  27. package/build/listItem/AdditionalInfo/ListItemAdditionalInfo.js +56 -0
  28. package/build/listItem/AdditionalInfo/ListItemAdditionalInfo.js.map +1 -0
  29. package/build/listItem/AdditionalInfo/ListItemAdditionalInfo.mjs +54 -0
  30. package/build/listItem/AdditionalInfo/ListItemAdditionalInfo.mjs.map +1 -0
  31. package/build/listItem/AvatarLayout/ListItemAvatarLayout.js +23 -0
  32. package/build/listItem/AvatarLayout/ListItemAvatarLayout.js.map +1 -0
  33. package/build/listItem/AvatarLayout/ListItemAvatarLayout.mjs +21 -0
  34. package/build/listItem/AvatarLayout/ListItemAvatarLayout.mjs.map +1 -0
  35. package/build/listItem/AvatarView/ListItemAvatarView.js +23 -0
  36. package/build/listItem/AvatarView/ListItemAvatarView.js.map +1 -0
  37. package/build/listItem/AvatarView/ListItemAvatarView.mjs +21 -0
  38. package/build/listItem/AvatarView/ListItemAvatarView.mjs.map +1 -0
  39. package/build/listItem/Button/ListItemButton.js +43 -0
  40. package/build/listItem/Button/ListItemButton.js.map +1 -0
  41. package/build/listItem/Button/ListItemButton.mjs +41 -0
  42. package/build/listItem/Button/ListItemButton.mjs.map +1 -0
  43. package/build/listItem/Checkbox/ListItemCheckbox.js +30 -0
  44. package/build/listItem/Checkbox/ListItemCheckbox.js.map +1 -0
  45. package/build/listItem/Checkbox/ListItemCheckbox.mjs +28 -0
  46. package/build/listItem/Checkbox/ListItemCheckbox.mjs.map +1 -0
  47. package/build/listItem/IconButton/ListItemIconButton.js +56 -0
  48. package/build/listItem/IconButton/ListItemIconButton.js.map +1 -0
  49. package/build/listItem/IconButton/ListItemIconButton.mjs +54 -0
  50. package/build/listItem/IconButton/ListItemIconButton.mjs.map +1 -0
  51. package/build/listItem/Image/ListItemImage.js +31 -0
  52. package/build/listItem/Image/ListItemImage.js.map +1 -0
  53. package/build/listItem/Image/ListItemImage.mjs +29 -0
  54. package/build/listItem/Image/ListItemImage.mjs.map +1 -0
  55. package/build/listItem/ListItem.js +311 -0
  56. package/build/listItem/ListItem.js.map +1 -0
  57. package/build/listItem/ListItem.mjs +306 -0
  58. package/build/listItem/ListItem.mjs.map +1 -0
  59. package/build/listItem/ListItemContext.js +8 -0
  60. package/build/listItem/ListItemContext.js.map +1 -0
  61. package/build/listItem/ListItemContext.mjs +6 -0
  62. package/build/listItem/ListItemContext.mjs.map +1 -0
  63. package/build/listItem/Navigation/ListItemNavigation.js +44 -0
  64. package/build/listItem/Navigation/ListItemNavigation.js.map +1 -0
  65. package/build/listItem/Navigation/ListItemNavigation.mjs +42 -0
  66. package/build/listItem/Navigation/ListItemNavigation.mjs.map +1 -0
  67. package/build/listItem/Prompt/ListItemPrompt.js +59 -0
  68. package/build/listItem/Prompt/ListItemPrompt.js.map +1 -0
  69. package/build/listItem/Prompt/ListItemPrompt.mjs +54 -0
  70. package/build/listItem/Prompt/ListItemPrompt.mjs.map +1 -0
  71. package/build/listItem/Radio/ListItemRadio.js +30 -0
  72. package/build/listItem/Radio/ListItemRadio.js.map +1 -0
  73. package/build/listItem/Radio/ListItemRadio.mjs +28 -0
  74. package/build/listItem/Radio/ListItemRadio.mjs.map +1 -0
  75. package/build/listItem/Switch/ListItemSwitch.js +30 -0
  76. package/build/listItem/Switch/ListItemSwitch.js.map +1 -0
  77. package/build/listItem/Switch/ListItemSwitch.mjs +28 -0
  78. package/build/listItem/Switch/ListItemSwitch.mjs.map +1 -0
  79. package/build/listItem/useListItemControl.js +22 -0
  80. package/build/listItem/useListItemControl.js.map +1 -0
  81. package/build/listItem/useListItemControl.mjs +20 -0
  82. package/build/listItem/useListItemControl.mjs.map +1 -0
  83. package/build/listItem/useListItemMedia.js +21 -0
  84. package/build/listItem/useListItemMedia.js.map +1 -0
  85. package/build/listItem/useListItemMedia.mjs +19 -0
  86. package/build/listItem/useListItemMedia.mjs.map +1 -0
  87. package/build/main.css +794 -14
  88. package/build/styles/header/Header.css +21 -14
  89. package/build/styles/listItem/ListItem.css +773 -0
  90. package/build/styles/listItem/ListItem.grid.css +370 -0
  91. package/build/styles/listItem/Prompt/ListItemPrompt.css +157 -0
  92. package/build/styles/main.css +794 -14
  93. package/build/title/Title.js +10 -4
  94. package/build/title/Title.js.map +1 -1
  95. package/build/title/Title.mjs +6 -4
  96. package/build/title/Title.mjs.map +1 -1
  97. package/build/types/header/Header.d.ts +27 -11
  98. package/build/types/header/Header.d.ts.map +1 -1
  99. package/build/types/header/index.d.ts +1 -0
  100. package/build/types/header/index.d.ts.map +1 -1
  101. package/build/types/index.d.ts +3 -0
  102. package/build/types/index.d.ts.map +1 -1
  103. package/build/types/listItem/AdditionalInfo/ListItemAdditionalInfo.d.ts +15 -0
  104. package/build/types/listItem/AdditionalInfo/ListItemAdditionalInfo.d.ts.map +1 -0
  105. package/build/types/listItem/AdditionalInfo/index.d.ts +3 -0
  106. package/build/types/listItem/AdditionalInfo/index.d.ts.map +1 -0
  107. package/build/types/listItem/AvatarLayout/ListItemAvatarLayout.d.ts +18 -0
  108. package/build/types/listItem/AvatarLayout/ListItemAvatarLayout.d.ts.map +1 -0
  109. package/build/types/listItem/AvatarLayout/index.d.ts +3 -0
  110. package/build/types/listItem/AvatarLayout/index.d.ts.map +1 -0
  111. package/build/types/listItem/AvatarView/ListItemAvatarView.d.ts +16 -0
  112. package/build/types/listItem/AvatarView/ListItemAvatarView.d.ts.map +1 -0
  113. package/build/types/listItem/AvatarView/index.d.ts +3 -0
  114. package/build/types/listItem/AvatarView/index.d.ts.map +1 -0
  115. package/build/types/listItem/Button/ListItemButton.d.ts +20 -0
  116. package/build/types/listItem/Button/ListItemButton.d.ts.map +1 -0
  117. package/build/types/listItem/Button/index.d.ts +3 -0
  118. package/build/types/listItem/Button/index.d.ts.map +1 -0
  119. package/build/types/listItem/Checkbox/ListItemCheckbox.d.ts +14 -0
  120. package/build/types/listItem/Checkbox/ListItemCheckbox.d.ts.map +1 -0
  121. package/build/types/listItem/Checkbox/index.d.ts +3 -0
  122. package/build/types/listItem/Checkbox/index.d.ts.map +1 -0
  123. package/build/types/listItem/IconButton/ListItemIconButton.d.ts +18 -0
  124. package/build/types/listItem/IconButton/ListItemIconButton.d.ts.map +1 -0
  125. package/build/types/listItem/IconButton/index.d.ts +3 -0
  126. package/build/types/listItem/IconButton/index.d.ts.map +1 -0
  127. package/build/types/listItem/Image/ListItemImage.d.ts +25 -0
  128. package/build/types/listItem/Image/ListItemImage.d.ts.map +1 -0
  129. package/build/types/listItem/Image/index.d.ts +3 -0
  130. package/build/types/listItem/Image/index.d.ts.map +1 -0
  131. package/build/types/listItem/ListItem.d.ts +111 -0
  132. package/build/types/listItem/ListItem.d.ts.map +1 -0
  133. package/build/types/listItem/ListItemContext.d.ts +21 -0
  134. package/build/types/listItem/ListItemContext.d.ts.map +1 -0
  135. package/build/types/listItem/Navigation/ListItemNavigation.d.ts +15 -0
  136. package/build/types/listItem/Navigation/ListItemNavigation.d.ts.map +1 -0
  137. package/build/types/listItem/Navigation/index.d.ts +3 -0
  138. package/build/types/listItem/Navigation/index.d.ts.map +1 -0
  139. package/build/types/listItem/Prompt/ListItemPrompt.d.ts +16 -0
  140. package/build/types/listItem/Prompt/ListItemPrompt.d.ts.map +1 -0
  141. package/build/types/listItem/Prompt/index.d.ts +3 -0
  142. package/build/types/listItem/Prompt/index.d.ts.map +1 -0
  143. package/build/types/listItem/Radio/ListItemRadio.d.ts +14 -0
  144. package/build/types/listItem/Radio/ListItemRadio.d.ts.map +1 -0
  145. package/build/types/listItem/Radio/index.d.ts +3 -0
  146. package/build/types/listItem/Radio/index.d.ts.map +1 -0
  147. package/build/types/listItem/Switch/ListItemSwitch.d.ts +14 -0
  148. package/build/types/listItem/Switch/ListItemSwitch.d.ts.map +1 -0
  149. package/build/types/listItem/Switch/index.d.ts +3 -0
  150. package/build/types/listItem/Switch/index.d.ts.map +1 -0
  151. package/build/types/listItem/_stories/helpers.d.ts +27 -0
  152. package/build/types/listItem/_stories/helpers.d.ts.map +1 -0
  153. package/build/types/listItem/_stories/subcomponents.d.ts +18 -0
  154. package/build/types/listItem/_stories/subcomponents.d.ts.map +1 -0
  155. package/build/types/listItem/index.d.ts +14 -0
  156. package/build/types/listItem/index.d.ts.map +1 -0
  157. package/build/types/listItem/test-utils.d.ts +7 -0
  158. package/build/types/listItem/test-utils.d.ts.map +1 -0
  159. package/build/types/listItem/useListItemControl.d.ts +5 -0
  160. package/build/types/listItem/useListItemControl.d.ts.map +1 -0
  161. package/build/types/listItem/useListItemMedia.d.ts +6 -0
  162. package/build/types/listItem/useListItemMedia.d.ts.map +1 -0
  163. package/build/types/title/Title.d.ts +4 -5
  164. package/build/types/title/Title.d.ts.map +1 -1
  165. package/package.json +3 -3
  166. package/src/button/Button.spec.tsx +25 -1
  167. package/src/button/Button.story.tsx +1 -0
  168. package/src/header/Header.accessibility.docs.mdx +85 -0
  169. package/src/header/Header.css +21 -14
  170. package/src/header/Header.less +17 -10
  171. package/src/header/Header.spec.tsx +68 -50
  172. package/src/header/Header.story.tsx +190 -36
  173. package/src/header/Header.tsx +96 -65
  174. package/src/header/index.ts +1 -0
  175. package/src/i18n/cs.json +2 -0
  176. package/src/i18n/es.json +2 -0
  177. package/src/i18n/th.json +2 -0
  178. package/src/iconButton/iconButton.spec.tsx +31 -0
  179. package/src/index.ts +16 -0
  180. package/src/legacylistItem/LegacyListItem.story.tsx +1 -1
  181. package/src/legacylistItem/LegacyListItem.tests.story.tsx +2 -1
  182. package/src/list/List.story.tsx +13 -3
  183. package/src/listItem/AdditionalInfo/ListItemAdditionalInfo.spec.tsx +56 -0
  184. package/src/listItem/AdditionalInfo/ListItemAdditionalInfo.story.tsx +198 -0
  185. package/src/listItem/AdditionalInfo/ListItemAdditionalInfo.tsx +36 -0
  186. package/src/listItem/AdditionalInfo/index.ts +2 -0
  187. package/src/listItem/AvatarLayout/ListItemAvatarLayout.spec.tsx +59 -0
  188. package/src/listItem/AvatarLayout/ListItemAvatarLayout.story.tsx +124 -0
  189. package/src/listItem/AvatarLayout/ListItemAvatarLayout.tsx +27 -0
  190. package/src/listItem/AvatarLayout/index.ts +2 -0
  191. package/src/listItem/AvatarView/ListItemAvatarView.spec.tsx +75 -0
  192. package/src/listItem/AvatarView/ListItemAvatarView.story.tsx +339 -0
  193. package/src/listItem/AvatarView/ListItemAvatarView.tsx +27 -0
  194. package/src/listItem/AvatarView/index.ts +2 -0
  195. package/src/listItem/Button/ListItemButton.spec.tsx +90 -0
  196. package/src/listItem/Button/ListItemButton.story.tsx +473 -0
  197. package/src/listItem/Button/ListItemButton.tsx +56 -0
  198. package/src/listItem/Button/index.ts +2 -0
  199. package/src/listItem/Checkbox/ListItemCheckbox.spec.tsx +82 -0
  200. package/src/listItem/Checkbox/ListItemCheckbox.story.tsx +128 -0
  201. package/src/listItem/Checkbox/ListItemCheckbox.tsx +33 -0
  202. package/src/listItem/Checkbox/index.ts +2 -0
  203. package/src/listItem/IconButton/ListItemIconButton.spec.tsx +131 -0
  204. package/src/listItem/IconButton/ListItemIconButton.story.tsx +284 -0
  205. package/src/listItem/IconButton/ListItemIconButton.tsx +73 -0
  206. package/src/listItem/IconButton/index.ts +2 -0
  207. package/src/listItem/Image/ListItemImage.spec.tsx +30 -0
  208. package/src/listItem/Image/ListItemImage.story.tsx +80 -0
  209. package/src/listItem/Image/ListItemImage.tsx +46 -0
  210. package/src/listItem/Image/index.ts +2 -0
  211. package/src/listItem/ListItem.css +773 -0
  212. package/src/listItem/ListItem.grid.css +370 -0
  213. package/src/listItem/ListItem.grid.less +622 -0
  214. package/src/listItem/ListItem.less +291 -0
  215. package/src/listItem/ListItem.spec.tsx +1511 -0
  216. package/src/listItem/ListItem.tsx +440 -0
  217. package/src/listItem/ListItemContext.tsx +26 -0
  218. package/src/listItem/Navigation/ListItemNavigation.spec.tsx +67 -0
  219. package/src/listItem/Navigation/ListItemNavigation.story.tsx +114 -0
  220. package/src/listItem/Navigation/ListItemNavigation.tsx +39 -0
  221. package/src/listItem/Navigation/index.ts +2 -0
  222. package/src/listItem/Prompt/ListItemPrompt.css +157 -0
  223. package/src/listItem/Prompt/ListItemPrompt.less +134 -0
  224. package/src/listItem/Prompt/ListItemPrompt.spec.tsx +36 -0
  225. package/src/listItem/Prompt/ListItemPrompt.story.tsx +204 -0
  226. package/src/listItem/Prompt/ListItemPrompt.tsx +32 -0
  227. package/src/listItem/Prompt/index.ts +2 -0
  228. package/src/listItem/Radio/ListItemRadio.spec.tsx +66 -0
  229. package/src/listItem/Radio/ListItemRadio.story.tsx +111 -0
  230. package/src/listItem/Radio/ListItemRadio.tsx +33 -0
  231. package/src/listItem/Radio/index.ts +2 -0
  232. package/src/listItem/Switch/ListItemSwitch.spec.tsx +47 -0
  233. package/src/listItem/Switch/ListItemSwitch.story.tsx +79 -0
  234. package/src/listItem/Switch/ListItemSwitch.tsx +33 -0
  235. package/src/listItem/Switch/index.ts +2 -0
  236. package/src/listItem/_stories/ListItem.focus.test.story.tsx +265 -0
  237. package/src/listItem/_stories/ListItem.layout.test.story.tsx +374 -0
  238. package/src/listItem/_stories/ListItem.scenarios.story.tsx +228 -0
  239. package/src/listItem/_stories/ListItem.story.tsx +774 -0
  240. package/src/listItem/_stories/ListItem.variants.test.story.tsx +274 -0
  241. package/src/listItem/_stories/helpers.tsx +53 -0
  242. package/src/listItem/_stories/subcomponents.tsx +141 -0
  243. package/src/listItem/index.ts +14 -0
  244. package/src/listItem/test-utils.tsx +33 -0
  245. package/src/listItem/useListItemControl.tsx +18 -0
  246. package/src/listItem/useListItemMedia.tsx +16 -0
  247. package/src/main.css +794 -14
  248. package/src/main.less +1 -0
  249. package/src/primitives/PrimitiveAnchor/test/PrimitiveAnchor.spec.tsx +15 -4
  250. package/src/title/Title.tsx +25 -12
@@ -0,0 +1,774 @@
1
+ import { useState } from 'react';
2
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
3
+ import { MultiCurrency, Plus } from '@transferwise/icons';
4
+ import { lorem5, lorem10 } from '../../test-utils';
5
+ import Emphasis from '../../emphasis';
6
+ import List from '../../list';
7
+ import { ListItem, type ListItemProps } from '../ListItem';
8
+ import {
9
+ SB_LIST_ITEM_CONTROLS as CONTROLS,
10
+ SB_LIST_ITEM_ADDITIONAL_INFO as ADDITIONAL_INFO,
11
+ SB_LIST_ITEM_PROMPTS as PROMPTS,
12
+ SB_LIST_ITEM_MEDIA as MEDIA,
13
+ } from './subcomponents';
14
+ import { disableControls, storySourceWithoutNoise, withoutKey } from './helpers';
15
+ import Link from '../../link';
16
+
17
+ const hideControls = disableControls([
18
+ 'additionalInfo',
19
+ 'control',
20
+ 'prompt',
21
+ 'media',
22
+ 'className',
23
+ 'id',
24
+ 'as',
25
+ ]);
26
+
27
+ /**
28
+ * List Items let users review or select options from a dynamic list.<br />
29
+ * For more details please refer to the [release notes](https://transferwise.atlassian.net/wiki/spaces/DS/pages/3647251055/List+Item+release+notes) and the [design spec](https://wise.design/components/list-item). <br />
30
+ *
31
+ * > This component replaces now deprecated `LegacyListItem`, `Summary` and all `*Option` components
32
+ */
33
+ export default {
34
+ component: ListItem,
35
+ subcomponents: {
36
+ 'ListItem.AdditionalInfo': ListItem.AdditionalInfo,
37
+ 'ListItem.Prompt': ListItem.Prompt,
38
+ 'ListItem.Button': ListItem.Button,
39
+ 'ListItem.IconButton': ListItem.IconButton,
40
+ 'ListItem.Navigation': ListItem.Navigation,
41
+ 'ListItem.Checkbox': ListItem.Checkbox,
42
+ 'ListItem.Radio': ListItem.Radio,
43
+ 'ListItem.Switch': ListItem.Switch,
44
+ 'ListItem.AvatarView': ListItem.AvatarView,
45
+ 'ListItem.AvatarLayout': ListItem.AvatarLayout,
46
+ 'ListItem.Image': ListItem.Image,
47
+ },
48
+ title: 'Content/ListItem',
49
+ tags: ['early-access'],
50
+ parameters: {
51
+ docs: {
52
+ toc: true,
53
+ },
54
+ },
55
+ args: {
56
+ title: 'List item title',
57
+ subtitle: 'Subtitle goes here',
58
+ valueTitle: '100 GBP',
59
+ valueSubtitle: '100 USD',
60
+ disabled: false,
61
+ spotlight: undefined,
62
+ inverted: false,
63
+ valueColumnWidth: undefined,
64
+ },
65
+ argTypes: {
66
+ spotlight: {
67
+ control: 'radio',
68
+ options: ['unset (undefined)', 'active', 'inactive'],
69
+ mapping: {
70
+ 'unset (undefined)': undefined,
71
+ active: 'active',
72
+ inactive: 'inactive',
73
+ },
74
+ },
75
+ },
76
+ } satisfies Meta<ListItemProps>;
77
+
78
+ type Story = StoryObj<ListItemProps>;
79
+
80
+ /**
81
+ * Convenience controls for previewing rich markup,
82
+ * not otherwise possible via Storybook
83
+ */
84
+ type PreviewStoryArgs = ListItemProps & {
85
+ previewInteractivity: 'non-interactive' | 'fully-interactive' | 'partially-interactive';
86
+ previewControlFull: ListItemProps['control'];
87
+ previewControlPartial: ListItemProps['control'];
88
+ previewAdditionalInfoFull: ListItemProps['additionalInfo'];
89
+ previewAdditionalInfoPartial: ListItemProps['additionalInfo'];
90
+ previewPrompt: ListItemProps['prompt'];
91
+ previewMedia: ListItemProps['media'];
92
+ };
93
+
94
+ const previewArgGroup = {
95
+ category: 'Preview options',
96
+ type: {
97
+ summary: undefined,
98
+ },
99
+ };
100
+
101
+ const previewArgTypes = {
102
+ previewInteractivity: {
103
+ name: 'Preview different interactivity',
104
+ control: 'radio',
105
+ options: ['non-interactive', 'fully-interactive', 'partially-interactive'],
106
+ table: previewArgGroup,
107
+ },
108
+
109
+ previewControlFull: {
110
+ name: 'Preview with `control`',
111
+ if: {
112
+ arg: 'previewInteractivity',
113
+ eq: 'fully-interactive',
114
+ },
115
+ control: 'select',
116
+ options: [
117
+ 'unset (undefined)',
118
+ 'Button',
119
+ 'Button as anchor',
120
+ 'IconButton',
121
+ 'IconButton as anchor',
122
+ 'Navigation',
123
+ 'Navigation as button',
124
+ 'Checkbox',
125
+ 'Radio',
126
+ 'Switch',
127
+ ],
128
+ mapping: {
129
+ 'unset (undefined)': undefined,
130
+ Button: CONTROLS.button,
131
+ 'Button as anchor': CONTROLS.buttonAsLink,
132
+ IconButton: CONTROLS.iconButton,
133
+ 'IconButton as anchor': CONTROLS.iconButtonAsLink,
134
+ Navigation: CONTROLS.navigation,
135
+ 'Navigation as button': CONTROLS.navigationAsButton,
136
+ Checkbox: CONTROLS.checkbox,
137
+ Radio: CONTROLS.radio,
138
+ Switch: CONTROLS.switch,
139
+ },
140
+ table: previewArgGroup,
141
+ },
142
+
143
+ previewControlPartial: {
144
+ name: 'Preview with `control`',
145
+ if: {
146
+ arg: 'previewInteractivity',
147
+ eq: 'partially-interactive',
148
+ },
149
+ control: 'select',
150
+ options: [
151
+ 'unset (undefined)',
152
+ 'Button',
153
+ 'Button as anchor',
154
+ 'IconButton',
155
+ 'IconButton as anchor',
156
+ ],
157
+ mapping: {
158
+ 'unset (undefined)': undefined,
159
+ Button: CONTROLS.partialButton,
160
+ 'Button as anchor': CONTROLS.partialButtonAsLink,
161
+ IconButton: CONTROLS.partialIconButton,
162
+ 'IconButton as anchor': CONTROLS.partialIconButtonAsLink,
163
+ },
164
+ table: previewArgGroup,
165
+ },
166
+
167
+ previewAdditionalInfoFull: {
168
+ name: 'Preview with `additionalInfo`',
169
+ if: {
170
+ arg: 'previewInteractivity',
171
+ eq: 'fully-interactive',
172
+ },
173
+ control: 'radio',
174
+ options: ['unset (undefined)', 'non-interactive'],
175
+ mapping: {
176
+ 'unset (undefined)': undefined,
177
+ 'non-interactive': ADDITIONAL_INFO.nonInteractive,
178
+ },
179
+ table: previewArgGroup,
180
+ },
181
+ previewAdditionalInfoPartial: {
182
+ name: 'Preview with `additionalInfo`',
183
+ if: {
184
+ arg: 'previewInteractivity',
185
+ eq: 'partially-interactive',
186
+ },
187
+ control: 'radio',
188
+ options: ['unset (undefined)', 'interactive', 'non-interactive'],
189
+ mapping: {
190
+ 'unset (undefined)': undefined,
191
+ interactive: ADDITIONAL_INFO.interactive,
192
+ 'non-interactive': ADDITIONAL_INFO.nonInteractive,
193
+ },
194
+ table: previewArgGroup,
195
+ },
196
+
197
+ previewPrompt: {
198
+ name: 'Preview with `prompt`',
199
+ control: 'radio',
200
+ options: ['unset (undefined)', 'interactive', 'non-interactive'],
201
+ mapping: {
202
+ 'unset (undefined)': undefined,
203
+ interactive: PROMPTS.interactive,
204
+ 'non-interactive': PROMPTS.nonInteractive,
205
+ },
206
+ table: previewArgGroup,
207
+ },
208
+
209
+ previewMedia: {
210
+ name: 'Preview with `media`',
211
+ control: 'select',
212
+ options: [
213
+ 'unset (undefined)',
214
+ 'image',
215
+ 'avatar: single',
216
+ 'avatar: double',
217
+ 'avatar: double-diagonal',
218
+ ],
219
+ mapping: {
220
+ 'unset (undefined)': undefined,
221
+ image: MEDIA.image,
222
+ 'avatar: single': MEDIA.avatarSingle,
223
+ 'avatar: double': MEDIA.avatarDouble,
224
+ 'avatar: double-diagonal': MEDIA.avatarDiagonal,
225
+ },
226
+ table: previewArgGroup,
227
+ },
228
+ } as const;
229
+
230
+ const getPropsForPreview = (args: PreviewStoryArgs): [ListItemProps, Partial<ListItemProps>] => {
231
+ const {
232
+ previewInteractivity,
233
+ previewControlFull,
234
+ previewControlPartial,
235
+ previewAdditionalInfoFull,
236
+ previewAdditionalInfoPartial,
237
+ previewPrompt,
238
+ previewMedia,
239
+ ...props
240
+ } = args;
241
+
242
+ return [
243
+ props,
244
+ {
245
+ control: previewControlFull || previewControlPartial,
246
+ additionalInfo: previewAdditionalInfoFull || previewAdditionalInfoPartial,
247
+ prompt: previewPrompt,
248
+ media: previewMedia,
249
+ },
250
+ ];
251
+ };
252
+
253
+ export const Playground: StoryObj<PreviewStoryArgs> = {
254
+ tags: ['!autodocs'],
255
+ render: (args: PreviewStoryArgs) => {
256
+ const [props, previewProps] = getPropsForPreview(args);
257
+
258
+ return (
259
+ <List>
260
+ <ListItem {...props} {...previewProps} />
261
+ </List>
262
+ );
263
+ },
264
+ argTypes: previewArgTypes,
265
+ args: {
266
+ previewInteractivity: 'fully-interactive',
267
+ previewPrompt: 'interactive',
268
+ previewMedia: 'avatar: single',
269
+ previewControlFull: 'Button',
270
+ previewControlPartial: 'Button',
271
+ previewAdditionalInfoFull: 'non-interactive',
272
+ previewAdditionalInfoPartial: 'non-interactive',
273
+ },
274
+ decorators: [withoutKey],
275
+ };
276
+
277
+ /**
278
+ * ListItem uses container queries under the hood, which means its layout self-adjusts based on
279
+ * the available space. At the 100% zoom level, these breakpoints correspond to
280
+ * containers under `290px`, those between `291px and 380px`, and finally everything including
281
+ * and above `381px`. <br />
282
+ * This also supports high levels of zoom for assistive tech users.
283
+ */
284
+ export const Responsiveness: StoryObj<PreviewStoryArgs> = {
285
+ parameters: {
286
+ docs: {
287
+ canvas: {
288
+ sourceState: 'hidden',
289
+ },
290
+ },
291
+ },
292
+ argTypes: {
293
+ ...hideControls(),
294
+ ...previewArgTypes,
295
+ },
296
+ args: {
297
+ subtitle: lorem10,
298
+ previewInteractivity: 'fully-interactive',
299
+ previewPrompt: 'interactive',
300
+ previewMedia: 'image',
301
+ previewControlFull: 'Button',
302
+ previewControlPartial: 'Button',
303
+ previewAdditionalInfoFull: 'non-interactive',
304
+ previewAdditionalInfoPartial: 'non-interactive',
305
+ },
306
+ decorators: [withoutKey],
307
+ render: (args) => {
308
+ const [props, previewProps] = getPropsForPreview(args);
309
+
310
+ return (
311
+ <List
312
+ as="ol"
313
+ className="list-unstyled"
314
+ style={{ display: 'grid', gridTemplateColumns: '290px 350px 381px', gap: 16 }}
315
+ >
316
+ <ListItem {...props} {...previewProps} />
317
+ <ListItem {...props} {...previewProps} />
318
+ <ListItem {...props} {...previewProps} />
319
+ </List>
320
+ );
321
+ },
322
+ };
323
+
324
+ /**
325
+ * Due to platform limitations, the component is unable to automagically adjust its content to
326
+ * all possible configurations. <br />
327
+ * By default, it'll follow a CSS grid `1fr max-content` ratio of left side content (`title` and
328
+ * `subtitle`) to the right side content (`valueTitle` and `valueSubtitle`).
329
+ *
330
+ * To adjust the width of the right side content, you can use `valueColumnWidth` prop which accepts
331
+ * a number between `0–100` which resolves to a `fr` value of a `grid-template-columns` declaration.
332
+ * E.g. `valueColumnWidth={25}` will result in a `75fr 25fr`.
333
+ *
334
+ * **NB:** This behaviour is slightly different on mobile platforms as they have more control over
335
+ * layout calculations.
336
+ */
337
+ export const ContentRatio: StoryObj<PreviewStoryArgs> = {
338
+ parameters: {
339
+ docs: {
340
+ canvas: {
341
+ sourceState: 'hidden',
342
+ },
343
+ },
344
+ },
345
+ args: {
346
+ valueColumnWidth: 70,
347
+ subtitle: lorem5,
348
+ valueTitle: `${lorem5} ${lorem5}`,
349
+ valueSubtitle: lorem5,
350
+ previewInteractivity: 'fully-interactive',
351
+ previewPrompt: 'interactive',
352
+ previewMedia: 'image',
353
+ previewControlFull: 'Button',
354
+ previewControlPartial: 'Button',
355
+ previewAdditionalInfoFull: 'non-interactive',
356
+ previewAdditionalInfoPartial: 'non-interactive',
357
+ as: 'div',
358
+ },
359
+ argTypes: {
360
+ ...hideControls(['disabled', 'spotlight']),
361
+ ...previewArgTypes,
362
+ },
363
+ render: (args) => {
364
+ const [props, previewProps] = getPropsForPreview(args);
365
+
366
+ return <ListItem {...props} {...previewProps} />;
367
+ },
368
+ };
369
+
370
+ /**
371
+ * List item supports default and inverted title and description to allow for further flexibility
372
+ * in the component. No other content elements are affected by this prop.
373
+ *
374
+ * Refer to the [design documentation](https://wise.design/components/list-item#content-hierarchy) for more details.
375
+ */
376
+ export const ContentHierarchy: StoryObj<PreviewStoryArgs> = {
377
+ args: {
378
+ inverted: true,
379
+ previewInteractivity: 'fully-interactive',
380
+ previewPrompt: 'interactive',
381
+ previewMedia: 'image',
382
+ previewControlFull: 'Button',
383
+ previewControlPartial: 'Button',
384
+ previewAdditionalInfoFull: 'non-interactive',
385
+ previewAdditionalInfoPartial: 'non-interactive',
386
+ as: 'div',
387
+ },
388
+ argTypes: {
389
+ ...hideControls(['valueColumnWidth', 'disabled']),
390
+ ...previewArgTypes,
391
+ },
392
+ render: (args) => {
393
+ const [props, previewProps] = getPropsForPreview(args);
394
+
395
+ return <ListItem {...props} {...previewProps} />;
396
+ },
397
+ };
398
+
399
+ /**
400
+ * Interactive list items can alternatively be displayed with a spotlight.
401
+ *
402
+ * Refer to the [design documentation](https://wise.design/components/list-item#spotlight) for more details.
403
+ */
404
+ export const Spotlight: StoryObj<PreviewStoryArgs> = {
405
+ argTypes: {
406
+ ...hideControls(['spotlight', 'valueColumnWidth']),
407
+ ...previewArgTypes,
408
+ },
409
+ args: {
410
+ subtitle: lorem10,
411
+ previewInteractivity: 'fully-interactive',
412
+ previewPrompt: 'interactive',
413
+ previewMedia: 'image',
414
+ previewControlFull: 'Button',
415
+ previewControlPartial: 'Button',
416
+ previewAdditionalInfoFull: 'non-interactive',
417
+ previewAdditionalInfoPartial: 'non-interactive',
418
+ },
419
+ decorators: [withoutKey],
420
+ render: (args) => {
421
+ const [props, previewProps] = getPropsForPreview(args);
422
+
423
+ return (
424
+ <List>
425
+ <ListItem {...props} {...previewProps} spotlight="inactive" />
426
+ <ListItem {...props} {...previewProps} spotlight="active" />
427
+ </List>
428
+ );
429
+ },
430
+ };
431
+
432
+ /**
433
+ * By default, all list items are fully interactive, meaning that their whole surface triggers the
434
+ * main action. The only 2 exceptions are those using `ListItem.Button` and `ListItem.IconButton`
435
+ * as their controls, which can be made partially interactive by toggling `partiallyInteractive`
436
+ * prop directly on them.
437
+ *
438
+ * Fully interactive list items **cannot contain any other interactive elements**, such as links or
439
+ * buttons, inside them, with the only exception being the `ListItem.Prompt` subcomponent, as it's
440
+ * rendered on a separate Accessibility Tree branch. <br/>
441
+ * Partially interactive items can also have interactive `ListItem.AdditionalInfo` which allows
442
+ * for a single, appended link or inline button.
443
+ *
444
+ * All of these limitations were put in place to ensure that the list item is compliant with
445
+ * accessibility guidance and offers consistent experience across all engineering platforms.
446
+ *
447
+ * Please refer to the [design documentation](https://wise.design/components/list-item#interaction) for more details.
448
+ */
449
+ export const Interactivity: StoryObj<PreviewStoryArgs> = storySourceWithoutNoise({
450
+ argTypes: {
451
+ ...hideControls([
452
+ 'title',
453
+ 'subtitle',
454
+ 'valueTitle',
455
+ 'valueSubtitle',
456
+ 'valueColumnWidth',
457
+ 'inverted',
458
+ ]),
459
+ },
460
+ args: {
461
+ subtitle: lorem10,
462
+ },
463
+ decorators: [withoutKey],
464
+ render: function Render(args) {
465
+ const [clicked, setClicked] = useState(0);
466
+
467
+ const renderPrompt = () => (
468
+ <ListItem.Prompt sentiment="positive">
469
+ Finally, there is a prompt{' '}
470
+ <Link href="https://wise.com" target="_blank" rel="noreferrer">
471
+ referencing some details
472
+ </Link>{' '}
473
+ for your convenience.
474
+ </ListItem.Prompt>
475
+ );
476
+
477
+ const renderInteractiveInfo = () => (
478
+ <ListItem.AdditionalInfo
479
+ action={{
480
+ label: 'Details about the subject.',
481
+ href: 'https://wise.com',
482
+ target: '_blank',
483
+ }}
484
+ >
485
+ Which is augmented with additional info.
486
+ </ListItem.AdditionalInfo>
487
+ );
488
+
489
+ const renderStaticInfo = () => (
490
+ <ListItem.AdditionalInfo>Which is augmented with additional info.</ListItem.AdditionalInfo>
491
+ );
492
+
493
+ return (
494
+ <>
495
+ <output>Count: {clicked}</output>
496
+ <List>
497
+ <ListItem
498
+ {...args}
499
+ title="Fully interactive"
500
+ control={
501
+ <ListItem.Button
502
+ priority="secondary-neutral"
503
+ onClick={() => setClicked((current) => current + 1)}
504
+ >
505
+ as Button
506
+ </ListItem.Button>
507
+ }
508
+ additionalInfo={renderStaticInfo()}
509
+ prompt={renderPrompt()}
510
+ />
511
+ <ListItem
512
+ {...args}
513
+ title="Partially interactive"
514
+ control={
515
+ <ListItem.Button
516
+ priority="secondary-neutral"
517
+ partiallyInteractive
518
+ onClick={() => setClicked((current) => current + 1)}
519
+ >
520
+ as Button
521
+ </ListItem.Button>
522
+ }
523
+ additionalInfo={renderInteractiveInfo()}
524
+ prompt={renderPrompt()}
525
+ />
526
+ <ListItem
527
+ {...args}
528
+ title="Fully interactive"
529
+ control={
530
+ <ListItem.IconButton
531
+ aria-label="Add something to me"
532
+ onClick={() => setClicked((current) => current + 1)}
533
+ >
534
+ <Plus />
535
+ </ListItem.IconButton>
536
+ }
537
+ additionalInfo={renderStaticInfo()}
538
+ prompt={renderPrompt()}
539
+ />
540
+ <ListItem
541
+ {...args}
542
+ title="Partially interactive"
543
+ control={
544
+ <ListItem.IconButton
545
+ aria-label="Add something to me"
546
+ partiallyInteractive
547
+ onClick={() => setClicked((current) => current + 1)}
548
+ >
549
+ <Plus />
550
+ </ListItem.IconButton>
551
+ }
552
+ additionalInfo={renderInteractiveInfo()}
553
+ prompt={renderPrompt()}
554
+ />
555
+ </List>
556
+ </>
557
+ );
558
+ },
559
+ });
560
+
561
+ /**
562
+ * While most disabled states will show as grayed out, the navigation control switches from chevron
563
+ * to a new icon for improved user experience and accessibility. <br />
564
+ * For the same reason, only the control part of the List Item is dimmed, while all the content
565
+ * retains high contrast and interactivity.
566
+ *
567
+ * Please refer to the [design documentation](https://wise.design/components/list-item#accessibility:~:text=-,Disabled%20states,-) for more details
568
+ */
569
+ export const Disabled: Story = {
570
+ parameters: {
571
+ docs: {
572
+ canvas: {
573
+ sourceState: 'hidden',
574
+ },
575
+ },
576
+ controls: { disable: true },
577
+ knobs: { disable: true },
578
+ },
579
+ render: (args) => (
580
+ <List>
581
+ <ListItem
582
+ disabled
583
+ media={
584
+ <ListItem.AvatarView>
585
+ <MultiCurrency />
586
+ </ListItem.AvatarView>
587
+ }
588
+ title="Navigation"
589
+ subtitle={lorem5}
590
+ control={<ListItem.Navigation onClick={() => {}} />}
591
+ />
592
+ <ListItem
593
+ disabled
594
+ media={
595
+ <ListItem.AvatarView>
596
+ <MultiCurrency />
597
+ </ListItem.AvatarView>
598
+ }
599
+ title="Button secondary neutral"
600
+ subtitle={lorem5}
601
+ control={<ListItem.Button priority="secondary-neutral">Secondary Neutral</ListItem.Button>}
602
+ />
603
+ <ListItem
604
+ disabled
605
+ media={
606
+ <ListItem.AvatarView>
607
+ <MultiCurrency />
608
+ </ListItem.AvatarView>
609
+ }
610
+ title="Button primary"
611
+ subtitle={lorem5}
612
+ control={<ListItem.Button priority="primary">Primary</ListItem.Button>}
613
+ />
614
+ <ListItem
615
+ disabled
616
+ media={
617
+ <ListItem.AvatarView>
618
+ <MultiCurrency />
619
+ </ListItem.AvatarView>
620
+ }
621
+ title="Button tertiary"
622
+ subtitle={lorem5}
623
+ control={<ListItem.Button priority="tertiary">Tertiary</ListItem.Button>}
624
+ />
625
+ <ListItem
626
+ disabled
627
+ media={
628
+ <ListItem.AvatarView>
629
+ <MultiCurrency />
630
+ </ListItem.AvatarView>
631
+ }
632
+ title="Icon Button"
633
+ subtitle={lorem5}
634
+ control={
635
+ <ListItem.IconButton>
636
+ <Plus />
637
+ </ListItem.IconButton>
638
+ }
639
+ />
640
+ <ListItem
641
+ disabled
642
+ media={
643
+ <ListItem.AvatarView>
644
+ <MultiCurrency />
645
+ </ListItem.AvatarView>
646
+ }
647
+ title="Checkbox"
648
+ subtitle={lorem5}
649
+ control={<ListItem.Checkbox />}
650
+ />
651
+ <ListItem
652
+ disabled
653
+ media={
654
+ <ListItem.AvatarView>
655
+ <MultiCurrency />
656
+ </ListItem.AvatarView>
657
+ }
658
+ title="Checkbox checked"
659
+ subtitle={lorem5}
660
+ control={<ListItem.Checkbox checked />}
661
+ />
662
+ <ListItem
663
+ disabled
664
+ media={
665
+ <ListItem.AvatarView>
666
+ <MultiCurrency />
667
+ </ListItem.AvatarView>
668
+ }
669
+ title="Checkbox indeterminate"
670
+ subtitle={lorem5}
671
+ control={<ListItem.Checkbox indeterminate />}
672
+ />
673
+ <ListItem
674
+ disabled
675
+ media={
676
+ <ListItem.AvatarView>
677
+ <MultiCurrency />
678
+ </ListItem.AvatarView>
679
+ }
680
+ title="Switch on"
681
+ subtitle={lorem5}
682
+ control={<ListItem.Switch checked onClick={() => {}} />}
683
+ />
684
+ <ListItem
685
+ disabled
686
+ media={
687
+ <ListItem.AvatarView>
688
+ <MultiCurrency />
689
+ </ListItem.AvatarView>
690
+ }
691
+ title="Switch off"
692
+ subtitle={lorem5}
693
+ control={<ListItem.Switch onClick={() => {}} />}
694
+ />
695
+ <ListItem
696
+ disabled
697
+ media={
698
+ <ListItem.AvatarView>
699
+ <MultiCurrency />
700
+ </ListItem.AvatarView>
701
+ }
702
+ title="Switch off"
703
+ subtitle={lorem5}
704
+ control={<ListItem.Radio name="radio" checked />}
705
+ />
706
+ <ListItem
707
+ disabled
708
+ media={
709
+ <ListItem.AvatarView>
710
+ <MultiCurrency />
711
+ </ListItem.AvatarView>
712
+ }
713
+ title="Switch off"
714
+ subtitle={lorem5}
715
+ control={<ListItem.Radio name="radios" />}
716
+ />
717
+ <ListItem
718
+ disabled
719
+ media={
720
+ <ListItem.AvatarView>
721
+ <MultiCurrency />
722
+ </ListItem.AvatarView>
723
+ }
724
+ title="Switch off"
725
+ subtitle={lorem5}
726
+ additionalInfo={ADDITIONAL_INFO.interactive}
727
+ prompt={PROMPTS.interactive}
728
+ control={
729
+ <ListItem.Button partiallyInteractive onClick={() => {}}>
730
+ Click me
731
+ </ListItem.Button>
732
+ }
733
+ />
734
+ </List>
735
+ ),
736
+ };
737
+
738
+ /**
739
+ * For backwards compatibility, all of the ListItem's content elements accept `ReactNode`.
740
+ * That said, most of them should be fed with plain text only. The exception is `valueTitle`
741
+ * and `valueSubtitle` which can be augmented with sentiment colours, strikethrough or bold
742
+ * styles. <br />
743
+ *
744
+ * Please refer to the [design documentation](https://wise.design/components/list-item#content) for more details.
745
+ */
746
+ export const StylingLabels: Story = {
747
+ argTypes: {
748
+ ...hideControls(['spotlight', 'valueColumnWidth']),
749
+ },
750
+ args: {
751
+ title: lorem5,
752
+ subtitle: lorem10,
753
+ media: MEDIA.image,
754
+ control: CONTROLS.iconButton,
755
+ prompt: PROMPTS.interactive,
756
+ },
757
+ decorators: [withoutKey],
758
+ render: function Render(args) {
759
+ return (
760
+ <List>
761
+ <ListItem
762
+ {...args}
763
+ valueTitle={<Emphasis text="<negative>100 GBP</negative>" />}
764
+ valueSubtitle={<s>125 GBP</s>}
765
+ />
766
+ <ListItem
767
+ {...args}
768
+ valueTitle={<Emphasis text="<positive>100 GBP</positive>" />}
769
+ valueSubtitle={<strong>125 GBP</strong>}
770
+ />
771
+ </List>
772
+ );
773
+ },
774
+ };