@aws-amplify/ui-react-storage 2.3.2 → 3.0.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 (45) hide show
  1. package/dist/esm/components/StorageImage/StorageImage.mjs +31 -1
  2. package/dist/esm/components/StorageManager/StorageManager.mjs +168 -1
  3. package/dist/esm/components/StorageManager/hooks/useStorageManager/actions.mjs +49 -1
  4. package/dist/esm/components/StorageManager/hooks/useStorageManager/reducer.mjs +130 -1
  5. package/dist/esm/components/StorageManager/hooks/useStorageManager/types.mjs +12 -1
  6. package/dist/esm/components/StorageManager/hooks/useStorageManager/useStorageManager.mjs +58 -1
  7. package/dist/esm/components/StorageManager/hooks/useUploadFiles/resolveFile.mjs +22 -1
  8. package/dist/esm/components/StorageManager/hooks/useUploadFiles/useUploadFiles.mjs +64 -1
  9. package/dist/esm/components/StorageManager/types.mjs +11 -1
  10. package/dist/esm/components/StorageManager/ui/Container/Container.mjs +8 -1
  11. package/dist/esm/components/StorageManager/ui/DropZone/DropZone.mjs +16 -1
  12. package/dist/esm/components/StorageManager/ui/FileList/FileControl.mjs +23 -1
  13. package/dist/esm/components/StorageManager/ui/FileList/FileDetails.mjs +14 -1
  14. package/dist/esm/components/StorageManager/ui/FileList/FileList.mjs +44 -1
  15. package/dist/esm/components/StorageManager/ui/FileList/FileRemoveButton.mjs +12 -1
  16. package/dist/esm/components/StorageManager/ui/FileList/FileStatusMessage.mjs +28 -1
  17. package/dist/esm/components/StorageManager/ui/FileList/FileThumbnail.mjs +12 -1
  18. package/dist/esm/components/StorageManager/ui/FileListFooter/FileListFooter.mjs +13 -1
  19. package/dist/esm/components/StorageManager/ui/FileListHeader/FileListHeader.mjs +14 -1
  20. package/dist/esm/components/StorageManager/ui/FilePicker/FilePicker.mjs +9 -1
  21. package/dist/esm/components/StorageManager/utils/checkMaxFileSize.mjs +12 -1
  22. package/dist/esm/components/StorageManager/utils/displayText.mjs +39 -1
  23. package/dist/esm/components/StorageManager/utils/filterAllowedFiles.mjs +27 -1
  24. package/dist/esm/components/StorageManager/utils/humanFileSize.mjs +29 -1
  25. package/dist/esm/components/StorageManager/utils/uploadFile.mjs +29 -1
  26. package/dist/esm/index.mjs +2 -1
  27. package/dist/esm/version.mjs +3 -0
  28. package/dist/index.js +782 -1
  29. package/dist/styles.css +298 -684
  30. package/dist/types/components/StorageImage/StorageImage.d.ts +1 -1
  31. package/dist/types/components/StorageImage/types.d.ts +3 -2
  32. package/dist/types/components/StorageManager/hooks/useStorageManager/actions.d.ts +2 -2
  33. package/dist/types/components/StorageManager/hooks/useStorageManager/types.d.ts +2 -2
  34. package/dist/types/components/StorageManager/hooks/useStorageManager/useStorageManager.d.ts +2 -2
  35. package/dist/types/components/StorageManager/hooks/useUploadFiles/useUploadFiles.d.ts +2 -2
  36. package/dist/types/components/StorageManager/types.d.ts +4 -8
  37. package/dist/types/components/StorageManager/ui/FileList/types.d.ts +8 -8
  38. package/dist/types/components/StorageManager/ui/FileListFooter/FileListFooter.d.ts +2 -2
  39. package/dist/types/components/StorageManager/ui/FileListHeader/FileListHeader.d.ts +2 -2
  40. package/dist/types/components/StorageManager/utils/displayText.d.ts +22 -20
  41. package/dist/types/components/StorageManager/utils/index.d.ts +1 -1
  42. package/dist/types/components/StorageManager/utils/uploadFile.d.ts +4 -10
  43. package/dist/types/version.d.ts +1 -0
  44. package/package.json +8 -39
  45. package/dist/types/components/StorageImage/_tests_/StorageImage.test.d.ts +0 -1
