@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.
- package/build/i18n/de.json +1 -0
- package/build/i18n/en.json +1 -0
- package/build/i18n/es.json +1 -0
- package/build/i18n/fr.json +1 -0
- package/build/i18n/hu.json +1 -0
- package/build/i18n/id.json +1 -0
- package/build/i18n/it.json +1 -0
- package/build/i18n/ja.json +1 -0
- package/build/i18n/pl.json +1 -0
- package/build/i18n/pt.json +1 -0
- package/build/i18n/ro.json +1 -0
- package/build/i18n/ru.json +1 -0
- package/build/i18n/th.json +1 -0
- package/build/i18n/tr.json +1 -0
- package/build/i18n/zh-CN.json +1 -0
- package/build/i18n/zh-HK.json +1 -0
- package/build/index.esm.js +82 -88
- package/build/index.esm.js.map +1 -1
- package/build/index.js +82 -88
- package/build/index.js.map +1 -1
- package/build/main.css +6 -0
- package/build/styles/drawer/Drawer.css +3 -0
- package/build/styles/main.css +6 -0
- package/build/styles/modal/Modal.css +3 -0
- package/build/types/common/index.d.ts +0 -1
- package/build/types/dateLookup/DateLookup.d.ts.map +1 -1
- package/build/types/inputs/SelectInput.d.ts +2 -1
- package/build/types/inputs/SelectInput.d.ts.map +1 -1
- package/build/types/moneyInput/MoneyInput.d.ts.map +1 -1
- package/build/types/phoneNumberInput/PhoneNumberInput.d.ts.map +1 -1
- package/build/types/phoneNumberInput/PhoneNumberInput.messages.d.ts +8 -0
- package/build/types/phoneNumberInput/PhoneNumberInput.messages.d.ts.map +1 -0
- package/build/types/select/Select.d.ts.map +1 -1
- package/build/types/switch/Switch.d.ts.map +1 -1
- package/build/types/tabs/Tabs.d.ts.map +1 -1
- package/build/types/typeahead/Typeahead.d.ts.map +1 -1
- package/package.json +14 -17
- package/src/button/Button.story.tsx +3 -3
- package/src/common/fakeEvents.js +2 -2
- package/src/common/index.js +0 -1
- package/src/dateInput/DateInput.story.tsx +4 -3
- package/src/dateLookup/DateLookup.js +6 -7
- package/src/dateLookup/DateLookup.keyboardEvents.spec.js +24 -25
- package/src/dateLookup/DateLookup.story.js +4 -3
- package/src/dateLookup/dateTrigger/DateTrigger.spec.js +3 -3
- package/src/drawer/Drawer.css +3 -0
- package/src/drawer/Drawer.less +4 -0
- package/src/i18n/de.json +1 -0
- package/src/i18n/en.json +1 -0
- package/src/i18n/es.json +1 -0
- package/src/i18n/fr.json +1 -0
- package/src/i18n/hu.json +1 -0
- package/src/i18n/id.json +1 -0
- package/src/i18n/it.json +1 -0
- package/src/i18n/ja.json +1 -0
- package/src/i18n/pl.json +1 -0
- package/src/i18n/pt.json +1 -0
- package/src/i18n/ro.json +1 -0
- package/src/i18n/ru.json +1 -0
- package/src/i18n/th.json +1 -0
- package/src/i18n/tr.json +1 -0
- package/src/i18n/zh-CN.json +1 -0
- package/src/i18n/zh-HK.json +1 -0
- package/src/info/Info.story.tsx +3 -3
- package/src/inputWithDisplayFormat/InputWithDisplayFormat.story.js +2 -7
- package/src/inputs/SelectInput.spec.tsx +7 -0
- package/src/inputs/SelectInput.story.tsx +223 -317
- package/src/inputs/SelectInput.tsx +4 -0
- package/src/logo/Logo.js +4 -4
- package/src/main.css +6 -0
- package/src/modal/Modal.css +3 -0
- package/src/modal/Modal.less +4 -0
- package/src/modal/Modal.story.tsx +55 -21
- package/src/moneyInput/MoneyInput.story.tsx +3 -3
- package/src/moneyInput/MoneyInput.tsx +14 -24
- package/src/phoneNumberInput/PhoneNumberInput.messages.ts +8 -0
- package/src/phoneNumberInput/PhoneNumberInput.spec.js +12 -7
- package/src/phoneNumberInput/PhoneNumberInput.tsx +3 -2
- package/src/select/Select.js +8 -9
- package/src/snackbar/Snackbar.story.tsx +3 -3
- package/src/switch/Switch.spec.js +2 -3
- package/src/switch/Switch.tsx +1 -2
- package/src/switchOption/SwitchOption.spec.js +1 -4
- package/src/tabs/Tabs.js +1 -2
- package/src/textareaWithDisplayFormat/TextareaWithDisplayFormat.story.tsx +5 -4
- package/src/tile/Tile.js +2 -2
- package/src/tile/Tile.spec.js +5 -5
- package/src/tooltip/Tooltip.story.tsx +3 -3
- package/src/typeahead/Typeahead.js +5 -6
- package/src/typeahead/Typeahead.spec.js +3 -8
- package/src/typeahead/Typeahead.story.js +3 -4
- package/build/types/common/key.d.ts +0 -9
- package/build/types/common/key.d.ts.map +0 -1
- package/build/types/common/keyCodes.d.ts +0 -16
- package/build/types/common/keyCodes.d.ts.map +0 -1
- package/src/common/key.js +0 -8
- package/src/common/keyCodes.js +0 -19
package/src/modal/Modal.less
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { action } from '@storybook/addon-actions';
|
|
2
2
|
import { Meta, StoryObj } from '@storybook/react';
|
|
3
|
+
import { ScreenMode, ThemeProvider } from '@wise/components-theming';
|
|
3
4
|
import { useState } from 'react';
|
|
4
5
|
|
|
5
|
-
import { Button, Modal } from '..';
|
|
6
|
-
import { Scroll } from '../common';
|
|
7
|
-
import { lorem10, lorem1000, storyConfig } from '../test-utils';
|
|
6
|
+
import { Button, Modal, ModalProps } from '..';
|
|
7
|
+
import { CommonProps, Scroll } from '../common';
|
|
8
|
+
import { lorem10, lorem100, lorem1000, storyConfig } from '../test-utils';
|
|
8
9
|
|
|
9
10
|
export default {
|
|
10
11
|
component: Modal,
|
|
@@ -23,6 +24,39 @@ export default {
|
|
|
23
24
|
|
|
24
25
|
type Story = StoryObj<typeof Modal>;
|
|
25
26
|
|
|
27
|
+
export interface StoryContentProps {
|
|
28
|
+
args: CommonProps & ModalProps;
|
|
29
|
+
screenMode?: ScreenMode;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const StoryContent = ({ args, screenMode }: StoryContentProps) => {
|
|
33
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
34
|
+
const [open, setOpen] = useState(args.open);
|
|
35
|
+
return (
|
|
36
|
+
<>
|
|
37
|
+
<Button onClick={() => setOpen(true)}>Open Modal</Button>
|
|
38
|
+
<Modal
|
|
39
|
+
{...args}
|
|
40
|
+
body={
|
|
41
|
+
!screenMode ? (
|
|
42
|
+
args.body
|
|
43
|
+
) : (
|
|
44
|
+
<ThemeProvider theme="personal" screenMode={screenMode}>
|
|
45
|
+
{lorem100}
|
|
46
|
+
</ThemeProvider>
|
|
47
|
+
)
|
|
48
|
+
}
|
|
49
|
+
open={open}
|
|
50
|
+
disableDimmerClickToClose={args.disableDimmerClickToClose}
|
|
51
|
+
onClose={() => {
|
|
52
|
+
setOpen(false);
|
|
53
|
+
action('Modal closed')();
|
|
54
|
+
}}
|
|
55
|
+
/>
|
|
56
|
+
</>
|
|
57
|
+
);
|
|
58
|
+
};
|
|
59
|
+
|
|
26
60
|
export const Basic: Story = {
|
|
27
61
|
args: {
|
|
28
62
|
title: 'Title',
|
|
@@ -30,24 +64,7 @@ export const Basic: Story = {
|
|
|
30
64
|
scroll: Scroll.VIEWPORT,
|
|
31
65
|
footer: <Button block>Action</Button>,
|
|
32
66
|
},
|
|
33
|
-
render: (args) => {
|
|
34
|
-
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
35
|
-
const [open, setOpen] = useState(args.open);
|
|
36
|
-
return (
|
|
37
|
-
<>
|
|
38
|
-
<Button onClick={() => setOpen(true)}>Open Modal</Button>
|
|
39
|
-
<Modal
|
|
40
|
-
{...args}
|
|
41
|
-
open={open}
|
|
42
|
-
disableDimmerClickToClose={args.disableDimmerClickToClose}
|
|
43
|
-
onClose={() => {
|
|
44
|
-
setOpen(false);
|
|
45
|
-
action('Modal closed')();
|
|
46
|
-
}}
|
|
47
|
-
/>
|
|
48
|
-
</>
|
|
49
|
-
);
|
|
50
|
-
},
|
|
67
|
+
render: (args) => <StoryContent args={args} />,
|
|
51
68
|
};
|
|
52
69
|
|
|
53
70
|
export const BasicMobile: Story = storyConfig(Basic, { variants: ['mobile'] });
|
|
@@ -80,3 +97,20 @@ export const WithoutTitle: Story = {
|
|
|
80
97
|
};
|
|
81
98
|
|
|
82
99
|
export const WithoutTitleMobile: Story = storyConfig(WithoutTitle, { variants: ['mobile'] });
|
|
100
|
+
|
|
101
|
+
export const WithThemeProviderInContent: Story = {
|
|
102
|
+
args: {
|
|
103
|
+
title: lorem10,
|
|
104
|
+
body: lorem100,
|
|
105
|
+
scroll: Scroll.VIEWPORT,
|
|
106
|
+
footer: <Button block>Action</Button>,
|
|
107
|
+
},
|
|
108
|
+
render: (args, { globals: { screenMode } }) => (
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
|
110
|
+
<StoryContent args={args} screenMode={screenMode} />
|
|
111
|
+
),
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
export const WithThemeProviderInContentMobile: Story = storyConfig(WithThemeProviderInContent, {
|
|
115
|
+
variants: ['mobile'],
|
|
116
|
+
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { within, userEvent } from '@storybook/
|
|
2
|
+
import { within, userEvent } from '@storybook/test';
|
|
3
3
|
import { Lock } from '@transferwise/icons';
|
|
4
4
|
import React, { useState } from 'react';
|
|
5
5
|
|
|
@@ -150,9 +150,9 @@ export const BalanceCurrencies: Story = {
|
|
|
150
150
|
|
|
151
151
|
export const OpenedInput: Story = {
|
|
152
152
|
...MultipleCurrencies,
|
|
153
|
-
play: ({ canvasElement }) => {
|
|
153
|
+
play: async ({ canvasElement }) => {
|
|
154
154
|
const canvas = within(canvasElement);
|
|
155
|
-
userEvent.click(canvas.getByRole('button'));
|
|
155
|
+
await userEvent.click(canvas.getByRole('button'));
|
|
156
156
|
},
|
|
157
157
|
};
|
|
158
158
|
|
|
@@ -5,8 +5,6 @@ import { Component } from 'react';
|
|
|
5
5
|
import { injectIntl, WrappedComponentProps } from 'react-intl';
|
|
6
6
|
|
|
7
7
|
import { Typography } from '../common';
|
|
8
|
-
import { Key as keyValues } from '../common/key';
|
|
9
|
-
import keyCodes from '../common/keyCodes';
|
|
10
8
|
import { Size, SizeLarge, SizeMedium, SizeSmall } from '../common/propsValues/size';
|
|
11
9
|
import { Input } from '../inputs/Input';
|
|
12
10
|
import {
|
|
@@ -76,22 +74,20 @@ const parseNumber = ({
|
|
|
76
74
|
return Number(amount);
|
|
77
75
|
};
|
|
78
76
|
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
77
|
+
const allowedInputKeys = new Set([
|
|
78
|
+
'Backspace',
|
|
79
|
+
'Delete',
|
|
80
|
+
',',
|
|
81
|
+
'.',
|
|
82
|
+
'ArrowDown',
|
|
83
|
+
'ArrowUp',
|
|
84
|
+
'ArrowLeft',
|
|
85
|
+
'ArrowRight',
|
|
86
|
+
'Enter',
|
|
87
|
+
'Escape',
|
|
88
|
+
'Tab',
|
|
91
89
|
]);
|
|
92
90
|
|
|
93
|
-
const inputKeyAllowlist = new Set([keyValues.PERIOD, keyValues.COMMA]);
|
|
94
|
-
|
|
95
91
|
export interface MoneyInputProps extends WrappedComponentProps {
|
|
96
92
|
id?: string;
|
|
97
93
|
currencies: readonly CurrencyItem[];
|
|
@@ -162,16 +158,10 @@ class MoneyInput extends Component<MoneyInputProps, MoneyInputState> {
|
|
|
162
158
|
}
|
|
163
159
|
|
|
164
160
|
isInputAllowedForKeyEvent = (event: React.KeyboardEvent<HTMLInputElement>) => {
|
|
165
|
-
const {
|
|
161
|
+
const { metaKey, key, ctrlKey } = event;
|
|
166
162
|
const isNumberKey = isNumber(parseInt(key, 10));
|
|
167
163
|
|
|
168
|
-
return (
|
|
169
|
-
isNumberKey ||
|
|
170
|
-
metaKey ||
|
|
171
|
-
ctrlKey ||
|
|
172
|
-
inputKeyCodeAllowlist.has(keyCode) ||
|
|
173
|
-
inputKeyAllowlist.has(key)
|
|
174
|
-
);
|
|
164
|
+
return isNumberKey || metaKey || ctrlKey || allowedInputKeys.has(key);
|
|
175
165
|
};
|
|
176
166
|
|
|
177
167
|
handleKeyDown: React.KeyboardEventHandler<HTMLInputElement> = (event) => {
|
|
@@ -5,7 +5,12 @@ import { mockMatchMedia, mockResizeObserver } from '../test-utils';
|
|
|
5
5
|
|
|
6
6
|
import PhoneNumberInput from '.';
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
const locale = 'en-GB';
|
|
9
|
+
const formatMessage = (message) => message.defaultMessage;
|
|
10
|
+
jest.mock('react-intl', () => ({
|
|
11
|
+
...jest.requireActual('react-intl'),
|
|
12
|
+
useIntl: jest.fn(() => ({ locale, formatMessage })),
|
|
13
|
+
}));
|
|
9
14
|
|
|
10
15
|
mockMatchMedia();
|
|
11
16
|
mockResizeObserver();
|
|
@@ -22,7 +27,7 @@ describe('Given a telephone number component', () => {
|
|
|
22
27
|
const NUMBER_SELECTOR = 'input[name="phoneNumber"]';
|
|
23
28
|
|
|
24
29
|
beforeEach(() => {
|
|
25
|
-
useIntl.mockReturnValue({ locale
|
|
30
|
+
useIntl.mockReturnValue({ locale, formatMessage });
|
|
26
31
|
});
|
|
27
32
|
|
|
28
33
|
afterEach(() => {
|
|
@@ -210,7 +215,7 @@ describe('Given a telephone number component', () => {
|
|
|
210
215
|
|
|
211
216
|
describe('when supplied with a placeholder', () => {
|
|
212
217
|
beforeEach(() => {
|
|
213
|
-
useIntl.mockReturnValue({ locale: 'es-ES' });
|
|
218
|
+
useIntl.mockReturnValue({ locale: 'es-ES', formatMessage });
|
|
214
219
|
component = shallow(
|
|
215
220
|
<PhoneNumberInput {...props} initialValue="+12345678" placeholder="placeholder" />,
|
|
216
221
|
);
|
|
@@ -224,7 +229,7 @@ describe('Given a telephone number component', () => {
|
|
|
224
229
|
|
|
225
230
|
describe('when supplied with a search placeholder', () => {
|
|
226
231
|
beforeEach(() => {
|
|
227
|
-
useIntl.mockReturnValue({ locale: 'es-ES' });
|
|
232
|
+
useIntl.mockReturnValue({ locale: 'es-ES', formatMessage });
|
|
228
233
|
component = shallow(
|
|
229
234
|
<PhoneNumberInput
|
|
230
235
|
{...props}
|
|
@@ -243,7 +248,7 @@ describe('Given a telephone number component', () => {
|
|
|
243
248
|
describe('when supplied with a locale', () => {
|
|
244
249
|
describe('and a value', () => {
|
|
245
250
|
beforeEach(() => {
|
|
246
|
-
useIntl.mockReturnValue({ locale: 'es-ES' });
|
|
251
|
+
useIntl.mockReturnValue({ locale: 'es-ES', formatMessage });
|
|
247
252
|
component = shallow(<PhoneNumberInput {...props} initialValue="+12345678" />);
|
|
248
253
|
select = component.find(PREFIX_SELECT_SELECTOR);
|
|
249
254
|
input = component.find(NUMBER_SELECTOR);
|
|
@@ -257,7 +262,7 @@ describe('Given a telephone number component', () => {
|
|
|
257
262
|
describe('and no value', () => {
|
|
258
263
|
describe('and no country code', () => {
|
|
259
264
|
beforeEach(() => {
|
|
260
|
-
useIntl.mockReturnValue({ locale: 'es' });
|
|
265
|
+
useIntl.mockReturnValue({ locale: 'es', formatMessage });
|
|
261
266
|
component = shallow(<PhoneNumberInput {...props} />);
|
|
262
267
|
select = component.find(PREFIX_SELECT_SELECTOR);
|
|
263
268
|
input = component.find(NUMBER_SELECTOR);
|
|
@@ -270,7 +275,7 @@ describe('Given a telephone number component', () => {
|
|
|
270
275
|
|
|
271
276
|
describe('and country code', () => {
|
|
272
277
|
beforeEach(() => {
|
|
273
|
-
useIntl.mockReturnValue({ locale: 'es-ES' });
|
|
278
|
+
useIntl.mockReturnValue({ locale: 'es-ES', formatMessage });
|
|
274
279
|
component = shallow(<PhoneNumberInput {...props} countryCode="US" />);
|
|
275
280
|
select = component.find(PREFIX_SELECT_SELECTOR);
|
|
276
281
|
input = component.find(NUMBER_SELECTOR);
|
|
@@ -4,6 +4,7 @@ import { useIntl } from 'react-intl';
|
|
|
4
4
|
import { Size, SizeLarge, SizeMedium, SizeSmall } from '../common';
|
|
5
5
|
import { SelectInput, SelectInputOptionContent, SelectInputProps } from '../inputs/SelectInput';
|
|
6
6
|
|
|
7
|
+
import messages from './PhoneNumberInput.messages';
|
|
7
8
|
import countries from './data/countries';
|
|
8
9
|
import {
|
|
9
10
|
explodeNumberModel,
|
|
@@ -54,7 +55,7 @@ const PhoneNumberInput = ({
|
|
|
54
55
|
selectProps = defaultSelectProps,
|
|
55
56
|
disabledCountries = defaultDisabledCountries,
|
|
56
57
|
}: PhoneNumberInputProps) => {
|
|
57
|
-
const { locale } = useIntl();
|
|
58
|
+
const { locale, formatMessage } = useIntl();
|
|
58
59
|
|
|
59
60
|
const [internalValue, setInternalValue] = useState<PhoneNumber>(() => {
|
|
60
61
|
const cleanValue = initialValue ? cleanNumber(initialValue) : null;
|
|
@@ -132,7 +133,7 @@ const PhoneNumberInput = ({
|
|
|
132
133
|
<div className="tw-telephone">
|
|
133
134
|
<div className="tw-telephone__country-select">
|
|
134
135
|
<SelectInput
|
|
135
|
-
placeholder=
|
|
136
|
+
placeholder={formatMessage(messages.selectInputPlaceholder)}
|
|
136
137
|
items={[...countriesByPrefix].map(([prefix, countries]) => ({
|
|
137
138
|
type: 'option',
|
|
138
139
|
value: prefix,
|
package/src/select/Select.js
CHANGED
|
@@ -10,7 +10,6 @@ import { Position, getSimpleRandomId } from '../common';
|
|
|
10
10
|
import BottomSheet from '../common/bottomSheet';
|
|
11
11
|
import { stopPropagation } from '../common/domHelpers';
|
|
12
12
|
import { useLayout } from '../common/hooks';
|
|
13
|
-
import KeyCodes from '../common/keyCodes';
|
|
14
13
|
import Panel from '../common/panel';
|
|
15
14
|
import Drawer from '../drawer';
|
|
16
15
|
|
|
@@ -204,17 +203,17 @@ export default function Select({
|
|
|
204
203
|
};
|
|
205
204
|
|
|
206
205
|
const handleKeyDown = (event) => {
|
|
207
|
-
switch (event.
|
|
208
|
-
case
|
|
209
|
-
case
|
|
206
|
+
switch (event.key) {
|
|
207
|
+
case 'ArrowUp':
|
|
208
|
+
case 'ArrowDown':
|
|
210
209
|
if (open) {
|
|
211
|
-
moveFocusWithDifference(event.
|
|
210
|
+
moveFocusWithDifference(event.key === 'ArrowUp' ? -1 : 1);
|
|
212
211
|
} else {
|
|
213
212
|
setOpen(true);
|
|
214
213
|
}
|
|
215
214
|
stopPropagation(event);
|
|
216
215
|
break;
|
|
217
|
-
case
|
|
216
|
+
case ' ':
|
|
218
217
|
if (event.target !== searchBoxReference.current) {
|
|
219
218
|
if (open) {
|
|
220
219
|
selectKeyboardFocusedOption();
|
|
@@ -224,7 +223,7 @@ export default function Select({
|
|
|
224
223
|
stopPropagation(event);
|
|
225
224
|
}
|
|
226
225
|
break;
|
|
227
|
-
case
|
|
226
|
+
case 'Enter':
|
|
228
227
|
if (open) {
|
|
229
228
|
selectKeyboardFocusedOption();
|
|
230
229
|
} else {
|
|
@@ -232,11 +231,11 @@ export default function Select({
|
|
|
232
231
|
}
|
|
233
232
|
stopPropagation(event);
|
|
234
233
|
break;
|
|
235
|
-
case
|
|
234
|
+
case 'Escape':
|
|
236
235
|
handleCloseOptions();
|
|
237
236
|
stopPropagation(event);
|
|
238
237
|
break;
|
|
239
|
-
case
|
|
238
|
+
case 'Tab':
|
|
240
239
|
if (open) {
|
|
241
240
|
selectKeyboardFocusedOption();
|
|
242
241
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { action } from '@storybook/addon-actions';
|
|
2
2
|
import { number } from '@storybook/addon-knobs';
|
|
3
3
|
import { StoryContext } from '@storybook/react';
|
|
4
|
+
import { userEvent, within } from '@storybook/test';
|
|
4
5
|
import { Mobile, Theme, Switch, Bulb, Info, Coins } from '@transferwise/icons';
|
|
5
6
|
|
|
6
7
|
import Button from '../button';
|
|
7
8
|
import CheckboxOption from '../checkboxOption/CheckboxOption';
|
|
8
|
-
import { within, userEvent } from '../test-utils';
|
|
9
9
|
|
|
10
10
|
import { Snackbar } from './Snackbar';
|
|
11
11
|
import { SnackbarConsumer } from './SnackbarContext';
|
|
@@ -121,7 +121,7 @@ export const basic = () => {
|
|
|
121
121
|
);
|
|
122
122
|
};
|
|
123
123
|
|
|
124
|
-
basic.play = ({ canvasElement }: StoryContext) => {
|
|
124
|
+
basic.play = async ({ canvasElement }: StoryContext) => {
|
|
125
125
|
const canvas = within(canvasElement);
|
|
126
|
-
userEvent.click(canvas.getByRole('button'));
|
|
126
|
+
await userEvent.click(canvas.getByRole('button'));
|
|
127
127
|
};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import KeyCodes from '../common/keyCodes';
|
|
2
1
|
import { render, fireEvent, screen } from '../test-utils';
|
|
3
2
|
|
|
4
3
|
import Switch from './Switch';
|
|
@@ -69,9 +68,9 @@ describe('Switch', () => {
|
|
|
69
68
|
);
|
|
70
69
|
|
|
71
70
|
const input = screen.getAllByRole('checkbox')[0];
|
|
72
|
-
fireEvent.keyDown(input, { key: '
|
|
71
|
+
fireEvent.keyDown(input, { key: 'Enter' });
|
|
73
72
|
expect(props.onClick).not.toHaveBeenCalled();
|
|
74
|
-
fireEvent.keyDown(input, { key: '
|
|
73
|
+
fireEvent.keyDown(input, { key: ' ' });
|
|
75
74
|
expect(props.onClick).toHaveBeenCalledTimes(1);
|
|
76
75
|
});
|
|
77
76
|
|
package/src/switch/Switch.tsx
CHANGED
|
@@ -4,7 +4,6 @@ import classnames from 'classnames';
|
|
|
4
4
|
import { KeyboardEventHandler, MouseEvent, ReactElement } from 'react';
|
|
5
5
|
|
|
6
6
|
import { CommonProps } from '../common';
|
|
7
|
-
import KeyCodes from '../common/keyCodes';
|
|
8
7
|
import { logActionRequiredIf } from '../utilities';
|
|
9
8
|
|
|
10
9
|
type Props = CommonProps & {
|
|
@@ -26,7 +25,7 @@ const Switch = (props: Props): ReactElement => {
|
|
|
26
25
|
const { checked, className, id, onClick, disabled } = props;
|
|
27
26
|
|
|
28
27
|
const handleKeyDown: KeyboardEventHandler = (event) => {
|
|
29
|
-
if (event.
|
|
28
|
+
if (event.key === ' ') {
|
|
30
29
|
event.preventDefault();
|
|
31
30
|
onClick();
|
|
32
31
|
}
|
|
@@ -63,10 +63,7 @@ describe('SwitchOption', () => {
|
|
|
63
63
|
|
|
64
64
|
expect(getSwitch()).toBeChecked();
|
|
65
65
|
|
|
66
|
-
fireEvent.keyDown(getSwitch(), {
|
|
67
|
-
keyCode: 32,
|
|
68
|
-
code: 'Space',
|
|
69
|
-
});
|
|
66
|
+
fireEvent.keyDown(getSwitch(), { key: ' ' });
|
|
70
67
|
|
|
71
68
|
expect(mockOnChange).toHaveBeenLastCalledWith(false);
|
|
72
69
|
expect(mockOnChange).toHaveBeenCalledTimes(2);
|
package/src/tabs/Tabs.js
CHANGED
|
@@ -6,7 +6,6 @@ import PropTypes from 'prop-types';
|
|
|
6
6
|
import { Component, createRef, Fragment, RefObject } from 'react';
|
|
7
7
|
|
|
8
8
|
import { Size, Width, Direction } from '../common';
|
|
9
|
-
import KeyCodes from '../common/keyCodes';
|
|
10
9
|
import { DirectionContext } from '../provider/direction';
|
|
11
10
|
|
|
12
11
|
import Tab from './Tab';
|
|
@@ -294,7 +293,7 @@ class Tabs extends Component {
|
|
|
294
293
|
};
|
|
295
294
|
|
|
296
295
|
onKeyDown = (index) => (event) => {
|
|
297
|
-
if (event && event.
|
|
296
|
+
if (event && event.key === 'Enter') {
|
|
298
297
|
this.switchTab(index);
|
|
299
298
|
}
|
|
300
299
|
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { StoryObj } from '@storybook/react';
|
|
2
|
-
|
|
3
|
-
import { userEvent, within } from '../test-utils';
|
|
2
|
+
import { userEvent, within } from '@storybook/test';
|
|
4
3
|
|
|
5
4
|
import TextareaWithDisplayFormat from './TextareaWithDisplayFormat';
|
|
6
5
|
|
|
@@ -25,8 +24,10 @@ export const Basic: Story = {
|
|
|
25
24
|
},
|
|
26
25
|
// intentionally use interactive typing (over init value via `value` prop)
|
|
27
26
|
// to trigger event handlers in the component
|
|
28
|
-
play: ({ canvasElement }) => {
|
|
27
|
+
play: async ({ canvasElement }) => {
|
|
29
28
|
const canvas = within(canvasElement);
|
|
30
|
-
userEvent.type(canvas.getByRole('textbox'), '111122223333'
|
|
29
|
+
await userEvent.type(canvas.getByRole('textbox'), '111122223333', {
|
|
30
|
+
initialSelectionStart: Number.MAX_SAFE_INTEGER,
|
|
31
|
+
});
|
|
31
32
|
},
|
|
32
33
|
};
|
package/src/tile/Tile.js
CHANGED
|
@@ -2,7 +2,7 @@ import classNames from 'classnames';
|
|
|
2
2
|
import PropTypes from 'prop-types';
|
|
3
3
|
|
|
4
4
|
import Body from '../body';
|
|
5
|
-
import { Size,
|
|
5
|
+
import { Size, Typography } from '../common';
|
|
6
6
|
import Title from '../title';
|
|
7
7
|
|
|
8
8
|
export const Tile = ({
|
|
@@ -41,7 +41,7 @@ export const Tile = ({
|
|
|
41
41
|
disabled
|
|
42
42
|
? null
|
|
43
43
|
: ({ key }) => {
|
|
44
|
-
if (key ===
|
|
44
|
+
if (key === 'Enter' || key === ' ') {
|
|
45
45
|
onClick();
|
|
46
46
|
}
|
|
47
47
|
}
|
package/src/tile/Tile.spec.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Size } from '../common';
|
|
2
2
|
import { render, fireEvent, screen } from '../test-utils';
|
|
3
3
|
|
|
4
4
|
import Tile from '.';
|
|
@@ -44,11 +44,11 @@ describe(Tile, () => {
|
|
|
44
44
|
|
|
45
45
|
const title = screen.getByText('Receive money');
|
|
46
46
|
|
|
47
|
-
fireEvent.keyDown(title, { key:
|
|
47
|
+
fireEvent.keyDown(title, { key: 'Enter' });
|
|
48
48
|
|
|
49
49
|
expect(onClick).toHaveBeenCalledTimes(1);
|
|
50
50
|
|
|
51
|
-
fireEvent.keyDown(title, { key:
|
|
51
|
+
fireEvent.keyDown(title, { key: ' ' });
|
|
52
52
|
|
|
53
53
|
expect(onClick).toHaveBeenCalledTimes(2);
|
|
54
54
|
});
|
|
@@ -66,11 +66,11 @@ describe(Tile, () => {
|
|
|
66
66
|
|
|
67
67
|
const title = screen.getByText('Receive money');
|
|
68
68
|
|
|
69
|
-
fireEvent.keyDown(title, { key:
|
|
69
|
+
fireEvent.keyDown(title, { key: 'Enter' });
|
|
70
70
|
|
|
71
71
|
expect(onClick).not.toHaveBeenCalled();
|
|
72
72
|
|
|
73
|
-
fireEvent.keyDown(title, { key:
|
|
73
|
+
fireEvent.keyDown(title, { key: ' ' });
|
|
74
74
|
|
|
75
75
|
expect(onClick).not.toHaveBeenCalled();
|
|
76
76
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react';
|
|
2
|
-
import { userEvent, within } from '@storybook/
|
|
2
|
+
import { userEvent, within } from '@storybook/test';
|
|
3
3
|
|
|
4
4
|
import Button from '../button';
|
|
5
5
|
import { storyConfig } from '../test-utils';
|
|
@@ -33,9 +33,9 @@ export const OpenedTooltip: Story = {
|
|
|
33
33
|
delay: 1000,
|
|
34
34
|
},
|
|
35
35
|
},
|
|
36
|
-
play: ({ canvasElement }) => {
|
|
36
|
+
play: async ({ canvasElement }) => {
|
|
37
37
|
const canvas = within(canvasElement);
|
|
38
|
-
userEvent.hover(canvas.getByRole('button'));
|
|
38
|
+
await userEvent.hover(canvas.getByRole('button'));
|
|
39
39
|
},
|
|
40
40
|
};
|
|
41
41
|
|
|
@@ -15,7 +15,6 @@ import {
|
|
|
15
15
|
addClickClassToDocumentOnIos,
|
|
16
16
|
removeClickClassFromDocumentOnIos,
|
|
17
17
|
} from '../common/domHelpers';
|
|
18
|
-
import KeyCodes from '../common/keyCodes';
|
|
19
18
|
import InlineAlert from '../inlineAlert';
|
|
20
19
|
|
|
21
20
|
import TypeaheadInput from './typeaheadInput/TypeaheadInput';
|
|
@@ -123,16 +122,16 @@ export default class Typeahead extends Component {
|
|
|
123
122
|
event.preventDefault();
|
|
124
123
|
this.selectItem({ label: query });
|
|
125
124
|
} else {
|
|
126
|
-
switch (event.
|
|
127
|
-
case
|
|
125
|
+
switch (event.key) {
|
|
126
|
+
case 'ArrowDown':
|
|
128
127
|
event.preventDefault();
|
|
129
128
|
this.moveFocusedOption(1);
|
|
130
129
|
break;
|
|
131
|
-
case
|
|
130
|
+
case 'ArrowUp':
|
|
132
131
|
event.preventDefault();
|
|
133
132
|
this.moveFocusedOption(-1);
|
|
134
133
|
break;
|
|
135
|
-
case
|
|
134
|
+
case 'Enter':
|
|
136
135
|
event.preventDefault();
|
|
137
136
|
if (options[keyboardFocusedOptionIndex]) {
|
|
138
137
|
this.selectItem(options[keyboardFocusedOptionIndex]);
|
|
@@ -140,7 +139,7 @@ export default class Typeahead extends Component {
|
|
|
140
139
|
this.selectItem({ label: query });
|
|
141
140
|
}
|
|
142
141
|
break;
|
|
143
|
-
case
|
|
142
|
+
case 'Backspace':
|
|
144
143
|
if (multiple && !query && selected.length > 0) {
|
|
145
144
|
this.updateSelectedValue(selected.slice(0, -1));
|
|
146
145
|
}
|
|
@@ -4,7 +4,6 @@ import doTimes from 'lodash.times';
|
|
|
4
4
|
import { InlineAlert } from '..';
|
|
5
5
|
import { Sentiment } from '../common';
|
|
6
6
|
import { fakeEvent, fakeKeyDownEventForKey } from '../common/fakeEvents';
|
|
7
|
-
import KeyCodes from '../common/keyCodes';
|
|
8
7
|
|
|
9
8
|
import Typeahead from './Typeahead';
|
|
10
9
|
|
|
@@ -94,7 +93,6 @@ describe('Typeahead', () => {
|
|
|
94
93
|
it('removes last selected value when backspace clicked on empty input', () => {
|
|
95
94
|
const event = {
|
|
96
95
|
key: 'Backspace',
|
|
97
|
-
keyCode: KeyCodes.BACKSPACE,
|
|
98
96
|
};
|
|
99
97
|
|
|
100
98
|
component.setProps({
|
|
@@ -116,7 +114,6 @@ describe('Typeahead', () => {
|
|
|
116
114
|
it('does not remove last selected value when backspace clicked on non-empty input', () => {
|
|
117
115
|
const event = {
|
|
118
116
|
key: 'Backspace',
|
|
119
|
-
keyCode: KeyCodes.BACKSPACE,
|
|
120
117
|
};
|
|
121
118
|
|
|
122
119
|
component.setProps({
|
|
@@ -228,21 +225,20 @@ describe('Typeahead', () => {
|
|
|
228
225
|
});
|
|
229
226
|
|
|
230
227
|
it('moves selected items when down and up keys pressed', () => {
|
|
231
|
-
doTimes(3, () => input().simulate('keyDown', fakeKeyDownEventForKey(
|
|
228
|
+
doTimes(3, () => input().simulate('keyDown', fakeKeyDownEventForKey('ArrowDown')));
|
|
232
229
|
|
|
233
230
|
expect(option().at(2).parent().is('.tw-dropdown-item--focused')).toBe(true);
|
|
234
231
|
|
|
235
|
-
input().simulate('keyDown', fakeKeyDownEventForKey(
|
|
232
|
+
input().simulate('keyDown', fakeKeyDownEventForKey('ArrowUp'));
|
|
236
233
|
expect(option().at(1).parent().is('.tw-dropdown-item--focused')).toBe(true);
|
|
237
234
|
|
|
238
|
-
doTimes(5, () => input().simulate('keyDown', fakeKeyDownEventForKey(
|
|
235
|
+
doTimes(5, () => input().simulate('keyDown', fakeKeyDownEventForKey('ArrowDown')));
|
|
239
236
|
expect(option().last().parent().is('.tw-dropdown-item--focused')).toBe(true);
|
|
240
237
|
});
|
|
241
238
|
|
|
242
239
|
it('adds new value as selected and clears the input when no option is highlighted and enter is pressed', () => {
|
|
243
240
|
const event = {
|
|
244
241
|
key: 'Enter',
|
|
245
|
-
keyCode: KeyCodes.ENTER,
|
|
246
242
|
preventDefault: jest.fn(),
|
|
247
243
|
};
|
|
248
244
|
const text = 'test';
|
|
@@ -263,7 +259,6 @@ describe('Typeahead', () => {
|
|
|
263
259
|
it('displays alert when alert is provided and chips are valid or alert type is error', () => {
|
|
264
260
|
const event = {
|
|
265
261
|
key: 'Enter',
|
|
266
|
-
keyCode: KeyCodes.ENTER,
|
|
267
262
|
preventDefault: jest.fn(),
|
|
268
263
|
};
|
|
269
264
|
const text = 'test';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { select, boolean } from '@storybook/addon-knobs';
|
|
2
|
+
import { userEvent, within } from '@storybook/test';
|
|
2
3
|
import { Search as SearchIcon } from '@transferwise/icons';
|
|
3
4
|
import { useState } from 'react';
|
|
4
5
|
|
|
5
6
|
import { Sentiment } from '../common';
|
|
6
|
-
import { within, userEvent } from '../test-utils';
|
|
7
7
|
|
|
8
8
|
import Typeahead from './Typeahead';
|
|
9
9
|
|
|
@@ -45,7 +45,7 @@ export const createable = () => {
|
|
|
45
45
|
|
|
46
46
|
createable.play = async ({ canvasElement }) => {
|
|
47
47
|
const canvas = within(canvasElement);
|
|
48
|
-
userEvent.type(canvas.getByRole('combobox'), 'chip{
|
|
48
|
+
await userEvent.type(canvas.getByRole('combobox'), 'chip{Enter}chip2{Enter}');
|
|
49
49
|
};
|
|
50
50
|
|
|
51
51
|
export const Basic = () => {
|
|
@@ -117,6 +117,5 @@ export const Basic = () => {
|
|
|
117
117
|
|
|
118
118
|
Basic.play = async ({ canvasElement }) => {
|
|
119
119
|
const canvas = within(canvasElement);
|
|
120
|
-
userEvent.type(canvas.getByRole('combobox'), 'abc');
|
|
121
|
-
userEvent.type(canvas.getByRole('combobox'), '{arrowDown}');
|
|
120
|
+
await userEvent.type(canvas.getByRole('combobox'), 'abc{ArrowDown}');
|
|
122
121
|
};
|