@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,157 @@
1
+ .wds-list-item-prompt {
2
+ grid-area: prompt;
3
+ display: inline-flex;
4
+ justify-self: start;
5
+ text-align: left;
6
+ padding-top: calc(8px / 2);
7
+ padding-top: calc(var(--padding-x-small) / 2);
8
+ padding-bottom: calc(8px / 2);
9
+ padding-bottom: calc(var(--padding-x-small) / 2);
10
+ padding-left: calc(8px - 1px);
11
+ padding-left: calc(var(--padding-x-small) - 1px);
12
+ padding-right: 8px;
13
+ padding-right: var(--padding-x-small);
14
+ border-radius: 10px;
15
+ border-radius: var(--radius-small);
16
+ word-break: break-word;
17
+ word-wrap: break-word;
18
+ }
19
+ .wds-list-item-prompt:has(a),
20
+ .wds-list-item-prompt:has(button) {
21
+ position: relative;
22
+ z-index: 1;
23
+ }
24
+ .wds-list-item-prompt a,
25
+ .wds-list-item-prompt button {
26
+ text-underline-offset: calc(4px / 2);
27
+ text-underline-offset: calc(var(--size-4) / 2);
28
+ }
29
+ .wds-list-item-prompt a:first-of-type:before,
30
+ .wds-list-item-prompt button:first-of-type:before {
31
+ content: '';
32
+ position: absolute;
33
+ inset: 0;
34
+ }
35
+ .wds-list-item-prompt.np-prompt-icon {
36
+ padding-left: calc(8px - 1px);
37
+ padding-left: calc(var(--padding-x-small) - 1px);
38
+ padding-right: 8px;
39
+ padding-right: var(--padding-x-small);
40
+ display: inline-flex;
41
+ align-items: center;
42
+ gap: 4px;
43
+ gap: var(--size-4);
44
+ }
45
+ .wds-list-item-prompt .np-prompt-icon {
46
+ padding-right: calc(12px / 2);
47
+ padding-right: calc(var(--size-12) / 2);
48
+ padding-top: calc(4px - 1px);
49
+ padding-top: calc(var(--size-4) - 1px);
50
+ padding-bottom: calc(4px - 1px);
51
+ padding-bottom: calc(var(--size-4) - 1px);
52
+ }
53
+ .wds-list-item-prompt .np-prompt-icon .tw-icon-tags,
54
+ .wds-list-item-prompt .np-prompt-icon .tw-icon-confetti {
55
+ color: var(--color-sentiment-positive-primary);
56
+ }
57
+ .wds-list-item-prompt.negative {
58
+ background-color: var(--color-sentiment-negative-secondary);
59
+ color: var(--color-sentiment-negative-primary);
60
+ }
61
+ .wds-list-item-prompt.negative a,
62
+ .wds-list-item-prompt.negative button {
63
+ color: var(--color-sentiment-negative-primary);
64
+ }
65
+ .wds-list-item-prompt.negative a:hover,
66
+ .wds-list-item-prompt.negative button:hover {
67
+ color: var(--color-sentiment-negative-primary-hover);
68
+ }
69
+ .wds-list-item-prompt.negative a:active,
70
+ .wds-list-item-prompt.negative button:active {
71
+ color: var(--color-sentiment-negative-primary-active);
72
+ }
73
+ .wds-list-item-prompt.wds-list-item-prompt.negative:has(a, button):hover {
74
+ background-color: var(--color-sentiment-negative-secondary-hover);
75
+ }
76
+ .wds-list-item-prompt.wds-list-item-prompt.negative:has(a, button):active {
77
+ background-color: var(--color-sentiment-negative-secondary-active);
78
+ }
79
+ .wds-list-item-prompt.positive,
80
+ .wds-list-item-prompt.discount,
81
+ .wds-list-item-prompt.savings {
82
+ background-color: var(--color-sentiment-positive-secondary);
83
+ color: var(--color-sentiment-positive-primary);
84
+ }
85
+ .wds-list-item-prompt.positive a,
86
+ .wds-list-item-prompt.discount a,
87
+ .wds-list-item-prompt.savings a,
88
+ .wds-list-item-prompt.positive button,
89
+ .wds-list-item-prompt.discount button,
90
+ .wds-list-item-prompt.savings button {
91
+ color: var(--color-sentiment-positive-primary);
92
+ }
93
+ .wds-list-item-prompt.positive a:hover,
94
+ .wds-list-item-prompt.discount a:hover,
95
+ .wds-list-item-prompt.savings a:hover,
96
+ .wds-list-item-prompt.positive button:hover,
97
+ .wds-list-item-prompt.discount button:hover,
98
+ .wds-list-item-prompt.savings button:hover {
99
+ color: var(--color-sentiment-positive-primary-hover);
100
+ }
101
+ .wds-list-item-prompt.positive a:active,
102
+ .wds-list-item-prompt.discount a:active,
103
+ .wds-list-item-prompt.savings a:active,
104
+ .wds-list-item-prompt.positive button:active,
105
+ .wds-list-item-prompt.discount button:active,
106
+ .wds-list-item-prompt.savings button:active {
107
+ color: var(--color-sentiment-positive-primary-active);
108
+ }
109
+ .wds-list-item-prompt.wds-list-item-prompt.positive:has(a, button):hover,
110
+ .wds-list-item-prompt.wds-list-item-prompt.discount:has(a, button):hover,
111
+ .wds-list-item-prompt.wds-list-item-prompt.savings:has(a, button):hover {
112
+ background-color: var(--color-sentiment-positive-secondary-hover);
113
+ }
114
+ .wds-list-item-prompt.wds-list-item-prompt.positive:has(a, button):active,
115
+ .wds-list-item-prompt.wds-list-item-prompt.discount:has(a, button):active,
116
+ .wds-list-item-prompt.wds-list-item-prompt.savings:has(a, button):active {
117
+ background-color: var(--color-sentiment-positive-secondary-active);
118
+ }
119
+ .wds-list-item-prompt.neutral {
120
+ background-color: rgba(134,167,189,0.10196);
121
+ background-color: var(--color-background-neutral);
122
+ color: #37517e;
123
+ color: var(--color-content-primary);
124
+ }
125
+ .wds-list-item-prompt.neutral a,
126
+ .wds-list-item-prompt.neutral button {
127
+ color: #37517e;
128
+ color: var(--color-content-primary);
129
+ }
130
+ .wds-list-item-prompt.wds-list-item-prompt.neutral:has(a, button):hover {
131
+ background-color: var(--color-background-neutral-hover);
132
+ }
133
+ .wds-list-item-prompt.wds-list-item-prompt.neutral:has(a, button):active {
134
+ background-color: var(--color-background-neutral-active);
135
+ }
136
+ .wds-list-item-prompt.warning {
137
+ background-color: var(--color-sentiment-warning-secondary);
138
+ color: var(--color-sentiment-warning-content);
139
+ }
140
+ .wds-list-item-prompt.warning a,
141
+ .wds-list-item-prompt.warning button {
142
+ color: var(--color-sentiment-warning-content);
143
+ }
144
+ .wds-list-item-prompt.warning a:hover,
145
+ .wds-list-item-prompt.warning button:hover {
146
+ color: var(--color-sentiment-warning-content-hover);
147
+ }
148
+ .wds-list-item-prompt.warning a:active,
149
+ .wds-list-item-prompt.warning button:active {
150
+ color: var(--color-sentiment-warning-content-active);
151
+ }
152
+ .wds-list-item-prompt.wds-list-item-prompt.warning:has(a, button):hover {
153
+ background-color: color-mix(in srgb, var(--color-sentiment-warning-secondary) 92%, var(--color-sentiment-warning-primary));
154
+ }
155
+ .wds-list-item-prompt.wds-list-item-prompt.warning:has(a, button):active {
156
+ background-color: color-mix(in srgb, var(--color-sentiment-warning-secondary) 84%, var(--color-sentiment-warning-primary));
157
+ }
@@ -0,0 +1,134 @@
1
+ .wds-list-item-prompt {
2
+ grid-area: prompt;
3
+
4
+ display: inline-flex;
5
+ justify-self: start;
6
+ text-align: left;
7
+ padding-top: calc(var(--padding-x-small) / 2);
8
+ padding-bottom: calc(var(--padding-x-small) / 2);
9
+ padding-left: calc(var(--padding-x-small) - 1px);
10
+ padding-right: var(--padding-x-small);
11
+ border-radius: var(--radius-small);
12
+ word-break: break-word;
13
+ overflow-wrap: break-word;
14
+
15
+ &:has(a),
16
+ &:has(button) {
17
+ position: relative;
18
+ z-index: 1;
19
+ }
20
+
21
+ a, button {
22
+ text-underline-offset: calc(var(--size-4) / 2);
23
+ &:first-of-type {
24
+ &:before {
25
+ content: '';
26
+ position: absolute;
27
+ inset: 0;
28
+ }
29
+ }
30
+ }
31
+
32
+ &.np-prompt-icon {
33
+ padding-left: calc(var(--padding-x-small) - 1px);
34
+ padding-right: var(--padding-x-small);
35
+ display: inline-flex;
36
+ align-items: center;
37
+ gap: var(--size-4);
38
+ }
39
+
40
+ .np-prompt-icon {
41
+ padding-right: calc(var(--size-12) / 2);
42
+ padding-top: calc(var(--size-4) - 1px);
43
+ padding-bottom: calc(var(--size-4) - 1px);
44
+
45
+ .tw-icon-tags,
46
+ .tw-icon-confetti {
47
+ color: var(--color-sentiment-positive-primary);
48
+ }
49
+ }
50
+
51
+ &.negative {
52
+ background-color: var(--color-sentiment-negative-secondary);
53
+ color: var(--color-sentiment-negative-primary);
54
+ a, button {
55
+ color: var(--color-sentiment-negative-primary);
56
+ &:hover {
57
+ color: var(--color-sentiment-negative-primary-hover);
58
+ }
59
+ &:active {
60
+ color: var(--color-sentiment-negative-primary-active);
61
+ }
62
+ }
63
+ .wds-list-item-prompt&:has(a, button) {
64
+ &:hover {
65
+ background-color: var(--color-sentiment-negative-secondary-hover);
66
+ }
67
+ &:active {
68
+ background-color: var(--color-sentiment-negative-secondary-active);
69
+ }
70
+ }
71
+ }
72
+ &.positive,
73
+ &.discount,
74
+ &.savings {
75
+ background-color: var(--color-sentiment-positive-secondary);
76
+ color: var(--color-sentiment-positive-primary);
77
+ a, button {
78
+ color: var(--color-sentiment-positive-primary);
79
+ &:hover {
80
+ color: var(--color-sentiment-positive-primary-hover);
81
+ }
82
+ &:active {
83
+ color: var(--color-sentiment-positive-primary-active);
84
+ }
85
+ }
86
+ .wds-list-item-prompt&:has(a, button) {
87
+ &:hover {
88
+ background-color: var(--color-sentiment-positive-secondary-hover);
89
+ }
90
+ &:active {
91
+ background-color: var(--color-sentiment-positive-secondary-active);
92
+ }
93
+ }
94
+ }
95
+ &.neutral {
96
+ background-color: var(--color-background-neutral);
97
+ color: var(--color-content-primary);
98
+ a, button {
99
+ color: var(--color-content-primary);
100
+ }
101
+ .wds-list-item-prompt&:has(a, button) {
102
+ &:hover {
103
+ background-color: var(--color-background-neutral-hover);
104
+ }
105
+ &:active {
106
+ background-color: var(--color-background-neutral-active);
107
+ }
108
+ }
109
+ }
110
+ &.warning {
111
+ background-color: var(--color-sentiment-warning-secondary);
112
+ color: var(--color-sentiment-warning-content);
113
+ a, button {
114
+ color: var(--color-sentiment-warning-content);
115
+ &:hover {
116
+ color: var(--color-sentiment-warning-content-hover);
117
+ }
118
+ &:active {
119
+ color: var(--color-sentiment-warning-content-active);
120
+ }
121
+ }
122
+ .wds-list-item-prompt&:has(a, button) {
123
+ &:hover {
124
+ // someday we'll have hover and active states for warning
125
+ // background-color: var(--color-sentiment-warning-secondary-hover);
126
+ background-color: color-mix(in srgb, var(--color-sentiment-warning-secondary) 92%, var(--color-sentiment-warning-primary));
127
+ }
128
+ &:active {
129
+ // background-color: var(--color-sentiment-warning-secondary-active);
130
+ background-color: color-mix(in srgb, var(--color-sentiment-warning-secondary) 84%, var(--color-sentiment-warning-primary));
131
+ }
132
+ }
133
+ }
134
+ }
@@ -0,0 +1,36 @@
1
+ import { mockMatchMedia, render, screen } from '../../test-utils';
2
+ import { Sentiment } from '../../common';
3
+ import { ListItem } from '../ListItem';
4
+ import type { ListItemPromptProps } from './ListItemPrompt';
5
+
6
+ mockMatchMedia();
7
+
8
+ describe('ListItem.Prompt', () => {
9
+ it('renders children content', () => {
10
+ render(
11
+ <ListItem
12
+ title="Test Title"
13
+ prompt={<ListItem.Prompt>This is a prompt message</ListItem.Prompt>}
14
+ />,
15
+ );
16
+
17
+ expect(screen.getByText('This is a prompt message')).toBeInTheDocument();
18
+ });
19
+
20
+ describe('render icon', () => {
21
+ it.each([
22
+ [Sentiment.NEUTRAL, 'info-icon'],
23
+ [Sentiment.POSITIVE, 'check-icon'],
24
+ [Sentiment.NEGATIVE, 'cross-icon'],
25
+ [Sentiment.WARNING, 'alert-icon'],
26
+ ] as [ListItemPromptProps['sentiment'], string][])('renders %s icon', (sentiment, iconId) => {
27
+ render(
28
+ <ListItem
29
+ title="Test Title"
30
+ prompt={<ListItem.Prompt sentiment={sentiment}>Message</ListItem.Prompt>}
31
+ />,
32
+ );
33
+ expect(screen.getByTestId(iconId)).toBeInTheDocument();
34
+ });
35
+ });
36
+ });
@@ -0,0 +1,204 @@
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
+ import { action } from 'storybook/actions';
3
+ import { lorem10, lorem5 } from '../../test-utils';
4
+ import Link from '../../link';
5
+ import List from '../../list';
6
+ import { Sentiment as Sentiments } from '../../common';
7
+ import { ListItem } from '../ListItem';
8
+ import { Prompt, type ListItemPromptProps } from './ListItemPrompt';
9
+ import {
10
+ SB_LIST_ITEM_CONTROLS as CONTROLS,
11
+ SB_LIST_ITEM_MEDIA as MEDIA,
12
+ } from '../_stories/subcomponents';
13
+
14
+ const meta: Meta<ListItemPromptProps> = {
15
+ component: Prompt,
16
+ title: 'Content/ListItem/ListItem.Prompt',
17
+ parameters: {
18
+ docs: {
19
+ toc: true,
20
+ },
21
+ },
22
+ args: {
23
+ sentiment: undefined,
24
+ children: 'You have done a terrible thing',
25
+ },
26
+ argTypes: {
27
+ sentiment: {
28
+ options: [
29
+ 'unset (undefined)',
30
+ Sentiments.POSITIVE,
31
+ Sentiments.NEGATIVE,
32
+ Sentiments.NEUTRAL,
33
+ Sentiments.WARNING,
34
+ ],
35
+ mapping: {
36
+ 'unset (undefined)': undefined,
37
+ },
38
+ control: { type: 'radio' },
39
+ },
40
+ children: {
41
+ table: {
42
+ type: { summary: 'ReactNode' },
43
+ },
44
+ },
45
+ },
46
+ };
47
+
48
+ export default meta;
49
+
50
+ type Story = StoryObj<ListItemPromptProps>;
51
+
52
+ export const Playground: Story = {
53
+ tags: ['!autodocs'],
54
+ parameters: {
55
+ docs: {
56
+ source: 'dynamic',
57
+ },
58
+ },
59
+ render: (args) => (
60
+ <List>
61
+ <ListItem
62
+ title={lorem5}
63
+ subtitle={lorem10}
64
+ media={MEDIA.avatarSingle}
65
+ control={CONTROLS.switch}
66
+ prompt={<Prompt {...args} />}
67
+ />
68
+ </List>
69
+ ),
70
+ };
71
+
72
+ export const Sentiment: Story = {
73
+ parameters: {
74
+ controls: { disable: true },
75
+ actions: { disable: true },
76
+ a11y: { disable: true },
77
+ knobs: { disable: true },
78
+ },
79
+ render: (args) => (
80
+ <List>
81
+ <ListItem
82
+ title={lorem5}
83
+ subtitle={lorem10}
84
+ media={MEDIA.avatarSingle}
85
+ control={CONTROLS.switch}
86
+ prompt={<Prompt sentiment={Sentiments.NEUTRAL}>This is a neutral prompt.</Prompt>}
87
+ />
88
+ <ListItem
89
+ title={lorem5}
90
+ subtitle={lorem10}
91
+ media={MEDIA.avatarSingle}
92
+ control={CONTROLS.switch}
93
+ prompt={<Prompt sentiment={Sentiments.POSITIVE}>This is a positive prompt.</Prompt>}
94
+ />
95
+ <ListItem
96
+ title={lorem5}
97
+ subtitle={lorem10}
98
+ media={MEDIA.avatarSingle}
99
+ control={CONTROLS.switch}
100
+ prompt={<Prompt sentiment={Sentiments.WARNING}>This is a warning prompt.</Prompt>}
101
+ />
102
+ <ListItem
103
+ title={lorem5}
104
+ subtitle={lorem10}
105
+ media={MEDIA.avatarSingle}
106
+ control={CONTROLS.switch}
107
+ prompt={<Prompt sentiment={Sentiments.NEGATIVE}>This is a negative prompt.</Prompt>}
108
+ />
109
+ </List>
110
+ ),
111
+ };
112
+
113
+ /**
114
+ * `ListItem.Prompt` is rendered on a separate branch of the Accessibility Tree from the item's
115
+ * control, so it can include a single instance of `Link` component, which can be rendered as
116
+ * either HTML anchor or button. That element will spread across the whole surface of the Prompt
117
+ * so it's easily accessible for all users.
118
+ */
119
+ export const Interactivity: Story = {
120
+ argTypes: {
121
+ children: {
122
+ table: {
123
+ disable: true,
124
+ },
125
+ },
126
+ },
127
+ render: (args) => (
128
+ <List>
129
+ <ListItem
130
+ title={lorem5}
131
+ subtitle={lorem10}
132
+ media={MEDIA.avatarSingle}
133
+ control={CONTROLS.switch}
134
+ prompt={
135
+ <Prompt sentiment={args.sentiment}>
136
+ This prompt includes a{' '}
137
+ <Link href="https://wise.com" target="_blank" rel="noreferrer">
138
+ link to some resource
139
+ </Link>{' '}
140
+ to help the user in their journey.
141
+ </Prompt>
142
+ }
143
+ />
144
+
145
+ <ListItem
146
+ title={lorem5}
147
+ subtitle={lorem10}
148
+ media={MEDIA.avatarSingle}
149
+ control={CONTROLS.switch}
150
+ prompt={
151
+ <Prompt sentiment={args.sentiment}>
152
+ {/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
153
+ This prompt includes an <Link onClick={action('inline button')}>
154
+ inline button
155
+ </Link>{' '}
156
+ than can e.g. trigger a modal.
157
+ </Prompt>
158
+ }
159
+ />
160
+ </List>
161
+ ),
162
+ };
163
+
164
+ /**
165
+ * By default, the Prompt will try to occupy as little space as possible, but as soon as you make it more than 1 line long, it will stretch to the full available width.
166
+ *
167
+ * **NB:** While Prompt supports multi-line text, its content should be concise and have no more than 2 short sentences so users can quickly understand the message.
168
+ */
169
+ export const Sizing: Story = {
170
+ parameters: {
171
+ docs: {
172
+ canvas: {
173
+ sourceState: 'hidden',
174
+ },
175
+ },
176
+ },
177
+ render: (args) => (
178
+ <List>
179
+ <ListItem
180
+ title={lorem5}
181
+ subtitle={lorem10}
182
+ media={MEDIA.image}
183
+ control={CONTROLS.switch}
184
+ prompt={
185
+ <ListItem.Prompt sentiment={Sentiments.POSITIVE}>This is a short text</ListItem.Prompt>
186
+ }
187
+ />
188
+ <ListItem
189
+ title={lorem5}
190
+ subtitle={lorem10}
191
+ media={MEDIA.image}
192
+ control={CONTROLS.switch}
193
+ prompt={
194
+ <ListItem.Prompt sentiment={Sentiments.WARNING}>
195
+ This is a very, very, very, very, very long text that will wrap into more than 1 line
196
+ and will make the prompt stretch to a full available width. Technically it can be as
197
+ long as Vim manual, but we recommend keeping it concise and no more than 2 short
198
+ sentences.
199
+ </ListItem.Prompt>
200
+ }
201
+ />
202
+ </List>
203
+ ),
204
+ };
@@ -0,0 +1,32 @@
1
+ import { useContext } from 'react';
2
+ import { clsx } from 'clsx';
3
+ import { Sentiment } from '../../common';
4
+ import StatusIcon from '../../statusIcon';
5
+ import Body from '../../body';
6
+ import { ListItemContext, type ListItemContextData } from '../ListItemContext';
7
+
8
+ export type ListItemPromptProps = {
9
+ sentiment?: `${Sentiment.POSITIVE | Sentiment.NEGATIVE | Sentiment.NEUTRAL | Sentiment.WARNING}`;
10
+ children: React.ReactNode;
11
+ };
12
+
13
+ /**
14
+ * This component allows for rendering an Inline Prompt. <br />In the future it will be a thin wrapper around a standalone component.<br />
15
+ *
16
+ * Please refer to the [Design documentation](https://wise.design/components/list-item#prompt) for details.
17
+ */
18
+ export const Prompt = ({ sentiment = Sentiment.NEUTRAL, children }: ListItemPromptProps) => {
19
+ const { ids } = useContext<ListItemContextData>(ListItemContext);
20
+
21
+ return (
22
+ <div id={ids.prompt} className={clsx('wds-list-item-prompt', sentiment)}>
23
+ <div className="np-prompt-icon">
24
+ <StatusIcon size={16} sentiment={sentiment} />
25
+ </div>
26
+ <Body>{children}</Body>
27
+ </div>
28
+ );
29
+ };
30
+
31
+ Prompt.displayName = 'ListItem.Prompt';
32
+ export default Prompt;
@@ -0,0 +1,2 @@
1
+ export type { ListItemPromptProps } from './ListItemPrompt';
2
+ export { Prompt } from './ListItemPrompt';
@@ -0,0 +1,66 @@
1
+ import { render, screen } from '../../test-utils';
2
+ import userEvent from '@testing-library/user-event';
3
+ import { ListItem, type ListItemProps } from '../ListItem';
4
+
5
+ describe('ListItem.Radio', () => {
6
+ const renderWith = (overrides: Partial<ListItemProps> = {}) =>
7
+ render(<ListItem title="Test Title" {...overrides} />);
8
+
9
+ it('renders radio button', () => {
10
+ renderWith({
11
+ control: <ListItem.Radio name="test-radio" value="option1" onChange={() => {}} />,
12
+ });
13
+
14
+ expect(screen.getByRole('radio')).toBeInTheDocument();
15
+ });
16
+
17
+ describe('checked state', () => {
18
+ it('reflects checked state', () => {
19
+ renderWith({
20
+ control: <ListItem.Radio name="test-radio" value="option1" checked />,
21
+ });
22
+
23
+ expect(screen.getByRole('radio')).toBeChecked();
24
+ });
25
+
26
+ it('reflects unchecked state', () => {
27
+ renderWith({
28
+ control: <ListItem.Radio name="test-radio" value="option1" checked={false} />,
29
+ });
30
+
31
+ expect(screen.getByRole('radio')).not.toBeChecked();
32
+ });
33
+ });
34
+
35
+ it('handles onChange events', async () => {
36
+ const handleChange = jest.fn();
37
+ renderWith({
38
+ control: <ListItem.Radio name="test-radio" value="option1" onChange={handleChange} />,
39
+ });
40
+
41
+ await userEvent.click(screen.getByRole('radio'));
42
+ expect(handleChange).toHaveBeenCalledTimes(1);
43
+ });
44
+
45
+ it('is disabled when ListItem is disabled', async () => {
46
+ const handleChange = jest.fn();
47
+ renderWith({
48
+ disabled: true,
49
+ control: <ListItem.Radio name="test-radio" value="option1" onChange={handleChange} />,
50
+ });
51
+
52
+ const radio = screen.getByRole('radio');
53
+ expect(radio).toBeDisabled();
54
+ await userEvent.click(radio);
55
+ expect(handleChange).not.toHaveBeenCalled();
56
+ });
57
+
58
+ it('supports name and value attributes', () => {
59
+ renderWith({ control: <ListItem.Radio name="test-radio" value="option1" /> });
60
+
61
+ const radio = screen.getByRole('radio');
62
+ expect(radio).toHaveAttribute('name', 'test-radio');
63
+ // eslint-disable-next-line jest-dom/prefer-to-have-value
64
+ expect(radio).toHaveAttribute('value', 'option1');
65
+ });
66
+ });