@transferwise/components 46.38.0 → 46.39.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.
- package/build/index.js +22 -42
- package/build/index.js.map +1 -1
- package/build/index.mjs +22 -42
- package/build/index.mjs.map +1 -1
- package/build/types/flowNavigation/backButton/BackButton.d.ts +5 -17
- package/build/types/flowNavigation/backButton/BackButton.d.ts.map +1 -1
- package/build/types/flowNavigation/backButton/index.d.ts +2 -2
- package/build/types/flowNavigation/backButton/index.d.ts.map +1 -1
- package/build/types/index.d.ts +1 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/types/info/Info.d.ts +2 -2
- package/build/types/info/Info.d.ts.map +1 -1
- package/build/types/info/index.d.ts +1 -1
- package/build/types/info/index.d.ts.map +1 -1
- package/build/types/overlayHeader/OverlayHeader.d.ts +9 -18
- package/build/types/overlayHeader/OverlayHeader.d.ts.map +1 -1
- package/build/types/overlayHeader/index.d.ts +2 -1
- package/build/types/overlayHeader/index.d.ts.map +1 -1
- package/package.json +24 -26
- package/src/accordion/Accordion.spec.js +5 -5
- package/src/accordion/AccordionItem/AccordionItem.spec.js +2 -2
- package/src/actionButton/ActionButton.spec.tsx +4 -5
- package/src/alert/Alert.spec.tsx +4 -4
- package/src/alert/Alert.story.tsx +6 -5
- package/src/button/Button.spec.js +4 -5
- package/src/card/Card.spec.tsx +4 -4
- package/src/carousel/Carousel.spec.tsx +17 -17
- package/src/checkbox/Checkbox.spec.tsx +0 -2
- package/src/checkboxButton/CheckboxButton.spec.tsx +0 -2
- package/src/checkboxOption/CheckboxOption.spec.tsx +0 -2
- package/src/chevron/Chevron.spec.tsx +0 -1
- package/src/chips/Chips.spec.tsx +0 -1
- package/src/chips/Chips.story.tsx +5 -3
- package/src/circularButton/CircularButton.spec.tsx +4 -5
- package/src/common/RadioButton/RadioButton.spec.tsx +2 -2
- package/src/common/card/Card.story.tsx +1 -0
- package/src/common/closeButton/CloseButton.spec.tsx +0 -1
- package/src/common/flowHeader/FlowHeader.spec.tsx +0 -1
- package/src/dateInput/DateInput.story.tsx +21 -16
- package/src/dateLookup/DateLookup.rtl.spec.tsx +18 -16
- package/src/dateLookup/DateLookup.testingLibrary.spec.js +47 -44
- package/src/dateLookup/DateLookup.tests.story.tsx +4 -2
- package/src/decision/Decision.spec.js +0 -2
- package/src/dimmer/Dimmer.rtl.spec.js +10 -10
- package/src/drawer/Drawer.rtl.spec.tsx +2 -2
- package/src/emphasis/Emphasis.spec.tsx +0 -1
- package/src/field/Field.spec.tsx +2 -2
- package/src/flowNavigation/FlowNavigation.spec.js +0 -2
- package/src/flowNavigation/animatedLabel/AnimatedLabel.spec.js +0 -1
- package/src/flowNavigation/backButton/BackButton.tsx +29 -0
- package/src/flowNavigation/backButton/index.ts +2 -0
- package/src/header/Header.spec.tsx +6 -6
- package/src/image/Image.spec.tsx +0 -1
- package/src/index.ts +1 -0
- package/src/info/Info.story.tsx +15 -9
- package/src/info/Info.tsx +2 -2
- package/src/info/index.ts +1 -1
- package/src/inlineAlert/InlineAlert.spec.tsx +0 -1
- package/src/inputs/SelectInput.spec.tsx +26 -47
- package/src/link/Link.spec.tsx +0 -1
- package/src/listItem/ListItem.spec.tsx +0 -1
- package/src/moneyInput/MoneyInput.rtl.spec.tsx +2 -2
- package/src/moneyInput/MoneyInput.story.tsx +1 -4
- package/src/overlayHeader/{OverlayHeader.spec.js → OverlayHeader.spec.tsx} +1 -1
- package/src/overlayHeader/{OverlayHeader.story.js → OverlayHeader.story.tsx} +10 -2
- package/src/overlayHeader/{OverlayHeader.js → OverlayHeader.tsx} +12 -19
- package/src/overlayHeader/index.ts +2 -0
- package/src/phoneNumberInput/PhoneNumberInput.story.tsx +1 -0
- package/src/popover/Popover.spec.tsx +10 -10
- package/src/progress/Progress.spec.tsx +0 -1
- package/src/progressBar/ProgressBar.spec.tsx +0 -1
- package/src/segmentedControl/SegmentedControl.spec.tsx +10 -11
- package/src/select/Select.spec.js +71 -71
- package/src/test-utils/index.js +1 -1
- package/src/test-utils/jest.setup.js +2 -0
- package/src/tooltip/Tooltip.spec.tsx +15 -16
- package/src/uploadInput/UploadInput.spec.tsx +9 -10
- package/src/uploadInput/UploadInput.story.tsx +8 -180
- package/src/uploadInput/UploadInput.tests.story.tsx +212 -0
- package/src/uploadInput/uploadButton/UploadButton.spec.tsx +4 -4
- package/src/uploadInput/uploadItem/UploadItem.spec.tsx +4 -4
- package/src/flowNavigation/backButton/BackButton.js +0 -32
- package/src/flowNavigation/backButton/BackButton.spec.js +0 -16
- package/src/flowNavigation/backButton/__snapshots__/BackButton.spec.js.snap +0 -37
- package/src/flowNavigation/backButton/index.js +0 -3
- package/src/overlayHeader/index.js +0 -1
- /package/src/overlayHeader/__snapshots__/{OverlayHeader.spec.js.snap → OverlayHeader.spec.tsx.snap} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { within } from '@testing-library/react';
|
|
2
|
-
import userEvent from '@testing-library/user-event';
|
|
2
|
+
import { userEvent } from '@testing-library/user-event';
|
|
3
3
|
|
|
4
4
|
import { Status } from '../common';
|
|
5
5
|
import { mockMatchMedia, render, screen, waitFor, waitForElementToBeRemoved } from '../test-utils';
|
|
@@ -9,6 +9,8 @@ import { TEST_IDS as UPLOAD_BUTTON_TEST_IDS } from './uploadButton/UploadButton'
|
|
|
9
9
|
import { TEST_IDS as UPLOAD_ITEM_TEST_IDS } from './uploadItem/UploadItem';
|
|
10
10
|
import { act } from 'react';
|
|
11
11
|
|
|
12
|
+
const user = userEvent.setup({ advanceTimers: jest.advanceTimersByTimeAsync });
|
|
13
|
+
|
|
12
14
|
mockMatchMedia();
|
|
13
15
|
|
|
14
16
|
describe('UploadInput', () => {
|
|
@@ -58,10 +60,7 @@ describe('UploadInput', () => {
|
|
|
58
60
|
renderComponent({ ...props, onFilesChange });
|
|
59
61
|
|
|
60
62
|
const input = screen.getByTestId(UPLOAD_BUTTON_TEST_IDS.uploadInput);
|
|
61
|
-
|
|
62
|
-
await act(async () => {
|
|
63
|
-
await jest.runOnlyPendingTimersAsync();
|
|
64
|
-
});
|
|
63
|
+
await user.upload(input, [pngFile, jpgFile]);
|
|
65
64
|
|
|
66
65
|
expect(props.onUploadFile).toHaveBeenCalledTimes(1);
|
|
67
66
|
expect(onFilesChange).toHaveBeenCalledTimes(2);
|
|
@@ -116,7 +115,7 @@ describe('UploadInput', () => {
|
|
|
116
115
|
expect(screen.getByTestId(UPLOAD_BUTTON_TEST_IDS.uploadInput)).toHaveAttribute('multiple');
|
|
117
116
|
|
|
118
117
|
const input = screen.getByTestId(UPLOAD_BUTTON_TEST_IDS.uploadInput);
|
|
119
|
-
|
|
118
|
+
await user.upload(input, [pngFile, jpgFile]);
|
|
120
119
|
|
|
121
120
|
await waitFor(() => {
|
|
122
121
|
expect(props.onUploadFile).toHaveBeenCalledTimes(2);
|
|
@@ -244,11 +243,11 @@ describe('UploadInput', () => {
|
|
|
244
243
|
});
|
|
245
244
|
|
|
246
245
|
const input = screen.getByTestId(UPLOAD_BUTTON_TEST_IDS.uploadInput);
|
|
247
|
-
|
|
246
|
+
await user.upload(input, [pngFile, jpgFile]);
|
|
248
247
|
|
|
249
248
|
const pngFile2 = new File(['foo2'], 'foo2.png', { type: 'image/png' });
|
|
250
249
|
const jpgFile2 = new File(['foo2'], 'foo2.jpg', { type: 'image/jpeg' });
|
|
251
|
-
|
|
250
|
+
await user.upload(input, [pngFile2, jpgFile2]);
|
|
252
251
|
|
|
253
252
|
await waitFor(() => {
|
|
254
253
|
expect(screen.getByText(maxFilesReachedMessage)).toBeInTheDocument();
|
|
@@ -274,7 +273,7 @@ describe('UploadInput', () => {
|
|
|
274
273
|
const input = screen.getByTestId(UPLOAD_BUTTON_TEST_IDS.uploadInput);
|
|
275
274
|
const pngFile2 = new File(['foo2'], 'foo2.png', { type: 'image/png' });
|
|
276
275
|
|
|
277
|
-
|
|
276
|
+
await user.upload(input, [pngFile, jpgFile, pngFile2]);
|
|
278
277
|
|
|
279
278
|
await waitFor(() => {
|
|
280
279
|
expect(screen.getByText(defaultMaxFilesReachedMessage)).toBeInTheDocument();
|
|
@@ -305,7 +304,7 @@ describe('UploadInput', () => {
|
|
|
305
304
|
const overSizedFile = new File([''], 'testFile.png', { type: 'image/png' });
|
|
306
305
|
Object.defineProperty(overSizedFile, 'size', { value: twoKbInBytes });
|
|
307
306
|
|
|
308
|
-
|
|
307
|
+
await user.upload(input, overSizedFile);
|
|
309
308
|
await waitFor(() => {
|
|
310
309
|
expect(screen.getByText(sizeLimitErrorMessage)).toBeInTheDocument();
|
|
311
310
|
});
|
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { Story, Meta } from '@storybook/react';
|
|
3
|
-
|
|
4
|
-
import { Status } from '../common';
|
|
1
|
+
import { StoryFn, Meta } from '@storybook/react';
|
|
5
2
|
|
|
6
3
|
import UploadInput, { UploadInputProps } from './UploadInput';
|
|
7
|
-
import {
|
|
4
|
+
import { UploadResponse } from './types';
|
|
8
5
|
|
|
9
6
|
const meta: Meta<typeof UploadInput> = {
|
|
10
7
|
title: 'Forms/UploadInput',
|
|
@@ -13,36 +10,7 @@ const meta: Meta<typeof UploadInput> = {
|
|
|
13
10
|
};
|
|
14
11
|
|
|
15
12
|
export default meta;
|
|
16
|
-
|
|
17
|
-
const files = [
|
|
18
|
-
{
|
|
19
|
-
id: 1,
|
|
20
|
-
filename: 'purchase-receipt-0.pdf',
|
|
21
|
-
url: 'https://wise.com/public-resources/assets/logos/wise/brand_logo_inverse.svg',
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
id: 2,
|
|
25
|
-
filename: 'purchase-receipt-1.pdf',
|
|
26
|
-
url: 'https://wise.com/public-resources/assets/logos/wise/brand_logo_inverse.svg',
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
id: 2,
|
|
30
|
-
filename: 'receipt failed.png',
|
|
31
|
-
status: Status.FAILED,
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
id: 3,
|
|
35
|
-
filename: 'receipt failed with error string.png',
|
|
36
|
-
status: Status.FAILED,
|
|
37
|
-
error: 'Something went wrong',
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
id: 4,
|
|
41
|
-
filename: 'receipt failed with error object.png',
|
|
42
|
-
status: Status.FAILED,
|
|
43
|
-
error: { message: 'Something went wrong' },
|
|
44
|
-
},
|
|
45
|
-
] satisfies UploadedFile[];
|
|
13
|
+
type Story = StoryFn<UploadInputProps>;
|
|
46
14
|
|
|
47
15
|
const createDelayedPromise = async ({
|
|
48
16
|
successful = true,
|
|
@@ -61,158 +29,18 @@ const createDelayedPromise = async ({
|
|
|
61
29
|
});
|
|
62
30
|
|
|
63
31
|
const props = {
|
|
64
|
-
onUploadFile: async (
|
|
32
|
+
onUploadFile: async () => {
|
|
65
33
|
return createDelayedPromise();
|
|
66
34
|
},
|
|
67
|
-
onDeleteFile: async (
|
|
35
|
+
onDeleteFile: async () => {
|
|
68
36
|
return createDelayedPromise();
|
|
69
37
|
},
|
|
70
38
|
};
|
|
71
39
|
|
|
72
|
-
const Template: Story
|
|
40
|
+
const Template: Story = (args: UploadInputProps) => <UploadInput {...args} />;
|
|
73
41
|
|
|
74
|
-
export const SingleFile: Story
|
|
42
|
+
export const SingleFile: Story = Template.bind({});
|
|
75
43
|
SingleFile.args = { ...props };
|
|
76
44
|
|
|
77
|
-
export const MultipleFiles: Story
|
|
45
|
+
export const MultipleFiles: Story = Template.bind({});
|
|
78
46
|
MultipleFiles.args = { ...props, multiple: true };
|
|
79
|
-
|
|
80
|
-
export const UploadInputWithDescriptionFromProps: Story<UploadInputProps> = Template.bind({});
|
|
81
|
-
UploadInputWithDescriptionFromProps.args = {
|
|
82
|
-
...props,
|
|
83
|
-
multiple: true,
|
|
84
|
-
description: 'Custom file description from prop',
|
|
85
|
-
};
|
|
86
|
-
|
|
87
|
-
export const Disabled: Story<UploadInputProps> = Template.bind({});
|
|
88
|
-
Disabled.args = { ...props, disabled: true };
|
|
89
|
-
|
|
90
|
-
export const WithAnyFileType: Story<UploadInputProps> = Template.bind({});
|
|
91
|
-
WithAnyFileType.args = { ...props, fileTypes: '*' };
|
|
92
|
-
|
|
93
|
-
export const WithSingleFileType: Story<UploadInputProps> = Template.bind({});
|
|
94
|
-
WithSingleFileType.args = { ...props, fileTypes: '.zip,application/zip' };
|
|
95
|
-
|
|
96
|
-
export const WithMultipleExistingFiles: Story<UploadInputProps> = Template.bind({});
|
|
97
|
-
WithMultipleExistingFiles.args = {
|
|
98
|
-
...props,
|
|
99
|
-
files,
|
|
100
|
-
multiple: true,
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
export const WithFileErrors: Story<UploadInputProps> = Template.bind({});
|
|
104
|
-
WithFileErrors.args = {
|
|
105
|
-
...props,
|
|
106
|
-
files: [
|
|
107
|
-
{
|
|
108
|
-
id: 1,
|
|
109
|
-
filename: 'Error with default message.png',
|
|
110
|
-
status: Status.FAILED,
|
|
111
|
-
},
|
|
112
|
-
{
|
|
113
|
-
id: 2,
|
|
114
|
-
filename: 'Error with `string` error.png',
|
|
115
|
-
status: Status.FAILED,
|
|
116
|
-
error: 'Single string error',
|
|
117
|
-
},
|
|
118
|
-
{
|
|
119
|
-
id: 3,
|
|
120
|
-
filename: 'Error with `obj` error ({ message : `string` }).png',
|
|
121
|
-
status: Status.FAILED,
|
|
122
|
-
error: { message: 'Single obj error' },
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
id: 4,
|
|
126
|
-
filename: 'Error with single error passed in `array`.png',
|
|
127
|
-
status: Status.FAILED,
|
|
128
|
-
errors: ['Single error in array'],
|
|
129
|
-
},
|
|
130
|
-
{
|
|
131
|
-
id: 5,
|
|
132
|
-
filename: 'Error with multiple `string` errors passed in `array`.png',
|
|
133
|
-
status: Status.FAILED,
|
|
134
|
-
errors: ['Error 1', 'Error 2', 'Error 3'],
|
|
135
|
-
},
|
|
136
|
-
{
|
|
137
|
-
id: 6,
|
|
138
|
-
filename: 'Error with multiple `obj` errors passed in `array`.png',
|
|
139
|
-
status: Status.FAILED,
|
|
140
|
-
errors: [{ message: 'Error 1' }, { message: 'Error 2' }, { message: 'Error 3' }],
|
|
141
|
-
},
|
|
142
|
-
],
|
|
143
|
-
multiple: true,
|
|
144
|
-
};
|
|
145
|
-
|
|
146
|
-
export const WithoutDelete: Story<UploadInputProps> = Template.bind({});
|
|
147
|
-
WithoutDelete.args = {
|
|
148
|
-
...props,
|
|
149
|
-
files,
|
|
150
|
-
onDeleteFile: undefined,
|
|
151
|
-
multiple: true,
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
export const WithUploadFailed: Story<UploadInputProps> = Template.bind({});
|
|
155
|
-
WithUploadFailed.args = {
|
|
156
|
-
...props,
|
|
157
|
-
files: files.slice(0),
|
|
158
|
-
onUploadFile: async () => createDelayedPromise({ successful: false }),
|
|
159
|
-
multiple: true,
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
export const WithDeleteFailed: Story<UploadInputProps> = Template.bind({});
|
|
163
|
-
WithDeleteFailed.args = {
|
|
164
|
-
...props,
|
|
165
|
-
files: files.slice(0),
|
|
166
|
-
onDeleteFile: async () => createDelayedPromise({ successful: false }),
|
|
167
|
-
multiple: true,
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
export const CustomConfirmMessage: Story<UploadInputProps> = Template.bind({});
|
|
171
|
-
CustomConfirmMessage.args = {
|
|
172
|
-
...props,
|
|
173
|
-
files: files.slice(0),
|
|
174
|
-
deleteConfirm: {
|
|
175
|
-
title: 'Sure you want to remove this invoice?',
|
|
176
|
-
body: (
|
|
177
|
-
<img
|
|
178
|
-
alt="brand logo"
|
|
179
|
-
src="https://wise.com/public-resources/assets/logos/wise/brand_logo.svg"
|
|
180
|
-
/>
|
|
181
|
-
),
|
|
182
|
-
},
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
export const withManualDownloadHandler: Story<UploadInputProps> = Template.bind({});
|
|
186
|
-
withManualDownloadHandler.args = {
|
|
187
|
-
...props,
|
|
188
|
-
files,
|
|
189
|
-
onDownload: action('Manual download handler'),
|
|
190
|
-
};
|
|
191
|
-
|
|
192
|
-
export const withFilesChangeHandler: Story<UploadInputProps> = Template.bind({});
|
|
193
|
-
withFilesChangeHandler.args = {
|
|
194
|
-
...props,
|
|
195
|
-
files,
|
|
196
|
-
onFilesChange: action('Files change handler'),
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
export const withMaxFilesToUploadLimit: Story<UploadInputProps> = Template.bind({});
|
|
200
|
-
withMaxFilesToUploadLimit.args = {
|
|
201
|
-
...props,
|
|
202
|
-
multiple: true,
|
|
203
|
-
maxFiles: 5,
|
|
204
|
-
maxFilesErrorMessage: "Can't upload as maximum number of files allowed are already uploaded",
|
|
205
|
-
};
|
|
206
|
-
|
|
207
|
-
export const withFileSizeErrorMessage: Story<UploadInputProps> = Template.bind({});
|
|
208
|
-
withFileSizeErrorMessage.args = {
|
|
209
|
-
...props,
|
|
210
|
-
sizeLimit: 1,
|
|
211
|
-
sizeLimitErrorMessage: 'The file is oversized',
|
|
212
|
-
};
|
|
213
|
-
|
|
214
|
-
export const withCustomUploadButtonTitle: Story<UploadInputProps> = Template.bind({});
|
|
215
|
-
withCustomUploadButtonTitle.args = {
|
|
216
|
-
...props,
|
|
217
|
-
uploadButtonTitle: 'Upload the VAT receipts for FY 2022-23',
|
|
218
|
-
};
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
import { action } from '@storybook/addon-actions';
|
|
2
|
+
import { StoryFn, Meta } from '@storybook/react';
|
|
3
|
+
|
|
4
|
+
import { Status } from '../common';
|
|
5
|
+
|
|
6
|
+
import UploadInput, { UploadInputProps } from './UploadInput';
|
|
7
|
+
import { UploadedFile, UploadResponse } from './types';
|
|
8
|
+
|
|
9
|
+
const meta: Meta<typeof UploadInput> = {
|
|
10
|
+
title: 'Forms/UploadInput/Tests',
|
|
11
|
+
component: UploadInput,
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default meta;
|
|
15
|
+
type Story = StoryFn<UploadInputProps>;
|
|
16
|
+
|
|
17
|
+
const files = [
|
|
18
|
+
{
|
|
19
|
+
id: 1,
|
|
20
|
+
filename: 'purchase-receipt-0.pdf',
|
|
21
|
+
url: 'https://wise.com/public-resources/assets/logos/wise/brand_logo_inverse.svg',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
id: 2,
|
|
25
|
+
filename: 'purchase-receipt-1.pdf',
|
|
26
|
+
url: 'https://wise.com/public-resources/assets/logos/wise/brand_logo_inverse.svg',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
id: 2,
|
|
30
|
+
filename: 'receipt failed.png',
|
|
31
|
+
status: Status.FAILED,
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: 3,
|
|
35
|
+
filename: 'receipt failed With error string.png',
|
|
36
|
+
status: Status.FAILED,
|
|
37
|
+
error: 'Something went wrong',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: 4,
|
|
41
|
+
filename: 'receipt failed With error object.png',
|
|
42
|
+
status: Status.FAILED,
|
|
43
|
+
error: { message: 'Something went wrong' },
|
|
44
|
+
},
|
|
45
|
+
] satisfies UploadedFile[];
|
|
46
|
+
|
|
47
|
+
const createDelayedPromise = async ({
|
|
48
|
+
successful = true,
|
|
49
|
+
delaySeconds = 3,
|
|
50
|
+
response = { id: Math.round(Math.random() * 10000), url: '#' },
|
|
51
|
+
}: {
|
|
52
|
+
successful?: boolean;
|
|
53
|
+
delaySeconds?: number;
|
|
54
|
+
response?: UploadResponse;
|
|
55
|
+
} = {}): Promise<UploadResponse> =>
|
|
56
|
+
new Promise((resolve, reject) => {
|
|
57
|
+
setTimeout(
|
|
58
|
+
() => (successful ? resolve(response) : reject(new Error('Unexpected error'))),
|
|
59
|
+
delaySeconds * 1000,
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
const props = {
|
|
64
|
+
onUploadFile: async (formData: FormData) => {
|
|
65
|
+
return createDelayedPromise();
|
|
66
|
+
},
|
|
67
|
+
onDeleteFile: async (id: string | number) => {
|
|
68
|
+
return createDelayedPromise();
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
const Template: Story = (args: UploadInputProps) => <UploadInput {...args} />;
|
|
73
|
+
|
|
74
|
+
export const UploadInputWithDescriptionFromProps: Story = Template.bind({});
|
|
75
|
+
UploadInputWithDescriptionFromProps.args = {
|
|
76
|
+
...props,
|
|
77
|
+
multiple: true,
|
|
78
|
+
description: 'Custom file description from prop',
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export const Disabled: Story = Template.bind({});
|
|
82
|
+
Disabled.args = { ...props, disabled: true };
|
|
83
|
+
|
|
84
|
+
export const WithAnyFileType: Story = Template.bind({});
|
|
85
|
+
WithAnyFileType.args = { ...props, fileTypes: '*' };
|
|
86
|
+
|
|
87
|
+
export const WithSingleFileType: Story = Template.bind({});
|
|
88
|
+
WithSingleFileType.args = { ...props, fileTypes: '.zip,application/zip' };
|
|
89
|
+
|
|
90
|
+
export const WithMultipleExistingFiles: Story = Template.bind({});
|
|
91
|
+
WithMultipleExistingFiles.args = {
|
|
92
|
+
...props,
|
|
93
|
+
files,
|
|
94
|
+
multiple: true,
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const WithFileErrors: Story = Template.bind({});
|
|
98
|
+
WithFileErrors.args = {
|
|
99
|
+
...props,
|
|
100
|
+
files: [
|
|
101
|
+
{
|
|
102
|
+
id: 1,
|
|
103
|
+
filename: 'Error with default message.png',
|
|
104
|
+
status: Status.FAILED,
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
id: 2,
|
|
108
|
+
filename: 'Error with `string` error.png',
|
|
109
|
+
status: Status.FAILED,
|
|
110
|
+
error: 'Single string error',
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
id: 3,
|
|
114
|
+
filename: 'Error with `obj` error ({ message : `string` }).png',
|
|
115
|
+
status: Status.FAILED,
|
|
116
|
+
error: { message: 'Single obj error' },
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
id: 4,
|
|
120
|
+
filename: 'Error with single error passed in `array`.png',
|
|
121
|
+
status: Status.FAILED,
|
|
122
|
+
errors: ['Single error in array'],
|
|
123
|
+
},
|
|
124
|
+
{
|
|
125
|
+
id: 5,
|
|
126
|
+
filename: 'Error with multiple `string` errors passed in `array`.png',
|
|
127
|
+
status: Status.FAILED,
|
|
128
|
+
errors: ['Error 1', 'Error 2', 'Error 3'],
|
|
129
|
+
},
|
|
130
|
+
{
|
|
131
|
+
id: 6,
|
|
132
|
+
filename: 'Error with multiple `obj` errors passed in `array`.png',
|
|
133
|
+
status: Status.FAILED,
|
|
134
|
+
errors: [{ message: 'Error 1' }, { message: 'Error 2' }, { message: 'Error 3' }],
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
multiple: true,
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const WithoutDelete: Story = Template.bind({});
|
|
141
|
+
WithoutDelete.args = {
|
|
142
|
+
...props,
|
|
143
|
+
files,
|
|
144
|
+
onDeleteFile: undefined,
|
|
145
|
+
multiple: true,
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
export const WithUploadFailed: Story = Template.bind({});
|
|
149
|
+
WithUploadFailed.args = {
|
|
150
|
+
...props,
|
|
151
|
+
files: files.slice(0),
|
|
152
|
+
onUploadFile: async () => createDelayedPromise({ successful: false }),
|
|
153
|
+
multiple: true,
|
|
154
|
+
};
|
|
155
|
+
|
|
156
|
+
export const WithDeleteFailed: Story = Template.bind({});
|
|
157
|
+
WithDeleteFailed.args = {
|
|
158
|
+
...props,
|
|
159
|
+
files: files.slice(0),
|
|
160
|
+
onDeleteFile: async () => createDelayedPromise({ successful: false }),
|
|
161
|
+
multiple: true,
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
export const CustomConfirmMessage: Story = Template.bind({});
|
|
165
|
+
CustomConfirmMessage.args = {
|
|
166
|
+
...props,
|
|
167
|
+
files: files.slice(0),
|
|
168
|
+
deleteConfirm: {
|
|
169
|
+
title: 'Sure you want to remove this invoice?',
|
|
170
|
+
body: (
|
|
171
|
+
<img
|
|
172
|
+
alt="brand logo"
|
|
173
|
+
src="https://wise.com/public-resources/assets/logos/wise/brand_logo.svg"
|
|
174
|
+
/>
|
|
175
|
+
),
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
export const WithManualDownloadHandler: Story = Template.bind({});
|
|
180
|
+
WithManualDownloadHandler.args = {
|
|
181
|
+
...props,
|
|
182
|
+
files,
|
|
183
|
+
onDownload: action('Manual download handler'),
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
export const WithFilesChangeHandler: Story = Template.bind({});
|
|
187
|
+
WithFilesChangeHandler.args = {
|
|
188
|
+
...props,
|
|
189
|
+
files,
|
|
190
|
+
onFilesChange: action('Files change handler'),
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
export const WithMaxFilesToUploadLimit: Story = Template.bind({});
|
|
194
|
+
WithMaxFilesToUploadLimit.args = {
|
|
195
|
+
...props,
|
|
196
|
+
multiple: true,
|
|
197
|
+
maxFiles: 5,
|
|
198
|
+
maxFilesErrorMessage: "Can't upload as maximum number of files allowed are already uploaded",
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
export const WithFileSizeErrorMessage: Story = Template.bind({});
|
|
202
|
+
WithFileSizeErrorMessage.args = {
|
|
203
|
+
...props,
|
|
204
|
+
sizeLimit: 1,
|
|
205
|
+
sizeLimitErrorMessage: 'The file is oversized',
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
export const WithCustomUploadButtonTitle: Story = Template.bind({});
|
|
209
|
+
WithCustomUploadButtonTitle.args = {
|
|
210
|
+
...props,
|
|
211
|
+
uploadButtonTitle: 'Upload the VAT receipts for FY 2022-23',
|
|
212
|
+
};
|
|
@@ -35,9 +35,9 @@ describe('UploadButton', () => {
|
|
|
35
35
|
);
|
|
36
36
|
});
|
|
37
37
|
|
|
38
|
-
it('trigger onChange callback with a FileList', () => {
|
|
38
|
+
it('trigger onChange callback with a FileList', async () => {
|
|
39
39
|
const input = screen.getByTestId(TEST_IDS.uploadInput);
|
|
40
|
-
userEvent.upload(input, [pngFile, jpgFile]);
|
|
40
|
+
await userEvent.upload(input, [pngFile, jpgFile]);
|
|
41
41
|
|
|
42
42
|
expect(props.onChange).toHaveBeenCalledTimes(1);
|
|
43
43
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
@@ -55,9 +55,9 @@ describe('UploadButton', () => {
|
|
|
55
55
|
expect(screen.getByTestId(TEST_IDS.uploadInput)).toHaveAttribute('multiple');
|
|
56
56
|
});
|
|
57
57
|
|
|
58
|
-
it('trigger onChange callback with a FileList', () => {
|
|
58
|
+
it('trigger onChange callback with a FileList', async () => {
|
|
59
59
|
const input = screen.getByTestId(TEST_IDS.uploadInput);
|
|
60
|
-
userEvent.upload(input, [pngFile, jpgFile]);
|
|
60
|
+
await userEvent.upload(input, [pngFile, jpgFile]);
|
|
61
61
|
|
|
62
62
|
expect(props.onChange).toHaveBeenCalledTimes(1);
|
|
63
63
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import userEvent from '@testing-library/user-event';
|
|
1
|
+
import { userEvent } from '@testing-library/user-event';
|
|
2
2
|
|
|
3
3
|
import { Status } from '../../common';
|
|
4
4
|
import { render, screen } from '../../test-utils';
|
|
5
5
|
|
|
6
|
-
import UploadItem, { UploadItemProps
|
|
6
|
+
import UploadItem, { UploadItemProps } from './UploadItem';
|
|
7
7
|
|
|
8
8
|
describe('UploadItem', () => {
|
|
9
9
|
const props: UploadItemProps = {
|
|
@@ -111,10 +111,10 @@ describe('UploadItem', () => {
|
|
|
111
111
|
});
|
|
112
112
|
|
|
113
113
|
describe('manual file download handler', () => {
|
|
114
|
-
it('calls onDownload handler provided through props', () => {
|
|
114
|
+
it('calls onDownload handler provided through props', async () => {
|
|
115
115
|
const onDownload = jest.fn();
|
|
116
116
|
renderComponent({ ...props, onDownload });
|
|
117
|
-
userEvent.click(screen.getAllByRole('link')[0]);
|
|
117
|
+
await userEvent.click(screen.getAllByRole('link')[0]);
|
|
118
118
|
expect(onDownload).toHaveBeenCalledTimes(1);
|
|
119
119
|
expect(onDownload).toHaveBeenCalledWith(props.file);
|
|
120
120
|
});
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import { ArrowLeft as ArrowLeftIcon } from '@transferwise/icons';
|
|
2
|
-
import classNames from 'classnames';
|
|
3
|
-
import PropTypes from 'prop-types';
|
|
4
|
-
|
|
5
|
-
import Avatar, { AvatarType } from '../../avatar';
|
|
6
|
-
|
|
7
|
-
const BackButton = ({ className, onClick, 'aria-label': ariaLabel }) => (
|
|
8
|
-
<Avatar type={AvatarType.ICON} size={40}>
|
|
9
|
-
<button
|
|
10
|
-
type="button"
|
|
11
|
-
aria-label={ariaLabel}
|
|
12
|
-
className={classNames('np-back-button', 'btn-unstyled', className)}
|
|
13
|
-
onClick={onClick}
|
|
14
|
-
>
|
|
15
|
-
<ArrowLeftIcon size={24} />
|
|
16
|
-
</button>
|
|
17
|
-
</Avatar>
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
BackButton.propTypes = {
|
|
21
|
-
'aria-label': PropTypes.string.isRequired,
|
|
22
|
-
className: PropTypes.string,
|
|
23
|
-
label: PropTypes.element,
|
|
24
|
-
onClick: PropTypes.func,
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
BackButton.defaultProps = {
|
|
28
|
-
className: undefined,
|
|
29
|
-
label: undefined,
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
export default BackButton;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { render } from '../../test-utils';
|
|
2
|
-
import messages from '../FlowNavigation.messages';
|
|
3
|
-
|
|
4
|
-
import BackButton from '.';
|
|
5
|
-
|
|
6
|
-
const props = {
|
|
7
|
-
label: <>label</>,
|
|
8
|
-
className: 'className',
|
|
9
|
-
onClick: jest.fn(),
|
|
10
|
-
'aria-label': messages.back.defaultMessage,
|
|
11
|
-
};
|
|
12
|
-
describe('BackButton', () => {
|
|
13
|
-
it(`renders as expected`, () => {
|
|
14
|
-
expect(render(<BackButton {...props} />).container).toMatchSnapshot();
|
|
15
|
-
});
|
|
16
|
-
});
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
|
2
|
-
|
|
3
|
-
exports[`BackButton renders as expected 1`] = `
|
|
4
|
-
<div>
|
|
5
|
-
<div
|
|
6
|
-
class="tw-avatar tw-avatar--40 tw-avatar--icon"
|
|
7
|
-
>
|
|
8
|
-
<div
|
|
9
|
-
class="tw-avatar__content"
|
|
10
|
-
>
|
|
11
|
-
<button
|
|
12
|
-
class="np-back-button btn-unstyled className"
|
|
13
|
-
type="button"
|
|
14
|
-
>
|
|
15
|
-
<span
|
|
16
|
-
aria-hidden="true"
|
|
17
|
-
class="tw-icon tw-icon-arrow-left "
|
|
18
|
-
data-testid="arrow-left-icon"
|
|
19
|
-
role="presentation"
|
|
20
|
-
>
|
|
21
|
-
<svg
|
|
22
|
-
fill="currentColor"
|
|
23
|
-
focusable="false"
|
|
24
|
-
height="24"
|
|
25
|
-
viewBox="0 0 24 24"
|
|
26
|
-
width="24"
|
|
27
|
-
>
|
|
28
|
-
<path
|
|
29
|
-
d="M22.286 11.316H4.629l7.114-7.114-1.2-1.2-8.572 8.571a.829.829 0 0 0 0 1.2l8.572 8.572 1.2-1.2-7.114-7.114h17.657v-1.715Z"
|
|
30
|
-
/>
|
|
31
|
-
</svg>
|
|
32
|
-
</span>
|
|
33
|
-
</button>
|
|
34
|
-
</div>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
`;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default } from './OverlayHeader';
|
/package/src/overlayHeader/__snapshots__/{OverlayHeader.spec.js.snap → OverlayHeader.spec.tsx.snap}
RENAMED
|
File without changes
|