@transferwise/components 46.155.0 → 46.156.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 (235) hide show
  1. package/build/AvatarLayout/AvatarLayout.js.map +1 -1
  2. package/build/AvatarLayout/AvatarLayout.mjs.map +1 -1
  3. package/build/AvatarView/AvatarView.js.map +1 -1
  4. package/build/AvatarView/AvatarView.mjs.map +1 -1
  5. package/build/AvatarView/Dot/Dot.js.map +1 -1
  6. package/build/AvatarView/Dot/Dot.mjs.map +1 -1
  7. package/build/Body/Body.js.map +1 -1
  8. package/build/Body/Body.mjs.map +1 -1
  9. package/build/Chips/Chip/Chip.js.map +1 -1
  10. package/build/Chips/Chip/Chip.mjs.map +1 -1
  11. package/build/DefinitionList/DefinitionList.js +2 -1
  12. package/build/DefinitionList/DefinitionList.js.map +1 -1
  13. package/build/DefinitionList/DefinitionList.mjs +2 -1
  14. package/build/DefinitionList/DefinitionList.mjs.map +1 -1
  15. package/build/Display/Display.js.map +1 -1
  16. package/build/Display/Display.mjs.map +1 -1
  17. package/build/ExpressiveMoneyInput/AmountInput/AmountInput.js +2 -2
  18. package/build/ExpressiveMoneyInput/AmountInput/AmountInput.js.map +1 -1
  19. package/build/ExpressiveMoneyInput/AmountInput/AmountInput.mjs +1 -1
  20. package/build/ExpressiveMoneyInput/AmountInput/AmountInput.mjs.map +1 -1
  21. package/build/ExpressiveMoneyInput/AnimatedNumber/AnimatedNumber.js +4 -4
  22. package/build/ExpressiveMoneyInput/AnimatedNumber/AnimatedNumber.js.map +1 -1
  23. package/build/ExpressiveMoneyInput/AnimatedNumber/AnimatedNumber.mjs +1 -1
  24. package/build/ExpressiveMoneyInput/AnimatedNumber/AnimatedNumber.mjs.map +1 -1
  25. package/build/ExpressiveMoneyInput/Chevron/Chevron.js +2 -2
  26. package/build/ExpressiveMoneyInput/Chevron/Chevron.js.map +1 -1
  27. package/build/ExpressiveMoneyInput/Chevron/Chevron.mjs +1 -1
  28. package/build/ExpressiveMoneyInput/Chevron/Chevron.mjs.map +1 -1
  29. package/build/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.js.map +1 -1
  30. package/build/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.mjs.map +1 -1
  31. package/build/ExpressiveMoneyInput/ExpressiveMoneyInput.js +3 -3
  32. package/build/ExpressiveMoneyInput/ExpressiveMoneyInput.js.map +1 -1
  33. package/build/ExpressiveMoneyInput/ExpressiveMoneyInput.mjs +1 -1
  34. package/build/ExpressiveMoneyInput/ExpressiveMoneyInput.mjs.map +1 -1
  35. package/build/ExpressiveMoneyInput/hooks/useInputStyle.js.map +1 -1
  36. package/build/ExpressiveMoneyInput/hooks/useInputStyle.mjs.map +1 -1
  37. package/build/IconButton/IconButton.js.map +1 -1
  38. package/build/IconButton/IconButton.mjs.map +1 -1
  39. package/build/Link/Link.js.map +1 -1
  40. package/build/Link/Link.mjs.map +1 -1
  41. package/build/Markup/Markup.js +138 -0
  42. package/build/Markup/Markup.js.map +1 -0
  43. package/build/Markup/Markup.mjs +133 -0
  44. package/build/Markup/Markup.mjs.map +1 -0
  45. package/build/Markup/constants.js +21 -0
  46. package/build/Markup/constants.js.map +1 -0
  47. package/build/Markup/constants.mjs +15 -0
  48. package/build/Markup/constants.mjs.map +1 -0
  49. package/build/Markup/utils/parseMarkup.js +263 -0
  50. package/build/Markup/utils/parseMarkup.js.map +1 -0
  51. package/build/Markup/utils/parseMarkup.mjs +258 -0
  52. package/build/Markup/utils/parseMarkup.mjs.map +1 -0
  53. package/build/Markup/utils/sanitise.js +111 -0
  54. package/build/Markup/utils/sanitise.js.map +1 -0
  55. package/build/Markup/utils/sanitise.mjs +108 -0
  56. package/build/Markup/utils/sanitise.mjs.map +1 -0
  57. package/build/Nudge/Nudge.js +11 -2
  58. package/build/Nudge/Nudge.js.map +1 -1
  59. package/build/Nudge/Nudge.mjs +12 -3
  60. package/build/Nudge/Nudge.mjs.map +1 -1
  61. package/build/Sticky/Sticky.js +1 -0
  62. package/build/Sticky/Sticky.js.map +1 -1
  63. package/build/Sticky/Sticky.mjs +1 -0
  64. package/build/Sticky/Sticky.mjs.map +1 -1
  65. package/build/Title/Title.js +1 -0
  66. package/build/Title/Title.js.map +1 -1
  67. package/build/Title/Title.mjs +1 -0
  68. package/build/Title/Title.mjs.map +1 -1
  69. package/build/_deprecated/Select/Option/Option.js.map +1 -1
  70. package/build/_deprecated/Select/Option/Option.mjs.map +1 -1
  71. package/build/_deprecated/Select/SearchBox/SearchBox.js.map +1 -1
  72. package/build/_deprecated/Select/SearchBox/SearchBox.mjs.map +1 -1
  73. package/build/common/Circle/Circle.js.map +1 -1
  74. package/build/common/Circle/Circle.mjs.map +1 -1
  75. package/build/i18n/hu.json +1 -1
  76. package/build/i18n/hu.json.js +1 -1
  77. package/build/i18n/hu.json.mjs +1 -1
  78. package/build/index.js +2 -0
  79. package/build/index.js.map +1 -1
  80. package/build/index.mjs +1 -0
  81. package/build/index.mjs.map +1 -1
  82. package/build/main.css +71 -1
  83. package/build/styles/DefinitionList/DefinitionList.css +30 -0
  84. package/build/styles/Markup/Markup.css +28 -0
  85. package/build/styles/Markup/_stories/Vulnerability/Vulnerability.css +69 -0
  86. package/build/styles/Nudge/Nudge.css +1 -1
  87. package/build/styles/Sticky/Sticky.css +4 -0
  88. package/build/styles/main.css +71 -1
  89. package/build/types/AvatarLayout/AvatarLayout.d.ts +2 -2
  90. package/build/types/AvatarLayout/AvatarLayout.d.ts.map +1 -1
  91. package/build/types/AvatarLayout/index.d.ts +1 -1
  92. package/build/types/AvatarLayout/index.d.ts.map +1 -1
  93. package/build/types/AvatarView/AvatarView.d.ts +2 -2
  94. package/build/types/AvatarView/AvatarView.d.ts.map +1 -1
  95. package/build/types/AvatarView/Dot/Dot.d.ts +1 -1
  96. package/build/types/AvatarView/Dot/Dot.d.ts.map +1 -1
  97. package/build/types/AvatarView/index.d.ts +1 -1
  98. package/build/types/AvatarView/index.d.ts.map +1 -1
  99. package/build/types/Body/Body.d.ts +13 -2
  100. package/build/types/Body/Body.d.ts.map +1 -1
  101. package/build/types/Body/index.d.ts +1 -0
  102. package/build/types/Body/index.d.ts.map +1 -1
  103. package/build/types/Chips/Chip/Chip.d.ts +2 -2
  104. package/build/types/Chips/Chip/Chip.d.ts.map +1 -1
  105. package/build/types/Chips/index.d.ts +1 -1
  106. package/build/types/Chips/index.d.ts.map +1 -1
  107. package/build/types/DefinitionList/DefinitionList.d.ts.map +1 -1
  108. package/build/types/Display/Display.d.ts +2 -2
  109. package/build/types/Display/Display.d.ts.map +1 -1
  110. package/build/types/Display/index.d.ts +1 -0
  111. package/build/types/Display/index.d.ts.map +1 -1
  112. package/build/types/ExpressiveMoneyInput/AmountInput/AmountInput.d.ts +3 -3
  113. package/build/types/ExpressiveMoneyInput/AmountInput/AmountInput.d.ts.map +1 -1
  114. package/build/types/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.d.ts +3 -3
  115. package/build/types/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.d.ts.map +1 -1
  116. package/build/types/ExpressiveMoneyInput/ExpressiveMoneyInput.d.ts +4 -4
  117. package/build/types/ExpressiveMoneyInput/ExpressiveMoneyInput.d.ts.map +1 -1
  118. package/build/types/ExpressiveMoneyInput/hooks/useInputStyle.d.ts +1 -1
  119. package/build/types/ExpressiveMoneyInput/hooks/useInputStyle.d.ts.map +1 -1
  120. package/build/types/ExpressiveMoneyInput/index.d.ts +1 -1
  121. package/build/types/ExpressiveMoneyInput/index.d.ts.map +1 -1
  122. package/build/types/IconButton/IconButton.d.ts +2 -2
  123. package/build/types/IconButton/IconButton.d.ts.map +1 -1
  124. package/build/types/IconButton/index.d.ts +1 -1
  125. package/build/types/IconButton/index.d.ts.map +1 -1
  126. package/build/types/Link/Link.d.ts +2 -2
  127. package/build/types/Link/Link.d.ts.map +1 -1
  128. package/build/types/Link/index.d.ts +1 -1
  129. package/build/types/Link/index.d.ts.map +1 -1
  130. package/build/types/Markup/Markup.d.ts +18 -0
  131. package/build/types/Markup/Markup.d.ts.map +1 -0
  132. package/build/types/Markup/Markup.types.d.ts +77 -0
  133. package/build/types/Markup/Markup.types.d.ts.map +1 -0
  134. package/build/types/Markup/_stories/Vulnerability/Vulnerability.d.ts +12 -0
  135. package/build/types/Markup/_stories/Vulnerability/Vulnerability.d.ts.map +1 -0
  136. package/build/types/Markup/constants.d.ts +6 -0
  137. package/build/types/Markup/constants.d.ts.map +1 -0
  138. package/build/types/Markup/index.d.ts +3 -0
  139. package/build/types/Markup/index.d.ts.map +1 -0
  140. package/build/types/Markup/utils/parseMarkup.d.ts +8 -0
  141. package/build/types/Markup/utils/parseMarkup.d.ts.map +1 -0
  142. package/build/types/Markup/utils/sanitise.d.ts +4 -0
  143. package/build/types/Markup/utils/sanitise.d.ts.map +1 -0
  144. package/build/types/MoneyInput/MoneyInput.d.ts +1 -1
  145. package/build/types/MoneyInput/MoneyInput.d.ts.map +1 -1
  146. package/build/types/Nudge/Nudge.d.ts +28 -5
  147. package/build/types/Nudge/Nudge.d.ts.map +1 -1
  148. package/build/types/Nudge/index.d.ts +1 -1
  149. package/build/types/Nudge/index.d.ts.map +1 -1
  150. package/build/types/Sticky/Sticky.d.ts.map +1 -1
  151. package/build/types/Title/Title.d.ts +13 -3
  152. package/build/types/Title/Title.d.ts.map +1 -1
  153. package/build/types/Title/index.d.ts +1 -0
  154. package/build/types/Title/index.d.ts.map +1 -1
  155. package/build/types/Upload/Steps/UploadImageStep/UploadImageStep.d.ts +1 -1
  156. package/build/types/UploadInput/UploadItem/UploadItemLink.d.ts +1 -1
  157. package/build/types/_deprecated/Select/Option/Option.d.ts +2 -2
  158. package/build/types/_deprecated/Select/Option/Option.d.ts.map +1 -1
  159. package/build/types/common/Circle/Circle.d.ts +1 -1
  160. package/build/types/common/Circle/Circle.d.ts.map +1 -1
  161. package/build/types/common/Circle/index.d.ts +1 -1
  162. package/build/types/common/Circle/index.d.ts.map +1 -1
  163. package/build/types/index.d.ts +6 -0
  164. package/build/types/index.d.ts.map +1 -1
  165. package/package.json +3 -3
  166. package/src/AvatarLayout/AvatarLayout.tsx +3 -3
  167. package/src/AvatarLayout/index.ts +1 -1
  168. package/src/AvatarView/AvatarView.tsx +4 -4
  169. package/src/AvatarView/Dot/Dot.tsx +1 -1
  170. package/src/AvatarView/index.ts +1 -1
  171. package/src/Body/Body.tsx +2 -2
  172. package/src/Body/index.ts +1 -0
  173. package/src/Chips/Chip/Chip.tsx +2 -2
  174. package/src/Chips/index.ts +1 -1
  175. package/src/DefinitionList/DefinitionList.css +30 -0
  176. package/src/DefinitionList/DefinitionList.less +24 -0
  177. package/src/DefinitionList/DefinitionList.tsx +1 -0
  178. package/src/DefinitionList/_stories/DefinitionList.test.story.tsx +168 -0
  179. package/src/Display/Display.tsx +2 -2
  180. package/src/Display/index.ts +1 -0
  181. package/src/Drawer/Drawer.test.tsx +2 -3
  182. package/src/ExpressiveMoneyInput/AmountInput/AmountInput.tsx +4 -4
  183. package/src/ExpressiveMoneyInput/AnimatedNumber/AnimatedNumber.tsx +1 -1
  184. package/src/ExpressiveMoneyInput/Chevron/Chevron.tsx +1 -1
  185. package/src/ExpressiveMoneyInput/CurrencySelector/CurrencySelector.tsx +3 -3
  186. package/src/ExpressiveMoneyInput/ExpressiveMoneyInput.test.tsx +1 -1
  187. package/src/ExpressiveMoneyInput/ExpressiveMoneyInput.tsx +5 -8
  188. package/src/ExpressiveMoneyInput/_stories/ExpressiveMoneyInput.story.tsx +1 -1
  189. package/src/ExpressiveMoneyInput/_stories/ExpressiveMoneyInput.test.story.tsx +1 -1
  190. package/src/ExpressiveMoneyInput/hooks/useInputStyle.ts +1 -1
  191. package/src/ExpressiveMoneyInput/index.ts +1 -1
  192. package/src/IconButton/IconButton.tsx +2 -2
  193. package/src/IconButton/_stories/IconButton.story.tsx +8 -8
  194. package/src/IconButton/index.ts +1 -1
  195. package/src/Link/Link.tsx +2 -2
  196. package/src/Link/index.ts +1 -1
  197. package/src/Markup/Markup.css +28 -0
  198. package/src/Markup/Markup.injection.test.tsx +163 -0
  199. package/src/Markup/Markup.less +29 -0
  200. package/src/Markup/Markup.test.tsx +502 -0
  201. package/src/Markup/Markup.tsx +175 -0
  202. package/src/Markup/Markup.types.ts +62 -0
  203. package/src/Markup/_stories/Markup.docs.mdx +75 -0
  204. package/src/Markup/_stories/Markup.security.docs.mdx +343 -0
  205. package/src/Markup/_stories/Markup.story.tsx +266 -0
  206. package/src/Markup/_stories/Vulnerability/Vulnerability.css +69 -0
  207. package/src/Markup/_stories/Vulnerability/Vulnerability.tsx +30 -0
  208. package/src/Markup/constants.ts +23 -0
  209. package/src/Markup/index.ts +2 -0
  210. package/src/Markup/utils/parseMarkup.test.ts +706 -0
  211. package/src/Markup/utils/parseMarkup.ts +265 -0
  212. package/src/Markup/utils/sanitise.test.ts +499 -0
  213. package/src/Markup/utils/sanitise.ts +129 -0
  214. package/src/Nudge/Nudge.css +1 -1
  215. package/src/Nudge/Nudge.less +1 -1
  216. package/src/Nudge/Nudge.test.tsx +43 -0
  217. package/src/Nudge/Nudge.tsx +43 -8
  218. package/src/Nudge/index.ts +1 -1
  219. package/src/Sticky/Sticky.css +4 -0
  220. package/src/Sticky/Sticky.less +6 -0
  221. package/src/Sticky/Sticky.test.tsx +1 -0
  222. package/src/Sticky/Sticky.tsx +1 -0
  223. package/src/Sticky/_stories/Sticky.test.story.tsx +177 -0
  224. package/src/Title/Title.tsx +25 -20
  225. package/src/Title/index.ts +1 -0
  226. package/src/_deprecated/LegacyListItem/_stories/LegacyListItem.story.tsx +2 -3
  227. package/src/_deprecated/Select/Option/Option.test.tsx +1 -1
  228. package/src/_deprecated/Select/Option/Option.tsx +2 -2
  229. package/src/_deprecated/Select/SearchBox/SearchBox.tsx +2 -2
  230. package/src/common/Circle/Circle.tsx +2 -2
  231. package/src/common/Circle/index.ts +1 -1
  232. package/src/i18n/hu.json +1 -1
  233. package/src/index.ts +6 -0
  234. package/src/main.css +71 -1
  235. package/src/main.less +2 -0
