@transferwise/components 46.92.0 → 46.93.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 (66) hide show
  1. package/build/actionOption/ActionOption.js +2 -0
  2. package/build/actionOption/ActionOption.js.map +1 -1
  3. package/build/actionOption/ActionOption.mjs +2 -0
  4. package/build/actionOption/ActionOption.mjs.map +1 -1
  5. package/build/common/Option/Option.js +9 -4
  6. package/build/common/Option/Option.js.map +1 -1
  7. package/build/common/Option/Option.mjs +10 -5
  8. package/build/common/Option/Option.mjs.map +1 -1
  9. package/build/dateLookup/dateTrigger/DateTrigger.js +11 -6
  10. package/build/dateLookup/dateTrigger/DateTrigger.js.map +1 -1
  11. package/build/dateLookup/dateTrigger/DateTrigger.mjs +11 -6
  12. package/build/dateLookup/dateTrigger/DateTrigger.mjs.map +1 -1
  13. package/build/definitionList/DefinitionList.js +5 -3
  14. package/build/definitionList/DefinitionList.js.map +1 -1
  15. package/build/definitionList/DefinitionList.mjs +5 -3
  16. package/build/definitionList/DefinitionList.mjs.map +1 -1
  17. package/build/main.css +23 -32
  18. package/build/snackbar/Snackbar.js +4 -2
  19. package/build/snackbar/Snackbar.js.map +1 -1
  20. package/build/snackbar/Snackbar.mjs +4 -2
  21. package/build/snackbar/Snackbar.mjs.map +1 -1
  22. package/build/styles/common/Option/Option.css +22 -0
  23. package/build/styles/dateLookup/dateTrigger/DateTrigger.css +1 -32
  24. package/build/styles/main.css +23 -32
  25. package/build/types/actionOption/ActionOption.d.ts +2 -1
  26. package/build/types/actionOption/ActionOption.d.ts.map +1 -1
  27. package/build/types/common/Option/Option.d.ts +1 -0
  28. package/build/types/common/Option/Option.d.ts.map +1 -1
  29. package/build/types/dateLookup/dateTrigger/DateTrigger.d.ts.map +1 -1
  30. package/build/types/definitionList/DefinitionList.d.ts.map +1 -1
  31. package/package.json +1 -1
  32. package/src/actionOption/ActionOption.story.tsx +2 -0
  33. package/src/actionOption/ActionOption.tsx +3 -0
  34. package/src/common/Option/Option.css +22 -0
  35. package/src/common/Option/Option.less +21 -0
  36. package/src/common/Option/Option.spec.tsx +21 -0
  37. package/src/common/Option/Option.tsx +7 -1
  38. package/src/dateLookup/DateLookup.spec.tsx +445 -0
  39. package/src/dateLookup/dateTrigger/DateTrigger.css +1 -32
  40. package/src/dateLookup/dateTrigger/DateTrigger.less +4 -28
  41. package/src/dateLookup/dateTrigger/DateTrigger.tsx +9 -5
  42. package/src/definitionList/DefinitionList.tsx +3 -3
  43. package/src/inputs/InputGroup.story.tsx +5 -3
  44. package/src/listItem/ListItem.spec.tsx +10 -2
  45. package/src/listItem/ListItem.story.tsx +11 -3
  46. package/src/main.css +23 -32
  47. package/src/snackbar/Snackbar.tsx +3 -3
  48. package/src/withNextPortal/withNextPortal.spec.tsx +24 -0
  49. package/src/common/Option/Option.spec.js +0 -129
  50. package/src/dateLookup/DateLookup.proptypes.spec.js +0 -28
  51. package/src/dateLookup/DateLookup.rtl.spec.tsx +0 -199
  52. package/src/dateLookup/DateLookup.state.spec.js +0 -76
  53. package/src/dateLookup/DateLookup.testingLibrary.spec.js +0 -256
  54. package/src/dateLookup/DateLookup.view.spec.js +0 -151
  55. package/src/dateLookup/dateHeader/DateHeader.spec.js +0 -95
  56. package/src/dateLookup/dateTrigger/DateTrigger.spec.js +0 -123
  57. package/src/dateLookup/dayCalendar/DayCalendar.spec.js +0 -122
  58. package/src/dateLookup/dayCalendar/table/DayCalendarTable.spec.js +0 -147
  59. package/src/dateLookup/monthCalendar/MonthCalendar.spec.js +0 -105
  60. package/src/dateLookup/monthCalendar/table/MonthCalendarTable.spec.js +0 -120
  61. package/src/dateLookup/tableLink/TableLink.spec.js +0 -109
  62. package/src/dateLookup/yearCalendar/YearCalendar.spec.js +0 -88
  63. package/src/dateLookup/yearCalendar/table/YearCalendarTable.spec.js +0 -121
  64. package/src/modal/Modal.spec.js +0 -197
  65. package/src/withNextPortal/withNextPortal.spec.js +0 -22
  66. /package/src/modal/{Modal.rtl.spec.tsx → Modal.spec.tsx} +0 -0
