@transferwise/components 46.39.0 → 46.40.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.
Files changed (123) hide show
  1. package/build/index.js +176 -419
  2. package/build/index.js.map +1 -1
  3. package/build/index.mjs +176 -419
  4. package/build/index.mjs.map +1 -1
  5. package/build/types/index.d.ts +2 -1
  6. package/build/types/index.d.ts.map +1 -1
  7. package/build/types/processIndicator/ProcessIndicator.d.ts +1 -1
  8. package/build/types/processIndicator/ProcessIndicator.d.ts.map +1 -1
  9. package/build/types/upload/Upload.d.ts +91 -55
  10. package/build/types/upload/Upload.d.ts.map +1 -1
  11. package/build/types/upload/Upload.messages.d.ts +42 -60
  12. package/build/types/upload/Upload.messages.d.ts.map +1 -1
  13. package/build/types/upload/index.d.ts +2 -2
  14. package/build/types/upload/index.d.ts.map +1 -1
  15. package/build/types/upload/steps/completeStep/completeStep.d.ts +11 -18
  16. package/build/types/upload/steps/completeStep/completeStep.d.ts.map +1 -1
  17. package/build/types/upload/steps/completeStep/index.d.ts +2 -1
  18. package/build/types/upload/steps/completeStep/index.d.ts.map +1 -1
  19. package/build/types/upload/steps/index.d.ts +3 -4
  20. package/build/types/upload/steps/index.d.ts.map +1 -1
  21. package/build/types/upload/steps/processingStep/index.d.ts +2 -1
  22. package/build/types/upload/steps/processingStep/index.d.ts.map +1 -1
  23. package/build/types/upload/steps/processingStep/processingStep.d.ts +11 -13
  24. package/build/types/upload/steps/processingStep/processingStep.d.ts.map +1 -1
  25. package/build/types/upload/steps/uploadImageStep/index.d.ts +2 -1
  26. package/build/types/upload/steps/uploadImageStep/index.d.ts.map +1 -1
  27. package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts +14 -18
  28. package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts.map +1 -1
  29. package/build/types/upload/utils/asyncFileRead/asyncFileRead.d.ts +1 -1
  30. package/build/types/upload/utils/asyncFileRead/asyncFileRead.d.ts.map +1 -1
  31. package/build/types/upload/utils/asyncFileRead/index.d.ts +1 -1
  32. package/build/types/upload/utils/asyncFileRead/index.d.ts.map +1 -1
  33. package/build/types/upload/utils/getFileType/getFileType.d.ts +1 -1
  34. package/build/types/upload/utils/getFileType/getFileType.d.ts.map +1 -1
  35. package/build/types/upload/utils/getFileType/index.d.ts +1 -1
  36. package/build/types/upload/utils/getFileType/index.d.ts.map +1 -1
  37. package/build/types/upload/utils/index.d.ts +5 -7
  38. package/build/types/upload/utils/index.d.ts.map +1 -1
  39. package/build/types/upload/utils/isSizeValid/index.d.ts +1 -1
  40. package/build/types/upload/utils/isSizeValid/index.d.ts.map +1 -1
  41. package/build/types/upload/utils/isSizeValid/isSizeValid.d.ts +1 -1
  42. package/build/types/upload/utils/isSizeValid/isSizeValid.d.ts.map +1 -1
  43. package/build/types/upload/utils/isTypeValid/index.d.ts +1 -1
  44. package/build/types/upload/utils/isTypeValid/index.d.ts.map +1 -1
  45. package/build/types/upload/utils/isTypeValid/isTypeValid.d.ts +1 -1
  46. package/build/types/upload/utils/isTypeValid/isTypeValid.d.ts.map +1 -1
  47. package/build/types/upload/utils/postData/index.d.ts +1 -1
  48. package/build/types/upload/utils/postData/index.d.ts.map +1 -1
  49. package/build/types/upload/utils/postData/postData.d.ts +11 -1
  50. package/build/types/upload/utils/postData/postData.d.ts.map +1 -1
  51. package/package.json +3 -3
  52. package/src/index.ts +2 -1
  53. package/src/processIndicator/ProcessIndicator.tsx +1 -1
  54. package/src/upload/Upload.spec.js +3 -14
  55. package/src/upload/Upload.story.tsx +37 -0
  56. package/src/upload/{Upload.js → Upload.tsx} +164 -169
  57. package/src/upload/index.ts +2 -0
  58. package/src/upload/steps/completeStep/completeStep.spec.js +3 -2
  59. package/src/upload/steps/completeStep/completeStep.tsx +74 -0
  60. package/src/upload/steps/completeStep/index.ts +2 -0
  61. package/src/upload/steps/{index.js → index.ts} +0 -1
  62. package/src/upload/steps/processingStep/index.ts +2 -0
  63. package/src/upload/steps/processingStep/processingStep.tsx +53 -0
  64. package/src/upload/steps/uploadImageStep/index.ts +2 -0
  65. package/src/upload/steps/uploadImageStep/{uploadImageStep.js → uploadImageStep.tsx} +17 -23
  66. package/src/upload/utils/asyncFileRead/asyncFileRead.spec.ts +14 -0
  67. package/src/upload/utils/asyncFileRead/asyncFileRead.ts +12 -0
  68. package/src/upload/utils/getFileType/getFileType.spec.ts +22 -0
  69. package/src/upload/utils/getFileType/getFileType.ts +16 -0
  70. package/src/upload/utils/{index.js → index.ts} +0 -2
  71. package/src/upload/utils/isSizeValid/{isSizeValid.spec.js → isSizeValid.spec.ts} +3 -3
  72. package/src/upload/utils/isSizeValid/isSizeValid.ts +3 -0
  73. package/src/upload/utils/isTypeValid/isTypeValid.spec.ts +62 -0
  74. package/src/upload/utils/isTypeValid/isTypeValid.ts +19 -0
  75. package/src/upload/utils/postData/postData.spec.ts +65 -0
  76. package/src/upload/utils/postData/postData.ts +36 -0
  77. package/src/uploadInput/UploadInput.tsx +1 -1
  78. package/build/types/upload/steps/mediaUploadStep/index.d.ts +0 -2
  79. package/build/types/upload/steps/mediaUploadStep/index.d.ts.map +0 -1
  80. package/build/types/upload/steps/mediaUploadStep/mediaUploadStep.d.ts +0 -24
  81. package/build/types/upload/steps/mediaUploadStep/mediaUploadStep.d.ts.map +0 -1
  82. package/build/types/upload/uploadSteps.d.ts +0 -5
  83. package/build/types/upload/uploadSteps.d.ts.map +0 -1
  84. package/build/types/upload/utils/getSupportedSpotMimeTypes/getSupportedSpotMimeTypes.d.ts +0 -2
  85. package/build/types/upload/utils/getSupportedSpotMimeTypes/getSupportedSpotMimeTypes.d.ts.map +0 -1
  86. package/build/types/upload/utils/getSupportedSpotMimeTypes/index.d.ts +0 -2
  87. package/build/types/upload/utils/getSupportedSpotMimeTypes/index.d.ts.map +0 -1
  88. package/build/types/upload/utils/requestMedia/index.d.ts +0 -2
  89. package/build/types/upload/utils/requestMedia/index.d.ts.map +0 -1
  90. package/build/types/upload/utils/requestMedia/requestMedia.d.ts +0 -2
  91. package/build/types/upload/utils/requestMedia/requestMedia.d.ts.map +0 -1
  92. package/src/upload/Upload.story.js +0 -36
  93. package/src/upload/index.js +0 -2
  94. package/src/upload/steps/completeStep/completeStep.js +0 -98
  95. package/src/upload/steps/completeStep/index.js +0 -1
  96. package/src/upload/steps/mediaUploadStep/index.js +0 -1
  97. package/src/upload/steps/mediaUploadStep/mediaUploadStep.js +0 -80
  98. package/src/upload/steps/mediaUploadStep/mediaUploadStep.spec.js +0 -77
  99. package/src/upload/steps/processingStep/index.js +0 -1
  100. package/src/upload/steps/processingStep/processingStep.js +0 -73
  101. package/src/upload/steps/uploadImageStep/index.js +0 -1
  102. package/src/upload/uploadSteps.ts +0 -5
  103. package/src/upload/utils/asyncFileRead/asyncFileRead.js +0 -11
  104. package/src/upload/utils/asyncFileRead/asyncFileRead.spec.js +0 -17
  105. package/src/upload/utils/getFileType/getFileType.js +0 -19
  106. package/src/upload/utils/getFileType/getFileType.spec.js +0 -33
  107. package/src/upload/utils/getSupportedSpotMimeTypes/getSupportedSpotMimeTypes.js +0 -18
  108. package/src/upload/utils/getSupportedSpotMimeTypes/getSupportedSpotMimeTypes.spec.js +0 -22
  109. package/src/upload/utils/getSupportedSpotMimeTypes/index.js +0 -1
  110. package/src/upload/utils/isSizeValid/isSizeValid.js +0 -1
  111. package/src/upload/utils/isTypeValid/isTypeValid.js +0 -26
  112. package/src/upload/utils/isTypeValid/isTypeValid.spec.js +0 -68
  113. package/src/upload/utils/postData/postData.js +0 -18
  114. package/src/upload/utils/postData/postData.spec.js +0 -109
  115. package/src/upload/utils/requestMedia/index.js +0 -1
  116. package/src/upload/utils/requestMedia/requestMedia.js +0 -26
  117. package/src/upload/utils/requestMedia/requestMedia.spec.js +0 -44
  118. /package/src/upload/{Upload.messages.js → Upload.messages.ts} +0 -0
  119. /package/src/upload/utils/asyncFileRead/{index.js → index.ts} +0 -0
  120. /package/src/upload/utils/getFileType/{index.js → index.ts} +0 -0
  121. /package/src/upload/utils/isSizeValid/{index.js → index.ts} +0 -0
  122. /package/src/upload/utils/isTypeValid/{index.js → index.ts} +0 -0
  123. /package/src/upload/utils/postData/{index.js → index.ts} +0 -0