@@ -0,0 +1,111 @@
1
+ 'use strict';
2
+
3
+ var constants = require('../constants.js');
4
+
5
+ const INVISIBLE_CHARS = /[\u200b\u200c\u200d\ufeff\u00ad\u2060\u180e]/g;
6
+ // eslint-disable-next-line regexp/no-control-character
7
+ const CONTROL_CHARS = /[\u0000-\u001f\u007f-\u009f]/;
8
+ const DANGEROUS_SCHEME = /^(?:javascript|vbscript|data|jscript)\s*:/i;
9
+ // eslint-disable-next-line regexp/no-useless-non-capturing-group
10
+ const ENCODED_COLON_SCHEME = /^(?:javascript|vbscript|data|jscript)(?:%3a)/i;
11
+ const IPV6_BRACKETS = /^\[|\]$/g;
12
+ const NUMERIC_IP = /^[\d.]+$/;
13
+ const HEX_IP = /^0x[0-9a-f]+$/i;
14
+ function sanitiseHref(href) {
15
+ const cleaned = href.replace(INVISIBLE_CHARS, '');
16
+ const trimmed = cleaned.trim();
17
+ if (!trimmed) {
18
+ return undefined;
19
+ }
20
+ if (CONTROL_CHARS.test(trimmed)) {
21
+ return undefined;
22
+ }
23
+ if (DANGEROUS_SCHEME.test(trimmed)) {
24
+ return undefined;
25
+ }
26
+ if (ENCODED_COLON_SCHEME.test(trimmed)) {
27
+ return undefined;
28
+ }
29
+ if (trimmed.startsWith('//')) {
30
+ return undefined;
31
+ }
32
+ if (trimmed.startsWith('\\')) {
33
+ return undefined;
34
+ }
35
+ if (trimmed.startsWith('/')) {
36
+ return trimmed[1] !== '\\' ? trimmed : undefined;
37
+ }
38
+ if (trimmed.startsWith('#')) {
39
+ return trimmed;
40
+ }
41
+ if (trimmed.startsWith('./') || trimmed.startsWith('../')) {
42
+ return undefined;
43
+ }
44
+ try {
45
+ const url = new URL(trimmed);
46
+ if (!constants.ALLOWED_PROTOCOLS.includes(url.protocol)) {
47
+ return undefined;
48
+ }
49
+ if (url.protocol === 'https:') {
50
+ if (!trimmed.startsWith('https://')) {
51
+ return undefined;
52
+ }
53
+ if (!url.hostname) {
54
+ return undefined;
55
+ }
56
+ if (url.username || url.password) {
57
+ return undefined;
58
+ }
59
+ if (isInternalHost(url.hostname)) {
60
+ return undefined;
61
+ }
62
+ }
63
+ if (url.protocol === 'mailto:') {
64
+ if (url.search) {
65
+ return undefined;
66
+ }
67
+ if (!url.pathname) {
68
+ return undefined;
69
+ }
70
+ }
71
+ return trimmed;
72
+ } catch {
73
+ return undefined;
74
+ }
75
+ }
76
+ // Synthetic origin used to resolve relative paths via the WHATWG URL parser.
77
+ // If the resolved origin still equals this sentinel, the path stays on-origin.
78
+ const SSR_SENTINEL_ORIGIN = 'https://internal.invalid';
79
+ function isHrefAllowedByMode(href, mode) {
80
+ switch (mode) {
81
+ case 'none':
82
+ return false;
83
+ case 'all':
84
+ return true;
85
+ case 'internal':
86
+ try {
87
+ if (!href.startsWith('/')) {
88
+ const parsed = new URL(href);
89
+ return parsed.protocol === 'https:' && parsed.hostname === 'wise.com';
90
+ }
91
+ const parsed = new URL(href, SSR_SENTINEL_ORIGIN);
92
+ return parsed.origin === SSR_SENTINEL_ORIGIN;
93
+ } catch {
94
+ return false;
95
+ }
96
+ }
97
+ }
98
+ function isInternalHost(hostname) {
99
+ const stripped = hostname.replace(IPV6_BRACKETS, '');
100
+ const host = stripped.endsWith('.') ? stripped.slice(0, -1) : stripped;
101
+ if (NUMERIC_IP.test(host)) return true;
102
+ if (HEX_IP.test(host)) return true;
103
+ if (host === '::1' || host === '0:0:0:0:0:0:0:1') return true;
104
+ if (host === 'localhost') return true;
105
+ if (host.endsWith('.internal')) return true;
106
+ return false;
107
+ }
108
+
109
+ exports.isHrefAllowedByMode = isHrefAllowedByMode;
110
+ exports.sanitiseHref = sanitiseHref;
111
+ //# sourceMappingURL=sanitise.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitise.js","sources":["../../../src/Markup/utils/sanitise.ts"],"sourcesContent":["import { ALLOWED_PROTOCOLS } from '../constants';\n\nconst INVISIBLE_CHARS = /[\\u200b\\u200c\\u200d\\ufeff\\u00ad\\u2060\\u180e]/g;\n// eslint-disable-next-line regexp/no-control-character\nconst CONTROL_CHARS = /[\\u0000-\\u001f\\u007f-\\u009f]/;\nconst DANGEROUS_SCHEME = /^(?:javascript|vbscript|data|jscript)\\s*:/i;\n// eslint-disable-next-line regexp/no-useless-non-capturing-group\nconst ENCODED_COLON_SCHEME = /^(?:javascript|vbscript|data|jscript)(?:%3a)/i;\nconst IPV6_BRACKETS = /^\\[|\\]$/g;\nconst NUMERIC_IP = /^[\\d.]+$/;\nconst HEX_IP = /^0x[0-9a-f]+$/i;\n\nexport function sanitiseHref(href: string): string | undefined {\n const cleaned = href.replace(INVISIBLE_CHARS, '');\n const trimmed = cleaned.trim();\n\n if (!trimmed) {\n return undefined;\n }\n\n if (CONTROL_CHARS.test(trimmed)) {\n return undefined;\n }\n\n if (DANGEROUS_SCHEME.test(trimmed)) {\n return undefined;\n }\n\n if (ENCODED_COLON_SCHEME.test(trimmed)) {\n return undefined;\n }\n\n if (trimmed.startsWith('//')) {\n return undefined;\n }\n\n if (trimmed.startsWith('\\\\')) {\n return undefined;\n }\n\n if (trimmed.startsWith('/')) {\n return trimmed[1] !== '\\\\' ? trimmed : undefined;\n }\n\n if (trimmed.startsWith('#')) {\n return trimmed;\n }\n\n if (trimmed.startsWith('./') || trimmed.startsWith('../')) {\n return undefined;\n }\n\n try {\n const url = new URL(trimmed);\n\n if (!ALLOWED_PROTOCOLS.includes(url.protocol)) {\n return undefined;\n }\n\n if (url.protocol === 'https:') {\n if (!trimmed.startsWith('https://')) {\n return undefined;\n }\n\n if (!url.hostname) {\n return undefined;\n }\n\n if (url.username || url.password) {\n return undefined;\n }\n\n if (isInternalHost(url.hostname)) {\n return undefined;\n }\n }\n\n if (url.protocol === 'mailto:') {\n if (url.search) {\n return undefined;\n }\n\n if (!url.pathname) {\n return undefined;\n }\n }\n\n return trimmed;\n } catch {\n return undefined;\n }\n}\n\nexport type AllowLinksMode = 'internal' | 'all' | 'none';\n\n// Synthetic origin used to resolve relative paths via the WHATWG URL parser.\n// If the resolved origin still equals this sentinel, the path stays on-origin.\nconst SSR_SENTINEL_ORIGIN = 'https://internal.invalid';\n\nexport function isHrefAllowedByMode(href: string, mode: AllowLinksMode): boolean {\n switch (mode) {\n case 'none':\n return false;\n case 'all':\n return true;\n case 'internal':\n try {\n if (!href.startsWith('/')) {\n const parsed = new URL(href);\n return parsed.protocol === 'https:' && parsed.hostname === 'wise.com';\n }\n const parsed = new URL(href, SSR_SENTINEL_ORIGIN);\n return parsed.origin === SSR_SENTINEL_ORIGIN;\n } catch {\n return false;\n }\n }\n}\n\nfunction isInternalHost(hostname: string): boolean {\n const stripped = hostname.replace(IPV6_BRACKETS, '');\n const host = stripped.endsWith('.') ? stripped.slice(0, -1) : stripped;\n if (NUMERIC_IP.test(host)) return true;\n if (HEX_IP.test(host)) return true;\n if (host === '::1' || host === '0:0:0:0:0:0:0:1') return true;\n if (host === 'localhost') return true;\n if (host.endsWith('.internal')) return true;\n return false;\n}\n"],"names":["INVISIBLE_CHARS","CONTROL_CHARS","DANGEROUS_SCHEME","ENCODED_COLON_SCHEME","IPV6_BRACKETS","NUMERIC_IP","HEX_IP","sanitiseHref","href","cleaned","replace","trimmed","trim","undefined","test","startsWith","url","URL","ALLOWED_PROTOCOLS","includes","protocol","hostname","username","password","isInternalHost","search","pathname","SSR_SENTINEL_ORIGIN","isHrefAllowedByMode","mode","parsed","origin","stripped","host","endsWith","slice"],"mappings":"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"}
@@ -0,0 +1,108 @@
1
+ import { ALLOWED_PROTOCOLS } from '../constants.mjs';
2
+
3
+ const INVISIBLE_CHARS = /[\u200b\u200c\u200d\ufeff\u00ad\u2060\u180e]/g;
4
+ // eslint-disable-next-line regexp/no-control-character
5
+ const CONTROL_CHARS = /[\u0000-\u001f\u007f-\u009f]/;
6
+ const DANGEROUS_SCHEME = /^(?:javascript|vbscript|data|jscript)\s*:/i;
7
+ // eslint-disable-next-line regexp/no-useless-non-capturing-group
8
+ const ENCODED_COLON_SCHEME = /^(?:javascript|vbscript|data|jscript)(?:%3a)/i;
9
+ const IPV6_BRACKETS = /^\[|\]$/g;
10
+ const NUMERIC_IP = /^[\d.]+$/;
11
+ const HEX_IP = /^0x[0-9a-f]+$/i;
12
+ function sanitiseHref(href) {
13
+ const cleaned = href.replace(INVISIBLE_CHARS, '');
14
+ const trimmed = cleaned.trim();
15
+ if (!trimmed) {
16
+ return undefined;
17
+ }
18
+ if (CONTROL_CHARS.test(trimmed)) {
19
+ return undefined;
20
+ }
21
+ if (DANGEROUS_SCHEME.test(trimmed)) {
22
+ return undefined;
23
+ }
24
+ if (ENCODED_COLON_SCHEME.test(trimmed)) {
25
+ return undefined;
26
+ }
27
+ if (trimmed.startsWith('//')) {
28
+ return undefined;
29
+ }
30
+ if (trimmed.startsWith('\\')) {
31
+ return undefined;
32
+ }
33
+ if (trimmed.startsWith('/')) {
34
+ return trimmed[1] !== '\\' ? trimmed : undefined;
35
+ }
36
+ if (trimmed.startsWith('#')) {
37
+ return trimmed;
38
+ }
39
+ if (trimmed.startsWith('./') || trimmed.startsWith('../')) {
40
+ return undefined;
41
+ }
42
+ try {
43
+ const url = new URL(trimmed);
44
+ if (!ALLOWED_PROTOCOLS.includes(url.protocol)) {
45
+ return undefined;
46
+ }
47
+ if (url.protocol === 'https:') {
48
+ if (!trimmed.startsWith('https://')) {
49
+ return undefined;
50
+ }
51
+ if (!url.hostname) {
52
+ return undefined;
53
+ }
54
+ if (url.username || url.password) {
55
+ return undefined;
56
+ }
57
+ if (isInternalHost(url.hostname)) {
58
+ return undefined;
59
+ }
60
+ }
61
+ if (url.protocol === 'mailto:') {
62
+ if (url.search) {
63
+ return undefined;
64
+ }
65
+ if (!url.pathname) {
66
+ return undefined;
67
+ }
68
+ }
69
+ return trimmed;
70
+ } catch {
71
+ return undefined;
72
+ }
73
+ }
74
+ // Synthetic origin used to resolve relative paths via the WHATWG URL parser.
75
+ // If the resolved origin still equals this sentinel, the path stays on-origin.
76
+ const SSR_SENTINEL_ORIGIN = 'https://internal.invalid';
77
+ function isHrefAllowedByMode(href, mode) {
78
+ switch (mode) {
79
+ case 'none':
80
+ return false;
81
+ case 'all':
82
+ return true;
83
+ case 'internal':
84
+ try {
85
+ if (!href.startsWith('/')) {
86
+ const parsed = new URL(href);
87
+ return parsed.protocol === 'https:' && parsed.hostname === 'wise.com';
88
+ }
89
+ const parsed = new URL(href, SSR_SENTINEL_ORIGIN);
90
+ return parsed.origin === SSR_SENTINEL_ORIGIN;
91
+ } catch {
92
+ return false;
93
+ }
94
+ }
95
+ }
96
+ function isInternalHost(hostname) {
97
+ const stripped = hostname.replace(IPV6_BRACKETS, '');
98
+ const host = stripped.endsWith('.') ? stripped.slice(0, -1) : stripped;
99
+ if (NUMERIC_IP.test(host)) return true;
100
+ if (HEX_IP.test(host)) return true;
101
+ if (host === '::1' || host === '0:0:0:0:0:0:0:1') return true;
102
+ if (host === 'localhost') return true;
103
+ if (host.endsWith('.internal')) return true;
104
+ return false;
105
+ }
106
+
107
+ export { isHrefAllowedByMode, sanitiseHref };
108
+ //# sourceMappingURL=sanitise.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitise.mjs","sources":["../../../src/Markup/utils/sanitise.ts"],"sourcesContent":["import { ALLOWED_PROTOCOLS } from '../constants';\n\nconst INVISIBLE_CHARS = /[\\u200b\\u200c\\u200d\\ufeff\\u00ad\\u2060\\u180e]/g;\n// eslint-disable-next-line regexp/no-control-character\nconst CONTROL_CHARS = /[\\u0000-\\u001f\\u007f-\\u009f]/;\nconst DANGEROUS_SCHEME = /^(?:javascript|vbscript|data|jscript)\\s*:/i;\n// eslint-disable-next-line regexp/no-useless-non-capturing-group\nconst ENCODED_COLON_SCHEME = /^(?:javascript|vbscript|data|jscript)(?:%3a)/i;\nconst IPV6_BRACKETS = /^\\[|\\]$/g;\nconst NUMERIC_IP = /^[\\d.]+$/;\nconst HEX_IP = /^0x[0-9a-f]+$/i;\n\nexport function sanitiseHref(href: string): string | undefined {\n const cleaned = href.replace(INVISIBLE_CHARS, '');\n const trimmed = cleaned.trim();\n\n if (!trimmed) {\n return undefined;\n }\n\n if (CONTROL_CHARS.test(trimmed)) {\n return undefined;\n }\n\n if (DANGEROUS_SCHEME.test(trimmed)) {\n return undefined;\n }\n\n if (ENCODED_COLON_SCHEME.test(trimmed)) {\n return undefined;\n }\n\n if (trimmed.startsWith('//')) {\n return undefined;\n }\n\n if (trimmed.startsWith('\\\\')) {\n return undefined;\n }\n\n if (trimmed.startsWith('/')) {\n return trimmed[1] !== '\\\\' ? trimmed : undefined;\n }\n\n if (trimmed.startsWith('#')) {\n return trimmed;\n }\n\n if (trimmed.startsWith('./') || trimmed.startsWith('../')) {\n return undefined;\n }\n\n try {\n const url = new URL(trimmed);\n\n if (!ALLOWED_PROTOCOLS.includes(url.protocol)) {\n return undefined;\n }\n\n if (url.protocol === 'https:') {\n if (!trimmed.startsWith('https://')) {\n return undefined;\n }\n\n if (!url.hostname) {\n return undefined;\n }\n\n if (url.username || url.password) {\n return undefined;\n }\n\n if (isInternalHost(url.hostname)) {\n return undefined;\n }\n }\n\n if (url.protocol === 'mailto:') {\n if (url.search) {\n return undefined;\n }\n\n if (!url.pathname) {\n return undefined;\n }\n }\n\n return trimmed;\n } catch {\n return undefined;\n }\n}\n\nexport type AllowLinksMode = 'internal' | 'all' | 'none';\n\n// Synthetic origin used to resolve relative paths via the WHATWG URL parser.\n// If the resolved origin still equals this sentinel, the path stays on-origin.\nconst SSR_SENTINEL_ORIGIN = 'https://internal.invalid';\n\nexport function isHrefAllowedByMode(href: string, mode: AllowLinksMode): boolean {\n switch (mode) {\n case 'none':\n return false;\n case 'all':\n return true;\n case 'internal':\n try {\n if (!href.startsWith('/')) {\n const parsed = new URL(href);\n return parsed.protocol === 'https:' && parsed.hostname === 'wise.com';\n }\n const parsed = new URL(href, SSR_SENTINEL_ORIGIN);\n return parsed.origin === SSR_SENTINEL_ORIGIN;\n } catch {\n return false;\n }\n }\n}\n\nfunction isInternalHost(hostname: string): boolean {\n const stripped = hostname.replace(IPV6_BRACKETS, '');\n const host = stripped.endsWith('.') ? stripped.slice(0, -1) : stripped;\n if (NUMERIC_IP.test(host)) return true;\n if (HEX_IP.test(host)) return true;\n if (host === '::1' || host === '0:0:0:0:0:0:0:1') return true;\n if (host === 'localhost') return true;\n if (host.endsWith('.internal')) return true;\n return false;\n}\n"],"names":["INVISIBLE_CHARS","CONTROL_CHARS","DANGEROUS_SCHEME","ENCODED_COLON_SCHEME","IPV6_BRACKETS","NUMERIC_IP","HEX_IP","sanitiseHref","href","cleaned","replace","trimmed","trim","undefined","test","startsWith","url","URL","ALLOWED_PROTOCOLS","includes","protocol","hostname","username","password","isInternalHost","search","pathname","SSR_SENTINEL_ORIGIN","isHrefAllowedByMode","mode","parsed","origin","stripped","host","endsWith","slice"],"mappings":";;AAEA,MAAMA,eAAe,GAAG,+CAA+C;AACvE;AACA,MAAMC,aAAa,GAAG,8BAA8B;AACpD,MAAMC,gBAAgB,GAAG,4CAA4C;AACrE;AACA,MAAMC,oBAAoB,GAAG,+CAA+C;AAC5E,MAAMC,aAAa,GAAG,UAAU;AAChC,MAAMC,UAAU,GAAG,UAAU;AAC7B,MAAMC,MAAM,GAAG,gBAAgB;AAEzB,SAAUC,YAAYA,CAACC,IAAY,EAAA;EACvC,MAAMC,OAAO,GAAGD,IAAI,CAACE,OAAO,CAACV,eAAe,EAAE,EAAE,CAAC;AACjD,EAAA,MAAMW,OAAO,GAAGF,OAAO,CAACG,IAAI,EAAE;EAE9B,IAAI,CAACD,OAAO,EAAE;AACZ,IAAA,OAAOE,SAAS;AAClB,EAAA;AAEA,EAAA,IAAIZ,aAAa,CAACa,IAAI,CAACH,OAAO,CAAC,EAAE;AAC/B,IAAA,OAAOE,SAAS;AAClB,EAAA;AAEA,EAAA,IAAIX,gBAAgB,CAACY,IAAI,CAACH,OAAO,CAAC,EAAE;AAClC,IAAA,OAAOE,SAAS;AAClB,EAAA;AAEA,EAAA,IAAIV,oBAAoB,CAACW,IAAI,CAACH,OAAO,CAAC,EAAE;AACtC,IAAA,OAAOE,SAAS;AAClB,EAAA;AAEA,EAAA,IAAIF,OAAO,CAACI,UAAU,CAAC,IAAI,CAAC,EAAE;AAC5B,IAAA,OAAOF,SAAS;AAClB,EAAA;AAEA,EAAA,IAAIF,OAAO,CAACI,UAAU,CAAC,IAAI,CAAC,EAAE;AAC5B,IAAA,OAAOF,SAAS;AAClB,EAAA;AAEA,EAAA,IAAIF,OAAO,CAACI,UAAU,CAAC,GAAG,CAAC,EAAE;IAC3B,OAAOJ,OAAO,CAAC,CAAC,CAAC,KAAK,IAAI,GAAGA,OAAO,GAAGE,SAAS;AAClD,EAAA;AAEA,EAAA,IAAIF,OAAO,CAACI,UAAU,CAAC,GAAG,CAAC,EAAE;AAC3B,IAAA,OAAOJ,OAAO;AAChB,EAAA;AAEA,EAAA,IAAIA,OAAO,CAACI,UAAU,CAAC,IAAI,CAAC,IAAIJ,OAAO,CAACI,UAAU,CAAC,KAAK,CAAC,EAAE;AACzD,IAAA,OAAOF,SAAS;AAClB,EAAA;EAEA,IAAI;AACF,IAAA,MAAMG,GAAG,GAAG,IAAIC,GAAG,CAACN,OAAO,CAAC;IAE5B,IAAI,CAACO,iBAAiB,CAACC,QAAQ,CAACH,GAAG,CAACI,QAAQ,CAAC,EAAE;AAC7C,MAAA,OAAOP,SAAS;AAClB,IAAA;AAEA,IAAA,IAAIG,GAAG,CAACI,QAAQ,KAAK,QAAQ,EAAE;AAC7B,MAAA,IAAI,CAACT,OAAO,CAACI,UAAU,CAAC,UAAU,CAAC,EAAE;AACnC,QAAA,OAAOF,SAAS;AAClB,MAAA;AAEA,MAAA,IAAI,CAACG,GAAG,CAACK,QAAQ,EAAE;AACjB,QAAA,OAAOR,SAAS;AAClB,MAAA;AAEA,MAAA,IAAIG,GAAG,CAACM,QAAQ,IAAIN,GAAG,CAACO,QAAQ,EAAE;AAChC,QAAA,OAAOV,SAAS;AAClB,MAAA;AAEA,MAAA,IAAIW,cAAc,CAACR,GAAG,CAACK,QAAQ,CAAC,EAAE;AAChC,QAAA,OAAOR,SAAS;AAClB,MAAA;AACF,IAAA;AAEA,IAAA,IAAIG,GAAG,CAACI,QAAQ,KAAK,SAAS,EAAE;MAC9B,IAAIJ,GAAG,CAACS,MAAM,EAAE;AACd,QAAA,OAAOZ,SAAS;AAClB,MAAA;AAEA,MAAA,IAAI,CAACG,GAAG,CAACU,QAAQ,EAAE;AACjB,QAAA,OAAOb,SAAS;AAClB,MAAA;AACF,IAAA;AAEA,IAAA,OAAOF,OAAO;AAChB,EAAA,CAAC,CAAC,MAAM;AACN,IAAA,OAAOE,SAAS;AAClB,EAAA;AACF;AAIA;AACA;AACA,MAAMc,mBAAmB,GAAG,0BAA0B;AAEhD,SAAUC,mBAAmBA,CAACpB,IAAY,EAAEqB,IAAoB,EAAA;AACpE,EAAA,QAAQA,IAAI;AACV,IAAA,KAAK,MAAM;AACT,MAAA,OAAO,KAAK;AACd,IAAA,KAAK,KAAK;AACR,MAAA,OAAO,IAAI;AACb,IAAA,KAAK,UAAU;MACb,IAAI;AACF,QAAA,IAAI,CAACrB,IAAI,CAACO,UAAU,CAAC,GAAG,CAAC,EAAE;AACzB,UAAA,MAAMe,MAAM,GAAG,IAAIb,GAAG,CAACT,IAAI,CAAC;UAC5B,OAAOsB,MAAM,CAACV,QAAQ,KAAK,QAAQ,IAAIU,MAAM,CAACT,QAAQ,KAAK,UAAU;AACvE,QAAA;QACA,MAAMS,MAAM,GAAG,IAAIb,GAAG,CAACT,IAAI,EAAEmB,mBAAmB,CAAC;AACjD,QAAA,OAAOG,MAAM,CAACC,MAAM,KAAKJ,mBAAmB;AAC9C,MAAA,CAAC,CAAC,MAAM;AACN,QAAA,OAAO,KAAK;AACd,MAAA;AACJ;AACF;AAEA,SAASH,cAAcA,CAACH,QAAgB,EAAA;EACtC,MAAMW,QAAQ,GAAGX,QAAQ,CAACX,OAAO,CAACN,aAAa,EAAE,EAAE,CAAC;AACpD,EAAA,MAAM6B,IAAI,GAAGD,QAAQ,CAACE,QAAQ,CAAC,GAAG,CAAC,GAAGF,QAAQ,CAACG,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,GAAGH,QAAQ;EACtE,IAAI3B,UAAU,CAACS,IAAI,CAACmB,IAAI,CAAC,EAAE,OAAO,IAAI;EACtC,IAAI3B,MAAM,CAACQ,IAAI,CAACmB,IAAI,CAAC,EAAE,OAAO,IAAI;EAClC,IAAIA,IAAI,KAAK,KAAK,IAAIA,IAAI,KAAK,iBAAiB,EAAE,OAAO,IAAI;AAC7D,EAAA,IAAIA,IAAI,KAAK,WAAW,EAAE,OAAO,IAAI;EACrC,IAAIA,IAAI,CAACC,QAAQ,CAAC,WAAW,CAAC,EAAE,OAAO,IAAI;AAC3C,EAAA,OAAO,KAAK;AACd;;;;"}
@@ -43,7 +43,7 @@ const getLocalStorage = () => {
43
43
  return storage.map(item => String(item));
44
44
  }
