@transferwise/components 0.0.0-experimental-faee41b → 0.0.0-experimental-96d193a

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 (112) hide show
  1. package/build/alert/Alert.js +3 -1
  2. package/build/alert/Alert.js.map +1 -1
  3. package/build/alert/Alert.mjs +3 -1
  4. package/build/alert/Alert.mjs.map +1 -1
  5. package/build/dimmer/Dimmer.js +1 -3
  6. package/build/dimmer/Dimmer.js.map +1 -1
  7. package/build/dimmer/Dimmer.mjs +1 -3
  8. package/build/dimmer/Dimmer.mjs.map +1 -1
  9. package/build/drawer/Drawer.js +0 -2
  10. package/build/drawer/Drawer.js.map +1 -1
  11. package/build/drawer/Drawer.mjs +0 -2
  12. package/build/drawer/Drawer.mjs.map +1 -1
  13. package/build/field/Field.js +2 -0
  14. package/build/field/Field.js.map +1 -1
  15. package/build/field/Field.mjs +2 -0
  16. package/build/field/Field.mjs.map +1 -1
  17. package/build/i18n/en.json +5 -0
  18. package/build/i18n/en.json.js +5 -0
  19. package/build/i18n/en.json.js.map +1 -1
  20. package/build/i18n/en.json.mjs +5 -0
  21. package/build/i18n/en.json.mjs.map +1 -1
  22. package/build/inlineAlert/InlineAlert.js +3 -1
  23. package/build/inlineAlert/InlineAlert.js.map +1 -1
  24. package/build/inlineAlert/InlineAlert.mjs +3 -1
  25. package/build/inlineAlert/InlineAlert.mjs.map +1 -1
  26. package/build/modal/Modal.js +0 -3
  27. package/build/modal/Modal.js.map +1 -1
  28. package/build/modal/Modal.mjs +0 -3
  29. package/build/modal/Modal.mjs.map +1 -1
  30. package/build/statusIcon/StatusIcon.js +50 -16
  31. package/build/statusIcon/StatusIcon.js.map +1 -1
  32. package/build/statusIcon/StatusIcon.messages.js +24 -0
  33. package/build/statusIcon/StatusIcon.messages.js.map +1 -0
  34. package/build/statusIcon/StatusIcon.messages.mjs +22 -0
  35. package/build/statusIcon/StatusIcon.messages.mjs.map +1 -0
  36. package/build/statusIcon/StatusIcon.mjs +48 -14
  37. package/build/statusIcon/StatusIcon.mjs.map +1 -1
  38. package/build/types/alert/Alert.d.ts +6 -1
  39. package/build/types/alert/Alert.d.ts.map +1 -1
  40. package/build/types/dimmer/Dimmer.d.ts +1 -2
  41. package/build/types/dimmer/Dimmer.d.ts.map +1 -1
  42. package/build/types/drawer/Drawer.d.ts +1 -2
  43. package/build/types/drawer/Drawer.d.ts.map +1 -1
  44. package/build/types/field/Field.d.ts +6 -1
  45. package/build/types/field/Field.d.ts.map +1 -1
  46. package/build/types/inlineAlert/InlineAlert.d.ts +2 -1
  47. package/build/types/inlineAlert/InlineAlert.d.ts.map +1 -1
  48. package/build/types/modal/Modal.d.ts +1 -2
  49. package/build/types/modal/Modal.d.ts.map +1 -1
  50. package/build/types/statusIcon/StatusIcon.d.ts +6 -1
  51. package/build/types/statusIcon/StatusIcon.d.ts.map +1 -1
  52. package/build/types/statusIcon/StatusIcon.messages.d.ts +29 -0
  53. package/build/types/statusIcon/StatusIcon.messages.d.ts.map +1 -0
  54. package/build/types/upload/Upload.d.ts +5 -0
  55. package/build/types/upload/Upload.d.ts.map +1 -1
  56. package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts +1 -0
  57. package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts.map +1 -1
  58. package/build/types/uploadInput/UploadInput.d.ts +0 -9
  59. package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
  60. package/build/types/uploadInput/uploadItem/UploadItem.d.ts +1 -16
  61. package/build/types/uploadInput/uploadItem/UploadItem.d.ts.map +1 -1
  62. package/build/types/uploadInput/uploadItem/UploadItemLink.d.ts.map +1 -1
  63. package/build/upload/Upload.js +4 -2
  64. package/build/upload/Upload.js.map +1 -1
  65. package/build/upload/Upload.mjs +4 -2
  66. package/build/upload/Upload.mjs.map +1 -1
  67. package/build/upload/steps/uploadImageStep/uploadImageStep.js +4 -2
  68. package/build/upload/steps/uploadImageStep/uploadImageStep.js.map +1 -1
  69. package/build/upload/steps/uploadImageStep/uploadImageStep.mjs +4 -2
  70. package/build/upload/steps/uploadImageStep/uploadImageStep.mjs.map +1 -1
  71. package/build/uploadInput/UploadInput.js +66 -71
  72. package/build/uploadInput/UploadInput.js.map +1 -1
  73. package/build/uploadInput/UploadInput.mjs +67 -72
  74. package/build/uploadInput/UploadInput.mjs.map +1 -1
  75. package/build/uploadInput/uploadItem/UploadItem.js +4 -13
  76. package/build/uploadInput/uploadItem/UploadItem.js.map +1 -1
  77. package/build/uploadInput/uploadItem/UploadItem.mjs +4 -13
  78. package/build/uploadInput/uploadItem/UploadItem.mjs.map +1 -1
  79. package/build/uploadInput/uploadItem/UploadItemLink.js +0 -1
  80. package/build/uploadInput/uploadItem/UploadItemLink.js.map +1 -1
  81. package/build/uploadInput/uploadItem/UploadItemLink.mjs +0 -1
  82. package/build/uploadInput/uploadItem/UploadItemLink.mjs.map +1 -1
  83. package/package.json +3 -3
  84. package/src/alert/Alert.spec.tsx +10 -0
  85. package/src/alert/Alert.tsx +7 -1
  86. package/src/dimmer/Dimmer.spec.js +0 -8
  87. package/src/dimmer/Dimmer.tsx +0 -4
  88. package/src/drawer/Drawer.spec.js +6 -25
  89. package/src/drawer/Drawer.tsx +1 -3
  90. package/src/field/Field.spec.tsx +19 -0
  91. package/src/field/Field.story.tsx +20 -4
  92. package/src/field/Field.tsx +7 -1
  93. package/src/i18n/en.json +5 -0
  94. package/src/inlineAlert/InlineAlert.spec.tsx +12 -1
  95. package/src/inlineAlert/InlineAlert.tsx +5 -1
  96. package/src/modal/Modal.spec.js +1 -19
  97. package/src/modal/Modal.tsx +0 -4
  98. package/src/statusIcon/StatusIcon.docs.mdx +22 -0
  99. package/src/statusIcon/StatusIcon.messages.ts +34 -0
  100. package/src/statusIcon/StatusIcon.spec.tsx +31 -4
  101. package/src/statusIcon/StatusIcon.story.tsx +2 -5
  102. package/src/statusIcon/StatusIcon.tsx +59 -14
  103. package/src/upload/Upload.spec.js +19 -0
  104. package/src/upload/Upload.tsx +7 -0
  105. package/src/upload/steps/uploadImageStep/uploadImageStep.spec.js +13 -0
  106. package/src/upload/steps/uploadImageStep/uploadImageStep.tsx +14 -3
  107. package/src/uploadInput/UploadInput.spec.tsx +9 -121
  108. package/src/uploadInput/UploadInput.tests.story.tsx +140 -209
  109. package/src/uploadInput/UploadInput.tsx +77 -110
  110. package/src/uploadInput/uploadItem/UploadItem.spec.tsx +0 -1
  111. package/src/uploadInput/uploadItem/UploadItem.tsx +6 -30
  112. package/src/uploadInput/uploadItem/UploadItemLink.tsx +1 -9
@@ -1,5 +1,5 @@
1
1
  import { clsx } from 'clsx';
2
- import { useState, useRef, useEffect } from 'react';
2
+ import { useState, useRef, useLayoutEffect, useEffect } from 'react';
3
3
  import { useIntl } from 'react-intl';
4
4
  import Button from '../button/Button.mjs';
5
5
  import { useInputAttributes } from '../inputs/contexts.mjs';
@@ -22,15 +22,6 @@ function generateFileId(file) {
22
22
  const uploadTimeStamp = new Date().getTime();
23
23
  return `${name}_${size}_${uploadTimeStamp}`;
24
24
  }
