@transferwise/components 46.22.1 → 46.24.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 (143) hide show
  1. package/build/i18n/es.json +2 -2
  2. package/build/i18n/hu.json +2 -2
  3. package/build/i18n/zh-HK.json +2 -2
  4. package/build/index.esm.js +101 -79
  5. package/build/index.esm.js.map +1 -1
  6. package/build/index.js +103 -82
  7. package/build/index.js.map +1 -1
  8. package/build/types/actionOption/ActionOption.d.ts +3 -3
  9. package/build/types/actionOption/ActionOption.d.ts.map +1 -1
  10. package/build/types/actionOption/index.d.ts +1 -0
  11. package/build/types/actionOption/index.d.ts.map +1 -1
  12. package/build/types/badge/Badge.d.ts +2 -2
  13. package/build/types/badge/Badge.d.ts.map +1 -1
  14. package/build/types/common/dateUtils/getFormatForLocale/getFormatForLocale.d.ts +3 -0
  15. package/build/types/common/dateUtils/getFormatForLocale/getFormatForLocale.d.ts.map +1 -0
  16. package/build/types/common/dateUtils/index.d.ts +7 -6
  17. package/build/types/common/dateUtils/index.d.ts.map +1 -1
  18. package/build/types/dateInput/DateInput.d.ts.map +1 -1
  19. package/build/types/emphasis/Emphasis.d.ts +1 -1
  20. package/build/types/emphasis/Emphasis.d.ts.map +1 -1
  21. package/build/types/emphasis/EmphasisHtmlTransformer.d.ts +1 -1
  22. package/build/types/emphasis/EmphasisHtmlTransformer.d.ts.map +1 -1
  23. package/build/types/emphasis/index.d.ts +1 -0
  24. package/build/types/emphasis/index.d.ts.map +1 -1
  25. package/build/types/i18n/index.d.ts.map +1 -1
  26. package/build/types/index.d.ts +13 -0
  27. package/build/types/index.d.ts.map +1 -1
  28. package/build/types/inputs/SelectInput.d.ts.map +1 -1
  29. package/build/types/loader/Loader.d.ts +3 -3
  30. package/build/types/loader/Loader.d.ts.map +1 -1
  31. package/build/types/loader/index.d.ts +2 -2
  32. package/build/types/loader/index.d.ts.map +1 -1
  33. package/build/types/money/Money.d.ts +8 -11
  34. package/build/types/money/Money.d.ts.map +1 -1
  35. package/build/types/money/index.d.ts +2 -1
  36. package/build/types/money/index.d.ts.map +1 -1
  37. package/build/types/navigationOptionsList/NavigationOptionsList.d.ts +7 -10
  38. package/build/types/navigationOptionsList/NavigationOptionsList.d.ts.map +1 -1
  39. package/build/types/navigationOptionsList/index.d.ts +2 -1
  40. package/build/types/navigationOptionsList/index.d.ts.map +1 -1
  41. package/build/types/progress/Progress.d.ts +1 -1
  42. package/build/types/progress/Progress.d.ts.map +1 -1
  43. package/build/types/progress/index.d.ts +1 -0
  44. package/build/types/progress/index.d.ts.map +1 -1
  45. package/build/types/progressBar/index.d.ts +1 -0
  46. package/build/types/progressBar/index.d.ts.map +1 -1
  47. package/build/types/segmentedControl/SegmentedControl.d.ts.map +1 -1
  48. package/build/types/slidingPanel/SlidingPanel.d.ts.map +1 -1
  49. package/build/types/statusIcon/StatusIcon.d.ts +3 -3
  50. package/build/types/statusIcon/StatusIcon.d.ts.map +1 -1
  51. package/build/types/statusIcon/index.d.ts +2 -1
  52. package/build/types/statusIcon/index.d.ts.map +1 -1
  53. package/build/types/switch/Switch.d.ts +3 -3
  54. package/build/types/switch/Switch.d.ts.map +1 -1
  55. package/build/types/switch/index.d.ts +1 -0
  56. package/build/types/switch/index.d.ts.map +1 -1
  57. package/build/types/switchOption/SwitchOption.d.ts +3 -3
  58. package/build/types/switchOption/SwitchOption.d.ts.map +1 -1
  59. package/build/types/switchOption/index.d.ts +1 -0
  60. package/build/types/switchOption/index.d.ts.map +1 -1
  61. package/build/types/tooltip/Tooltip.d.ts +3 -3
  62. package/build/types/tooltip/Tooltip.d.ts.map +1 -1
  63. package/build/types/tooltip/index.d.ts +2 -2
  64. package/build/types/tooltip/index.d.ts.map +1 -1
  65. package/package.json +3 -4
  66. package/src/actionOption/{ActionOption.spec.js → ActionOption.spec.tsx} +2 -2
  67. package/src/actionOption/ActionOption.tsx +3 -3
  68. package/src/actionOption/index.ts +1 -0
  69. package/src/avatar/{Avatar.spec.js → Avatar.spec.tsx} +6 -13
  70. package/src/badge/{Badge.story.js → Badge.story.tsx} +1 -1
  71. package/src/badge/Badge.tsx +2 -2
  72. package/src/common/dateUtils/getFormatForLocale/getFormatForLocale.ts +2 -0
  73. package/src/common/dateUtils/index.ts +7 -6
  74. package/src/common/dateUtils/isMonthAndYearFormat/isMonthAndYearFormat.ts +1 -1
  75. package/src/dateInput/DateInput.spec.js +29 -9
  76. package/src/dateInput/DateInput.story.tsx +0 -3
  77. package/src/dateInput/DateInput.tsx +90 -48
  78. package/src/emphasis/{Emphasis.spec.js → Emphasis.spec.tsx} +2 -1
  79. package/src/emphasis/Emphasis.tsx +1 -1
  80. package/src/emphasis/{EmphasisHtmlTransformer.spec.js → EmphasisHtmlTransformer.spec.tsx} +0 -12
  81. package/src/emphasis/EmphasisHtmlTransformer.ts +1 -1
  82. package/src/emphasis/index.ts +1 -0
  83. package/src/i18n/es.json +2 -2
  84. package/src/i18n/hu.json +2 -2
  85. package/src/i18n/index.ts +1 -0
  86. package/src/i18n/zh-HK.json +2 -2
  87. package/src/index.ts +13 -0
  88. package/src/inputWithDisplayFormat/InputWithDisplayFormat.story.js +3 -2
  89. package/src/inputs/SelectInput.tsx +5 -3
  90. package/src/loader/Loader.tsx +3 -3
  91. package/src/loader/index.ts +2 -0
  92. package/src/money/{Money.spec.js → Money.spec.tsx} +1 -1
  93. package/src/money/{Money.js → Money.tsx} +6 -7
  94. package/src/money/index.ts +2 -0
  95. package/src/navigationOptionsList/NavigationOptionsList.tsx +20 -0
  96. package/src/navigationOptionsList/index.ts +2 -0
  97. package/src/progress/{Progress.spec.js → Progress.spec.tsx} +4 -3
  98. package/src/progress/Progress.tsx +1 -1
  99. package/src/progress/index.ts +1 -0
  100. package/src/progressBar/index.ts +1 -0
  101. package/src/radio/Radio.story.tsx +3 -4
  102. package/src/segmentedControl/SegmentedControl.tsx +1 -0
  103. package/src/slidingPanel/SlidingPanel.tsx +4 -4
  104. package/src/statusIcon/StatusIcon.spec.tsx +80 -0
  105. package/src/statusIcon/StatusIcon.tsx +3 -4
  106. package/src/statusIcon/index.ts +2 -0
  107. package/src/switch/Switch.story.tsx +4 -1
  108. package/src/switch/Switch.tsx +3 -3
  109. package/src/switch/index.ts +1 -0
  110. package/src/switchOption/{SwitchOption.spec.js → SwitchOption.spec.tsx} +8 -3
  111. package/src/switchOption/SwitchOption.tsx +3 -3
  112. package/src/switchOption/index.ts +1 -0
  113. package/src/tooltip/Tooltip.tsx +2 -2
  114. package/src/tooltip/index.ts +2 -0
  115. package/build/types/common/dateUtils/getDayNames/index.d.ts +0 -2
  116. package/build/types/common/dateUtils/getDayNames/index.d.ts.map +0 -1
  117. package/build/types/common/dateUtils/getMonthNames/index.d.ts +0 -2
  118. package/build/types/common/dateUtils/getMonthNames/index.d.ts.map +0 -1
  119. package/build/types/common/dateUtils/isDateValid/index.d.ts +0 -2
  120. package/build/types/common/dateUtils/isDateValid/index.d.ts.map +0 -1
  121. package/build/types/common/dateUtils/isWithinRange/index.d.ts +0 -2
  122. package/build/types/common/dateUtils/isWithinRange/index.d.ts.map +0 -1
  123. package/build/types/common/dateUtils/moveToWithinRange/index.d.ts +0 -2
  124. package/build/types/common/dateUtils/moveToWithinRange/index.d.ts.map +0 -1
  125. package/src/common/dateUtils/getDayNames/index.ts +0 -1
  126. package/src/common/dateUtils/getMonthNames/index.ts +0 -1
  127. package/src/common/dateUtils/isDateValid/index.ts +0 -1
  128. package/src/common/dateUtils/isWithinRange/index.ts +0 -1
  129. package/src/common/dateUtils/moveToWithinRange/index.ts +0 -1
  130. package/src/loader/index.js +0 -3
  131. package/src/money/index.js +0 -1
  132. package/src/navigationOptionsList/NavigationOptionsList.js +0 -20
  133. package/src/navigationOptionsList/index.js +0 -1
  134. package/src/statusIcon/StatusIcon.spec.js +0 -70
  135. package/src/statusIcon/index.js +0 -1
  136. package/src/tooltip/index.js +0 -3
  137. /package/src/badge/{Badge.spec.js → Badge.spec.tsx} +0 -0
  138. /package/src/loader/{Loader.spec.js → Loader.spec.tsx} +0 -0
  139. /package/src/navigationOptionsList/{NavigationOptionsList.spec.js → NavigationOptionsList.spec.tsx} +0 -0
  140. /package/src/navigationOptionsList/{NavigationOptionsList.story.js → NavigationOptionsList.story.tsx} +0 -0
  141. /package/src/progressBar/{ProgressBar.spec.js → ProgressBar.spec.tsx} +0 -0
  142. /package/src/switch/{Switch.spec.js → Switch.spec.tsx} +0 -0
  143. /package/src/switch/__snapshots__/{Switch.spec.js.snap → Switch.spec.tsx.snap} +0 -0
