@transferwise/components 0.0.0-experimental-a18466a → 0.0.0-experimental-e789c10

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 (257) hide show
  1. package/build/criticalBanner/CriticalCommsBanner.js +68 -3
  2. package/build/criticalBanner/CriticalCommsBanner.js.map +1 -1
  3. package/build/criticalBanner/CriticalCommsBanner.mjs +69 -4
  4. package/build/criticalBanner/CriticalCommsBanner.mjs.map +1 -1
  5. package/build/dateInput/DateInput.js +12 -5
  6. package/build/dateInput/DateInput.js.map +1 -1
  7. package/build/dateInput/DateInput.mjs +11 -4
  8. package/build/dateInput/DateInput.mjs.map +1 -1
  9. package/build/expressiveMoneyInput/currencySelector/CurrencySelector.js +16 -8
  10. package/build/expressiveMoneyInput/currencySelector/CurrencySelector.js.map +1 -1
  11. package/build/expressiveMoneyInput/currencySelector/CurrencySelector.mjs +14 -6
  12. package/build/expressiveMoneyInput/currencySelector/CurrencySelector.mjs.map +1 -1
  13. package/build/index.js +12 -7
  14. package/build/index.js.map +1 -1
  15. package/build/index.mjs +9 -3
  16. package/build/index.mjs.map +1 -1
  17. package/build/inputs/{_BottomSheet.js → SelectInput/BottomSheet/SelectInputBottomSheet.js} +7 -7
  18. package/build/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.js.map +1 -0
  19. package/build/inputs/{_BottomSheet.mjs → SelectInput/BottomSheet/SelectInputBottomSheet.mjs} +7 -7
  20. package/build/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.mjs.map +1 -0
  21. package/build/inputs/{_ButtonInput.js → SelectInput/ButtonInput/SelectInputButtonInput.js} +5 -5
  22. package/build/inputs/SelectInput/ButtonInput/SelectInputButtonInput.js.map +1 -0
  23. package/build/inputs/{_ButtonInput.mjs → SelectInput/ButtonInput/SelectInputButtonInput.mjs} +5 -5
  24. package/build/inputs/SelectInput/ButtonInput/SelectInputButtonInput.mjs.map +1 -0
  25. package/build/inputs/SelectInput/ClearButton/SelectInputClearButton.js +26 -0
  26. package/build/inputs/SelectInput/ClearButton/SelectInputClearButton.js.map +1 -0
  27. package/build/inputs/SelectInput/ClearButton/SelectInputClearButton.mjs +24 -0
  28. package/build/inputs/SelectInput/ClearButton/SelectInputClearButton.mjs.map +1 -0
  29. package/build/inputs/SelectInput/DefaultRenderTrigger/SelectInputDefaultRenderTrigger.js +59 -0
  30. package/build/inputs/SelectInput/DefaultRenderTrigger/SelectInputDefaultRenderTrigger.js.map +1 -0
  31. package/build/inputs/SelectInput/DefaultRenderTrigger/SelectInputDefaultRenderTrigger.mjs +56 -0
  32. package/build/inputs/SelectInput/DefaultRenderTrigger/SelectInputDefaultRenderTrigger.mjs.map +1 -0
  33. package/build/inputs/SelectInput/ItemView/GroupItemView/SelectInputGroupItemView.js +50 -0
  34. package/build/inputs/SelectInput/ItemView/GroupItemView/SelectInputGroupItemView.js.map +1 -0
  35. package/build/inputs/SelectInput/ItemView/GroupItemView/SelectInputGroupItemView.mjs +48 -0
  36. package/build/inputs/SelectInput/ItemView/GroupItemView/SelectInputGroupItemView.mjs.map +1 -0
  37. package/build/inputs/SelectInput/ItemView/SelectInputItemView.js +47 -0
  38. package/build/inputs/SelectInput/ItemView/SelectInputItemView.js.map +1 -0
  39. package/build/inputs/SelectInput/ItemView/SelectInputItemView.mjs +45 -0
  40. package/build/inputs/SelectInput/ItemView/SelectInputItemView.mjs.map +1 -0
  41. package/build/inputs/SelectInput/Option/SelectInputOption.js +42 -0
  42. package/build/inputs/SelectInput/Option/SelectInputOption.js.map +1 -0
  43. package/build/inputs/SelectInput/Option/SelectInputOption.mjs +40 -0
  44. package/build/inputs/SelectInput/Option/SelectInputOption.mjs.map +1 -0
  45. package/build/inputs/SelectInput/OptionContent/SelectInputOptionContent.js +40 -0
  46. package/build/inputs/SelectInput/OptionContent/SelectInputOptionContent.js.map +1 -0
  47. package/build/inputs/SelectInput/OptionContent/SelectInputOptionContent.mjs +38 -0
  48. package/build/inputs/SelectInput/OptionContent/SelectInputOptionContent.mjs.map +1 -0
  49. package/build/inputs/SelectInput/Options/OptionsContainer/SelectInputOptionsContainer.js +48 -0
  50. package/build/inputs/SelectInput/Options/OptionsContainer/SelectInputOptionsContainer.js.map +1 -0
  51. package/build/inputs/SelectInput/Options/OptionsContainer/SelectInputOptionsContainer.mjs +46 -0
  52. package/build/inputs/SelectInput/Options/OptionsContainer/SelectInputOptionsContainer.mjs.map +1 -0
  53. package/build/inputs/SelectInput/Options/SelectInputOptions.js +300 -0
  54. package/build/inputs/SelectInput/Options/SelectInputOptions.js.map +1 -0
  55. package/build/inputs/SelectInput/Options/SelectInputOptions.mjs +298 -0
  56. package/build/inputs/SelectInput/Options/SelectInputOptions.mjs.map +1 -0
  57. package/build/inputs/{_Popover.js → SelectInput/Popover/SelectInputPopover.js} +7 -7
  58. package/build/inputs/SelectInput/Popover/SelectInputPopover.js.map +1 -0
  59. package/build/inputs/{_Popover.mjs → SelectInput/Popover/SelectInputPopover.mjs} +7 -7
  60. package/build/inputs/SelectInput/Popover/SelectInputPopover.mjs.map +1 -0
  61. package/build/inputs/SelectInput/SelectInput.contexts.js +29 -0
  62. package/build/inputs/SelectInput/SelectInput.contexts.js.map +1 -0
  63. package/build/inputs/SelectInput/SelectInput.contexts.mjs +24 -0
  64. package/build/inputs/SelectInput/SelectInput.contexts.mjs.map +1 -0
  65. package/build/inputs/SelectInput/SelectInput.js +222 -0
  66. package/build/inputs/SelectInput/SelectInput.js.map +1 -0
  67. package/build/inputs/SelectInput/SelectInput.messages.js.map +1 -0
  68. package/build/inputs/SelectInput/SelectInput.messages.mjs.map +1 -0
  69. package/build/inputs/SelectInput/SelectInput.mjs +216 -0
  70. package/build/inputs/SelectInput/SelectInput.mjs.map +1 -0
  71. package/build/inputs/SelectInput/SelectInput.utils.js +164 -0
  72. package/build/inputs/SelectInput/SelectInput.utils.js.map +1 -0
  73. package/build/inputs/SelectInput/SelectInput.utils.mjs +154 -0
  74. package/build/inputs/SelectInput/SelectInput.utils.mjs.map +1 -0
  75. package/build/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.js +42 -0
  76. package/build/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.js.map +1 -0
  77. package/build/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.mjs +36 -0
  78. package/build/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.mjs.map +1 -0
  79. package/build/main.css +123 -105
  80. package/build/moneyInput/MoneyInput.js +9 -2
  81. package/build/moneyInput/MoneyInput.js.map +1 -1
  82. package/build/moneyInput/MoneyInput.mjs +8 -1
  83. package/build/moneyInput/MoneyInput.mjs.map +1 -1
  84. package/build/phoneNumberInput/PhoneNumberInput.js +10 -3
  85. package/build/phoneNumberInput/PhoneNumberInput.js.map +1 -1
  86. package/build/phoneNumberInput/PhoneNumberInput.mjs +9 -2
  87. package/build/phoneNumberInput/PhoneNumberInput.mjs.map +1 -1
  88. package/build/styles/criticalBanner/CriticalCommsBanner.css +33 -15
  89. package/build/styles/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.css +96 -0
  90. package/build/styles/inputs/SelectInput/ButtonInput/SelectInputButtonInput.css +16 -0
  91. package/build/styles/inputs/SelectInput/ClearButton/SelectInputClearButton.css +46 -0
  92. package/build/styles/inputs/SelectInput/ItemView/SelectInputItemView.css +16 -0
  93. package/build/styles/inputs/SelectInput/Option/SelectInputOption.css +33 -0
  94. package/build/styles/inputs/SelectInput/OptionContent/SelectInputOptionContent.css +37 -0
  95. package/build/styles/inputs/SelectInput/Options/SelectInputOptions.css +81 -0
  96. package/build/styles/inputs/SelectInput/Popover/SelectInputPopover.css +46 -0
  97. package/build/styles/main.css +123 -105
  98. package/build/types/criticalBanner/CriticalCommsBanner.d.ts +4 -1
  99. package/build/types/criticalBanner/CriticalCommsBanner.d.ts.map +1 -1
  100. package/build/types/criticalBanner/index.d.ts +1 -0
  101. package/build/types/criticalBanner/index.d.ts.map +1 -1
  102. package/build/types/index.d.ts +2 -1
  103. package/build/types/index.d.ts.map +1 -1
  104. package/build/types/inputs/{_BottomSheet.d.ts → SelectInput/BottomSheet/SelectInputBottomSheet.d.ts} +3 -3
  105. package/build/types/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.d.ts.map +1 -0
  106. package/build/types/inputs/SelectInput/BottomSheet/index.d.ts +3 -0
  107. package/build/types/inputs/SelectInput/BottomSheet/index.d.ts.map +1 -0
  108. package/build/types/inputs/SelectInput/ButtonInput/SelectInputButtonInput.d.ts +5 -0
  109. package/build/types/inputs/SelectInput/ButtonInput/SelectInputButtonInput.d.ts.map +1 -0
  110. package/build/types/inputs/SelectInput/ButtonInput/index.d.ts +3 -0
  111. package/build/types/inputs/SelectInput/ButtonInput/index.d.ts.map +1 -0
  112. package/build/types/inputs/SelectInput/ClearButton/SelectInputClearButton.d.ts +7 -0
  113. package/build/types/inputs/SelectInput/ClearButton/SelectInputClearButton.d.ts.map +1 -0
  114. package/build/types/inputs/SelectInput/ClearButton/index.d.ts +3 -0
  115. package/build/types/inputs/SelectInput/ClearButton/index.d.ts.map +1 -0
  116. package/build/types/inputs/SelectInput/DefaultRenderTrigger/SelectInputDefaultRenderTrigger.d.ts +16 -0
  117. package/build/types/inputs/SelectInput/DefaultRenderTrigger/SelectInputDefaultRenderTrigger.d.ts.map +1 -0
  118. package/build/types/inputs/SelectInput/DefaultRenderTrigger/index.d.ts +2 -0
  119. package/build/types/inputs/SelectInput/DefaultRenderTrigger/index.d.ts.map +1 -0
  120. package/build/types/inputs/SelectInput/ItemView/GroupItemView/SelectInputGroupItemView.d.ts +9 -0
  121. package/build/types/inputs/SelectInput/ItemView/GroupItemView/SelectInputGroupItemView.d.ts.map +1 -0
  122. package/build/types/inputs/SelectInput/ItemView/GroupItemView/index.d.ts +3 -0
  123. package/build/types/inputs/SelectInput/ItemView/GroupItemView/index.d.ts.map +1 -0
  124. package/build/types/inputs/SelectInput/ItemView/SelectInputItemView.d.ts +11 -0
  125. package/build/types/inputs/SelectInput/ItemView/SelectInputItemView.d.ts.map +1 -0
  126. package/build/types/inputs/SelectInput/ItemView/index.d.ts +4 -0
  127. package/build/types/inputs/SelectInput/ItemView/index.d.ts.map +1 -0
  128. package/build/types/inputs/SelectInput/Option/SelectInputOption.d.ts +11 -0
  129. package/build/types/inputs/SelectInput/Option/SelectInputOption.d.ts.map +1 -0
  130. package/build/types/inputs/SelectInput/Option/index.d.ts +3 -0
  131. package/build/types/inputs/SelectInput/Option/index.d.ts.map +1 -0
  132. package/build/types/inputs/SelectInput/OptionContent/SelectInputOptionContent.d.ts +13 -0
  133. package/build/types/inputs/SelectInput/OptionContent/SelectInputOptionContent.d.ts.map +1 -0
  134. package/build/types/inputs/SelectInput/OptionContent/index.d.ts +3 -0
  135. package/build/types/inputs/SelectInput/OptionContent/index.d.ts.map +1 -0
  136. package/build/types/inputs/SelectInput/Options/OptionsContainer/SelectInputOptionsContainer.d.ts +9 -0
  137. package/build/types/inputs/SelectInput/Options/OptionsContainer/SelectInputOptionsContainer.d.ts.map +1 -0
  138. package/build/types/inputs/SelectInput/Options/OptionsContainer/index.d.ts +3 -0
  139. package/build/types/inputs/SelectInput/Options/OptionsContainer/index.d.ts.map +1 -0
  140. package/build/types/inputs/SelectInput/Options/SelectInputOptions.d.ts +21 -0
  141. package/build/types/inputs/SelectInput/Options/SelectInputOptions.d.ts.map +1 -0
  142. package/build/types/inputs/SelectInput/Options/index.d.ts +4 -0
  143. package/build/types/inputs/SelectInput/Options/index.d.ts.map +1 -0
  144. package/build/types/inputs/{_Popover.d.ts → SelectInput/Popover/SelectInputPopover.d.ts} +3 -3
  145. package/build/types/inputs/SelectInput/Popover/SelectInputPopover.d.ts.map +1 -0
  146. package/build/types/inputs/SelectInput/Popover/index.d.ts +3 -0
  147. package/build/types/inputs/SelectInput/Popover/index.d.ts.map +1 -0
  148. package/build/types/inputs/SelectInput/SelectInput.contexts.d.ts +33 -0
  149. package/build/types/inputs/SelectInput/SelectInput.contexts.d.ts.map +1 -0
  150. package/build/types/inputs/SelectInput/SelectInput.d.ts +10 -0
  151. package/build/types/inputs/SelectInput/SelectInput.d.ts.map +1 -0
  152. package/build/types/inputs/SelectInput/SelectInput.messages.d.ts.map +1 -0
  153. package/build/types/inputs/{SelectInput.d.ts → SelectInput/SelectInput.types.d.ts} +12 -38
  154. package/build/types/inputs/SelectInput/SelectInput.types.d.ts.map +1 -0
  155. package/build/types/inputs/SelectInput/SelectInput.utils.d.ts +60 -0
  156. package/build/types/inputs/SelectInput/SelectInput.utils.d.ts.map +1 -0
  157. package/build/types/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.d.ts +12 -0
  158. package/build/types/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.d.ts.map +1 -0
  159. package/build/types/inputs/SelectInput/TriggerButton/index.d.ts +3 -0
  160. package/build/types/inputs/SelectInput/TriggerButton/index.d.ts.map +1 -0
  161. package/build/types/inputs/SelectInput/components.d.ts +10 -0
  162. package/build/types/inputs/SelectInput/components.d.ts.map +1 -0
  163. package/build/types/inputs/SelectInput/index.d.ts +10 -0
  164. package/build/types/inputs/SelectInput/index.d.ts.map +1 -0
  165. package/build/types/uploadInput/UploadInput.d.ts +2 -2
  166. package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
  167. package/build/uploadInput/UploadInput.js.map +1 -1
  168. package/build/uploadInput/UploadInput.mjs.map +1 -1
  169. package/package.json +1 -1
  170. package/src/criticalBanner/CriticalCommsBanner.css +33 -15
  171. package/src/criticalBanner/CriticalCommsBanner.less +46 -36
  172. package/src/criticalBanner/CriticalCommsBanner.story.tsx +9 -15
  173. package/src/criticalBanner/CriticalCommsBanner.test.story.tsx +70 -0
  174. package/src/criticalBanner/CriticalCommsBanner.test.tsx +66 -0
  175. package/src/criticalBanner/CriticalCommsBanner.tsx +54 -5
  176. package/src/criticalBanner/index.ts +1 -0
  177. package/src/index.ts +1 -1
  178. package/src/inputs/SelectInput/BottomSheet/SelectInputBottomSheet.css +96 -0
  179. package/src/inputs/{_BottomSheet.tsx → SelectInput/BottomSheet/SelectInputBottomSheet.tsx} +7 -7
  180. package/src/inputs/SelectInput/BottomSheet/index.ts +2 -0
  181. package/src/inputs/SelectInput/ButtonInput/SelectInputButtonInput.css +16 -0
  182. package/src/inputs/{_ButtonInput.tsx → SelectInput/ButtonInput/SelectInputButtonInput.tsx} +5 -5
  183. package/src/inputs/SelectInput/ButtonInput/index.ts +2 -0
  184. package/src/inputs/SelectInput/ClearButton/SelectInputClearButton.css +46 -0
  185. package/src/inputs/SelectInput/ClearButton/SelectInputClearButton.less +39 -0
  186. package/src/inputs/SelectInput/ClearButton/SelectInputClearButton.tsx +27 -0
  187. package/src/inputs/SelectInput/ClearButton/index.ts +2 -0
  188. package/src/inputs/SelectInput/DefaultRenderTrigger/SelectInputDefaultRenderTrigger.tsx +74 -0
  189. package/src/inputs/SelectInput/DefaultRenderTrigger/index.ts +5 -0
  190. package/src/inputs/SelectInput/ItemView/GroupItemView/SelectInputGroupItemView.tsx +61 -0
  191. package/src/inputs/SelectInput/ItemView/GroupItemView/index.ts +2 -0
  192. package/src/inputs/SelectInput/ItemView/SelectInputItemView.css +16 -0
  193. package/src/inputs/SelectInput/ItemView/SelectInputItemView.less +17 -0
  194. package/src/inputs/SelectInput/ItemView/SelectInputItemView.tsx +48 -0
  195. package/src/inputs/SelectInput/ItemView/index.ts +3 -0
  196. package/src/inputs/SelectInput/Option/SelectInputOption.css +33 -0
  197. package/src/inputs/SelectInput/Option/SelectInputOption.less +32 -0
  198. package/src/inputs/SelectInput/Option/SelectInputOption.tsx +57 -0
  199. package/src/inputs/SelectInput/Option/index.ts +2 -0
  200. package/src/inputs/SelectInput/OptionContent/SelectInputOptionContent.css +37 -0
  201. package/src/inputs/SelectInput/OptionContent/SelectInputOptionContent.less +38 -0
  202. package/src/inputs/SelectInput/OptionContent/SelectInputOptionContent.tsx +72 -0
  203. package/src/inputs/SelectInput/OptionContent/index.ts +2 -0
  204. package/src/inputs/SelectInput/Options/OptionsContainer/SelectInputOptionsContainer.tsx +59 -0
  205. package/src/inputs/SelectInput/Options/OptionsContainer/index.ts +2 -0
  206. package/src/inputs/SelectInput/Options/SelectInputOptions.css +81 -0
  207. package/src/inputs/SelectInput/Options/SelectInputOptions.less +77 -0
  208. package/src/inputs/SelectInput/Options/SelectInputOptions.tsx +411 -0
  209. package/src/inputs/SelectInput/Options/index.ts +3 -0
  210. package/src/inputs/SelectInput/Popover/SelectInputPopover.css +46 -0
  211. package/src/inputs/{_Popover.tsx → SelectInput/Popover/SelectInputPopover.tsx} +7 -7
  212. package/src/inputs/SelectInput/Popover/index.ts +2 -0
  213. package/src/inputs/SelectInput/SelectInput.contexts.tsx +40 -0
  214. package/src/inputs/SelectInput/SelectInput.less +22 -0
  215. package/src/inputs/{SelectInput.test.tsx → SelectInput/SelectInput.test.tsx} +9 -11
  216. package/src/inputs/SelectInput/SelectInput.tsx +257 -0
  217. package/src/inputs/SelectInput/SelectInput.types.ts +113 -0
  218. package/src/inputs/SelectInput/SelectInput.utils.ts +205 -0
  219. package/src/inputs/SelectInput/TriggerButton/SelectInputTriggerButton.tsx +36 -0
  220. package/src/inputs/SelectInput/TriggerButton/index.ts +5 -0
  221. package/src/inputs/{SelectInput.docs.mdx → SelectInput/_stories/SelectInput.docs.mdx} +0 -1
  222. package/src/inputs/{SelectInput.story.tsx → SelectInput/_stories/SelectInput.story.tsx} +11 -8
  223. package/src/inputs/{SelectInput.test.story.tsx → SelectInput/_stories/SelectInput.test.story.tsx} +6 -10
  224. package/src/inputs/SelectInput/components.ts +10 -0
  225. package/src/inputs/SelectInput/index.ts +12 -0
  226. package/src/main.css +123 -105
  227. package/src/main.less +1 -1
  228. package/src/uploadInput/UploadInput.tsx +2 -2
  229. package/build/inputs/SelectInput.js +0 -890
  230. package/build/inputs/SelectInput.js.map +0 -1
  231. package/build/inputs/SelectInput.messages.js.map +0 -1
  232. package/build/inputs/SelectInput.messages.mjs.map +0 -1
  233. package/build/inputs/SelectInput.mjs +0 -881
  234. package/build/inputs/SelectInput.mjs.map +0 -1
  235. package/build/inputs/_BottomSheet.js.map +0 -1
  236. package/build/inputs/_BottomSheet.mjs.map +0 -1
  237. package/build/inputs/_ButtonInput.js.map +0 -1
  238. package/build/inputs/_ButtonInput.mjs.map +0 -1
  239. package/build/inputs/_Popover.js.map +0 -1
  240. package/build/inputs/_Popover.mjs.map +0 -1
  241. package/build/types/inputs/SelectInput.d.ts.map +0 -1
  242. package/build/types/inputs/SelectInput.messages.d.ts.map +0 -1
  243. package/build/types/inputs/_BottomSheet.d.ts.map +0 -1
  244. package/build/types/inputs/_ButtonInput.d.ts +0 -5
  245. package/build/types/inputs/_ButtonInput.d.ts.map +0 -1
  246. package/build/types/inputs/_Popover.d.ts.map +0 -1
  247. package/src/inputs/SelectInput.less +0 -219
  248. package/src/inputs/SelectInput.tsx +0 -1269
  249. package/build/inputs/{SelectInput.messages.js → SelectInput/SelectInput.messages.js} +0 -0
  250. package/build/inputs/{SelectInput.messages.mjs → SelectInput/SelectInput.messages.mjs} +0 -0
  251. package/build/styles/inputs/{SelectInput.css → SelectInput/SelectInput.css} +90 -90
  252. package/build/types/inputs/{SelectInput.messages.d.ts → SelectInput/SelectInput.messages.d.ts} +0 -0
  253. package/src/inputs/{_BottomSheet.less → SelectInput/BottomSheet/SelectInputBottomSheet.less} +0 -0
  254. package/src/inputs/{_ButtonInput.less → SelectInput/ButtonInput/SelectInputButtonInput.less} +0 -0
  255. package/src/inputs/{_Popover.less → SelectInput/Popover/SelectInputPopover.less} +0 -0
  256. package/src/inputs/{SelectInput.css → SelectInput/SelectInput.css} +90 -90
  257. /package/src/inputs/{SelectInput.messages.ts → SelectInput/SelectInput.messages.ts} +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"UploadInput.mjs","sources":["../../src/uploadInput/UploadInput.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useEffect, useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Button from '../button';\nimport { CommonProps, ControlType, Priority, Status } from '../common';\nimport { useInputAttributes } from '../inputs/contexts';\nimport Modal from '../modal';\nimport { isSizeValid } from '../upload/utils/isSizeValid';\nimport { isTypeValid } from '../upload/utils/isTypeValid';\n\nimport MESSAGES from './UploadInput.messages';\nimport { UploadedFile, UploadError, UploadResponse } from './types';\nimport UploadButton, { UploadButtonProps } from './uploadButton/UploadButton';\nimport { DEFAULT_SIZE_LIMIT, imageFileTypes } from './uploadButton/defaults';\nimport UploadItem, { UploadItemProps } from './uploadItem/UploadItem';\n\nexport type UploadInputProps = {\n /**\n * List of already existing, failed or in progress files\n * @default []\n */\n files?: readonly UploadedFile[];\n\n /**\n * The key of the file in the returned FormData object (default: file)\n * @default 'file'\n */\n fileInputName?: string;\n\n /**\n * Callback that handles form submission\n *\n * @param formData\n */\n onUploadFile: (formData: FormData) => Promise<UploadResponse>;\n\n /**\n * Provide a callback if the file can be removed/deleted from the server\n * Your app is responsible for reloading the uploaded files list and updating the component to ensure that the file has in fact been deleted successfully\n *\n * @param id\n */\n onDeleteFile?: (id: string | number) => Promise<any>;\n\n /**\n * Provide a callback to trigger on validation error\n *\n * @param file\n */\n onValidationError?: (file: UploadedFile) => void;\n\n /**\n * Provide a callback to trigger on change whenever the files are updated\n *\n * @param files\n */\n onFilesChange?: (files: UploadedFile[]) => void;\n\n /**\n * Confirmation modal displayed on delete\n */\n deleteConfirm?: {\n /**\n * The title of the confirmation modal on delete\n */\n title?: string;\n\n /**\n * The body of the confirmation modal on delete\n */\n body?: React.ReactNode;\n\n /**\n * The confirm button text of the confirmation modal on delete\n */\n confirmText?: string;\n\n /**\n * The cancel button text of the confirmation modal on delete\n */\n cancelText?: string;\n };\n\n /**\n * Maximum number of files allowed, if provided, shows error below file item\n */\n maxFiles?: number;\n\n /**\n * Error message to show when the maximum number of files are uploaded already\n */\n maxFilesErrorMessage?: string;\n\n /**\n * Error message to show when files over allowed size limit are uploaded\n */\n sizeLimitErrorMessage?: string;\n} & {\n /** @default false */\n multiple?: UploadButtonProps['multiple'];\n /** @default imageFileTypes */\n fileTypes?: UploadButtonProps['fileTypes'];\n /** @default DEFAULT_SIZE_LIMIT */\n sizeLimit?: UploadButtonProps['sizeLimit'];\n} & Pick<UploadButtonProps, 'disabled' | 'description' | 'id' | 'uploadButtonTitle'> & {\n onDownload?: UploadItemProps['onDownload'];\n } & CommonProps;\n\n/**\n * Interface representing a reference to an UploadItem component.\n * Provides a method to focus the UploadItem.\n */\ninterface UploadItemRef {\n /**\n * Focuses the UploadItem component.\n */\n focus: () => void;\n\n /**\n * Required id of the UploadItem component.\n */\n id: string | number;\n\n /**\n * Optional status of the UploadItem component.\n */\n status?: string;\n}\n\n/**\n * Generates a unique ID for a file based on its name, size, and the current timestamp\n */\nfunction generateFileId(file: File) {\n const { name, size } = file;\n const uploadTimeStamp = new Date().getTime();\n return `${name}_${size}_${uploadTimeStamp}`;\n}\n\n/**\n * The component allows users to upload files, manage the list of uploaded files,\n * and handle file validation and deletion.\n *\n * @param {UploadInputProps} props - The properties for the UploadInput component.\n *\n * @see {@link UploadInput} for further information.\n * @see {@link https://storybook.wise.design/?path=/docs/forms-uploadinput--docs|Storybook Wise Design}\n */\nconst UploadInput = ({\n files = [],\n fileInputName = 'file',\n className,\n deleteConfirm,\n disabled,\n multiple = false,\n fileTypes = imageFileTypes,\n sizeLimit = DEFAULT_SIZE_LIMIT,\n description,\n onUploadFile,\n onDeleteFile,\n onValidationError,\n onFilesChange,\n onDownload,\n maxFiles,\n maxFilesErrorMessage,\n id,\n sizeLimitErrorMessage,\n uploadButtonTitle,\n}: UploadInputProps) => {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n const [markedFileForDelete, setMarkedFileForDelete] = useState<UploadedFile | null>(null);\n const [lastAttemptedDeleteId, setLastAttemptedDeleteId] = useState<string | number | null>(null);\n const [mounted, setMounted] = useState(false);\n const { formatMessage } = useIntl();\n const uploadInputRef = useRef<HTMLInputElement | null>(null);\n let fileRefs: (HTMLDivElement | UploadItemRef | null)[] = [];\n\n const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);\n\n const [uploadedFiles, setUploadedFiles] = useState<readonly UploadedFile[]>(\n multiple || files.length === 0 ? files : [files[0]],\n );\n\n const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);\n\n function updateFileList(updateFn: (list: readonly UploadedFile[]) => readonly UploadedFile[]) {\n setUploadedFiles(updateFn);\n uploadedFilesListReference.current = updateFn(uploadedFilesListReference.current);\n }\n\n function addFileToList(recentUploadedFile: UploadedFile) {\n updateFileList((list) => [...list, recentUploadedFile]);\n }\n\n function removeFileFromList(file: UploadedFile) {\n updateFileList((list) =>\n list.filter((fileInList) => file !== fileInList && file.id !== fileInList.id),\n );\n fileRefs = fileRefs.filter((ref) => ref && ref.id !== file.id);\n }\n\n function modifyFileInList(file: UploadedFile, updates: Partial<UploadedFile>) {\n updateFileList((list) =>\n list.map((fileInList) =>\n fileInList === file || fileInList.id === file.id ? { ...file, ...updates } : fileInList,\n ),\n );\n }\n\n const removeFile = async (file: UploadedFile) => {\n const { id, status } = file;\n fileRefs = fileRefs.filter((item) => item && item.id !== file.id);\n\n if (status === Status.FAILED) {\n removeFileFromList(file);\n return Promise.resolve();\n }\n\n if (onDeleteFile && id) {\n modifyFileInList(file, { status: Status.PROCESSING, error: undefined });\n\n return onDeleteFile(id)\n .then(() => {\n removeFileFromList(file);\n })\n .catch((error) => {\n modifyFileInList(file, { error: error as UploadError });\n });\n }\n };\n\n function handleFileUploadFailure(file: File, failureMessage: string) {\n const { name } = file;\n\n const failedUpload = {\n id: generateFileId(file),\n filename: name,\n status: Status.FAILED,\n error: failureMessage,\n };\n\n addFileToList(failedUpload);\n\n if (onValidationError) {\n onValidationError(failedUpload);\n }\n }\n\n function getNumberOfFilesUploaded() {\n const uploadInitiatedStatus = new Set([Status.SUCCEEDED, Status.PENDING]);\n const validFiles = uploadedFilesListReference.current.filter(\n (file) => file.status && uploadInitiatedStatus.has(file.status),\n );\n return validFiles.length;\n }\n\n function areMaximumFilesUploadedAlready() {\n if (!maxFiles) {\n return false;\n }\n\n const numberOfValidFiles = getNumberOfFilesUploaded();\n return numberOfValidFiles >= maxFiles;\n }\n\n const addFiles = (selectedFiles: FileList) => {\n for (let i = 0; i < selectedFiles.length; i += 1) {\n const file = selectedFiles.item(i);\n\n const formData = new FormData();\n\n if (file) {\n const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');\n\n if (!isTypeValid(file, allowedFileTypes)) {\n handleFileUploadFailure(file, formatMessage(MESSAGES.fileTypeNotSupported));\n continue;\n }\n\n if (typeof sizeLimit === 'number' && !isSizeValid(file, sizeLimit * 1000)) {\n const failureMessage = sizeLimitErrorMessage || formatMessage(MESSAGES.fileIsTooLarge);\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n if (areMaximumFilesUploadedAlready()) {\n const failureMessage =\n maxFilesErrorMessage ||\n formatMessage(MESSAGES.maximumFilesAlreadyUploaded, { maxFilesAllowed: maxFiles });\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n const existingFile = uploadedFiles.find((f) => f.filename === file.name);\n if (existingFile) {\n removeFileFromList(existingFile);\n }\n\n formData.append(fileInputName, file);\n const pendingFile = {\n id: generateFileId(file),\n filename: file.name,\n status: Status.PENDING,\n };\n\n addFileToList(pendingFile);\n\n onUploadFile(formData)\n .then(({ id, url, error }: UploadResponse) => {\n modifyFileInList(pendingFile, { id, url, error, status: Status.SUCCEEDED });\n })\n .catch((error) => {\n modifyFileInList(pendingFile, { error: error as UploadError, status: Status.FAILED });\n });\n\n if (!multiple) {\n break;\n }\n }\n }\n };\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n if (onFilesChange && mounted) {\n onFilesChange([...uploadedFiles]);\n }\n }, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps\n\n type NextFocusable =\n | HTMLDivElement\n | UploadItemRef\n | { ref: HTMLDivElement | UploadItemRef; target: 'button' | 'link' }\n | null;\n\n const [nextFocusable, setNextFocusable] = useState<NextFocusable>(uploadInputRef.current);\n\n const handleFocus = (fileId: string | number) => {\n fileRefs = fileRefs.filter((ref) => {\n return ref && ref.id !== markedFileForDelete?.id;\n });\n\n const filesCount = fileRefs.length;\n let next: UploadItemRef | HTMLDivElement | null = uploadInputRef.current;\n let focusTarget: 'button' | 'link' = 'button';\n\n // If there will be no files left after deletion, focus the upload button\n if (filesCount === 1) {\n next = uploadInputRef.current;\n setNextFocusable(next);\n return;\n }\n\n if (filesCount > 1) {\n const currentFileIndex = fileRefs.findIndex((file) => file?.id === fileId);\n const currentFileId = fileRefs?.[currentFileIndex]?.id;\n const lastFileId = fileRefs?.[filesCount - 1]?.id;\n\n // if last file, select a previous one\n if (currentFileId === lastFileId) {\n next = fileRefs[filesCount - 2];\n } else {\n next = fileRefs[currentFileIndex + 1];\n }\n\n // If next is an UploadItemRef, check if it has a URL (succeeded)\n if (next && 'status' in next) {\n // Find the file object for this ref\n const fileObj = uploadedFiles.find((f) => f.id === next?.id);\n if (\n fileObj &&\n (fileObj.status === Status.SUCCEEDED || fileObj.status === Status.DONE) &&\n fileObj.url\n ) {\n focusTarget = 'link';\n }\n }\n setNextFocusable(() => {\n if (next && typeof (next as UploadItemRef).focus === 'function') {\n return { ref: next, target: focusTarget };\n }\n return next;\n });\n }\n };\n\n const handleRefocus = () => {\n const focusTarget = nextFocusable;\n if (lastAttemptedDeleteId) {\n setLastAttemptedDeleteId(null);\n return;\n }\n if (focusTarget) {\n // If there are no files left, focus the upload button\n if (\n uploadedFiles.length === 0 &&\n uploadInputRef.current &&\n typeof uploadInputRef.current.focus === 'function'\n ) {\n setTimeout(() => {\n uploadInputRef.current!.focus();\n }, 0);\n } else if (\n typeof focusTarget === 'object' &&\n 'ref' in focusTarget &&\n focusTarget.ref &&\n typeof focusTarget.ref.focus === 'function'\n ) {\n setTimeout(() => {\n if (focusTarget.ref && typeof (focusTarget.ref as UploadItemRef).focus === 'function') {\n // @ts-expect-error: focus may not exist on all possible ref types, but is safe here\n (focusTarget.ref as UploadItemRef).focus(focusTarget.target);\n }\n }, 0);\n } else if (focusTarget && typeof (focusTarget as UploadItemRef).focus === 'function') {\n setTimeout(() => {\n (focusTarget as UploadItemRef).focus();\n }, 0);\n }\n }\n };\n\n return (\n <>\n <div\n role=\"group\"\n className={clsx('np-upload-input', className, { disabled })}\n {...inputAttributes}\n >\n <div\n className=\"np-upload-input__section\"\n aria-live=\"polite\"\n aria-relevant=\"all\"\n role=\"region\"\n >\n {uploadedFiles.map((file, index) => (\n <UploadItem\n key={file.id}\n ref={(el: UploadItemRef | null) => {\n if (\n el &&\n el.id !== markedFileForDelete?.id &&\n !fileRefs.some((ref) => ref && ref.id === el.id) &&\n el.status !== 'processing'\n ) {\n fileRefs.push(el);\n }\n }}\n file={file}\n singleFileUpload={!multiple}\n canDelete={\n (!!onDeleteFile || file.status === Status.FAILED) &&\n (!file.status || !PROGRESS_STATUSES.has(file.status))\n }\n onDelete={\n file.status === Status.FAILED\n ? async () => {\n setLastAttemptedDeleteId(file.id);\n await removeFile(file);\n handleRefocus();\n }\n : () => {\n setLastAttemptedDeleteId(file.id);\n setMarkedFileForDelete(file);\n }\n }\n onDownload={onDownload}\n onFocus={() => handleFocus(file.id)}\n />\n ))}\n </div>\n {(multiple || (!multiple && !uploadedFiles.length)) && (\n <div className=\"np-upload-input__section np-upload-input__section--uploader\">\n <UploadButton\n ref={uploadInputRef}\n id={id}\n uploadButtonTitle={uploadButtonTitle}\n disabled={areMaximumFilesUploadedAlready() || disabled}\n multiple={multiple}\n fileTypes={fileTypes}\n sizeLimit={sizeLimit}\n description={description}\n maxFiles={maxFiles}\n withEntries={Boolean(uploadedFiles.length)}\n onChange={addFiles}\n />\n </div>\n )}\n </div>\n <Modal\n title={\n deleteConfirm?.title !== undefined\n ? deleteConfirm.title\n : formatMessage(MESSAGES.deleteModalTitle)\n }\n body={\n deleteConfirm?.body !== undefined\n ? deleteConfirm.body\n : formatMessage(MESSAGES.deleteModalBody)\n }\n open={!!markedFileForDelete}\n footer={\n <>\n <Button\n block\n onClick={() => {\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.cancelText || formatMessage(MESSAGES.deleteModalCancelButtonText)}\n </Button>\n <Button\n block\n priority={Priority.SECONDARY}\n type={ControlType.NEGATIVE}\n tabIndex={markedFileForDelete ? 0 : -1}\n onClick={() => {\n if (markedFileForDelete) {\n void removeFile(markedFileForDelete);\n }\n setMarkedFileForDelete(null);\n setLastAttemptedDeleteId(null);\n }}\n >\n {deleteConfirm?.confirmText || formatMessage(MESSAGES.deleteModalConfirmButtonText)}\n </Button>\n </>\n }\n onUnmount={handleRefocus}\n onClose={() => {\n setMarkedFileForDelete(null);\n }}\n />\n </>\n );\n};\n\nexport default UploadInput;\n"],"names":["generateFileId","file","name","size","uploadTimeStamp","Date","getTime","UploadInput","files","fileInputName","className","deleteConfirm","disabled","multiple","fileTypes","imageFileTypes","sizeLimit","DEFAULT_SIZE_LIMIT","description","onUploadFile","onDeleteFile","onValidationError","onFilesChange","onDownload","maxFiles","maxFilesErrorMessage","id","sizeLimitErrorMessage","uploadButtonTitle","inputAttributes","useInputAttributes","nonLabelable","markedFileForDelete","setMarkedFileForDelete","useState","lastAttemptedDeleteId","setLastAttemptedDeleteId","mounted","setMounted","formatMessage","useIntl","uploadInputRef","useRef","fileRefs","PROGRESS_STATUSES","Set","Status","PENDING","PROCESSING","uploadedFiles","setUploadedFiles","length","uploadedFilesListReference","updateFileList","updateFn","current","addFileToList","recentUploadedFile","list","removeFileFromList","filter","fileInList","ref","modifyFileInList","updates","map","removeFile","status","item","FAILED","Promise","resolve","error","undefined","then","catch","handleFileUploadFailure","failureMessage","failedUpload","filename","getNumberOfFilesUploaded","uploadInitiatedStatus","SUCCEEDED","validFiles","has","areMaximumFilesUploadedAlready","numberOfValidFiles","addFiles","selectedFiles","i","formData","FormData","allowedFileTypes","join","isTypeValid","MESSAGES","fileTypeNotSupported","isSizeValid","fileIsTooLarge","maximumFilesAlreadyUploaded","maxFilesAllowed","existingFile","find","f","append","pendingFile","url","useEffect","nextFocusable","setNextFocusable","handleFocus","fileId","filesCount","next","focusTarget","currentFileIndex","findIndex","currentFileId","lastFileId","fileObj","DONE","focus","target","handleRefocus","setTimeout","_jsxs","_Fragment","children","role","clsx","_jsx","index","UploadItem","el","some","push","singleFileUpload","canDelete","onDelete","onFocus","UploadButton","withEntries","Boolean","onChange","Modal","title","deleteModalTitle","body","deleteModalBody","open","footer","Button","block","onClick","cancelText","deleteModalCancelButtonText","priority","Priority","SECONDARY","type","ControlType","NEGATIVE","tabIndex","confirmText","deleteModalConfirmButtonText","onUnmount","onClose"],"mappings":"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"}
