@transferwise/components 46.97.5 → 46.98.1

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 (293) hide show
  1. package/build/alert/Alert.js +8 -0
  2. package/build/alert/Alert.js.map +1 -1
  3. package/build/alert/Alert.mjs +8 -0
  4. package/build/alert/Alert.mjs.map +1 -1
  5. package/build/common/closeButton/CloseButton.js +3 -1
  6. package/build/common/closeButton/CloseButton.js.map +1 -1
  7. package/build/common/closeButton/CloseButton.mjs +3 -1
  8. package/build/common/closeButton/CloseButton.mjs.map +1 -1
  9. package/build/dateInput/DateInput.js +4 -4
  10. package/build/dateInput/DateInput.js.map +1 -1
  11. package/build/dateInput/DateInput.mjs +4 -4
  12. package/build/dateInput/DateInput.mjs.map +1 -1
  13. package/build/dateLookup/DateLookup.js +4 -4
  14. package/build/dateLookup/DateLookup.js.map +1 -1
  15. package/build/dateLookup/DateLookup.mjs +4 -4
  16. package/build/dateLookup/DateLookup.mjs.map +1 -1
  17. package/build/dateLookup/dayCalendar/table/DayCalendarTable.js +3 -3
  18. package/build/dateLookup/dayCalendar/table/DayCalendarTable.js.map +1 -1
  19. package/build/dateLookup/dayCalendar/table/DayCalendarTable.mjs +3 -3
  20. package/build/dateLookup/dayCalendar/table/DayCalendarTable.mjs.map +1 -1
  21. package/build/i18n/cs.json +3 -2
  22. package/build/i18n/cs.json.js +3 -2
  23. package/build/i18n/cs.json.js.map +1 -1
  24. package/build/i18n/cs.json.mjs +3 -2
  25. package/build/i18n/cs.json.mjs.map +1 -1
  26. package/build/i18n/de.json +3 -2
  27. package/build/i18n/de.json.js +3 -2
  28. package/build/i18n/de.json.js.map +1 -1
  29. package/build/i18n/de.json.mjs +3 -2
  30. package/build/i18n/de.json.mjs.map +1 -1
  31. package/build/i18n/en.json +3 -2
  32. package/build/i18n/en.json.js +3 -2
  33. package/build/i18n/en.json.js.map +1 -1
  34. package/build/i18n/en.json.mjs +3 -2
  35. package/build/i18n/en.json.mjs.map +1 -1
  36. package/build/i18n/es.json +3 -2
  37. package/build/i18n/es.json.js +3 -2
  38. package/build/i18n/es.json.js.map +1 -1
  39. package/build/i18n/es.json.mjs +3 -2
  40. package/build/i18n/es.json.mjs.map +1 -1
  41. package/build/i18n/fr.json +3 -2
  42. package/build/i18n/fr.json.js +3 -2
  43. package/build/i18n/fr.json.js.map +1 -1
  44. package/build/i18n/fr.json.mjs +3 -2
  45. package/build/i18n/fr.json.mjs.map +1 -1
  46. package/build/i18n/hu.json +3 -2
  47. package/build/i18n/hu.json.js +3 -2
  48. package/build/i18n/hu.json.js.map +1 -1
  49. package/build/i18n/hu.json.mjs +3 -2
  50. package/build/i18n/hu.json.mjs.map +1 -1
  51. package/build/i18n/id.json +3 -2
  52. package/build/i18n/id.json.js +3 -2
  53. package/build/i18n/id.json.js.map +1 -1
  54. package/build/i18n/id.json.mjs +3 -2
  55. package/build/i18n/id.json.mjs.map +1 -1
  56. package/build/i18n/it.json +3 -2
  57. package/build/i18n/it.json.js +3 -2
  58. package/build/i18n/it.json.js.map +1 -1
  59. package/build/i18n/it.json.mjs +3 -2
  60. package/build/i18n/it.json.mjs.map +1 -1
  61. package/build/i18n/ja.json +3 -2
  62. package/build/i18n/ja.json.js +3 -2
  63. package/build/i18n/ja.json.js.map +1 -1
  64. package/build/i18n/ja.json.mjs +3 -2
  65. package/build/i18n/ja.json.mjs.map +1 -1
  66. package/build/i18n/nl.json +6 -5
  67. package/build/i18n/pl.json +3 -2
  68. package/build/i18n/pl.json.js +3 -2
  69. package/build/i18n/pl.json.js.map +1 -1
  70. package/build/i18n/pl.json.mjs +3 -2
  71. package/build/i18n/pl.json.mjs.map +1 -1
  72. package/build/i18n/pt.json +3 -2
  73. package/build/i18n/pt.json.js +3 -2
  74. package/build/i18n/pt.json.js.map +1 -1
  75. package/build/i18n/pt.json.mjs +3 -2
  76. package/build/i18n/pt.json.mjs.map +1 -1
  77. package/build/i18n/ro.json +3 -2
  78. package/build/i18n/ro.json.js +3 -2
  79. package/build/i18n/ro.json.js.map +1 -1
  80. package/build/i18n/ro.json.mjs +3 -2
  81. package/build/i18n/ro.json.mjs.map +1 -1
  82. package/build/i18n/ru.json +3 -2
  83. package/build/i18n/ru.json.js +3 -2
  84. package/build/i18n/ru.json.js.map +1 -1
  85. package/build/i18n/ru.json.mjs +3 -2
  86. package/build/i18n/ru.json.mjs.map +1 -1
  87. package/build/i18n/th.json +3 -2
  88. package/build/i18n/th.json.js +3 -2
  89. package/build/i18n/th.json.js.map +1 -1
  90. package/build/i18n/th.json.mjs +3 -2
  91. package/build/i18n/th.json.mjs.map +1 -1
  92. package/build/i18n/tr.json +3 -2
  93. package/build/i18n/tr.json.js +3 -2
  94. package/build/i18n/tr.json.js.map +1 -1
  95. package/build/i18n/tr.json.mjs +3 -2
  96. package/build/i18n/tr.json.mjs.map +1 -1
  97. package/build/i18n/zh-CN.json +3 -2
  98. package/build/i18n/zh-CN.json.js +3 -2
  99. package/build/i18n/zh-CN.json.js.map +1 -1
  100. package/build/i18n/zh-CN.json.mjs +3 -2
  101. package/build/i18n/zh-CN.json.mjs.map +1 -1
  102. package/build/i18n/zh-HK.json +3 -2
  103. package/build/i18n/zh-HK.json.js +3 -2
  104. package/build/i18n/zh-HK.json.js.map +1 -1
  105. package/build/i18n/zh-HK.json.mjs +3 -2
  106. package/build/i18n/zh-HK.json.mjs.map +1 -1
  107. package/build/image/Image.js +9 -10
  108. package/build/image/Image.js.map +1 -1
  109. package/build/image/Image.mjs +11 -11
  110. package/build/image/Image.mjs.map +1 -1
  111. package/build/index.js +0 -2
  112. package/build/index.js.map +1 -1
  113. package/build/index.mjs +0 -1
  114. package/build/index.mjs.map +1 -1
  115. package/build/main.css +16 -45
  116. package/build/moneyInput/MoneyInput.js +4 -8
  117. package/build/moneyInput/MoneyInput.js.map +1 -1
  118. package/build/moneyInput/MoneyInput.messages.js +3 -0
  119. package/build/moneyInput/MoneyInput.messages.js.map +1 -1
  120. package/build/moneyInput/MoneyInput.messages.mjs +3 -0
  121. package/build/moneyInput/MoneyInput.messages.mjs.map +1 -1
  122. package/build/moneyInput/MoneyInput.mjs +4 -8
  123. package/build/moneyInput/MoneyInput.mjs.map +1 -1
  124. package/build/phoneNumberInput/PhoneNumberInput.js +36 -2
  125. package/build/phoneNumberInput/PhoneNumberInput.js.map +1 -1
  126. package/build/phoneNumberInput/PhoneNumberInput.messages.js +6 -0
  127. package/build/phoneNumberInput/PhoneNumberInput.messages.js.map +1 -1
  128. package/build/phoneNumberInput/PhoneNumberInput.messages.mjs +6 -0
  129. package/build/phoneNumberInput/PhoneNumberInput.messages.mjs.map +1 -1
  130. package/build/phoneNumberInput/PhoneNumberInput.mjs +36 -2
  131. package/build/phoneNumberInput/PhoneNumberInput.mjs.map +1 -1
  132. package/build/snackbar/Snackbar.js +1 -1
  133. package/build/snackbar/Snackbar.js.map +1 -1
  134. package/build/snackbar/Snackbar.mjs +1 -1
  135. package/build/snackbar/Snackbar.mjs.map +1 -1
  136. package/build/styles/circularButton/CircularButton.css +1 -0
  137. package/build/styles/dateInput/DateInput.css +13 -0
  138. package/build/styles/main.css +16 -45
  139. package/build/styles/uploadInput/uploadItem/UploadItem.css +2 -1
  140. package/build/tabs/Tabs.js +3 -3
  141. package/build/tabs/Tabs.js.map +1 -1
  142. package/build/tabs/Tabs.mjs +3 -3
  143. package/build/tabs/Tabs.mjs.map +1 -1
  144. package/build/test-utils/assets/apple-pay-logo.svg +84 -0
  145. package/build/typeahead/Typeahead.js +2 -2
  146. package/build/typeahead/Typeahead.js.map +1 -1
  147. package/build/typeahead/Typeahead.mjs +2 -2
  148. package/build/typeahead/Typeahead.mjs.map +1 -1
  149. package/build/typeahead/typeaheadInput/TypeaheadInput.js +2 -2
  150. package/build/typeahead/typeaheadInput/TypeaheadInput.js.map +1 -1
  151. package/build/typeahead/typeaheadInput/TypeaheadInput.mjs +2 -2
  152. package/build/typeahead/typeaheadInput/TypeaheadInput.mjs.map +1 -1
  153. package/build/types/alert/Alert.d.ts.map +1 -1
  154. package/build/types/common/closeButton/CloseButton.d.ts +2 -0
  155. package/build/types/common/closeButton/CloseButton.d.ts.map +1 -1
  156. package/build/types/image/Image.d.ts +0 -1
  157. package/build/types/image/Image.d.ts.map +1 -1
  158. package/build/types/index.d.ts +0 -2
  159. package/build/types/index.d.ts.map +1 -1
  160. package/build/types/moneyInput/MoneyInput.d.ts.map +1 -1
  161. package/build/types/moneyInput/MoneyInput.messages.d.ts +5 -0
  162. package/build/types/moneyInput/MoneyInput.messages.d.ts.map +1 -1
  163. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
  164. package/build/types/phoneNumberInput/PhoneNumberInput.messages.d.ts +8 -0
  165. package/build/types/phoneNumberInput/PhoneNumberInput.messages.d.ts.map +1 -1
  166. package/build/types/test-utils/fake-data.d.ts +2 -0
  167. package/build/types/test-utils/fake-data.d.ts.map +1 -1
  168. package/build/types/test-utils/index.d.ts +6 -4
  169. package/build/types/test-utils/index.d.ts.map +1 -1
  170. package/build/types/upload/Upload.d.ts +1 -2
  171. package/build/types/upload/Upload.d.ts.map +1 -1
  172. package/build/types/upload/steps/processingStep/processingStep.d.ts +1 -3
  173. package/build/types/upload/steps/processingStep/processingStep.d.ts.map +1 -1
  174. package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
  175. package/build/types/uploadInput/uploadItem/UploadItem.d.ts +1 -1
  176. package/build/types/uploadInput/uploadItem/UploadItem.d.ts.map +1 -1
  177. package/build/types/withDisplayFormat/WithDisplayFormat.d.ts.map +1 -1
  178. package/build/upload/Upload.js +29 -45
  179. package/build/upload/Upload.js.map +1 -1
  180. package/build/upload/Upload.mjs +29 -45
  181. package/build/upload/Upload.mjs.map +1 -1
  182. package/build/upload/steps/processingStep/processingStep.js +1 -3
  183. package/build/upload/steps/processingStep/processingStep.js.map +1 -1
  184. package/build/upload/steps/processingStep/processingStep.mjs +1 -3
  185. package/build/upload/steps/processingStep/processingStep.mjs.map +1 -1
  186. package/build/upload/steps/uploadImageStep/uploadImageStep.js +1 -1
  187. package/build/upload/steps/uploadImageStep/uploadImageStep.js.map +1 -1
  188. package/build/upload/steps/uploadImageStep/uploadImageStep.mjs +1 -1
  189. package/build/upload/steps/uploadImageStep/uploadImageStep.mjs.map +1 -1
  190. package/build/uploadInput/UploadInput.js +54 -6
  191. package/build/uploadInput/UploadInput.js.map +1 -1
  192. package/build/uploadInput/UploadInput.mjs +54 -6
  193. package/build/uploadInput/UploadInput.mjs.map +1 -1
  194. package/build/uploadInput/uploadItem/UploadItem.js +12 -6
  195. package/build/uploadInput/uploadItem/UploadItem.js.map +1 -1
  196. package/build/uploadInput/uploadItem/UploadItem.mjs +12 -6
  197. package/build/uploadInput/uploadItem/UploadItem.mjs.map +1 -1
  198. package/build/withDisplayFormat/WithDisplayFormat.js +3 -2
  199. package/build/withDisplayFormat/WithDisplayFormat.js.map +1 -1
  200. package/build/withDisplayFormat/WithDisplayFormat.mjs +3 -2
  201. package/build/withDisplayFormat/WithDisplayFormat.mjs.map +1 -1
  202. package/package.json +14 -17
  203. package/src/alert/Alert.spec.tsx +11 -0
  204. package/src/alert/Alert.story.tsx +23 -9
  205. package/src/alert/Alert.tsx +14 -1
  206. package/src/circularButton/CircularButton.css +1 -0
  207. package/src/circularButton/CircularButton.less +1 -0
  208. package/src/circularButton/CircularButton.tests.story.tsx +23 -0
  209. package/src/common/closeButton/CloseButton.spec.tsx +13 -1
  210. package/src/common/closeButton/CloseButton.tsx +3 -0
  211. package/src/dateInput/DateInput.css +13 -0
  212. package/src/dateInput/DateInput.less +20 -0
  213. package/src/dateInput/DateInput.tests.story.tsx +14 -3
  214. package/src/dateInput/DateInput.tsx +4 -4
  215. package/src/i18n/cs.json +3 -2
  216. package/src/i18n/de.json +3 -2
  217. package/src/i18n/en.json +3 -2
  218. package/src/i18n/es.json +3 -2
  219. package/src/i18n/fr.json +3 -2
  220. package/src/i18n/hu.json +3 -2
  221. package/src/i18n/id.json +3 -2
  222. package/src/i18n/it.json +3 -2
  223. package/src/i18n/ja.json +3 -2
  224. package/src/i18n/nl.json +6 -5
  225. package/src/i18n/pl.json +3 -2
  226. package/src/i18n/pt.json +3 -2
  227. package/src/i18n/ro.json +3 -2
  228. package/src/i18n/ru.json +3 -2
  229. package/src/i18n/th.json +3 -2
  230. package/src/i18n/tr.json +3 -2
  231. package/src/i18n/zh-CN.json +3 -2
  232. package/src/i18n/zh-HK.json +3 -2
  233. package/src/image/Image.spec.tsx +3 -3
  234. package/src/image/Image.tsx +10 -12
  235. package/src/index.ts +0 -2
  236. package/src/legacylistItem/LegacyListItem.story.tsx +5 -5
  237. package/src/legacylistItem/LegacyListItem.tests.story.tsx +6 -6
  238. package/src/main.css +16 -45
  239. package/src/main.less +0 -1
  240. package/src/moneyInput/MoneyInput.messages.ts +5 -0
  241. package/src/moneyInput/MoneyInput.spec.tsx +42 -5
  242. package/src/moneyInput/MoneyInput.story.tsx +11 -2
  243. package/src/moneyInput/MoneyInput.tsx +5 -7
  244. package/src/phoneNumberInput/PhoneNumberInput.messages.ts +8 -0
  245. package/src/phoneNumberInput/PhoneNumberInput.spec.tsx +77 -43
  246. package/src/phoneNumberInput/PhoneNumberInput.tsx +34 -2
  247. package/src/promoCard/__snapshots__/PromoCard.spec.tsx.snap +1 -0
  248. package/src/promoCard/__snapshots__/PromoCardGroup.spec.tsx.snap +2 -0
  249. package/src/ssr.spec.tsx +0 -1
  250. package/src/test-utils/assets/apple-pay-logo.svg +84 -0
  251. package/src/test-utils/fake-data.ts +5 -0
  252. package/src/test-utils/jest.setup.ts +0 -4
  253. package/src/typeahead/Typeahead.spec.tsx +182 -0
  254. package/src/typeahead/typeaheadInput/TypeaheadInput.spec.tsx +103 -0
  255. package/src/typeahead/util/highlight.spec.tsx +43 -0
  256. package/src/upload/Upload.spec.tsx +63 -0
  257. package/src/upload/Upload.story.tsx +0 -51
  258. package/src/upload/Upload.tests.story.tsx +93 -0
  259. package/src/upload/Upload.tsx +28 -49
  260. package/src/upload/steps/processingStep/processingStep.tsx +2 -7
  261. package/src/uploadInput/UploadInput.tsx +74 -10
  262. package/src/uploadInput/uploadItem/UploadItem.css +2 -1
  263. package/src/uploadInput/uploadItem/UploadItem.less +1 -1
  264. package/src/uploadInput/uploadItem/UploadItem.tsx +11 -6
  265. package/src/withDisplayFormat/WithDisplayFormat.spec.js +11 -15
  266. package/src/withDisplayFormat/WithDisplayFormat.tsx +3 -2
  267. package/build/selectOption/SelectOption.js +0 -131
  268. package/build/selectOption/SelectOption.js.map +0 -1
  269. package/build/selectOption/SelectOption.messages.js +0 -17
  270. package/build/selectOption/SelectOption.messages.js.map +0 -1
  271. package/build/selectOption/SelectOption.messages.mjs +0 -13
  272. package/build/selectOption/SelectOption.messages.mjs.map +0 -1
  273. package/build/selectOption/SelectOption.mjs +0 -127
  274. package/build/selectOption/SelectOption.mjs.map +0 -1
  275. package/build/styles/selectOption/SelectOption.css +0 -44
  276. package/build/types/selectOption/SelectOption.d.ts +0 -21
  277. package/build/types/selectOption/SelectOption.d.ts.map +0 -1
  278. package/build/types/selectOption/SelectOption.messages.d.ts +0 -12
  279. package/build/types/selectOption/SelectOption.messages.d.ts.map +0 -1
  280. package/build/types/selectOption/index.d.ts +0 -3
  281. package/build/types/selectOption/index.d.ts.map +0 -1
  282. package/src/selectOption/SelectOption.css +0 -44
  283. package/src/selectOption/SelectOption.less +0 -40
  284. package/src/selectOption/SelectOption.messages.ts +0 -12
  285. package/src/selectOption/SelectOption.spec.tsx +0 -83
  286. package/src/selectOption/SelectOption.story.tsx +0 -277
  287. package/src/selectOption/SelectOption.tsx +0 -151
  288. package/src/selectOption/index.ts +0 -2
  289. package/src/typeahead/Typeahead.rtl.spec.tsx +0 -54
  290. package/src/typeahead/Typeahead.spec.js +0 -404
  291. package/src/typeahead/typeaheadInput/TypeaheadInput.spec.js +0 -74
  292. package/src/typeahead/typeaheadOption/TypeaheadOption.spec.js +0 -75
  293. package/src/typeahead/util/highlight.spec.js +0 -34
