@transferwise/components 46.9.0 → 46.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/build/i18n/de.json +1 -0
  2. package/build/i18n/en.json +1 -0
  3. package/build/i18n/es.json +1 -0
  4. package/build/i18n/fr.json +1 -0
  5. package/build/i18n/hu.json +1 -0
  6. package/build/i18n/id.json +1 -0
  7. package/build/i18n/it.json +1 -0
  8. package/build/i18n/ja.json +1 -0
  9. package/build/i18n/pl.json +1 -0
  10. package/build/i18n/pt.json +1 -0
  11. package/build/i18n/ro.json +1 -0
  12. package/build/i18n/ru.json +1 -0
  13. package/build/i18n/th.json +1 -0
  14. package/build/i18n/tr.json +1 -0
  15. package/build/i18n/zh-CN.json +1 -0
  16. package/build/i18n/zh-HK.json +1 -0
  17. package/build/index.esm.js +82 -88
  18. package/build/index.esm.js.map +1 -1
  19. package/build/index.js +82 -88
  20. package/build/index.js.map +1 -1
  21. package/build/main.css +6 -0
  22. package/build/styles/drawer/Drawer.css +3 -0
  23. package/build/styles/main.css +6 -0
  24. package/build/styles/modal/Modal.css +3 -0
  25. package/build/types/common/index.d.ts +0 -1
  26. package/build/types/dateLookup/DateLookup.d.ts.map +1 -1
  27. package/build/types/inputs/SelectInput.d.ts +2 -1
  28. package/build/types/inputs/SelectInput.d.ts.map +1 -1
  29. package/build/types/moneyInput/MoneyInput.d.ts.map +1 -1
  30. package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
  31. package/build/types/phoneNumberInput/PhoneNumberInput.messages.d.ts +8 -0
  32. package/build/types/phoneNumberInput/PhoneNumberInput.messages.d.ts.map +1 -0
  33. package/build/types/select/Select.d.ts.map +1 -1
  34. package/build/types/switch/Switch.d.ts.map +1 -1
  35. package/build/types/tabs/Tabs.d.ts.map +1 -1
  36. package/build/types/typeahead/Typeahead.d.ts.map +1 -1
  37. package/package.json +14 -17
  38. package/src/button/Button.story.tsx +3 -3
  39. package/src/common/fakeEvents.js +2 -2
  40. package/src/common/index.js +0 -1
  41. package/src/dateInput/DateInput.story.tsx +4 -3
  42. package/src/dateLookup/DateLookup.js +6 -7
  43. package/src/dateLookup/DateLookup.keyboardEvents.spec.js +24 -25
  44. package/src/dateLookup/DateLookup.story.js +4 -3
  45. package/src/dateLookup/dateTrigger/DateTrigger.spec.js +3 -3
  46. package/src/drawer/Drawer.css +3 -0
  47. package/src/drawer/Drawer.less +4 -0
  48. package/src/i18n/de.json +1 -0
  49. package/src/i18n/en.json +1 -0
  50. package/src/i18n/es.json +1 -0
  51. package/src/i18n/fr.json +1 -0
  52. package/src/i18n/hu.json +1 -0
  53. package/src/i18n/id.json +1 -0
  54. package/src/i18n/it.json +1 -0
  55. package/src/i18n/ja.json +1 -0
  56. package/src/i18n/pl.json +1 -0
  57. package/src/i18n/pt.json +1 -0
  58. package/src/i18n/ro.json +1 -0
  59. package/src/i18n/ru.json +1 -0
  60. package/src/i18n/th.json +1 -0
  61. package/src/i18n/tr.json +1 -0
  62. package/src/i18n/zh-CN.json +1 -0
  63. package/src/i18n/zh-HK.json +1 -0
  64. package/src/info/Info.story.tsx +3 -3
  65. package/src/inputWithDisplayFormat/InputWithDisplayFormat.story.js +2 -7
  66. package/src/inputs/SelectInput.spec.tsx +7 -0
  67. package/src/inputs/SelectInput.story.tsx +223 -317
  68. package/src/inputs/SelectInput.tsx +4 -0
  69. package/src/logo/Logo.js +4 -4
  70. package/src/main.css +6 -0
  71. package/src/modal/Modal.css +3 -0
  72. package/src/modal/Modal.less +4 -0
  73. package/src/modal/Modal.story.tsx +55 -21
  74. package/src/moneyInput/MoneyInput.story.tsx +3 -3
  75. package/src/moneyInput/MoneyInput.tsx +14 -24
  76. package/src/phoneNumberInput/PhoneNumberInput.messages.ts +8 -0
  77. package/src/phoneNumberInput/PhoneNumberInput.spec.js +12 -7
  78. package/src/phoneNumberInput/PhoneNumberInput.tsx +3 -2
  79. package/src/select/Select.js +8 -9
  80. package/src/snackbar/Snackbar.story.tsx +3 -3
  81. package/src/switch/Switch.spec.js +2 -3
  82. package/src/switch/Switch.tsx +1 -2
  83. package/src/switchOption/SwitchOption.spec.js +1 -4
  84. package/src/tabs/Tabs.js +1 -2
  85. package/src/textareaWithDisplayFormat/TextareaWithDisplayFormat.story.tsx +5 -4
  86. package/src/tile/Tile.js +2 -2
  87. package/src/tile/Tile.spec.js +5 -5
  88. package/src/tooltip/Tooltip.story.tsx +3 -3
  89. package/src/typeahead/Typeahead.js +5 -6
  90. package/src/typeahead/Typeahead.spec.js +3 -8
  91. package/src/typeahead/Typeahead.story.js +3 -4
  92. package/build/types/common/key.d.ts +0 -9
  93. package/build/types/common/key.d.ts.map +0 -1
  94. package/build/types/common/keyCodes.d.ts +0 -16
  95. package/build/types/common/keyCodes.d.ts.map +0 -1
  96. package/src/common/key.js +0 -8
  97. package/src/common/keyCodes.js +0 -19