1
+ {"version":3,"file":"UploadInput.mjs","sources":["../../src/uploadInput/UploadInput.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useEffect, useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Button from '../button';\nimport { CommonProps, ControlType, Priority, Status } from '../common';\nimport { useInputAttributes } from '../inputs/contexts';\nimport Modal from '../modal';\nimport { isSizeValid } from '../upload/utils/isSizeValid';\nimport { isTypeValid } from '../upload/utils/isTypeValid';\n\nimport MESSAGES from './UploadInput.messages';\nimport { UploadedFile, UploadError, UploadResponse } from './types';\nimport UploadButton, { UploadButtonProps } from './uploadButton/UploadButton';\nimport { DEFAULT_SIZE_LIMIT, imageFileTypes } from './uploadButton/defaults';\nimport UploadItem, { UploadItemProps } from './uploadItem/UploadItem';\n\nexport type UploadInputProps = {\n /**\n * List of already existing, failed or in progress files\n * @default []\n */\n files?: readonly UploadedFile[];\n\n /**\n * The key of the file in the returned FormData object (default: file)\n * @default 'file'\n */\n fileInputName?: string;\n\n /**\n * Callback that handles form submission\n *\n * @param formData\n */\n onUploadFile: (formData: FormData) => Promise<UploadResponse>;\n\n /**\n * Provide a callback if the file can be removed/deleted from the server\n * Your app is responsible for reloading the uploaded files list and updating the component to ensure that the file has in fact been deleted successfully\n *\n * @param id\n */\n onDeleteFile?: (id: string | number) => Promise<any>;\n\n /**\n * Provide a callback to trigger on validation error\n *\n * @param file\n */\n onValidationError?: (file: UploadedFile) => void;\n\n /**\n * Provide a callback to trigger on change whenever the files are updated\n *\n * @param files\n */\n onFilesChange?: (files: UploadedFile[]) => void;\n\n /**\n * Confirmation modal displayed on delete\n */\n deleteConfirm?: {\n /**\n * The title of the confirmation modal on delete\n */\n title?: string;\n\n /**\n * The body of the confirmation modal on delete\n */\n body?: React.ReactNode;\n\n /**\n * The confirm button text of the confirmation modal on delete\n */\n confirmText?: string;\n\n /**\n * The cancel button text of the confirmation modal on delete\n */\n cancelText?: string;\n };\n\n /**\n * Maximum number of files allowed, if provided, shows error below file item\n */\n maxFiles?: number;\n\n /**\n * Error message to show when the maximum number of files are uploaded already\n */\n maxFilesErrorMessage?: string;\n\n /**\n * Error message to show when files over allowed size limit are uploaded\n */\n sizeLimitErrorMessage?: string;\n} & {\n /** @default false */\n multiple?: UploadButtonProps['multiple'];\n /** @default ['.pdf,application/pdf', '.jpg,.jpeg,image/jpeg', '.png,image/png'] */\n fileTypes?: UploadButtonProps['fileTypes'];\n /** @default 5000 */\n sizeLimit?: UploadButtonProps['sizeLimit'];\n} & Pick<UploadButtonProps, 'disabled' | 'description' | 'id' | 'uploadButtonTitle'> & {\n onDownload?: UploadItemProps['onDownload'];\n } & CommonProps;\n\n/**\n * Interface representing a reference to an UploadItem component.\n * Provides a method to focus the UploadItem.\n */\ninterface UploadItemRef {\n /**\n * Focuses the UploadItem component.\n */\n focus: () => void;\n\n /**\n * Required id of the UploadItem component.\n */\n id: string | number;\n\n /**\n * Optional status of the UploadItem component.\n */\n status?: string;\n}\n\n/**\n * Generates a unique ID for a file based on its name, size, and the current timestamp\n */\nfunction generateFileId(file: File) {\n const { name, size } = file;\n const uploadTimeStamp = new Date().getTime();\n return `${name}_${size}_${uploadTimeStamp}`;\n}\n\n/**\n * The component allows users to upload files, manage the list of uploaded files,\n * and handle file validation and deletion.\n *\n * @param {UploadInputProps} props - The properties for the UploadInput component.\n *\n * @see {@link UploadInput} for further information.\n * @see {@link https://storybook.wise.design/?path=/docs/forms-uploadinput--docs|Storybook Wise Design}\n */\nconst UploadInput = ({\n files = [],\n fileInputName = 'file',\n className,\n deleteConfirm,\n disabled,\n multiple = false,\n fileTypes = imageFileTypes,\n sizeLimit = DEFAULT_SIZE_LIMIT,\n description,\n onUploadFile,\n onDeleteFile,\n onValidationError,\n onFilesChange,\n onDownload,\n maxFiles,\n maxFilesErrorMessage,\n id,\n sizeLimitErrorMessage,\n uploadButtonTitle,\n}: UploadInputProps) => {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n const [markedFileForDelete, setMarkedFileForDelete] = useState<UploadedFile | null>(null);\n const [lastAttemptedDeleteId, setLastAttemptedDeleteId] = useState<string | number | null>(null);\n const [mounted, setMounted] = useState(false);\n const { formatMessage } = useIntl();\n const uploadInputRef = useRef<HTMLInputElement | null>(null);\n let fileRefs: (HTMLDivElement | UploadItemRef | null)[] = [];\n\n const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);\n\n const [uploadedFiles, setUploadedFiles] = useState<readonly UploadedFile[]>(\n multiple || files.length === 0 ? files : [files[0]],\n );\n\n const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);\n\n function updateFileList(updateFn: (list: readonly UploadedFile[]) => readonly UploadedFile[]) {\n setUploadedFiles(updateFn);\n uploadedFilesListReference.current = updateFn(uploadedFilesListReference.current);\n }\n\n function addFileToList(recentUploadedFile: UploadedFile) {\n updateFileList((list) => [...list, recentUploadedFile]);\n }\n\n function removeFileFromList(file: UploadedFile) {\n updateFileList((list) =>\n list.filter((fileInList) => file !== fileInList && file.id !== fileInList.id),\n );\n fileRefs = fileRefs.filter((ref) => ref && ref.id !== file.id);\n }\n\n function modifyFileInList(file: UploadedFile, updates: Partial<UploadedFile>) {\n updateFileList((list) =>\n list.map((fileInList) =>\n fileInList === file || fileInList.id === file.id ? { ...file, ...updates } : fileInList,\n ),\n );\n }\n\n const removeFile = async (file: UploadedFile) => {\n const { id, status } = file;\n fileRefs = fileRefs.filter((item) => item && item.id !== file.id);\n\n if (status === Status.FAILED) {\n removeFileFromList(file);\n return Promise.resolve();\n }\n\n if (onDeleteFile && id) {\n modifyFileInList(file, { status: Status.PROCESSING, error: undefined });\n\n return onDeleteFile(id)\n .then(() => {\n removeFileFromList(file);\n })\n .catch((error) => {\n modifyFileInList(file, { error: error as UploadError });\n });\n }\n };\n\n function handleFileUploadFailure(file: File, failureMessage: string) {\n const { name } = file;\n\n const failedUpload = {\n id: generateFileId(file),\n filename: name,\n status: Status.FAILED,\n error: failureMessage,\n };\n\n addFileToList(failedUpload);\n\n if (onValidationError) {\n onValidationError(failedUpload);\n }\n }\n\n function getNumberOfFilesUploaded() {\n const uploadInitiatedStatus = new Set([Status.SUCCEEDED, Status.PENDING]);\n const validFiles = uploadedFilesListReference.current.filter(\n (file) => file.status && uploadInitiatedStatus.has(file.status),\n );\n return validFiles.length;\n }\n\n function areMaximumFilesUploadedAlready() {\n if (!maxFiles) {\n return false;\n }\n\n const numberOfValidFiles = getNumberOfFilesUploaded();\n return numberOfValidFiles >= maxFiles;\n }\n\n const addFiles = (selectedFiles: FileList) => {\n for (let i = 0; i < selectedFiles.length; i += 1) {\n const file = selectedFiles.item(i);\n\n const formData = new FormData();\n\n if (file) {\n const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');\n\n if (!isTypeValid(file, allowedFileTypes)) {\n handleFileUploadFailure(file, formatMessage(MESSAGES.fileTypeNotSupported));\n continue;\n }\n\n if (typeof sizeLimit === 'number' && !isSizeValid(file, sizeLimit * 1000)) {\n const failureMessage = sizeLimitErrorMessage || formatMessage(MESSAGES.fileIsTooLarge);\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n if (areMaximumFilesUploadedAlready()) {\n const failureMessage =\n maxFilesErrorMessage ||\n formatMessage(MESSAGES.maximumFilesAlreadyUploaded, { maxFilesAllowed: maxFiles });\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n const existingFile = uploadedFiles.find((f) => f.filename === file.name);\n if (existingFile) {\n removeFileFromList(existingFile);\n }\n\n formData.append(fileInputName, file);\n const pendingFile = {\n id: generateFileId(file),\n filename: file.name,\n status: Status.PENDING,\n };\n\n addFileToList(pendingFile);\n\n onUploadFile(formData)\n .then(({ id, url, error }: UploadResponse) => {\n modifyFileInList(pendingFile, { id, url, error, status: Status.SUCCEEDED });\n })\n .catch((error) => {\n modifyFileInList(pendingFile, { error: error as UploadError, status: Status.FAILED });\n });\n\n if (!multiple) {\n break;\n }\n }\n }\n };\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n if (onFilesChange && mounted) {\n onFilesChange([...uploadedFiles]);\n }\n }, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps\n\n type NextFocusable =\n | HTMLDivElement\n | UploadItemRef\n | { ref: HTMLDivElement | UploadItemRef; target: 'button' | 'link' }\n | null;\n\n const [nextFocusable, setNextFocusable] = useState<NextFocusable>(uploadInputRef.current);\n\n const handleFocus = (fileId: string | number) => {\n fileRefs = fileRefs.filter((ref) => {\n return ref && ref.id !== markedFileForDelete?.id;\n });\n\n const filesCount = fileRefs.length;\n let next: UploadItemRef | HTMLDivElement | null = uploadInputRef.current;\n let focusTarget: 'button' | 'link' = 'button';\n\n // If there will be no files left after deletion, focus the upload button\n if (filesCount === 1) {\n next = uploadInputRef.current;\n setNextFocusable(next);\n return;\n }\n\n if (filesCount > 1) {\n const currentFileIndex = fileRefs.findIndex((file) => file?.id === fileId);\n const currentFileId = fileRefs?.[currentFileIndex]?.id;\n const lastFileId = fileRefs?.[filesCount - 1]?.id;\n\n // if last file, select a previous one\n if (currentFileId === lastFileId) {\n next = fileRefs[filesCount - 2];\n } else {\n next = fileRefs[currentFileIndex + 1];\n }\n\n // If next is an UploadItemRef, check if it has a URL (succeeded)\n if (next && 'status' in next) {\n // Find the file object for this ref\n const fileObj = uploadedFiles.find((f) => f.id === next?.id);\n if (\n fileObj &&\n (fileObj.status === Status.SUCCEEDED || fileObj.status === Status.DONE) &&\n fileObj.url\n ) {\n focusTarget = 'link';\n }\n }\n setNextFocusable(() => {\n if (next && typeof (next as UploadItemRef).focus === 'function') {\n return { ref: next, target: focusTarget };\n }\n return next;\n });\n }\n };\n\n const handleRefocus = () => {\n const focusTarget = nextFocusable;\n if (lastAttemptedDeleteId) {\n setLastAttemptedDeleteId(null);\n return;\n }\n if (focusTarget) {\n // If there are no files left, focus the upload button\n if (\n uploadedFiles.length === 0 &&\n uploadInputRef.current &&\n typeof uploadInputRef.current.focus === 'function'\n ) {\n setTimeout(() => {\n uploadInputRef.current!.focus();\n }, 0);\n } else if (\n typeof focusTarget === 'object' &&\n 'ref' in focusTarget &&\n focusTarget.ref &&\n typeof focusTarget.ref.focus === 'function'\n ) {\n setTimeout(() => {\n if (focusTarget.ref && typeof (focusTarget.ref as UploadItemRef).focus === 'function') {\n // @ts-expect-error: focus may not exist on all possible ref types, but is safe here\n (focusTarget.ref as UploadItemRef).focus(focusTarget.target);\n }\n }, 0);\n } else if (focusTarget && typeof (focusTarget as UploadItemRef).focus === 'function') {\n setTimeout(() => {\n (focusTarget as UploadItemRef).focus();\n }, 0);\n }\n }\n };\n\n return (\n <>\n <div\n role=\"group\"\n className={clsx('np-upload-input', className, { disabled })}\n {...inputAttributes}\n >\n <div\n className=\"np-upload-input__section\"\n aria-live=\"polite\"\n aria-relevant=\"all\"\n role=\"region\"\n >\n {uploadedFiles.map((file, index) => (\n <UploadItem\n key={file.id}\n ref={(el: UploadItemRef | null) => {\n if (\n el &&\n el.id !== markedFileForDelete?.id &&\n !fileRefs.some((ref) => ref && ref.id === el.id) &&\n el.status !== 'processing'\n ) {\n fileRefs.push(el);\n }\n }}\n file={file}\n singleFileUpload={!multiple}\n canDelete={\n (!!onDeleteFile || file.status === Status.FAILED) &&\n (!file.status || !PROGRESS_STATUSES.has(file.status))\n }\n onDelete={\n file.status === Status.FAILED\n ? async () => {\n setLastAttemptedDeleteId(file.id);\n await removeFile(file);\n handleRefocus();\n }\n : () => {\n setLastAttemptedDeleteId(file.id);\n setMarkedFileForDelete(file);\n }\n }\n onDownload={onDownload}\n onFocus={() => handleFocus(file.id)}\n />\n ))}\n </div>\n {(multiple || (!multiple && !uploadedFiles.length)) && (\n <div className=\"np-upload-input__section np-upload-input__section--uploader\">\n <UploadButton\n ref={uploadInputRef}\n id={id}\n uploadButtonTitle={uploadButtonTitle}\n disabled={areMaximumFilesUploadedAlready() || disabled}\n multiple={multiple}\n fileTypes={fileTypes}\n sizeLimit={sizeLimit}\n description={description}\n maxFiles={maxFiles}\n withEntries={Boolean(uploadedFiles.length)}\n onChange={addFiles}\n />\n </div>\n )}\n </div>\n <Modal\n title={\n deleteConfirm?.title !== undefined\n ? deleteConfirm.title\n : formatMessage(MESSAGES.deleteModalTitle)\n }\n body={\n deleteConfirm?.body !== undefined\n ? deleteConfirm.body\n : formatMessage(MESSAGES.deleteModalBody)\n }\n open={!!markedFileForDelete}\n footer={\n <>\n <Button\n block\n onClick={() => {\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.cancelText || formatMessage(MESSAGES.deleteModalCancelButtonText)}\n </Button>\n <Button\n block\n priority={Priority.SECONDARY}\n type={ControlType.NEGATIVE}\n tabIndex={markedFileForDelete ? 0 : -1}\n onClick={() => {\n if (markedFileForDelete) {\n void removeFile(markedFileForDelete);\n }\n setMarkedFileForDelete(null);\n setLastAttemptedDeleteId(null);\n }}\n >\n {deleteConfirm?.confirmText || formatMessage(MESSAGES.deleteModalConfirmButtonText)}\n </Button>\n </>\n }\n onUnmount={handleRefocus}\n onClose={() => {\n setMarkedFileForDelete(null);\n }}\n />\n </>\n );\n};\n\nexport default UploadInput;\n"],"names":["generateFileId","file","name","size","uploadTimeStamp","Date","getTime","UploadInput","files","fileInputName","className","deleteConfirm","disabled","multiple","fileTypes","imageFileTypes","sizeLimit","DEFAULT_SIZE_LIMIT","description","onUploadFile","onDeleteFile","onValidationError","onFilesChange","onDownload","maxFiles","maxFilesErrorMessage","id","sizeLimitErrorMessage","uploadButtonTitle","inputAttributes","useInputAttributes","nonLabelable","markedFileForDelete","setMarkedFileForDelete","useState","lastAttemptedDeleteId","setLastAttemptedDeleteId","mounted","setMounted","formatMessage","useIntl","uploadInputRef","useRef","fileRefs","PROGRESS_STATUSES","Set","Status","PENDING","PROCESSING","uploadedFiles","setUploadedFiles","length","uploadedFilesListReference","updateFileList","updateFn","current","addFileToList","recentUploadedFile","list","removeFileFromList","filter","fileInList","ref","modifyFileInList","updates","map","removeFile","status","item","FAILED","Promise","resolve","error","undefined","then","catch","handleFileUploadFailure","failureMessage","failedUpload","filename","getNumberOfFilesUploaded","uploadInitiatedStatus","SUCCEEDED","validFiles","has","areMaximumFilesUploadedAlready","numberOfValidFiles","addFiles","selectedFiles","i","formData","FormData","allowedFileTypes","join","isTypeValid","MESSAGES","fileTypeNotSupported","isSizeValid","fileIsTooLarge","maximumFilesAlreadyUploaded","maxFilesAllowed","existingFile","find","f","append","pendingFile","url","useEffect","nextFocusable","setNextFocusable","handleFocus","fileId","filesCount","next","focusTarget","currentFileIndex","findIndex","currentFileId","lastFileId","fileObj","DONE","focus","target","handleRefocus","setTimeout","_jsxs","_Fragment","children","role","clsx","_jsx","index","UploadItem","el","some","push","singleFileUpload","canDelete","onDelete","onFocus","UploadButton","withEntries","Boolean","onChange","Modal","title","deleteModalTitle","body","deleteModalBody","open","footer","Button","block","onClick","cancelText","deleteModalCancelButtonText","priority","Priority","SECONDARY","type","ControlType","NEGATIVE","tabIndex","confirmText","deleteModalConfirmButtonText","onUnmount","onClose"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transferwise/components",
3
- "version": "0.0.0-experimental-a18466a",
3
+ "version": "0.0.0-experimental-e789c10",
4
4
  "description": "Neptune React components",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -1,34 +1,52 @@
1
- .np-theme-personal .critical-comms .alert-warning {
2
- color: var(--color-contrast-overlay);
3
- background-color: var(--color-sentiment-negative);
1
+ .critical-comms {
2
+ border-radius: 16px;
3
+ border-radius: var(--radius-medium);
4
+ overflow: hidden;
4
5
  }
5
- .np-theme-personal .critical-comms .alert-warning .np-text-title-body {
6
- color: var(--color-contrast-overlay);
6
+ .critical-comms .alert {
7
+ background-color: var(--color-sentiment-background-surface);
8
+ color: var(--color-sentiment-content-primary);
9
+ margin-bottom: 0;
7
10
  }
8
- .np-theme-personal .critical-comms .status-circle.warning {
11
+ .critical-comms .alert .np-text-title-body {
12
+ color: var(--color-sentiment-content-primary);
13
+ }
14
+ .critical-comms .status-circle.negative {
9
15
  background-color: #ffffff;
10
16
  background-color: var(--color-background-screen);
11
17
  }
12
- .np-theme-personal .critical-comms .status-circle.warning .status-icon {
13
- color: var(--color-contrast-theme);
18
+ .critical-comms .status-circle.negative .status-icon {
19
+ color: #37517e;
20
+ color: var(--color-content-primary);
14
21
  }
15
- .np-theme-personal .critical-comms .alert__message .alert__action {
22
+ .critical-comms .alert__message .alert__action {
16
23
  margin-top: 16px;
17
24
  margin-top: var(--size-16);
18
25
  }
19
- .np-theme-personal .critical-comms .wds-Button {
20
- --Button-background: var(--color-contrast-overlay);
21
- --Button-background-hover: var(--color-sentiment-negative-secondary-hover);
22
- --Button-background-active: var(--color-sentiment-negative-secondary-active);
26
+ .critical-comms .wds-Button {
27
+ --Button-color: var(--color-content-primary);
28
+ --Button-color-hover: var(--color-content-primary);
29
+ --Button-color-active: var(--color-content-primary);
30
+ --Button-background: var(--color-background-screen);
31
+ --Button-background-hover: var(--color-sentiment-interactive-primary-hover);
32
+ --Button-background-active: var(--color-sentiment-interactive-primary-active);
33
+ }
34
+ .critical-comms .alert-warning .wds-Button {
35
+ --Button-background-hover: var(--color-sentiment-interactive-secondary-neutral-hover);
36
+ --Button-background-active: var(--color-sentiment-interactive-secondary-neutral-active);
23
37
  }
24
38
  @media (min-width: 768px) {
25
- .np-theme-personal .critical-comms .alert-warning .alert__message {
39
+ .critical-comms .alert-warning .alert__message,
40
+ .critical-comms .alert-negative .alert__message,
41
+ .critical-comms .alert-neutral .alert__message {
26
42
  flex-direction: row;
27
43
  justify-content: space-between;
28
44
  align-items: center;
29
45
  width: 100%;
30
46
  }
31
- .np-theme-personal .critical-comms .alert-warning .alert__message .alert__action {
47
+ .critical-comms .alert-warning .alert__message .alert__action,
48
+ .critical-comms .alert-negative .alert__message .alert__action,
49
+ .critical-comms .alert-neutral .alert__message .alert__action {
32
50
  margin-top: 0;
33
51
  margin-left: 16px;
34
52
  margin-left: var(--padding-small);
@@ -1,51 +1,61 @@
1
- .np-theme-personal {
2
- .critical-comms {
3
- .alert-warning {
4
- color: var(--color-contrast-overlay);
5
- background-color: var(--color-sentiment-negative);
6
-
7
- .np-text-title-body {
8
- color: var(--color-contrast-overlay);
9
- }
10
- }
1
+ .critical-comms {
2
+ border-radius: var(--radius-medium);
3
+ overflow: hidden;
11
4
 
12
- .status-circle.warning {
13
- background-color: var(--color-background-screen);
5
+ .alert {
6
+ background-color: var(--color-sentiment-background-surface);
7
+ color: var(--color-sentiment-content-primary);
8
+ margin-bottom: 0;
14
9
 
15
- .status-icon {
16
- color: var(--color-contrast-theme);
17
- }
10
+ .np-text-title-body {
11
+ color: var(--color-sentiment-content-primary);
18
12
  }
13
+ }
19
14
 
20
- .alert__message {
21
- .alert__action {
22
- margin-top: var(--size-16);
23
- }
15
+ .status-circle.negative {
16
+ background-color: var(--color-background-screen);
17
+
18
+ .status-icon {
19
+ color: var(--color-content-primary);
24
20
  }
21
+ }
25
22
 
26
- .wds-Button {
27
- --Button-background: var(--color-contrast-overlay);
28
- --Button-background-hover: var(--color-sentiment-negative-secondary-hover);
29
- --Button-background-active: var(--color-sentiment-negative-secondary-active);
23
+ .alert__message {
24
+ .alert__action {
25
+ margin-top: var(--size-16);
30
26
  }
31
27
  }
32
28
 
29
+ .wds-Button {
30
+ --Button-color: var(--color-content-primary);
31
+ --Button-color-hover: var(--color-content-primary);
32
+ --Button-color-active: var(--color-content-primary);
33
+
34
+ --Button-background: var(--color-background-screen);
35
+ --Button-background-hover: var(--color-sentiment-interactive-primary-hover);
36
+ --Button-background-active: var(--color-sentiment-interactive-primary-active);
37
+ }
38
+
39
+ .alert-warning .wds-Button {
40
+ --Button-background-hover: var(--color-sentiment-interactive-secondary-neutral-hover);
41
+ --Button-background-active: var(--color-sentiment-interactive-secondary-neutral-active);
42
+ }
33
43
 
34
44
  @media (--screen-md) {
35
- .critical-comms {
36
- .alert-warning {
37
- .alert__message {
38
- flex-direction: row;
39
- justify-content: space-between;
40
- align-items: center;
41
- width: 100%;
42
-
43
- .alert__action {
44
- margin-top: 0;
45
- margin-left: var(--padding-small);
46
- }
45
+ .alert-warning,
46
+ .alert-negative,
47
+ .alert-neutral {
48
+ .alert__message {
49
+ flex-direction: row;
50
+ justify-content: space-between;
51
+ align-items: center;
52
+ width: 100%;
53
+
54
+ .alert__action {
55
+ margin-top: 0;
56
+ margin-left: var(--padding-small);
47
57
  }
48
58
  }
49
59
  }
50
60
  }
51
- }
61
+ }
@@ -1,7 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react-webpack5';
2
-
3
2
  import CriticalCommsBanner from '.';
4
- import { withVariantConfig } from '../../.storybook/helpers';
5
3
 
6
4
  export default {
7
5
  component: CriticalCommsBanner,
@@ -18,21 +16,17 @@ export const Basic = {
18
16
  },
19
17
  };
20
18
 
21
- export const Variants: Story = {
19
+ export const Sentiments: Story = {
20
+ render: (args) => (
21
+ <>
22
+ <CriticalCommsBanner {...args} sentiment="negative" title="Your account is overdrawn" />
23
+ <CriticalCommsBanner {...args} sentiment="warning" title="Your account needs attention" />
24
+ <CriticalCommsBanner {...args} sentiment="neutral" title="Your transfer is being processed" />
25
+ </>
26
+ ),
22
27
  args: {
23
- title: 'Your account is overdrawn',
24
- subtitle: 'Add money within the next 30 days',
25
- action: { label: 'Take action', href: 'https://wise.com' },
26
- },
27
- ...withVariantConfig(['default', 'dark', 'rtl']),
28
- };
29
-
30
- export const Mobile: Story = {
31
- tags: ['!autodocs'],
32
- args: {
33
- title: 'Your account is overdrawn',
34
28
  subtitle: 'Add money within the next 30 days',
35
29
  action: { label: 'Take action', href: 'https://wise.com' },
30
+ className: 'm-b-1',
36
31
  },
37
- ...withVariantConfig(['default', 'dark', 'rtl', 'mobile']),
38
32
  };
@@ -0,0 +1,70 @@
1
+ import { Meta, StoryObj } from '@storybook/react-webpack5';
2
+
3
+ import CriticalCommsBanner from '.';
4
+ import { withVariantConfig } from '../../.storybook/helpers';
5
+
6
+ export default {
7
+ component: CriticalCommsBanner,
8
+ title: 'Prompts/CriticalCommsBanner/tests',
9
+ tags: ['!autodocs'],
10
+ } satisfies Meta<typeof CriticalCommsBanner>;
11
+
12
+ type Story = StoryObj<typeof CriticalCommsBanner>;
13
+
14
+ export const Sentiments: Story = {
15
+ render: (args) => (
16
+ <>
17
+ <CriticalCommsBanner {...args} sentiment="negative" />
18
+ <CriticalCommsBanner {...args} sentiment="warning" />
19
+ <CriticalCommsBanner {...args} sentiment="neutral" />
20
+ </>
21
+ ),
22
+ args: {
23
+ subtitle: 'Add money within the next 30 days',
24
+ action: { label: 'Take action', href: 'https://wise.com' },
25
+ className: 'm-b-1',
26
+ },
27
+ ...withVariantConfig([
28
+ 'default',
29
+ 'dark',
30
+ 'bright-green',
31
+ 'forest-green',
32
+ 'business',
33
+ 'business--forest-green',
34
+ 'business--bright-green',
35
+ ]),
36
+ };
37
+
38
+ export const RTL: Story = {
39
+ render: (args) => (
40
+ <>
41
+ <CriticalCommsBanner {...args} sentiment="negative" />
42
+ <CriticalCommsBanner {...args} sentiment="warning" />
43
+ <CriticalCommsBanner {...args} sentiment="neutral" />
44
+ </>
45
+ ),
46
+ args: {
47
+ subtitle: 'Add money within the next 30 days',
48
+ action: { label: 'Take action', href: 'https://wise.com' },
49
+ className: 'm-b-1',
50
+ },
51
+ ...withVariantConfig(['rtl']),
52
+ };
53
+
54
+ export const Mobile: Story = {
55
+ args: {
56
+ subtitle: 'Add money within the next 30 days',
57
+ action: { label: 'Take action', href: 'https://wise.com' },
58
+ className: 'm-b-1',
59
+ },
60
+ ...withVariantConfig(['mobile']),
61
+ };
62
+
63
+ export const Zoom: Story = {
64
+ args: {
65
+ subtitle: 'Add money within the next 30 days',
66
+ action: { label: 'Take action', href: 'https://wise.com' },
67
+ className: 'm-b-1',
68
+ },
69
+ ...withVariantConfig(['400%']),
70
+ };
@@ -0,0 +1,66 @@
1
+ import { render, screen, mockMatchMedia } from '../test-utils';
2
+
3
+ import CriticalCommsBanner from './CriticalCommsBanner';
4
+
5
+ mockMatchMedia();
6
+
7
+ describe('CriticalCommsBanner', () => {
8
+ const defaultProps = {
9
+ title: 'Test title',
10
+ subtitle: 'Test subtitle',
11
+ action: { label: 'Take action', href: 'https://wise.com' },
12
+ };
13
+
14
+ it('renders with default negative sentiment', () => {
15
+ render(<CriticalCommsBanner {...defaultProps} />);
16
+
17
+ expect(screen.getByText('Test title')).toBeInTheDocument();
18
+ expect(screen.getByText('Test subtitle')).toBeInTheDocument();
19
+ expect(screen.getByTestId('alert')).toHaveClass('alert-negative');
20
+ });
21
+
22
+ it('renders the action', () => {
23
+ render(<CriticalCommsBanner {...defaultProps} />);
24
+
25
+ expect(screen.getByText('Take action')).toBeInTheDocument();
26
+ });
27
+
28
+ describe('sentiment variants', () => {
29
+ it('renders negative sentiment with correct alert type and icon', () => {
30
+ render(<CriticalCommsBanner {...defaultProps} sentiment="negative" />);
31
+
32
+ expect(screen.getByTestId('alert')).toHaveClass('alert-negative');
33
+ // Custom icon replaces the default StatusIcon
34
+ expect(screen.queryByTestId('status-icon')).not.toBeInTheDocument();
35
+ });
36
+
37
+ it('renders warning sentiment with correct alert type and icon', () => {
38
+ render(<CriticalCommsBanner {...defaultProps} sentiment="warning" />);
39
+
40
+ expect(screen.getByTestId('alert')).toHaveClass('alert-warning');
41
+ expect(screen.queryByTestId('status-icon')).not.toBeInTheDocument();
42
+ });
43
+
44
+ it('renders neutral sentiment with correct alert type and icon', () => {
45
+ render(<CriticalCommsBanner {...defaultProps} sentiment="neutral" />);
46
+
47
+ expect(screen.getByTestId('alert')).toHaveClass('alert-neutral');
48
+ expect(screen.queryByTestId('status-icon')).not.toBeInTheDocument();
49
+ });
50
+ });
51
+
52
+ it('wraps content in SentimentSurface with elevated emphasis', () => {
53
+ render(<CriticalCommsBanner {...defaultProps} sentiment="warning" />);
54
+
55
+ const surface = screen.getByTestId('alert').closest('.critical-comms');
56
+ expect(surface).toHaveClass('wds-sentiment-surface');
57
+ expect(surface).toHaveClass('wds-sentiment-surface-warning-elevated');
58
+ });
59
+
60
+ it('applies className to the wrapper', () => {
61
+ render(<CriticalCommsBanner {...defaultProps} className="custom-class" />);
62
+
63
+ const surface = screen.getByTestId('alert').closest('.critical-comms');
64
+ expect(surface).toHaveClass('custom-class');
65
+ });
66
+ });
@@ -1,5 +1,16 @@
1
- import Alert from '../alert';
1
+ import { Alert as AlertIcon, ClockBorderless as ClockIcon } from '@transferwise/icons';
2
2
  import { clsx } from 'clsx';
3
+ import { PropsWithChildren } from 'react';
4
+
5
+ import Alert from '../alert';
6
+ import { Sentiment } from '../common';
7
+ import Circle, { CircleProps } from '../common/circle';
8
+ import SentimentSurface from '../sentimentSurface';
9
+
10
+ export type CriticalCommsBannerSentiment =
11
+ | `${Sentiment.WARNING}`
12
+ | `${Sentiment.NEGATIVE}`
13
+ | `${Sentiment.NEUTRAL}`;
3
14
 
4
15
  export type CriticalCommsBannerProps = {
5
16
  title: string;
@@ -9,20 +20,58 @@ export type CriticalCommsBannerProps = {
9
20
  href?: string;
10
21
  onClick?: () => void;
11
22
  };
23
+ sentiment?: CriticalCommsBannerSentiment;
12
24
  className?: string;
13
25
  };
14
26
 
15
- function CriticalCommsBanner({ title, subtitle, action, className }: CriticalCommsBannerProps) {
27
+ const makeSurface = (sentiment: CriticalCommsBannerSentiment) => {
28
+ const Surface = (props: PropsWithChildren<Pick<CircleProps, 'className'>>) => (
29
+ <SentimentSurface as="span" emphasis="elevated" sentiment={sentiment} {...props} />
30
+ );
31
+ Surface.displayName = `CriticalCommsSurface(${sentiment})`;
32
+ return Surface;
33
+ };
34
+
35
+ const iconBySentiment: Record<CriticalCommsBannerSentiment, React.ReactNode> = {
36
+ [Sentiment.NEGATIVE]: (
37
+ <Circle as={makeSurface(Sentiment.NEGATIVE)} size={32} className="status-circle negative">
38
+ <AlertIcon className="status-icon light" />
39
+ </Circle>
40
+ ),
41
+ [Sentiment.WARNING]: (
42
+ <Circle as={makeSurface(Sentiment.WARNING)} size={32} className="status-circle warning">
43
+ <AlertIcon className="status-icon dark" />
44
+ </Circle>
45
+ ),
46
+ [Sentiment.NEUTRAL]: (
47
+ <Circle as={makeSurface(Sentiment.NEUTRAL)} size={32} className="status-circle neutral">
48
+ <ClockIcon className="status-icon dark" />
49
+ </Circle>
50
+ ),
51
+ };
52
+
53
+ function CriticalCommsBanner({
54
+ title,
55
+ subtitle,
56
+ action,
57
+ sentiment = Sentiment.NEGATIVE,
58
+ className,
59
+ }: CriticalCommsBannerProps) {
16
60
  return (
17
- <div className={clsx('critical-comms', className)}>
61
+ <SentimentSurface
62
+ sentiment={sentiment}
63
+ emphasis="elevated"
64
+ className={clsx('critical-comms', className)}
65
+ >
18
66
  <Alert
19
67
  title={title}
20
68
  message={subtitle}
21
69
  action={{ onClick: action?.onClick, target: action?.href, text: action?.label }}
22
70
  className={className}
23
- type="warning"
71
+ type={sentiment}
72
+ icon={iconBySentiment[sentiment]}
24
73
  />
25
- </div>
74
+ </SentimentSurface>
26
75
  );
27
76
  }
28
77
 
@@ -1 +1,2 @@
1
1
  export { default } from './CriticalCommsBanner';
2
+ export type { CriticalCommsBannerProps } from './CriticalCommsBanner';
package/src/index.ts CHANGED
@@ -156,6 +156,7 @@ export { default as Option } from './common/Option';
156
156
  export { default as BottomSheet } from './common/bottomSheet';
157
157
  export { default as BaseCard } from './common/baseCard';
158
158
  export { default as CriticalCommsBanner } from './criticalBanner';
159
+ export type { CriticalCommsBannerProps } from './criticalBanner';
159
160
  export { default as DateInput } from './dateInput';
160
161
  export { default as DateLookup } from './dateLookup';
161
162
  export { default as Decision } from './decision';
@@ -181,7 +182,6 @@ export {
181
182
  SelectInput,
182
183
  SelectInputOptionContent,
183
184
  SelectInputTriggerButton,
184
- sortByRelevance,
185
185
  } from './inputs/SelectInput';
186
186
  export { TextArea } from './inputs/TextArea';
187
187
  export { default as InstructionsList } from './instructionsList';