@@ -1,11 +1,11 @@
1
1
  import classNames from 'classnames';
2
- import { ReactChild, ReactElement } from 'react';
2
+ import { ReactChild } from 'react';
3
3
 
4
4
  import ActionButton from '../actionButton';
5
5
  import { CommonProps, Priority, PriorityPrimary, PrioritySecondary } from '../common';
6
6
  import Option from '../common/Option';
7
7
 
8
- type Props = {
8
+ export type ActionOptionProps = {
9
9
  complex?: boolean;
10
10
  content?: ReactChild;
11
11
  disabled?: boolean;
@@ -32,7 +32,7 @@ const ActionOption = ({
32
32
  showMediaAtAllSizes,
33
33
  showMediaCircle,
34
34
  isContainerAligned,
35
- }: Props): ReactElement => {
35
+ }: ActionOptionProps) => {
36
36
  const sharedProps = {
37
37
  media,
38
38
  title,
@@ -1 +1,2 @@
1
1
  export { default } from './ActionOption';
2
+ export type { ActionOptionProps } from './ActionOption';
@@ -15,7 +15,7 @@ describe('Avatar', () => {
15
15
  </Avatar>,
16
16
  );
17
17
 
18
- expect(screen.getByText('😎').parentElement.parentElement).toHaveClass(
18
+ expect(screen.getByText('😎')?.parentElement?.parentElement).toHaveClass(
19
19
  'tw-avatar tw-avatar--thumbnail tw-avatar--48',
20
20
  );
21
21
  });
@@ -29,23 +29,16 @@ describe('Avatar', () => {
29
29
  </Avatar>,
30
30
  );
31
31
 
32
- expect(screen.getByText('💰').parentElement.parentElement).toHaveClass(
32
+ expect(screen.getByText('💰')?.parentElement?.parentElement).toHaveClass(
33
33
  'tw-avatar tw-avatar--emoji tw-avatar--24 tw-avatar--outlined',
34
34
  );
35
35
  });
36
36
 
37
37
  describe('branded avatar colors', () => {
38
- it.each(getAvatarColorTestCases())(
39
- 'for seed of %s return background color of %s',
40
- (key, color) => {
41
- render(<Avatar backgroundColorSeed={key.toString()}>JS</Avatar>);
38
+ it.each(avatarColorTestCases)('for seed of %s return background color of %s', (item) => {
39
+ render(<Avatar backgroundColorSeed={item.key.toString()}>JS</Avatar>);
42
40
 
43
- expect(screen.getByText('JS')).toHaveStyle(`background-color: ${color.token}`);
44
- },
45
- );
41
+ expect(screen.getByText('JS')).toHaveStyle(`background-color: ${item.color.token}`);
42
+ });
46
43
  });
47
44
  });
48
-
49
- function getAvatarColorTestCases() {
50
- return avatarColorTestCases.map(({ key, color }) => [key, color]);
51
- }
@@ -24,7 +24,7 @@ export const ExampleBadgeCss = {
24
24
 
25
25
  export const Avatar = () => {
26
26
  const BadgeText = text('BadgeText', 'B');
27
- const border = select('Border', [null, Theme.LIGHT, Theme.DARK]);
27
+ const border = select('Border', [undefined, Theme.LIGHT, Theme.DARK], Theme.LIGHT);
28
28
 
29
29
  return (
30
30
  <div>
@@ -1,5 +1,5 @@
1
1
  import classNames from 'classnames';
2
- import { ReactElement, ReactNode } from 'react';
2
+ import { ReactNode } from 'react';
3
3
 
4
4
  import {
5
5
  Size,
@@ -25,7 +25,7 @@ const Badge = ({
25
25
  size = Size.SMALL,
26
26
  border = Theme.LIGHT,
27
27
  children,
28
- }: BadgeProps): ReactElement => {
28
+ }: BadgeProps) => {
29
29
  const classes: string = classNames(
30
30
  'tw-badge',
31
31
  {
@@ -0,0 +1,2 @@
1
+ export const MDY = new Set(['en-US']);
2
+ export const YMD = new Set(['hu', 'hu-HU', 'zh-HK', 'zh-CN', 'ja', 'ja-JP']);
@@ -1,6 +1,7 @@
1
- export { getDayNames } from './getDayNames';
2
- export { moveToWithinRange } from './moveToWithinRange';
3
- export { isWithinRange } from './isWithinRange';
4
- export { getMonthNames } from './getMonthNames';
5
- export { isDateValid } from './isDateValid';
6
- export { isMonthAndYearFormat } from './isMonthAndYearFormat';
1
+ export { getDayNames } from './getDayNames/getDayNames';
2
+ export { moveToWithinRange } from './moveToWithinRange/moveToWithinRange';
3
+ export { isWithinRange } from './isWithinRange/isWithinRange';
4
+ export { getMonthNames } from './getMonthNames/getMonthNames';
5
+ export { isDateValid } from './isDateValid/isDateValid';
6
+ export { isMonthAndYearFormat } from './isMonthAndYearFormat/isMonthAndYearFormat';
7
+ export { MDY, YMD } from './getFormatForLocale/getFormatForLocale';
@@ -1,4 +1,4 @@
1
- import { validDateString } from '../isDateValid';
1
+ import { validDateString } from '../isDateValid/isDateValid';
2
2
 
3
3
  export const isMonthAndYearFormat = (dateString: string) =>
4
4
  validDateString(dateString) && dateString.split('-').length < 3;
@@ -1,11 +1,12 @@
1
1
  import { shallow, mount } from 'enzyme';
2
2
  import { useIntl } from 'react-intl';
3
3
 
4
- import { DateInput, Input } from '..';
4
+ import { DateInput } from '..';
5
5
  import { mockMatchMedia, mockResizeObserver } from '../test-utils';
6
6
 
7
7
  const LOCALES = {
8
8
  jp: 'ja-JP',
9
+ us: 'en-US',
9
10
  };
10
11
  const DEFAULT_LOCALE = 'en-GB';
11
12
  const FEBRUARY_INDEX = 1;
@@ -182,24 +183,43 @@ describe('Date Input Component', () => {
182
183
  });
183
184
 
184
185
  describe('when locale is provided', () => {
185
- it('shows day before month if locale not US', () => {
186
+ it('shows day before month if locale is GB', () => {
187
+ useIntl.mockReturnValue({
188
+ locale: DEFAULT_LOCALE,
189
+ formatMessage: (message) => message.defaultMessage,
190
+ });
191
+
186
192
  component = shallow(<DateInput {...props} />);
187
193
 
188
- const labels = component.find('label');
189
- expect(labels.at(0).find(Input).exists()).toBe(true);
190
- expect(labels.at(1).find(Input).exists()).toBe(false);
194
+ expect(component.find('span').at(0).text()).toBe('Day');
195
+ expect(component.find('span').at(1).text()).toBe('Month');
196
+ expect(component.find('span').at(2).text()).toBe('Year');
191
197
  });
192
198
 
193
- it('shows day before month if locale is JP', () => {
199
+ it('shows month before day if locale is US', () => {
200
+ useIntl.mockReturnValue({
201
+ locale: LOCALES.us,
202
+ formatMessage: (message) => message.defaultMessage,
203
+ });
204
+
205
+ component = shallow(<DateInput {...props} />);
206
+
207
+ expect(component.find('span').at(0).text()).toBe('Month');
208
+ expect(component.find('span').at(1).text()).toBe('Day');
209
+ expect(component.find('span').at(2).text()).toBe('Year');
210
+ });
211
+
212
+ it('shows year, month, day if locale is JP', () => {
194
213
  useIntl.mockReturnValue({
195
214
  locale: LOCALES.jp,
196
215
  formatMessage: (message) => message.defaultMessage,
197
216
  });
217
+
198
218
  component = shallow(<DateInput {...props} />);
199
219
 
200
- const labels = component.find('label');
201
- expect(labels.at(0).find(Input).exists()).toBe(false);
202
- expect(labels.at(1).find(Input).exists()).toBe(true);
220
+ expect(component.find('span').at(0).text()).toBe('Year');
221
+ expect(component.find('span').at(1).text()).toBe('Month');
222
+ expect(component.find('span').at(2).text()).toBe('Day');
203
223
  });
204
224
  });
205
225
 
@@ -16,9 +16,6 @@ export default {
16
16
  monthLabel: 'Month select',
17
17
  yearLabel: 'Year input',
18
18
  yearAutoComplete: 'bday-year',
19
- selectProps: {
20
- placeholder: 'Month',
21
- },
22
19
  },
23
20
  tags: ['autodocs'],
24
21
  } satisfies Meta<typeof DateInput>;
@@ -4,13 +4,11 @@ import { useIntl } from 'react-intl';
4
4
 
5
5
  import { Input, SelectInput, SelectInputProps, SelectInputOptionContent } from '..';
6
6
  import { Size, DateMode, MonthFormat, SizeSmall, SizeMedium, SizeLarge } from '../common';
7
- import { getMonthNames, isDateValid, isMonthAndYearFormat } from '../common/dateUtils';
7
+ import { getMonthNames, isDateValid, isMonthAndYearFormat, MDY, YMD } from '../common/dateUtils';
8
8
 
9
9
  import messages from './DateInput.messages';
10
10
  import { convertToLocalMidnight } from './utils';
11
11
 
12
- const MonthBeforeDay = new Set(['en-US', 'ja-JP']);
13
-
14
12
  export interface DateInputProps {
15
13
  'aria-label'?: string;
16
14
  'aria-labelledby'?: string;
@@ -243,7 +241,59 @@ const DateInput = ({
243
241
  'col-sm-5': !monthYearOnly,
244
242
  });
245
243
 
246
- const monthBeforeDay = MonthBeforeDay.has(locale);
244
+ const getMonth = () => {
245
+ return <div className={monthWidth}>{getSelectElement()}</div>;
246
+ };
247
+
248
+ const getDay = () => {
249
+ return (
250
+ <div className="col-sm-3">
251
+ <label>
252
+ <span className="sr-only">{dayLabel}</span>
253
+ <div className={`input-group input-group-${size}`}>
254
+ <Input
255
+ type="text"
256
+ inputMode="numeric"
257
+ pattern="[0-9]*"
258
+ name="day"
259
+ autoComplete={dayAutoComplete}
260
+ value={day || ''}
261
+ placeholder={placeholders?.day}
262
+ disabled={disabled}
263
+ min={1}
264
+ onChange={(event) => handleDayChange(event)}
265
+ />
266
+ </div>
267
+ </label>
268
+ </div>
269
+ );
270
+ };
271
+
272
+ const getYear = () => {
273
+ return (
274
+ <div className="col-sm-4">
275
+ <label>
276
+ <span className="sr-only">{yearLabel}</span>
277
+ <div className={`input-group input-group-${size}`}>
278
+ <Input
279
+ type="text"
280
+ inputMode="numeric"
281
+ pattern="[0-9]*"
282
+ name="year"
283
+ autoComplete={yearAutoComplete}
284
+ placeholder={placeholders?.year}
285
+ value={year || ''}
286
+ disabled={disabled}
287
+ min={1}
288
+ onChange={(event) => handleYearChange(event)}
289
+ />
290
+ </div>
291
+ </label>
292
+ </div>
293
+ );
294
+ };
295
+ const monthBeforeDay = MDY.has(locale);
296
+ const yearFirst = YMD.has(locale);
247
297
 
248
298
  return (
249
299
  <div
@@ -260,50 +310,42 @@ const DateInput = ({
260
310
  }
261
311
  >
262
312
  <div className="row">
263
- {monthBeforeDay && <div className={monthWidth}>{getSelectElement()}</div>}
264
- {!monthYearOnly && (
265
- <div className="col-sm-3">
266
- <label>
267
- <span className="sr-only">{dayLabel}</span>
268
- <div className={`input-group input-group-${size}`}>
269
- <Input
270
- type="text"
271
- inputMode="numeric"
272
- pattern="[0-9]*"
273
- name="day"
274
- autoComplete={dayAutoComplete}
275
- value={day || ''}
276
- placeholder={placeholders.day}
277
- disabled={disabled}
278
- min={1}
279
- onChange={(event) => handleDayChange(event)}
280
- />
281
- </div>
282
- </label>
283
- </div>
284
- )}
285
-
286
- {!monthBeforeDay && <div className={monthWidth}>{getSelectElement()}</div>}
287
-
288
- <div className="col-sm-4">
289
- <label>
290
- <span className="sr-only">{yearLabel}</span>
291
- <div className={`input-group input-group-${size}`}>
292
- <Input
293
- type="text"
294
- inputMode="numeric"
295
- pattern="[0-9]*"
296
- name="year"
297
- autoComplete={yearAutoComplete}
298
- placeholder={placeholders.year}
299
- value={year || ''}
300
- disabled={disabled}
301
- min={1}
302
- onChange={(event) => handleYearChange(event)}
303
- />
304
- </div>
305
- </label>
306
- </div>
313
+ {(() => {
314
+ if (monthYearOnly) {
315
+ return (
316
+ <>
317
+ {!yearFirst && getMonth()}
318
+ {getYear()}
319
+ {yearFirst && getMonth()}
320
+ </>
321
+ );
322
+ }
323
+ if (monthBeforeDay) {
324
+ return (
325
+ <>
326
+ {getMonth()}
327
+ {getDay()}
328
+ {getYear()}
329
+ </>
330
+ );
331
+ } else if (yearFirst) {
332
+ return (
333
+ <>
334
+ {getYear()}
335
+ {getMonth()}
336
+ {getDay()}
337
+ </>
338
+ );
339
+ } else {
340
+ return (
341
+ <>
342
+ {getDay()}
343
+ {getMonth()}
344
+ {getYear()}
345
+ </>
346
+ );
347
+ }
348
+ })()}
307
349
  </div>
308
350
  </div>
309
351
  );
@@ -12,10 +12,11 @@ describe('Emphasis', () => {
12
12
  ${'<negative>negative</negative>'} | ${'em.emphasis.emphasis--negative'}
13
13
  ${'<warning>warning</warning>'} | ${'em.emphasis.emphasis--warning'}
14
14
  `('$text renders as expected with selectoe $selector', ({ text, selector }) => {
15
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
15
16
  const { container } = render(<Emphasis text={text} />);
16
17
 
17
18
  expect(container.querySelector(selector)).toBeInTheDocument();
18
- expect(container.firstElementChild.tagName).toBe('SPAN');
19
+ expect(container?.firstElementChild?.tagName).toBe('SPAN');
19
20
  });
20
21
  });
21
22
 
@@ -5,7 +5,7 @@ import EmphasisHtmlTransformer from './EmphasisHtmlTransformer';
5
5
  const SUPPORTED_TAGS = ['important', 'positive', 'negative', 'warning'];
6
6
  const emphasisHtmlTransformer = new EmphasisHtmlTransformer(SUPPORTED_TAGS);
7
7
 
8
- type EmphasisProps = {
8
+ export type EmphasisProps = {
9
9
  text?: string;
10
10
  };
11
11
 
@@ -33,16 +33,4 @@ describe('creates safe, enphasised html', () => {
33
33
  expect(emphasisHtmlTransformer.transform('hello\nworld')).toStrictEqual('hello<br />world');
34
34
  });
35
35
  });
36
-
37
- describe('returns null when no input provided', () => {
38
- it('input is null', () => {
39
- const emphasisHtmlTransformer = new EmphasisHtmlTransformer();
40
- expect(emphasisHtmlTransformer.transform(null)).toBeNull();
41
- });
42
-
43
- it('input is undefined', () => {
44
- const emphasisHtmlTransformer = new EmphasisHtmlTransformer();
45
- expect(emphasisHtmlTransformer.transform(undefined)).toBeNull();
46
- });
47
- });
48
36
  });
@@ -15,7 +15,7 @@ type Tags = {
15
15
  class EmphasisHtmlTransformer {
16
16
  tags: Array<Tags>;
17
17
 
18
- constructor(whitelistedTags: Array<string>) {
18
+ constructor(whitelistedTags?: Array<string>) {
19
19
  this.tags = (whitelistedTags || []).map((tag) => {
20
20
  return {
21
21
  transformed: {
@@ -1 +1,2 @@
1
1
  export { default } from './Emphasis';
2
+ export type { EmphasisProps } from './Emphasis';
package/src/i18n/es.json CHANGED
@@ -29,13 +29,13 @@
29
29
  "neptune.Upload.csButtonText": "¿Quieres subir otro archivo?",
30
30
  "neptune.Upload.csFailureText": "La carga del archivo ha fallado. Por favor, inténtalo de nuevo",
31
31
  "neptune.Upload.csSuccessText": "¡Se ha subido el archivo!",
32
- "neptune.Upload.csTooLargeMessage": "Por favor, sube un archivo de menos de {maxSize}MB",
32
+ "neptune.Upload.csTooLargeMessage": "Proporciona un archivo menor de {maxSize} MB",
33
33
  "neptune.Upload.csWrongTypeMessage": "Tipo de archivo no aceptado. Por favor, inténtalo de nuevo con un archivo diferente",
34
34
  "neptune.Upload.psButtonText": "Cancela",
35
35
  "neptune.Upload.psProcessingText": "Subiendo...",
36
36
  "neptune.Upload.usButtonText": "O selecciona un archivo",
37
37
  "neptune.Upload.usDropMessage": "Arrastra un archivo para subirlo",
38
- "neptune.Upload.usPlaceholder": "Arrastra y suelta un archivo menor de {maxSize}MB",
38
+ "neptune.Upload.usPlaceholder": "Arrastra y suelta un archivo de menos de {maxSize} MB",
39
39
  "neptune.UploadButton.allFileTypes": "Todos los tipos de archivos",
40
40
  "neptune.UploadButton.dropFiles": "Arrastra un archivo para subirlo",
41
41
  "neptune.UploadButton.instructions": "{fileTypes}, menor que {size}MB",
package/src/i18n/hu.json CHANGED
@@ -29,13 +29,13 @@
29
29
  "neptune.Upload.csButtonText": "Másik fájl feltöltése?",
30
30
  "neptune.Upload.csFailureText": "Feltöltés sikertelen. Kérünk, próbáld újra",
31
31
  "neptune.Upload.csSuccessText": "Feltöltés sikeres",
32
- "neptune.Upload.csTooLargeMessage": "Kérünk, {maxSize} MB-nál kisebb fájlt tölts fel",
32
+ "neptune.Upload.csTooLargeMessage": "Kérünk, olyan fájlt küldj el, amely kisebb mint {maxSize}MB",
33
33
  "neptune.Upload.csWrongTypeMessage": "Nem támogatott fájltípus. Kérünk, próbáld újra másik fájllal",
34
34
  "neptune.Upload.psButtonText": "Mégsem",
35
35
  "neptune.Upload.psProcessingText": "Feltöltés...",
36
36
  "neptune.Upload.usButtonText": "Vagy válaszd ki a fájlt",
37
37
  "neptune.Upload.usDropMessage": "Húzd ide a fájlokat a feltöltéshez",
38
- "neptune.Upload.usPlaceholder": "Húzz ide egy {maxSize} MB-nál kisebb fájlt",
38
+ "neptune.Upload.usPlaceholder": "Húzz ide egy legfeljebb {maxSize} MB méretű fájlt",
39
39
  "neptune.UploadButton.allFileTypes": "Összes fájltípus",
40
40
  "neptune.UploadButton.dropFiles": "Húzd a fájlokat ide a feltöltéshez",
41
41
  "neptune.UploadButton.instructions": "{fileTypes}, legfeljebb {size}MB",
package/src/i18n/index.ts CHANGED
@@ -21,6 +21,7 @@ const translations: Record<string, Record<string, string>> = {
21
21
  cs,
22
22
  de,
23
23
  en,
24
+ 'en-US': en,
24
25
  es,
25
26
  fr,
26
27
  hu,
@@ -29,13 +29,13 @@
29
29
  "neptune.Upload.csButtonText": "上載另一個檔案?",
30
30
  "neptune.Upload.csFailureText": "上載失敗,請重試。",
31
31
  "neptune.Upload.csSuccessText": "上載完成!",
32
- "neptune.Upload.csTooLargeMessage": "請提供小於{maxSize}MB的檔案",
32
+ "neptune.Upload.csTooLargeMessage": "請提供一個小於{maxSize}MB的檔案",
33
33
  "neptune.Upload.csWrongTypeMessage": "不支持檔案類型,請使用其他檔案重試",
34
34
  "neptune.Upload.psButtonText": "取消",
35
35
  "neptune.Upload.psProcessingText": "上載中...",
36
36
  "neptune.Upload.usButtonText": "或者選擇一個檔案",
37
37
  "neptune.Upload.usDropMessage": "拖放檔案以開始上載",
38
- "neptune.Upload.usPlaceholder": "拖放不超過{maxSize}MB的檔案",
38
+ "neptune.Upload.usPlaceholder": "拖放一個不超過{maxSize}MB的檔案",
39
39
  "neptune.UploadButton.allFileTypes": "所有檔案類型",
40
40
  "neptune.UploadButton.dropFiles": "拖放檔案以開始上載",
41
41
  "neptune.UploadButton.instructions": "{fileTypes},小於{size}MB",
package/src/index.ts CHANGED
@@ -2,14 +2,20 @@
2
2
  * Types
3
3
  */
4
4
  export type { AccordionProps, AccordionItem } from './accordion';
5
+ export type { AvatarProps } from './avatar';
6
+ export type { ActionOptionProps } from './actionOption';
7
+ export type { BadgeProps } from './badge';
5
8
  export type { CircularButtonProps } from './circularButton';
6
9
  export type { DecisionProps } from './decision/Decision';
10
+ export type { EmphasisProps } from './emphasis';
7
11
  export type { InfoProps } from './info';
8
12
  export type { SummaryProps } from './summary';
9
13
  export type { InputProps } from './inputs/Input';
10
14
  export type { DateInputProps } from './dateInput';
11
15
  export type { InputWithDisplayFormatProps } from './inputWithDisplayFormat';
12
16
  export type { InputGroupProps } from './inputs/InputGroup';
17
+ export type { LoaderProps } from './loader';
18
+ export type { NavigationOptionListProps } from './navigationOptionsList';
13
19
  export type { SearchInputProps } from './inputs/SearchInput';
14
20
  export type {
15
21
  SelectInputGroupItem,
@@ -23,16 +29,23 @@ export type {
23
29
  export type { TextAreaProps } from './inputs/TextArea';
24
30
  export type { PhoneNumberInputProps } from './phoneNumberInput/PhoneNumberInput';
25
31
  export type { PopoverProps } from './popover';
32
+ export type { ProgressProps } from './progress';
33
+ export type { ProgressBarProps } from './progressBar';
26
34
  export type { RadioProps } from './radio';
27
35
  export type { RadioGroupProps, RadioGroupRadio } from './radioGroup';
28
36
  export type { RadioOptionProps } from './radioOption';
29
37
  export type { SnackbarProps } from './snackbar/Snackbar';
30
38
  export type { SnackbarContextType } from './snackbar/SnackbarContext';
39
+ export type { StatusIconProps } from './statusIcon';
31
40
  export type { StickyProps } from './sticky';
41
+ export type { SwitchProps } from './switch';
42
+ export type { SwitchOptionProps } from './switchOption';
32
43
  export type { TextareaWithDisplayFormatProps } from './textareaWithDisplayFormat';
44
+ export type { TooltipProps } from './tooltip';
33
45
  export type { UploadedFile, UploadError, UploadResponse } from './uploadInput/types';
34
46
  export type { MarkdownProps } from './markdown';
35
47
  export type { ModalProps } from './modal';
48
+ export type { MoneyProps } from './money';
36
49
  export type {
37
50
  CurrencyHeaderItem,
38
51
  CurrencyItem,
@@ -34,14 +34,15 @@ const Template = (args) => {
34
34
  const placeholder = args.pattern;
35
35
  const displayPattern = args.pattern;
36
36
  const label = args.label;
37
+ const id = label.replaceAll(' ', '-').toLowerCase();
37
38
 
38
39
  return (
39
40
  <>
40
- <label id="template" htmlFor="template">
41
+ <label id="template" htmlFor={id}>
41
42
  {label}
42
43
  </label>
43
44
  <InputWithDisplayFormat
44
- id="template"
45
+ id={id}
45
46
  placeholder={placeholder}
46
47
  displayPattern={displayPattern}
47
48
  className="form-control"
@@ -5,7 +5,6 @@ import classNames from 'classnames';
5
5
  import mergeProps from 'merge-props';
6
6
  import { createContext, forwardRef, useContext, useEffect, useMemo, useRef, useState } from 'react';
7
7
  import { useIntl } from 'react-intl';
8
- import mergeRefs from 'react-merge-refs';
9
8
 
10
9
  import { useEffectEvent } from '../common/hooks/useEffectEvent';
11
10
  import { useScreenSize } from '../common/hooks/useScreenSize';
@@ -251,7 +250,7 @@ export function SelectInput<T = string, M extends boolean = false>({
251
250
  });
252
251
  });
253
252
 
254
- const triggerRef = useRef<HTMLButtonElement>(null);
253
+ const triggerRef = useRef<HTMLButtonElement | null>(null);
255
254
 
256
255
  const screenSm = useScreenSize(Breakpoint.SMALL);
257
256
  const OptionsOverlay = screenSm ? Popover : BottomSheet;
@@ -290,7 +289,10 @@ export function SelectInput<T = string, M extends boolean = false>({
290
289
  <SelectInputTriggerButtonPropsContext.Provider
291
290
  // eslint-disable-next-line react/jsx-no-constructed-context-values
292
291
  value={{
293
- ref: mergeRefs([ref, triggerRef]),
292
+ ref: (node) => {
293
+ ref(node);
294
+ triggerRef.current = node;
295
+ },
294
296
  id,
295
297
  ...mergeProps(
296
298
  {
@@ -1,6 +1,6 @@
1
1
  import { useTheme } from '@wise/components-theming';
2
2
  import classnames from 'classnames';
3
- import { ReactElement, useEffect, useState } from 'react';
3
+ import { useEffect, useState } from 'react';
4
4
 
5
5
  import { Size, SizeExtraSmall, SizeSmall, SizeMedium, SizeLarge, SizeExtraLarge } from '../common';
6
6
 
@@ -9,7 +9,7 @@ type DeprecatedSize = SizeExtraSmall | SizeLarge | SizeExtraLarge;
9
9
 
10
10
  type SizeType = SizeSmall | SizeMedium;
11
11
 
12
- type Props = {
12
+ export type LoaderProps = {
13
13
  /**
14
14
  * @deprecated use `size` instead
15
15
  */
@@ -37,7 +37,7 @@ const Loader = ({
37
37
  displayInstantly = false,
38
38
  classNames = {},
39
39
  ...restProps
40
- }: Props): ReactElement => {
40
+ }: LoaderProps) => {
41
41
  const { theme } = useTheme();
42
42
  const [hasDebounced, setHasDebounced] = useState(displayInstantly);
43
43
 
@@ -0,0 +1,2 @@
1
+ export { default } from './Loader';
2
+ export type { LoaderProps } from './Loader';
@@ -11,7 +11,7 @@ describe('Money', () => {
11
11
  it('formats the string with amount, currency & the passed in locale', () => {
12
12
  const { container } = render(<Money amount={4.98} currency="GBP" />, {
13
13
  locale: 'fr',
14
- messages: {},
14
+ messages: undefined,
15
15
  });
16
16
  expect(container).toHaveTextContent('4,98 GBP');
17
17
  });
@@ -1,15 +1,14 @@
1
1
  import { formatMoney } from '@transferwise/formatting';
2
- import PropTypes from 'prop-types';
3
2
  import { useIntl } from 'react-intl';
4
3
 
5
- const Money = ({ amount, currency }) => {
4
+ export interface MoneyProps {
5
+ amount: number;
6
+ currency: string;
7
+ }
8
+
9
+ const Money = ({ amount, currency }: MoneyProps) => {
6
10
  const { locale } = useIntl();
7
11
  return <>{formatMoney(amount, currency, locale)}</>;
8
12
  };
9
13
 
10
- Money.propTypes = {
11
- amount: PropTypes.number.isRequired,
12
- currency: PropTypes.string.isRequired,
13
- };
14
-
15
14
  export default Money;
@@ -0,0 +1,2 @@
1
+ export { default } from './Money';
2
+ export type { MoneyProps } from './Money';