@@ -0,0 +1,445 @@
1
+ import { Field } from '../field/Field';
2
+ import {
3
+ mockMatchMedia,
4
+ mockResizeObserver,
5
+ render,
6
+ RenderResult,
7
+ screen,
8
+ userEvent,
9
+ } from '../test-utils';
10
+ import DateLookup, { DateLookupProps } from './DateLookup';
11
+
12
+ import { act } from 'react';
13
+
14
+ const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTimeAsync });
15
+
16
+ mockMatchMedia();
17
+ mockResizeObserver();
18
+
19
+ const initialValue = new Date(2000, 0, 1);
20
+ const labelProp = 'label';
21
+
22
+ describe('DateLookup', () => {
23
+ beforeEach(() => {
24
+ jest.useFakeTimers();
25
+ });
26
+
27
+ afterEach(async () => {
28
+ await jest.runOnlyPendingTimersAsync();
29
+ jest.useRealTimers();
30
+ jest.clearAllMocks();
31
+ });
32
+
33
+ it('supports `Field` for labeling', () => {
34
+ render(
35
+ <Field label="Date of birth">
36
+ <DateLookup value={initialValue} onChange={() => {}} />
37
+ </Field>,
38
+ );
39
+ const button = screen.getByRole('button', { name: /^Date of birth/ });
40
+
41
+ expect(button).toBeInTheDocument();
42
+ expect(button).toHaveAttribute('aria-haspopup');
43
+ });
44
+
45
+ it.each([' ', '{Enter}', '{ArrowDown}', '{ArrowUp}', '{ArrowRight}', '{ArrowLeft}'])(
46
+ "opens with '%s' and closes with '{Escape}'",
47
+ async (text) => {
48
+ render(<DateLookup value={initialValue} onChange={() => {}} />);
49
+
50
+ await user.tab();
51
+ await user.keyboard(text);
52
+
53
+ expect(screen.getByRole('button', { name: /next/iu })).toBeInTheDocument();
54
+
55
+ await user.keyboard('{Escape}');
56
+ await act(async () => {
57
+ await jest.runOnlyPendingTimersAsync();
58
+ });
59
+
60
+ expect(screen.queryByRole('button', { name: /next/iu })).not.toBeInTheDocument();
61
+ },
62
+ );
63
+
64
+ const setupAndOpenWithMouse = async (props: Partial<DateLookupProps> = {}) => {
65
+ const view = render(<DateLookup value={initialValue} onChange={() => {}} {...props} />);
66
+
67
+ await user.click(screen.getByRole('button'));
68
+ await act(async () => {
69
+ await jest.runOnlyPendingTimersAsync();
70
+ });
71
+
72
+ return view;
73
+ };
74
+
75
+ it('opens and closes with mouse', async () => {
76
+ await setupAndOpenWithMouse();
77
+
78
+ expect(screen.getByRole('button', { name: /next/iu })).toBeInTheDocument();
79
+
80
+ const dimmerElement = screen.getByRole('dialog').parentElement?.parentElement;
81
+ if (dimmerElement != null) {
82
+ await user.click(dimmerElement);
83
+ }
84
+ await act(async () => {
85
+ await jest.runOnlyPendingTimersAsync();
86
+ });
87
+
88
+ expect(screen.queryByRole('button', { name: /next/iu })).not.toBeInTheDocument();
89
+ });
90
+
91
+ describe('in day view', () => {
92
+ it.each([
93
+ ['{ArrowLeft}', -1],
94
+ ['{ArrowRight}', +1],
95
+ ['{ArrowUp}', -7],
96
+ ['{ArrowDown}', +7],
97
+ ])("handles '%s' to step %d day(s)", async (text, step) => {
98
+ const handleChange = jest.fn();
99
+ await setupAndOpenWithMouse({ onChange: handleChange });
100
+
101
+ expect(handleChange).not.toHaveBeenCalled();
102
+
103
+ await user.keyboard(text);
104
+
105
+ const value = new Date(initialValue);
106
+ value.setDate(initialValue.getDate() + step);
107
+ expect(handleChange).toHaveBeenCalledWith(value);
108
+
109
+ await user.keyboard('{Escape}');
110
+ await act(async () => {
111
+ await jest.runOnlyPendingTimersAsync();
112
+ });
113
+
114
+ expect(handleChange).toHaveBeenCalledWith(initialValue);
115
+ });
116
+ });
117
+
118
+ describe('in year view', () => {
119
+ it.each([
120
+ ['{ArrowLeft}', -1],
121
+ ['{ArrowRight}', +1],
122
+ ['{ArrowUp}', -4],
123
+ ['{ArrowDown}', +4],
124
+ ])("handles '%s' to step %d year(s)", async (text, step) => {
125
+ const handleChange = jest.fn();
126
+ await setupAndOpenWithMouse({ onChange: handleChange });
127
+
128
+ await user.click(screen.getByRole('button', { name: /year view/iu }));
129
+ await act(async () => {
130
+ await jest.runOnlyPendingTimersAsync();
131
+ });
132
+
133
+ expect(handleChange).not.toHaveBeenCalled();
134
+
135
+ await user.keyboard(text);
136
+
137
+ const value = new Date(initialValue);
138
+ value.setFullYear(initialValue.getFullYear() + step);
139
+ expect(handleChange).toHaveBeenCalledWith(value);
140
+
141
+ await user.keyboard('{Escape}');
142
+ await act(async () => {
143
+ await jest.runOnlyPendingTimersAsync();
144
+ });
145
+
146
+ expect(handleChange).toHaveBeenCalledWith(initialValue);
147
+ });
148
+ });
149
+
150
+ describe('in month view', () => {
151
+ it.each([
152
+ ['{ArrowLeft}', -1],
153
+ ['{ArrowRight}', +1],
154
+ ['{ArrowUp}', -4],
155
+ ['{ArrowDown}', +4],
156
+ ])("handles '%s' to step %d month(s)", async (text, step) => {
157
+ const handleChange = jest.fn();
158
+ await setupAndOpenWithMouse({ onChange: handleChange });
159
+
160
+ await user.click(screen.getByRole('button', { name: /year view/iu }));
161
+ await act(async () => {
162
+ await jest.runOnlyPendingTimersAsync();
163
+ });
164
+ await user.keyboard(' ');
165
+ await act(async () => {
166
+ await jest.runOnlyPendingTimersAsync();
167
+ });
168
+
169
+ expect(handleChange).not.toHaveBeenCalled();
170
+
171
+ await user.keyboard(text);
172
+
173
+ const value = new Date(initialValue);
174
+ value.setMonth(initialValue.getMonth() + step);
175
+ expect(handleChange).toHaveBeenCalledWith(value);
176
+
177
+ await user.keyboard('{Escape}');
178
+ await act(async () => {
179
+ await jest.runOnlyPendingTimersAsync();
180
+ });
181
+
182
+ expect(handleChange).toHaveBeenCalledWith(initialValue);
183
+ });
184
+ });
185
+
186
+ it('limits min value', async () => {
187
+ const min = new Date(initialValue);
188
+ min.setDate(min.getDate() - 1);
189
+ const handleChange = jest.fn();
190
+ await setupAndOpenWithMouse({ min, onChange: handleChange });
191
+
192
+ await user.keyboard('{ArrowLeft}{ArrowLeft}');
193
+
194
+ expect(handleChange).toHaveBeenCalledWith(min);
195
+ });
196
+
197
+ it('limits max value', async () => {
198
+ const max = new Date(initialValue);
199
+ max.setDate(max.getDate() + 1);
200
+ const handleChange = jest.fn();
201
+ await setupAndOpenWithMouse({ max, onChange: handleChange });
202
+
203
+ await user.keyboard('{ArrowRight}{ArrowRight}');
204
+
205
+ expect(handleChange).toHaveBeenCalledWith(max);
206
+ });
207
+ });
208
+
209
+ describe('DateLookup propTypes', () => {
210
+ describe('when the value prop is set to null', () => {
211
+ it('renders without prop type warnings in the console', () => {
212
+ const consoleSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
213
+
214
+ render(<DateLookup value={null} onChange={jest.fn()} />);
215
+
216
+ // eslint-disable-next-line no-console
217
+ expect(console.error).not.toHaveBeenCalledWith(
218
+ expect.stringContaining('Warning: Failed %s type'),
219
+ 'prop',
220
+ 'The prop `value` is marked as required in `DateLookup`, but its value is `null`.',
221
+ expect.anything(),
222
+ );
223
+
224
+ consoleSpy.mockRestore();
225
+ });
226
+ });
227
+ });
228
+
229
+ describe('DateLookup (events)', () => {
230
+ const date = new Date(2018, 11, 27);
231
+ const min = new Date(2018, 11, 26);
232
+ const max = new Date(2018, 11, 28);
233
+
234
+ describe('when not clearable', () => {
235
+ let handleChange: jest.Mock;
236
+
237
+ const setup = async (overrides = {}) => {
238
+ handleChange = jest.fn();
239
+
240
+ return render(
241
+ <>
242
+ {/* eslint-disable-next-line jsx-a11y/label-has-associated-control */}
243
+ <label id="prioritized-label">Prioritized label</label>
244
+ <DateLookup
245
+ value={date}
246
+ min={min}
247
+ max={max}
248
+ size="lg"
249
+ placeholder="Select date"
250
+ label={labelProp}
251
+ aria-labelledby="prioritized-label"
252
+ disabled={false}
253
+ clearable={false}
254
+ onChange={handleChange}
255
+ {...overrides}
256
+ />
257
+ </>,
258
+ );
259
+ };
260
+
261
+ it('switches to years', async () => {
262
+ const view = await setup();
263
+ await openDateLookup();
264
+ await clickDateButton();
265
+
266
+ expect(getActiveYearButton(view)).toHaveFocus();
267
+
268
+ await closeDateLookup(view);
269
+ });
270
+
271
+ it('has aria-label for 20 years', async () => {
272
+ const view = await setup();
273
+ await openDateLookup();
274
+ await clickDateButton();
275
+
276
+ expect(getButtonByAriaLabel('next 20 years')).toBeInTheDocument();
277
+ expect(getButtonByAriaLabel('previous 20 years')).toBeInTheDocument();
278
+
279
+ await closeDateLookup(view);
280
+ });
281
+
282
+ it('switches to months', async () => {
283
+ const view = await setup();
284
+ await openDateLookup();
285
+ await clickDateButton();
286
+ await userEvent.click(getActiveYearButton(view));
287
+
288
+ expect(getActiveMonthButton(view)).toHaveFocus();
289
+
290
+ await closeDateLookup(view);
291
+ });
292
+
293
+ it('has aria label for year', async () => {
294
+ const view = await setup();
295
+ await openDateLookup();
296
+ await clickDateButton();
297
+ await userEvent.click(getActiveYearButton(view));
298
+
299
+ expect(getButtonByAriaLabel('next year')).toBeInTheDocument();
300
+ expect(getButtonByAriaLabel('previous year')).toBeInTheDocument();
301
+
302
+ await closeDateLookup(view);
303
+ });
304
+
305
+ it('switches to days', async () => {
306
+ const view = await setup();
307
+ await openDateLookup();
308
+ await clickDateButton();
309
+ await userEvent.click(getActiveYearButton(view));
310
+ await userEvent.click(getActiveMonthButton(view));
311
+
312
+ expect(getActiveDayButton(view)).toHaveFocus();
313
+
314
+ await closeDateLookup(view);
315
+ });
316
+
317
+ it('has aria label for month', async () => {
318
+ const view = await setup();
319
+ await openDateLookup();
320
+ await clickDateButton();
321
+ await userEvent.click(getActiveYearButton(view));
322
+ await userEvent.click(getActiveMonthButton(view));
323
+
324
+ expect(getButtonByAriaLabel('next month')).toBeInTheDocument();
325
+ expect(getButtonByAriaLabel('previous month')).toBeInTheDocument();
326
+
327
+ await closeDateLookup(view);
328
+ });
329
+
330
+ it('has aria label on selected date', async () => {
331
+ const view = await setup();
332
+ await openDateLookup();
333
+ const d = new Date(2018, 11, 28);
334
+ const newDay = screen.getByText(d.getDate().toString());
335
+ await userEvent.click(newDay);
336
+ await openDateLookup();
337
+ expect(screen.getByRole('button', { name: /selected day/i })).toBeInTheDocument();
338
+
339
+ await closeDateLookup(view);
340
+ });
341
+
342
+ it('supports custom `aria-labelledby` attribute', async () => {
343
+ const view = await setup();
344
+ expect(screen.getByRole('button', { name: /^Prioritized label/ })).toBeInTheDocument();
345
+ await closeDateLookup(view);
346
+ });
347
+
348
+ it('reads our the HTML label as well as the input prefix and the value', async () => {
349
+ const view = await setup();
350
+ expect(
351
+ screen.getByRole('button', { name: 'Prioritized label label 27 December 2018' }),
352
+ ).toBeInTheDocument();
353
+ await closeDateLookup(view);
354
+ });
355
+
356
+ it('reads our the HTML label as well as the input prefix and the placeholder', async () => {
357
+ const view = await setup({ value: undefined });
358
+ expect(
359
+ screen.getByRole('button', { name: 'Prioritized label label Select date' }),
360
+ ).toBeInTheDocument();
361
+ await closeDateLookup(view);
362
+ });
363
+ });
364
+
365
+ describe('when is clearable', () => {
366
+ const props: DateLookupProps = {
367
+ value: date,
368
+ onChange: jest.fn(),
369
+ clearable: true,
370
+ label: labelProp,
371
+ };
372
+
373
+ it(`doesn't show clear button if disable is true`, async () => {
374
+ const view = render(<DateLookup {...props} />);
375
+ expect(getClearButton(view)).toBeInTheDocument();
376
+
377
+ view.rerender(<DateLookup {...props} disabled />);
378
+
379
+ expect(getClearButton(view)).not.toBeInTheDocument();
380
+ });
381
+
382
+ it('when user clicks on clear the focus returns to btn', async () => {
383
+ const view = render(<DateLookup {...props} />);
384
+ await clickClearButton(view);
385
+ expect(getOpenButton(labelProp)).toHaveFocus();
386
+ });
387
+
388
+ it('onChange gets called with null when reset button is clicked', async () => {
389
+ const view = render(<DateLookup {...props} />);
390
+ await clickClearButton(view);
391
+ expect(props.onChange).toHaveBeenCalledWith(null);
392
+ });
393
+ });
394
+
395
+ const getClearButton = (view: RenderResult) => {
396
+ return view.container.querySelector('.clear-btn');
397
+ };
398
+ const getOpenButton = (label: DateLookupProps['label']) => {
399
+ return screen.getByRole('button', {
400
+ name: new RegExp(String(label), 'i'),
401
+ expanded: false,
402
+ });
403
+ };
404
+
405
+ const getDateButton = () => {
406
+ return screen.getByRole('button', {
407
+ name: /Go to 20 year view/i,
408
+ });
409
+ };
410
+
411
+ const openDateLookup = async () => userEvent.click(getOpenButton(labelProp));
412
+
413
+ const clickDateButton = async () => userEvent.click(getDateButton());
414
+
415
+ // Close dateLookup and removes events attached to documents.
416
+ const closeDateLookup = async (view: RenderResult) => userEvent.click(view.container);
417
+
418
+ // @ts-expect-error getClearButton returns node
419
+ const clickClearButton = async (view: RenderResult) => userEvent.click(getClearButton(view));
420
+
421
+ const getActiveYearButton = (view: RenderResult) => {
422
+ return screen.getByRole('button', {
423
+ name: /selected year/i,
424
+ pressed: true,
425
+ });
426
+ };
427
+
428
+ const getActiveMonthButton = (view: RenderResult) => {
429
+ return screen.getByRole('button', {
430
+ name: /selected month/i,
431
+ pressed: true,
432
+ });
433
+ };
434
+
435
+ const getActiveDayButton = (view: RenderResult) => {
436
+ return screen.getByRole('button', {
437
+ name: /selected day/i,
438
+ pressed: true,
439
+ });
440
+ };
441
+
442
+ const getButtonByAriaLabel = (ariaLabel: string) => {
443
+ return screen.getByRole('button', { name: ariaLabel });
444
+ };
445
+ });
@@ -9,52 +9,21 @@
9
9
  padding-left: var(--size-16);
