@transferwise/components 45.27.0 → 45.28.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.
@@ -1,8 +1,10 @@
1
- import { render } from '@testing-library/react';
2
- import userEvent from '@testing-library/user-event';
3
1
  import { shallow } from 'enzyme';
4
2
 
5
- import { Select, MoneyInput, Title, Input } from '..';
3
+ import { MoneyInput, Title, Input, SelectInput } from '..';
4
+ import { mockMatchMedia, mockResizeObserver } from '../test-utils';
5
+
6
+ mockMatchMedia();
7
+ mockResizeObserver();
6
8
 
7
9
  jest.mock('./currencyFormatting', () => ({
8
10
  parseAmount: jest.fn(),
@@ -83,7 +85,7 @@ describe('Money Input', () => {
83
85
  });
84
86
 
85
87
  function currencySelect() {
86
- return component.find(Select);
88
+ return component.find(SelectInput);
87
89
  }
88
90
 
89
91
  function fixedCurrencyDisplay() {
@@ -96,7 +98,11 @@ describe('Money Input', () => {
96
98
  }
97
99
 
98
100
  function displayedCurrencies() {
99
- return currencySelect().prop('options');
101
+ return currencySelect().prop('items');
102
+ }
103
+
104
+ function getFooter() {
105
+ return currencySelect().prop('renderFooter');
100
106
  }
101
107
 
102
108
  function amountInput() {
@@ -122,31 +128,86 @@ describe('Money Input', () => {
122
128
 
123
129
  it('renders a select with all the currencies as options', () => {
124
130
  expect(currencySelect()).toHaveLength(1);
125
- expect(displayedCurrencies()).toStrictEqual(props.currencies);
126
- });
127
-
128
- it('renders a Select component with expected id when id is provided', () => {
129
- let componentWithId = shallow(<MoneyInput id="mock-id" {...props} />).dive();
130
- const select = componentWithId.find('Select');
131
-
132
- expect(select.prop('id')).toBe('mock-id-select');
131
+ expect(displayedCurrencies()).toStrictEqual([
132
+ {
133
+ type: 'group',
134
+ label: 'Popular currencies',
135
+ options: [
136
+ {
137
+ type: 'option',
138
+ value: {
139
+ value: 'EUR',
140
+ label: 'EUR',
141
+ note: 'Euro',
142
+ currency: 'eur',
143
+ searchable: 'Spain, Germany, France, Austria, Estonia',
144
+ },
145
+ filterMatchers: ['EUR', 'EUR', 'Euro', 'Spain, Germany, France, Austria, Estonia'],
146
+ },
147
+ {
148
+ type: 'option',
149
+ value: {
150
+ value: 'USD',
151
+ label: 'USD',
152
+ note: 'United States dollar',
153
+ currency: 'usd',
154
+ searchable: 'Hong Kong, Saudi Arabia',
155
+ },
156
+ filterMatchers: ['USD', 'USD', 'United States dollar', 'Hong Kong, Saudi Arabia'],
157
+ },
158
+ {
159
+ type: 'option',
160
+ value: {
161
+ value: 'GBP',
162
+ label: 'GBP',
163
+ note: 'British pound',
164
+ currency: 'gbp',
165
+ searchable: 'England, Scotland, Wales',
166
+ },
167
+ filterMatchers: ['GBP', 'GBP', 'British pound', 'England, Scotland, Wales'],
168
+ },
169
+ ],
170
+ },
171
+ {
172
+ type: 'group',
173
+ label: 'Some other currencies',
174
+ options: [
175
+ {
176
+ type: 'option',
177
+ value: {
178
+ value: 'CAD',
179
+ label: 'CAD',
180
+ note: 'Canadian dollar',
181
+ currency: 'cad',
182
+ },
183
+ filterMatchers: ['CAD', 'CAD', 'Canadian dollar', undefined],
184
+ },
185
+ {
186
+ type: 'option',
187
+ value: {
188
+ value: 'AUD',
189
+ label: 'AUD',
190
+ note: 'Australian dollar',
191
+ currency: 'aud',
192
+ },
193
+ filterMatchers: ['AUD', 'AUD', 'Australian dollar', undefined],
194
+ },
195
+ ],
196
+ },
197
+ ]);
133
198
  });
134
199
 
135
200
  it('renders Select component with undefined id when id is not provided', () => {
136
- const select = component.find('Select');
201
+ const select = component.find('SelectInput');
137
202
 
138
203
  expect(select.prop('id')).toBeUndefined();
139
204
  });
140
205
 
141
206
  it('shows the currently active currency as active and hides its note', () => {
142
- expect(currencySelect().prop('selected')).toStrictEqual({
207
+ expect(currencySelect().prop('value')).toStrictEqual({
143
208
  value: 'EUR',
144
- label: (
145
- <Title as="span" type="title-subsection" className="tw-money-input__text">
146
- EUR
147
- </Title>
148
- ),
149
- note: null,
209
+ label: 'EUR',
210
+ note: 'Euro',
150
211
  currency: 'eur',
151
212
  searchable: 'Spain, Germany, France, Austria, Estonia',
152
213
  });
@@ -170,22 +231,7 @@ describe('Money Input', () => {
170
231
  });
171
232
  });
172
233
 
173
- it('configures the select visually correctly', () => {
174
- const options = currencySelect().props();
175
-
176
- expect(options.required).toBe(true);
177
- expect(options.dropdownWidth).toBe('lg');
178
- expect(options.inverse).toBe(true);
179
- });
180
-
181
234
  describe('when searching', () => {
182
- it('passes search value to currency select', () => {
183
- expect(currencySelect().prop('searchValue')).toBe('');
184
-
185
- searchCurrencies('EEK');
186
- expect(currencySelect().prop('searchValue')).toBe('EEK');
187
- });
188
-
189
235
  it('hides headers', () => {
190
236
  currencies = [
191
237
  { header: 'A currency' },
@@ -194,12 +240,43 @@ describe('Money Input', () => {
194
240
  { value: 'EUR', label: 'Euro' },
195
241
  ];
196
242
  component.setProps({ currencies });
197
- expect(displayedCurrencies()).toStrictEqual(currencies);
243
+ expect(displayedCurrencies()).toStrictEqual([
244
+ {
245
+ type: 'group',
246
+ label: 'A currency',
247
+ options: [
248
+ {
249
+ type: 'option',
250
+ value: { value: 'GBP', label: 'British pound' },
251
+ filterMatchers: ['GBP', 'British pound', undefined, undefined],
252
+ },
253
+ ],
254
+ },
255
+ {
256
+ type: 'group',
257
+ label: 'Another currency',
258
+ options: [
259
+ {
260
+ type: 'option',
261
+ value: { value: 'EUR', label: 'Euro' },
262
+ filterMatchers: ['EUR', 'Euro', undefined, undefined],
263
+ },
264
+ ],
265
+ },
266
+ ]);
198
267
 
199
268
  searchCurrencies('O');
200
269
  expect(displayedCurrencies()).toStrictEqual([
201
- { value: 'GBP', label: 'British pound' },
202
- { value: 'EUR', label: 'Euro' },
270
+ {
271
+ type: 'option',
272
+ value: { value: 'GBP', label: 'British pound' },
273
+ filterMatchers: ['GBP', 'British pound', undefined, undefined],
274
+ },
275
+ {
276
+ type: 'option',
277
+ value: { value: 'EUR', label: 'Euro' },
278
+ filterMatchers: ['EUR', 'Euro', undefined, undefined],
279
+ },
203
280
  ]);
204
281
  });
205
282
 
@@ -209,10 +286,27 @@ describe('Money Input', () => {
209
286
  { value: 'EUR', label: 'Euro' },
210
287
  ];
211
288
  component.setProps({ currencies });
212
- expect(displayedCurrencies()).toStrictEqual(currencies);
289
+ expect(displayedCurrencies()).toStrictEqual([
290
+ {
291
+ type: 'option',
292
+ value: { value: 'GBP', label: 'British pound' },
293
+ filterMatchers: ['GBP', 'British pound', undefined, undefined],
294
+ },
295
+ {
296
+ type: 'option',
297
+ value: { value: 'EUR', label: 'Euro' },
298
+ filterMatchers: ['EUR', 'Euro', undefined, undefined],
299
+ },
300
+ ]);
213
301
 
214
302
  searchCurrencies('P');
215
- expect(displayedCurrencies()).toStrictEqual([{ value: 'GBP', label: 'British pound' }]);
303
+ expect(displayedCurrencies()).toStrictEqual([
304
+ {
305
+ type: 'option',
306
+ value: { value: 'GBP', label: 'British pound' },
307
+ filterMatchers: ['GBP', 'British pound', undefined, undefined],
308
+ },
309
+ ]);
216
310
  });
217
311
 
218
312
  it('searches by note', () => {
@@ -221,10 +315,27 @@ describe('Money Input', () => {
221
315
  { value: 'EUR', note: 'Other money' },
222
316
  ];
223
317
  component.setProps({ currencies });
224
- expect(displayedCurrencies()).toStrictEqual(currencies);
318
+ expect(displayedCurrencies()).toStrictEqual([
319
+ {
320
+ type: 'option',
321
+ value: { value: 'GBP', note: 'Queen money' },
322
+ filterMatchers: ['GBP', undefined, 'Queen money', undefined],
323
+ },
324
+ {
325
+ type: 'option',
326
+ value: { value: 'EUR', note: 'Other money' },
327
+ filterMatchers: ['EUR', undefined, 'Other money', undefined],
328
+ },
329
+ ]);
225
330
 
226
331
  searchCurrencies('Other');
227
- expect(displayedCurrencies()).toStrictEqual([{ value: 'EUR', note: 'Other money' }]);
332
+ expect(displayedCurrencies()).toStrictEqual([
333
+ {
334
+ type: 'option',
335
+ value: { value: 'EUR', note: 'Other money' },
336
+ filterMatchers: ['EUR', undefined, 'Other money', undefined],
337
+ },
338
+ ]);
228
339
  });
229
340
 
230
341
  it('searches by searchable string', () => {
@@ -233,11 +344,26 @@ describe('Money Input', () => {
233
344
  { value: 'EUR', searchable: 'Europe' },
234
345
  ];
235
346
  component.setProps({ currencies });
236
- expect(displayedCurrencies()).toStrictEqual(currencies);
347
+ expect(displayedCurrencies()).toStrictEqual([
348
+ {
349
+ type: 'option',
350
+ value: { value: 'GBP', searchable: 'Great Britain, United Kingdom' },
351
+ filterMatchers: ['GBP', undefined, undefined, 'Great Britain, United Kingdom'],
352
+ },
353
+ {
354
+ type: 'option',
355
+ value: { value: 'EUR', searchable: 'Europe' },
356
+ filterMatchers: ['EUR', undefined, undefined, 'Europe'],
357
+ },
358
+ ]);
237
359
 
238
360
  searchCurrencies('Britain');
239
361
  expect(displayedCurrencies()).toStrictEqual([
240
- { value: 'GBP', searchable: 'Great Britain, United Kingdom' },
362
+ {
363
+ type: 'option',
364
+ value: { value: 'GBP', searchable: 'Great Britain, United Kingdom' },
365
+ filterMatchers: ['GBP', undefined, undefined, 'Great Britain, United Kingdom'],
366
+ },
241
367
  ]);
242
368
  });
243
369
 
@@ -246,51 +372,73 @@ describe('Money Input', () => {
246
372
  { value: 'GBP', searchable: 'Great Britain, United Kingdom' },
247
373
  { value: 'EUR', searchable: 'Europe' },
248
374
  ];
249
- const CUSTOM_ACTION = 'CUSTOM_ACTION';
250
375
  component.setProps({
251
376
  currencies,
252
377
  onCustomAction: jest.fn(),
253
378
  customActionLabel: 'I am a label',
254
379
  });
255
380
  expect(displayedCurrencies()).toStrictEqual([
256
- ...currencies,
257
- { value: CUSTOM_ACTION, label: 'I am a label' },
381
+ {
382
+ type: 'option',
383
+ value: { value: 'GBP', searchable: 'Great Britain, United Kingdom' },
384
+ filterMatchers: ['GBP', undefined, undefined, 'Great Britain, United Kingdom'],
385
+ },
386
+ {
387
+ type: 'option',
388
+ value: { value: 'EUR', searchable: 'Europe' },
389
+ filterMatchers: ['EUR', undefined, undefined, 'Europe'],
390
+ },
258
391
  ]);
259
392
 
260
393
  searchCurrencies('Britain');
261
394
  expect(displayedCurrencies()).toStrictEqual([
262
- { value: 'GBP', searchable: 'Great Britain, United Kingdom' },
263
- { value: CUSTOM_ACTION, label: 'I am a label' },
395
+ {
396
+ type: 'option',
397
+ value: { value: 'GBP', searchable: 'Great Britain, United Kingdom' },
398
+ filterMatchers: ['GBP', undefined, undefined, 'Great Britain, United Kingdom'],
399
+ },
264
400
  ]);
265
401
 
266
402
  searchCurrencies('Random search string');
267
- expect(displayedCurrencies()).toStrictEqual([
268
- { value: CUSTOM_ACTION, label: 'I am a label' },
269
- ]);
403
+ expect(displayedCurrencies()).toHaveLength(0);
404
+ const footerNode = shallow(getFooter()()).find('div');
405
+ expect(footerNode).not.toBeNull();
270
406
  });
271
407
 
272
408
  it('sorts labels to first', () => {
273
409
  searchCurrencies('au');
274
410
  expect(displayedCurrencies()).toStrictEqual([
275
411
  {
276
- value: 'AUD',
277
- label: 'AUD',
278
- note: 'Australian dollar',
279
- currency: 'aud',
412
+ type: 'option',
413
+ value: {
414
+ value: 'AUD',
415
+ label: 'AUD',
416
+ note: 'Australian dollar',
417
+ currency: 'aud',
418
+ },
419
+ filterMatchers: ['AUD', 'AUD', 'Australian dollar', undefined],
280
420
  },
281
421
  {
282
- value: 'EUR',
283
- label: 'EUR',
284
- note: 'Euro',
285
- currency: 'eur',
286
- searchable: 'Spain, Germany, France, Austria, Estonia',
422
+ type: 'option',
423
+ value: {
424
+ value: 'EUR',
425
+ label: 'EUR',
426
+ note: 'Euro',
427
+ currency: 'eur',
428
+ searchable: 'Spain, Germany, France, Austria, Estonia',
429
+ },
430
+ filterMatchers: ['EUR', 'EUR', 'Euro', 'Spain, Germany, France, Austria, Estonia'],
287
431
  },
288
432
  {
289
- value: 'USD',
290
- label: 'USD',
291
- note: 'United States dollar',
292
- currency: 'usd',
293
- searchable: 'Hong Kong, Saudi Arabia',
433
+ type: 'option',
434
+ value: {
435
+ value: 'USD',
436
+ label: 'USD',
437
+ note: 'United States dollar',
438
+ currency: 'usd',
439
+ searchable: 'Hong Kong, Saudi Arabia',
440
+ },
441
+ filterMatchers: ['USD', 'USD', 'United States dollar', 'Hong Kong, Saudi Arabia'],
294
442
  },
295
443
  ]);
296
444
  });
@@ -389,7 +537,6 @@ describe('Money Input', () => {
389
537
  expect(currencySelect()).toHaveLength(0);
390
538
  expect(fixedCurrencyDisplay()).toHaveLength(1);
391
539
  expect(component.find(Title).props().children).toBe('EEK');
392
- expect(component.find('.currency-flag').hasClass('currency-flag-eek')).toBe(true);
393
540
  });
394
541
 
395
542
  it('shows fixed currency view when no function is passed to onCurrencyChange prop', () => {
@@ -408,13 +555,11 @@ describe('Money Input', () => {
408
555
 
409
556
  ['md', 'lg'].forEach((size) => {
410
557
  component.setProps({ size });
411
- expect(component.find('.tw-money-input__keyline')).toHaveLength(1);
412
- expect(component.find('.currency-flag')).toHaveLength(1);
558
+ expect(component.find('.money-input-currency-flag')).toHaveLength(1);
413
559
  });
414
560
 
415
561
  component.setProps({ size: 'sm' });
416
- expect(component.find('.tw-money-input__keyline')).toHaveLength(0);
417
- expect(component.find('.currency-flag')).toHaveLength(0);
562
+ expect(component.find('.money-input-currency-flag')).toHaveLength(0);
418
563
  });
419
564
 
420
565
  it('amount input will be disabled when there is no onAmountChange prop', () => {
@@ -434,18 +579,24 @@ describe('Money Input', () => {
434
579
 
435
580
  it('uses the passed in search placeholder', () => {
436
581
  component.setProps({ searchPlaceholder: 'a placeholder' });
437
- expect(currencySelect().prop('searchPlaceholder')).toBe('a placeholder');
582
+ expect(currencySelect().prop('filterPlaceholder')).toBe('a placeholder');
438
583
  });
439
584
 
440
585
  it('clears the search value when selecting an option', () => {
586
+ const onSearchChange = jest.fn();
587
+ component.setProps({ onSearchChange });
441
588
  searchCurrencies('eur');
442
- expect(currencySelect().prop('options')).toHaveLength(1);
443
- expect(currencySelect().prop('searchValue')).toBe('eur');
589
+ expect(onSearchChange).toHaveBeenLastCalledWith({
590
+ searchQuery: 'eur',
591
+ filteredOptions: [props.currencies[1]],
592
+ });
444
593
 
445
594
  currencySelect().prop('onChange')(props.currencies[1]);
446
595
  component.update();
447
- expect(currencySelect().prop('options')).toHaveLength(7);
448
- expect(currencySelect().prop('searchValue')).toBe('');
596
+ expect(onSearchChange).toHaveBeenLastCalledWith({
597
+ searchQuery: '',
598
+ filteredOptions: [...props.currencies],
599
+ });
449
600
  });
450
601
 
451
602
  it('shows custom action last when onCustomAction prop is passed to MoneyInput', () => {
@@ -453,21 +604,25 @@ describe('Money Input', () => {
453
604
  { value: 'GBP', searchable: 'Great Britain, United Kingdom' },
454
605
  { value: 'EUR', searchable: 'Europe' },
455
606
  ];
607
+ const onCustomActionMock = jest.fn();
456
608
  component.setProps({
457
609
  currencies,
458
- onCustomAction: jest.fn(),
610
+ onCustomAction: onCustomActionMock,
459
611
  customActionLabel: 'Label boy',
460
612
  });
461
613
 
462
- expect(displayedCurrencies()).toStrictEqual([
463
- ...currencies,
464
- { value: 'CUSTOM_ACTION', label: 'Label boy' },
465
- ]);
614
+ const options = displayedCurrencies();
466
615
 
467
- expect(displayedCurrencies()[displayedCurrencies().length - 1]).toStrictEqual({
468
- value: 'CUSTOM_ACTION',
469
- label: 'Label boy',
470
- });
616
+ expect(options).toHaveLength(2);
617
+ expect(options[0].value).toStrictEqual(currencies[0]);
618
+ expect(options[1].value).toStrictEqual(currencies[1]);
619
+
620
+ const footerNode = shallow(getFooter()()).find('div');
621
+
622
+ expect(footerNode.prop('role')).toBe('button');
623
+ expect(onCustomActionMock).toHaveBeenCalledTimes(0);
624
+ footerNode.simulate('click');
625
+ expect(onCustomActionMock).toHaveBeenCalledTimes(1);
471
626
  });
472
627
 
473
628
  it('calls onCustomAction callback when custom action is selected', () => {
@@ -476,7 +631,9 @@ describe('Money Input', () => {
476
631
  expect(onCustomAction).not.toHaveBeenCalled();
477
632
  expect(props.onCurrencyChange).not.toHaveBeenCalled();
478
633
 
479
- currencySelect().prop('onChange')({ value: 'CUSTOM_ACTION', label: '' });
634
+ const footerNode = shallow(getFooter()()).find('div');
635
+ expect(onCustomAction).toHaveBeenCalledTimes(0);
636
+ footerNode.simulate('click');
480
637
  expect(onCustomAction).toHaveBeenCalledTimes(1);
481
638
  expect(props.onCurrencyChange).toHaveBeenCalledTimes(0);
482
639
  });
@@ -545,7 +702,8 @@ describe('Money Input', () => {
545
702
  filteredOptions: [getCurrencyByValue('EUR')],
546
703
  });
547
704
 
548
- currencySelect().prop('onChange')({ value: 'CUSTOM_ACTION' });
705
+ const footerNode = shallow(getFooter()()).find('div');
706
+ footerNode.simulate('click');
549
707
  expect(onCustomAction).toHaveBeenCalledTimes(1);
550
708
  expect(onSearchChange).toHaveBeenLastCalledWith({
551
709
  searchQuery: '',
@@ -554,33 +712,6 @@ describe('Money Input', () => {
554
712
  });
555
713
  });
556
714
 
557
- describe('when typing', () => {
558
- let rtlComponent;
559
- const { formatAmount } = jest.requireActual('./currencyFormatting');
560
- beforeAll(() => {
561
- numberFormatting.formatAmount = formatAmount;
562
- });
563
-
564
- beforeEach(() => {
565
- rtlComponent = render(<MoneyInput {...props} amount={null} />);
566
- jest.clearAllMocks();
567
- });
568
-
569
- it.each([
570
- ['asd', ''],
571
- ['1a2s3d', '123'],
572
- ['±!@#$^*_+?><', ''],
573
- ['1±!@#$^*,_+?><2', '1,2'],
574
- ['12,3', '12,3'],
575
- ['12.3', '12.3'],
576
- ])("ignores the letters when typed '%s' and shows '%s'", (testValue, expectedValue) => {
577
- const { container } = rtlComponent;
578
- const input = container.querySelector('input');
579
- userEvent.type(input, testValue);
580
- expect(input).toHaveValue(expectedValue);
581
- });
582
- });
583
-
584
715
  describe('when passed selectProps', () => {
585
716
  beforeEach(() => {
586
717
  component = shallow(
@@ -596,7 +727,7 @@ describe('Money Input', () => {
596
727
  });
597
728
 
598
729
  it('renders Select component with expected props', () => {
599
- const select = component.find('Select');
730
+ const select = component.find('SelectInput');
600
731
 
601
732
  expect(select.prop('buttonProps')).toStrictEqual({
602
733
  'aria-label': 'mock-button-label',
@@ -1,5 +1,9 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
2
  import { within, userEvent } from '@storybook/testing-library';
3
+ import { Lock } from '@transferwise/icons';
4
+ import React from 'react';
5
+
6
+ import Drawer from '../drawer';
3
7
 
4
8
  import MoneyInput from '.';
5
9
 
@@ -41,6 +45,41 @@ const exampleCurrency = {
41
45
  currency: 'gbp',
42
46
  searchable: 'England, Scotland, Wales',
43
47
  },
48
+ usd: {
49
+ value: 'USD',
50
+ label: 'USD',
51
+ note: 'United States dollar',
52
+ currency: 'usd',
53
+ searchable: 'Hong Kong, Saudi Arabia',
54
+ },
55
+ hkd: {
56
+ value: 'HKD',
57
+ label: 'HKD',
58
+ note: 'Hong Kong',
59
+ currency: 'hkd',
60
+ searchable: 'Hong Kong, Saudi Arabia',
61
+ },
62
+ aud: {
63
+ value: 'AUD',
64
+ label: 'AUD',
65
+ note: 'Australia',
66
+ currency: 'aud',
67
+ searchable: 'Kenguru',
68
+ },
69
+ cny: {
70
+ value: 'CNY',
71
+ label: 'CNY',
72
+ note: 'China',
73
+ currency: 'cny',
74
+ searchable: 'China',
75
+ },
76
+ jpy: {
77
+ value: 'JPY',
78
+ label: 'JPY',
79
+ note: 'Japan',
80
+ currency: 'jpy',
81
+ searchable: 'Japan',
82
+ },
44
83
  } as const;
45
84
 
46
85
  export const SingleCurrency: Story = {
@@ -53,14 +92,28 @@ export const SingleCurrency: Story = {
53
92
 
54
93
  export const MultipleCurrencies: Story = {
55
94
  args: {
95
+ addon: <Lock />,
56
96
  currencies: [
57
97
  {
58
98
  header: 'Popular currencies',
59
99
  },
60
100
  exampleCurrency.eur,
61
101
  exampleCurrency.gbp,
102
+ exampleCurrency.usd,
103
+ exampleCurrency.hkd,
104
+ { header: 'All currencies' },
105
+ exampleCurrency.eur,
106
+ exampleCurrency.gbp,
107
+ exampleCurrency.usd,
108
+ exampleCurrency.aud,
109
+ exampleCurrency.jpy,
62
110
  ],
63
- selectedCurrency: exampleCurrency.eur,
111
+ customActionLabel: 'Custom message with custom action',
112
+ onCustomAction: () => {
113
+ console.log('Custom action');
114
+ },
115
+ selectedCurrency: exampleCurrency.usd,
116
+ searchPlaceholder: 'Type a currency / country',
64
117
  },
65
118
  };
66
119