@@ -1,151 +0,0 @@
1
- import { useRef, useState } from 'react';
2
- import { ActionButtonProps } from '../actionButton';
3
- import { clsx } from 'clsx';
4
- import Option from '../common/Option';
5
- import type { OptionProps } from '../common/Option/Option';
6
- import { Breakpoint, Position } from '../common';
7
- import Section from '../section';
8
- import Header from '../header';
9
- import { HeaderProps } from '../header/Header';
10
- import NavigationOption from '../navigationOption';
11
- import NavigationOptionsList from '../navigationOptionsList';
12
- import { useInputAttributes } from '../inputs/contexts';
13
- import messages from './SelectOption.messages';
14
- import { useIntl } from 'react-intl';
15
- import ResponsivePanel from '../common/responsivePanel';
16
- import { useScreenSize } from '../common/hooks/useScreenSize';
17
- import { ChevronDown, Plus } from '@transferwise/icons';
18
-
19
- export type SelectOptiopsSection<T = unknown> = {
20
- title?: HeaderProps['title'];
21
- options: SelectOptionValue<T>[];
22
- };
23
-
24
- export type SelectOptionValue<T = unknown> = Pick<
25
- OptionProps,
26
- 'media' | 'title' | 'content' | 'disabled'
27
- > & {
28
- value?: T;
29
- };
30
-
31
- export type SelectOptionPlaceholder = Pick<OptionProps, 'media' | 'title' | 'content'> & {
32
- actionLabel?: ActionButtonProps['children'];
33
- };
34
-
35
- export type SelectOptionProps<T = unknown> = {
36
- onChange: (selected: SelectOptionValue<T>) => void;
37
- selected?: SelectOptionValue<T>;
38
- options: SelectOptiopsSection<T>[];
39
- placeholder: SelectOptionPlaceholder;
40
- } & Omit<
41
- OptionProps,
42
- 'as' | 'title' | 'media' | 'content' | 'onClick' | 'onChange' | 'showMediaAtAllSizes' | 'decision'
43
- >;
44
-
45
- export default function SelectOption<T>({
46
- selected = undefined,
47
- options,
48
- onChange,
49
- placeholder,
50
- disabled,
51
- ...props
52
- }: SelectOptionProps<T>) {
53
- const intl = useIntl();
54
- const rootRef = useRef(null);
55
- const [showOptions, setShowOptions] = useState(false);
56
-
57
- const hasSelected = selected !== undefined;
58
- const isLargeScreen = useScreenSize(Breakpoint.SMALL);
59
-
60
- const inputAttributes = useInputAttributes();
61
- const ariaLabelledBy = props['aria-labelledby'] ?? inputAttributes?.['aria-labelledby'];
62
-
63
- function handleOnClick(showOptionsStatus: boolean) {
64
- return () => {
65
- setShowOptions(showOptionsStatus);
66
- };
67
- }
68
-
69
- function handleOnChange(data: SelectOptionValue<T>) {
70
- return () => {
71
- setShowOptions(false);
72
- onChange(data);
73
- };
74
- }
75
-
76
- function getOptions(isLargeScreen = false) {
77
- return (
78
- <div className={clsx({ 'np-select-option-list': isLargeScreen })}>
79
- {options.map((optionsSection, index) => (
80
- <Section key={index} className={clsx({ 'p-x-2 p-y-1': isLargeScreen })}>
81
- {optionsSection.title && <Header title={optionsSection.title} />}
82
- <NavigationOptionsList>
83
- {optionsSection.options.map((option, index) => {
84
- return (
85
- <NavigationOption
86
- key={index}
87
- isContainerAligned={!isLargeScreen}
88
- showMediaCircle
89
- showMediaAtAllSizes
90
- onClick={handleOnChange(option)}
91
- {...option}
92
- />
93
- );
94
- })}
95
- </NavigationOptionsList>
96
- </Section>
97
- ))}
98
- </div>
99
- );
100
- }
101
-
102
- return (
103
- <>
104
- <Option
105
- ref={rootRef}
106
- as="div"
107
- showMediaAtAllSizes
108
- disabled={disabled}
109
- decision={false}
110
- media={hasSelected ? selected.media : (placeholder.media ?? <Plus size={24} />)}
111
- title={(hasSelected ? selected : placeholder).title}
112
- content={(hasSelected ? selected : placeholder).content}
113
- className={clsx(
114
- 'np-select-option',
115
- 'clickable',
116
- hasSelected ? 'np-select-option-selected' : 'np-select-option-placeholder',
117
- props.className,
118
- )}
119
- button={
120
- <button
121
- {...inputAttributes}
122
- type="button"
123
- disabled={disabled}
124
- aria-labelledby={ariaLabelledBy}
125
- aria-haspopup="dialog"
126
- aria-expanded={showOptions}
127
- className={hasSelected ? 'btn-unstyled' : 'np-action-btn'}
128
- aria-label={hasSelected ? undefined : props['aria-label']}
129
- onClick={handleOnClick(true)}
130
- >
131
- {hasSelected ? (
132
- <ChevronDown title={intl.formatMessage(messages.selectedActionLabel)} />
133
- ) : (
134
- placeholder.actionLabel || intl.formatMessage(messages.actionLabel)
135
- )}
136
- </button>
137
- }
138
- />
139
- <ResponsivePanel
140
- anchorWidth
141
- altAxis
142
- anchorRef={rootRef}
143
- open={showOptions}
144
- position={Position.BOTTOM}
145
- onClose={handleOnClick(false)}
146
- >
147
- {getOptions(isLargeScreen)}
148
- </ResponsivePanel>
149
- </>
150
- );
151
- }
@@ -1,2 +0,0 @@
1
- export { default } from './SelectOption';
2
- export type { SelectOptionProps, SelectOptionValue, SelectOptiopsSection } from './SelectOption';
@@ -1,54 +0,0 @@
1
- import { Field } from '../field/Field';
2
- import { mockMatchMedia, render, screen } from '../test-utils';
3
- import Typeahead from './Typeahead';
4
- import { createIntl, createIntlCache } from 'react-intl';
5
- import messages from '../i18n';
6
- import { DEFAULT_LANG, DEFAULT_LOCALE } from '../common';
7
-
8
- mockMatchMedia();
9
-
10
- const cache = createIntlCache();
11
- const intl = createIntl({ locale: DEFAULT_LOCALE, messages: messages[DEFAULT_LANG] }, cache);
12
-
13
- describe('Typeahead', () => {
14
- it('supports `Field` for labeling', () => {
15
- render(
16
- <Field id="test" label="Tags">
17
- <Typeahead
18
- id="test"
19
- name="test"
20
- options={[{ label: 'Test' }]}
21
- intl={intl}
22
- onChange={() => {}}
23
- />
24
- </Field>,
25
- );
26
- expect(screen.getAllByRole('group')[0]).toHaveAccessibleName(/^Tags/);
27
- });
28
-
29
- describe('when no options are provided', () => {
30
- it('does not render a dropdown when no options and no footer are provided', () => {
31
- render(
32
- <Field id="test" label="Tags">
33
- <Typeahead id="test" name="test" options={[]} intl={intl} onChange={() => {}} />
34
- </Field>,
35
- );
36
- expect(screen.queryByRole('menu')).not.toBeInTheDocument();
37
- });
38
- it('does render a dropdown when only a footer is provided', () => {
39
- render(
40
- <Field id="test" label="Tags">
41
- <Typeahead
42
- id="test"
43
- name="test"
44
- options={[]}
45
- intl={intl}
46
- footer={<p>hello</p>}
47
- onChange={() => {}}
48
- />
49
- </Field>,
50
- );
51
- expect(screen.getByRole('menu')).toBeInTheDocument();
52
- });
53
- });
54
- });
@@ -1,404 +0,0 @@
1
- import { mount } from 'enzyme';
2
- import doTimes from 'lodash.times';
3
- import { mockMatchMedia } from '../test-utils';
4
-
5
- import { InlineAlert } from '..';
6
- import { Sentiment } from '../common';
7
- import { fakeEvent, fakeKeyDownEventForKey } from '../common/fakeEvents';
8
-
9
- import Typeahead from './Typeahead';
10
-
11
- mockMatchMedia();
12
-
13
- const defaultLocale = 'en-GB';
14
- jest.mock('react-intl', () => {
15
- const mockedIntl = {
16
- locale: defaultLocale,
17
- formatMessage: (id) => String(id),
18
- };
19
- return {
20
- injectIntl: (Component) => (props) => <Component {...props} intl={mockedIntl} />,
21
- defineMessages: (translations) => translations,
22
- useIntl: () => mockedIntl,
23
- };
24
- });
25
-
26
- describe('Typeahead', () => {
27
- let component;
28
- let props;
29
- const closeButton = () => component.find('.input-group-addon button');
30
- const formGroup = () => component.find('.form-group');
31
- const input = () => component.find('input');
32
- const chip = () => component.find('.np-chip');
33
- const option = () => component.find('.dropdown-item');
34
- const menu = () => component.find('.dropdown');
35
-
36
- beforeEach(() => {
37
- props = {
38
- id: 'test',
39
- onChange: () => {},
40
- name: 'test',
41
- options: [
42
- {
43
- label: 'Test',
44
- },
45
- {
46
- label: 'Test1',
47
- },
48
- {
49
- label: 'Test2',
50
- },
51
- {
52
- label: 'Test3',
53
- },
54
- ],
55
- };
56
-
57
- component = mount(<Typeahead {...props} />);
58
- });
59
-
60
- it('renders addon', () => {
61
- expect(component.find('#test-addon')).toHaveLength(0);
62
- component.setProps({ addon: <div id="test-addon" /> });
63
- expect(component.find('#test-addon')).toHaveLength(1);
64
- });
65
-
66
- it('renders clear button', () => {
67
- component.setProps({
68
- clearable: true,
69
- });
70
- input().simulate('change', { target: { value: 'test' } });
71
-
72
- expect(closeButton()).toHaveLength(1);
73
- });
74
-
75
- it('splits pasted value correctly', () => {
76
- const chips = ['test', 'test2', 'test3'];
77
- const event = {
78
- preventDefault: jest.fn(),
79
- clipboardData: {
80
- getData: () => chips.join(', '),
81
- },
82
- };
83
-
84
- component.setProps({
85
- allowNew: true,
86
- multiple: true,
87
- chipSeparators: [',', ' '],
88
- });
89
-
90
- input().simulate('paste', event);
91
- const renderedChips = chip().map((chipNode) => chipNode.text());
92
-
93
- expect(renderedChips.every((label, idx) => chips[idx] === label)).toBe(true);
94
- expect(renderedChips).toHaveLength(chips.length);
95
- expect(event.preventDefault).toHaveBeenCalledTimes(1);
96
- });
97
-
98
- it('removes last selected value when backspace clicked on empty input', () => {
99
- const event = {
100
- key: 'Backspace',
101
- };
102
-
103
- component.setProps({
104
- multiple: true,
105
- });
106
-
107
- expect(chip()).toHaveLength(0);
108
-
109
- input().simulate('change', { target: { value: 'test' } });
110
- option().at(0).simulate('click', fakeEvent());
111
-
112
- expect(chip()).toHaveLength(1);
113
-
114
- input().simulate('keyDown', event);
115
-
116
- expect(chip()).toHaveLength(0);
117
- });
118
-
119
- it('does not remove last selected value when backspace clicked on non-empty input', () => {
120
- const event = {
121
- key: 'Backspace',
122
- };
123
-
124
- component.setProps({
125
- multiple: true,
126
- });
127
-
128
- expect(chip()).toHaveLength(0);
129
-
130
- input().simulate('change', { target: { value: 'test' } });
131
- option().at(0).simulate('click', fakeEvent());
132
-
133
- expect(chip()).toHaveLength(1);
134
-
135
- input().simulate('change', { target: { value: 'test' } });
136
- input().simulate('keyDown', event);
137
-
138
- expect(chip()).toHaveLength(1);
139
- });
140
-
141
- it('adds new value as selected and clears the input when separator is entered', () => {
142
- const event = {
143
- key: ',',
144
- preventDefault: jest.fn(),
145
- };
146
- const text = 'test';
147
-
148
- component.setProps({
149
- multiple: true,
150
- allowNew: true,
151
- showSuggestions: false,
152
- chipSeparators: [','],
153
- });
154
-
155
- input().simulate('change', { target: { value: text } });
156
- input().simulate('keyDown', event);
157
-
158
- expect(chip().text()).toStrictEqual(text);
159
- expect(event.preventDefault).toHaveBeenCalledTimes(1);
160
- });
161
-
162
- it('adds new value as selected and clears the input when Enter is pressed', () => {
163
- const event = {
164
- key: 'Enter',
165
- preventDefault: jest.fn(),
166
- };
167
- const text = 'test';
168
-
169
- component.setProps({
170
- multiple: true,
171
- allowNew: true,
172
- showSuggestions: false,
173
- chipSeparators: [','],
174
- });
175
-
176
- input().simulate('change', { target: { value: text } });
177
- input().simulate('keyDown', event);
178
-
179
- expect(chip().text()).toStrictEqual(text);
180
- expect(event.preventDefault).toHaveBeenCalledTimes(1);
181
- });
182
-
183
- it('adds new value as selected and clears the input when Tab is pressed', () => {
184
- const event = {
185
- key: 'Tab',
186
- preventDefault: jest.fn(),
187
- };
188
- const text = 'test';
189
-
190
- component.setProps({
191
- multiple: true,
192
- allowNew: true,
193
- showSuggestions: false,
194
- chipSeparators: [','],
195
- });
196
-
197
- input().simulate('change', { target: { value: text } });
198
- input().simulate('keyDown', event);
199
-
200
- expect(chip().text()).toStrictEqual(text);
201
- expect(event.preventDefault).toHaveBeenCalledTimes(1);
202
- });
203
-
204
- it('clears typeahead when clear button is clicked', () => {
205
- const event = {
206
- key: ',',
207
- preventDefault: jest.fn(),
208
- };
209
-
210
- const query = 'test';
211
-
212
- component.setProps({
213
- multiple: true,
214
- allowNew: true,
215
- showSuggestions: false,
216
- chipSeparators: [','],
217
- clearable: true,
218
- });
219
-
220
- input().simulate('change', { target: { value: query } });
221
- input().simulate('keyDown', event);
222
- input().simulate('change', { target: { value: query } });
223
-
224
- expect(chip()).toHaveLength(1);
225
- expect(input().getDOMNode().value).toBe(query);
226
-
227
- closeButton().simulate('click', fakeEvent());
228
- expect(chip()).toHaveLength(0);
229
- expect(input().getDOMNode().value).toBe('');
230
- });
231
-
232
- it('moves selected items when down and up keys pressed', () => {
233
- doTimes(3, () => input().simulate('keyDown', fakeKeyDownEventForKey('ArrowDown')));
234
-
235
- expect(option().at(2).parent().is('.tw-dropdown-item--focused')).toBe(true);
236
-
237
- input().simulate('keyDown', fakeKeyDownEventForKey('ArrowUp'));
238
- expect(option().at(1).parent().is('.tw-dropdown-item--focused')).toBe(true);
239
-
240
- doTimes(5, () => input().simulate('keyDown', fakeKeyDownEventForKey('ArrowDown')));
241
- expect(option().last().parent().is('.tw-dropdown-item--focused')).toBe(true);
242
- });
243
-
244
- it('adds new value as selected and clears the input when no option is highlighted and enter is pressed', () => {
245
- const event = {
246
- key: 'Enter',
247
- preventDefault: jest.fn(),
248
- };
249
- const text = 'test';
250
-
251
- component.setProps({
252
- multiple: true,
253
- allowNew: true,
254
- chipSeparators: [','],
255
- });
256
-
257
- input().simulate('change', { target: { value: text } });
258
- input().simulate('keyDown', event);
259
-
260
- expect(chip().text()).toStrictEqual(text);
261
- expect(event.preventDefault).toHaveBeenCalledTimes(1);
262
- });
263
-
264
- it('sets aria-activedescendant correctly based on focus', () => {
265
- const inputElement = input().getDOMNode();
266
-
267
- doTimes(3, () => input().simulate('keyDown', fakeKeyDownEventForKey('ArrowDown')));
268
-
269
- expect(inputElement).toHaveAttribute('aria-activedescendant', 'menu-test option-Test2');
270
- });
271
-
272
- it('displays alert when alert is provided and chips are valid or alert type is error', () => {
273
- const event = {
274
- key: 'Enter',
275
- preventDefault: jest.fn(),
276
- };
277
- const text = 'test';
278
-
279
- expect(component.find(InlineAlert)).toHaveLength(0);
280
- expect(formGroup().hasClass('has-error')).toBe(false);
281
- component.setProps({
282
- validateChip: () => {
283
- return false;
284
- },
285
- allowNew: true,
286
- alert: {
287
- message: 'test',
288
- type: Sentiment.ERROR,
289
- },
290
- });
291
-
292
- expect(formGroup().hasClass('has-error')).toBe(true);
293
- expect(component.find(InlineAlert)).toHaveLength(1);
294
-
295
- input().simulate('change', { target: { value: text } });
296
- input().simulate('keyDown', event);
297
-
298
- expect(formGroup().hasClass('has-error')).toBe(true);
299
- expect(component.find(InlineAlert)).toHaveLength(1);
300
- component.setProps({
301
- alert: {
302
- message: 'test',
303
- type: Sentiment.WARNING,
304
- },
305
- });
306
-
307
- expect(formGroup().hasClass('has-error')).toBe(true);
308
- expect(component.find(InlineAlert)).toHaveLength(0);
309
-
310
- closeButton().simulate('click', fakeEvent());
311
-
312
- expect(formGroup().hasClass('has-error')).toBe(false);
313
- expect(formGroup().hasClass('has-warning')).toBe(true);
314
- expect(component.find(InlineAlert)).toHaveLength(1);
315
- });
316
-
317
- it('allows supplying options with arbitrary data that will be included with the onChange callback', () => {
318
- const text = 'test';
319
- const options = [
320
- {
321
- label: 'label 1',
322
- note: 'note-1',
323
- secondary: 'secondary-1',
324
- value: { id: 123, name: 'Neptune' },
325
- },
326
- ];
327
- let selectedOption;
328
-
329
- component.setProps({
330
- onChange: (selections) => {
331
- selectedOption = selections[0];
332
- },
333
- options,
334
- });
335
-
336
- input().simulate('change', { target: { value: text } });
337
- option().at(0).simulate('click', fakeEvent());
338
- expect(selectedOption).toStrictEqual({
339
- label: 'label 1',
340
- note: 'note-1',
341
- secondary: 'secondary-1',
342
- value: { id: 123, name: 'Neptune' },
343
- });
344
- });
345
-
346
- describe('menu', () => {
347
- it('should render footer', () => {
348
- component.setProps({
349
- footer: <div id="footer">footer</div>,
350
- });
351
-
352
- expect(component.find('#footer')).toHaveLength(1);
353
- });
354
-
355
- it('renders all options', () => {
356
- const options = option().map((optNode) => optNode.text());
357
- expect(options).toHaveLength(props.options.length);
358
- expect(options.every((label, i) => label === props.options[i].label)).toBe(true);
359
- });
360
-
361
- it('renders dropdown-menu if has options', () => {
362
- expect(component.find('.dropdown-menu')).toHaveLength(1);
363
- component.setProps({ options: [] });
364
- expect(component.find('.dropdown-menu')).toHaveLength(0);
365
- });
366
-
367
- it('does not render new option if showNewEntry is false', () => {
368
- component.setProps({
369
- allowNew: true,
370
- showNewEntry: false,
371
- });
372
- input().simulate('change', { target: { value: 'check' } });
373
-
374
- const options = option().map((optNode) => optNode.text());
375
- expect(options).toHaveLength(props.options.length);
376
- });
377
-
378
- it('renders new option if showNewEntry is true', () => {
379
- component.setProps({
380
- allowNew: true,
381
- showNewEntry: true,
382
- });
383
- input().simulate('change', { target: { value: 'check' } });
384
-
385
- const options = option().map((optNode) => optNode.text());
386
- expect(options).toHaveLength(props.options.length + 1);
387
- });
388
-
389
- it('does not show options if query is too short', () => {
390
- expect(menu().is('.open')).toBe(false);
391
- input().simulate('change', { target: { value: 'test' } });
392
- expect(menu().is('.open')).toBe(true);
393
- });
394
-
395
- it('sets aria-expanded to true when options are shown', () => {
396
- expect(input().prop('aria-expanded')).toBe(false);
397
- // we don't want aria-expanded to be true on focus or before 3 characters are entered (that's when the menu is shown)
398
- input().simulate('change', { target: { value: 'aa' } });
399
- expect(input().prop('aria-expanded')).toBe(false);
400
- input().simulate('change', { target: { value: 'aaa' } });
401
- expect(input().prop('aria-expanded')).toBe(true);
402
- });
403
- });
404
- });
@@ -1,74 +0,0 @@
1
- import { shallow } from 'enzyme';
2
-
3
- import { Input } from '../../inputs/Input';
4
-
5
- import TypeaheadInput from './TypeaheadInput';
6
-
7
- describe('Typeahead input', () => {
8
- let component;
9
- let props;
10
-
11
- const inputWrapper = () => component.find('.typeahead__input-wrapper');
12
- const input = () => component.find(Input);
13
-
14
- beforeEach(() => {
15
- props = {
16
- name: 'test',
17
- typeaheadId: 'test',
18
- multiple: false,
19
- value: '',
20
- renderChip: jest.fn(),
21
- onKeyDown: jest.fn(),
22
- onFocus: jest.fn(),
23
- onPaste: jest.fn(),
24
- onChange: jest.fn(),
25
- autoComplete: 'off',
26
- selected: [],
27
- };
28
-
29
- component = shallow(<TypeaheadInput {...props} />);
30
- });
31
-
32
- it('renders single input when multiple is false', () => {
33
- expect(component.children()).toHaveLength(0);
34
- expect(component.is(Input)).toBe(true);
35
- });
36
-
37
- it('renders chips when provided', () => {
38
- const selected = [{ label: 'test1' }, { label: 'test2' }];
39
- component.setProps({
40
- multiple: true,
41
- selected,
42
- renderChip: jest.fn(({ label }, idx) => <span key={idx}>{label}</span>),
43
- });
44
-
45
- expect(inputWrapper().find('span')).toHaveLength(selected.length);
46
- });
47
-
48
- it('adds aria-controls prop if dropdown is open', () => {
49
- expect(component.prop('aria-controls')).toBeUndefined();
50
- component.setProps({ dropdownOpen: true });
51
- expect(component.prop('aria-controls')).toBe('menu-test');
52
- });
53
-
54
- it('passes all callbacks to input', () => {
55
- const event = {};
56
- const extraProps = {
57
- multiple: true,
58
- value: '',
59
- onKeyDown: jest.fn(),
60
- onBlur: jest.fn(),
61
- onFocus: jest.fn(),
62
- onPaste: jest.fn(),
63
- };
64
- component.setProps(extraProps);
65
-
66
- input().simulate('focus', event);
67
- input().simulate('paste', event);
68
- input().simulate('keyDown', event);
69
- const inputProps = input().props();
70
- expect(inputProps.onKeyDown).toHaveBeenCalledWith(event);
71
- expect(inputProps.onFocus).toHaveBeenCalledWith(event);
72
- expect(inputProps.onPaste).toHaveBeenCalledWith(event);
73
- });
74
- });