@transferwise/components 0.0.0-experimental-da6dbbf → 0.0.0-experimental-4c1cb43

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 (96) hide show
  1. package/build/index.js +635 -933
  2. package/build/index.js.map +1 -1
  3. package/build/index.mjs +625 -922
  4. package/build/index.mjs.map +1 -1
  5. package/build/main.css +0 -135
  6. package/build/styles/main.css +0 -135
  7. package/build/types/accordion/AccordionItem/AccordionItem.d.ts.map +1 -1
  8. package/build/types/common/card/Card.d.ts +2 -2
  9. package/build/types/common/card/Card.d.ts.map +1 -1
  10. package/build/types/common/hooks/useMedia.d.ts.map +1 -1
  11. package/build/types/common/panel/Panel.d.ts.map +1 -1
  12. package/build/types/common/responsivePanel/ResponsivePanel.d.ts.map +1 -1
  13. package/build/types/dateLookup/DateLookup.d.ts +6 -5
  14. package/build/types/dateLookup/DateLookup.d.ts.map +1 -1
  15. package/build/types/dimmer/Dimmer.d.ts +1 -11
  16. package/build/types/dimmer/Dimmer.d.ts.map +1 -1
  17. package/build/types/drawer/Drawer.d.ts +4 -4
  18. package/build/types/index.d.ts +3 -4
  19. package/build/types/index.d.ts.map +1 -1
  20. package/build/types/inputWithDisplayFormat/InputWithDisplayFormat.d.ts +2 -1
  21. package/build/types/inputWithDisplayFormat/InputWithDisplayFormat.d.ts.map +1 -1
  22. package/build/types/inputs/SelectInput.d.ts.map +1 -1
  23. package/build/types/inputs/contexts.d.ts +2 -2
  24. package/build/types/inputs/contexts.d.ts.map +1 -1
  25. package/build/types/modal/Modal.d.ts.map +1 -1
  26. package/build/types/processIndicator/ProcessIndicator.d.ts +36 -19
  27. package/build/types/processIndicator/ProcessIndicator.d.ts.map +1 -1
  28. package/build/types/processIndicator/index.d.ts +2 -2
  29. package/build/types/processIndicator/index.d.ts.map +1 -1
  30. package/build/types/promoCard/PromoCard.d.ts +5 -16
  31. package/build/types/promoCard/PromoCard.d.ts.map +1 -1
  32. package/build/types/select/searchBox/SearchBox.d.ts +1 -1
  33. package/build/types/textareaWithDisplayFormat/TextareaWithDisplayFormat.d.ts +2 -1
  34. package/build/types/textareaWithDisplayFormat/TextareaWithDisplayFormat.d.ts.map +1 -1
  35. package/build/types/tooltip/Tooltip.d.ts +1 -1
  36. package/build/types/tooltip/Tooltip.d.ts.map +1 -1
  37. package/build/types/uploadInput/uploadItem/UploadItem.d.ts.map +1 -1
  38. package/build/types/withDisplayFormat/WithDisplayFormat.d.ts +14 -14
  39. package/build/types/withDisplayFormat/WithDisplayFormat.d.ts.map +1 -1
  40. package/package.json +9 -13
  41. package/src/accordion/AccordionItem/AccordionItem.tsx +2 -4
  42. package/src/avatarWrapper/AvatarWrapper.story.tsx +1 -3
  43. package/src/button/Button.tsx +1 -1
  44. package/src/common/card/Card.tsx +43 -51
  45. package/src/common/hooks/useConditionalListener/useConditionalListener.spec.js +1 -1
  46. package/src/common/hooks/useHasIntersected/useHasIntersected.spec.js +3 -3
  47. package/src/common/hooks/useMedia.spec.ts +1 -1
  48. package/src/common/hooks/useMedia.ts +1 -2
  49. package/src/common/panel/Panel.tsx +90 -92
  50. package/src/common/responsivePanel/ResponsivePanel.tsx +34 -38
  51. package/src/dateLookup/DateLookup.rtl.spec.tsx +181 -5
  52. package/src/dateLookup/DateLookup.testingLibrary.spec.js +171 -124
  53. package/src/dateLookup/DateLookup.tsx +14 -9
  54. package/src/drawer/Drawer.js +3 -3
  55. package/src/field/Field.tsx +3 -3
  56. package/src/index.ts +3 -4
  57. package/src/inputWithDisplayFormat/InputWithDisplayFormat.tsx +2 -1
  58. package/src/inputs/SelectInput.story.tsx +2 -1
  59. package/src/inputs/SelectInput.tsx +10 -2
  60. package/src/inputs/contexts.tsx +4 -4
  61. package/src/main.css +0 -135
  62. package/src/main.less +0 -1
  63. package/src/modal/Modal.tsx +1 -2
  64. package/src/processIndicator/ProcessIndicator.rtl.spec.tsx +45 -0
  65. package/src/processIndicator/ProcessIndicator.tsx +110 -0
  66. package/src/promoCard/PromoCard.story.tsx +2 -2
  67. package/src/promoCard/PromoCard.tsx +9 -31
  68. package/src/radio/__snapshots__/Radio.rtl.spec.tsx.snap +0 -1
  69. package/src/snackbar/Snackbar.spec.js +4 -1
  70. package/src/snackbar/Snackbar.story.tsx +4 -2
  71. package/src/tabs/Tabs.spec.js +46 -27
  72. package/src/test-utils/index.js +5 -7
  73. package/src/test-utils/jest.setup.js +9 -3
  74. package/src/textareaWithDisplayFormat/TextareaWithDisplayFormat.tsx +2 -1
  75. package/src/tooltip/Tooltip.tsx +44 -46
  76. package/src/tooltip/__snapshots__/Tooltip.spec.tsx.snap +2 -2
  77. package/src/upload/Upload.spec.js +34 -13
  78. package/src/uploadInput/UploadInput.spec.tsx +21 -23
  79. package/src/uploadInput/uploadItem/UploadItem.tsx +1 -3
  80. package/src/withDisplayFormat/WithDisplayFormat.spec.js +63 -32
  81. package/src/withDisplayFormat/WithDisplayFormat.tsx +28 -28
  82. package/build/styles/carousel/Carousel.css +0 -135
  83. package/build/types/carousel/Carousel.d.ts +0 -26
  84. package/build/types/carousel/Carousel.d.ts.map +0 -1
  85. package/build/types/carousel/index.d.ts +0 -3
  86. package/build/types/carousel/index.d.ts.map +0 -1
  87. package/src/carousel/Carousel.css +0 -135
  88. package/src/carousel/Carousel.less +0 -133
  89. package/src/carousel/Carousel.spec.tsx +0 -221
  90. package/src/carousel/Carousel.story.tsx +0 -63
  91. package/src/carousel/Carousel.tsx +0 -345
  92. package/src/carousel/index.ts +0 -3
  93. package/src/dateLookup/DateLookup.keyboardEvents.spec.js +0 -180
  94. package/src/processIndicator/ProcessIndicator.js +0 -117
  95. package/src/processIndicator/ProcessIndicator.spec.js +0 -101
  96. /package/src/processIndicator/{index.js → index.ts} +0 -0