10
10
  }
11
11
  .clear-btn {
12
- transition: color 0.15s ease-in-out;
13
- color: #c9cbce;
14
- color: var(--color-interactive-secondary);
15
12
  position: absolute;
16
- top: 16px;
17
- top: var(--size-16);
18
- right: 16px;
19
- right: var(--size-16);
20
- }
21
- [dir="rtl"] .clear-btn {
22
- left: 16px;
23
- left: var(--size-16);
24
- right: auto;
25
- right: initial;
26
- }
27
- .np-theme-personal .clear-btn {
28
13
  top: 8px;
29
14
  top: var(--size-8);
30
15
  right: 8px;
31
16
  right: var(--size-8);
32
17
  }
33
- [dir="rtl"] .np-theme-personal .clear-btn {
18
+ [dir="rtl"] .clear-btn {
34
19
  left: 8px;
35
20
  left: var(--size-8);
36
21
  right: auto;
37
22
  right: initial;
38
23
  }
39
24
  .clear-btn--sm {
40
- top: 8px;
41
- top: var(--size-8);
42
- }
43
- .np-theme-personal .clear-btn--sm {
44
25
  top: 0;
45
26
  }
46
27
  .clear-btn--lg {
47
- top: 28px;
48
- }
49
- .np-theme-personal .clear-btn--lg {
50
28
  top: 20px;
51
29
  }
52
- .clear-btn:not(.disabled):not(:disabled):hover,
53
- .clear-btn:not(.disabled):not(:disabled):focus {
54
- color: #d03238;
55
- color: var(--color-interactive-negative-hover);
56
- }
57
- .clear-btn:not(.disabled):not(:disabled):active {
58
- color: #bf1e2c;
59
- color: var(--color-interactive-negative-active);
60
- }
@@ -13,39 +13,15 @@
13
13
  }