25
- /**
26
- * The component allows users to upload files, manage the list of uploaded files,
27
- * and handle file validation and deletion.
28
- *
29
- * @param {UploadInputProps} props - The properties for the UploadInput component.
30
- *
31
- * @see {@link UploadInput} for further information.
32
- * @see {@link https://storybook.wise.design/?path=/docs/forms-uploadinput--docs|Storybook Wise Design}
33
- */
34
25
  const UploadInput = ({
35
26
  files = [],
36
27
  fileInputName = 'file',
@@ -56,53 +47,64 @@ const UploadInput = ({
56
47
  nonLabelable: true
57
48
  });
58
49
  const [markedFileForDelete, setMarkedFileForDelete] = useState(null);
50
+ const [fileToRemoveIndex, setFileToRemoveIndex] = useState(null);
59
51
  const [mounted, setMounted] = useState(false);
60
52
  const {
61
53
  formatMessage
62
54
  } = useIntl();
55
+ const itemRefs = useRef([]);
63
56
  const uploadInputRef = useRef(null);
64
- let fileRefs = [];
65
57
  const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);
66
58
  const [uploadedFiles, setUploadedFiles] = useState(multiple || files.length === 0 ? files : [files[0]]);
67
59
  const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);
68
- function updateFileList(updateFn) {
69
- setUploadedFiles(updateFn);
70
- uploadedFilesListReference.current = updateFn(uploadedFilesListReference.current);
71
- }
72
60
  function addFileToList(recentUploadedFile) {
73
- updateFileList(list => [...list, recentUploadedFile]);
74
- }
75
- function removeFileFromList(file) {
76
- updateFileList(list => list.filter(fileInList => file !== fileInList && file.id !== fileInList.id));
77
- fileRefs = fileRefs.filter(ref => ref && ref.id !== file.id);
78
- }
79
- function modifyFileInList(file, updates) {
80
- updateFileList(list => list.map(fileInList => fileInList === file || fileInList.id === file.id ? {
81
- ...file,
82
- ...updates
83
- } : fileInList));
61
+ function addToList(listToAddTo) {
62
+ return [...listToAddTo, recentUploadedFile];
63
+ }
64
+ setUploadedFiles(addToList);
65
+ uploadedFilesListReference.current = addToList(uploadedFilesListReference.current);
84
66
  }