@@ -1,9 +1,9 @@
1
1
  import '@testing-library/jest-dom';
2
2
  import user from '@testing-library/user-event';
3
+ import { act } from 'react';
3
4
 
4
5
  import { render, screen, mockMatchMedia } from '../test-utils';
5
-
6
- import DateLookup from '.';
6
+ import DateLookup from './DateLookup';
7
7
 
8
8
  mockMatchMedia();
9
9
 
@@ -20,171 +20,218 @@ describe('DateLookup (events)', () => {
20
20
  const min = new Date(2018, 11, 26);
21
21
  const max = new Date(2018, 11, 28);
22
22
 
23
- let props;
24
- let container;
25
- let rerender;
26
-
27
- beforeEach(() => {
28
- props = {
29
- value: date,
30
- min,
31
- max,
32
- size: 'lg',
33
- placeholder: 'Asd..',
34
- label: 'label',
35
- 'aria-labelledby': 'prioritized-label',
36
- onChange: jest.fn(),
37
- onClick: jest.fn(),
38
- disabled: false,
39
- clearable: false,
23
+ describe('when not clearable', () => {
24
+ /** @type {jest.Mock} */
25
+ let handleChange;
26
+
27
+ const setup = async () => {
28
+ handleChange = jest.fn();
29
+
30
+ /** @type {import('@testing-library/react').RenderResult} */
31
+ let view;
32
+ await act(async () => {
33
+ view = render(
34
+ <>
35
+ {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
36
+ <label id="prioritized-label">Prioritized label</label>
37
+ <DateLookup
38
+ value={date}
39
+ min={min}
40
+ max={max}
41
+ size="lg"
42
+ placeholder="Asd.."
43
+ label="label"
44
+ aria-labelledby="prioritized-label"
45
+ disabled={false}
46
+ clearable={false}
47
+ onChange={handleChange}
48
+ onClick={jest.fn()}
49
+ />
50
+ </>,
51
+ );
52
+ });
53
+ return view;
40
54
  };
41
- ({ container } = render(
42
- <>
43
- {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
44
- <label id="prioritized-label">Prioritized label</label>
45
- <DateLookup {...props} />
46
- </>,
47
- ));
48
- });
49
55
 
50
- afterEach(() => {
51
- closeDateLookup();
52
- });
56
+ it('switches to years', async () => {
57
+ const view = await setup();
58
+ openDateLookup(view);
59
+ clickDateButton(view);
53
60
 
54
- it('switches to years', () => {
55
- openDateLookup();
56
- clickDateButton();
61
+ expect(getActiveYearButton(view)).toHaveFocus();
57
62
 
58
- expect(getActiveYearButton()).toHaveFocus();
59
- });
63
+ closeDateLookup(view);
64
+ });
60
65
 
61
- it('has aria-label for 20 years', () => {
62
- openDateLookup();
63
- clickDateButton();
66
+ it('has aria-label for 20 years', async () => {
67
+ const view = await setup();
68
+ openDateLookup(view);
69
+ clickDateButton(view);
64
70
 
65
- expect(getButtonByAriaLabel('next 20 years')).toBeInTheDocument();
66
- expect(getButtonByAriaLabel('previous 20 years')).toBeInTheDocument();
67
- });
71
+ expect(getButtonByAriaLabel('next 20 years')).toBeInTheDocument();
72
+ expect(getButtonByAriaLabel('previous 20 years')).toBeInTheDocument();
68
73
 
69
- it('switches to months', () => {
70
- openDateLookup();
71
- clickDateButton();
72
- user.click(getActiveYearButton());
74
+ closeDateLookup(view);
75
+ });
73
76
 
74
- expect(getActiveMonthButton()).toHaveFocus();
75
- });
77
+ it('switches to months', async () => {
78
+ const view = await setup();
79
+ openDateLookup(view);
80
+ clickDateButton(view);
81
+ user.click(getActiveYearButton(view));
76
82
 
77
- it('has aria label for year', () => {
78
- openDateLookup();
79
- clickDateButton();
80
- user.click(getActiveYearButton());
83
+ expect(getActiveMonthButton(view)).toHaveFocus();
81
84
 
82
- expect(getButtonByAriaLabel('next year')).toBeInTheDocument();
83
- expect(getButtonByAriaLabel('previous year')).toBeInTheDocument();
84
- });
85
+ closeDateLookup(view);
86
+ });
85
87
 
86
- it('switches to days', () => {
87
- openDateLookup();
88
- clickDateButton();
89
- user.click(getActiveYearButton());
90
- user.click(getActiveMonthButton());
88
+ it('has aria label for year', async () => {
89
+ const view = await setup();
90
+ openDateLookup(view);
91
+ clickDateButton(view);
92
+ user.click(getActiveYearButton(view));
91
93
 
92
- expect(getActiveDayButton()).toHaveFocus();
93
- });
94
+ expect(getButtonByAriaLabel('next year')).toBeInTheDocument();
95
+ expect(getButtonByAriaLabel('previous year')).toBeInTheDocument();
94
96
 
95
- it('has aria label for month', () => {
96
- openDateLookup();
97
- clickDateButton();
98
- user.click(getActiveYearButton());
99
- user.click(getActiveMonthButton());
97
+ closeDateLookup(view);
98
+ });
100
99
 
101
- expect(getButtonByAriaLabel('next month')).toBeInTheDocument();
102
- expect(getButtonByAriaLabel('previous month')).toBeInTheDocument();
103
- });
100
+ it('switches to days', async () => {
101
+ const view = await setup();
102
+ openDateLookup(view);
103
+ clickDateButton(view);
104
+ user.click(getActiveYearButton(view));
105
+ user.click(getActiveMonthButton(view));
104
106
 
105
- it('updates selected date and closes', () => {
106
- openDateLookup();
107
- const d = new Date(2018, 11, 28);
108
- const newDay = screen.getByText(d.getDate().toString());
109
- user.click(newDay);
107
+ expect(getActiveDayButton(view)).toHaveFocus();
110
108
 
111
- expect(props.onChange).toHaveBeenCalledWith(d);
112
- expect(getOpenButton()).toHaveFocus();
113
- });
109
+ closeDateLookup(view);
110
+ });
114
111
 
115
- it('has aria label on selected date', () => {
116
- openDateLookup();
117
- const d = new Date(2018, 11, 28);
118
- const newDay = screen.getByText(d.getDate().toString());
119
- user.click(newDay);
120
- openDateLookup();
121
- expect(screen.getByRole('button', { name: /selected day/i })).toBeInTheDocument();
122
- });
112
+ it('has aria label for month', async () => {
113
+ const view = await setup();
114
+ openDateLookup(view);
115
+ clickDateButton(view);
116
+ user.click(getActiveYearButton(view));
117
+ user.click(getActiveMonthButton(view));
123
118
 
124
- it('supports custom `aria-labelledby` attribute', () => {
125
- expect(screen.getByLabelText('Prioritized label')).toHaveClass('input-group');
119
+ expect(getButtonByAriaLabel('next month')).toBeInTheDocument();
120
+ expect(getButtonByAriaLabel('previous month')).toBeInTheDocument();
121
+
122
+ closeDateLookup(view);
123
+ });
124
+
125
+ it('updates selected date and closes', async () => {
126
+ const view = await setup();
127
+ openDateLookup(view);
128
+ const d = new Date(2018, 11, 28);
129
+ const newDay = screen.getByText(d.getDate().toString());
130
+ user.click(newDay);
131
+
132
+ expect(handleChange).toHaveBeenCalledWith(d);
133
+ expect(getOpenButton(view)).toHaveFocus();
134
+
135
+ closeDateLookup(view);
136
+ });
137
+
138
+ it('has aria label on selected date', async () => {
139
+ const view = await setup();
140
+ openDateLookup(view);
141
+ const d = new Date(2018, 11, 28);
142
+ const newDay = screen.getByText(d.getDate().toString());
143
+ user.click(newDay);
144
+ openDateLookup(view);
145
+ expect(screen.getByRole('button', { name: /selected day/i })).toBeInTheDocument();
146
+
147
+ closeDateLookup(view);
148
+ });
149
+
150
+ it('supports custom `aria-labelledby` attribute', async () => {
151
+ const view = await setup();
152
+ expect(screen.getByLabelText('Prioritized label')).toHaveClass('input-group');
153
+
154
+ closeDateLookup(view);
155
+ });
126
156
  });
127
157
 
128
158
  describe('when is clearable', () => {
129
- beforeEach(() => {
130
- props = { value: date, onChange: jest.fn(), clearable: true };
131
- ({ container, rerender } = render(<DateLookup {...props} />));
132
- });
159
+ /** @satisfies {import('./DateLookup').DateLookupProps} */
160
+ const props = {
161
+ value: date,
162
+ onChange: jest.fn(),
163
+ clearable: true,
164
+ };
165
+
166
+ const setup = async () => {
167
+ /** @type {import('@testing-library/react').RenderResult} */
168
+ let view;
169
+ await act(async () => {
170
+ view = render(<DateLookup {...props} />);
171
+ });
172
+ return view;
173
+ };
133
174
 
134
- it(`doesn't show clear button if disable is true`, () => {
135
- expect(getClearButton()).toBeInTheDocument();
175
+ it(`doesn't show clear button if disable is true`, async () => {
176
+ const view = await setup();
177
+ expect(getClearButton(view)).toBeInTheDocument();
136
178
 
137
- rerender(<DateLookup {...props} disabled />);
179
+ view.rerender(<DateLookup {...props} disabled />);
138
180
 
139
- expect(getClearButton()).not.toBeInTheDocument();
181
+ expect(getClearButton(view)).not.toBeInTheDocument();
140
182
  });
141
183
 
142
- it('when user clicks on clear the focus returns to btn', () => {
143
- clickClearButton();
144
- expect(getOpenButton()).toHaveFocus();
184
+ it('when user clicks on clear the focus returns to btn', async () => {
185
+ const view = await setup();
186
+ clickClearButton(view);
187
+ expect(getOpenButton(view)).toHaveFocus();
145
188
  });
146
189
 
147
- it('onChange gets called with null when reset button is clicked', () => {
148
- clickClearButton();
190
+ it('onChange gets called with null when reset button is clicked', async () => {
191
+ const view = await setup();
192
+ clickClearButton(view);
149
193
  expect(props.onChange).toHaveBeenCalledWith(null);
150
194
  });
151
195
  });
152
196
 
153
- const openDateLookup = () => {
154
- user.click(getOpenButton());
155
- };
197
+ const openDateLookup = (/** @type {import('@testing-library/react').RenderResult} */ view) =>
198
+ user.click(getOpenButton(view));
156
199
 
157
- const clickDateButton = () => {
158
- user.click(getDateButton());
159
- };
200
+ const clickDateButton = (/** @type {import('@testing-library/react').RenderResult} */ view) =>
201
+ user.click(getDateButton(view));
160
202
 
161
203
  // Close dateLookup and removes events attached to documents.
162
- const closeDateLookup = () => {
163
- user.click(container);
164
- };
204
+ const closeDateLookup = (/** @type {import('@testing-library/react').RenderResult} */ view) =>
205
+ user.click(view.container);
165
206
 
166
- const clickClearButton = () => {
167
- user.click(getClearButton());
168
- };
207
+ const clickClearButton = (/** @type {import('@testing-library/react').RenderResult} */ view) =>
208
+ user.click(getClearButton(view));
169
209
 
170
- const getActiveYearButton = () => {
171
- return container.querySelector('button.tw-date-lookup-year-option.active');
210
+ const getActiveYearButton = (
211
+ /** @type {import('@testing-library/react').RenderResult} */ view,
212
+ ) => {
213
+ return view.container.querySelector('button.tw-date-lookup-year-option.active');
172
214
  };
173
215
 
174
- const getActiveMonthButton = () => {
175
- return container.querySelector('button.tw-date-lookup-month-option.active');
216
+ const getActiveMonthButton = (
217
+ /** @type {import('@testing-library/react').RenderResult} */ view,
218
+ ) => {
219
+ return view.container.querySelector('button.tw-date-lookup-month-option.active');
176
220
  };
177
221
 
178
- const getActiveDayButton = () => {
179
- return container.querySelector('button.tw-date-lookup-day-option.active');
222
+ const getActiveDayButton = (
223
+ /** @type {import('@testing-library/react').RenderResult} */ view,
224
+ ) => {
225
+ return view.container.querySelector('button.tw-date-lookup-day-option.active');
180
226
  };
181
227
 
182
- const getButtonByAriaLabel = (ariaLabel) => {
228
+ const getButtonByAriaLabel = (/** @type {string} */ ariaLabel) => {
183
229
  return screen.getByRole('button', { name: ariaLabel });
184
230
  };
185
- const getClearButton = () => container.querySelector('.clear-btn');
186
- const getOpenButton = () => container.querySelector('button.np-date-trigger');
187
- const getDateButton = () => container.querySelector('button.tw-date-lookup-header-current');
188
- const getBottomSheet = () => container.querySelector('.np-bottom-sheet');
189
- const getPanel = () => container.querySelector('.np-panel');
231
+ const getClearButton = (/** @type {import('@testing-library/react').RenderResult} */ view) =>
232
+ view.container.querySelector('.clear-btn');
233
+ const getOpenButton = (/** @type {import('@testing-library/react').RenderResult} */ view) =>
234
+ view.container.querySelector('button.np-date-trigger');
235
+ const getDateButton = (/** @type {import('@testing-library/react').RenderResult} */ view) =>
236
+ view.container.querySelector('button.tw-date-lookup-header-current');
190
237
  });
@@ -19,7 +19,7 @@ import { getStartOfDay } from './getStartOfDay';
19
19
  import MonthCalendar from './monthCalendar';
20
20
  import YearCalendar from './yearCalendar';
21
21
 
22
- export interface DateLookupProps extends Partial<WithInputAttributesProps> {
22
+ export interface DateLookupProps {
23
23
  id?: string;
24
24
  value: Date | null;
25
25
  min?: Date | null;
@@ -36,6 +36,8 @@ export interface DateLookupProps extends Partial<WithInputAttributesProps> {
36
36
  onBlur?: () => void;
37
37
  }
38
38
 
39
+ type DateLookupPropsWithInputAttributes = DateLookupProps & Partial<WithInputAttributesProps>;
40
+
39
41
  interface DateLookupState {
40
42
  selectedDate: Date | null;
41
43
  originalDate: Date | null;
@@ -48,9 +50,9 @@ interface DateLookupState {
48
50
  isMobile: boolean;
49
51
  }
50
52
 
51
- class DateLookup extends PureComponent<DateLookupProps, DateLookupState> {
52
- declare props: DateLookupProps &
53
- Required<Pick<DateLookupProps, keyof typeof DateLookup.defaultProps>>;
53
+ class DateLookup extends PureComponent<DateLookupPropsWithInputAttributes, DateLookupState> {
54
+ declare props: DateLookupPropsWithInputAttributes &
55
+ Required<Pick<DateLookupPropsWithInputAttributes, keyof typeof DateLookup.defaultProps>>;
54
56
 
55
57
  static defaultProps = {
56
58
  value: null,
@@ -62,7 +64,7 @@ class DateLookup extends PureComponent<DateLookupProps, DateLookupState> {
62
64
  monthFormat: MonthFormat.LONG,
63
65
  disabled: false,
64
66
  clearable: false,
65
- } satisfies Partial<DateLookupProps>;
67
+ } satisfies Partial<DateLookupPropsWithInputAttributes>;
66
68
 
67
69
  element = createRef<HTMLDivElement>();
68
70
  dropdown = createRef<HTMLDivElement>();
@@ -106,7 +108,7 @@ class DateLookup extends PureComponent<DateLookupProps, DateLookupState> {
106
108
  return null;
107
109
  }
108
110
 
109
- componentDidUpdate(previousProps: DateLookupProps) {
111
+ componentDidUpdate(previousProps: DateLookupPropsWithInputAttributes) {
110
112
  if (this.props.value?.getTime() !== previousProps.value?.getTime() && this.state.open) {
111
113
  this.focusOn('.active');
112
114
  }
@@ -350,6 +352,9 @@ class DateLookup extends PureComponent<DateLookupProps, DateLookupState> {
350
352
 
351
353
  export const DateLookupWithoutInputAttributes = DateLookup;
352
354
 
353
- export default withInputAttributes(DateLookup as React.ComponentType<DateLookupProps>, {
354
- nonLabelable: true,
355
- });
355
+ export default withInputAttributes(
356
+ DateLookup as React.ComponentType<DateLookupPropsWithInputAttributes>,
357
+ {
358
+ nonLabelable: true,
359
+ },
360
+ );
@@ -1,6 +1,6 @@
1
- import { useId } from '@radix-ui/react-id';
2
1
  import classNames from 'classnames';
3
2
  import PropTypes from 'prop-types';
3
+ import { useId } from 'react';
4
4
 
5
5
  import { Position, Typography } from '../common';
6
6
  import { CloseButton } from '../common/closeButton';
@@ -56,12 +56,12 @@ Drawer.propTypes = {
56
56
  footerContent: PropTypes.node,
57
57
  /** The content to appear in the drawer header. */
58
58
  headerTitle: PropTypes.node,
59
- /** The action to perform on close click. */
60
- onClose: PropTypes.func,
61
59
  /** The status of Drawer either open or not. */
62
60
  open: PropTypes.bool,
63
61
  /** The placement of Drawer on the screen either left or right. On mobile it will default to bottom. */
64
62
  position: PropTypes.oneOf(['left', 'right', 'bottom']),
63
+ /** The action to perform on close click. */
64
+ onClose: PropTypes.func,
65
65
  };
66
66
 
67
67
  Drawer.defaultProps = {
@@ -1,5 +1,5 @@
1
- import { useId } from '@radix-ui/react-id';
2
1
  import classNames from 'classnames';
2
+ import { useId } from 'react';
3
3
 
4
4
  import { Sentiment } from '../common';
5
5
  import InlineAlert from '../inlineAlert/InlineAlert';
@@ -27,10 +27,10 @@ export const Field = ({ id, label, hint, error, className, children }: FieldProp
27
27
 
28
28
  const labelId = useId();
29
29
 
30
- const fallbackInputId = useId(); // TODO: Use `React.useId()` when react>=18
30
+ const fallbackInputId = useId();
31
31
  const inputId = id !== null ? id ?? fallbackInputId : undefined;
32
32
 
33
- const descriptionId = useId(); // TODO: Use `React.useId()` when react>=18
33
+ const descriptionId = useId();
34
34
 
35
35
  return (
36
36
  <FieldLabelIdContextProvider value={labelId}>
package/src/index.ts CHANGED
@@ -6,7 +6,6 @@ export type { ActionOptionProps } from './actionOption';
6
6
  export type { AlertAction, AlertProps, AlertType } from './alert';
7
7
  export type { AvatarProps } from './avatar';
8
8
  export type { BadgeProps } from './badge';
9
- export type { CarouselProps } from './carousel';
10
9
  export type { CircularButtonProps } from './circularButton';
11
10
  export type {
12
11
  BodyTypes,
@@ -53,6 +52,7 @@ export type {
53
52
  export type { NavigationOptionListProps } from './navigationOptionsList';
54
53
  export type { PhoneNumberInputProps } from './phoneNumberInput/PhoneNumberInput';
55
54
  export type { PopoverProps } from './popover';
55
+ export type { ProcessIndicatorProps } from './processIndicator';
56
56
  export type { ProgressProps } from './progress';
57
57
  export type { ProgressBarProps } from './progressBar';
58
58
  export type { DirectionProviderProps, LanguageProviderProps, ProviderProps } from './provider';
@@ -85,7 +85,6 @@ export { default as AvatarWrapper } from './avatarWrapper';
85
85
  export { default as Badge } from './badge';
86
86
  export { default as Body } from './body';
87
87
  export { default as Button } from './button';
88
- export { default as Carousel } from './carousel';
89
88
  export { default as Card } from './card';
90
89
  export { default as Checkbox } from './checkbox';
91
90
  export { default as CheckboxButton } from './checkboxButton';
@@ -106,8 +105,8 @@ export { default as Display } from './display';
106
105
  export { default as Drawer } from './drawer';
107
106
  export { default as DropFade } from './dropFade';
108
107
  export { default as Emphasis } from './emphasis';
109
- export { default as FlowNavigation } from './flowNavigation/FlowNavigation';
110
108
  export { Field } from './field/Field';
109
+ export { default as FlowNavigation } from './flowNavigation/FlowNavigation';
111
110
  export { default as Header } from './header';
112
111
  export { default as Image } from './image';
113
112
  export { default as Info } from './info';
@@ -141,7 +140,7 @@ export { default as Popover } from './popover';
141
140
  export { default as ProcessIndicator } from './processIndicator';
142
141
  export { default as Progress } from './progress';
143
142
  export { default as ProgressBar } from './progressBar';
144
- export { PromoCardGroup, default as PromoCard } from './promoCard';
143
+ export { default as PromoCard, PromoCardGroup } from './promoCard';
145
144
  export { DirectionProvider, LanguageProvider, default as Provider } from './provider';
146
145
  export { default as Radio } from './radio';
147
146
  export { default as RadioGroup } from './radioGroup';
@@ -1,7 +1,8 @@
1
1
  import { Input, type InputProps } from '../inputs/Input';
2
2
  import WithDisplayFormat, { type WithDisplayFormatProps } from '../withDisplayFormat';
3
3
 
4
- export interface InputWithDisplayFormatProps extends Omit<WithDisplayFormatProps, 'render'> {}
4
+ export interface InputWithDisplayFormatProps
5
+ extends Omit<WithDisplayFormatProps<InputProps>, 'render'> {}
5
6
 
6
7
  const InputWithDisplayFormat = (props: InputWithDisplayFormatProps) => (
7
8
  <WithDisplayFormat<InputProps> {...props} render={(renderProps) => <Input {...renderProps} />} />
@@ -1,5 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
- import { expect, fn, type Mock, screen, userEvent, within } from '@storybook/test';
2
+ import { expect, fn, type Mock, screen, userEvent, waitFor, within } from '@storybook/test';
3
3
  import { Calendar, ChevronDown } from '@transferwise/icons';
4
4
  import { Flag } from '@wise/art';
5
5
  import classNames from 'classnames';
@@ -197,6 +197,7 @@ export const Currencies: Story<Currency> = {
197
197
 
198
198
  const input = screen.getByRole('searchbox');
199
199
 
200
+ await userEvent.click(input); // TODO: Remove
200
201
  await userEvent.type(input, 'huf');
201
202
  await expect(
202
203
  within(screen.getByRole('listbox')).queryByRole('option'),
@@ -1,9 +1,17 @@
1
1
  import { Listbox as ListboxBase } from '@headlessui/react';
2
- import { useId } from '@radix-ui/react-id';
3
2
  import { Check, ChevronDown, Cross, CrossCircle } from '@transferwise/icons';
4
3
  import classNames from 'classnames';
5
4
  import mergeProps from 'merge-props';
6
- import { createContext, forwardRef, useContext, useEffect, useMemo, useRef, useState } from 'react';
5
+ import {
6
+ createContext,
7
+ forwardRef,
8
+ useContext,
9
+ useEffect,
10
+ useId,
11
+ useMemo,
12
+ useRef,
13
+ useState,
14
+ } from 'react';
7
15
  import { useIntl } from 'react-intl';
8
16
 
9
17
  import { useEffectEvent } from '../common/hooks/useEffectEvent';
@@ -31,12 +31,12 @@ export interface WithInputAttributesProps {
31
31
  inputAttributes: ReturnType<typeof useInputAttributes>;
32
32
  }
33
33
 
34
- export function withInputAttributes<T>(
35
- Component: React.ComponentType<T & Partial<WithInputAttributesProps>>,
34
+ export function withInputAttributes<T extends Partial<WithInputAttributesProps>>(
35
+ Component: React.ComponentType<T>,
36
36
  args?: UseInputAttributesArgs,
37
37
  ) {
38
- function ComponentWithInputAttributes(props: T) {
39
- return <Component inputAttributes={useInputAttributes(args)} {...props} />;
38
+ function ComponentWithInputAttributes(props: Omit<T, keyof WithInputAttributesProps>) {
39
+ return <Component inputAttributes={useInputAttributes(args)} {...(props as T)} />;
40
40
  }
41
41
 
42
42
  ComponentWithInputAttributes.displayName = `withInputAttributes(${Component.displayName || Component.name || 'Component'})`;