@@ -1,4 +1,5 @@
1
- import { Meta, StoryObj } from '@storybook/react';
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { expect, fn, type Mock, screen, userEvent, within } from '@storybook/test';
2
3
  import { Calendar, ChevronDown } from '@transferwise/icons';
3
4
  import { Flag } from '@wise/art';
4
5
  import classNames from 'classnames';
@@ -7,186 +8,85 @@ import { useState } from 'react';
7
8
  import { getMonthNames } from '../common/dateUtils';
8
9
  import Drawer from '../drawer';
9
10
  import Modal from '../modal';
10
- import { within, userEvent } from '../test-utils';
11
11
 
12
12
  import {
13
13
  SelectInput,
14
14
  type SelectInputItem,
15
15
  SelectInputOptionContent,
16
+ type SelectInputProps,
16
17
  SelectInputTriggerButton,
17
18
  } from './SelectInput';
18
19
 
19
- export default {
20
+ const meta = {
21
+ title: 'components/SelectInput',
20
22
  component: SelectInput,
23
+ tags: ['autodocs'],
24
+ parameters: { actions: { argTypesRegex: '' } },
21
25
  } satisfies Meta<typeof SelectInput>;
26
+ export default meta;
22
27
 
23
- interface TestMonth {
28
+ type Story<T, M extends boolean = false> = StoryObj<SelectInputProps<T, M>>;
29
+
30
+ interface Month {
24
31
  id: number;
25
32
  name: string;
26
- unavailable: boolean;
27
33
  }
28
34
 
29
- const testMonths: TestMonth[] = getMonthNames('en-US').map((name, index) => ({
35
+ const months: Month[] = getMonthNames('en-US').map((name, index) => ({
30
36
  id: index + 1,
31
37
  name,
32
- unavailable: index % 6 === 2,
33
38
  }));
34
39
 
35
- const testQuarters = [
36
- testMonths.slice(0, 3),
37
- testMonths.slice(3, 6),
38
- testMonths.slice(6, 9),
39
- testMonths.slice(9, 12),
40
- ] as const;
41
-
42
- export const Basic: StoryObj<{
43
- filterable: boolean;
44
- filterPlaceholder: string;
45
- clearable: boolean;
46
- invalid: boolean;
47
- disabled: boolean;
48
- size: 'md' | 'lg';
49
- onChange: (value: TestMonth | null) => void;
50
- onClear: () => void;
51
- }> = {
52
- render: function Story({
53
- filterable,
54
- filterPlaceholder,
55
- clearable,
56
- disabled,
57
- size,
58
- onChange,
59
- onClear,
60
- }) {
61
- const [selectedMonth, setSelectedMonth] = useState<TestMonth | null>(null);
40
+ export const Months: Story<Month | null> = {
41
+ args: {
42
+ placeholder: 'Month',
43
+ items: months.map((month) => ({
44
+ type: 'option',
45
+ value: month,
46
+ })),
47
+ renderValue: (month) => <SelectInputOptionContent title={month.name} />,
48
+ onChange: fn() satisfies Mock,
49
+ onClear: fn() satisfies Mock,
50
+ },
51
+ render: function Render({ onChange, onClear, ...args }) {
52
+ const [selectedMonth, setSelectedMonth] = useState<Month | null>(null);
62
53
 
63
54
  return (
64
- <div className="d-flex flex-column">
65
- {/* TODO:
66
- <Field
67
- label="Label"
68
- hint="Information message."
69
- error={invalid ? "Error message." : undefined}
70
- >
71
- */}
72
- <SelectInput
73
- placeholder="Month"
74
- items={testQuarters
75
- .flatMap<SelectInputItem<TestMonth>>((quarterMonths, index) => [
76
- {
77
- type: 'group',
78
- label: `Quarter #${index + 1}`,
79
- options: quarterMonths.map((month) => ({
80
- type: 'option',
81
- value: month,
82
- filterMatchers: [month.name],
83
- disabled: month.unavailable,
84
- })),
85
- },
86
- { type: 'separator' },
87
- ])
88
- .slice(0, -1)}
89
- value={selectedMonth}
90
- renderValue={(month, withinTrigger) => (
91
- <SelectInputOptionContent
92
- title={month.name}
93
- note="Note"
94
- description={withinTrigger ? undefined : `Month #${month.id}`}
95
- icon={<Calendar size={24} />}
96
- />
97
- )}
98
- filterable={filterable}
99
- filterPlaceholder={filterPlaceholder}
100
- size={size}
101
- disabled={disabled}
102
- onChange={(month) => {
103
- setSelectedMonth(month);
104
- onChange(month);
105
- }}
106
- onClear={
107
- clearable
108
- ? () => {
109
- setSelectedMonth(null);
110
- onClear();
111
- }
112
- : undefined
113
- }
114
- />
115
- </div>
55
+ <SelectInput
56
+ {...args}
57
+ value={selectedMonth}
58
+ onChange={(month) => {
59
+ setSelectedMonth(month);
60
+ onChange?.(month);
61
+ }}
62
+ onClear={() => {
63
+ setSelectedMonth(null);
64
+ onClear?.();
65
+ }}
66
+ />
116
67
  );
117
68
  },
118
- args: {
119
- filterable: true,
120
- filterPlaceholder: 'Type a month’s name',
121
- clearable: true,
122
- invalid: false,
123
- disabled: false,
124
- size: 'md',
125
- },
126
- argTypes: {
127
- onChange: {
128
- action: 'changed',
129
- },
130
- onClear: {
131
- action: 'cleared',
132
- },
133
- },
134
- play: ({ canvasElement }) => {
135
- const triggerButton = within(canvasElement).getByRole('button');
136
- userEvent.click(triggerButton);
137
- },
138
- };
69
+ play: async ({ canvasElement, step }) => {
70
+ const canvas = within(canvasElement);
139
71
 
140
- interface Month {
141
- id: number;
142
- name: string;
143
- }
72
+ await step('renders placeholder', async () => {
73
+ const triggerButton = canvas.getByRole('button');
74
+ await expect(triggerButton).toHaveTextContent('Month');
75
+ });
144
76
 
145
- const months: Month[] = getMonthNames('en-US').map((name, index) => ({
146
- id: index + 1,
147
- name,
148
- }));
77
+ await step('selects option via mouse', async () => {
78
+ const triggerButton = canvas.getByRole('button');
149
79
 
150
- export const Months: StoryObj<{
151
- onChange: (value: Month | null) => void;
152
- onClear: () => void;
153
- }> = {
154
- render: function Story({ onChange, onClear }) {
155
- const [selectedMonth, setSelectedMonth] = useState<Month | null>(months[0]);
80
+ await userEvent.click(triggerButton);
81
+ await userEvent.unhover(triggerButton);
156
82
 
157
- return (
158
- <div className="d-flex flex-column">
159
- <SelectInput
160
- placeholder="Month"
161
- items={months.map((month) => ({
162
- type: 'option',
163
- value: month,
164
- }))}
165
- value={selectedMonth}
166
- renderValue={(month) => <SelectInputOptionContent title={month.name} />}
167
- onChange={(month) => {
168
- setSelectedMonth(month);
169
- onChange(month);
170
- }}
171
- onClear={() => {
172
- setSelectedMonth(null);
173
- onClear();
174
- }}
175
- />
176
- </div>
177
- );
178
- },
179
- argTypes: {
180
- onChange: {
181
- action: 'changed',
182
- },
183
- onClear: {
184
- action: 'cleared',
185
- },
186
- },
187
- play: ({ canvasElement }) => {
188
- const triggerButton = within(canvasElement).getByText('January');
189
- userEvent.click(triggerButton);
83
+ const option = within(screen.getByRole('listbox')).getByRole('option', {
84
+ name: 'May',
85
+ });
86
+ await userEvent.click(option);
87
+
88
+ await expect(triggerButton).toHaveTextContent('May');
89
+ });
190
90
  },
191
91
  };
192
92
 
@@ -238,180 +138,188 @@ function currencyOption(currency: Currency) {
238
138
  } satisfies SelectInputItem<Currency>;
239
139
  }
240
140
 
241
- export const Currencies: StoryObj<{
242
- onChange: (value: Currency) => void;
243
- }> = {
244
- render: function Story({ onChange }) {
245
- const [selectedCurrency, setSelectedCurrency] = useState(popularCurrencies[0]);
246
-
247
- return (
248
- <SelectInput
249
- items={[
250
- {
251
- type: 'group',
252
- label: 'Popular currencies',
253
- options: popularCurrencies.map((currency) => currencyOption(currency)),
254
- },
255
- {
256
- type: 'group',
257
- label: 'All currencies',
258
- options: allCurrencies.map((currency) => currencyOption(currency)),
259
- },
260
- ]}
261
- value={selectedCurrency}
262
- renderValue={(currency, withinTrigger) => (
263
- <SelectInputOptionContent
264
- title={currency.code}
265
- note={withinTrigger ? undefined : currency.name}
266
- icon={<Flag code={currency.code} intrinsicSize={24} />}
267
- />
268
- )}
269
- renderFooter={({ resultsEmpty, queryNormalized: normalizedQuery }) =>
270
- resultsEmpty && normalizedQuery != null && /^[a-z]{3}$/u.test(normalizedQuery) ? (
271
- <>
272
- It’s not possible use {normalizedQuery.toUpperCase()} yet.{' '}
273
- <a href="#_" className="np-text-link-default">
274
- Email me when it’s available.
275
- </a>
276
- </>
277
- ) : (
278
- <>
279
- Can’t find it?{' '}
280
- <a href="#_" className="np-text-link-default">
281
- Request the currency you need,
282
- </a>{' '}
283
- and we’ll notify you once it’s available.
284
- </>
285
- )
286
- }
287
- filterable
288
- filterPlaceholder="Type a currency / country"
289
- size="lg"
290
- onChange={(currency) => {
291
- setSelectedCurrency(currency);
292
- onChange(currency);
293
- }}
294
- />
295
- );
296
- },
297
- argTypes: {
298
- onChange: {
299
- action: 'changed',
141
+ const CurrenciesArgs = {
142
+ items: [
143
+ {
144
+ type: 'group',
145
+ label: 'Popular currencies',
146
+ options: popularCurrencies.map((currency) => currencyOption(currency)),
147
+ },
148
+ {
149
+ type: 'group',
150
+ label: 'All currencies',
151
+ options: allCurrencies.map((currency) => currencyOption(currency)),
300
152
  },
153
+ ],
154
+ defaultValue: popularCurrencies[0],
155
+ renderValue: (currency, withinTrigger) => (
156
+ <SelectInputOptionContent
157
+ title={currency.code}
158
+ note={withinTrigger ? undefined : currency.name}
159
+ icon={<Flag code={currency.code} intrinsicSize={24} />}
160
+ />
161
+ ),
162
+ renderFooter: ({ resultsEmpty, queryNormalized }) =>
163
+ resultsEmpty && queryNormalized != null && /^[a-z]{3}$/u.test(queryNormalized) ? (
164
+ <>
165
+ It’s not possible use {queryNormalized.toUpperCase()} yet.{' '}
166
+ <a href="#_" className="np-text-link-default" onClick={(event) => event.preventDefault()}>
167
+ Email me when it’s available.
168
+ </a>
169
+ </>
170
+ ) : (
171
+ <>
172
+ Can’t find it?{' '}
173
+ <a href="#_" className="np-text-link-default" onClick={(event) => event.preventDefault()}>
174
+ Request the currency you need,
175
+ </a>{' '}
176
+ and we’ll notify you once it’s available.
177
+ </>
178
+ ),
179
+ filterable: true,
180
+ filterPlaceholder: 'Type a currency / country',
181
+ size: 'lg',
182
+ onChange: fn() satisfies Mock,
183
+ } satisfies Story<Currency>['args'];
184
+
185
+ export const Currencies: Story<Currency> = {
186
+ args: CurrenciesArgs,
187
+ play: async ({ step }) => {
188
+ await step('filters options via keyboard', async () => {
189
+ await userEvent.tab();
190
+ await userEvent.keyboard(' ');
191
+
192
+ await expect(within(screen.getByRole('listbox')).queryAllByRole('option')).toHaveLength(8);
193
+ await expect(screen.getByText(/^Can’t find it?/u)).toBeInTheDocument();
194
+
195
+ const input = screen.getByRole('searchbox');
196
+
197
+ await userEvent.type(input, 'huf');
198
+ await expect(
199
+ within(screen.getByRole('listbox')).queryByRole('option'),
200
+ ).not.toBeInTheDocument();
201
+ await expect(screen.getByText(/^It’s not possible use HUF yet./u)).toBeInTheDocument();
202
+
203
+ await userEvent.type(input, '{Backspace}{Backspace}');
204
+ await expect(within(screen.getByRole('listbox')).queryAllByRole('option')).toHaveLength(2);
205
+
206
+ await userEvent.type(input, '{Backspace}eu');
207
+ await expect(input).toHaveAttribute('aria-activedescendant');
208
+ });
301
209
  },
302
210
  };
303
211
 
304
- export const MultipleCurrencies: StoryObj<{
305
- onChange: (value: Currency[]) => void;
306
- }> = {
307
- render: function Story({ onChange }) {
308
- const [selectedCurrencies, setSelectedCurrencies] = useState<readonly Currency[]>([
309
- popularCurrencies[0],
310
- ]);
212
+ export const MultipleCurrencies: Story<Currency, true> = {
213
+ args: {
214
+ ...CurrenciesArgs,
215
+ multiple: true,
216
+ placeholder: 'Choose currencies…',
217
+ defaultValue: [popularCurrencies[0]],
218
+ renderValue: (currency, withinTrigger) =>
219
+ withinTrigger ? (
220
+ currency.code
221
+ ) : (
222
+ <SelectInputOptionContent
223
+ title={currency.code}
224
+ note={currency.name}
225
+ icon={<Flag code={currency.code} intrinsicSize={24} />}
226
+ />
227
+ ),
228
+ },
229
+ play: async ({ canvasElement, step }) => {
230
+ const canvas = within(canvasElement);
311
231
 
312
- return (
313
- <SelectInput
314
- multiple
315
- placeholder="Choose currencies…"
316
- items={[
317
- {
318
- type: 'group',
319
- label: 'Popular currencies',
320
- options: popularCurrencies.map((currency) => currencyOption(currency)),
321
- },
322
- {
323
- type: 'group',
324
- label: 'All currencies',
325
- options: allCurrencies.map((currency) => currencyOption(currency)),
326
- },
327
- ]}
328
- value={selectedCurrencies}
329
- renderValue={(currency, withinTrigger) =>
330
- withinTrigger ? (
331
- currency.code
332
- ) : (
333
- <SelectInputOptionContent
334
- title={currency.code}
335
- note={currency.name}
336
- icon={<Flag code={currency.code} intrinsicSize={24} />}
337
- />
338
- )
339
- }
340
- // eslint-disable-next-line sonarjs/no-identical-functions
341
- renderFooter={({ resultsEmpty, queryNormalized: normalizedQuery }) =>
342
- resultsEmpty && normalizedQuery != null && /^[a-z]{3}$/u.test(normalizedQuery) ? (
343
- <>
344
- It’s not possible use {normalizedQuery.toUpperCase()} yet.{' '}
345
- <a href="#_" className="np-text-link-default">
346
- Email me when it’s available.
347
- </a>
348
- </>
349
- ) : (
350
- <>
351
- Can’t find it?{' '}
352
- <a href="#_" className="np-text-link-default">
353
- Request the currency you need,
354
- </a>{' '}
355
- and we’ll notify you once it’s available.
356
- </>
357
- )
358
- }
359
- filterable
360
- filterPlaceholder="Type a currency / country"
361
- size="lg"
362
- onChange={(currency) => {
363
- setSelectedCurrencies(currency);
364
- onChange(currency);
365
- }}
366
- />
367
- );
232
+ await step('selects multiple options via mouse', async () => {
233
+ const triggerButton = canvas.getByRole('button');
234
+
235
+ await userEvent.click(triggerButton);
236
+ await userEvent.unhover(triggerButton);
237
+
238
+ const option = within(screen.getByRole('listbox')).getAllByRole('option', {
239
+ name: /^EUR/u,
240
+ })[0];
241
+ await userEvent.click(option);
242
+
243
+ await expect(triggerButton).toHaveTextContent('USD, EUR');
244
+ });
368
245
  },
369
- argTypes: {
370
- onChange: {
371
- action: 'changed',
372
- },
246
+ };
247
+
248
+ export const CustomTrigger: Story<Month> = {
249
+ args: {
250
+ placeholder: 'Month',
251
+ items: months.map((month) => ({
252
+ type: 'option',
253
+ value: month,
254
+ })),
255
+ renderValue: (month, withinTrigger) =>
256
+ withinTrigger ? month.name : <SelectInputOptionContent title={month.name} />,
257
+ renderTrigger: ({ content, className }) => (
258
+ <SelectInputTriggerButton
259
+ className={classNames(className, 'btn-unstyled np-text-link-large align-items-center')}
260
+ style={{ display: 'inline-flex', columnGap: '0.25rem' }}
261
+ >
262
+ {content}
263
+ <ChevronDown size={16} />
264
+ </SelectInputTriggerButton>
265
+ ),
266
+ onChange: fn() satisfies Mock,
267
+ },
268
+ play: async ({ canvasElement }) => {
269
+ const canvas = within(canvasElement);
270
+
271
+ const triggerButton = canvas.getByRole('button');
272
+ await userEvent.click(triggerButton);
373
273
  },
374
274
  };
375
275
 
376
- export const CustomTrigger: StoryObj = {
377
- render: function Story() {
378
- return (
379
- <div>
380
- <SelectInput
381
- placeholder="Month"
382
- items={months.map((month) => ({
276
+ const quarters = [
277
+ months.slice(0, 3),
278
+ months.slice(3, 6),
279
+ months.slice(6, 9),
280
+ months.slice(9, 12),
281
+ ] as const;
282
+
283
+ export const Advanced: Story<Month> = {
284
+ args: {
285
+ placeholder: 'Month',
286
+ items: quarters
287
+ .flatMap<SelectInputItem<Month>>((quarterMonths, quarterIndex) => [
288
+ {
289
+ type: 'group',
290
+ label: `Quarter #${quarterIndex + 1}`,
291
+ options: quarterMonths.map((month, monthIndex) => ({
383
292
  type: 'option',
384
293
  value: month,
385
- }))}
386
- renderValue={(month, withinTrigger) =>
387
- withinTrigger ? month.name : <SelectInputOptionContent title={month.name} />
388
- }
389
- renderTrigger={({ content, className }) => (
390
- <SelectInputTriggerButton
391
- className={classNames(
392
- className,
393
- 'btn-unstyled np-text-link-large align-items-center',
394
- )}
395
- style={{ display: 'inline-flex', columnGap: '0.25rem' }}
396
- >
397
- {content}
398
- <ChevronDown size={16} />
399
- </SelectInputTriggerButton>
400
- )}
401
- />
402
- </div>
403
- );
294
+ filterMatchers: [month.name],
295
+ disabled: monthIndex % 6 === 2,
296
+ })),
297
+ },
298
+ { type: 'separator' },
299
+ ])
300
+ .slice(0, -1),
301
+ renderValue: (month, withinTrigger) => (
302
+ <SelectInputOptionContent
303
+ title={month.name}
304
+ note="Note"
305
+ description={withinTrigger ? undefined : `Month #${month.id}`}
306
+ icon={<Calendar size={24} />}
307
+ />
308
+ ),
309
+ filterable: true,
310
+ filterPlaceholder: 'Type a month’s name',
311
+ onChange: fn() satisfies Mock,
404
312
  },
405
- play: ({ canvasElement }) => {
406
- const triggerButton = within(canvasElement).getByRole('button');
407
- userEvent.click(triggerButton);
313
+ play: async ({ canvasElement }) => {
314
+ const canvas = within(canvasElement);
315
+
316
+ const triggerButton = canvas.getByRole('button');
317
+ await userEvent.click(triggerButton);
408
318
  },
409
319
  };
410
320
 
411
- export const WithinDrawer: StoryObj<{
412
- onChange: (value: Currency) => void;
413
- }> = {
414
- ...Currencies,
321
+ export const WithinDrawer: Story<Currency> = {
322
+ args: CurrenciesArgs,
415
323
  decorators: [
416
324
  (Story) => (
417
325
  <Drawer open headerTitle="This is the title of the drawer">
@@ -421,9 +329,7 @@ export const WithinDrawer: StoryObj<{
421
329
  ],
422
330
  };
423
331
 
424
- export const WithinModal: StoryObj<{
425
- onChange: (value: Currency) => void;
426
- }> = {
427
- ...Currencies,
332
+ export const WithinModal: Story<Currency> = {
333
+ args: CurrenciesArgs,
428
334
  decorators: [(Story) => <Modal open body={<Story />} onClose={() => {}} />],
429
335
  };
@@ -41,6 +41,7 @@ function inferSearchableStrings(value: unknown) {
41
41
 
42
42
  const SelectInputTriggerButtonPropsContext = createContext<{
43
43
  ref?: React.ForwardedRef<HTMLButtonElement>;
44
+ id?: string;
44
45
  onClick?: (event: React.MouseEvent) => void;
45
46
  onKeyDown?: (event: React.KeyboardEvent) => void;
46
47
  [key: string]: unknown;
@@ -125,6 +126,7 @@ function filterSelectInputItems<T>(items: readonly SelectInputItem<T>[], needle:
125
126
  }
126
127
 
127
128
  export interface SelectInputProps<T = string, M extends boolean = false> {
129
+ id?: string;
128
130
  name?: string;
129
131
  multiple?: M;
130
132
  placeholder?: string;
@@ -218,6 +220,7 @@ function SelectInputClearButton({ className, onClick }: SelectInputClearButtonPr
218
220
  const noop = () => {};
219
221
 
220
222
  export function SelectInput<T = string, M extends boolean = false>({
223
+ id,
221
224
  name,
222
225
  multiple,
223
226
  placeholder,
@@ -288,6 +291,7 @@ export function SelectInput<T = string, M extends boolean = false>({
288
291
  // eslint-disable-next-line react/jsx-no-constructed-context-values
289
292
  value={{
290
293
  ref: mergeRefs([ref, triggerRef]),
294
+ id,
291
295
  ...mergeProps(
292
296
  {
293
297
  onClick: () => {
package/src/logo/Logo.js CHANGED
@@ -2,10 +2,10 @@ import classNames from 'classnames';
2
2
  import PropTypes from 'prop-types';
3
3
 
4
4
  import { LogoType } from './logoTypes';
5
- import { LogoFlagInverse } from './svg/flag-inverse.svg';
6
- import { LogoFlag } from './svg/flag.svg';
7
- import { LogoWiseInverse } from './svg/logo-inverse.svg';
8
- import { LogoWise } from './svg/logo.svg';
5
+ import { ReactComponent as LogoFlagInverse } from './svg/flag-inverse.svg';
6
+ import { ReactComponent as LogoFlag } from './svg/flag.svg';
7
+ import { ReactComponent as LogoWiseInverse } from './svg/logo-inverse.svg';
8
+ import { ReactComponent as LogoWise } from './svg/logo.svg';
9
9
 
10
10
  const svgPaths = {
11
11
  WISE: LogoWise,
package/src/main.css CHANGED
@@ -1884,6 +1884,9 @@ button.np-option {
1884
1884
  overflow-y: auto;
1885
1885
  flex: 1;
1886
1886
  }
1887
+ .np-drawer .np-drawer-content .np-theme-personal {
1888
+ background-color: transparent;
1889
+ }
1887
1890
  .np-drawer .np-drawer-footer,
1888
1891
  .np-drawer .np-drawer-content {
1889
1892
  padding: 16px;
@@ -3197,6 +3200,9 @@ a {
3197
3200
  min-height: var(--size-32);
3198
3201
  padding-bottom: 4px !important;
3199
3202
  }
3203
+ .tw-modal .tw-modal-content .np-theme-personal {
3204
+ background-color: transparent;
3205
+ }
3200
3206
  .tw-modal table,
3201
3207
  .tw-modal .table {
3202
3208
  background-color: transparent;
@@ -82,6 +82,9 @@
82
82
  min-height: var(--size-32);
83
83
  padding-bottom: 4px !important;
84
84
  }
85
+ .tw-modal .tw-modal-content .np-theme-personal {
86
+ background-color: transparent;
87
+ }
85
88
  .tw-modal table,
86
89
  .tw-modal .table {
87
90
  background-color: transparent;