14
14
 
15
15
  .clear-btn {
16
- transition: color 0.15s ease-in-out;
17
- color: var(--color-interactive-secondary);
18
16
  position: absolute;
19
- top: var(--size-16);
20
- .right(var(--size-16));
21
-
22
- .np-theme-personal & {
23
- top: var(--size-8);
24
- .right(var(--size-8));
25
- }
17
+ top: var(--size-8);
18
+ .right(var(--size-8));
26
19
 
27
20
  &--sm {
28
- top: var(--size-8);
29
-
30
- .np-theme-personal & {
31
- top: 0;
32
- }
21
+ top: 0;
33
22
  }
34
23
 
35
24
  &--lg {
36
- top: 28px;
37
-
38
- .np-theme-personal & {
39
- top: 20px;
40
- }
41
- }
42
-
43
- &:not(.disabled, :disabled):hover,
44
- &:not(.disabled, :disabled):focus {
45
- color: var(--color-interactive-negative-hover);
46
- }
47
-
48
- &:not(.disabled, :disabled):active {
49
- color: var(--color-interactive-negative-active);
25
+ top: 20px;
50
26
  }
51
27
  }
@@ -3,12 +3,13 @@ import { useIntl } from 'react-intl';
3
3
 
4
4
  import Chevron from '../../chevron';