package/dist/index.js CHANGED
@@ -1 +1,782 @@
1
- "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("tslib"),a=require("react"),t=require("classnames"),s=require("@aws-amplify/ui-react"),l=require("@aws-amplify/ui-react/internal"),r=require("aws-amplify"),n=require("@aws-amplify/ui");function i(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}function o(e){if(e&&e.__esModule)return e;var a=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var s=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(a,t,s.get?s:{enumerable:!0,get:function(){return e[t]}})}})),a.default=e,Object.freeze(a)}var c=o(a),u=i(a),d=i(t);var m,g;function p(e,a){switch(a.type){case g.ADD_FILES:{const{files:t,status:s}=a,l=t.map((e=>{const t=a.getFileErrorMessage(e);return{id:e.name,file:e,error:t,key:e.name,status:t?m.ERROR:s,isImage:e.type.startsWith("image/"),progress:-1}})),r=[...e.files,...l];return Object.assign(Object.assign({},e),{files:r})}case g.CLEAR_FILES:return Object.assign(Object.assign({},e),{files:[]});case g.QUEUE_FILES:{const{files:a}=e,t=a.reduce(((e,a)=>[...e,Object.assign(Object.assign({},a),{status:m.QUEUED})]),[]);return Object.assign(Object.assign({},e),{files:t})}case g.SET_STATUS_UPLOADING:{const{id:t,uploadTask:s}=a,{files:l}=e,r=l.reduce(((e,a)=>a.id===t?[...e,Object.assign(Object.assign({},a),{status:m.UPLOADING,progress:0,uploadTask:s||void 0})]:[...e,a]),[]);return Object.assign(Object.assign({},e),{files:r})}case g.SET_UPLOAD_PROGRESS:{const{id:t,progress:s}=a,{files:l}=e,r=l.reduce(((e,a)=>a.id===t?[...e,Object.assign(Object.assign({},a),{progress:s})]:[...e,a]),[]);return Object.assign(Object.assign({},e),{files:r})}case g.SET_STATUS:{const{id:t,status:s}=a,{files:l}=e,r=l.reduce(((e,a)=>a.id===t?[...e,Object.assign(Object.assign({},a),{status:s})]:[...e,a]),[]);return Object.assign(Object.assign({},e),{files:r})}case g.REMOVE_UPLOAD:{const{id:t}=a,{files:s}=e,l=s.reduce(((e,a)=>a.id===t?[...e]:[...e,a]),[]);return Object.assign(Object.assign({},e),{files:l})}}}!function(e){e.ADDED="added",e.QUEUED="queued",e.UPLOADING="uploading",e.PAUSED="paused",e.ERROR="error",e.UPLOADED="uploaded"}(m||(m={})),function(e){e.ADD_FILES="ADD_FILES",e.CLEAR_FILES="CLEAR_FILES",e.QUEUE_FILES="QUEUE_FILES",e.SET_STATUS="SET_STATUS",e.SET_STATUS_UPLOADING="SET_STATUS_UPLOADING",e.SET_UPLOAD_PROGRESS="SET_UPLOAD_PROGRESS",e.REMOVE_UPLOAD="REMOVE_UPLOAD"}(g||(g={}));const f=({files:e,status:a,getFileErrorMessage:t})=>({type:g.ADD_FILES,files:e,status:a,getFileErrorMessage:t}),E=()=>({type:g.CLEAR_FILES}),S=()=>({type:g.QUEUE_FILES}),T=({id:e,uploadTask:a})=>({type:g.SET_STATUS_UPLOADING,id:e,uploadTask:a}),U=({id:e,progress:a})=>({type:g.SET_UPLOAD_PROGRESS,id:e,progress:a}),F=({id:e,status:a})=>({type:g.SET_STATUS,id:e,status:a}),C=({id:e})=>({type:g.REMOVE_UPLOAD,id:e}),b=e=>(e=>!(!n.isObject(e)||!e.key))(e)?Object.assign(Object.assign({},e),{id:e.key,status:m.UPLOADED}):void 0;function D(a){var{file:t,key:s,level:l="private",progressCallback:n,errorCallback:i,completeCallback:o,isResumable:c=!1,provider:u}=a,d=e.__rest(a,["file","key","level","progressCallback","errorCallback","completeCallback","isResumable","provider"]);const m=t.type||"binary/octet-stream";return!0===c?r.Storage.put(s,t,Object.assign({level:l,resumable:!0,progressCallback:n,errorCallback:i,completeCallback:o,contentType:m,provider:u},d)):r.Storage.put(s,t,Object.assign({level:l,resumable:!1,progressCallback:n,contentType:m,provider:u},d)).then(o,i)}const x=({processFile:e,file:a,key:t})=>new Promise(((s,l)=>{const r=n.isFunction(e)?e({file:a,key:t}):{file:a,key:t};r instanceof Promise?r.then(s).catch(l):s(r)}));function O({children:e,className:a}){return u.default.createElement(s.View,{className:a},e)}function v({children:e,displayText:a,inDropZone:t,onDragEnter:r,onDragLeave:i,onDragOver:o,onDragStart:c,onDrop:m,testId:g}){var p;const{dropFilesText:f}=a,E=l.useIcons("storageManager");return u.default.createElement(s.View,{className:d.default(t&&n.classNameModifier(s.ComponentClassNames.StorageManagerDropZone,"active"),s.ComponentClassNames.StorageManagerDropZone),"data-testid":g,onDragStart:c,onDragEnter:r,onDragLeave:i,onDrop:m,onDragOver:o},u.default.createElement(s.View,{as:"span","aria-hidden":!0,className:s.ComponentClassNames.StorageManagerDropZoneIcon},null!==(p=null==E?void 0:E.upload)&&void 0!==p?p:u.default.createElement(l.IconUpload,null)),u.default.createElement(s.Text,{className:s.ComponentClassNames.StorageManagerDropZoneText},f),e)}const y=({errorMessage:e,getPausedText:a,getUploadingText:t,percentage:r,status:i,uploadSuccessfulText:o})=>{var c,g;const p=l.useIcons("storageManager");switch(i){case m.UPLOADING:return u.default.createElement(s.Text,{className:s.ComponentClassNames.StorageManagerFileStatus},t(r));case m.PAUSED:return u.default.createElement(s.Text,{className:s.ComponentClassNames.StorageManagerFileStatus},a(r));case m.UPLOADED:return u.default.createElement(s.Text,{className:d.default(s.ComponentClassNames.StorageManagerFileStatus,n.classNameModifier(s.ComponentClassNames.StorageManagerFileStatus,"success"))},u.default.createElement(s.View,{as:"span",fontSize:"xl"},null!==(c=null==p?void 0:p.success)&&void 0!==c?c:u.default.createElement(l.IconCheck,null)),o);case m.ERROR:return u.default.createElement(s.Text,{className:d.default(s.ComponentClassNames.StorageManagerFileStatus,n.classNameModifier(s.ComponentClassNames.StorageManagerFileStatus,"error"))},u.default.createElement(s.View,{as:"span",fontSize:"xl"},null!==(g=null==p?void 0:p.error)&&void 0!==g?g:u.default.createElement(l.IconError,null)),e);default:return null}},N=({altText:e,onClick:a})=>{var t;const r=l.useIcons("storageManager");return u.default.createElement(s.Button,{size:"small",onClick:a},u.default.createElement(s.VisuallyHidden,null,e),u.default.createElement(s.View,{as:"span","aria-hidden":!0,fontSize:"medium"},null!==(t=null==r?void 0:r.remove)&&void 0!==t?t:u.default.createElement(l.IconClose,null)))},L=({displayName:e,fileSize:a})=>u.default.createElement(u.default.Fragment,null,u.default.createElement(s.View,{className:s.ComponentClassNames.StorageManagerFileMain},u.default.createElement(s.Text,{className:s.ComponentClassNames.StorageManagerFileName},e)),u.default.createElement(s.Text,{as:"span",className:s.ComponentClassNames.StorageManagerFileSize},a?n.humanFileSize(a,!0):"")),k=({fileName:e,isImage:a,url:t})=>{var r;const n=l.useIcons("storageManager"),i=a?u.default.createElement(s.Image,{alt:e,src:t}):null!==(r=null==n?void 0:n.file)&&void 0!==r?r:u.default.createElement(l.IconFile,null);return u.default.createElement(s.View,{className:s.ComponentClassNames.StorageManagerFileImage},i)};function P({onPause:e,onResume:a,displayName:t,errorMessage:l,isImage:r,isResumable:n,loaderIsDeterminate:i,onRemove:o,progress:c,showThumbnails:d=!0,size:g,status:p,displayText:f,thumbnailUrl:E}){const{getPausedText:S,getUploadingText:T,uploadSuccessfulText:U,pauseText:F,resumeText:C}=f;return u.default.createElement(s.View,{className:s.ComponentClassNames.StorageManagerFile},u.default.createElement(s.View,{className:s.ComponentClassNames.StorageManagerFileWrapper},d?u.default.createElement(k,{isImage:r,fileName:t,url:E}):null,u.default.createElement(L,{displayName:t,fileSize:g}),p===m.UPLOADING?u.default.createElement(s.Loader,{className:s.ComponentClassNames.StorageManagerLoader,variation:"linear",percentage:c,isDeterminate:i,isPercentageTextHidden:!0}):null,!n||p!==m.UPLOADING&&p!==m.PAUSED?null:p===m.PAUSED?u.default.createElement(s.Button,{onClick:a,size:"small",variation:"link"},C):u.default.createElement(s.Button,{onClick:e,size:"small",variation:"link"},F),u.default.createElement(N,{altText:`Remove file ${t}`,onClick:o})),u.default.createElement(y,{uploadSuccessfulText:U,getUploadingText:T,getPausedText:S,status:p,errorMessage:l,percentage:c}))}function A({displayText:e,files:a,hasMaxFilesError:t,isResumable:l,onCancelUpload:r,onDeleteUpload:n,onResume:i,onPause:o,showThumbnails:c,maxFileCount:d}){if(a.length<1)return null;const{getMaxFilesErrorText:g}=e,p=g(d);return u.default.createElement(s.View,{className:s.ComponentClassNames.StorageManagerFileList},a.map((a=>{const{file:t,status:s,progress:d,error:g,key:p,isImage:f,id:E,uploadTask:S}=a,T=t&&f?URL.createObjectURL(t):"",U=!l||d>0,F=s===m.UPLOADING;return u.default.createElement(P,{displayName:p,errorMessage:g,displayText:e,isImage:f,isUploading:F,isResumable:l,key:E,loaderIsDeterminate:U,onRemove:()=>{l&&(s===m.UPLOADING||s===m.PAUSED)&&S?r({id:E,uploadTask:S}):n({id:E})},onPause:()=>{S&&o({id:E,uploadTask:S})},onResume:()=>{S&&i({id:E,uploadTask:S})},progress:d,showThumbnails:c,size:null==t?void 0:t.size,status:s,thumbnailUrl:T})})),t&&u.default.createElement(s.Alert,{variation:"error",heading:p}))}function M({allUploadsSuccessful:e,displayText:a,fileCount:t,remainingFilesCount:l,selectedFilesCount:r=0}){const{getFilesUploadedText:n,getRemainingFilesText:i,getSelectedFilesText:o}=a;return u.default.createElement(s.Text,{className:s.ComponentClassNames.StorageManagerPreviewerText},r?o(r):e?n(t):i(l))}function h({displayText:e,remainingFilesCount:a,onClearAll:t,onUploadAll:l}){const{clearAllButtonText:r,getUploadButtonText:n}=e;return u.default.createElement(s.View,{className:s.ComponentClassNames.StorageManagerPreviewerFooter},u.default.createElement(s.View,{className:s.ComponentClassNames.StorageManagerPreviewerActions},u.default.createElement(s.Button,{size:"small",variation:"link",onClick:t},r),u.default.createElement(s.Button,{size:"small",variation:"primary",onClick:l},n(a))))}function R(a){var{children:t,className:l=s.ComponentClassNames.StorageManagerFilePicker,size:r="small"}=a,n=e.__rest(a,["children","className","size"]);return u.default.createElement(s.Button,Object.assign({},n,{className:l,size:r}),t)}const I=({file:e,getFileSizeErrorText:a,maxFileSize:t})=>void 0===t?"":e.size>t?a(function(e,a=!1,t=1){const s=a?1e3:1024;if(Math.abs(e)<s)return`${e} B`;const l=a?["kB","MB","GB","TB","PB","EB","ZB","YB"]:["KiB","MiB","GiB","TiB","PiB","EiB","ZiB","YiB"];let r=-1;const n=Math.pow(10,t);do{e/=s,++r}while(Math.round(Math.abs(e)*n)/n>=s&&r<l.length-1);return e.toFixed(t)+" "+l[r]}(t,!0)):"",_={getFilesUploadedText:e=>`${e} ${1===e?"file uploaded":"files uploaded"}`,getFileSizeErrorText:e=>`File size must be below ${e}`,getRemainingFilesText:e=>`${e} ${1===e?"file":"files"} uploading`,getSelectedFilesText:e=>`${e} ${1===e?"file":"files"} selected`,getUploadingText:e=>"Uploading"+(e>0?`: ${e}%`:""),getUploadButtonText:e=>`Upload ${e} ${1===e?"file":"files"}`,getMaxFilesErrorText:e=>`Cannot choose more than ${e} ${1===e?"file":"files"}. Remove files before updating`,getErrorText:e=>e,doneButtonText:"Done",clearAllButtonText:"Clear all",extensionNotAllowedText:"Extension not allowed",browseFilesText:"Browse files",dropFilesText:"Drop files here or",pauseText:"Pause",resumeText:"Resume",uploadSuccessfulText:"Uploaded",getPausedText:e=>`Paused: ${e}%`},j=new r.Logger("Storage.StorageManager");const w=Object.assign(c.forwardRef((function({acceptedFileTypes:a=[],accessLevel:t,autoUpload:r=!0,defaultFiles:n,displayText:i,isResumable:o=!1,maxFileCount:d,maxFileSize:g,onUploadError:y,onUploadSuccess:N,onFileRemove:L,onUploadStart:k,showThumbnails:P=!0,processFile:w,components:B,provider:z,path:G},V){t&&d||j.warn("FileUploader requires accessLevel and maxFileCount props");const $=Object.assign({Container:O,DropZone:v,FileList:A,FilePicker:R,FileListHeader:M,FileListFooter:h},B),Z=void 0===d||"number"==typeof d&&d>1,q=Object.assign(Object.assign({},_),i),{getFileSizeErrorText:Q}=q,H=e=>I({file:e,maxFileSize:g,getFileSizeErrorText:Q}),{addFiles:W,clearFiles:K,files:Y,removeUpload:J,queueFiles:X,setUploadingFile:ee,setUploadPaused:ae,setUploadProgress:te,setUploadSuccess:se,setUploadResumed:le}=function(e=[]){const[{files:a},t]=u.default.useReducer(p,{files:Array.isArray(e)?e.map(b).filter((e=>!!e)):[]});return{removeUpload:({id:e})=>{t(C({id:e}))},setUploadPaused:({id:e})=>{t(F({id:e,status:m.PAUSED}))},setUploadProgress:({progress:e,id:a})=>{t(U({id:a,progress:e}))},setUploadResumed:({id:e})=>{t(F({id:e,status:m.UPLOADING}))},setUploadSuccess:({id:e})=>{t(F({id:e,status:m.UPLOADED}))},setUploadingFile:({uploadTask:e,id:a})=>{t(T({id:a,uploadTask:e}))},queueFiles:()=>{t(S())},addFiles:({files:e,status:a,getFileErrorMessage:s})=>{t(f({files:e,status:a,getFileErrorMessage:s}))},clearFiles:()=>{t(E())},files:a}}(n);c.useImperativeHandle(V,(()=>({clearFiles:K})));const re=l.useDropZone({acceptedFileTypes:a,onDropComplete:({acceptedFiles:e,rejectedFiles:t})=>{t&&t.length>0&&j.warn("Rejected files: ",t);const s=((e,a)=>!a||0===a.length||a.includes("*")?e:e.filter((e=>{const t=e.name||"",s=(e.type||"").toLowerCase(),l=s.replace(/\/.*$/,"");return a.some((e=>{const a=e.trim().toLowerCase();return"."===a.charAt(0)?t.toLowerCase().endsWith(a):a.endsWith("/*")?l===a.replace(/\/.*$/,""):s===a}))})))(e,a);W({files:s,status:r?m.QUEUED:m.ADDED,getFileErrorMessage:H})}}),{dragState:ne}=re,ie=e.__rest(re,["dragState"]);!function({files:a,accessLevel:t,isResumable:s,setUploadProgress:l,setUploadingFile:r,setUploadSuccess:n,onUploadError:i,onUploadSuccess:o,onUploadStart:u,maxFileCount:d,processFile:g,provider:p,path:f=""}){c.useEffect((()=>{const c=a.filter((e=>e.status===m.QUEUED));if(!(c.length>d))for(const{file:a,key:d,id:m}of c){const c=e=>{null==o||o(e),n({id:m})},E=e=>{const a=0===e.total?100:Math.floor(e.loaded/e.total*100);l({id:m,progress:a})},S=e=>{null==i||i(e,{key:d})};a&&x({processFile:g,file:a,key:d}).then((a=>{var{key:l}=a,n=e.__rest(a,["key"]);null==u||u({key:l});const i=D(Object.assign(Object.assign({},n),{isResumable:s,provider:p,key:f+l,level:t,completeCallback:c,progressCallback:E,errorCallback:S}));r({id:m,uploadTask:s?i:void 0})}))}}),[a,t,s,l,r,i,o,u,d,n,g,p,f])}({accessLevel:t,files:Y,isResumable:o,maxFileCount:d,onUploadError:y,onUploadSuccess:N,onUploadStart:k,setUploadingFile:ee,setUploadProgress:te,setUploadSuccess:se,processFile:w,provider:z,path:G});const oe=0!==Y.length&&Y.every((e=>(null==e?void 0:e.status)===m.UPLOADED)),ce=Y.filter((e=>e.progress<100)).length>d,ue=Y.filter((e=>(null==e?void 0:e.status)===m.UPLOADED)).length,de=Y.length-ue,me=r?0:de,ge=Y.length>0,pe=!r&&de>0,fe=c.useRef(null);return c.createElement($.Container,{className:`${s.ComponentClassNames.StorageManager} ${ge?s.ComponentClassNames.StorageManagerPreviewer:""}`},c.createElement($.DropZone,Object.assign({inDropZone:"inactive"!==ne},ie,{displayText:q}),c.createElement(c.Fragment,null,c.createElement($.FilePicker,{onClick:function(){fe.current&&(fe.current.click(),fe.current.value="")}},q.browseFilesText),c.createElement(s.VisuallyHidden,null,c.createElement("input",{type:"file",tabIndex:-1,ref:fe,onChange:e=>{const{files:a}=e.target;a&&0!==a.length&&W({files:Array.from(a),status:r?m.QUEUED:m.ADDED,getFileErrorMessage:H})},multiple:Z,accept:a.join(",")})))),ge?c.createElement($.FileListHeader,{allUploadsSuccessful:oe,displayText:q,fileCount:Y.length,remainingFilesCount:de,selectedFilesCount:me}):null,c.createElement($.FileList,{displayText:q,files:Y,isResumable:o,onCancelUpload:({id:e,uploadTask:a})=>{a.pause(),J({id:e})},onDeleteUpload:({id:e})=>{if(J({id:e}),"function"==typeof L){const a=Y.find((a=>a.id===e));a&&L({key:a.key})}},onResume:({id:e,uploadTask:a})=>{a.resume(),le({id:e})},onPause:({id:e,uploadTask:a})=>{a.pause(),ae({id:e})},showThumbnails:P,hasMaxFilesError:ce,maxFileCount:d}),pe?c.createElement($.FileListFooter,{displayText:q,remainingFilesCount:de,onClearAll:()=>{K()},onUploadAll:()=>{X()}}):null)})),{Container:O,DropZone:v,FileList:A,FileListHeader:M,FileListFooter:h,FilePicker:R});exports.StorageImage=a=>{var{accessLevel:t,className:r,fallbackSrc:n,identityId:i,imgKey:o,onStorageGetError:u}=a,m=e.__rest(a,["accessLevel","className","fallbackSrc","identityId","imgKey","onStorageGetError"]);const g=c.useMemo((()=>({level:t,identityId:i})),[t,i]),p=l.useStorageURL({key:o,options:g,fallbackURL:n,onStorageGetError:u});return c.createElement(s.Image,Object.assign({},m,{className:d.default(s.ComponentClassNames.StorageImage,r),src:p}))},exports.StorageManager=w;
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var React = require('react');
6
+ var ui = require('@aws-amplify/ui');
7
+ var uiReact = require('@aws-amplify/ui-react');
8
+ var internal = require('@aws-amplify/ui-react/internal');
9
+ var uiReactCore = require('@aws-amplify/ui-react-core');
10
+ var storage = require('aws-amplify/storage');
11
+
12
+ function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
13
+
14
+ function _interopNamespace(e) {
15
+ if (e && e.__esModule) return e;
16
+ var n = Object.create(null);
17
+ if (e) {
18
+ Object.keys(e).forEach(function (k) {
19
+ if (k !== 'default') {
20
+ var d = Object.getOwnPropertyDescriptor(e, k);
21
+ Object.defineProperty(n, k, d.get ? d : {
22
+ enumerable: true,
23
+ get: function () { return e[k]; }
24
+ });
25
+ }
26
+ });
27
+ }
28
+ n["default"] = e;
29
+ return Object.freeze(n);
30
+ }
31
+
32
+ var React__namespace = /*#__PURE__*/_interopNamespace(React);
33
+ var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
34
+
35
+ const VERSION = '2.3.1';
36
+
37
+ const StorageImage = ({ accessLevel, className, fallbackSrc, identityId, imgKey, onStorageGetError, validateObjectExistence, ...rest }) => {
38
+ const resolvedValidateObjectExistence = ui.isUndefined(validateObjectExistence)
39
+ ? true
40
+ : validateObjectExistence;
41
+ const options = React__namespace.useMemo(() => ({
42
+ accessLevel,
43
+ identityId,
44
+ validateObjectExistence: resolvedValidateObjectExistence,
45
+ }), [accessLevel, identityId, resolvedValidateObjectExistence]);
46
+ uiReactCore.useSetUserAgent({
47
+ componentName: 'StorageImage',
48
+ packageName: 'react-storage',
49
+ version: VERSION,
50
+ });
51
+ const url = internal.useStorageURL({
52
+ key: imgKey,
53
+ options,
54
+ fallbackURL: fallbackSrc,
55
+ onStorageGetError,
56
+ });
57
+ return (React__namespace.createElement(uiReact.Image, { ...rest, className: ui.classNames(ui.ComponentClassName.StorageImage, className), src: url }));
58
+ };
59
+
60
+ var FileStatus;
61
+ (function (FileStatus) {
62
+ FileStatus["ADDED"] = "added";
63
+ FileStatus["QUEUED"] = "queued";
64
+ FileStatus["UPLOADING"] = "uploading";
65
+ FileStatus["PAUSED"] = "paused";
66
+ FileStatus["ERROR"] = "error";
67
+ FileStatus["UPLOADED"] = "uploaded";
68
+ })(FileStatus || (FileStatus = {}));
69
+
70
+ var StorageManagerActionTypes;
71
+ (function (StorageManagerActionTypes) {
72
+ StorageManagerActionTypes["ADD_FILES"] = "ADD_FILES";
73
+ StorageManagerActionTypes["CLEAR_FILES"] = "CLEAR_FILES";
74
+ StorageManagerActionTypes["QUEUE_FILES"] = "QUEUE_FILES";
75
+ StorageManagerActionTypes["SET_STATUS"] = "SET_STATUS";
76
+ StorageManagerActionTypes["SET_STATUS_UPLOADING"] = "SET_STATUS_UPLOADING";
77
+ StorageManagerActionTypes["SET_UPLOAD_PROGRESS"] = "SET_UPLOAD_PROGRESS";
78
+ StorageManagerActionTypes["REMOVE_UPLOAD"] = "REMOVE_UPLOAD";
79
+ })(StorageManagerActionTypes || (StorageManagerActionTypes = {}));
80
+
81
+ function storageManagerStateReducer(state, action) {
82
+ switch (action.type) {
83
+ case StorageManagerActionTypes.ADD_FILES: {
84
+ const { files, status } = action;
85
+ const newUploads = files.map((file) => {
86
+ const errorText = action.getFileErrorMessage(file);
87
+ return {
88
+ // make sure id is unique,
89
+ // we only use it internally and don't send it to Storage
90
+ id: `${Date.now()}-${file.name}`,
91
+ file,
92
+ error: errorText,
93
+ key: file.name,
94
+ status: errorText ? FileStatus.ERROR : status,
95
+ isImage: file.type.startsWith('image/'),
96
+ progress: -1,
97
+ };
98
+ });
99
+ const newFiles = [...state.files, ...newUploads];
100
+ return {
101
+ ...state,
102
+ files: newFiles,
103
+ };
104
+ }
105
+ case StorageManagerActionTypes.CLEAR_FILES: {
106
+ return {
107
+ ...state,
108
+ files: [],
109
+ };
110
+ }
111
+ case StorageManagerActionTypes.QUEUE_FILES: {
112
+ const { files } = state;
113
+ const newFiles = files.reduce((files, currentFile) => {
114
+ return [
115
+ ...files,
116
+ {
117
+ ...currentFile,
118
+ status: FileStatus.QUEUED,
119
+ },
120
+ ];
121
+ }, []);
122
+ return {
123
+ ...state,
124
+ files: newFiles,
125
+ };
126
+ }
127
+ case StorageManagerActionTypes.SET_STATUS_UPLOADING: {
128
+ const { id, uploadTask } = action;
129
+ const { files } = state;
130
+ const newFiles = files.reduce((files, currentFile) => {
131
+ if (currentFile.id === id) {
132
+ return [
133
+ ...files,
134
+ {
135
+ ...currentFile,
136
+ status: FileStatus.UPLOADING,
137
+ progress: 0,
138
+ uploadTask: uploadTask ? uploadTask : undefined,
139
+ },
140
+ ];
141
+ }
142
+ return [...files, currentFile];
143
+ }, []);
144
+ return {
145
+ ...state,
146
+ files: newFiles,
147
+ };
148
+ }
149
+ case StorageManagerActionTypes.SET_UPLOAD_PROGRESS: {
150
+ const { id, progress } = action;
151
+ const { files } = state;
152
+ const newFiles = files.reduce((files, currentFile) => {
153
+ if (currentFile.id === id) {
154
+ return [
155
+ ...files,
156
+ {
157
+ ...currentFile,
158
+ progress,
159
+ },
160
+ ];
161
+ }
162
+ return [...files, currentFile];
163
+ }, []);
164
+ return {
165
+ ...state,
166
+ files: newFiles,
167
+ };
168
+ }
169
+ case StorageManagerActionTypes.SET_STATUS: {
170
+ const { id, status } = action;
171
+ const { files } = state;
172
+ const newFiles = files.reduce((files, currentFile) => {
173
+ if (currentFile.id === id) {
174
+ return [
175
+ ...files,
176
+ {
177
+ ...currentFile,
178
+ status,
179
+ },
180
+ ];
181
+ }
182
+ return [...files, currentFile];
183
+ }, []);
184
+ return {
185
+ ...state,
186
+ files: newFiles,
187
+ };
188
+ }
189
+ case StorageManagerActionTypes.REMOVE_UPLOAD: {
190
+ const { id } = action;
191
+ const { files } = state;
192
+ const newFiles = files.reduce((files, currentFile) => {
193
+ if (currentFile.id === id) {
194
+ // remove by not returning currentFile
195
+ return [...files];
196
+ }
197
+ return [...files, currentFile];
198
+ }, []);
199
+ return {
200
+ ...state,
201
+ files: newFiles,
202
+ };
203
+ }
204
+ }
205
+ }
206
+
207
+ const addFilesAction = ({ files, status, getFileErrorMessage, }) => {
208
+ return {
209
+ type: StorageManagerActionTypes.ADD_FILES,
210
+ files,
211
+ status,
212
+ getFileErrorMessage,
213
+ };
214
+ };
215
+ const clearFilesAction = () => {
216
+ return {
217
+ type: StorageManagerActionTypes.CLEAR_FILES,
218
+ };
219
+ };
220
+ const queueFilesAction = () => {
221
+ return {
222
+ type: StorageManagerActionTypes.QUEUE_FILES,
223
+ };
224
+ };
225
+ const setUploadingFileAction = ({ id, uploadTask, }) => {
226
+ return {
227
+ type: StorageManagerActionTypes.SET_STATUS_UPLOADING,
228
+ id,
229
+ uploadTask,
230
+ };
231
+ };
232
+ const setUploadProgressAction = ({ id, progress, }) => {
233
+ return {
234
+ type: StorageManagerActionTypes.SET_UPLOAD_PROGRESS,
235
+ id,
236
+ progress,
237
+ };
238
+ };
239
+ const setUploadStatusAction = ({ id, status, }) => {
240
+ return {
241
+ type: StorageManagerActionTypes.SET_STATUS,
242
+ id,
243
+ status,
244
+ };
245
+ };
246
+ const removeUploadAction = ({ id }) => {
247
+ return {
248
+ type: StorageManagerActionTypes.REMOVE_UPLOAD,
249
+ id,
250
+ };
251
+ };
252
+
253
+ const isDefaultFile = (file) => !!(ui.isObject(file) && file.key);
254
+ const createFileFromDefault = (file) => isDefaultFile(file)
255
+ ? { ...file, id: file.key, status: FileStatus.UPLOADED }
256
+ : undefined;
257
+ function useStorageManager(defaultFiles = []) {
258
+ const [{ files }, dispatch] = React__default["default"].useReducer(storageManagerStateReducer, {
259
+ files: (Array.isArray(defaultFiles)
260
+ ? defaultFiles.map(createFileFromDefault).filter((file) => !!file)
261
+ : []),
262
+ });
263
+ const addFiles = ({ files, status, getFileErrorMessage, }) => {
264
+ dispatch(addFilesAction({ files, status, getFileErrorMessage }));
265
+ };
266
+ const clearFiles = () => {
267
+ dispatch(clearFilesAction());
268
+ };
269
+ const queueFiles = () => {
270
+ dispatch(queueFilesAction());
271
+ };
272
+ const setUploadingFile = ({ uploadTask, id, }) => {
273
+ dispatch(setUploadingFileAction({ id, uploadTask }));
274
+ };
275
+ const setUploadProgress = ({ progress, id, }) => {
276
+ dispatch(setUploadProgressAction({ id, progress }));
277
+ };
278
+ const setUploadSuccess = ({ id }) => {
279
+ dispatch(setUploadStatusAction({ id, status: FileStatus.UPLOADED }));
280
+ };
281
+ const setUploadPaused = ({ id }) => {
282
+ dispatch(setUploadStatusAction({ id, status: FileStatus.PAUSED }));
283
+ };
284
+ const setUploadResumed = ({ id }) => {
285
+ dispatch(setUploadStatusAction({ id, status: FileStatus.UPLOADING }));
286
+ };
287
+ const removeUpload = ({ id }) => {
288
+ dispatch(removeUploadAction({ id }));
289
+ };
290
+ return {
291
+ removeUpload,
292
+ setUploadPaused,
293
+ setUploadProgress,
294
+ setUploadResumed,
295
+ setUploadSuccess,
296
+ setUploadingFile,
297
+ queueFiles,
298
+ addFiles,
299
+ clearFiles,
300
+ files,
301
+ };
302
+ }
303
+
304
+ function uploadFile({ file, key, level = 'private', progressCallback, errorCallback, completeCallback, ...rest }) {
305
+ const contentType = file.type || 'binary/octet-stream';
306
+ const input = {
307
+ key,
308
+ data: file,
309
+ options: {
310
+ accessLevel: level,
311
+ contentType,
312
+ onProgress: ({ transferredBytes, totalBytes }) => progressCallback({ transferredBytes, totalBytes }),
313
+ ...rest,
314
+ },
315
+ };
316
+ const output = storage.uploadData(input);
317
+ output.result
318
+ .then(() => {
319
+ if (output.state === 'SUCCESS') {
320
+ completeCallback?.({ key });
321
+ }
322
+ })
323
+ .catch((e) => {
324
+ const error = e;
325
+ errorCallback?.(error.message);
326
+ });
327
+ return output;
328
+ }
329
+
330
+ /**
331
+ * Utility function that takes the processFile prop, along with a file a key
332
+ * and returns a Promise that resolves to { file, key, ..rest }
333
+ * regardless if processFile is defined and if it is sync or async
334
+ */
335
+ const resolveFile = ({ processFile, file, key, }) => {
336
+ return new Promise((resolve, reject) => {
337
+ const result = ui.isFunction(processFile)
338
+ ? processFile({ file, key })
339
+ : { file, key };
340
+ if (result instanceof Promise) {
341
+ result.then(resolve).catch(reject);
342
+ }
343
+ else {
344
+ resolve(result);
345
+ }
346
+ });
347
+ };
348
+
349
+ function useUploadFiles({ files, accessLevel, isResumable, setUploadProgress, setUploadingFile, setUploadSuccess, onUploadError, onUploadSuccess, onUploadStart, maxFileCount, processFile, path = '', }) {
350
+ React__namespace.useEffect(() => {
351
+ const filesReadyToUpload = files.filter((file) => file.status === FileStatus.QUEUED);
352
+ if (filesReadyToUpload.length > maxFileCount) {
353
+ return;
354
+ }
355
+ for (const { file, key, id } of filesReadyToUpload) {
356
+ const onComplete = (event) => {
357
+ onUploadSuccess?.(event);
358
+ setUploadSuccess({ id });
359
+ };
360
+ const onProgress = (event) => {
361
+ /**
362
+ * When a file is zero bytes, the progress.total will equal zero.
363
+ * Therefore, this will prevent a divide by zero error.
364
+ */
365
+ const progressPercentage = event.totalBytes === undefined || event.totalBytes === 0
366
+ ? 100
367
+ : Math.floor((event.transferredBytes / event.totalBytes) * 100);
368
+ setUploadProgress({ id, progress: progressPercentage });
369
+ };
370
+ const onError = (error) => {
371
+ onUploadError?.(error, { key });
372
+ };
373
+ if (file) {
374
+ resolveFile({ processFile, file, key }).then(({ key: processedKey, ...rest }) => {
375
+ onUploadStart?.({ key: processedKey });
376
+ const uploadTask = uploadFile({
377
+ ...rest,
378
+ key: processedKey,
379
+ level: accessLevel,
380
+ progressCallback: onProgress,
381
+ errorCallback: onError,
382
+ completeCallback: onComplete,
383
+ });
384
+ setUploadingFile({
385
+ id,
386
+ uploadTask,
387
+ });
388
+ });
389
+ }
390
+ }
391
+ }, [
392
+ files,
393
+ accessLevel,
394
+ isResumable,
395
+ setUploadProgress,
396
+ setUploadingFile,
397
+ onUploadError,
398
+ onUploadSuccess,
399
+ onUploadStart,
400
+ maxFileCount,
401
+ setUploadSuccess,
402
+ processFile,
403
+ path,
404
+ ]);
405
+ }
406
+
407
+ function Container({ children, className, }) {
408
+ return React__default["default"].createElement(uiReact.View, { className: className }, children);
409
+ }
410
+
411
+ function DropZone({ children, displayText, inDropZone, onDragEnter, onDragLeave, onDragOver, onDragStart, onDrop, testId, }) {
412
+ const { dropFilesText } = displayText;
413
+ const icons = internal.useIcons('storageManager');
414
+ return (React__default["default"].createElement(uiReact.View, { className: ui.classNames(inDropZone &&
415
+ ui.classNameModifier(ui.ComponentClassName.StorageManagerDropZone, 'active'), ui.ComponentClassName.StorageManagerDropZone), "data-testid": testId, onDragStart: onDragStart, onDragEnter: onDragEnter, onDragLeave: onDragLeave, onDrop: onDrop, onDragOver: onDragOver },
416
+ React__default["default"].createElement(uiReact.View, { as: "span", "aria-hidden": true, className: ui.ComponentClassName.StorageManagerDropZoneIcon }, icons?.upload ?? React__default["default"].createElement(internal.IconUpload, null)),
417
+ React__default["default"].createElement(uiReact.Text, { className: ui.ComponentClassName.StorageManagerDropZoneText }, dropFilesText),
418
+ children));
419
+ }
420
+
421
+ const FileStatusMessage = ({ errorMessage, getPausedText, getUploadingText, percentage, status, uploadSuccessfulText, }) => {
422
+ const icons = internal.useIcons('storageManager');
423
+ switch (status) {
424
+ case FileStatus.UPLOADING: {
425
+ return (React__default["default"].createElement(uiReact.Text, { className: ui.ComponentClassName.StorageManagerFileStatus }, getUploadingText(percentage)));
426
+ }
427
+ case FileStatus.PAUSED:
428
+ return (React__default["default"].createElement(uiReact.Text, { className: ui.ComponentClassName.StorageManagerFileStatus }, getPausedText(percentage)));
429
+ case FileStatus.UPLOADED:
430
+ return (React__default["default"].createElement(uiReact.Text, { className: ui.classNames(ui.ComponentClassName.StorageManagerFileStatus, ui.classNameModifier(ui.ComponentClassName.StorageManagerFileStatus, 'success')) },
431
+ React__default["default"].createElement(uiReact.View, { as: "span", fontSize: "xl" }, icons?.success ?? React__default["default"].createElement(internal.IconCheck, null)),
432
+ uploadSuccessfulText));
433
+ case FileStatus.ERROR:
434
+ return (React__default["default"].createElement(uiReact.Text, { className: ui.classNames(ui.ComponentClassName.StorageManagerFileStatus, ui.classNameModifier(ui.ComponentClassName.StorageManagerFileStatus, 'error')) },
435
+ React__default["default"].createElement(uiReact.View, { as: "span", fontSize: "xl" }, icons?.error ?? React__default["default"].createElement(internal.IconError, null)),
436
+ errorMessage));
437
+ default:
438
+ return null;
439
+ }
440
+ };
441
+
442
+ const FileRemoveButton = ({ altText, onClick, }) => {
443
+ const icons = internal.useIcons('storageManager');
444
+ return (React__default["default"].createElement(uiReact.Button, { size: "small", onClick: onClick },
445
+ React__default["default"].createElement(uiReact.VisuallyHidden, null, altText),
446
+ React__default["default"].createElement(uiReact.View, { as: "span", "aria-hidden": true, fontSize: "medium" }, icons?.remove ?? React__default["default"].createElement(internal.IconClose, null))));
447
+ };
448
+
449
+ /**
450
+ * Format bytes as human-readable text.
451
+ *
452
+ * @param bytes Number of bytes.
453
+ * @param si True to use metric (SI) units, aka powers of 1000. False to use
454
+ * binary (IEC), aka powers of 1024.
455
+ * @param dp Number of decimal places to display.
456
+ *
457
+ * @return Formatted string.
458
+ */
459
+ function humanFileSize(bytes, si = false, dp = 1) {
460
+ const thresh = si ? 1000 : 1024;
461
+ if (Math.abs(bytes) < thresh) {
462
+ return `${bytes} B`;
463
+ }
464
+ const units = si
465
+ ? ['kB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']
466
+ : ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'];
467
+ let unit = -1;
468
+ const range = 10 ** dp;
469
+ do {
470
+ bytes /= thresh;
471
+ ++unit;
472
+ } while (Math.round(Math.abs(bytes) * range) / range >= thresh &&
473
+ unit < units.length - 1);
474
+ return bytes.toFixed(dp) + ' ' + units[unit];
475
+ }
476
+
477
+ const checkMaxFileSize = ({ file, getFileSizeErrorText, maxFileSize, }) => {
478
+ if (maxFileSize === undefined)
479
+ return '';
480
+ if (file.size > maxFileSize) {
481
+ return getFileSizeErrorText(humanFileSize(maxFileSize, true));
482
+ }
483
+ return '';
484
+ };
485
+
486
+ const defaultStorageManagerDisplayText = {
487
+ getFilesUploadedText(count) {
488
+ return `${count} ${count === 1 ? 'file uploaded' : 'files uploaded'}`;
489
+ },
490
+ getFileSizeErrorText(sizeText) {
491
+ return `File size must be below ${sizeText}`;
492
+ },
493
+ getRemainingFilesText(count) {
494
+ return `${count} ${count === 1 ? 'file' : 'files'} uploading`;
495
+ },
496
+ getSelectedFilesText(count) {
497
+ return `${count} ${count === 1 ? 'file' : 'files'} selected`;
498
+ },
499
+ getUploadingText(percentage) {
500
+ return `Uploading${percentage > 0 ? `: ${percentage}%` : ''}`;
501
+ },
502
+ getUploadButtonText(count) {
503
+ return `Upload ${count} ${count === 1 ? 'file' : 'files'}`;
504
+ },
505
+ getMaxFilesErrorText(count) {
506
+ return `Cannot choose more than ${count} ${count === 1 ? 'file' : 'files'}. Remove files before updating`;
507
+ },
508
+ getErrorText(message) {
509
+ return message;
510
+ },
511
+ doneButtonText: 'Done',
512
+ clearAllButtonText: 'Clear all',
513
+ extensionNotAllowedText: 'Extension not allowed',
514
+ browseFilesText: 'Browse files',
515
+ dropFilesText: 'Drop files here or',
516
+ pauseButtonText: 'Pause',
517
+ resumeButtonText: 'Resume',
518
+ uploadSuccessfulText: 'Uploaded',
519
+ getPausedText(percentage) {
520
+ return `Paused: ${percentage}%`;
521
+ },
522
+ };
523
+
524
+ const filterAllowedFiles = (files, acceptedFileTypes) => {
525
+ // Allow any files if acceptedFileTypes is undefined, empty array, or contains '*'
526
+ if (!acceptedFileTypes ||
527
+ acceptedFileTypes.length === 0 ||
528
+ acceptedFileTypes.includes('*')) {
529
+ return files;
530
+ }
531
+ // Remove any files that are not in the accepted file list
532
+ return files.filter((file) => {
533
+ const fileName = file.name || '';
534
+ const mimeType = (file.type || '').toLowerCase();
535
+ const baseMimeType = mimeType.replace(/\/.*$/, '');
536
+ return acceptedFileTypes.some((type) => {
537
+ const validType = type.trim().toLowerCase();
538
+ if (validType.charAt(0) === '.') {
539
+ return fileName.toLowerCase().endsWith(validType);
540
+ }
541
+ else if (validType.endsWith('/*')) {
542
+ // This is something like a image/* mime type
543
+ return baseMimeType === validType.replace(/\/.*$/, '');
544
+ }
545
+ return mimeType === validType;
546
+ });
547
+ });
548
+ };
549
+
550
+ const UploadDetails = ({ displayName, fileSize, }) => {
551
+ return (React__default["default"].createElement(React__default["default"].Fragment, null,
552
+ React__default["default"].createElement(uiReact.View, { className: ui.ComponentClassName.StorageManagerFileMain },
553
+ React__default["default"].createElement(uiReact.Text, { className: ui.ComponentClassName.StorageManagerFileName }, displayName)),
554
+ React__default["default"].createElement(uiReact.Text, { as: "span", className: ui.ComponentClassName.StorageManagerFileSize }, fileSize ? humanFileSize(fileSize, true) : '')));
555
+ };
556
+
557
+ const FileThumbnail = ({ fileName, isImage, url, }) => {
558
+ const icons = internal.useIcons('storageManager');
559
+ const thumbnail = isImage ? (React__default["default"].createElement(uiReact.Image, { alt: fileName, src: url })) : (icons?.file ?? React__default["default"].createElement(internal.IconFile, null));
560
+ return (React__default["default"].createElement(uiReact.View, { className: ui.ComponentClassName.StorageManagerFileImage }, thumbnail));
561
+ };
562
+
563
+ function FileControl({ onPause, onResume, displayName, errorMessage, isImage, isResumable, loaderIsDeterminate, onRemove, progress, showThumbnails = true, size, status, displayText, thumbnailUrl, }) {
564
+ const { getPausedText, getUploadingText, uploadSuccessfulText, pauseButtonText, resumeButtonText, } = displayText;
565
+ return (React__default["default"].createElement(uiReact.View, { className: ui.ComponentClassName.StorageManagerFile },
566
+ React__default["default"].createElement(uiReact.View, { className: ui.ComponentClassName.StorageManagerFileWrapper },
567
+ showThumbnails ? (React__default["default"].createElement(FileThumbnail, { isImage: isImage, fileName: displayName, url: thumbnailUrl })) : null,
568
+ React__default["default"].createElement(UploadDetails, { displayName: displayName, fileSize: size }),
569
+ status === FileStatus.UPLOADING ? (React__default["default"].createElement(uiReact.Loader, { className: ui.ComponentClassName.StorageManagerLoader, variation: "linear", percentage: progress, isDeterminate: loaderIsDeterminate, isPercentageTextHidden: true })) : null,
570
+ isResumable &&
571
+ (status === FileStatus.UPLOADING || status === FileStatus.PAUSED) ? (status === FileStatus.PAUSED ? (React__default["default"].createElement(uiReact.Button, { onClick: onResume, size: "small", variation: "link" }, resumeButtonText)) : (React__default["default"].createElement(uiReact.Button, { onClick: onPause, size: "small", variation: "link" }, pauseButtonText))) : null,
572
+ React__default["default"].createElement(FileRemoveButton, { altText: `Remove file ${displayName}`, onClick: onRemove })),
573
+ React__default["default"].createElement(FileStatusMessage, { uploadSuccessfulText: uploadSuccessfulText, getUploadingText: getUploadingText, getPausedText: getPausedText, status: status, errorMessage: errorMessage, percentage: progress })));
574
+ }
575
+
576
+ function FileList({ displayText, files, hasMaxFilesError, isResumable, onCancelUpload, onDeleteUpload, onResume, onPause, showThumbnails, maxFileCount, }) {
577
+ if (files.length < 1) {
578
+ return null;
579
+ }
580
+ const { getMaxFilesErrorText } = displayText;
581
+ const headingMaxFiles = getMaxFilesErrorText(maxFileCount);
582
+ return (React__default["default"].createElement(uiReact.View, { className: ui.ComponentClassName.StorageManagerFileList },
583
+ files.map((storageFile) => {
584
+ const { file, status, progress, error, key, isImage, id, uploadTask } = storageFile;
585
+ const thumbnailUrl = file && isImage ? URL.createObjectURL(file) : '';
586
+ const loaderIsDeterminate = isResumable ? progress > 0 : true;
587
+ const isUploading = status === FileStatus.UPLOADING;
588
+ const onRemove = () => {
589
+ if (isResumable &&
590
+ (status === FileStatus.UPLOADING || status === FileStatus.PAUSED) &&
591
+ uploadTask) {
592
+ onCancelUpload({ id, uploadTask });
593
+ }
594
+ else {
595
+ onDeleteUpload({ id });
596
+ }
597
+ };
598
+ const handlePauseUpload = () => {
599
+ if (uploadTask) {
600
+ onPause({ id, uploadTask });
601
+ }
602
+ };
603
+ const handleResumeUpload = () => {
604
+ if (uploadTask) {
605
+ onResume({ id, uploadTask });
606
+ }
607
+ };
608
+ return (React__default["default"].createElement(FileControl, { displayName: key, errorMessage: error, displayText: displayText, isImage: isImage, isUploading: isUploading, isResumable: isResumable, key: id, loaderIsDeterminate: loaderIsDeterminate, onRemove: onRemove, onPause: handlePauseUpload, onResume: handleResumeUpload, progress: progress, showThumbnails: showThumbnails, size: file?.size, status: status, thumbnailUrl: thumbnailUrl }));
609
+ }),
610
+ hasMaxFilesError && (React__default["default"].createElement(uiReact.Alert, { variation: "error", heading: headingMaxFiles }))));
611
+ }
612
+
613
+ function FileListHeader({ allUploadsSuccessful, displayText, fileCount, remainingFilesCount, selectedFilesCount = 0, }) {
614
+ const { getFilesUploadedText, getRemainingFilesText, getSelectedFilesText } = displayText;
615
+ return (React__default["default"].createElement(uiReact.Text, { className: ui.ComponentClassName.StorageManagerPreviewerText }, selectedFilesCount
616
+ ? getSelectedFilesText(selectedFilesCount)
617
+ : allUploadsSuccessful
618
+ ? getFilesUploadedText(fileCount)
619
+ : getRemainingFilesText(remainingFilesCount)));
620
+ }
621
+
622
+ function FileListFooter({ displayText, remainingFilesCount, onClearAll, onUploadAll, }) {
623
+ const { clearAllButtonText, getUploadButtonText } = displayText;
624
+ return (React__default["default"].createElement(uiReact.View, { className: ui.ComponentClassName.StorageManagerPreviewerFooter },
625
+ React__default["default"].createElement(uiReact.View, { className: ui.ComponentClassName.StorageManagerPreviewerActions },
626
+ React__default["default"].createElement(uiReact.Button, { size: "small", variation: "link", onClick: onClearAll }, clearAllButtonText),
627
+ React__default["default"].createElement(uiReact.Button, { size: "small", variation: "primary", onClick: onUploadAll }, getUploadButtonText(remainingFilesCount)))));
628
+ }
629
+
630
+ function FilePicker({ children, className = ui.ComponentClassName.StorageManagerFilePicker, size = 'small', ...props }) {
631
+ return (React__default["default"].createElement(uiReact.Button, { ...props, className: className, size: size }, children));
632
+ }
633
+
634
+ const logger = ui.getLogger('Storage');
635
+ function StorageManagerBase({ acceptedFileTypes = [], accessLevel, autoUpload = true, defaultFiles, displayText: overrideDisplayText, isResumable = false, maxFileCount, maxFileSize, onUploadError, onUploadSuccess, onFileRemove, onUploadStart, showThumbnails = true, processFile, components, path, }, ref) {
636
+ if (!accessLevel || !maxFileCount) {
637
+ logger.warn('StorageManager requires accessLevel and maxFileCount props');
638
+ }
639
+ const Components = {
640
+ Container,
641
+ DropZone,
642
+ FileList,
643
+ FilePicker,
644
+ FileListHeader,
645
+ FileListFooter,
646
+ ...components,
647
+ };
648
+ const allowMultipleFiles = maxFileCount === undefined ||
649
+ (typeof maxFileCount === 'number' && maxFileCount > 1);
650
+ const displayText = {
651
+ ...defaultStorageManagerDisplayText,
652
+ ...overrideDisplayText,
653
+ };
654
+ const { getFileSizeErrorText } = displayText;
655
+ const getMaxFileSizeErrorMessage = (file) => {
656
+ return checkMaxFileSize({
657
+ file,
658
+ maxFileSize,
659
+ getFileSizeErrorText,
660
+ });
661
+ };
662
+ const { addFiles, clearFiles, files, removeUpload, queueFiles, setUploadingFile, setUploadPaused, setUploadProgress, setUploadSuccess, setUploadResumed, } = useStorageManager(defaultFiles);
663
+ React__namespace.useImperativeHandle(ref, () => ({ clearFiles }));
664
+ const { dragState, ...dropZoneProps } = internal.useDropZone({
665
+ acceptedFileTypes,
666
+ onDropComplete: ({ acceptedFiles, rejectedFiles }) => {
667
+ if (rejectedFiles && rejectedFiles.length > 0) {
668
+ logger.warn('Rejected files: ', rejectedFiles);
669
+ }
670
+ // We need to filter out files by extension here,
671
+ // we don't get filenames on the drag event, only on drop
672
+ const _acceptedFiles = filterAllowedFiles(acceptedFiles, acceptedFileTypes);
673
+ addFiles({
674
+ files: _acceptedFiles,
675
+ status: autoUpload ? FileStatus.QUEUED : FileStatus.ADDED,
676
+ getFileErrorMessage: getMaxFileSizeErrorMessage,
677
+ });
678
+ },
679
+ });
680
+ useUploadFiles({
681
+ accessLevel,
682
+ files,
683
+ isResumable,
684
+ maxFileCount,
685
+ onUploadError,
686
+ onUploadSuccess,
687
+ onUploadStart,
688
+ setUploadingFile,
689
+ setUploadProgress,
690
+ setUploadSuccess,
691
+ processFile,
692
+ path,
693
+ });
694
+ const onFilePickerChange = (event) => {
695
+ const { files } = event.target;
696
+ if (!files || files.length === 0) {
697
+ return;
698
+ }
699
+ addFiles({
700
+ files: Array.from(files),
701
+ status: autoUpload ? FileStatus.QUEUED : FileStatus.ADDED,
702
+ getFileErrorMessage: getMaxFileSizeErrorMessage,
703
+ });
704
+ };
705
+ const onClearAll = () => {
706
+ clearFiles();
707
+ };
708
+ const onUploadAll = () => {
709
+ queueFiles();
710
+ };
711
+ const onPauseUpload = ({ id, uploadTask, }) => {
712
+ uploadTask.pause();
713
+ setUploadPaused({ id });
714
+ };
715
+ const onResumeUpload = ({ id, uploadTask, }) => {
716
+ uploadTask.resume();
717
+ setUploadResumed({ id });
718
+ };
719
+ const onCancelUpload = ({ id, uploadTask, }) => {
720
+ // At this time we don't know if the delete
721
+ // permissions are enabled (required to cancel upload),
722
+ // so we do a pause instead and remove from files
723
+ uploadTask.pause();
724
+ removeUpload({ id });
725
+ };
726
+ const onDeleteUpload = ({ id }) => {
727
+ // At this time we don't know if the delete
728
+ // permissions are enabled, so we do a soft delete
729
+ // from file list, but don't remove from storage
730
+ removeUpload({ id });
731
+ if (typeof onFileRemove === 'function') {
732
+ const file = files.find((file) => file.id === id);
733
+ if (file) {
734
+ onFileRemove({ key: file.key });
735
+ }
736
+ }
737
+ };
738
+ // checks if all downloads completed to 100%
739
+ const allUploadsSuccessful = files.length === 0
740
+ ? false
741
+ : files.every((file) => file?.status === FileStatus.UPLOADED);
742
+ // Displays if over max files
743
+ const hasMaxFilesError = files.filter((file) => file.progress < 100).length > maxFileCount;
744
+ const uploadedFilesLength = files.filter((file) => file?.status === FileStatus.UPLOADED).length;
745
+ const remainingFilesCount = files.length - uploadedFilesLength;
746
+ // number of files selected for upload when autoUpload is turned off
747
+ const selectedFilesCount = autoUpload ? 0 : remainingFilesCount;
748
+ const hasFiles = files.length > 0;
749
+ const hasUploadActions = !autoUpload && remainingFilesCount > 0;
750
+ const hiddenInput = React__namespace.useRef(null);
751
+ function handleClick() {
752
+ if (hiddenInput.current) {
753
+ hiddenInput.current.click();
754
+ hiddenInput.current.value = '';
755
+ }
756
+ }
757
+ uiReactCore.useSetUserAgent({
758
+ componentName: 'StorageManager',
759
+ packageName: 'react-storage',
760
+ version: VERSION,
761
+ });
762
+ return (React__namespace.createElement(Components.Container, { className: `${ui.ComponentClassName.StorageManager} ${hasFiles ? ui.ComponentClassName.StorageManagerPreviewer : ''}` },
763
+ React__namespace.createElement(Components.DropZone, { inDropZone: dragState !== 'inactive', ...dropZoneProps, displayText: displayText },
764
+ React__namespace.createElement(React__namespace.Fragment, null,
765
+ React__namespace.createElement(Components.FilePicker, { onClick: handleClick }, displayText.browseFilesText),
766
+ React__namespace.createElement(uiReact.VisuallyHidden, null,
767
+ React__namespace.createElement("input", { type: "file", tabIndex: -1, ref: hiddenInput, onChange: onFilePickerChange, multiple: allowMultipleFiles, accept: acceptedFileTypes.join(',') })))),
768
+ hasFiles ? (React__namespace.createElement(Components.FileListHeader, { allUploadsSuccessful: allUploadsSuccessful, displayText: displayText, fileCount: files.length, remainingFilesCount: remainingFilesCount, selectedFilesCount: selectedFilesCount })) : null,
769
+ React__namespace.createElement(Components.FileList, { displayText: displayText, files: files, isResumable: isResumable, onCancelUpload: onCancelUpload, onDeleteUpload: onDeleteUpload, onResume: onResumeUpload, onPause: onPauseUpload, showThumbnails: showThumbnails, hasMaxFilesError: hasMaxFilesError, maxFileCount: maxFileCount }),
770
+ hasUploadActions ? (React__namespace.createElement(Components.FileListFooter, { displayText: displayText, remainingFilesCount: remainingFilesCount, onClearAll: onClearAll, onUploadAll: onUploadAll })) : null));
771
+ }
772
+ const StorageManager = Object.assign(React__namespace.forwardRef(StorageManagerBase), {
773
+ Container,
774
+ DropZone,
775
+ FileList,
776
+ FileListHeader,
777
+ FileListFooter,
778
+ FilePicker,
779
+ });
780
+
781
+ exports.StorageImage = StorageImage;
782
+ exports.StorageManager = StorageManager;