85
- const removeFile = async file => {
67
+ const removeFileFromList = file => {
68
+ function filterOutFrom(listToFilterFrom) {
69
+ return listToFilterFrom.filter(fileInList => file !== fileInList && file.id !== fileInList.id);
70
+ }
71
+ setUploadedFiles(filterOutFrom);
72
+ uploadedFilesListReference.current = filterOutFrom(uploadedFilesListReference.current);
73
+ };
74
+ const modifyFileInList = (file, updates) => {
75
+ const updateListItem = listToUpdate => listToUpdate.map(fileInList => {
76
+ return fileInList === file || fileInList.id === file.id ? {
77
+ ...file,
78
+ ...updates
79
+ } : fileInList;
80
+ });
81
+ setUploadedFiles(updateListItem);
82
+ uploadedFilesListReference.current = updateListItem(uploadedFilesListReference.current);
83
+ };
84
+ const [fileToRemove, setFileToRemove] = useState(null);
85
+ const removeFile = file => {
86
86
  const {
87
87
  id,
88
88
  status
89
89
  } = file;
90
- fileRefs = fileRefs.filter(item => item && item.id !== file.id);
90
+ const index = uploadedFiles.findIndex(f => f.id === file.id);
91
+ setFileToRemoveIndex(index);
91
92
  if (status === Status.FAILED) {
92
93
  removeFileFromList(file);
93
- return Promise.resolve();
94
- }
95
- if (onDeleteFile && id) {
94
+ setFileToRemove(file);
95
+ } else if (onDeleteFile && id) {
96
96
  modifyFileInList(file, {
97
97
  status: Status.PROCESSING,
98
98
  error: undefined
99
99
  });
100
- return onDeleteFile(id).then(() => {
100
+ onDeleteFile(id).then(() => {
101
101
  removeFileFromList(file);
102
102
  }).catch(error => {
103
103
  modifyFileInList(file, {
104
104
  error: error
105
105
  });
106
+ }).finally(() => {
107
+ setFileToRemove(file);
106
108
  });
107
109
  }
108
110
  };
@@ -110,8 +112,9 @@ const UploadInput = ({
110
112
  const {
111
113
  name
112
114
  } = file;
115
+ const id = generateFileId(file);
113
116
  const failedUpload = {
114
- id: generateFileId(file),
117
+ id,
115
118
  filename: name,
116
119
  status: Status.FAILED,
117
120
  error: failureMessage
@@ -133,16 +136,22 @@ const UploadInput = ({
133
136
  const numberOfValidFiles = getNumberOfFilesUploaded();
134
137
  return numberOfValidFiles >= maxFiles;
135
138
  }
139
+ // One or more files selected, create entries for them
136
140
  const addFiles = selectedFiles => {
137
141
  for (let i = 0; i < selectedFiles.length; i += 1) {
138
142
  const file = selectedFiles.item(i);
143
+ // Returning a FormData[] array instead of FileList so we can filter out incorrect files
139
144
  const formData = new FormData();
140
145
  if (file) {
146
+ generateFileId(file);
141
147
  const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');
148
+ // Check if file type is valid
142
149
  if (!isTypeValid(file, allowedFileTypes)) {
143
150
  handleFileUploadFailure(file, formatMessage(MESSAGES.fileTypeNotSupported));
144
151
  continue;
145
152
  }
153
+ // Check if the filesize is valid
154
+ // Convert to rough bytes
146
155
  if (!isSizeValid(file, sizeLimit * 1000)) {
147
156
  const failureMessage = sizeLimitErrorMessage || formatMessage(MESSAGES.fileIsTooLarge);
148
157
  handleFileUploadFailure(file, failureMessage);
@@ -155,10 +164,13 @@ const UploadInput = ({
155
164
  handleFileUploadFailure(file, failureMessage);
156
165
  continue;
157
166
  }
167
+ // Check if the file is already in the list
158
168
  const existingFile = uploadedFiles.find(f => f.filename === file.name);
159
169
  if (existingFile) {
170
+ // Remove the file from the list before adding it again
160
171
  removeFileFromList(existingFile);
161
172
  }
173
+ // Add the file to the list
162
174
  formData.append(fileInputName, file);
163
175
  const pendingFile = {
164
176
  id: generateFileId(file),
@@ -166,11 +178,13 @@ const UploadInput = ({
166
178
  status: Status.PENDING
167
179
  };
168
180
  addFileToList(pendingFile);
181
+ // Start uploading the file
169
182
  onUploadFile(formData).then(({
170
183
  id,
171
184
  url,
172
185
  error
173
186
  }) => {
187
+ // Replace the temporary id with the final one received from the API, and also set any errors
174
188
  modifyFileInList(pendingFile, {
175
189
  id,
176
190
  url,
@@ -184,11 +198,27 @@ const UploadInput = ({
184
198
  });
185
199
  });
186
200
  if (!multiple) {
201
+ // Only upload a single file
187
202
  break;
188
203
  }
189
204
  }
190
205
  }
191
206
  };
207
+ useLayoutEffect(() => {
208
+ if (fileToRemove && fileToRemoveIndex !== null) {
209
+ requestAnimationFrame(() => {
210
+ const nextFocusIndex = Math.min(fileToRemoveIndex, uploadedFiles.length - 1);
211
+ if (itemRefs.current[nextFocusIndex]) {
212
+ itemRefs.current[nextFocusIndex].focus(); // Focus the next UploadItem
213
+ } else {
214
+ // If there's only one item left, focus the UploadButton
215
+ uploadInputRef.current?.focus();
216
+ }
217
+ });
218
+ setFileToRemove(null); // Reset the state
219
+ setFileToRemoveIndex(null); // Reset the index
220
+ }
221
+ }, [uploadedFiles, fileToRemove, fileToRemoveIndex, itemRefs, uploadInputRef]);
192
222
  useEffect(() => {
193
223
  setMounted(true);
194
224
  }, []);
@@ -197,33 +227,6 @@ const UploadInput = ({
197
227
  onFilesChange([...uploadedFiles]);
198
228
  }
199
229
  }, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps
200
- const [nextFocusable, setNextFocusable] = useState(uploadInputRef.current);
201
- const handleFocus = fileId => {
202
- fileRefs = fileRefs.filter(ref => {
203
- return ref && ref.id !== markedFileForDelete?.id;
204
- });
205
- const filesCount = fileRefs.length;
206
- let next = uploadInputRef.current;
207
- if (filesCount > 1) {
208
- const currentFileIndex = fileRefs.findIndex(file => file?.id === fileId);
209
- const currentFileId = fileRefs?.[currentFileIndex]?.id;
210
- const lastFileId = fileRefs?.[filesCount - 1]?.id;
211
- // if last file, select a previous one
212
- if (currentFileId === lastFileId) {
213
- next = fileRefs[filesCount - 2];
214
- } else {
215
- next = fileRefs[currentFileIndex + 1];
216
- }
217
- }
218
- setNextFocusable(next);
219
- };
220
- const handleRefocus = () => {
221
- if (nextFocusable && 'focus' in nextFocusable && typeof nextFocusable.focus === 'function') {
222
- setTimeout(() => {
223
- nextFocusable.focus();
224
- }, 0);
225
- }
226
- };
227
230
  return /*#__PURE__*/jsxs(Fragment, {
228
231
  children: [/*#__PURE__*/jsxs("div", {
229
232
  role: "group",
@@ -238,19 +241,13 @@ const UploadInput = ({
238
241
  role: "region",
239
242
  children: uploadedFiles.map((file, index) => /*#__PURE__*/jsx(UploadItem, {
240
243
  ref: el => {
241
- if (el && el.id !== markedFileForDelete?.id && !fileRefs.some(ref => ref && ref.id === el.id) && el.status !== 'processing') {
242
- fileRefs.push(el);
243
- }
244
+ itemRefs.current[index] = el;
244
245
  },
245
246
  file: file,
246
247
  singleFileUpload: !multiple,
247
248
  canDelete: (!!onDeleteFile || file.status === Status.FAILED) && (!file.status || !PROGRESS_STATUSES.has(file.status)),
248
- onDelete: file.status === Status.FAILED ? async () => {
249
- await removeFile(file);
250
- handleRefocus();
251
- } : () => setMarkedFileForDelete(file),
252
- onDownload: onDownload,
253
- onFocus: () => handleFocus(file.id)
249
+ onDelete: file.status === Status.FAILED ? () => removeFile(file) : () => setMarkedFileForDelete(file),
250
+ onDownload: onDownload
254
251
  }, file.id))
255
252
  }), (multiple || !multiple && !uploadedFiles.length) && /*#__PURE__*/jsx("div", {
256
253
  className: "np-upload-input__section np-upload-input__section--uploader",
@@ -283,17 +280,15 @@ const UploadInput = ({
283
280
  block: true,
284
281
  priority: Priority.SECONDARY,
285
282
  type: ControlType.NEGATIVE,
286
- tabIndex: markedFileForDelete ? 0 : -1,
287
283
  onClick: () => {
288
284
  if (markedFileForDelete) {
289
- void removeFile(markedFileForDelete);
285
+ removeFile(markedFileForDelete);
290
286
  }
291
287
  setMarkedFileForDelete(null);
292
288
  },
293
289
  children: deleteConfirm?.confirmText || formatMessage(MESSAGES.deleteModalConfirmButtonText)
294
290
  })]
295
291
  }),
296
- onUnmount: handleRefocus,
297
292
  onClose: () => {
298
293
  setMarkedFileForDelete(null);
299
294
  }
@@ -1 +1 @@
1
- {"version":3,"file":"UploadInput.mjs","sources":["../../src/uploadInput/UploadInput.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useEffect, useRef, useState } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Button from '../button';\nimport { CommonProps, ControlType, Priority, Status } from '../common';\nimport { useInputAttributes } from '../inputs/contexts';\nimport Modal from '../modal';\nimport { isSizeValid } from '../upload/utils/isSizeValid';\nimport { isTypeValid } from '../upload/utils/isTypeValid';\n\nimport MESSAGES from './UploadInput.messages';\nimport { UploadedFile, UploadError, UploadResponse } from './types';\nimport UploadButton, { UploadButtonProps } from './uploadButton/UploadButton';\nimport { DEFAULT_SIZE_LIMIT, imageFileTypes } from './uploadButton/defaults';\nimport UploadItem, { UploadItemProps } from './uploadItem/UploadItem';\n\nexport type UploadInputProps = {\n /**\n * List of already existing, failed or in progress files\n */\n files?: readonly UploadedFile[];\n\n /**\n * The key of the file in the returned FormData object (default: file)\n */\n fileInputName?: string;\n\n /**\n * Callback that handles form submission\n *\n * @param formData\n */\n onUploadFile: (formData: FormData) => Promise<UploadResponse>;\n\n /**\n * Provide a callback if the file can be removed/deleted from the server\n * Your app is responsible for reloading the uploaded files list and updating the component to ensure that the file has in fact been deleted successfully\n *\n * @param id\n */\n onDeleteFile?: (id: string | number) => Promise<any>;\n\n /**\n * Provide a callback to trigger on validation error\n *\n * @param file\n */\n onValidationError?: (file: UploadedFile) => void;\n\n /**\n * Provide a callback to trigger on change whenever the files are updated\n *\n * @param files\n */\n onFilesChange?: (files: UploadedFile[]) => void;\n\n /**\n * Confirmation modal displayed on delete\n */\n deleteConfirm?: {\n /**\n * The title of the confirmation modal on delete\n */\n title?: string;\n\n /**\n * The body of the confirmation modal on delete\n */\n body?: React.ReactNode;\n\n /**\n * The confirm button text of the confirmation modal on delete\n */\n confirmText?: string;\n\n /**\n * The cancel button text of the confirmation modal on delete\n */\n cancelText?: string;\n };\n\n /**\n * Maximum number of files allowed, if provided, shows error below file item\n */\n maxFiles?: number;\n\n /**\n * Error message to show when the maximum number of files are uploaded already\n */\n maxFilesErrorMessage?: string;\n\n /**\n * Error message to show when files over a allowed size limit are uploaded\n */\n sizeLimitErrorMessage?: string;\n} & Pick<\n UploadButtonProps,\n 'disabled' | 'multiple' | 'fileTypes' | 'sizeLimit' | 'description' | 'id' | 'uploadButtonTitle'\n> & { onDownload?: UploadItemProps['onDownload'] } & CommonProps;\n\n/**\n * Interface representing a reference to an UploadItem component.\n * Provides a method to focus the UploadItem.\n */\ninterface UploadItemRef {\n /**\n * Focuses the UploadItem component.\n */\n focus: () => void;\n\n /**\n * Required id of the UploadItem component.\n */\n id: string | number;\n\n /**\n * Optional status of the UploadItem component.\n */\n status?: string;\n}\n\n/**\n * Generates a unique ID for a file based on its name, size, and the current timestamp\n */\nfunction generateFileId(file: File) {\n const { name, size } = file;\n const uploadTimeStamp = new Date().getTime();\n return `${name}_${size}_${uploadTimeStamp}`;\n}\n\n/**\n * The component allows users to upload files, manage the list of uploaded files,\n * and handle file validation and deletion.\n *\n * @param {UploadInputProps} props - The properties for the UploadInput component.\n *\n * @see {@link UploadInput} for further information.\n * @see {@link https://storybook.wise.design/?path=/docs/forms-uploadinput--docs|Storybook Wise Design}\n */\nconst UploadInput = ({\n files = [],\n fileInputName = 'file',\n className,\n deleteConfirm,\n disabled,\n multiple = false,\n fileTypes = imageFileTypes,\n sizeLimit = DEFAULT_SIZE_LIMIT,\n description,\n onUploadFile,\n onDeleteFile,\n onValidationError,\n onFilesChange,\n onDownload,\n maxFiles,\n maxFilesErrorMessage,\n id,\n sizeLimitErrorMessage,\n uploadButtonTitle,\n}: UploadInputProps) => {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n const [markedFileForDelete, setMarkedFileForDelete] = useState<UploadedFile | null>(null);\n const [mounted, setMounted] = useState(false);\n const { formatMessage } = useIntl();\n const uploadInputRef = useRef<HTMLInputElement | null>(null);\n let fileRefs: (HTMLDivElement | UploadItemRef | null)[] = [];\n\n const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);\n\n const [uploadedFiles, setUploadedFiles] = useState<readonly UploadedFile[]>(\n multiple || files.length === 0 ? files : [files[0]],\n );\n\n const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);\n\n function updateFileList(updateFn: (list: readonly UploadedFile[]) => readonly UploadedFile[]) {\n setUploadedFiles(updateFn);\n uploadedFilesListReference.current = updateFn(uploadedFilesListReference.current);\n }\n\n function addFileToList(recentUploadedFile: UploadedFile) {\n updateFileList((list) => [...list, recentUploadedFile]);\n }\n\n function removeFileFromList(file: UploadedFile) {\n updateFileList((list) =>\n list.filter((fileInList) => file !== fileInList && file.id !== fileInList.id),\n );\n fileRefs = fileRefs.filter((ref) => ref && ref.id !== file.id);\n }\n\n function modifyFileInList(file: UploadedFile, updates: Partial<UploadedFile>) {\n updateFileList((list) =>\n list.map((fileInList) =>\n fileInList === file || fileInList.id === file.id ? { ...file, ...updates } : fileInList,\n ),\n );\n }\n\n const removeFile = async (file: UploadedFile) => {\n const { id, status } = file;\n fileRefs = fileRefs.filter((item) => item && item.id !== file.id);\n\n if (status === Status.FAILED) {\n removeFileFromList(file);\n return Promise.resolve();\n }\n\n if (onDeleteFile && id) {\n modifyFileInList(file, { status: Status.PROCESSING, error: undefined });\n\n return onDeleteFile(id)\n .then(() => {\n removeFileFromList(file);\n })\n .catch((error) => {\n modifyFileInList(file, { error: error as UploadError });\n });\n }\n };\n\n function handleFileUploadFailure(file: File, failureMessage: string) {\n const { name } = file;\n\n const failedUpload = {\n id: generateFileId(file),\n filename: name,\n status: Status.FAILED,\n error: failureMessage,\n };\n\n addFileToList(failedUpload);\n\n if (onValidationError) {\n onValidationError(failedUpload);\n }\n }\n\n function getNumberOfFilesUploaded() {\n const uploadInitiatedStatus = new Set([Status.SUCCEEDED, Status.PENDING]);\n const validFiles = uploadedFilesListReference.current.filter(\n (file) => file.status && uploadInitiatedStatus.has(file.status),\n );\n return validFiles.length;\n }\n\n function areMaximumFilesUploadedAlready() {\n if (!maxFiles) {\n return false;\n }\n\n const numberOfValidFiles = getNumberOfFilesUploaded();\n return numberOfValidFiles >= maxFiles;\n }\n\n const addFiles = (selectedFiles: FileList) => {\n for (let i = 0; i < selectedFiles.length; i += 1) {\n const file = selectedFiles.item(i);\n\n const formData = new FormData();\n\n if (file) {\n const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');\n\n if (!isTypeValid(file, allowedFileTypes)) {\n handleFileUploadFailure(file, formatMessage(MESSAGES.fileTypeNotSupported));\n continue;\n }\n\n if (!isSizeValid(file, sizeLimit * 1000)) {\n const failureMessage = sizeLimitErrorMessage || formatMessage(MESSAGES.fileIsTooLarge);\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n if (areMaximumFilesUploadedAlready()) {\n const failureMessage =\n maxFilesErrorMessage ||\n formatMessage(MESSAGES.maximumFilesAlreadyUploaded, { maxFilesAllowed: maxFiles });\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n const existingFile = uploadedFiles.find((f) => f.filename === file.name);\n if (existingFile) {\n removeFileFromList(existingFile);\n }\n\n formData.append(fileInputName, file);\n const pendingFile = {\n id: generateFileId(file),\n filename: file.name,\n status: Status.PENDING,\n };\n\n addFileToList(pendingFile);\n\n onUploadFile(formData)\n .then(({ id, url, error }: UploadResponse) => {\n modifyFileInList(pendingFile, { id, url, error, status: Status.SUCCEEDED });\n })\n .catch((error) => {\n modifyFileInList(pendingFile, { error: error as UploadError, status: Status.FAILED });\n });\n\n if (!multiple) {\n break;\n }\n }\n }\n };\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n if (onFilesChange && mounted) {\n onFilesChange([...uploadedFiles]);\n }\n }, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps\n\n const [nextFocusable, setNextFocusable] = useState<HTMLDivElement | UploadItemRef | null>(\n uploadInputRef.current,\n );\n\n const handleFocus = (fileId: string | number) => {\n fileRefs = fileRefs.filter((ref) => {\n return ref && ref.id !== markedFileForDelete?.id;\n });\n\n const filesCount = fileRefs.length;\n let next: HTMLDivElement | UploadItemRef | null = uploadInputRef.current;\n\n if (filesCount > 1) {\n const currentFileIndex = fileRefs.findIndex((file) => file?.id === fileId);\n const currentFileId = fileRefs?.[currentFileIndex]?.id;\n const lastFileId = fileRefs?.[filesCount - 1]?.id;\n\n // if last file, select a previous one\n if (currentFileId === lastFileId) {\n next = fileRefs[filesCount - 2];\n } else {\n next = fileRefs[currentFileIndex + 1];\n }\n }\n setNextFocusable(next);\n };\n\n const handleRefocus = () => {\n if (nextFocusable && 'focus' in nextFocusable && typeof nextFocusable.focus === 'function') {\n setTimeout(() => {\n nextFocusable.focus();\n }, 0);\n }\n };\n\n return (\n <>\n <div\n role=\"group\"\n className={clsx('np-upload-input', className, { disabled })}\n {...inputAttributes}\n >\n <div\n className=\"np-upload-input__section\"\n aria-live=\"polite\"\n aria-relevant=\"all\"\n role=\"region\"\n >\n {uploadedFiles.map((file, index) => (\n <UploadItem\n key={file.id}\n ref={(el: UploadItemRef | null) => {\n if (\n el &&\n el.id !== markedFileForDelete?.id &&\n !fileRefs.some((ref) => ref && ref.id === el.id) &&\n el.status !== 'processing'\n ) {\n fileRefs.push(el);\n }\n }}\n file={file}\n singleFileUpload={!multiple}\n canDelete={\n (!!onDeleteFile || file.status === Status.FAILED) &&\n (!file.status || !PROGRESS_STATUSES.has(file.status))\n }\n onDelete={\n file.status === Status.FAILED\n ? async () => {\n await removeFile(file);\n handleRefocus();\n }\n : () => setMarkedFileForDelete(file)\n }\n onDownload={onDownload}\n onFocus={() => handleFocus(file.id)}\n />\n ))}\n </div>\n {(multiple || (!multiple && !uploadedFiles.length)) && (\n <div className=\"np-upload-input__section np-upload-input__section--uploader\">\n <UploadButton\n ref={uploadInputRef}\n id={id}\n uploadButtonTitle={uploadButtonTitle}\n disabled={areMaximumFilesUploadedAlready() || disabled}\n multiple={multiple}\n fileTypes={fileTypes}\n sizeLimit={sizeLimit}\n description={description}\n maxFiles={maxFiles}\n withEntries={Boolean(uploadedFiles.length)}\n onChange={addFiles}\n />\n </div>\n )}\n </div>\n <Modal\n title={\n deleteConfirm?.title !== undefined\n ? deleteConfirm.title\n : formatMessage(MESSAGES.deleteModalTitle)\n }\n body={\n deleteConfirm?.body !== undefined\n ? deleteConfirm.body\n : formatMessage(MESSAGES.deleteModalBody)\n }\n open={!!markedFileForDelete}\n footer={\n <>\n <Button\n block\n onClick={() => {\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.cancelText || formatMessage(MESSAGES.deleteModalCancelButtonText)}\n </Button>\n <Button\n block\n priority={Priority.SECONDARY}\n type={ControlType.NEGATIVE}\n tabIndex={markedFileForDelete ? 0 : -1}\n onClick={() => {\n if (markedFileForDelete) {\n void removeFile(markedFileForDelete);\n }\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.confirmText || formatMessage(MESSAGES.deleteModalConfirmButtonText)}\n </Button>\n </>\n }\n onUnmount={handleRefocus}\n onClose={() => {\n setMarkedFileForDelete(null);\n }}\n />\n </>\n );\n};\n\nexport default UploadInput;\n"],"names":["generateFileId","file","name","size","uploadTimeStamp","Date","getTime","UploadInput","files","fileInputName","className","deleteConfirm","disabled","multiple","fileTypes","imageFileTypes","sizeLimit","DEFAULT_SIZE_LIMIT","description","onUploadFile","onDeleteFile","onValidationError","onFilesChange","onDownload","maxFiles","maxFilesErrorMessage","id","sizeLimitErrorMessage","uploadButtonTitle","inputAttributes","useInputAttributes","nonLabelable","markedFileForDelete","setMarkedFileForDelete","useState","mounted","setMounted","formatMessage","useIntl","uploadInputRef","useRef","fileRefs","PROGRESS_STATUSES","Set","Status","PENDING","PROCESSING","uploadedFiles","setUploadedFiles","length","uploadedFilesListReference","updateFileList","updateFn","current","addFileToList","recentUploadedFile","list","removeFileFromList","filter","fileInList","ref","modifyFileInList","updates","map","removeFile","status","item","FAILED","Promise","resolve","error","undefined","then","catch","handleFileUploadFailure","failureMessage","failedUpload","filename","getNumberOfFilesUploaded","uploadInitiatedStatus","SUCCEEDED","validFiles","has","areMaximumFilesUploadedAlready","numberOfValidFiles","addFiles","selectedFiles","i","formData","FormData","allowedFileTypes","join","isTypeValid","MESSAGES","fileTypeNotSupported","isSizeValid","fileIsTooLarge","maximumFilesAlreadyUploaded","maxFilesAllowed","existingFile","find","f","append","pendingFile","url","useEffect","nextFocusable","setNextFocusable","handleFocus","fileId","filesCount","next","currentFileIndex","findIndex","currentFileId","lastFileId","handleRefocus","focus","setTimeout","_jsxs","_Fragment","children","role","clsx","_jsx","index","UploadItem","el","some","push","singleFileUpload","canDelete","onDelete","onFocus","UploadButton","withEntries","Boolean","onChange","Modal","title","deleteModalTitle","body","deleteModalBody","open","footer","Button","block","onClick","cancelText","deleteModalCancelButtonText","priority","Priority","SECONDARY","type","ControlType","NEGATIVE","tabIndex","confirmText","deleteModalConfirmButtonText","onUnmount","onClose"],"mappings":"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"}
1
+ {"version":3,"file":"UploadInput.mjs","sources":["../../src/uploadInput/UploadInput.tsx"],"sourcesContent":["import { clsx } from 'clsx';\nimport { useEffect, useRef, useState, useLayoutEffect } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Button from '../button';\nimport { CommonProps, ControlType, Priority, Status } from '../common';\nimport { useInputAttributes } from '../inputs/contexts';\nimport Modal from '../modal';\nimport { isSizeValid } from '../upload/utils/isSizeValid';\nimport { isTypeValid } from '../upload/utils/isTypeValid';\n\nimport MESSAGES from './UploadInput.messages';\nimport { UploadedFile, UploadError, UploadResponse } from './types';\nimport UploadButton, { UploadButtonProps } from './uploadButton/UploadButton';\nimport { DEFAULT_SIZE_LIMIT, imageFileTypes } from './uploadButton/defaults';\nimport UploadItem, { UploadItemProps } from './uploadItem/UploadItem';\n\nexport type UploadInputProps = {\n /**\n * List of already existing, failed or in progress files\n */\n files?: readonly UploadedFile[];\n\n /**\n * The key of the file in the returned FormData object (default: file)\n */\n fileInputName?: string;\n\n /**\n * Callback that handles form submission\n *\n * @param formData\n */\n onUploadFile: (formData: FormData) => Promise<UploadResponse>;\n\n /**\n * Provide a callback if the file can be removed/deleted from the server\n * Your app is responsible for reloading the uploaded files list and updating the component to ensure that the file has in fact been deleted successfully\n *\n * @param id\n */\n onDeleteFile?: (id: string | number) => Promise<any>;\n\n /**\n * Provide a callback to trigger on validation error\n *\n * @param file\n */\n onValidationError?: (file: UploadedFile) => void;\n\n /**\n * Provide a callback to trigger on change whenever the files are updated\n *\n * @param files\n */\n onFilesChange?: (files: UploadedFile[]) => void;\n\n /**\n * Confirmation modal displayed on delete\n */\n deleteConfirm?: {\n /**\n * The title of the confirmation modal on delete\n */\n title?: string;\n\n /**\n * The body of the confirmation modal on delete\n */\n body?: React.ReactNode;\n\n /**\n * The confirm button text of the confirmation modal on delete\n */\n confirmText?: string;\n\n /**\n * The cancel button text of the confirmation modal on delete\n */\n cancelText?: string;\n };\n\n /**\n * Maximum number of files allowed, if provided, shows error below file item\n */\n maxFiles?: number;\n\n /**\n * Error message to show when the maximum number of files are uploaded already\n */\n maxFilesErrorMessage?: string;\n\n /**\n * Error message to show when files over a allowed size limit are uploaded\n */\n sizeLimitErrorMessage?: string;\n} & Pick<\n UploadButtonProps,\n 'disabled' | 'multiple' | 'fileTypes' | 'sizeLimit' | 'description' | 'id' | 'uploadButtonTitle'\n> & { onDownload?: UploadItemProps['onDownload'] } & CommonProps;\n\ninterface UploadItemRef {\n focus: () => void;\n}\n\nfunction generateFileId(file: File) {\n const { name, size } = file;\n const uploadTimeStamp = new Date().getTime();\n return `${name}_${size}_${uploadTimeStamp}`;\n}\n\nconst UploadInput = ({\n files = [],\n fileInputName = 'file',\n className,\n deleteConfirm,\n disabled,\n multiple = false,\n fileTypes = imageFileTypes,\n sizeLimit = DEFAULT_SIZE_LIMIT,\n description,\n onUploadFile,\n onDeleteFile,\n onValidationError,\n onFilesChange,\n onDownload,\n maxFiles,\n maxFilesErrorMessage,\n id,\n sizeLimitErrorMessage,\n uploadButtonTitle,\n}: UploadInputProps) => {\n const inputAttributes = useInputAttributes({ nonLabelable: true });\n\n const [markedFileForDelete, setMarkedFileForDelete] = useState<UploadedFile | null>(null);\n const [fileToRemoveIndex, setFileToRemoveIndex] = useState<number | null>(null);\n const [mounted, setMounted] = useState(false);\n const { formatMessage } = useIntl();\n const itemRefs = useRef<(HTMLDivElement | UploadItemRef | null)[]>([]);\n const uploadInputRef = useRef<HTMLInputElement | null>(null);\n\n const PROGRESS_STATUSES = new Set([Status.PENDING, Status.PROCESSING]);\n\n const [uploadedFiles, setUploadedFiles] = useState<readonly UploadedFile[]>(\n multiple || files.length === 0 ? files : [files[0]],\n );\n\n const uploadedFilesListReference = useRef(multiple || files.length === 0 ? files : [files[0]]);\n\n function addFileToList(recentUploadedFile: UploadedFile) {\n function addToList(listToAddTo: readonly UploadedFile[]) {\n return [...listToAddTo, recentUploadedFile];\n }\n\n setUploadedFiles(addToList);\n uploadedFilesListReference.current = addToList(uploadedFilesListReference.current);\n }\n\n const removeFileFromList = (file: UploadedFile) => {\n function filterOutFrom(listToFilterFrom: readonly UploadedFile[]) {\n return listToFilterFrom.filter(\n (fileInList) => file !== fileInList && file.id !== fileInList.id,\n );\n }\n\n setUploadedFiles(filterOutFrom);\n uploadedFilesListReference.current = filterOutFrom(uploadedFilesListReference.current);\n };\n\n const modifyFileInList = (file: UploadedFile, updates: Partial<UploadedFile>) => {\n const updateListItem = (listToUpdate: readonly UploadedFile[]) =>\n listToUpdate.map((fileInList) => {\n return fileInList === file || fileInList.id === file.id\n ? { ...file, ...updates }\n : fileInList;\n });\n\n setUploadedFiles(updateListItem);\n uploadedFilesListReference.current = updateListItem(uploadedFilesListReference.current);\n };\n\n const [fileToRemove, setFileToRemove] = useState<UploadedFile | null>(null);\n\n const removeFile = (file: UploadedFile) => {\n const { id, status } = file;\n const index = uploadedFiles.findIndex((f) => f.id === file.id);\n setFileToRemoveIndex(index);\n\n if (status === Status.FAILED) {\n removeFileFromList(file);\n setFileToRemove(file);\n } else if (onDeleteFile && id) {\n modifyFileInList(file, { status: Status.PROCESSING, error: undefined });\n\n onDeleteFile(id)\n .then(() => {\n removeFileFromList(file);\n })\n .catch((error) => {\n modifyFileInList(file, { error: error as UploadError });\n })\n .finally(() => {\n setFileToRemove(file);\n });\n }\n };\n\n function handleFileUploadFailure(file: File, failureMessage: string) {\n const { name } = file;\n const id = generateFileId(file);\n const failedUpload = {\n id,\n filename: name,\n status: Status.FAILED,\n error: failureMessage,\n };\n\n addFileToList(failedUpload);\n\n if (onValidationError) {\n onValidationError(failedUpload);\n }\n }\n\n function getNumberOfFilesUploaded() {\n const uploadInitiatedStatus = new Set([Status.SUCCEEDED, Status.PENDING]);\n const validFiles = uploadedFilesListReference.current.filter(\n (file) => file.status && uploadInitiatedStatus.has(file.status),\n );\n return validFiles.length;\n }\n\n function areMaximumFilesUploadedAlready() {\n if (!maxFiles) {\n return false;\n }\n\n const numberOfValidFiles = getNumberOfFilesUploaded();\n return numberOfValidFiles >= maxFiles;\n }\n\n // One or more files selected, create entries for them\n const addFiles = (selectedFiles: FileList) => {\n for (let i = 0; i < selectedFiles.length; i += 1) {\n const file = selectedFiles.item(i);\n\n // Returning a FormData[] array instead of FileList so we can filter out incorrect files\n const formData = new FormData();\n\n if (file) {\n const { name } = file;\n const id = generateFileId(file);\n\n const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');\n\n // Check if file type is valid\n if (!isTypeValid(file, allowedFileTypes)) {\n handleFileUploadFailure(file, formatMessage(MESSAGES.fileTypeNotSupported));\n continue;\n }\n\n // Check if the filesize is valid\n // Convert to rough bytes\n if (!isSizeValid(file, sizeLimit * 1000)) {\n const failureMessage = sizeLimitErrorMessage || formatMessage(MESSAGES.fileIsTooLarge);\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n if (areMaximumFilesUploadedAlready()) {\n const failureMessage =\n maxFilesErrorMessage ||\n formatMessage(MESSAGES.maximumFilesAlreadyUploaded, { maxFilesAllowed: maxFiles });\n handleFileUploadFailure(file, failureMessage);\n continue;\n }\n\n // Check if the file is already in the list\n const existingFile = uploadedFiles.find((f) => f.filename === file.name);\n if (existingFile) {\n // Remove the file from the list before adding it again\n removeFileFromList(existingFile);\n }\n\n // Add the file to the list\n formData.append(fileInputName, file);\n const pendingFile = {\n id: generateFileId(file),\n filename: file.name,\n status: Status.PENDING,\n };\n\n addFileToList(pendingFile);\n\n // Start uploading the file\n onUploadFile(formData)\n .then(({ id, url, error }: UploadResponse) => {\n // Replace the temporary id with the final one received from the API, and also set any errors\n modifyFileInList(pendingFile, { id, url, error, status: Status.SUCCEEDED });\n })\n .catch((error) => {\n modifyFileInList(pendingFile, { error: error as UploadError, status: Status.FAILED });\n });\n\n if (!multiple) {\n // Only upload a single file\n break;\n }\n }\n }\n };\n\n useLayoutEffect(() => {\n if (fileToRemove && fileToRemoveIndex !== null) {\n requestAnimationFrame(() => {\n const nextFocusIndex = Math.min(fileToRemoveIndex, uploadedFiles.length - 1);\n if (itemRefs.current[nextFocusIndex]) {\n itemRefs.current[nextFocusIndex].focus(); // Focus the next UploadItem\n } else {\n // If there's only one item left, focus the UploadButton\n uploadInputRef.current?.focus();\n }\n });\n setFileToRemove(null); // Reset the state\n setFileToRemoveIndex(null); // Reset the index\n }\n }, [uploadedFiles, fileToRemove, fileToRemoveIndex, itemRefs, uploadInputRef]);\n\n useEffect(() => {\n setMounted(true);\n }, []);\n\n useEffect(() => {\n if (onFilesChange && mounted) {\n onFilesChange([...uploadedFiles]);\n }\n }, [onFilesChange, uploadedFiles]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return (\n <>\n <div\n role=\"group\"\n className={clsx('np-upload-input', className, { disabled })}\n {...inputAttributes}\n >\n <div\n className=\"np-upload-input__section\"\n aria-live=\"polite\"\n aria-relevant=\"all\"\n role=\"region\"\n >\n {uploadedFiles.map((file, index) => (\n <UploadItem\n key={file.id}\n ref={(el: UploadItemRef | null) => {\n itemRefs.current[index] = el;\n }}\n file={file}\n singleFileUpload={!multiple}\n canDelete={\n (!!onDeleteFile || file.status === Status.FAILED) &&\n (!file.status || !PROGRESS_STATUSES.has(file.status))\n }\n onDelete={\n file.status === Status.FAILED\n ? () => removeFile(file)\n : () => setMarkedFileForDelete(file)\n }\n onDownload={onDownload}\n />\n ))}\n </div>\n {(multiple || (!multiple && !uploadedFiles.length)) && (\n <div className=\"np-upload-input__section np-upload-input__section--uploader\">\n <UploadButton\n ref={uploadInputRef}\n id={id}\n uploadButtonTitle={uploadButtonTitle}\n disabled={areMaximumFilesUploadedAlready() || disabled}\n multiple={multiple}\n fileTypes={fileTypes}\n sizeLimit={sizeLimit}\n description={description}\n maxFiles={maxFiles}\n withEntries={Boolean(uploadedFiles.length)}\n onChange={addFiles}\n />\n </div>\n )}\n </div>\n <Modal\n title={\n deleteConfirm?.title !== undefined\n ? deleteConfirm.title\n : formatMessage(MESSAGES.deleteModalTitle)\n }\n body={\n deleteConfirm?.body !== undefined\n ? deleteConfirm.body\n : formatMessage(MESSAGES.deleteModalBody)\n }\n open={!!markedFileForDelete}\n footer={\n <>\n <Button\n block\n onClick={() => {\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.cancelText || formatMessage(MESSAGES.deleteModalCancelButtonText)}\n </Button>\n <Button\n block\n priority={Priority.SECONDARY}\n type={ControlType.NEGATIVE}\n onClick={() => {\n if (markedFileForDelete) {\n removeFile(markedFileForDelete);\n }\n setMarkedFileForDelete(null);\n }}\n >\n {deleteConfirm?.confirmText || formatMessage(MESSAGES.deleteModalConfirmButtonText)}\n </Button>\n </>\n }\n onClose={() => {\n setMarkedFileForDelete(null);\n }}\n />\n </>\n );\n};\n\nexport default UploadInput;\n"],"names":["generateFileId","file","name","size","uploadTimeStamp","Date","getTime","UploadInput","files","fileInputName","className","deleteConfirm","disabled","multiple","fileTypes","imageFileTypes","sizeLimit","DEFAULT_SIZE_LIMIT","description","onUploadFile","onDeleteFile","onValidationError","onFilesChange","onDownload","maxFiles","maxFilesErrorMessage","id","sizeLimitErrorMessage","uploadButtonTitle","inputAttributes","useInputAttributes","nonLabelable","markedFileForDelete","setMarkedFileForDelete","useState","fileToRemoveIndex","setFileToRemoveIndex","mounted","setMounted","formatMessage","useIntl","itemRefs","useRef","uploadInputRef","PROGRESS_STATUSES","Set","Status","PENDING","PROCESSING","uploadedFiles","setUploadedFiles","length","uploadedFilesListReference","addFileToList","recentUploadedFile","addToList","listToAddTo","current","removeFileFromList","filterOutFrom","listToFilterFrom","filter","fileInList","modifyFileInList","updates","updateListItem","listToUpdate","map","fileToRemove","setFileToRemove","removeFile","status","index","findIndex","f","FAILED","error","undefined","then","catch","finally","handleFileUploadFailure","failureMessage","failedUpload","filename","getNumberOfFilesUploaded","uploadInitiatedStatus","SUCCEEDED","validFiles","has","areMaximumFilesUploadedAlready","numberOfValidFiles","addFiles","selectedFiles","i","item","formData","FormData","allowedFileTypes","join","isTypeValid","MESSAGES","fileTypeNotSupported","isSizeValid","fileIsTooLarge","maximumFilesAlreadyUploaded","maxFilesAllowed","existingFile","find","append","pendingFile","url","useLayoutEffect","requestAnimationFrame","nextFocusIndex","Math","min","focus","useEffect","_jsxs","_Fragment","children","role","clsx","_jsx","UploadItem","ref","el","singleFileUpload","canDelete","onDelete","UploadButton","withEntries","Boolean","onChange","Modal","title","deleteModalTitle","body","deleteModalBody","open","footer","Button","block","onClick","cancelText","deleteModalCancelButtonText","priority","Priority","SECONDARY","type","ControlType","NEGATIVE","confirmText","deleteModalConfirmButtonText","onClose"],"mappings":"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"}
@@ -19,16 +19,13 @@ exports.TEST_IDS = void 0;
19
19
  (function (TEST_IDS) {
20
20
  TEST_IDS["uploadItem"] = "uploadItem";
21
21
  TEST_IDS["mediaBody"] = "mediaBody";
22
- TEST_IDS["link"] = "link";
23
- TEST_IDS["action"] = "action";
24
22
  })(exports.TEST_IDS || (exports.TEST_IDS = {}));
25
23
  const UploadItem = /*#__PURE__*/React.forwardRef(({
26
24
  file,
27
25
  canDelete,
28
26
  onDelete,
29
27
  onDownload,
30
- singleFileUpload,
31
- onFocus: handleFocus
28
+ singleFileUpload
32
29
  }, ref) => {
33
30
  const {
34
31
  formatMessage
@@ -49,9 +46,7 @@ const UploadItem = /*#__PURE__*/React.forwardRef(({
49
46
  } else {
50
47
  buttonRef.current?.focus();
51
48
  }
52
- },
53
- id: file.id,
54
- status: file.status
49
+ }
55
50
  }));
56
51
  const isSucceeded = [status.Status.SUCCEEDED, undefined].includes(status$1) && !!url;
57
52
  /**
@@ -146,19 +141,18 @@ const UploadItem = /*#__PURE__*/React.forwardRef(({
146
141
  className: clsx.clsx('np-upload-input__item', {
147
142
  'is-interactive': isSucceeded && url
148
143
  }),
149
- "data-testid": `${file.id}-${exports.TEST_IDS.uploadItem}`,
144
+ "data-testid": exports.TEST_IDS.uploadItem,
150
145
  children: [/*#__PURE__*/jsxRuntime.jsxs(UploadItemLink.UploadItemLink, {
151
146
  ref: linkRef,
152
147
  url: isSucceeded ? url : undefined,
153
148
  singleFileUpload: singleFileUpload,
154
- "data-testid": `${file.id}-${exports.TEST_IDS.link}`,
155
149
  onDownload: onDownloadFile,
156
150
  children: [/*#__PURE__*/jsxRuntime.jsx("span", {
157
151
  className: "np-upload-input__icon",
158
152
  children: getIcon()
159
153
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
160
154
  className: "np-upload-input__item-content",
161
- "data-testid": `${file.id}-${exports.TEST_IDS.mediaBody}`,
155
+ "data-testid": exports.TEST_IDS.mediaBody,
162
156
  children: [/*#__PURE__*/jsxRuntime.jsx(Body, {
163
157
  type: typography.Typography.BODY_LARGE,
164
158
  className: "np-upload-input__title text-word-break",
@@ -174,10 +168,7 @@ const UploadItem = /*#__PURE__*/React.forwardRef(({
174
168
  }),
175
169
  className: "np-upload-input__item-button",
176
170
  type: "button",
177
- tabIndex: 0,
178
- "data-testid": `${file.id}-${exports.TEST_IDS.action}`,
179
171
  onClick: () => onDelete(),
180
- onFocus: handleFocus,
181
172
  children: /*#__PURE__*/jsxRuntime.jsx(icons.Bin, {
182
173
  size: 16
183
174
  })
@@ -1 +1 @@
1
- {"version":3,"file":"UploadItem.js","sources":["../../../src/uploadInput/uploadItem/UploadItem.tsx"],"sourcesContent":["import { Bin, CheckCircleFill, CrossCircleFill } from '@transferwise/icons';\nimport { clsx } from 'clsx';\nimport { forwardRef, useImperativeHandle, useRef } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Body from '../../body';\nimport { Size, Status, Typography } from '../../common';\nimport ProcessIndicator from '../../processIndicator/ProcessIndicator';\nimport { UploadedFile, UploadError } from '../types';\n\nimport MESSAGES from './UploadItem.messages';\nimport { UploadItemLink } from './UploadItemLink';\n\nexport type UploadItemProps = React.JSX.IntrinsicAttributes & {\n file: UploadedFile;\n /**\n * Is this Item part of a multiple- or single-file UploadInput\n */\n singleFileUpload: boolean;\n canDelete: boolean;\n onDelete: () => void;\n onFocus: () => void;\n\n /**\n * Callback to be called when the file link is clicked.\n * When provided, you need to manually trigger actions to load/download the file.\n *\n * @param file\n */\n onDownload?: (file: UploadedFile) => void;\n ref?: React.Ref<UploadItemRef>;\n};\ninterface UploadItemRef {\n /**\n * A method to set focus on the upload item.\n * @returns {void}\n */\n focus: () => void;\n\n /**\n * A required unique identifier for the upload item.\n */\n id: string | number;\n\n /**\n * An optional status of the upload item.\n */\n status?: string;\n}\n\nexport enum TEST_IDS {\n uploadItem = 'uploadItem',\n mediaBody = 'mediaBody',\n link = 'link',\n action = 'action',\n}\n\nconst UploadItem = forwardRef<UploadItemRef, UploadItemProps>(\n ({ file, canDelete, onDelete, onDownload, singleFileUpload, onFocus: handleFocus }, ref) => {\n const { formatMessage } = useIntl();\n const { status, filename, error, errors, url } = file;\n const linkRef = useRef<HTMLAnchorElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n useImperativeHandle<UploadItemRef, UploadItemRef>(ref, () => ({\n focus: (): void => {\n if (url) {\n linkRef.current?.focus();\n } else {\n buttonRef.current?.focus();\n }\n },\n id: file.id,\n status: file.status,\n }));\n\n const isSucceeded = [Status.SUCCEEDED, undefined].includes(status) && !!url;\n\n /**\n * We're temporarily reverting to the regular icon components,\n * until the StatusIcon receives 24px sizing. Some misalignment\n * to be expected.\n */\n const getIcon = () => {\n if (error || errors?.length || status === Status.FAILED) {\n return <CrossCircleFill size={24} className=\"emphasis--negative\" />;\n }\n\n let processIndicator: React.ReactNode;\n\n switch (status) {\n case Status.PROCESSING:\n case Status.PENDING:\n processIndicator = (\n <ProcessIndicator size={Size.EXTRA_SMALL} status={Status.PROCESSING} />\n );\n break;\n case Status.SUCCEEDED:\n case Status.DONE:\n default:\n processIndicator = <CheckCircleFill size={24} className=\"emphasis--positive\" />;\n }\n\n return processIndicator;\n };\n\n const getErrorMessage = (error?: UploadError) =>\n typeof error === 'object' ? error.message : error || formatMessage(MESSAGES.uploadingFailed);\n\n const getMultipleErrors = (errors?: UploadError[]) => {\n if (!errors?.length) {\n return null;\n }\n\n if (errors?.length === 1) {\n return getErrorMessage(errors[0]);\n }\n\n return (\n <ul className=\"np-upload-input-errors m-b-0\">\n {errors.map((error, index) => {\n // eslint-disable-next-line react/no-array-index-key\n return <li key={index}>{getErrorMessage(error)}</li>;\n })}\n </ul>\n );\n };\n\n const getDescription = () => {\n if (error || errors?.length || status === Status.FAILED) {\n return (\n <Body type={Typography.BODY_DEFAULT_BOLD} className=\"np-upload-input__text text-negative\">\n {errors?.length ? getMultipleErrors(errors) : getErrorMessage(error)}\n </Body>\n );\n }\n\n switch (status) {\n case Status.PENDING:\n return (\n <Body type={Typography.BODY_DEFAULT} className=\"np-upload-input__text\">\n {formatMessage(MESSAGES.uploading)}\n </Body>\n );\n case Status.PROCESSING:\n return <Body className=\"np-upload-input__text\">{formatMessage(MESSAGES.deleting)}</Body>;\n case Status.SUCCEEDED:\n case Status.DONE:\n default:\n return (\n <Body type={Typography.BODY_DEFAULT_BOLD} className=\"np-upload-input__text\">\n {formatMessage(MESSAGES.uploaded)}\n </Body>\n );\n }\n };\n\n const getTitle = () => {\n return filename || formatMessage(MESSAGES.uploadedFile);\n };\n\n const onDownloadFile = (event: React.MouseEvent): void => {\n if (onDownload) {\n event.preventDefault();\n onDownload(file);\n }\n };\n\n return (\n <div\n className={clsx('np-upload-input__item', { 'is-interactive': isSucceeded && url })}\n data-testid={`${file.id}-${TEST_IDS.uploadItem}`}\n >\n <UploadItemLink\n ref={linkRef}\n url={isSucceeded ? url : undefined}\n singleFileUpload={singleFileUpload}\n data-testid={`${file.id}-${TEST_IDS.link}`}\n onDownload={onDownloadFile}\n >\n <span className=\"np-upload-input__icon\">{getIcon()}</span>\n <div\n className=\"np-upload-input__item-content\"\n data-testid={`${file.id}-${TEST_IDS.mediaBody}`}\n >\n <Body type={Typography.BODY_LARGE} className=\"np-upload-input__title text-word-break\">\n {getTitle()}\n </Body>\n {getDescription()}\n </div>\n </UploadItemLink>\n {canDelete && (\n <div className=\"np-upload-input__item-action\">\n <button\n ref={buttonRef}\n aria-label={formatMessage(MESSAGES.removeFile, { filename })}\n className=\"np-upload-input__item-button\"\n type=\"button\"\n tabIndex={0}\n data-testid={`${file.id}-${TEST_IDS.action}`}\n onClick={() => onDelete()}\n onFocus={handleFocus}\n >\n <Bin size={16} />\n </button>\n </div>\n )}\n </div>\n );\n },\n);\n\nUploadItem.displayName = 'UploadItem';\n\nexport default UploadItem;\n"],"names":["TEST_IDS","UploadItem","forwardRef","file","canDelete","onDelete","onDownload","singleFileUpload","onFocus","handleFocus","ref","formatMessage","useIntl","status","filename","error","errors","url","linkRef","useRef","buttonRef","useImperativeHandle","focus","current","id","isSucceeded","Status","SUCCEEDED","undefined","includes","getIcon","length","FAILED","_jsx","CrossCircleFill","size","className","processIndicator","PROCESSING","PENDING","ProcessIndicator","Size","EXTRA_SMALL","DONE","CheckCircleFill","getErrorMessage","message","MESSAGES","uploadingFailed","getMultipleErrors","children","map","index","getDescription","Body","type","Typography","BODY_DEFAULT_BOLD","BODY_DEFAULT","uploading","deleting","uploaded","getTitle","uploadedFile","onDownloadFile","event","preventDefault","_jsxs","clsx","uploadItem","UploadItemLink","link","mediaBody","BODY_LARGE","removeFile","tabIndex","action","onClick","Bin","displayName"],"mappings":"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"}
1
+ {"version":3,"file":"UploadItem.js","sources":["../../../src/uploadInput/uploadItem/UploadItem.tsx"],"sourcesContent":["import { Bin, CheckCircleFill, CrossCircleFill } from '@transferwise/icons';\nimport { clsx } from 'clsx';\nimport { forwardRef, useImperativeHandle, useRef } from 'react';\nimport { useIntl } from 'react-intl';\n\nimport Body from '../../body';\nimport { Size, Status, Typography, Sentiment } from '../../common';\nimport ProcessIndicator from '../../processIndicator/ProcessIndicator';\nimport StatusIcon from '../../statusIcon/StatusIcon';\nimport { UploadedFile, UploadError } from '../types';\n\nimport MESSAGES from './UploadItem.messages';\nimport { UploadItemLink } from './UploadItemLink';\n\nexport type UploadItemProps = React.JSX.IntrinsicAttributes & {\n file: UploadedFile;\n /**\n * Is this Item part of a multiple- or single-file UploadInput\n */\n singleFileUpload: boolean;\n canDelete: boolean;\n onDelete: () => void;\n\n /**\n * Callback to be called when the file link is clicked.\n * When provided, you need to manually trigger actions to load/download the file.\n *\n * @param file\n */\n onDownload?: (file: UploadedFile) => void;\n ref?: React.Ref<UploadItemRef>;\n};\n\ninterface UploadItemRef {\n focus: () => void;\n}\n\nexport enum TEST_IDS {\n uploadItem = 'uploadItem',\n mediaBody = 'mediaBody',\n}\n\nconst UploadItem = forwardRef<UploadItemRef, UploadItemProps>(\n ({ file, canDelete, onDelete, onDownload, singleFileUpload }, ref) => {\n const { formatMessage } = useIntl();\n const { status, filename, error, errors, url } = file;\n const linkRef = useRef<HTMLAnchorElement>(null);\n const buttonRef = useRef<HTMLButtonElement>(null);\n\n useImperativeHandle<UploadItemRef, UploadItemRef>(ref, () => ({\n focus: (): void => {\n if (url) {\n linkRef.current?.focus();\n } else {\n buttonRef.current?.focus();\n }\n },\n }));\n\n const isSucceeded = [Status.SUCCEEDED, undefined].includes(status) && !!url;\n\n /**\n * We're temporarily reverting to the regular icon components,\n * until the StatusIcon receives 24px sizing. Some misalignment\n * to be expected.\n */\n const getIcon = () => {\n if (error || errors?.length || status === Status.FAILED) {\n return <CrossCircleFill size={24} className=\"emphasis--negative\" />;\n }\n\n let processIndicator: React.ReactNode;\n\n switch (status) {\n case Status.PROCESSING:\n case Status.PENDING:\n processIndicator = (\n <ProcessIndicator size={Size.EXTRA_SMALL} status={Status.PROCESSING} />\n );\n break;\n case Status.SUCCEEDED:\n case Status.DONE:\n default:\n processIndicator = <CheckCircleFill size={24} className=\"emphasis--positive\" />;\n }\n\n return processIndicator;\n };\n\n const getErrorMessage = (error?: UploadError) =>\n typeof error === 'object' ? error.message : error || formatMessage(MESSAGES.uploadingFailed);\n\n const getMultipleErrors = (errors?: UploadError[]) => {\n if (!errors?.length) {\n return null;\n }\n\n if (errors?.length === 1) {\n return getErrorMessage(errors[0]);\n }\n\n return (\n <ul className=\"np-upload-input-errors m-b-0\">\n {errors.map((error, index) => {\n // eslint-disable-next-line react/no-array-index-key\n return <li key={index}>{getErrorMessage(error)}</li>;\n })}\n </ul>\n );\n };\n\n const getDescription = () => {\n if (error || errors?.length || status === Status.FAILED) {\n return (\n <Body type={Typography.BODY_DEFAULT_BOLD} className=\"np-upload-input__text text-negative\">\n {errors?.length ? getMultipleErrors(errors) : getErrorMessage(error)}\n </Body>\n );\n }\n\n switch (status) {\n case Status.PENDING:\n return (\n <Body type={Typography.BODY_DEFAULT} className=\"np-upload-input__text\">\n {formatMessage(MESSAGES.uploading)}\n </Body>\n );\n case Status.PROCESSING:\n return <Body className=\"np-upload-input__text\">{formatMessage(MESSAGES.deleting)}</Body>;\n case Status.SUCCEEDED:\n case Status.DONE:\n default:\n return (\n <Body type={Typography.BODY_DEFAULT_BOLD} className=\"np-upload-input__text\">\n {formatMessage(MESSAGES.uploaded)}\n </Body>\n );\n }\n };\n\n const getTitle = () => {\n return filename || formatMessage(MESSAGES.uploadedFile);\n };\n\n const onDownloadFile = (event: React.MouseEvent): void => {\n if (onDownload) {\n event.preventDefault();\n onDownload(file);\n }\n };\n\n return (\n <div\n className={clsx('np-upload-input__item', { 'is-interactive': isSucceeded && url })}\n data-testid={TEST_IDS.uploadItem}\n >\n <UploadItemLink\n ref={linkRef}\n url={isSucceeded ? url : undefined}\n singleFileUpload={singleFileUpload}\n onDownload={onDownloadFile}\n >\n <span className=\"np-upload-input__icon\">{getIcon()}</span>\n <div className=\"np-upload-input__item-content\" data-testid={TEST_IDS.mediaBody}>\n <Body type={Typography.BODY_LARGE} className=\"np-upload-input__title text-word-break\">\n {getTitle()}\n </Body>\n {getDescription()}\n </div>\n </UploadItemLink>\n {canDelete && (\n <div className=\"np-upload-input__item-action\">\n <button\n ref={buttonRef}\n aria-label={formatMessage(MESSAGES.removeFile, { filename })}\n className=\"np-upload-input__item-button\"\n type=\"button\"\n onClick={() => onDelete()}\n >\n <Bin size={16} />\n </button>\n </div>\n )}\n </div>\n );\n },\n);\n\nUploadItem.displayName = 'UploadItem';\n\nexport default UploadItem;\n"],"names":["TEST_IDS","UploadItem","forwardRef","file","canDelete","onDelete","onDownload","singleFileUpload","ref","formatMessage","useIntl","status","filename","error","errors","url","linkRef","useRef","buttonRef","useImperativeHandle","focus","current","isSucceeded","Status","SUCCEEDED","undefined","includes","getIcon","length","FAILED","_jsx","CrossCircleFill","size","className","processIndicator","PROCESSING","PENDING","ProcessIndicator","Size","EXTRA_SMALL","DONE","CheckCircleFill","getErrorMessage","message","MESSAGES","uploadingFailed","getMultipleErrors","children","map","index","getDescription","Body","type","Typography","BODY_DEFAULT_BOLD","BODY_DEFAULT","uploading","deleting","uploaded","getTitle","uploadedFile","onDownloadFile","event","preventDefault","_jsxs","clsx","uploadItem","UploadItemLink","mediaBody","BODY_LARGE","removeFile","onClick","Bin","displayName"],"mappings":"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"}
@@ -15,16 +15,13 @@ var TEST_IDS;
15
15
  (function (TEST_IDS) {
16
16
  TEST_IDS["uploadItem"] = "uploadItem";
17
17
  TEST_IDS["mediaBody"] = "mediaBody";
18
- TEST_IDS["link"] = "link";
19
- TEST_IDS["action"] = "action";
20
18
  })(TEST_IDS || (TEST_IDS = {}));
21
19
  const UploadItem = /*#__PURE__*/forwardRef(({
22
20
  file,
23
21
  canDelete,
24
22
  onDelete,
25
23
  onDownload,
26
- singleFileUpload,
27
- onFocus: handleFocus
24
+ singleFileUpload
28
25
  }, ref) => {
29
26
  const {
30
27
  formatMessage
@@ -45,9 +42,7 @@ const UploadItem = /*#__PURE__*/forwardRef(({
45
42
  } else {
46
43
  buttonRef.current?.focus();
47
44
  }
48
- },
49
- id: file.id,
50
- status: file.status
45
+ }
51
46
  }));
52
47
  const isSucceeded = [Status.SUCCEEDED, undefined].includes(status) && !!url;
53
48
  /**
@@ -142,19 +137,18 @@ const UploadItem = /*#__PURE__*/forwardRef(({
142
137
  className: clsx('np-upload-input__item', {
143
138
  'is-interactive': isSucceeded && url
144
139
  }),
145
- "data-testid": `${file.id}-${TEST_IDS.uploadItem}`,
140
+ "data-testid": TEST_IDS.uploadItem,
146
141
  children: [/*#__PURE__*/jsxs(UploadItemLink, {
147
142
  ref: linkRef,
148
143
  url: isSucceeded ? url : undefined,
149
144
  singleFileUpload: singleFileUpload,
150
- "data-testid": `${file.id}-${TEST_IDS.link}`,
151
145
  onDownload: onDownloadFile,
152
146
  children: [/*#__PURE__*/jsx("span", {
153
147
  className: "np-upload-input__icon",
154
148
  children: getIcon()
155
149
  }), /*#__PURE__*/jsxs("div", {
156
150
  className: "np-upload-input__item-content",
157
- "data-testid": `${file.id}-${TEST_IDS.mediaBody}`,
151
+ "data-testid": TEST_IDS.mediaBody,
158
152
  children: [/*#__PURE__*/jsx(Body, {
159
153
  type: Typography.BODY_LARGE,
160
154
  className: "np-upload-input__title text-word-break",
@@ -170,10 +164,7 @@ const UploadItem = /*#__PURE__*/forwardRef(({
170
164
  }),
171
165
  className: "np-upload-input__item-button",
172
166
  type: "button",
173
- tabIndex: 0,
174
- "data-testid": `${file.id}-${TEST_IDS.action}`,
175
167
  onClick: () => onDelete(),
176
- onFocus: handleFocus,
177
168
  children: /*#__PURE__*/jsx(Bin, {
178
169
  size: 16
179
170
  })