5
5
  import { Size, Position, SizeSmall, SizeMedium, SizeLarge, Typography } from '../../common';
6
- import { CloseButton } from '../../common/closeButton/CloseButton';
7
6
 
8
7
  import messages from './DateTrigger.messages';
9
8
  import { useContext, useId } from 'react';
10
9
  import { OverlayIdContext } from '../../provider/overlay/OverlayIdProvider';
11
10
  import Body from '../../body';
11
+ import IconButton from '../../iconButton';
12
+ import { Cross } from '@transferwise/icons';
12
13
 
13
14
  interface DateTriggerProps {
14
15
  ariaLabelledBy?: string;
@@ -78,16 +79,19 @@ const DateTrigger: React.FC<DateTriggerProps> = ({
78
79
  <>
79
80
  <div className="clearfix" />
80
81
  <span className="input-group-addon">
81
- <CloseButton
82
+ <IconButton
83
+ size={32}
84
+ priority="minimal"
82
85
  className={`clear-btn clear-btn--${size}`}
83
86
  aria-label={`${formatMessage(messages.ariaLabel)} ${label}`}
84
- size={Size.SMALL}
85
- onClick={(event: React.MouseEvent<HTMLButtonElement>) => {
87
+ onClick={(event) => {
86
88
  event.stopPropagation();
87
89
  event.preventDefault();
88
90
  onClear();
89
91
  }}
90
- />
92
+ >
93
+ <Cross />
94
+ </IconButton>
91
95
  </span>
92
96
  </>
93
97
  ) : null}
@@ -1,7 +1,7 @@
1
1
  import { clsx } from 'clsx';
2
2
 
3
- import ActionButton from '../actionButton';
4
3
  import { Layout } from '../common';
4
+ import Button from '../button';
5
5
 
6
6
  export interface DefinitionListDefinition {
7
7
  action?: {
@@ -85,9 +85,9 @@ export default function DefinitionList({
85
85
  'tw-definition-list__action',
86
86
  )}
87
87
  >
88
- <ActionButton className="tw-definition-list__button" onClick={action.onClick}>
88
+ <Button as="button" size="sm" v2 onClick={action.onClick}>
89
89
  {action.label}
90
- </ActionButton>
90
+ </Button>
91
91
  </div>
92
92
  ) : null}
93
93
  </dd>
@@ -2,7 +2,7 @@ import type { Meta, StoryObj } from '@storybook/react';
2
2
  import { Search } from '@transferwise/icons';
3
3
  import { useRef, useState } from 'react';
4
4
 
5
- import ActionButton from '../actionButton';
5
+ import { Button } from '..';
6
6
  import { Field } from '../field/Field';
7
7
 
8
8
  import { Input } from './Input';
@@ -59,7 +59,9 @@ function InputGroupWithSuffix(args: NonNullable<Story['args']>) {
59
59
  {...args}
60
60
  addonEnd={{
61
61
  content: (
62
- <ActionButton
62
+ <Button
63
+ size="sm"
64
+ v2
63
65
  onClick={async () => {
64
66
  await navigator.clipboard.writeText(value);
65
67
  if (ref.current != null) {
@@ -69,7 +71,7 @@ function InputGroupWithSuffix(args: NonNullable<Story['args']>) {
69
71
  }}
70
72
  >
71
73
  Copy
72
- </ActionButton>
74
+ </Button>
73
75
  ),
74
76
  interactive: true,
75
77
  padding: 'sm',
@@ -1,4 +1,4 @@
1
- import ActionButton from '../actionButton/ActionButton';
1
+ import { Button } from '..';
2
2
  import { render, screen, within } from '../test-utils';
3
3
 
4
4
  import ListItem from '.';
@@ -17,7 +17,15 @@ describe('ListItem', () => {
17
17
 
18
18
  it('shows an action', async () => {
19
19
  render(
20
- <ListItem title="Account number" value="123" action={<ActionButton>Copy</ActionButton>} />,
20
+ <ListItem
21
+ title="Account number"
22
+ value="123"
23
+ action={
24
+ <Button v2 size="sm">
25
+ Copy
26
+ </Button>
27
+ }
28
+ />,
21
29
  );
22
30
 
23
31
  const listItem = await findListItem();
@@ -4,7 +4,7 @@ import { action } from '@storybook/addon-actions';
4
4
  import { Documents, FastFlag } from '@transferwise/icons';
5
5
  import { ComponentProps } from 'react';
6
6
 
7
- import ActionButton from '../actionButton/ActionButton';
7
+ import { Button } from '..';
8
8
  import AvatarView from '../avatarView';
9
9
  import Info from '../info';
10
10
  import Title from '../title/Title';
@@ -58,7 +58,11 @@ export const Variants = () => {
58
58
  title="Account holder"
59
59
  value="Sandra Pepper"
60
60
  media={<AvatarView profileName="Super Pepa" badge={{ icon: <FastFlag /> }} />}
61
- action={<ActionButton>Share details</ActionButton>}
61
+ action={
62
+ <Button v2 size="sm">
63
+ Share details
64
+ </Button>
65
+ }
62
66
  />
63
67
  </List>
64
68
  </div>
@@ -75,7 +79,11 @@ export const Variants = () => {
75
79
  <Template
76
80
  title="SWIFT/BIC"
77
81
  value="••• •••"
78
- action={<ActionButton onClick={() => action('clicked')}>Reveal</ActionButton>}
82
+ action={
83
+ <Button v2 size="sm" onClick={() => action('clicked')}>
84
+ Reveal
85
+ </Button>
86
+ }
79
87
  />
80
88
  </List>
81
89
  </div>