package/build/index.mjs CHANGED
@@ -12059,13 +12059,6 @@ var Typeahead$1 = withInputAttributes(Typeahead, {
12059
12059
  nonLabelable: true
12060
12060
  });
12061
12061
 
12062
- // TODO: consider to move this enum into component file once we migrate it on TypeScript or replace with some common enum
12063
- var UploadStep;
12064
- (function (UploadStep) {
12065
- UploadStep["UPLOAD_IMAGE_STEP"] = "uploadImageStep";
12066
- UploadStep["MEDIA_UPLOAD_STEP"] = "mediaUploadStep";
12067
- })(UploadStep || (UploadStep = {}));
12068
-
12069
12062
  var messages = defineMessages({
12070
12063
  csButtonText: {
12071
12064
  id: "neptune.Upload.csButtonText"
@@ -12100,16 +12093,13 @@ var messages = defineMessages({
12100
12093
  });
12101
12094
 
12102
12095
  class UploadImageStep extends PureComponent {
12103
- constructor() {
12104
- super();
12105
- this.uploadInputRef = /*#__PURE__*/createRef();
12106
- }
12096
+ uploadInputRef = /*#__PURE__*/createRef();
12107
12097
  onManualUpload = () => {
12108
12098
  const {
12109
12099
  fileDropped
12110
12100
  } = this.props;
12111
- if (this.uploadInputRef && this.uploadInputRef.current) {
12112
- const file = this.uploadInputRef.current.files[0];
12101
+ const file = this.uploadInputRef.current?.files?.[0];
12102
+ if (file != null) {
12113
12103
  fileDropped(file);
12114
12104
  }
12115
12105
  };
@@ -12158,7 +12148,7 @@ class UploadImageStep extends PureComponent {
12158
12148
  children: usLabel
12159
12149
  }), usPlaceholder && /*#__PURE__*/jsx("p", {
12160
12150
  className: "np-text-body-large m-b-3",
12161
- children: `${usPlaceholder}`
12151
+ children: String(usPlaceholder)
12162
12152
  }), /*#__PURE__*/jsxs("label", {
12163
12153
  className: `btn btn-primary btn-md ${usDisabled ? 'disabled' : ''}`,
12164
12154
  children: [usButtonText ? /*#__PURE__*/jsx("span", {
@@ -12169,7 +12159,7 @@ class UploadImageStep extends PureComponent {
12169
12159
  }), /*#__PURE__*/jsx("input", {
12170
12160
  ref: this.uploadInputRef,
12171
12161
  type: "file",
12172
- accept: usAccept === '*' ? null : usAccept,
12162
+ accept: usAccept === '*' ? undefined : usAccept,
12173
12163
  className: "tw-droppable-input hidden",
12174
12164
  disabled: usDisabled,
12175
12165
  name: "file-upload",
@@ -12181,213 +12171,17 @@ class UploadImageStep extends PureComponent {
12181
12171
  });
12182
12172
  }
12183
12173
  }
12184
- UploadImageStep.propTypes = {
12185
- fileDropped: PropTypes.func.isRequired,
12186
- isComplete: PropTypes.bool.isRequired,
12187
- usAccept: PropTypes.string.isRequired,
12188
- usButtonText: PropTypes.string.isRequired,
12189
- usDisabled: PropTypes.bool.isRequired,
12190
- usHelpImage: PropTypes.node.isRequired,
12191
- usLabel: PropTypes.string.isRequired,
12192
- usPlaceholder: PropTypes.string.isRequired
12193
- };
12194
-
12195
- const postData = (httpOptions, data = {}, fetcher = fetch) => fetcher(`${httpOptions.url}`, {
12196
- method: 'POST',
12197
- body: data,
12198
- ...httpOptions
12199
- }).then(response => {
12200
- if (!response.ok) {
12201
- const error = new Error(response.statusText);
12202
- error.status = response.status;
12203
- error.response = response;
12204
- throw error;
12205
- }
12206
- return response;
12207
- }).catch(error => {
12208
- throw error;
12209
- });
12210
-
12211
- const asyncFileRead = file => new Promise((resolve, reject) => {
12212
- const reader = new FileReader();
12213
- reader.readAsDataURL(file);
12214
- reader.addEventListener('load', event => {
12215
- resolve(event.target.result);
12216
- });
12217
- reader.addEventListener('error', event => {
12218
- reject(event);
12219
- });
12220
- });
12221
-
12222
- const isSizeValid = (file, maxSize) => Number.isInteger(maxSize) && file.size <= maxSize;
12223
-
12224
- const getFileType = (file, file64) => {
12225
- if (!file && !file64) {
12226
- return '';
12227
- }
12228
- if (file && file.type && file.type !== '') {
12229
- return file.type ?? '';
12230
- }
12231
- if (file64) {
12232
- const regex = /^data:([a-z]+\/[a-z]+);/;
12233
- const typeFromEncoded = file64.match(regex);
12234
- if (typeFromEncoded && typeFromEncoded[1]) {
12235
- return typeFromEncoded[1] ?? '';
12236
- }
12237
- }
12238
- return '';
12239
- };
12240
-
12241
- const isTypeValid = (file, rule, file64) => {
12242
- if (!file || !rule) {
12243
- return false;
12244
- }
12245
- const allowedTypes = rule.replace(/\s/g, '').split(',');
12246
- const fileType = getFileType(file, file64);
12247
- if (rule === '*' || allowedTypes.includes(fileType)) {
12248
- return true;
12249
- }
12250
- return allowedTypes.some(type => {
12251
- const splittedRule = type.split('/');
12252
- const typeAllowed = splittedRule[0];
12253
- const extensionAllowed = splittedRule[1];
12254
- if (extensionAllowed !== '*') {
12255
- return false;
12256
- }
12257
- return fileType.includes(typeAllowed);
12258
- });
12259
- };
12260
-
12261
- // Spot Platform's Media API only support these MIME types
12262
- const SUPPORTED_MIME_TYPES = ['image/jpeg', 'video/*', 'application/pdf'];
12263
- const getSupportedSpotMimeTypes = mimeTypes => {
12264
- if (mimeTypes === '*') {
12265
- return SUPPORTED_MIME_TYPES;
12266
- }
12267
- const mimeTypesArray = mimeTypes.split(',');
12268
- const mimeMapping = {
12269
- 'image/*': 'image/jpeg',
12270
- 'application/*': 'application/pdf'
12271
- };
12272
- const mapSupportedMimeTypes = mimeTypesArray.map(type => mimeMapping[type] || type);
12273
- return mapSupportedMimeTypes.filter(type => SUPPORTED_MIME_TYPES.includes(type));
12274
- };
12275
12174
 
12276
- const requestMedia = mediaRequest => new Promise((resolve, reject) => {
12277
- if (typeof window === 'undefined' || typeof window.microapps === 'undefined') {
12278
- reject(`microapps must be available in window to use Spot Platform's Media API`);
12279
- }
12280
- window.microapps.requestMedia(mediaRequest).then(response => {
12281
- const fileByteArray = base64ToByteArray(response.bytes);
12282
- const blob = new Blob([fileByteArray], {
12283
- type: response.mimeType
12284
- });
12285
- resolve(blob);
12286
- }).catch(error => reject(error));
12287
- });
12288
- const base64ToByteArray = base64String => {
12289
- const byteCharacters = atob(base64String);
12290
- const byteCharactersLength = byteCharacters.length;
12291
- const byteArray = new Array(byteCharactersLength);
12292
- for (let i = 0; i < byteCharactersLength; i += 1) {
12293
- byteArray[i] = byteCharacters.charCodeAt(i);
12294
- }
12295
- return new Uint8Array(byteArray);
12296
- };
12297
-
12298
- const MediaUploadStep = ({
12175
+ function ProcessingStep({
12299
12176
  isComplete,
12300
- usAccept,
12301
- usButtonText,
12302
- usDisabled,
12303
- usHelpImage,
12304
- usLabel,
12305
- usPlaceholder,
12306
- fileDropped
12307
- }) => {
12308
- const getMediaFile = () => {
12309
- const allowedMimeTypes = getSupportedSpotMimeTypes(usAccept);
12310
- if (allowedMimeTypes.length === 0) {
12311
- throw new Error('provided mimeTypes not supported');
12312
- }
12313
- const mediaRequest = {
12314
- allowedMimeTypes
12315
- };
12316
- requestMedia(mediaRequest).then(file => fileDropped(file));
12317
- };
12318
- const getImage = () => {
12319
- if (!usHelpImage) {
12320
- return /*#__PURE__*/jsx("div", {
12321
- className: "circle circle-sm circle-inverse p-t-1",
12322
- children: /*#__PURE__*/jsx(Upload$2, {
12323
- size: 24
12324
- })
12325
- });
12326
- }
12327
- if (typeof usHelpImage === 'string') {
12328
- return /*#__PURE__*/jsx("img", {
12329
- src: usHelpImage,
12330
- alt: usLabel,
12331
- className: "thumbnail text-xs-center"
12332
- });
12333
- }
12334
- return usHelpImage;
12335
- };
12336
- return /*#__PURE__*/jsx("div", {
12337
- children: /*#__PURE__*/jsx("div", {
12338
- className: "droppable-default-card",
12339
- "aria-hidden": isComplete,
12340
- children: /*#__PURE__*/jsxs("div", {
12341
- className: "droppable-card-content",
12342
- children: [/*#__PURE__*/jsx("div", {
12343
- className: "m-b-3",
12344
- children: getImage()
12345
- }), usLabel && /*#__PURE__*/jsx(Title, {
12346
- type: Typography.TITLE_BODY,
12347
- className: "m-b-1",
12348
- children: usLabel
12349
- }), usPlaceholder && /*#__PURE__*/jsx(Body, {
12350
- as: "p",
12351
- type: Typography.BODY_LARGE,
12352
- className: "m-b-3",
12353
- children: `${usPlaceholder}`
12354
- }), /*#__PURE__*/jsx(Button, {
12355
- disabled: usDisabled,
12356
- onClick: getMediaFile,
12357
- children: usButtonText || /*#__PURE__*/jsx(Upload$2, {
12358
- size: 24,
12359
- className: "m-r-0"
12360
- })
12361
- })]
12362
- })
12363
- })
12364
- });
12365
- };
12366
- MediaUploadStep.propTypes = {
12367
- fileDropped: PropTypes.func.isRequired,
12368
- isComplete: PropTypes.bool.isRequired,
12369
- usAccept: PropTypes.string.isRequired,
12370
- usButtonText: PropTypes.string.isRequired,
12371
- usDisabled: PropTypes.bool.isRequired,
12372
- usHelpImage: PropTypes.node.isRequired,
12373
- usLabel: PropTypes.string.isRequired,
12374
- usPlaceholder: PropTypes.string.isRequired
12375
- };
12376
-
12377
- const ProcessingStep = props => {
12378
- const {
12379
- isComplete,
12380
- isError,
12381
- isSuccess,
12382
- onAnimationCompleted,
12383
- onClear,
12384
- psButtonText,
12385
- psProcessingText,
12386
- psButtonDisabled
12387
- } = props;
12388
- const {
12389
- isModern
12390
- } = useTheme();
12177
+ isError,
12178
+ isSuccess,
12179
+ onAnimationCompleted,
12180
+ onClear,
12181
+ psButtonText,
12182
+ psProcessingText,
12183
+ psButtonDisabled
12184
+ }) {
12391
12185
  let processStatus = Status.PROCESSING;
12392
12186
  if (isError) {
12393
12187
  processStatus = Status.FAILED;
@@ -12401,53 +12195,33 @@ const ProcessingStep = props => {
12401
12195
  children: /*#__PURE__*/jsxs("div", {
12402
12196
  className: "droppable-card-content",
12403
12197
  children: [/*#__PURE__*/jsx(ProcessIndicator, {
12404
- size: Size.Small,
12405
12198
  status: processStatus,
12406
12199
  onAnimationCompleted: status => onAnimationCompleted(status)
12407
12200
  }), /*#__PURE__*/jsx(Title, {
12408
- className: classNames({
12409
- 'm-t-3': !isModern,
12410
- 'm-b-3': !isModern,
12411
- 'm-t-2': isModern,
12412
- 'm-b-2': isModern
12413
- }),
12201
+ className: "m-y-2",
12414
12202
  type: Typography.TITLE_BODY,
12415
12203
  "aria-live": "polite",
12416
12204
  children: psProcessingText
12417
12205
  }), psButtonText && /*#__PURE__*/jsx(Button, {
12418
12206
  disabled: psButtonDisabled,
12419
- onClick: event => onClear(event),
12207
+ onClick: onClear,
12420
12208
  children: psButtonText
12421
12209
  })]
12422
12210
  })
12423
12211
  });
12424
- };
12425
- ProcessingStep.propTypes = {
12426
- isComplete: PropTypes.bool.isRequired,
12427
- isError: PropTypes.bool.isRequired,
12428
- isSuccess: PropTypes.bool.isRequired,
12429
- onAnimationCompleted: PropTypes.func.isRequired,
12430
- onClear: PropTypes.func.isRequired,
12431
- psButtonText: PropTypes.string.isRequired,
12432
- psProcessingText: PropTypes.string.isRequired,
12433
- psButtonDisabled: PropTypes.bool.isRequired
12434
- };
12212
+ }
12435
12213
 
12436
- const CompleteStep = props => {
12437
- const {
12438
- isModern
12439
- } = useTheme();
12440
- const {
12441
- csButtonText,
12442
- csFailureText,
12443
- csSuccessText,
12444
- fileName,
12445
- isComplete,
12446
- isError,
12447
- isImage,
12448
- onClear,
12449
- uploadedImage
12450
- } = props;
12214
+ function CompleteStep({
12215
+ csButtonText,
12216
+ csFailureText,
12217
+ csSuccessText,
12218
+ fileName,
12219
+ isComplete,
12220
+ isError,
12221
+ isImage,
12222
+ onClear,
12223
+ uploadedImage
12224
+ }) {
12451
12225
  return /*#__PURE__*/jsx("div", {
12452
12226
  className: "droppable-complete-card droppable-card",
12453
12227
  "aria-hidden": !isComplete,
@@ -12457,16 +12231,11 @@ const CompleteStep = props => {
12457
12231
  className: "droppable-card-content d-flex flex-column align-items-center",
12458
12232
  "aria-live": "polite",
12459
12233
  children: isError ? /*#__PURE__*/jsxs(Fragment, {
12460
- children: [isModern ? /*#__PURE__*/jsx(StatusIcon, {
12234
+ children: [/*#__PURE__*/jsx(StatusIcon, {
12461
12235
  size: Size.LARGE,
12462
12236
  sentiment: Sentiment.NEGATIVE
12463
- }) : /*#__PURE__*/jsx(AlertCircle, {
12464
- size: 24,
12465
- className: "text-negative"
12466
12237
  }), csFailureText && /*#__PURE__*/jsx("p", {
12467
- className: classNames('m-t-2', {
12468
- 'm-b-0': isModern
12469
- }),
12238
+ className: "m-t-2 m-b-0",
12470
12239
  children: csFailureText
12471
12240
  })]
12472
12241
  }) : /*#__PURE__*/jsxs(Fragment, {
@@ -12485,71 +12254,135 @@ const CompleteStep = props => {
12485
12254
  })]
12486
12255
  })
12487
12256
  }), csButtonText && /*#__PURE__*/jsx(Button, {
12488
- priority: isModern ? Priority.PRIMARY : Priority.SECONDARY,
12489
- className: classNames({
12490
- 'm-t-1': isModern && !isError,
12491
- 'm-t-2': isModern && isError,
12492
- 'm-t-3': !isModern
12493
- }),
12494
- onClick: event => onClear(event),
12257
+ className: isError ? 'm-t-2' : 'm-t-1',
12258
+ onClick: onClear,
12495
12259
  children: csButtonText
12496
12260
  })]
12497
12261
  })
12498
12262
  });
12499
- };
12500
- CompleteStep.propTypes = {
12501
- csButtonText: PropTypes.string.isRequired,
12502
- csSuccessText: PropTypes.string.isRequired,
12503
- csFailureText: PropTypes.string.isRequired,
12504
- fileName: PropTypes.string.isRequired,
12505
- isComplete: PropTypes.bool.isRequired,
12506
- isError: PropTypes.bool.isRequired,
12507
- isImage: PropTypes.bool.isRequired,
12508
- onClear: PropTypes.func.isRequired,
12509
- uploadedImage: PropTypes.string
12510
- };
12511
- CompleteStep.defaultProps = {
12512
- uploadedImage: null
12513
- };
12263
+ }
12514
12264
 
12515
- const PROCESS_STATE = ['error', 'success'];
12265
+ class ResponseError extends Error {
12266
+ response;
12267
+ status;
12268
+ constructor(response, message) {
12269
+ super(message);
12270
+ this.name = 'ResponseError';
12271
+ this.response = response;
12272
+ this.status = response.status;
12273
+ }
12274
+ }
12275
+ async function postData({
12276
+ url,
12277
+ method = 'POST',
12278
+ ...httpOptions
12279
+ }, data, fetcher = fetch) {
12280
+ const response = await fetcher(url, {
12281
+ method,
12282
+ body: data,
12283
+ ...httpOptions
12284
+ });
12285
+ if (!response.ok) {
12286
+ throw new ResponseError(response, response.statusText);
12287
+ }
12288
+ return response;
12289
+ }
12290
+
12291
+ async function asyncFileRead(file) {
12292
+ return new Promise((resolve, reject) => {
12293
+ const reader = new FileReader();
12294
+ reader.addEventListener('load', () => {
12295
+ resolve(reader.result);
12296
+ });
12297
+ reader.addEventListener('error', () => {
12298
+ reject(reader.error ?? new Error('Cannot read file'));
12299
+ });
12300
+ reader.readAsDataURL(file);
12301
+ });
12302
+ }
12303
+
12304
+ function isSizeValid(file, maxSize) {
12305
+ return Number.isInteger(maxSize) && file.size <= maxSize;
12306
+ }
12307
+
12308
+ function getFileType(file, file64) {
12309
+ if (file.type) {
12310
+ return file.type;
12311
+ }
12312
+ if (file64) {
12313
+ const regex = /^data:([a-z]+\/[a-z]+);/;
12314
+ const typeFromEncoded = regex.exec(file64);
12315
+ if (typeFromEncoded?.[1]) {
12316
+ return typeFromEncoded[1];
12317
+ }
12318
+ }
12319
+ return '';
12320
+ }
12321
+
12322
+ function isTypeValid(file, rule, file64) {
12323
+ if (!rule) {
12324
+ return false;
12325
+ }
12326
+ const allowedTypes = rule.replace(/\s/g, '').split(',');
12327
+ const fileType = getFileType(file, file64);
12328
+ if (rule === '*' || allowedTypes.includes(fileType)) {
12329
+ return true;
12330
+ }
12331
+ return allowedTypes.some(type => {
12332
+ const [typeAllowed, extensionAllowed] = type.split('/');
12333
+ return extensionAllowed === '*' && fileType.includes(typeAllowed);
12334
+ });
12335
+ }
12516
12336
 
12517
- /*
12518
- * This delay is required for the isError/isSuccess to be fired after isProcessing so the processIndicator, will be
12519
- * rendered first and then updated with the right status.
12520
- */
12521
12337
  const ANIMATION_FIX = 10;
12522
12338
  const MAX_SIZE_DEFAULT = 5000000;
12523
- const UPLOAD_STEP_COMPONENTS = {
12524
- [UploadStep.UPLOAD_IMAGE_STEP]: UploadImageStep,
12525
- [UploadStep.MEDIA_UPLOAD_STEP]: MediaUploadStep
12526
- };
12339
+ var UploadStep;
12340
+ (function (UploadStep) {
12341
+ UploadStep["UPLOAD_IMAGE_STEP"] = "uploadImageStep";
12342
+ })(UploadStep || (UploadStep = {}));
12527
12343
  class Upload extends Component {
12344
+ static defaultProps = {
12345
+ animationDelay: 700,
12346
+ maxSize: MAX_SIZE_DEFAULT,
12347
+ psButtonDisabled: false,
12348
+ size: 'md',
12349
+ usAccept: 'image/*',
12350
+ usDisabled: false,
12351
+ usLabel: ''
12352
+ };
12353
+ dragCounter = 0;
12354
+ timeouts = 0;
12528
12355
  constructor(props) {
12529
12356
  super(props);
12530
- this.dragCounter = 0;
12531
- this.timeouts = null;
12532
12357
  this.state = {
12533
12358
  fileName: '',
12359
+ isDroppable: false,
12534
12360
  isComplete: false,
12535
12361
  isError: false,
12536
12362
  isImage: false,
12537
12363
  isProcessing: false,
12538
12364
  isSuccess: false,
12539
- response: null,
12540
- uploadedImage: null
12365
+ response: undefined,
12366
+ uploadedImage: undefined
12541
12367
  };
12542
12368
  }
12543
12369
  getErrorMessage(status) {
12370
+ const {
12371
+ csFailureText,
12372
+ csTooLargeMessage,
12373
+ csWrongTypeMessage,
12374
+ maxSize,
12375
+ intl
12376
+ } = this.props;
12544
12377
  switch (status) {
12545
12378
  case 413:
12546
- return this.props.csTooLargeMessage || this.props.intl.formatMessage(messages.csTooLargeMessage, {
12547
- maxSize: this.props.maxSize / 1000000
12379
+ return csTooLargeMessage || intl.formatMessage(messages.csTooLargeMessage, {
12380
+ maxSize: maxSize / 1000000
12548
12381
  });
12549
12382
  case 415:
12550
- return this.props.csWrongTypeMessage || this.props.intl.formatMessage(messages.csWrongTypeMessage);
12383
+ return csWrongTypeMessage || intl.formatMessage(messages.csWrongTypeMessage);
12551
12384
  default:
12552
- return this.props.csFailureText || this.props.intl.formatMessage(messages.csFailureText);
12385
+ return csFailureText || intl.formatMessage(messages.csFailureText);
12553
12386
  }
12554
12387
  }
12555
12388
  onDragLeave(event) {
@@ -12576,7 +12409,7 @@ class Upload extends Component {
12576
12409
  });
12577
12410
  }
12578
12411
  }
12579
- onDrop(event) {
12412
+ async onDrop(event) {
12580
12413
  const {
12581
12414
  isProcessing
12582
12415
  } = this.state;
@@ -12584,8 +12417,8 @@ class Upload extends Component {
12584
12417
  if (!isProcessing) {
12585
12418
  this.reset();
12586
12419
  }
12587
- if (event.dataTransfer && event.dataTransfer.files && event.dataTransfer.files[0]) {
12588
- this.fileDropped(event.dataTransfer.files[0]);
12420
+ if (event.dataTransfer?.files?.[0]) {
12421
+ await this.fileDropped(event.dataTransfer.files[0]);
12589
12422
  }
12590
12423
  }
12591
12424
  onAnimationCompleted = async status => {
@@ -12594,77 +12427,70 @@ class Upload extends Component {
12594
12427
  isProcessing,
12595
12428
  fileName
12596
12429
  } = this.state;
12597
- // Success.
12598
12430
  const {
12599
12431
  animationDelay
12600
12432
  } = this.props;
12601
- if (isProcessing && status === Status.SUCCEEDED) {
12433
+ if (isProcessing && status === 'succeeded') {
12602
12434
  const {
12603
12435
  onSuccess
12604
12436
  } = this.props;
12605
- this.timeouts = setTimeout(() => {
12437
+ this.timeouts = window.setTimeout(() => {
12606
12438
  this.setState({
12607
12439
  isProcessing: false,
12608
12440
  isComplete: true
12609
- }, () => onSuccess ? onSuccess(response, fileName) : {});
12441
+ }, onSuccess ? () => onSuccess(response, fileName) : undefined);
12610
12442
  }, animationDelay);
12611
12443
  }
12612
- // Failure.
12613
- if (isProcessing && status === Status.FAILED) {
12444
+ if (isProcessing && status === 'failed') {
12614
12445
  const {
12615
12446
  onFailure
12616
12447
  } = this.props;
12617
- this.timeouts = setTimeout(() => {
12448
+ this.timeouts = window.setTimeout(() => {
12618
12449
  this.setState({
12619
12450
  isProcessing: false,
12620
12451
  isComplete: true
12621
- }, () => onFailure ? onFailure(response) : {});
12452
+ }, onFailure ? () => onFailure(response) : undefined);
12622
12453
  }, animationDelay);
12623
12454
  }
12624
12455
  };
12625
- asyncPost = file => {
12456
+ asyncPost = async file => {
12626
12457
  const {
12627
12458
  httpOptions,
12628
12459
  fetcher
12629
12460
  } = this.props;
12461
+ if (httpOptions == null) {
12462
+ throw new Error('Cannot find HTTP options');
12463
+ }
12630
12464
  const {
12631
12465
  fileInputName = file.name,
12632
12466
  data = {}
12633
- } = httpOptions || {};
12467
+ } = httpOptions;
12634
12468
  const formData = new FormData();
12635
12469
  formData.append(fileInputName, file);
12636
12470
  Object.keys(data).forEach(key => formData.append(key, data[key]));
12637
- return postData(this.prepareHttpOptions(httpOptions), formData, fetcher);
12471
+ return postData(httpOptions, formData, fetcher);
12638
12472
  };
12639
12473
  asyncResponse = (response, type) => {
12640
12474
  // Gives time to the animation callback to fire.
12641
- this.timeouts = setTimeout(() => {
12475
+ this.timeouts = window.setTimeout(() => {
12642
12476
  this.setState({
12643
12477
  response,
12644
- isError: type === PROCESS_STATE[0],
12645
- isSuccess: type === PROCESS_STATE[1]
12478
+ isError: type === 'error',
12479
+ isSuccess: type === 'success'
12646
12480
  });
12647
12481
  }, ANIMATION_FIX);
12648
12482
  };
12649
- prepareHttpOptions = httpOptions => {
12650
- if (!httpOptions.url) {
12651
- throw new Error('You must supply a URL to post image data asynchronously');
12652
- }
12653
- return httpOptions;
12654
- };
12655
12483
  handleOnClear = event => {
12656
12484
  event.preventDefault();
12657
12485
  const {
12658
12486
  onCancel
12659
12487
  } = this.props;
12660
- if (onCancel) {
12661
- onCancel();
12662
- }
12488
+ onCancel?.();
12663
12489
  this.reset();
12664
12490
  };
12665
12491
  reset = () => {
12666
12492
  this.dragCounter = 0;
12667
- clearTimeout(this.timeouts);
12493
+ window.clearTimeout(this.timeouts);
12668
12494
  this.setState({
12669
12495
  isComplete: false,
12670
12496
  isError: false,
@@ -12704,14 +12530,12 @@ class Upload extends Component {
12704
12530
  isDroppable: false,
12705
12531
  isProcessing: true
12706
12532
  });
12707
- if (onStart) {
12708
- onStart(file);
12709
- }
12533
+ onStart?.(file);
12710
12534
  let file64 = null;
12711
12535
  try {
12712
12536
  file64 = await asyncFileRead(file);
12713
12537
  } catch (error) {
12714
- this.asyncResponse(error, PROCESS_STATE[0]);
12538
+ this.asyncResponse(error, 'error');
12715
12539
  }
12716
12540
  if (!file64) {
12717
12541
  return false;
@@ -12720,30 +12544,31 @@ class Upload extends Component {
12720
12544
  isImage: getFileType(file, file64).includes('image')
12721
12545
  });
12722
12546
  if (!isTypeValid(file, usAccept, file64)) {
12723
- const response = {
12547
+ this.asyncResponse(new ResponseError(new Response(null, {
12724
12548
  status: 415,
12725
12549
  statusText: 'Unsupported Media Type'
12726
- };
12727
- this.asyncResponse(response, PROCESS_STATE[0]);
12550
+ })), 'error');
12728
12551
  return false;
12729
12552
  }
12730
12553
  if (!isSizeValid(file, maxSize)) {
12731
- const response = {
12554
+ this.asyncResponse(new ResponseError(new Response(null, {
12732
12555
  status: 413,
12733
12556
  statusText: 'Request Entity Too Large'
12734
- };
12735
- this.asyncResponse(response, PROCESS_STATE[0]);
12557
+ })), 'error');
12736
12558
  return false;
12737
12559
  }
12738
12560
  if (httpOptions) {
12739
12561
  // Post the file to provided endpoint
12740
- return await this.asyncPost(file).then(response => this.asyncResponse(response, 'success')).then(() => {
12741
- this.showDataImage(file64);
12742
- return true;
12743
- }).catch(error => {
12744
- this.asyncResponse(error, PROCESS_STATE[0]);
12562
+ let response;
12563
+ try {
12564
+ response = await this.asyncPost(file);
12565
+ } catch (error) {
12566
+ this.asyncResponse(error, 'error');
12745
12567
  return false;
12746
- });
12568
+ }
12569
+ this.asyncResponse(response, 'success');
12570
+ this.showDataImage(file64);
12571
+ return true;
12747
12572
  }
12748
12573
  // Post on form submit. And return the encoded image.
12749
12574
  this.showDataImage(file64);
@@ -12752,6 +12577,7 @@ class Upload extends Component {
12752
12577
  };
12753
12578
  render() {
12754
12579
  const {
12580
+ maxSize,
12755
12581
  usDropMessage,
12756
12582
  usAccept,
12757
12583
  usButtonText,
@@ -12765,7 +12591,6 @@ class Upload extends Component {
12765
12591
  csButtonText,
12766
12592
  csSuccessText,
12767
12593
  size,
12768
- uploadStep,
12769
12594
  intl
12770
12595
  } = this.props;
12771
12596
  const {
@@ -12779,7 +12604,6 @@ class Upload extends Component {
12779
12604
  isSuccess,
12780
12605
  uploadedImage
12781
12606
  } = this.state;
12782
- const UploadStepComponent = UPLOAD_STEP_COMPONENTS[uploadStep] || UploadImageStep;
12783
12607
  return /*#__PURE__*/jsxs("div", {
12784
12608
  className: classNames('droppable-area', {
12785
12609
  droppable: true,
@@ -12793,10 +12617,10 @@ class Upload extends Component {
12793
12617
  }),
12794
12618
  onDragEnter: event => this.onDragEnter(event),
12795
12619
  onDragLeave: event => this.onDragLeave(event),
12796
- onDrop: event => this.onDrop(event),
12620
+ onDrop: async event => this.onDrop(event),
12797
12621
  onDragOver: event => event.preventDefault(),
12798
- children: [!isProcessing && !isComplete && /*#__PURE__*/jsx(UploadStepComponent, {
12799
- fileDropped: file => this.fileDropped(file),
12622
+ children: [!isProcessing && !isComplete && /*#__PURE__*/jsx(UploadImageStep, {
12623
+ fileDropped: async file => this.fileDropped(file),
12800
12624
  isComplete: isComplete,
12801
12625
  usAccept: usAccept,
12802
12626
  usButtonText: usButtonText || intl.formatMessage(messages.usButtonText),
@@ -12804,7 +12628,7 @@ class Upload extends Component {
12804
12628
  usHelpImage: usHelpImage,
12805
12629
  usLabel: usLabel,
12806
12630
  usPlaceholder: usPlaceholder || intl.formatMessage(messages.usPlaceholder, {
12807
- maxSize: this.props.maxSize / 1000000
12631
+ maxSize: maxSize / 1000000
12808
12632
  })
12809
12633
  }), isProcessing && /*#__PURE__*/jsx(ProcessingStep, {
12810
12634
  isComplete: isComplete,
@@ -12813,7 +12637,7 @@ class Upload extends Component {
12813
12637
  psButtonText: psButtonText || intl.formatMessage(messages.psButtonText),
12814
12638
  psProcessingText: psProcessingText || intl.formatMessage(messages.psProcessingText),
12815
12639
  psButtonDisabled: psButtonDisabled,
12816
- onAnimationCompleted: status => this.onAnimationCompleted(status),
12640
+ onAnimationCompleted: async status => this.onAnimationCompleted(status),
12817
12641
  onClear: event => this.handleOnClear(event)
12818
12642
  }), (isSuccess || isError || isComplete) && /*#__PURE__*/jsx(CompleteStep, {
12819
12643
  fileName: fileName,
@@ -12821,7 +12645,7 @@ class Upload extends Component {
12821
12645
  isError: isError,
12822
12646
  isImage: isImage,
12823
12647
  csButtonText: csButtonText || intl.formatMessage(messages.csButtonText),
12824
- csFailureText: this.getErrorMessage(response?.status),
12648
+ csFailureText: this.getErrorMessage(response != null && typeof response === 'object' && 'status' in response && typeof response.status === 'number' ? response.status : undefined),
12825
12649
  csSuccessText: csSuccessText || intl.formatMessage(messages.csSuccessText),
12826
12650
  uploadedImage: uploadedImage,
12827
12651
  onClear: event => this.handleOnClear(event)
@@ -12845,73 +12669,6 @@ class Upload extends Component {
12845
12669
  });
12846
12670
  }
12847
12671
  }
12848
- Upload.propTypes = {
12849
- animationDelay: PropTypes.number,
12850
- csButtonText: PropTypes.string,
12851
- csFailureText: PropTypes.string,
12852
- csSuccessText: PropTypes.string,
12853
- csTooLargeMessage: PropTypes.string,
12854
- csWrongTypeMessage: PropTypes.string,
12855
- httpOptions: PropTypes.shape({
12856
- url: PropTypes.string.isRequired,
12857
- method: PropTypes.oneOf(['POST', 'PUT', 'PATCH']),
12858
- fileInputName: PropTypes.string,
12859
- data: PropTypes.object,
12860
- headers: PropTypes.object
12861
- }),
12862
- /**
12863
- * You can provide a fetcher function with the same interface as the global fetch function, which is used by default.
12864
- * function fetcher(input: RequestInfo, init?: RequestInit): Promise<Response>
12865
- */
12866
- fetcher: PropTypes.func,
12867
- maxSize: PropTypes.number,
12868
- onCancel: PropTypes.func,
12869
- onFailure: PropTypes.func,
12870
- onStart: PropTypes.func,
12871
- onSuccess: PropTypes.func,
12872
- psButtonText: PropTypes.string,
12873
- psButtonDisabled: PropTypes.bool,
12874
- psProcessingText: PropTypes.string,
12875
- size: PropTypes.oneOf(['sm', 'md', 'lg']),
12876
- /**
12877
- * You can provide multiple rules separated by comma, e.g.: "application/pdf,image/*".
12878
- * Using "*" will allow every file type to be uploaded.
12879
- */
12880
- usAccept: PropTypes.string,
12881
- usButtonText: PropTypes.string,
12882
- usDisabled: PropTypes.bool,
12883
- usDropMessage: PropTypes.string,
12884
- usHelpImage: PropTypes.node,
12885
- usLabel: PropTypes.string,
12886
- usPlaceholder: PropTypes.string,
12887
- uploadStep: PropTypes.oneOf(['uploadImageStep', 'mediaUploadStep'])
12888
- };
12889
- Upload.defaultProps = {
12890
- animationDelay: 700,
12891
- csButtonText: undefined,
12892
- csFailureText: undefined,
12893
- csSuccessText: undefined,
12894
- csTooLargeMessage: undefined,
12895
- csWrongTypeMessage: undefined,
12896
- httpOptions: null,
12897
- maxSize: MAX_SIZE_DEFAULT,
12898
- onCancel: null,
12899
- onFailure: null,
12900
- onStart: null,
12901
- onSuccess: null,
12902
- psButtonText: undefined,
12903
- psButtonDisabled: false,
12904
- psProcessingText: undefined,
12905
- size: 'md',
12906
- usAccept: 'image/*',
12907
- usButtonText: undefined,
12908
- usDisabled: false,
12909
- usDropMessage: undefined,
12910
- usHelpImage: '',
12911
- usLabel: '',
12912
- usPlaceholder: undefined,
12913
- uploadStep: UploadStep.UPLOAD_IMAGE_STEP
12914
- };
12915
12672
  var Upload$1 = injectIntl(Upload);
12916
12673
 
12917
12674
  var MESSAGES$2 = defineMessages({
@@ -13442,7 +13199,7 @@ const UploadInput = ({
13442
13199
  name
13443
13200
  } = file;
13444
13201
  const id = generateFileId(file);
13445
- const allowedFileTypes = Array.isArray(fileTypes) ? fileTypes.join(',') : fileTypes;
13202
+ const allowedFileTypes = typeof fileTypes === 'string' ? fileTypes : fileTypes.join(',');
13446
13203
  // Check if file type is valid
13447
13204
  if (!isTypeValid(file, allowedFileTypes)) {
13448
13205
  handleFileUploadFailure(file, formatMessage(MESSAGES$2.fileTypeNotSupported));