45
45
  }
46
- } catch (error) {}
46
+ } catch {}
47
47
  return [];
48
48
  };
49
49
  const Nudge = ({
@@ -60,6 +60,15 @@ const Nudge = ({
60
60
  action
61
61
  }) => {
62
62
  const intl = reactIntl.useIntl();
63
+ const hasLegacyLink = Boolean(link);
64
+ const hasAction = action != null;
65
+ const shouldRenderLegacyLink = hasLegacyLink && !hasAction;
66
+ React.useEffect(() => {
67
+ if (process.env.NODE_ENV !== 'production' && hasAction && (hasLegacyLink || href != null)) {
68
+ // eslint-disable-next-line no-console -- Intentional developer warning for conflicting API usage.
69
+ console.warn('Nudge received both action and link/href props. Rendering action only. Remove link/href to silence this warning.');
70
+ }
71
+ }, [hasAction, hasLegacyLink, href]);
63
72
  const getIsDismissed = React.useCallback(() => persistDismissal && id ? !!getLocalStorage()?.find(item => item === id) : false, [persistDismissal, id]);
64
73
  const [nudgeState, setNudgeState] = React.useState(() => ({
65
74
  isDismissed: getIsDismissed(),
@@ -128,7 +137,7 @@ const Nudge = ({
128
137
  type: typography.Typography.BODY_LARGE,
129
138
  className: clsx.clsx('wds-nudge-body'),
130
139
  children: title
131
- }), link && /*#__PURE__*/jsxRuntime.jsx(Link.default, {
140
+ }), shouldRenderLegacyLink && /*#__PURE__*/jsxRuntime.jsx(Link.default, {
132
141
  href: href,
133
142
  type: typography.Typography.LINK_LARGE,
134
143
  className: "wds-nudge-link",
@@ -1 +1 @@
1
- {"version":3,"file":"Nudge.js","sources":["../../src/Nudge/Nudge.tsx"],"sourcesContent":["import { Illustration, Assets } from '@wise/art';\nimport { clsx } from 'clsx';\nimport { ReactNode, useEffect, useState, MouseEvent, useCallback } from 'react';\n\nimport Body from '../Body';\nimport { Typography } from '../common';\nimport Link from '../Link';\nimport type { AlertAction } from '../_deprecated/Alert';\nimport IconButton from '../IconButton';\nimport { Cross } from '@transferwise/icons';\nimport { useIntl } from 'react-intl';\nimport closeBtnMessages from '../common/CloseButton/CloseButton.messages';\n\n// WARNING: Changing this will cause nudges to reappear wherever persist nudge is used and privacy team will need to be updated too\nexport const STORAGE_NAME = 'dismissedNudges';\n\nconst getLocalStorage = (): string[] => {\n try {\n const storageItem = localStorage.getItem(STORAGE_NAME);\n\n if (storageItem) {\n const storage: unknown = JSON.parse(storageItem);\n\n if (Array.isArray(storage)) {\n return storage.map((item) => String(item));\n }\n }\n } catch (error) {}\n\n return [];\n};\n\ntype MediaNameType =\n | `${Assets.GLOBE}`\n | `${Assets.LOCK}`\n | `${Assets.WALLET}`\n | `${Assets.GEAR}`\n | `${Assets.INVITE_LETTER}`\n | `${Assets.PERSONAL_CARD}`\n | `${Assets.BUSINESS_CARD}`\n | `${Assets.HEART}`\n | `${Assets.MULTI_CURRENCY}`\n | `${Assets.SHOPPING_BAG}`\n | `${Assets.FLOWER}`\n | `${Assets.GIFT_BOX}`\n | `${Assets.BACKPACK}`\n | `${Assets.DOCUMENTS}`;\n\ntype BaseProps = {\n /** @deprecated Use `mediaName` property instead. */\n media?: ReactNode;\n /** Media name */\n mediaName?: MediaNameType;\n title: ReactNode;\n link?: ReactNode;\n href?: string;\n onClick?: (event?: MouseEvent<HTMLSpanElement>) => void;\n /** Fired when the user clicks on close button */\n onDismiss?: () => void;\n /** An optional call to action to sit under the main body of the nudge. If your label is short, use aria-label to provide more context */\n action?: AlertAction;\n className?: string;\n};\n\nexport interface OptionalId extends BaseProps {\n id?: string;\n persistDismissal?: false;\n isPreviouslyDismissed?: undefined;\n}\n\nexport interface RequiredPersistProps extends BaseProps {\n /** This ID should be completely unique to the page and feature as it uses a shared array which could conflict with other nudges in Wise */\n id: string;\n /** Use persist dismissal to keep the nudge dismissed using the browser's localStorage */\n persistDismissal: true;\n /**\n * Fired on mount for determining if nudge has been dismissed before\n *\n * @param {boolean} value - set to true if dismissed previously\n */\n isPreviouslyDismissed?: (value: boolean) => void;\n}\n\nexport type Props = OptionalId | RequiredPersistProps;\n\nconst Nudge = ({\n mediaName,\n title,\n link,\n href,\n onClick,\n onDismiss,\n persistDismissal,\n isPreviouslyDismissed,\n id,\n className,\n action,\n}: Props) => {\n const intl = useIntl();\n const getIsDismissed = useCallback(\n () => (persistDismissal && id ? !!getLocalStorage()?.find((item) => item === id) : false),\n [persistDismissal, id],\n );\n\n const [nudgeState, setNudgeState] = useState(() => ({\n isDismissed: getIsDismissed(),\n isMounted: false,\n }));\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- Setting mount state in mount effect\n setNudgeState((prev) => ({ ...prev, isMounted: true }));\n }, []);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- Syncing dismissed state from localStorage on prop change\n setNudgeState((prev) => ({ ...prev, isDismissed: getIsDismissed() }));\n }, [getIsDismissed, id, persistDismissal]);\n\n const { isDismissed } = nudgeState;\n\n const handleOnDismiss = () => {\n const dismissedNudgesStorage = getLocalStorage();\n\n if (persistDismissal && id) {\n try {\n localStorage.setItem(STORAGE_NAME, JSON.stringify([...dismissedNudgesStorage, id]));\n } catch {}\n\n setNudgeState((prev) => ({ ...prev, isDismissed: true }));\n }\n\n if (onDismiss) {\n onDismiss();\n }\n };\n\n useEffect(() => {\n if (persistDismissal && id && isPreviouslyDismissed) {\n const dismissedNudgesStorage = getLocalStorage();\n const wasDismissed = !!dismissedNudgesStorage?.find((item) => item === id);\n isPreviouslyDismissed(wasDismissed);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [id, persistDismissal]);\n\n if (persistDismissal && (isDismissed || !nudgeState.isMounted)) {\n return null;\n }\n\n return (\n <div className={clsx('wds-nudge', className)} id={id}>\n {!!mediaName && (\n <div className=\"wds-nudge-media\">\n <Illustration\n name={mediaName}\n className={clsx(`wds-nudge-media-${mediaName}`)}\n size=\"small\"\n disablePadding\n alt=\"\"\n />\n </div>\n )}\n <div className=\"wds-nudge-container\">\n <div className=\"wds-nudge-content\">\n <Body type={Typography.BODY_LARGE} className={clsx('wds-nudge-body')}>\n {title}\n </Body>\n {/* Merge these two Link instances into one */}\n {link && (\n <Link\n href={href}\n type={Typography.LINK_LARGE}\n className=\"wds-nudge-link\"\n onClick={onClick}\n >\n {link}\n </Link>\n )}\n {action && (\n <Link\n href={action.href}\n target={action.target}\n className=\"m-t-1\"\n aria-label={action['aria-label']}\n type={Typography.LINK_LARGE}\n onClick={action.onClick}\n >\n {action.text}\n </Link>\n )}\n </div>\n {onDismiss || persistDismissal ? (\n <IconButton\n size={24}\n priority=\"tertiary\"\n aria-label={intl.formatMessage(closeBtnMessages.ariaLabel)}\n onClick={handleOnDismiss}\n >\n <Cross />\n </IconButton>\n ) : null}\n </div>\n </div>\n );\n};\n\nexport default Nudge;\n"],"names":["STORAGE_NAME","getLocalStorage","storageItem","localStorage","getItem","storage","JSON","parse","Array","isArray","map","item","String","error","Nudge","mediaName","title","link","href","onClick","onDismiss","persistDismissal","isPreviouslyDismissed","id","className","action","intl","useIntl","getIsDismissed","useCallback","find","nudgeState","setNudgeState","useState","isDismissed","isMounted","useEffect","prev","handleOnDismiss","dismissedNudgesStorage","setItem","stringify","wasDismissed","_jsxs","clsx","children","_jsx","Illustration","name","size","disablePadding","alt","Body","type","Typography","BODY_LARGE","Link","LINK_LARGE","target","text","IconButton","priority","formatMessage","closeBtnMessages","ariaLabel","Cross"],"mappings":"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"}
1
+ {"version":3,"file":"Nudge.js","sources":["../../src/Nudge/Nudge.tsx"],"sourcesContent":["import { Illustration, Assets } from '@wise/art';\nimport { clsx } from 'clsx';\nimport { ReactNode, useEffect, useState, MouseEvent, useCallback } from 'react';\n\nimport Body from '../Body';\nimport { Typography } from '../common';\nimport Link from '../Link';\nimport type { AlertAction } from '../_deprecated/Alert';\nimport IconButton from '../IconButton';\nimport { Cross } from '@transferwise/icons';\nimport { useIntl } from 'react-intl';\nimport closeBtnMessages from '../common/CloseButton/CloseButton.messages';\n\n// WARNING: Changing this will cause nudges to reappear wherever persist nudge is used and privacy team will need to be updated too\nexport const STORAGE_NAME = 'dismissedNudges';\n\nconst getLocalStorage = (): string[] => {\n try {\n const storageItem = localStorage.getItem(STORAGE_NAME);\n\n if (storageItem) {\n const storage: unknown = JSON.parse(storageItem);\n\n if (Array.isArray(storage)) {\n return storage.map((item) => String(item));\n }\n }\n } catch {}\n\n return [];\n};\n\ntype MediaNameType =\n | `${Assets.GLOBE}`\n | `${Assets.LOCK}`\n | `${Assets.WALLET}`\n | `${Assets.GEAR}`\n | `${Assets.INVITE_LETTER}`\n | `${Assets.PERSONAL_CARD}`\n | `${Assets.BUSINESS_CARD}`\n | `${Assets.HEART}`\n | `${Assets.MULTI_CURRENCY}`\n | `${Assets.SHOPPING_BAG}`\n | `${Assets.FLOWER}`\n | `${Assets.GIFT_BOX}`\n | `${Assets.BACKPACK}`\n | `${Assets.DOCUMENTS}`;\n\ntype BaseProps = {\n /**\n * @deprecated Use `mediaName` instead.\n * Legacy custom media content is no longer used by `Nudge`.\n */\n media?: ReactNode;\n /**\n * Illustration asset name shown at the start of the nudge.\n */\n mediaName?: MediaNameType;\n /** Main nudge message content. */\n title: ReactNode;\n /**\n * Legacy CTA label content.\n * Rendered only when `action` is not provided.\n */\n link?: ReactNode;\n /**\n * Legacy CTA destination for `link`.\n * Ignored when `action` is provided.\n */\n href?: string;\n /**\n * Legacy click handler for `link`.\n * Ignored when `action` is provided.\n */\n onClick?: (event?: MouseEvent<HTMLSpanElement>) => void;\n /** Fired when the user clicks on close button */\n onDismiss?: () => void;\n /**\n * Preferred CTA configuration rendered under the nudge body.\n * Single CTA rule: when `action` is provided, legacy `link`/`href` is not rendered.\n * If your label is short, use `aria-label` to provide more context.\n */\n action?: AlertAction;\n /** Optional class name applied to the root nudge container. */\n className?: string;\n};\n\nexport interface OptionalId extends BaseProps {\n id?: string;\n persistDismissal?: false;\n isPreviouslyDismissed?: undefined;\n}\n\nexport interface RequiredPersistProps extends BaseProps {\n /** This ID should be completely unique to the page and feature as it uses a shared array which could conflict with other nudges in Wise */\n id: string;\n /** Use persist dismissal to keep the nudge dismissed using the browser's localStorage */\n persistDismissal: true;\n /**\n * Fired on mount for determining if nudge has been dismissed before\n *\n * @param {boolean} value - set to true if dismissed previously\n */\n isPreviouslyDismissed?: (value: boolean) => void;\n}\n\nexport type NudgeProps = OptionalId | RequiredPersistProps;\n\nconst Nudge = ({\n mediaName,\n title,\n link,\n href,\n onClick,\n onDismiss,\n persistDismissal,\n isPreviouslyDismissed,\n id,\n className,\n action,\n}: NudgeProps) => {\n const intl = useIntl();\n const hasLegacyLink = Boolean(link);\n const hasAction = action != null;\n const shouldRenderLegacyLink = hasLegacyLink && !hasAction;\n\n useEffect(() => {\n if (process.env.NODE_ENV !== 'production' && hasAction && (hasLegacyLink || href != null)) {\n // eslint-disable-next-line no-console -- Intentional developer warning for conflicting API usage.\n console.warn(\n 'Nudge received both action and link/href props. Rendering action only. Remove link/href to silence this warning.',\n );\n }\n }, [hasAction, hasLegacyLink, href]);\n\n const getIsDismissed = useCallback(\n () => (persistDismissal && id ? !!getLocalStorage()?.find((item) => item === id) : false),\n [persistDismissal, id],\n );\n\n const [nudgeState, setNudgeState] = useState(() => ({\n isDismissed: getIsDismissed(),\n isMounted: false,\n }));\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- Setting mount state in mount effect\n setNudgeState((prev) => ({ ...prev, isMounted: true }));\n }, []);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- Syncing dismissed state from localStorage on prop change\n setNudgeState((prev) => ({ ...prev, isDismissed: getIsDismissed() }));\n }, [getIsDismissed, id, persistDismissal]);\n\n const { isDismissed } = nudgeState;\n\n const handleOnDismiss = () => {\n const dismissedNudgesStorage = getLocalStorage();\n\n if (persistDismissal && id) {\n try {\n localStorage.setItem(STORAGE_NAME, JSON.stringify([...dismissedNudgesStorage, id]));\n } catch {}\n\n setNudgeState((prev) => ({ ...prev, isDismissed: true }));\n }\n\n if (onDismiss) {\n onDismiss();\n }\n };\n\n useEffect(() => {\n if (persistDismissal && id && isPreviouslyDismissed) {\n const dismissedNudgesStorage = getLocalStorage();\n const wasDismissed = !!dismissedNudgesStorage?.find((item) => item === id);\n isPreviouslyDismissed(wasDismissed);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [id, persistDismissal]);\n\n if (persistDismissal && (isDismissed || !nudgeState.isMounted)) {\n return null;\n }\n\n return (\n <div className={clsx('wds-nudge', className)} id={id}>\n {!!mediaName && (\n <div className=\"wds-nudge-media\">\n <Illustration\n name={mediaName}\n className={clsx(`wds-nudge-media-${mediaName}`)}\n size=\"small\"\n disablePadding\n alt=\"\"\n />\n </div>\n )}\n <div className=\"wds-nudge-container\">\n <div className=\"wds-nudge-content\">\n <Body type={Typography.BODY_LARGE} className={clsx('wds-nudge-body')}>\n {title}\n </Body>\n {shouldRenderLegacyLink && (\n <Link\n href={href}\n type={Typography.LINK_LARGE}\n className=\"wds-nudge-link\"\n onClick={onClick}\n >\n {link}\n </Link>\n )}\n {action && (\n <Link\n href={action.href}\n target={action.target}\n className=\"m-t-1\"\n aria-label={action['aria-label']}\n type={Typography.LINK_LARGE}\n onClick={action.onClick}\n >\n {action.text}\n </Link>\n )}\n </div>\n {onDismiss || persistDismissal ? (\n <IconButton\n size={24}\n priority=\"tertiary\"\n aria-label={intl.formatMessage(closeBtnMessages.ariaLabel)}\n onClick={handleOnDismiss}\n >\n <Cross />\n </IconButton>\n ) : null}\n </div>\n </div>\n );\n};\n\nexport default Nudge;\n"],"names":["STORAGE_NAME","getLocalStorage","storageItem","localStorage","getItem","storage","JSON","parse","Array","isArray","map","item","String","Nudge","mediaName","title","link","href","onClick","onDismiss","persistDismissal","isPreviouslyDismissed","id","className","action","intl","useIntl","hasLegacyLink","Boolean","hasAction","shouldRenderLegacyLink","useEffect","process","env","NODE_ENV","console","warn","getIsDismissed","useCallback","find","nudgeState","setNudgeState","useState","isDismissed","isMounted","prev","handleOnDismiss","dismissedNudgesStorage","setItem","stringify","wasDismissed","_jsxs","clsx","children","_jsx","Illustration","name","size","disablePadding","alt","Body","type","Typography","BODY_LARGE","Link","LINK_LARGE","target","text","IconButton","priority","formatMessage","closeBtnMessages","ariaLabel","Cross"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { Illustration } from '@wise/art';
2
2
  import { clsx } from 'clsx';
3
- import { useCallback, useState, useEffect } from 'react';
3
+ import { useEffect, useCallback, useState } from 'react';
4
4
  import Body from '../Body/Body.mjs';
5
5
  import '../common/theme.mjs';
6
6
  import '../common/direction.mjs';
@@ -39,7 +39,7 @@ const getLocalStorage = () => {
39
39
  return storage.map(item => String(item));
40
40
  }
41
41
  }
42
- } catch (error) {}
42
+ } catch {}
43
43
  return [];
44
44
  };
45
45
  const Nudge = ({
@@ -56,6 +56,15 @@ const Nudge = ({
56
56
  action
57
57
  }) => {
58
58
  const intl = useIntl();
59
+ const hasLegacyLink = Boolean(link);
60
+ const hasAction = action != null;
61
+ const shouldRenderLegacyLink = hasLegacyLink && !hasAction;
62
+ useEffect(() => {
63
+ if (process.env.NODE_ENV !== 'production' && hasAction && (hasLegacyLink || href != null)) {
64
+ // eslint-disable-next-line no-console -- Intentional developer warning for conflicting API usage.
65
+ console.warn('Nudge received both action and link/href props. Rendering action only. Remove link/href to silence this warning.');
66
+ }
67
+ }, [hasAction, hasLegacyLink, href]);
59
68
  const getIsDismissed = useCallback(() => persistDismissal && id ? !!getLocalStorage()?.find(item => item === id) : false, [persistDismissal, id]);
60
69
  const [nudgeState, setNudgeState] = useState(() => ({
61
70
  isDismissed: getIsDismissed(),
@@ -124,7 +133,7 @@ const Nudge = ({
124
133
  type: Typography.BODY_LARGE,
125
134
  className: clsx('wds-nudge-body'),
126
135
  children: title
127
- }), link && /*#__PURE__*/jsx(Link, {
136
+ }), shouldRenderLegacyLink && /*#__PURE__*/jsx(Link, {
128
137
  href: href,
129
138
  type: Typography.LINK_LARGE,
130
139
  className: "wds-nudge-link",
@@ -1 +1 @@
1
- {"version":3,"file":"Nudge.mjs","sources":["../../src/Nudge/Nudge.tsx"],"sourcesContent":["import { Illustration, Assets } from '@wise/art';\nimport { clsx } from 'clsx';\nimport { ReactNode, useEffect, useState, MouseEvent, useCallback } from 'react';\n\nimport Body from '../Body';\nimport { Typography } from '../common';\nimport Link from '../Link';\nimport type { AlertAction } from '../_deprecated/Alert';\nimport IconButton from '../IconButton';\nimport { Cross } from '@transferwise/icons';\nimport { useIntl } from 'react-intl';\nimport closeBtnMessages from '../common/CloseButton/CloseButton.messages';\n\n// WARNING: Changing this will cause nudges to reappear wherever persist nudge is used and privacy team will need to be updated too\nexport const STORAGE_NAME = 'dismissedNudges';\n\nconst getLocalStorage = (): string[] => {\n try {\n const storageItem = localStorage.getItem(STORAGE_NAME);\n\n if (storageItem) {\n const storage: unknown = JSON.parse(storageItem);\n\n if (Array.isArray(storage)) {\n return storage.map((item) => String(item));\n }\n }\n } catch (error) {}\n\n return [];\n};\n\ntype MediaNameType =\n | `${Assets.GLOBE}`\n | `${Assets.LOCK}`\n | `${Assets.WALLET}`\n | `${Assets.GEAR}`\n | `${Assets.INVITE_LETTER}`\n | `${Assets.PERSONAL_CARD}`\n | `${Assets.BUSINESS_CARD}`\n | `${Assets.HEART}`\n | `${Assets.MULTI_CURRENCY}`\n | `${Assets.SHOPPING_BAG}`\n | `${Assets.FLOWER}`\n | `${Assets.GIFT_BOX}`\n | `${Assets.BACKPACK}`\n | `${Assets.DOCUMENTS}`;\n\ntype BaseProps = {\n /** @deprecated Use `mediaName` property instead. */\n media?: ReactNode;\n /** Media name */\n mediaName?: MediaNameType;\n title: ReactNode;\n link?: ReactNode;\n href?: string;\n onClick?: (event?: MouseEvent<HTMLSpanElement>) => void;\n /** Fired when the user clicks on close button */\n onDismiss?: () => void;\n /** An optional call to action to sit under the main body of the nudge. If your label is short, use aria-label to provide more context */\n action?: AlertAction;\n className?: string;\n};\n\nexport interface OptionalId extends BaseProps {\n id?: string;\n persistDismissal?: false;\n isPreviouslyDismissed?: undefined;\n}\n\nexport interface RequiredPersistProps extends BaseProps {\n /** This ID should be completely unique to the page and feature as it uses a shared array which could conflict with other nudges in Wise */\n id: string;\n /** Use persist dismissal to keep the nudge dismissed using the browser's localStorage */\n persistDismissal: true;\n /**\n * Fired on mount for determining if nudge has been dismissed before\n *\n * @param {boolean} value - set to true if dismissed previously\n */\n isPreviouslyDismissed?: (value: boolean) => void;\n}\n\nexport type Props = OptionalId | RequiredPersistProps;\n\nconst Nudge = ({\n mediaName,\n title,\n link,\n href,\n onClick,\n onDismiss,\n persistDismissal,\n isPreviouslyDismissed,\n id,\n className,\n action,\n}: Props) => {\n const intl = useIntl();\n const getIsDismissed = useCallback(\n () => (persistDismissal && id ? !!getLocalStorage()?.find((item) => item === id) : false),\n [persistDismissal, id],\n );\n\n const [nudgeState, setNudgeState] = useState(() => ({\n isDismissed: getIsDismissed(),\n isMounted: false,\n }));\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- Setting mount state in mount effect\n setNudgeState((prev) => ({ ...prev, isMounted: true }));\n }, []);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- Syncing dismissed state from localStorage on prop change\n setNudgeState((prev) => ({ ...prev, isDismissed: getIsDismissed() }));\n }, [getIsDismissed, id, persistDismissal]);\n\n const { isDismissed } = nudgeState;\n\n const handleOnDismiss = () => {\n const dismissedNudgesStorage = getLocalStorage();\n\n if (persistDismissal && id) {\n try {\n localStorage.setItem(STORAGE_NAME, JSON.stringify([...dismissedNudgesStorage, id]));\n } catch {}\n\n setNudgeState((prev) => ({ ...prev, isDismissed: true }));\n }\n\n if (onDismiss) {\n onDismiss();\n }\n };\n\n useEffect(() => {\n if (persistDismissal && id && isPreviouslyDismissed) {\n const dismissedNudgesStorage = getLocalStorage();\n const wasDismissed = !!dismissedNudgesStorage?.find((item) => item === id);\n isPreviouslyDismissed(wasDismissed);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [id, persistDismissal]);\n\n if (persistDismissal && (isDismissed || !nudgeState.isMounted)) {\n return null;\n }\n\n return (\n <div className={clsx('wds-nudge', className)} id={id}>\n {!!mediaName && (\n <div className=\"wds-nudge-media\">\n <Illustration\n name={mediaName}\n className={clsx(`wds-nudge-media-${mediaName}`)}\n size=\"small\"\n disablePadding\n alt=\"\"\n />\n </div>\n )}\n <div className=\"wds-nudge-container\">\n <div className=\"wds-nudge-content\">\n <Body type={Typography.BODY_LARGE} className={clsx('wds-nudge-body')}>\n {title}\n </Body>\n {/* Merge these two Link instances into one */}\n {link && (\n <Link\n href={href}\n type={Typography.LINK_LARGE}\n className=\"wds-nudge-link\"\n onClick={onClick}\n >\n {link}\n </Link>\n )}\n {action && (\n <Link\n href={action.href}\n target={action.target}\n className=\"m-t-1\"\n aria-label={action['aria-label']}\n type={Typography.LINK_LARGE}\n onClick={action.onClick}\n >\n {action.text}\n </Link>\n )}\n </div>\n {onDismiss || persistDismissal ? (\n <IconButton\n size={24}\n priority=\"tertiary\"\n aria-label={intl.formatMessage(closeBtnMessages.ariaLabel)}\n onClick={handleOnDismiss}\n >\n <Cross />\n </IconButton>\n ) : null}\n </div>\n </div>\n );\n};\n\nexport default Nudge;\n"],"names":["STORAGE_NAME","getLocalStorage","storageItem","localStorage","getItem","storage","JSON","parse","Array","isArray","map","item","String","error","Nudge","mediaName","title","link","href","onClick","onDismiss","persistDismissal","isPreviouslyDismissed","id","className","action","intl","useIntl","getIsDismissed","useCallback","find","nudgeState","setNudgeState","useState","isDismissed","isMounted","useEffect","prev","handleOnDismiss","dismissedNudgesStorage","setItem","stringify","wasDismissed","_jsxs","clsx","children","_jsx","Illustration","name","size","disablePadding","alt","Body","type","Typography","BODY_LARGE","Link","LINK_LARGE","target","text","IconButton","priority","formatMessage","closeBtnMessages","ariaLabel","Cross"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAcO,MAAMA,YAAY,GAAG;AAE5B,MAAMC,eAAe,GAAGA,MAAe;EACrC,IAAI;AACF,IAAA,MAAMC,WAAW,GAAGC,YAAY,CAACC,OAAO,CAACJ,YAAY,CAAC;AAEtD,IAAA,IAAIE,WAAW,EAAE;AACf,MAAA,MAAMG,OAAO,GAAYC,IAAI,CAACC,KAAK,CAACL,WAAW,CAAC;AAEhD,MAAA,IAAIM,KAAK,CAACC,OAAO,CAACJ,OAAO,CAAC,EAAE;QAC1B,OAAOA,OAAO,CAACK,GAAG,CAAEC,IAAI,IAAKC,MAAM,CAACD,IAAI,CAAC,CAAC;AAC5C,MAAA;AACF,IAAA;AACF,EAAA,CAAC,CAAC,OAAOE,KAAK,EAAE,CAAC;AAEjB,EAAA,OAAO,EAAE;AACX,CAAC;AAuDD,MAAMC,KAAK,GAAGA,CAAC;EACbC,SAAS;EACTC,KAAK;EACLC,IAAI;EACJC,IAAI;EACJC,OAAO;EACPC,SAAS;EACTC,gBAAgB;EAChBC,qBAAqB;EACrBC,EAAE;EACFC,SAAS;AACTC,EAAAA;AAAM,CACA,KAAI;AACV,EAAA,MAAMC,IAAI,GAAGC,OAAO,EAAE;AACtB,EAAA,MAAMC,cAAc,GAAGC,WAAW,CAChC,MAAOR,gBAAgB,IAAIE,EAAE,GAAG,CAAC,CAACtB,eAAe,EAAE,EAAE6B,IAAI,CAAEnB,IAAI,IAAKA,IAAI,KAAKY,EAAE,CAAC,GAAG,KAAM,EACzF,CAACF,gBAAgB,EAAEE,EAAE,CAAC,CACvB;EAED,MAAM,CAACQ,UAAU,EAAEC,aAAa,CAAC,GAAGC,QAAQ,CAAC,OAAO;IAClDC,WAAW,EAAEN,cAAc,EAAE;AAC7BO,IAAAA,SAAS,EAAE;AACZ,GAAA,CAAC,CAAC;AAEHC,EAAAA,SAAS,CAAC,MAAK;AACb;IACAJ,aAAa,CAAEK,IAAI,KAAM;AAAE,MAAA,GAAGA,IAAI;AAAEF,MAAAA,SAAS,EAAE;AAAI,KAAE,CAAC,CAAC;EACzD,CAAC,EAAE,EAAE,CAAC;AAENC,EAAAA,SAAS,CAAC,MAAK;AACb;IACAJ,aAAa,CAAEK,IAAI,KAAM;AAAE,MAAA,GAAGA,IAAI;MAAEH,WAAW,EAAEN,cAAc;AAAE,KAAE,CAAC,CAAC;EACvE,CAAC,EAAE,CAACA,cAAc,EAAEL,EAAE,EAAEF,gBAAgB,CAAC,CAAC;EAE1C,MAAM;AAAEa,IAAAA;AAAW,GAAE,GAAGH,UAAU;EAElC,MAAMO,eAAe,GAAGA,MAAK;AAC3B,IAAA,MAAMC,sBAAsB,GAAGtC,eAAe,EAAE;IAEhD,IAAIoB,gBAAgB,IAAIE,EAAE,EAAE;MAC1B,IAAI;AACFpB,QAAAA,YAAY,CAACqC,OAAO,CAACxC,YAAY,EAAEM,IAAI,CAACmC,SAAS,CAAC,CAAC,GAAGF,sBAAsB,EAAEhB,EAAE,CAAC,CAAC,CAAC;MACrF,CAAC,CAAC,MAAM,CAAC;MAETS,aAAa,CAAEK,IAAI,KAAM;AAAE,QAAA,GAAGA,IAAI;AAAEH,QAAAA,WAAW,EAAE;AAAI,OAAE,CAAC,CAAC;AAC3D,IAAA;AAEA,IAAA,IAAId,SAAS,EAAE;AACbA,MAAAA,SAAS,EAAE;AACb,IAAA;EACF,CAAC;AAEDgB,EAAAA,SAAS,CAAC,MAAK;AACb,IAAA,IAAIf,gBAAgB,IAAIE,EAAE,IAAID,qBAAqB,EAAE;AACnD,MAAA,MAAMiB,sBAAsB,GAAGtC,eAAe,EAAE;AAChD,MAAA,MAAMyC,YAAY,GAAG,CAAC,CAACH,sBAAsB,EAAET,IAAI,CAAEnB,IAAI,IAAKA,IAAI,KAAKY,EAAE,CAAC;MAC1ED,qBAAqB,CAACoB,YAAY,CAAC;AACrC,IAAA;AACA;AACF,EAAA,CAAC,EAAE,CAACnB,EAAE,EAAEF,gBAAgB,CAAC,CAAC;EAE1B,IAAIA,gBAAgB,KAAKa,WAAW,IAAI,CAACH,UAAU,CAACI,SAAS,CAAC,EAAE;AAC9D,IAAA,OAAO,IAAI;AACb,EAAA;AAEA,EAAA,oBACEQ,IAAA,CAAA,KAAA,EAAA;AAAKnB,IAAAA,SAAS,EAAEoB,IAAI,CAAC,WAAW,EAAEpB,SAAS,CAAE;AAACD,IAAAA,EAAE,EAAEA,EAAG;AAAAsB,IAAAA,QAAA,EAAA,CAClD,CAAC,CAAC9B,SAAS,iBACV+B,GAAA,CAAA,KAAA,EAAA;AAAKtB,MAAAA,SAAS,EAAC,iBAAiB;MAAAqB,QAAA,eAC9BC,GAAA,CAACC,YAAY,EAAA;AACXC,QAAAA,IAAI,EAAEjC,SAAU;AAChBS,QAAAA,SAAS,EAAEoB,IAAI,CAAC,CAAA,gBAAA,EAAmB7B,SAAS,EAAE,CAAE;AAChDkC,QAAAA,IAAI,EAAC,OAAO;QACZC,cAAc,EAAA,IAAA;AACdC,QAAAA,GAAG,EAAC;OAAE;KAEL,CACN,eACDR,IAAA,CAAA,KAAA,EAAA;AAAKnB,MAAAA,SAAS,EAAC,qBAAqB;AAAAqB,MAAAA,QAAA,gBAClCF,IAAA,CAAA,KAAA,EAAA;AAAKnB,QAAAA,SAAS,EAAC,mBAAmB;QAAAqB,QAAA,EAAA,cAChCC,GAAA,CAACM,IAAI,EAAA;UAACC,IAAI,EAAEC,UAAU,CAACC,UAAW;AAAC/B,UAAAA,SAAS,EAAEoB,IAAI,CAAC,gBAAgB,CAAE;AAAAC,UAAAA,QAAA,EAClE7B;AAAK,SACF,CACN,EACCC,IAAI,iBACH6B,GAAA,CAACU,IAAI,EAAA;AACHtC,UAAAA,IAAI,EAAEA,IAAK;UACXmC,IAAI,EAAEC,UAAU,CAACG,UAAW;AAC5BjC,UAAAA,SAAS,EAAC,gBAAgB;AAC1BL,UAAAA,OAAO,EAAEA,OAAQ;AAAA0B,UAAAA,QAAA,EAEhB5B;AAAI,SACD,CACP,EACAQ,MAAM,iBACLqB,GAAA,CAACU,IAAI,EAAA;UACHtC,IAAI,EAAEO,MAAM,CAACP,IAAK;UAClBwC,MAAM,EAAEjC,MAAM,CAACiC,MAAO;AACtBlC,UAAAA,SAAS,EAAC,OAAO;UACjB,YAAA,EAAYC,MAAM,CAAC,YAAY,CAAE;UACjC4B,IAAI,EAAEC,UAAU,CAACG,UAAW;UAC5BtC,OAAO,EAAEM,MAAM,CAACN,OAAQ;UAAA0B,QAAA,EAEvBpB,MAAM,CAACkC;AAAI,SACR,CACP;OACE,CACL,EAACvC,SAAS,IAAIC,gBAAgB,gBAC5ByB,GAAA,CAACc,UAAU,EAAA;AACTX,QAAAA,IAAI,EAAE,EAAG;AACTY,QAAAA,QAAQ,EAAC,UAAU;AACnB,QAAA,YAAA,EAAYnC,IAAI,CAACoC,aAAa,CAACC,gBAAgB,CAACC,SAAS,CAAE;AAC3D7C,QAAAA,OAAO,EAAEmB,eAAgB;AAAAO,QAAAA,QAAA,eAEzBC,GAAA,CAACmB,KAAK,EAAA,EAAA;OACI,CAAC,GACX,IAAI;AAAA,KACL,CACP;AAAA,GAAK,CAAC;AAEV;;;;"}
1
+ {"version":3,"file":"Nudge.mjs","sources":["../../src/Nudge/Nudge.tsx"],"sourcesContent":["import { Illustration, Assets } from '@wise/art';\nimport { clsx } from 'clsx';\nimport { ReactNode, useEffect, useState, MouseEvent, useCallback } from 'react';\n\nimport Body from '../Body';\nimport { Typography } from '../common';\nimport Link from '../Link';\nimport type { AlertAction } from '../_deprecated/Alert';\nimport IconButton from '../IconButton';\nimport { Cross } from '@transferwise/icons';\nimport { useIntl } from 'react-intl';\nimport closeBtnMessages from '../common/CloseButton/CloseButton.messages';\n\n// WARNING: Changing this will cause nudges to reappear wherever persist nudge is used and privacy team will need to be updated too\nexport const STORAGE_NAME = 'dismissedNudges';\n\nconst getLocalStorage = (): string[] => {\n try {\n const storageItem = localStorage.getItem(STORAGE_NAME);\n\n if (storageItem) {\n const storage: unknown = JSON.parse(storageItem);\n\n if (Array.isArray(storage)) {\n return storage.map((item) => String(item));\n }\n }\n } catch {}\n\n return [];\n};\n\ntype MediaNameType =\n | `${Assets.GLOBE}`\n | `${Assets.LOCK}`\n | `${Assets.WALLET}`\n | `${Assets.GEAR}`\n | `${Assets.INVITE_LETTER}`\n | `${Assets.PERSONAL_CARD}`\n | `${Assets.BUSINESS_CARD}`\n | `${Assets.HEART}`\n | `${Assets.MULTI_CURRENCY}`\n | `${Assets.SHOPPING_BAG}`\n | `${Assets.FLOWER}`\n | `${Assets.GIFT_BOX}`\n | `${Assets.BACKPACK}`\n | `${Assets.DOCUMENTS}`;\n\ntype BaseProps = {\n /**\n * @deprecated Use `mediaName` instead.\n * Legacy custom media content is no longer used by `Nudge`.\n */\n media?: ReactNode;\n /**\n * Illustration asset name shown at the start of the nudge.\n */\n mediaName?: MediaNameType;\n /** Main nudge message content. */\n title: ReactNode;\n /**\n * Legacy CTA label content.\n * Rendered only when `action` is not provided.\n */\n link?: ReactNode;\n /**\n * Legacy CTA destination for `link`.\n * Ignored when `action` is provided.\n */\n href?: string;\n /**\n * Legacy click handler for `link`.\n * Ignored when `action` is provided.\n */\n onClick?: (event?: MouseEvent<HTMLSpanElement>) => void;\n /** Fired when the user clicks on close button */\n onDismiss?: () => void;\n /**\n * Preferred CTA configuration rendered under the nudge body.\n * Single CTA rule: when `action` is provided, legacy `link`/`href` is not rendered.\n * If your label is short, use `aria-label` to provide more context.\n */\n action?: AlertAction;\n /** Optional class name applied to the root nudge container. */\n className?: string;\n};\n\nexport interface OptionalId extends BaseProps {\n id?: string;\n persistDismissal?: false;\n isPreviouslyDismissed?: undefined;\n}\n\nexport interface RequiredPersistProps extends BaseProps {\n /** This ID should be completely unique to the page and feature as it uses a shared array which could conflict with other nudges in Wise */\n id: string;\n /** Use persist dismissal to keep the nudge dismissed using the browser's localStorage */\n persistDismissal: true;\n /**\n * Fired on mount for determining if nudge has been dismissed before\n *\n * @param {boolean} value - set to true if dismissed previously\n */\n isPreviouslyDismissed?: (value: boolean) => void;\n}\n\nexport type NudgeProps = OptionalId | RequiredPersistProps;\n\nconst Nudge = ({\n mediaName,\n title,\n link,\n href,\n onClick,\n onDismiss,\n persistDismissal,\n isPreviouslyDismissed,\n id,\n className,\n action,\n}: NudgeProps) => {\n const intl = useIntl();\n const hasLegacyLink = Boolean(link);\n const hasAction = action != null;\n const shouldRenderLegacyLink = hasLegacyLink && !hasAction;\n\n useEffect(() => {\n if (process.env.NODE_ENV !== 'production' && hasAction && (hasLegacyLink || href != null)) {\n // eslint-disable-next-line no-console -- Intentional developer warning for conflicting API usage.\n console.warn(\n 'Nudge received both action and link/href props. Rendering action only. Remove link/href to silence this warning.',\n );\n }\n }, [hasAction, hasLegacyLink, href]);\n\n const getIsDismissed = useCallback(\n () => (persistDismissal && id ? !!getLocalStorage()?.find((item) => item === id) : false),\n [persistDismissal, id],\n );\n\n const [nudgeState, setNudgeState] = useState(() => ({\n isDismissed: getIsDismissed(),\n isMounted: false,\n }));\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- Setting mount state in mount effect\n setNudgeState((prev) => ({ ...prev, isMounted: true }));\n }, []);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect -- Syncing dismissed state from localStorage on prop change\n setNudgeState((prev) => ({ ...prev, isDismissed: getIsDismissed() }));\n }, [getIsDismissed, id, persistDismissal]);\n\n const { isDismissed } = nudgeState;\n\n const handleOnDismiss = () => {\n const dismissedNudgesStorage = getLocalStorage();\n\n if (persistDismissal && id) {\n try {\n localStorage.setItem(STORAGE_NAME, JSON.stringify([...dismissedNudgesStorage, id]));\n } catch {}\n\n setNudgeState((prev) => ({ ...prev, isDismissed: true }));\n }\n\n if (onDismiss) {\n onDismiss();\n }\n };\n\n useEffect(() => {\n if (persistDismissal && id && isPreviouslyDismissed) {\n const dismissedNudgesStorage = getLocalStorage();\n const wasDismissed = !!dismissedNudgesStorage?.find((item) => item === id);\n isPreviouslyDismissed(wasDismissed);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [id, persistDismissal]);\n\n if (persistDismissal && (isDismissed || !nudgeState.isMounted)) {\n return null;\n }\n\n return (\n <div className={clsx('wds-nudge', className)} id={id}>\n {!!mediaName && (\n <div className=\"wds-nudge-media\">\n <Illustration\n name={mediaName}\n className={clsx(`wds-nudge-media-${mediaName}`)}\n size=\"small\"\n disablePadding\n alt=\"\"\n />\n </div>\n )}\n <div className=\"wds-nudge-container\">\n <div className=\"wds-nudge-content\">\n <Body type={Typography.BODY_LARGE} className={clsx('wds-nudge-body')}>\n {title}\n </Body>\n {shouldRenderLegacyLink && (\n <Link\n href={href}\n type={Typography.LINK_LARGE}\n className=\"wds-nudge-link\"\n onClick={onClick}\n >\n {link}\n </Link>\n )}\n {action && (\n <Link\n href={action.href}\n target={action.target}\n className=\"m-t-1\"\n aria-label={action['aria-label']}\n type={Typography.LINK_LARGE}\n onClick={action.onClick}\n >\n {action.text}\n </Link>\n )}\n </div>\n {onDismiss || persistDismissal ? (\n <IconButton\n size={24}\n priority=\"tertiary\"\n aria-label={intl.formatMessage(closeBtnMessages.ariaLabel)}\n onClick={handleOnDismiss}\n >\n <Cross />\n </IconButton>\n ) : null}\n </div>\n </div>\n );\n};\n\nexport default Nudge;\n"],"names":["STORAGE_NAME","getLocalStorage","storageItem","localStorage","getItem","storage","JSON","parse","Array","isArray","map","item","String","Nudge","mediaName","title","link","href","onClick","onDismiss","persistDismissal","isPreviouslyDismissed","id","className","action","intl","useIntl","hasLegacyLink","Boolean","hasAction","shouldRenderLegacyLink","useEffect","process","env","NODE_ENV","console","warn","getIsDismissed","useCallback","find","nudgeState","setNudgeState","useState","isDismissed","isMounted","prev","handleOnDismiss","dismissedNudgesStorage","setItem","stringify","wasDismissed","_jsxs","clsx","children","_jsx","Illustration","name","size","disablePadding","alt","Body","type","Typography","BODY_LARGE","Link","LINK_LARGE","target","text","IconButton","priority","formatMessage","closeBtnMessages","ariaLabel","Cross"],"mappings":"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"}
@@ -37,6 +37,7 @@ const Sticky = ({
37
37
  testId
38
38
  }) => {
39
39
  return /*#__PURE__*/jsxRuntime.jsx(SlidingPanel.default, {
40
+ className: "wds-sticky",
40
41
  testId: testId,
41
42
  open: open,
42
43
  position: position$1,
@@ -1 +1 @@
1
- {"version":3,"file":"Sticky.js","sources":["../../src/Sticky/Sticky.tsx"],"sourcesContent":["import { Position } from '../common';\nimport SlidingPanel from '../SlidingPanel';\nimport { FunctionComponent } from 'react';\n\nexport interface StickyProps {\n /** Optional prop for children components to be rendered inside the Sticky component. */\n children?: React.ReactNode;\n\n /** Optional props that determines if the Sticky component is open or closed. Default value is `true`. */\n open?: boolean;\n\n /** Optional props that specifies the position of the Sticky component on the screen. Can be either `top` or `bottom`. */\n position?: `${Position.TOP}` | `${Position.BOTTOM}`;\n\n /** Optional prop to specify the ID used for testing */\n testId?: string;\n}\n\n/**\n * ### Sticky Component\n *\n * `<Sticky />` is a component that renders a `<SlidingPanel />` with specified props.\n * It uses the `<SlidingPanel />` component to create a panel that can slide in and out of view,\n * based on the `open` prop. It can be positioned at the top or bottom of the container,\n * as specified by the `position` prop.\n *\n * @component\n * @param {ReactNode} children - Children content.\n * @param {boolean} open - Determines if the Sticky component is open or closed.\n * @param {('top'|'bottom')} position - Specifies the position.\n * @param {string} testId - ID used for testing.\n * @returns {React.JSX.Element} The `SlidingPanel` component with applied props.\n * @example\n * <Button onClick={() => setOpen(!open)}>Open Sticky</Button>\n * <Sticky open={open} position={'bottom'}>\n * <div>\n * <Button onClick={() => setOpen(!open)}>Close Sticky</Button>\n * </div>\n * </Sticky>\n */\nconst Sticky: FunctionComponent<StickyProps> = ({\n children,\n open = true,\n position = Position.BOTTOM,\n testId,\n}: StickyProps) => {\n return (\n <SlidingPanel\n testId={testId}\n open={open}\n position={position}\n slidingPanelPositionFixed\n showSlidingPanelBorder\n >\n {children}\n </SlidingPanel>\n );\n};\n\nexport default Sticky;\n"],"names":["Sticky","children","open","position","Position","BOTTOM","testId","_jsx","SlidingPanel","slidingPanelPositionFixed","showSlidingPanelBorder"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAMA,MAAM,GAAmCA,CAAC;EAC9CC,QAAQ;AACRC,EAAAA,IAAI,GAAG,IAAI;YACXC,UAAQ,GAAGC,iBAAQ,CAACC,MAAM;AAC1BC,EAAAA;AAAM,CACM,KAAI;EAChB,oBACEC,cAAA,CAACC,oBAAY,EAAA;AACXF,IAAAA,MAAM,EAAEA,MAAO;AACfJ,IAAAA,IAAI,EAAEA,IAAK;AACXC,IAAAA,QAAQ,EAAEA,UAAS;IACnBM,yBAAyB,EAAA,IAAA;IACzBC,sBAAsB,EAAA,IAAA;AAAAT,IAAAA,QAAA,EAErBA;AAAQ,GACG,CAAC;AAEnB;;;;"}
1
+ {"version":3,"file":"Sticky.js","sources":["../../src/Sticky/Sticky.tsx"],"sourcesContent":["import { Position } from '../common';\nimport SlidingPanel from '../SlidingPanel';\nimport { FunctionComponent } from 'react';\n\nexport interface StickyProps {\n /** Optional prop for children components to be rendered inside the Sticky component. */\n children?: React.ReactNode;\n\n /** Optional props that determines if the Sticky component is open or closed. Default value is `true`. */\n open?: boolean;\n\n /** Optional props that specifies the position of the Sticky component on the screen. Can be either `top` or `bottom`. */\n position?: `${Position.TOP}` | `${Position.BOTTOM}`;\n\n /** Optional prop to specify the ID used for testing */\n testId?: string;\n}\n\n/**\n * ### Sticky Component\n *\n * `<Sticky />` is a component that renders a `<SlidingPanel />` with specified props.\n * It uses the `<SlidingPanel />` component to create a panel that can slide in and out of view,\n * based on the `open` prop. It can be positioned at the top or bottom of the container,\n * as specified by the `position` prop.\n *\n * @component\n * @param {ReactNode} children - Children content.\n * @param {boolean} open - Determines if the Sticky component is open or closed.\n * @param {('top'|'bottom')} position - Specifies the position.\n * @param {string} testId - ID used for testing.\n * @returns {React.JSX.Element} The `SlidingPanel` component with applied props.\n * @example\n * <Button onClick={() => setOpen(!open)}>Open Sticky</Button>\n * <Sticky open={open} position={'bottom'}>\n * <div>\n * <Button onClick={() => setOpen(!open)}>Close Sticky</Button>\n * </div>\n * </Sticky>\n */\nconst Sticky: FunctionComponent<StickyProps> = ({\n children,\n open = true,\n position = Position.BOTTOM,\n testId,\n}: StickyProps) => {\n return (\n <SlidingPanel\n className=\"wds-sticky\"\n testId={testId}\n open={open}\n position={position}\n slidingPanelPositionFixed\n showSlidingPanelBorder\n >\n {children}\n </SlidingPanel>\n );\n};\n\nexport default Sticky;\n"],"names":["Sticky","children","open","position","Position","BOTTOM","testId","_jsx","SlidingPanel","className","slidingPanelPositionFixed","showSlidingPanelBorder"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAMA,MAAM,GAAmCA,CAAC;EAC9CC,QAAQ;AACRC,EAAAA,IAAI,GAAG,IAAI;YACXC,UAAQ,GAAGC,iBAAQ,CAACC,MAAM;AAC1BC,EAAAA;AAAM,CACM,KAAI;EAChB,oBACEC,cAAA,CAACC,oBAAY,EAAA;AACXC,IAAAA,SAAS,EAAC,YAAY;AACtBH,IAAAA,MAAM,EAAEA,MAAO;AACfJ,IAAAA,IAAI,EAAEA,IAAK;AACXC,IAAAA,QAAQ,EAAEA,UAAS;IACnBO,yBAAyB,EAAA,IAAA;IACzBC,sBAAsB,EAAA,IAAA;AAAAV,IAAAA,QAAA,EAErBA;AAAQ,GACG,CAAC;AAEnB;;;;"}
@@ -33,6 +33,7 @@ const Sticky = ({
33
33
  testId
34
34
  }) => {
35
35
  return /*#__PURE__*/jsx(SlidingPanel, {
36
+ className: "wds-sticky",
36
37
  testId: testId,
37
38
  open: open,
38
39
  position: position,
@@ -1 +1 @@
1
- {"version":3,"file":"Sticky.mjs","sources":["../../src/Sticky/Sticky.tsx"],"sourcesContent":["import { Position } from '../common';\nimport SlidingPanel from '../SlidingPanel';\nimport { FunctionComponent } from 'react';\n\nexport interface StickyProps {\n /** Optional prop for children components to be rendered inside the Sticky component. */\n children?: React.ReactNode;\n\n /** Optional props that determines if the Sticky component is open or closed. Default value is `true`. */\n open?: boolean;\n\n /** Optional props that specifies the position of the Sticky component on the screen. Can be either `top` or `bottom`. */\n position?: `${Position.TOP}` | `${Position.BOTTOM}`;\n\n /** Optional prop to specify the ID used for testing */\n testId?: string;\n}\n\n/**\n * ### Sticky Component\n *\n * `<Sticky />` is a component that renders a `<SlidingPanel />` with specified props.\n * It uses the `<SlidingPanel />` component to create a panel that can slide in and out of view,\n * based on the `open` prop. It can be positioned at the top or bottom of the container,\n * as specified by the `position` prop.\n *\n * @component\n * @param {ReactNode} children - Children content.\n * @param {boolean} open - Determines if the Sticky component is open or closed.\n * @param {('top'|'bottom')} position - Specifies the position.\n * @param {string} testId - ID used for testing.\n * @returns {React.JSX.Element} The `SlidingPanel` component with applied props.\n * @example\n * <Button onClick={() => setOpen(!open)}>Open Sticky</Button>\n * <Sticky open={open} position={'bottom'}>\n * <div>\n * <Button onClick={() => setOpen(!open)}>Close Sticky</Button>\n * </div>\n * </Sticky>\n */\nconst Sticky: FunctionComponent<StickyProps> = ({\n children,\n open = true,\n position = Position.BOTTOM,\n testId,\n}: StickyProps) => {\n return (\n <SlidingPanel\n testId={testId}\n open={open}\n position={position}\n slidingPanelPositionFixed\n showSlidingPanelBorder\n >\n {children}\n </SlidingPanel>\n );\n};\n\nexport default Sticky;\n"],"names":["Sticky","children","open","position","Position","BOTTOM","testId","_jsx","SlidingPanel","slidingPanelPositionFixed","showSlidingPanelBorder"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAMA,MAAM,GAAmCA,CAAC;EAC9CC,QAAQ;AACRC,EAAAA,IAAI,GAAG,IAAI;EACXC,QAAQ,GAAGC,QAAQ,CAACC,MAAM;AAC1BC,EAAAA;AAAM,CACM,KAAI;EAChB,oBACEC,GAAA,CAACC,YAAY,EAAA;AACXF,IAAAA,MAAM,EAAEA,MAAO;AACfJ,IAAAA,IAAI,EAAEA,IAAK;AACXC,IAAAA,QAAQ,EAAEA,QAAS;IACnBM,yBAAyB,EAAA,IAAA;IACzBC,sBAAsB,EAAA,IAAA;AAAAT,IAAAA,QAAA,EAErBA;AAAQ,GACG,CAAC;AAEnB;;;;"}
1
+ {"version":3,"file":"Sticky.mjs","sources":["../../src/Sticky/Sticky.tsx"],"sourcesContent":["import { Position } from '../common';\nimport SlidingPanel from '../SlidingPanel';\nimport { FunctionComponent } from 'react';\n\nexport interface StickyProps {\n /** Optional prop for children components to be rendered inside the Sticky component. */\n children?: React.ReactNode;\n\n /** Optional props that determines if the Sticky component is open or closed. Default value is `true`. */\n open?: boolean;\n\n /** Optional props that specifies the position of the Sticky component on the screen. Can be either `top` or `bottom`. */\n position?: `${Position.TOP}` | `${Position.BOTTOM}`;\n\n /** Optional prop to specify the ID used for testing */\n testId?: string;\n}\n\n/**\n * ### Sticky Component\n *\n * `<Sticky />` is a component that renders a `<SlidingPanel />` with specified props.\n * It uses the `<SlidingPanel />` component to create a panel that can slide in and out of view,\n * based on the `open` prop. It can be positioned at the top or bottom of the container,\n * as specified by the `position` prop.\n *\n * @component\n * @param {ReactNode} children - Children content.\n * @param {boolean} open - Determines if the Sticky component is open or closed.\n * @param {('top'|'bottom')} position - Specifies the position.\n * @param {string} testId - ID used for testing.\n * @returns {React.JSX.Element} The `SlidingPanel` component with applied props.\n * @example\n * <Button onClick={() => setOpen(!open)}>Open Sticky</Button>\n * <Sticky open={open} position={'bottom'}>\n * <div>\n * <Button onClick={() => setOpen(!open)}>Close Sticky</Button>\n * </div>\n * </Sticky>\n */\nconst Sticky: FunctionComponent<StickyProps> = ({\n children,\n open = true,\n position = Position.BOTTOM,\n testId,\n}: StickyProps) => {\n return (\n <SlidingPanel\n className=\"wds-sticky\"\n testId={testId}\n open={open}\n position={position}\n slidingPanelPositionFixed\n showSlidingPanelBorder\n >\n {children}\n </SlidingPanel>\n );\n};\n\nexport default Sticky;\n"],"names":["Sticky","children","open","position","Position","BOTTOM","testId","_jsx","SlidingPanel","className","slidingPanelPositionFixed","showSlidingPanelBorder"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,MAAMA,MAAM,GAAmCA,CAAC;EAC9CC,QAAQ;AACRC,EAAAA,IAAI,GAAG,IAAI;EACXC,QAAQ,GAAGC,QAAQ,CAACC,MAAM;AAC1BC,EAAAA;AAAM,CACM,KAAI;EAChB,oBACEC,GAAA,CAACC,YAAY,EAAA;AACXC,IAAAA,SAAS,EAAC,YAAY;AACtBH,IAAAA,MAAM,EAAEA,MAAO;AACfJ,IAAAA,IAAI,EAAEA,IAAK;AACXC,IAAAA,QAAQ,EAAEA,QAAS;IACnBO,yBAAyB,EAAA,IAAA;IACzBC,sBAAsB,EAAA,IAAA;AAAAV,IAAAA,QAAA,EAErBA;AAAQ,GACG,CAAC;AAEnB;;;;"}
@@ -64,6 +64,7 @@ const Title = /*#__PURE__*/React__default.default.forwardRef(({
64
64
  className: clsx.clsx(`np-text-${DEFAULT_TYPE}`, className)
65
65
  });
66
66
  });
67
+ Title.displayName = 'Title';
67
68
 
68
69
  exports.default = Title;
69
70
  //# sourceMappingURL=Title.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Title.js","sources":["../../src/Title/Title.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport React, { forwardRef, LabelHTMLAttributes, LiHTMLAttributes } from 'react';\n\nimport { TitleTypes, Typography, Heading } from '../common';\n\nconst DEFAULT_TYPE = Typography.TITLE_GROUP;\n\nconst titleTypeMapping = {\n [Typography.TITLE_SCREEN]: 'h1',\n [Typography.TITLE_SECTION]: 'h2',\n [Typography.TITLE_SUBSECTION]: 'h3',\n [Typography.TITLE_BODY]: 'h4',\n [Typography.TITLE_GROUP]: 'h5',\n} as const;\n\ntype Props = LabelHTMLAttributes<HTMLHeadingElement | HTMLSpanElement | HTMLLabelElement> &\n LiHTMLAttributes<HTMLLIElement> & {\n /**\n * Default value will based one `type` prop\n */\n as?: 'span' | 'label' | 'li' | 'legend' | 'header' | Heading;\n /**\n * Default value: {@link DEFAULT_TYPE}\n */\n type?: TitleTypes;\n };\n\nconst Title = React.forwardRef<HTMLHeadingElement | HTMLSpanElement | HTMLLabelElement, Props>(\n ({ as, type = DEFAULT_TYPE, className, ...props }, ref) => {\n const mapping = titleTypeMapping[type as keyof typeof titleTypeMapping];\n const isTypeSupported = mapping !== undefined;\n if (isTypeSupported) {\n const HeaderTag = as ?? mapping;\n return (\n <HeaderTag\n ref={ref as React.Ref<any>}\n {...props}\n className={clsx(`np-text-${type}`, className)}\n />\n );\n }\n const HeaderTag = as ?? titleTypeMapping[DEFAULT_TYPE];\n return (\n <HeaderTag\n ref={ref as React.Ref<any>}\n {...props}\n className={clsx(`np-text-${DEFAULT_TYPE}`, className)}\n />\n );\n },\n);\n\nexport default Title;\n"],"names":["DEFAULT_TYPE","Typography","TITLE_GROUP","titleTypeMapping","TITLE_SCREEN","TITLE_SECTION","TITLE_SUBSECTION","TITLE_BODY","Title","React","forwardRef","as","type","className","props","ref","mapping","isTypeSupported","undefined","HeaderTag","_jsx","clsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAMA,YAAY,GAAGC,qBAAU,CAACC,WAAW;AAE3C,MAAMC,gBAAgB,GAAG;AACvB,EAAA,CAACF,qBAAU,CAACG,YAAY,GAAG,IAAI;AAC/B,EAAA,CAACH,qBAAU,CAACI,aAAa,GAAG,IAAI;AAChC,EAAA,CAACJ,qBAAU,CAACK,gBAAgB,GAAG,IAAI;AACnC,EAAA,CAACL,qBAAU,CAACM,UAAU,GAAG,IAAI;EAC7B,CAACN,qBAAU,CAACC,WAAW,GAAG;CAClB;AAcV,MAAMM,KAAK,gBAAGC,sBAAK,CAACC,UAAU,CAC5B,CAAC;EAAEC,EAAE;AAAEC,EAAAA,IAAI,GAAGZ,YAAY;EAAEa,SAAS;EAAE,GAAGC;AAAK,CAAE,EAAEC,GAAG,KAAI;AACxD,EAAA,MAAMC,OAAO,GAAGb,gBAAgB,CAACS,IAAqC,CAAC;AACvE,EAAA,MAAMK,eAAe,GAAGD,OAAO,KAAKE,SAAS;AAC7C,EAAA,IAAID,eAAe,EAAE;AACnB,IAAA,MAAME,SAAS,GAAGR,EAAE,IAAIK,OAAO;IAC/B,oBACEI,cAAA,CAACD,SAAS,EAAA;AACRJ,MAAAA,GAAG,EAAEA,GAAsB;AAAA,MAAA,GACvBD,KAAK;AACTD,MAAAA,SAAS,EAAEQ,SAAI,CAAC,WAAWT,IAAI,CAAA,CAAE,EAAEC,SAAS;AAAE,KAAA,CAC9C;AAEN,EAAA;AACA,EAAA,MAAMM,SAAS,GAAGR,EAAE,IAAIR,gBAAgB,CAACH,YAAY,CAAC;EACtD,oBACEoB,cAAA,CAACD,SAAS,EAAA;AACRJ,IAAAA,GAAG,EAAEA,GAAsB;AAAA,IAAA,GACvBD,KAAK;AACTD,IAAAA,SAAS,EAAEQ,SAAI,CAAC,WAAWrB,YAAY,CAAA,CAAE,EAAEa,SAAS;AAAE,GAAA,CACtD;AAEN,CAAC;;;;"}
1
+ {"version":3,"file":"Title.js","sources":["../../src/Title/Title.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport React, { LabelHTMLAttributes, LiHTMLAttributes } from 'react';\n\nimport { TitleTypes, Typography, Heading } from '../common';\n\nconst DEFAULT_TYPE = Typography.TITLE_GROUP;\n\nconst titleTypeMapping = {\n [Typography.TITLE_SCREEN]: 'h1',\n [Typography.TITLE_SECTION]: 'h2',\n [Typography.TITLE_SUBSECTION]: 'h3',\n [Typography.TITLE_BODY]: 'h4',\n [Typography.TITLE_GROUP]: 'h5',\n} as const;\n\nexport type TitleProps = LabelHTMLAttributes<\n HTMLHeadingElement | HTMLSpanElement | HTMLLabelElement\n> &\n LiHTMLAttributes<HTMLLIElement> & {\n /**\n * Default value will based one `type` prop\n */\n as?: 'span' | 'label' | 'li' | 'legend' | 'header' | Heading;\n /**\n * Default value: {@link DEFAULT_TYPE}\n */\n type?: TitleTypes;\n };\n\nconst Title = React.forwardRef<\n HTMLHeadingElement | HTMLSpanElement | HTMLLabelElement | HTMLLIElement | HTMLLegendElement,\n TitleProps\n>(({ as, type = DEFAULT_TYPE, className, ...props }, ref) => {\n const mapping = titleTypeMapping[type as keyof typeof titleTypeMapping];\n const isTypeSupported = mapping !== undefined;\n if (isTypeSupported) {\n const HeaderTag = as ?? mapping;\n return (\n <HeaderTag\n ref={ref as React.Ref<any>}\n {...props}\n className={clsx(`np-text-${type}`, className)}\n />\n );\n }\n const HeaderTag = as ?? titleTypeMapping[DEFAULT_TYPE];\n return (\n <HeaderTag\n ref={ref as React.Ref<any>}\n {...props}\n className={clsx(`np-text-${DEFAULT_TYPE}`, className)}\n />\n );\n});\n\nTitle.displayName = 'Title';\n\nexport default Title;\n"],"names":["DEFAULT_TYPE","Typography","TITLE_GROUP","titleTypeMapping","TITLE_SCREEN","TITLE_SECTION","TITLE_SUBSECTION","TITLE_BODY","Title","React","forwardRef","as","type","className","props","ref","mapping","isTypeSupported","undefined","HeaderTag","_jsx","clsx","displayName"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAMA,YAAY,GAAGC,qBAAU,CAACC,WAAW;AAE3C,MAAMC,gBAAgB,GAAG;AACvB,EAAA,CAACF,qBAAU,CAACG,YAAY,GAAG,IAAI;AAC/B,EAAA,CAACH,qBAAU,CAACI,aAAa,GAAG,IAAI;AAChC,EAAA,CAACJ,qBAAU,CAACK,gBAAgB,GAAG,IAAI;AACnC,EAAA,CAACL,qBAAU,CAACM,UAAU,GAAG,IAAI;EAC7B,CAACN,qBAAU,CAACC,WAAW,GAAG;CAClB;AAgBV,MAAMM,KAAK,gBAAGC,sBAAK,CAACC,UAAU,CAG5B,CAAC;EAAEC,EAAE;AAAEC,EAAAA,IAAI,GAAGZ,YAAY;EAAEa,SAAS;EAAE,GAAGC;AAAK,CAAE,EAAEC,GAAG,KAAI;AAC1D,EAAA,MAAMC,OAAO,GAAGb,gBAAgB,CAACS,IAAqC,CAAC;AACvE,EAAA,MAAMK,eAAe,GAAGD,OAAO,KAAKE,SAAS;AAC7C,EAAA,IAAID,eAAe,EAAE;AACnB,IAAA,MAAME,SAAS,GAAGR,EAAE,IAAIK,OAAO;IAC/B,oBACEI,cAAA,CAACD,SAAS,EAAA;AACRJ,MAAAA,GAAG,EAAEA,GAAsB;AAAA,MAAA,GACvBD,KAAK;AACTD,MAAAA,SAAS,EAAEQ,SAAI,CAAC,WAAWT,IAAI,CAAA,CAAE,EAAEC,SAAS;AAAE,KAAA,CAC9C;AAEN,EAAA;AACA,EAAA,MAAMM,SAAS,GAAGR,EAAE,IAAIR,gBAAgB,CAACH,YAAY,CAAC;EACtD,oBACEoB,cAAA,CAACD,SAAS,EAAA;AACRJ,IAAAA,GAAG,EAAEA,GAAsB;AAAA,IAAA,GACvBD,KAAK;AACTD,IAAAA,SAAS,EAAEQ,SAAI,CAAC,WAAWrB,YAAY,CAAA,CAAE,EAAEa,SAAS;AAAE,GAAA,CACtD;AAEN,CAAC;AAEDL,KAAK,CAACc,WAAW,GAAG,OAAO;;;;"}
@@ -56,6 +56,7 @@ const Title = /*#__PURE__*/React__default.forwardRef(({
56
56
  className: clsx(`np-text-${DEFAULT_TYPE}`, className)
57
57
  });
58
58
  });
59
+ Title.displayName = 'Title';
59
60
 
60
61
  export { Title as default };
61
62
  //# sourceMappingURL=Title.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"Title.mjs","sources":["../../src/Title/Title.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport React, { forwardRef, LabelHTMLAttributes, LiHTMLAttributes } from 'react';\n\nimport { TitleTypes, Typography, Heading } from '../common';\n\nconst DEFAULT_TYPE = Typography.TITLE_GROUP;\n\nconst titleTypeMapping = {\n [Typography.TITLE_SCREEN]: 'h1',\n [Typography.TITLE_SECTION]: 'h2',\n [Typography.TITLE_SUBSECTION]: 'h3',\n [Typography.TITLE_BODY]: 'h4',\n [Typography.TITLE_GROUP]: 'h5',\n} as const;\n\ntype Props = LabelHTMLAttributes<HTMLHeadingElement | HTMLSpanElement | HTMLLabelElement> &\n LiHTMLAttributes<HTMLLIElement> & {\n /**\n * Default value will based one `type` prop\n */\n as?: 'span' | 'label' | 'li' | 'legend' | 'header' | Heading;\n /**\n * Default value: {@link DEFAULT_TYPE}\n */\n type?: TitleTypes;\n };\n\nconst Title = React.forwardRef<HTMLHeadingElement | HTMLSpanElement | HTMLLabelElement, Props>(\n ({ as, type = DEFAULT_TYPE, className, ...props }, ref) => {\n const mapping = titleTypeMapping[type as keyof typeof titleTypeMapping];\n const isTypeSupported = mapping !== undefined;\n if (isTypeSupported) {\n const HeaderTag = as ?? mapping;\n return (\n <HeaderTag\n ref={ref as React.Ref<any>}\n {...props}\n className={clsx(`np-text-${type}`, className)}\n />\n );\n }\n const HeaderTag = as ?? titleTypeMapping[DEFAULT_TYPE];\n return (\n <HeaderTag\n ref={ref as React.Ref<any>}\n {...props}\n className={clsx(`np-text-${DEFAULT_TYPE}`, className)}\n />\n );\n },\n);\n\nexport default Title;\n"],"names":["DEFAULT_TYPE","Typography","TITLE_GROUP","titleTypeMapping","TITLE_SCREEN","TITLE_SECTION","TITLE_SUBSECTION","TITLE_BODY","Title","React","forwardRef","as","type","className","props","ref","mapping","isTypeSupported","undefined","HeaderTag","_jsx","clsx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAMA,YAAY,GAAGC,UAAU,CAACC,WAAW;AAE3C,MAAMC,gBAAgB,GAAG;AACvB,EAAA,CAACF,UAAU,CAACG,YAAY,GAAG,IAAI;AAC/B,EAAA,CAACH,UAAU,CAACI,aAAa,GAAG,IAAI;AAChC,EAAA,CAACJ,UAAU,CAACK,gBAAgB,GAAG,IAAI;AACnC,EAAA,CAACL,UAAU,CAACM,UAAU,GAAG,IAAI;EAC7B,CAACN,UAAU,CAACC,WAAW,GAAG;CAClB;AAcV,MAAMM,KAAK,gBAAGC,cAAK,CAACC,UAAU,CAC5B,CAAC;EAAEC,EAAE;AAAEC,EAAAA,IAAI,GAAGZ,YAAY;EAAEa,SAAS;EAAE,GAAGC;AAAK,CAAE,EAAEC,GAAG,KAAI;AACxD,EAAA,MAAMC,OAAO,GAAGb,gBAAgB,CAACS,IAAqC,CAAC;AACvE,EAAA,MAAMK,eAAe,GAAGD,OAAO,KAAKE,SAAS;AAC7C,EAAA,IAAID,eAAe,EAAE;AACnB,IAAA,MAAME,SAAS,GAAGR,EAAE,IAAIK,OAAO;IAC/B,oBACEI,GAAA,CAACD,SAAS,EAAA;AACRJ,MAAAA,GAAG,EAAEA,GAAsB;AAAA,MAAA,GACvBD,KAAK;AACTD,MAAAA,SAAS,EAAEQ,IAAI,CAAC,WAAWT,IAAI,CAAA,CAAE,EAAEC,SAAS;AAAE,KAAA,CAC9C;AAEN,EAAA;AACA,EAAA,MAAMM,SAAS,GAAGR,EAAE,IAAIR,gBAAgB,CAACH,YAAY,CAAC;EACtD,oBACEoB,GAAA,CAACD,SAAS,EAAA;AACRJ,IAAAA,GAAG,EAAEA,GAAsB;AAAA,IAAA,GACvBD,KAAK;AACTD,IAAAA,SAAS,EAAEQ,IAAI,CAAC,WAAWrB,YAAY,CAAA,CAAE,EAAEa,SAAS;AAAE,GAAA,CACtD;AAEN,CAAC;;;;"}
1
+ {"version":3,"file":"Title.mjs","sources":["../../src/Title/Title.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport React, { LabelHTMLAttributes, LiHTMLAttributes } from 'react';\n\nimport { TitleTypes, Typography, Heading } from '../common';\n\nconst DEFAULT_TYPE = Typography.TITLE_GROUP;\n\nconst titleTypeMapping = {\n [Typography.TITLE_SCREEN]: 'h1',\n [Typography.TITLE_SECTION]: 'h2',\n [Typography.TITLE_SUBSECTION]: 'h3',\n [Typography.TITLE_BODY]: 'h4',\n [Typography.TITLE_GROUP]: 'h5',\n} as const;\n\nexport type TitleProps = LabelHTMLAttributes<\n HTMLHeadingElement | HTMLSpanElement | HTMLLabelElement\n> &\n LiHTMLAttributes<HTMLLIElement> & {\n /**\n * Default value will based one `type` prop\n */\n as?: 'span' | 'label' | 'li' | 'legend' | 'header' | Heading;\n /**\n * Default value: {@link DEFAULT_TYPE}\n */\n type?: TitleTypes;\n };\n\nconst Title = React.forwardRef<\n HTMLHeadingElement | HTMLSpanElement | HTMLLabelElement | HTMLLIElement | HTMLLegendElement,\n TitleProps\n>(({ as, type = DEFAULT_TYPE, className, ...props }, ref) => {\n const mapping = titleTypeMapping[type as keyof typeof titleTypeMapping];\n const isTypeSupported = mapping !== undefined;\n if (isTypeSupported) {\n const HeaderTag = as ?? mapping;\n return (\n <HeaderTag\n ref={ref as React.Ref<any>}\n {...props}\n className={clsx(`np-text-${type}`, className)}\n />\n );\n }\n const HeaderTag = as ?? titleTypeMapping[DEFAULT_TYPE];\n return (\n <HeaderTag\n ref={ref as React.Ref<any>}\n {...props}\n className={clsx(`np-text-${DEFAULT_TYPE}`, className)}\n />\n );\n});\n\nTitle.displayName = 'Title';\n\nexport default Title;\n"],"names":["DEFAULT_TYPE","Typography","TITLE_GROUP","titleTypeMapping","TITLE_SCREEN","TITLE_SECTION","TITLE_SUBSECTION","TITLE_BODY","Title","React","forwardRef","as","type","className","props","ref","mapping","isTypeSupported","undefined","HeaderTag","_jsx","clsx","displayName"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAKA,MAAMA,YAAY,GAAGC,UAAU,CAACC,WAAW;AAE3C,MAAMC,gBAAgB,GAAG;AACvB,EAAA,CAACF,UAAU,CAACG,YAAY,GAAG,IAAI;AAC/B,EAAA,CAACH,UAAU,CAACI,aAAa,GAAG,IAAI;AAChC,EAAA,CAACJ,UAAU,CAACK,gBAAgB,GAAG,IAAI;AACnC,EAAA,CAACL,UAAU,CAACM,UAAU,GAAG,IAAI;EAC7B,CAACN,UAAU,CAACC,WAAW,GAAG;CAClB;AAgBV,MAAMM,KAAK,gBAAGC,cAAK,CAACC,UAAU,CAG5B,CAAC;EAAEC,EAAE;AAAEC,EAAAA,IAAI,GAAGZ,YAAY;EAAEa,SAAS;EAAE,GAAGC;AAAK,CAAE,EAAEC,GAAG,KAAI;AAC1D,EAAA,MAAMC,OAAO,GAAGb,gBAAgB,CAACS,IAAqC,CAAC;AACvE,EAAA,MAAMK,eAAe,GAAGD,OAAO,KAAKE,SAAS;AAC7C,EAAA,IAAID,eAAe,EAAE;AACnB,IAAA,MAAME,SAAS,GAAGR,EAAE,IAAIK,OAAO;IAC/B,oBACEI,GAAA,CAACD,SAAS,EAAA;AACRJ,MAAAA,GAAG,EAAEA,GAAsB;AAAA,MAAA,GACvBD,KAAK;AACTD,MAAAA,SAAS,EAAEQ,IAAI,CAAC,WAAWT,IAAI,CAAA,CAAE,EAAEC,SAAS;AAAE,KAAA,CAC9C;AAEN,EAAA;AACA,EAAA,MAAMM,SAAS,GAAGR,EAAE,IAAIR,gBAAgB,CAACH,YAAY,CAAC;EACtD,oBACEoB,GAAA,CAACD,SAAS,EAAA;AACRJ,IAAAA,GAAG,EAAEA,GAAsB;AAAA,IAAA,GACvBD,KAAK;AACTD,IAAAA,SAAS,EAAEQ,IAAI,CAAC,WAAWrB,YAAY,CAAA,CAAE,EAAEa,SAAS;AAAE,GAAA,CACtD;AAEN,CAAC;AAEDL,KAAK,CAACc,WAAW,GAAG,OAAO;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Option.js","sources":["../../../../src/_deprecated/Select/Option/Option.tsx"],"sourcesContent":["import { IdIconProps } from '@transferwise/icons';\nimport { Flag } from '@wise/art';\nimport { clsx } from 'clsx';\nimport { cloneElement, ReactElement, ReactNode } from 'react';\n\nimport Body from '../../../Body';\nimport { Typography } from '../../../common';\n\nexport type Props<T> = {\n label: ReactNode;\n value: T;\n currency?: string;\n note?: ReactNode;\n secondary?: ReactNode;\n icon?: ReactNode;\n /** @deprecated */\n classNames?: Record<string, string>;\n selected?: boolean;\n testId?: string;\n};\n\nfunction Option<T>({\n label,\n currency = '',\n note = '',\n secondary = '',\n icon,\n selected = false,\n testId,\n}: Props<T>) {\n const iconElement = icon\n ? cloneElement(icon as ReactElement<IdIconProps>, {\n size: 24,\n className: 'tw-icon',\n })\n : currency && <Flag code={currency.toLowerCase()} intrinsicSize={24} />;\n\n const titleAndNoteElement = (\n <Body as=\"span\" type={Typography.BODY_LARGE} className={selected ? 'text-ellipsis' : undefined}>\n {label}\n {note && (\n <Body as=\"span\" className=\"m-l-1\">\n {note}\n </Body>\n )}\n </Body>\n );\n\n const secondaryElement = secondary && (\n <Body className={clsx(selected && 'text-ellipsis')}>{secondary}</Body>\n );\n\n return iconElement ? (\n <div className=\"d-flex np-option-content\" data-testid={testId}>\n <div className={`d-flex flex-column${selected ? ' justify-content-center' : ''}`}>\n {iconElement}\n </div>\n <div className=\"d-flex flex-column justify-content-center\">\n {titleAndNoteElement}\n {secondaryElement}\n </div>\n </div>\n ) : (\n <>\n {iconElement}\n {titleAndNoteElement}\n {secondaryElement}\n </>\n );\n}\n\nexport default Option;\n"],"names":["Option","label","currency","note","secondary","icon","selected","testId","iconElement","cloneElement","size","className","_jsx","Flag","code","toLowerCase","intrinsicSize","titleAndNoteElement","_jsxs","Body","as","type","Typography","BODY_LARGE","undefined","children","secondaryElement","clsx","_Fragment"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,SAASA,MAAMA,CAAI;EACjBC,KAAK;AACLC,EAAAA,QAAQ,GAAG,EAAE;AACbC,EAAAA,IAAI,GAAG,EAAE;AACTC,EAAAA,SAAS,GAAG,EAAE;EACdC,IAAI;AACJC,EAAAA,QAAQ,GAAG,KAAK;AAChBC,EAAAA;AAAM,CACG,EAAA;AACT,EAAA,MAAMC,WAAW,GAAGH,IAAI,gBACpBI,kBAAY,CAACJ,IAAiC,EAAE;AAC9CK,IAAAA,IAAI,EAAE,EAAE;AACRC,IAAAA,SAAS,EAAE;GACZ,CAAC,GACFT,QAAQ,iBAAIU,cAAA,CAACC,QAAI,EAAA;AAACC,IAAAA,IAAI,EAAEZ,QAAQ,CAACa,WAAW,EAAG;AAACC,IAAAA,aAAa,EAAE;AAAG,GAAA,CAAG;AAEzE,EAAA,MAAMC,mBAAmB,gBACvBC,eAAA,CAACC,YAAI,EAAA;AAACC,IAAAA,EAAE,EAAC,MAAM;IAACC,IAAI,EAAEC,qBAAU,CAACC,UAAW;AAACZ,IAAAA,SAAS,EAAEL,QAAQ,GAAG,eAAe,GAAGkB,SAAU;AAAAC,IAAAA,QAAA,GAC5FxB,KAAK,EACLE,IAAI,iBACHS,cAAA,CAACO,YAAI,EAAA;AAACC,MAAAA,EAAE,EAAC,MAAM;AAACT,MAAAA,SAAS,EAAC,OAAO;AAAAc,MAAAA,QAAA,EAC9BtB;AAAI,KACD,CACP;AAAA,GACG,CACP;AAED,EAAA,MAAMuB,gBAAgB,GAAGtB,SAAS,iBAChCQ,cAAA,CAACO,YAAI,EAAA;AAACR,IAAAA,SAAS,EAAEgB,SAAI,CAACrB,QAAQ,IAAI,eAAe,CAAE;AAAAmB,IAAAA,QAAA,EAAErB;AAAS,GAAO,CACtE;EAED,OAAOI,WAAW,gBAChBU,eAAA,CAAA,KAAA,EAAA;AAAKP,IAAAA,SAAS,EAAC,0BAA0B;AAAC,IAAA,aAAA,EAAaJ,MAAO;AAAAkB,IAAAA,QAAA,gBAC5Db,cAAA,CAAA,KAAA,EAAA;AAAKD,MAAAA,SAAS,EAAE,CAAA,kBAAA,EAAqBL,QAAQ,GAAG,yBAAyB,GAAG,EAAE,CAAA,CAAG;AAAAmB,MAAAA,QAAA,EAC9EjB;KACE,CACL,eAAAU,eAAA,CAAA,KAAA,EAAA;AAAKP,MAAAA,SAAS,EAAC,2CAA2C;MAAAc,QAAA,EAAA,CACvDR,mBAAmB,EACnBS,gBAAgB;AAAA,KACd,CACP;AAAA,GAAK,CAAC,gBAENR,eAAA,CAAAU,mBAAA,EAAA;AAAAH,IAAAA,QAAA,EAAA,CACGjB,WAAW,EACXS,mBAAmB,EACnBS,gBAAgB;AAAA,GACnB,CACD;AACH;;;;"}
1
+ {"version":3,"file":"Option.js","sources":["../../../../src/_deprecated/Select/Option/Option.tsx"],"sourcesContent":["import { IdIconProps } from '@transferwise/icons';\nimport { Flag } from '@wise/art';\nimport { clsx } from 'clsx';\nimport { cloneElement, ReactElement, ReactNode } from 'react';\n\nimport Body from '../../../Body';\nimport { Typography } from '../../../common';\n\nexport type OptionProps<T> = {\n label: ReactNode;\n value: T;\n currency?: string;\n note?: ReactNode;\n secondary?: ReactNode;\n icon?: ReactNode;\n /** @deprecated */\n classNames?: Record<string, string>;\n selected?: boolean;\n testId?: string;\n};\n\nfunction Option<T>({\n label,\n currency = '',\n note = '',\n secondary = '',\n icon,\n selected = false,\n testId,\n}: OptionProps<T>) {\n const iconElement = icon\n ? cloneElement(icon as ReactElement<IdIconProps>, {\n size: 24,\n className: 'tw-icon',\n })\n : currency && <Flag code={currency.toLowerCase()} intrinsicSize={24} />;\n\n const titleAndNoteElement = (\n <Body as=\"span\" type={Typography.BODY_LARGE} className={selected ? 'text-ellipsis' : undefined}>\n {label}\n {note && (\n <Body as=\"span\" className=\"m-l-1\">\n {note}\n </Body>\n )}\n </Body>\n );\n\n const secondaryElement = secondary && (\n <Body className={clsx(selected && 'text-ellipsis')}>{secondary}</Body>\n );\n\n return iconElement ? (\n <div className=\"d-flex np-option-content\" data-testid={testId}>\n <div className={`d-flex flex-column${selected ? ' justify-content-center' : ''}`}>\n {iconElement}\n </div>\n <div className=\"d-flex flex-column justify-content-center\">\n {titleAndNoteElement}\n {secondaryElement}\n </div>\n </div>\n ) : (\n <>\n {iconElement}\n {titleAndNoteElement}\n {secondaryElement}\n </>\n );\n}\n\nexport default Option;\n"],"names":["Option","label","currency","note","secondary","icon","selected","testId","iconElement","cloneElement","size","className","_jsx","Flag","code","toLowerCase","intrinsicSize","titleAndNoteElement","_jsxs","Body","as","type","Typography","BODY_LARGE","undefined","children","secondaryElement","clsx","_Fragment"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,SAASA,MAAMA,CAAI;EACjBC,KAAK;AACLC,EAAAA,QAAQ,GAAG,EAAE;AACbC,EAAAA,IAAI,GAAG,EAAE;AACTC,EAAAA,SAAS,GAAG,EAAE;EACdC,IAAI;AACJC,EAAAA,QAAQ,GAAG,KAAK;AAChBC,EAAAA;AAAM,CACS,EAAA;AACf,EAAA,MAAMC,WAAW,GAAGH,IAAI,gBACpBI,kBAAY,CAACJ,IAAiC,EAAE;AAC9CK,IAAAA,IAAI,EAAE,EAAE;AACRC,IAAAA,SAAS,EAAE;GACZ,CAAC,GACFT,QAAQ,iBAAIU,cAAA,CAACC,QAAI,EAAA;AAACC,IAAAA,IAAI,EAAEZ,QAAQ,CAACa,WAAW,EAAG;AAACC,IAAAA,aAAa,EAAE;AAAG,GAAA,CAAG;AAEzE,EAAA,MAAMC,mBAAmB,gBACvBC,eAAA,CAACC,YAAI,EAAA;AAACC,IAAAA,EAAE,EAAC,MAAM;IAACC,IAAI,EAAEC,qBAAU,CAACC,UAAW;AAACZ,IAAAA,SAAS,EAAEL,QAAQ,GAAG,eAAe,GAAGkB,SAAU;AAAAC,IAAAA,QAAA,GAC5FxB,KAAK,EACLE,IAAI,iBACHS,cAAA,CAACO,YAAI,EAAA;AAACC,MAAAA,EAAE,EAAC,MAAM;AAACT,MAAAA,SAAS,EAAC,OAAO;AAAAc,MAAAA,QAAA,EAC9BtB;AAAI,KACD,CACP;AAAA,GACG,CACP;AAED,EAAA,MAAMuB,gBAAgB,GAAGtB,SAAS,iBAChCQ,cAAA,CAACO,YAAI,EAAA;AAACR,IAAAA,SAAS,EAAEgB,SAAI,CAACrB,QAAQ,IAAI,eAAe,CAAE;AAAAmB,IAAAA,QAAA,EAAErB;AAAS,GAAO,CACtE;EAED,OAAOI,WAAW,gBAChBU,eAAA,CAAA,KAAA,EAAA;AAAKP,IAAAA,SAAS,EAAC,0BAA0B;AAAC,IAAA,aAAA,EAAaJ,MAAO;AAAAkB,IAAAA,QAAA,gBAC5Db,cAAA,CAAA,KAAA,EAAA;AAAKD,MAAAA,SAAS,EAAE,CAAA,kBAAA,EAAqBL,QAAQ,GAAG,yBAAyB,GAAG,EAAE,CAAA,CAAG;AAAAmB,MAAAA,QAAA,EAC9EjB;KACE,CACL,eAAAU,eAAA,CAAA,KAAA,EAAA;AAAKP,MAAAA,SAAS,EAAC,2CAA2C;MAAAc,QAAA,EAAA,CACvDR,mBAAmB,EACnBS,gBAAgB;AAAA,KACd,CACP;AAAA,GAAK,CAAC,gBAENR,eAAA,CAAAU,mBAAA,EAAA;AAAAH,IAAAA,QAAA,EAAA,CACGjB,WAAW,EACXS,mBAAmB,EACnBS,gBAAgB;AAAA,GACnB,CACD;AACH;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"Option.mjs","sources":["../../../../src/_deprecated/Select/Option/Option.tsx"],"sourcesContent":["import { IdIconProps } from '@transferwise/icons';\nimport { Flag } from '@wise/art';\nimport { clsx } from 'clsx';\nimport { cloneElement, ReactElement, ReactNode } from 'react';\n\nimport Body from '../../../Body';\nimport { Typography } from '../../../common';\n\nexport type Props<T> = {\n label: ReactNode;\n value: T;\n currency?: string;\n note?: ReactNode;\n secondary?: ReactNode;\n icon?: ReactNode;\n /** @deprecated */\n classNames?: Record<string, string>;\n selected?: boolean;\n testId?: string;\n};\n\nfunction Option<T>({\n label,\n currency = '',\n note = '',\n secondary = '',\n icon,\n selected = false,\n testId,\n}: Props<T>) {\n const iconElement = icon\n ? cloneElement(icon as ReactElement<IdIconProps>, {\n size: 24,\n className: 'tw-icon',\n })\n : currency && <Flag code={currency.toLowerCase()} intrinsicSize={24} />;\n\n const titleAndNoteElement = (\n <Body as=\"span\" type={Typography.BODY_LARGE} className={selected ? 'text-ellipsis' : undefined}>\n {label}\n {note && (\n <Body as=\"span\" className=\"m-l-1\">\n {note}\n </Body>\n )}\n </Body>\n );\n\n const secondaryElement = secondary && (\n <Body className={clsx(selected && 'text-ellipsis')}>{secondary}</Body>\n );\n\n return iconElement ? (\n <div className=\"d-flex np-option-content\" data-testid={testId}>\n <div className={`d-flex flex-column${selected ? ' justify-content-center' : ''}`}>\n {iconElement}\n </div>\n <div className=\"d-flex flex-column justify-content-center\">\n {titleAndNoteElement}\n {secondaryElement}\n </div>\n </div>\n ) : (\n <>\n {iconElement}\n {titleAndNoteElement}\n {secondaryElement}\n </>\n );\n}\n\nexport default Option;\n"],"names":["Option","label","currency","note","secondary","icon","selected","testId","iconElement","cloneElement","size","className","_jsx","Flag","code","toLowerCase","intrinsicSize","titleAndNoteElement","_jsxs","Body","as","type","Typography","BODY_LARGE","undefined","children","secondaryElement","clsx","_Fragment"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,SAASA,MAAMA,CAAI;EACjBC,KAAK;AACLC,EAAAA,QAAQ,GAAG,EAAE;AACbC,EAAAA,IAAI,GAAG,EAAE;AACTC,EAAAA,SAAS,GAAG,EAAE;EACdC,IAAI;AACJC,EAAAA,QAAQ,GAAG,KAAK;AAChBC,EAAAA;AAAM,CACG,EAAA;AACT,EAAA,MAAMC,WAAW,GAAGH,IAAI,gBACpBI,YAAY,CAACJ,IAAiC,EAAE;AAC9CK,IAAAA,IAAI,EAAE,EAAE;AACRC,IAAAA,SAAS,EAAE;GACZ,CAAC,GACFT,QAAQ,iBAAIU,GAAA,CAACC,IAAI,EAAA;AAACC,IAAAA,IAAI,EAAEZ,QAAQ,CAACa,WAAW,EAAG;AAACC,IAAAA,aAAa,EAAE;AAAG,GAAA,CAAG;AAEzE,EAAA,MAAMC,mBAAmB,gBACvBC,IAAA,CAACC,IAAI,EAAA;AAACC,IAAAA,EAAE,EAAC,MAAM;IAACC,IAAI,EAAEC,UAAU,CAACC,UAAW;AAACZ,IAAAA,SAAS,EAAEL,QAAQ,GAAG,eAAe,GAAGkB,SAAU;AAAAC,IAAAA,QAAA,GAC5FxB,KAAK,EACLE,IAAI,iBACHS,GAAA,CAACO,IAAI,EAAA;AAACC,MAAAA,EAAE,EAAC,MAAM;AAACT,MAAAA,SAAS,EAAC,OAAO;AAAAc,MAAAA,QAAA,EAC9BtB;AAAI,KACD,CACP;AAAA,GACG,CACP;AAED,EAAA,MAAMuB,gBAAgB,GAAGtB,SAAS,iBAChCQ,GAAA,CAACO,IAAI,EAAA;AAACR,IAAAA,SAAS,EAAEgB,IAAI,CAACrB,QAAQ,IAAI,eAAe,CAAE;AAAAmB,IAAAA,QAAA,EAAErB;AAAS,GAAO,CACtE;EAED,OAAOI,WAAW,gBAChBU,IAAA,CAAA,KAAA,EAAA;AAAKP,IAAAA,SAAS,EAAC,0BAA0B;AAAC,IAAA,aAAA,EAAaJ,MAAO;AAAAkB,IAAAA,QAAA,gBAC5Db,GAAA,CAAA,KAAA,EAAA;AAAKD,MAAAA,SAAS,EAAE,CAAA,kBAAA,EAAqBL,QAAQ,GAAG,yBAAyB,GAAG,EAAE,CAAA,CAAG;AAAAmB,MAAAA,QAAA,EAC9EjB;KACE,CACL,eAAAU,IAAA,CAAA,KAAA,EAAA;AAAKP,MAAAA,SAAS,EAAC,2CAA2C;MAAAc,QAAA,EAAA,CACvDR,mBAAmB,EACnBS,gBAAgB;AAAA,KACd,CACP;AAAA,GAAK,CAAC,gBAENR,IAAA,CAAAU,QAAA,EAAA;AAAAH,IAAAA,QAAA,EAAA,CACGjB,WAAW,EACXS,mBAAmB,EACnBS,gBAAgB;AAAA,GACnB,CACD;AACH;;;;"}
1
+ {"version":3,"file":"Option.mjs","sources":["../../../../src/_deprecated/Select/Option/Option.tsx"],"sourcesContent":["import { IdIconProps } from '@transferwise/icons';\nimport { Flag } from '@wise/art';\nimport { clsx } from 'clsx';\nimport { cloneElement, ReactElement, ReactNode } from 'react';\n\nimport Body from '../../../Body';\nimport { Typography } from '../../../common';\n\nexport type OptionProps<T> = {\n label: ReactNode;\n value: T;\n currency?: string;\n note?: ReactNode;\n secondary?: ReactNode;\n icon?: ReactNode;\n /** @deprecated */\n classNames?: Record<string, string>;\n selected?: boolean;\n testId?: string;\n};\n\nfunction Option<T>({\n label,\n currency = '',\n note = '',\n secondary = '',\n icon,\n selected = false,\n testId,\n}: OptionProps<T>) {\n const iconElement = icon\n ? cloneElement(icon as ReactElement<IdIconProps>, {\n size: 24,\n className: 'tw-icon',\n })\n : currency && <Flag code={currency.toLowerCase()} intrinsicSize={24} />;\n\n const titleAndNoteElement = (\n <Body as=\"span\" type={Typography.BODY_LARGE} className={selected ? 'text-ellipsis' : undefined}>\n {label}\n {note && (\n <Body as=\"span\" className=\"m-l-1\">\n {note}\n </Body>\n )}\n </Body>\n );\n\n const secondaryElement = secondary && (\n <Body className={clsx(selected && 'text-ellipsis')}>{secondary}</Body>\n );\n\n return iconElement ? (\n <div className=\"d-flex np-option-content\" data-testid={testId}>\n <div className={`d-flex flex-column${selected ? ' justify-content-center' : ''}`}>\n {iconElement}\n </div>\n <div className=\"d-flex flex-column justify-content-center\">\n {titleAndNoteElement}\n {secondaryElement}\n </div>\n </div>\n ) : (\n <>\n {iconElement}\n {titleAndNoteElement}\n {secondaryElement}\n </>\n );\n}\n\nexport default Option;\n"],"names":["Option","label","currency","note","secondary","icon","selected","testId","iconElement","cloneElement","size","className","_jsx","Flag","code","toLowerCase","intrinsicSize","titleAndNoteElement","_jsxs","Body","as","type","Typography","BODY_LARGE","undefined","children","secondaryElement","clsx","_Fragment"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqBA,SAASA,MAAMA,CAAI;EACjBC,KAAK;AACLC,EAAAA,QAAQ,GAAG,EAAE;AACbC,EAAAA,IAAI,GAAG,EAAE;AACTC,EAAAA,SAAS,GAAG,EAAE;EACdC,IAAI;AACJC,EAAAA,QAAQ,GAAG,KAAK;AAChBC,EAAAA;AAAM,CACS,EAAA;AACf,EAAA,MAAMC,WAAW,GAAGH,IAAI,gBACpBI,YAAY,CAACJ,IAAiC,EAAE;AAC9CK,IAAAA,IAAI,EAAE,EAAE;AACRC,IAAAA,SAAS,EAAE;GACZ,CAAC,GACFT,QAAQ,iBAAIU,GAAA,CAACC,IAAI,EAAA;AAACC,IAAAA,IAAI,EAAEZ,QAAQ,CAACa,WAAW,EAAG;AAACC,IAAAA,aAAa,EAAE;AAAG,GAAA,CAAG;AAEzE,EAAA,MAAMC,mBAAmB,gBACvBC,IAAA,CAACC,IAAI,EAAA;AAACC,IAAAA,EAAE,EAAC,MAAM;IAACC,IAAI,EAAEC,UAAU,CAACC,UAAW;AAACZ,IAAAA,SAAS,EAAEL,QAAQ,GAAG,eAAe,GAAGkB,SAAU;AAAAC,IAAAA,QAAA,GAC5FxB,KAAK,EACLE,IAAI,iBACHS,GAAA,CAACO,IAAI,EAAA;AAACC,MAAAA,EAAE,EAAC,MAAM;AAACT,MAAAA,SAAS,EAAC,OAAO;AAAAc,MAAAA,QAAA,EAC9BtB;AAAI,KACD,CACP;AAAA,GACG,CACP;AAED,EAAA,MAAMuB,gBAAgB,GAAGtB,SAAS,iBAChCQ,GAAA,CAACO,IAAI,EAAA;AAACR,IAAAA,SAAS,EAAEgB,IAAI,CAACrB,QAAQ,IAAI,eAAe,CAAE;AAAAmB,IAAAA,QAAA,EAAErB;AAAS,GAAO,CACtE;EAED,OAAOI,WAAW,gBAChBU,IAAA,CAAA,KAAA,EAAA;AAAKP,IAAAA,SAAS,EAAC,0BAA0B;AAAC,IAAA,aAAA,EAAaJ,MAAO;AAAAkB,IAAAA,QAAA,gBAC5Db,GAAA,CAAA,KAAA,EAAA;AAAKD,MAAAA,SAAS,EAAE,CAAA,kBAAA,EAAqBL,QAAQ,GAAG,yBAAyB,GAAG,EAAE,CAAA,CAAG;AAAAmB,MAAAA,QAAA,EAC9EjB;KACE,CACL,eAAAU,IAAA,CAAA,KAAA,EAAA;AAAKP,MAAAA,SAAS,EAAC,2CAA2C;MAAAc,QAAA,EAAA,CACvDR,mBAAmB,EACnBS,gBAAgB;AAAA,KACd,CACP;AAAA,GAAK,CAAC,gBAENR,IAAA,CAAAU,QAAA,EAAA;AAAAH,IAAAA,QAAA,EAAA,CACGjB,WAAW,EACXS,mBAAmB,EACnBS,gBAAgB;AAAA,GACnB,CACD;AACH;;;;"}