@armco/uploader 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ (function(){"use strict";try{if(typeof document<"u"){var r=document.createElement("style");r.appendChild(document.createTextNode(".ar-Uploader .ar-Uploader__file-uploader-progress-bar{transition:max-height .3s,opacity .3s,padding .3s,margin-bottom .3s,background-color .3s;opacity:0;max-height:0}.ar-Uploader .ar-Uploader__file-uploader-progress-bar.show{opacity:1;max-height:4rem}.ar-Uploader .ar-Uploader__file-uploader-progress-bar:hover{background-color:var(--ar-bg-hover-6)}.ar-Uploader .ar-Button.loading .pre{animation:rotating .5s linear infinite}.ar-Uploader:not(.compact):not(.image-rect):not(.image-circle) .ar-Uploader__file-input{transition:border .3s ease-in-out;border:1px dashed lightgrey;border-radius:.5rem;padding:.5rem;background-color:var(--ar-bg-base)}.ar-Uploader:not(.compact):not(.image-rect):not(.image-circle) .ar-Uploader__file-input:has(.ar-Avatar.FAILED){border-color:var(--ar-color-danger-soft)}.ar-Uploader .ar-Uploader__upload-prompt-text{color:var(--ar-color-obscure-4)}.ar-Uploader .ar-Uploader__upload-message{color:var(--ar-color-obscure-2)}")),document.head.appendChild(r)}}catch(a){console.error("vite-plugin-css-injected-by-js",a)}})();
2
+ "use strict";const ie=require("./useUpload.js"),s=require("react/jsx-runtime"),c=require("react"),C=require("uuid"),oe=require("react-dnd-html5-backend"),a=require("@armco/types"),ce=require("@armco/utils/hooks"),de=require("@armco/utils/helper"),ue=require("@armco/utils/network"),me=require("@armco/shared-components/Droppable"),W=require("@armco/shared-components/Button"),fe=require("@armco/shared-components/Text"),pe=require("@armco/shared-components/ProgressIndicator"),ge=require("@armco/shared-components/Tooltip"),xe=require("@armco/configs/endpoints"),P=require("@armco/avatar"),_=require("@armco/icon");const he=({clear:i,demo:n,disabled:p,result:d})=>{const[F,A]=c.useState(),[T,u]=c.useState();c.useEffect(()=>{u(!0)},[]);const b=d.type==="image",I=s.jsx(pe,{label:d.file.name,preIcon:b?"":"im.ImAttachment",progress:d.progress,slot:a.ArPopoverSlots.ANCHOR,rightEndContent:(F||d.status===a.ArProgress.FAILED)&&s.jsx(_,{icon:"ri.RiDeleteBin6Fill",attributes:{colors:{fillColor:d.status===a.ArProgress.FAILED?"#ff4d4f":"grey"},classes:p?"":"cursor-pointer"},events:{onClick:()=>{p||(u(!1),setTimeout(i,300))}}}),status:d.status,thumbnailRenderer:()=>b?s.jsx(P,{classes:"me-3",item:d,size:a.ArSizes.XSMALL,variant:"circle",viewOnly:!0}):null}),R=x=>typeof x=="string"?x:x.error||x.message||"Server Error";return s.jsx("div",{className:`ar-Uploader__file-uploader-progress-bar position-relative ${T?" show p-1 border-radius l1 mb-1 cursor-pointer":" px-1"} ${d.status}`,onMouseEnter:()=>A(!0),onMouseLeave:()=>A(!1),children:d.status===a.ArProgress.FAILED?s.jsxs(ge,{demo:n,children:[I,s.jsx("span",{slot:a.ArPopoverSlots.POPOVER,children:R(d.error)})]}):I})},ye=c.memo(i=>{const{acceptedFileTypes:n,acceptedFileCount:p,afterUpload:d,allowMultiple:F,beforeUpload:A,demo:T,disabled:u,uploadEntryRenderer:b,errorMessage:I="Failed to upload",endpoint:R,fileSizeLimit:x="5mb",files:g,handler:V,message:U,onFileSelected:q,avatarSize:J=a.ArSizes.REGULAR,variant:r="compact",theme:K,updateEndpoint:M,uploadSequential:X,uploadButtonText:w="Upload",uploadingButtonText:z="Uploading..."}=i,m=c.useRef(null),{notify:j}=ce.useNotification(),[t,$]=c.useState(),[v,D]=c.useState(),[L,B]=c.useState(),[N,k]=c.useState(),Y=c.useMemo(()=>v?p!==void 0?g==null?void 0:g.slice(0,p):g:g==null?void 0:g.slice(0,1),[g]),{clear:E,upload:Q,results:O}=ie(R||V||"",X,Y),h=r==="image-circle"||r==="image-rect";c.useEffect(()=>{$(O),(!O||Object.keys(O).length===0)&&m.current&&(m.current.value="");let e;t&&Object.keys(t).length>0&&Object.keys(t).every(l=>{const o=t[l];return e||(e=o.status===a.ArProgress.FAILED),o.status===a.ArProgress.FAILED}),e&&k(I)},[O]),c.useEffect(()=>{D(F)},[F]),c.useEffect(()=>{B(n)},[n]),c.useEffect(()=>{h&&(D(!1),B(["image/jpeg","image/png","image/gif","image/svg+xml"]))},[h]);const G=e=>{const l=de.convertToBytes(x);let o;try{o=p!==void 0&&(typeof p=="number"?p:parseInt(p))}catch{console.warn("Incorrect prop acceptedFileCount supplied, should be a numeric value")}if(typeof o=="number"&&e&&e.length+Object.keys(t||{}).length>o)k("Exceeded allowed number of files."),j({message:"You've selected more then allowed number of files",type:a.ArAlertType.WARNING,uid:C.v4()});else if(e.findIndex(f=>f.size>l)>-1){const f=`${v?"One or more files exceed ":"Selected file exceeds "}specified size limit of ${x}`;k(f),j({message:f,type:a.ArAlertType.WARNING,uid:C.v4()})}else e&&e.length>0&&(Q(e,d,v),q&&q(e))},Z=e=>{var o;k("");const l=Array.from((o=e.target||e.dataTransfer)==null?void 0:o.files);(!A||A(l,()=>G(l)))&&G(l)},y=t&&Object.keys(t).findIndex(e=>t[e].status===a.ArProgress.IN_PROGRESS)>-1,ee=!!(t&&Object.keys(t).length>0&&Object.keys(t).every(e=>{const l=t[e];return l.status===a.ArProgress.COMPLETED||l.status===a.ArProgress.FAILED})),S=t&&t[Object.keys(t)[0]],te=e=>{if(t&&S){const l=Object.keys(t).find(o=>o.startsWith(S.file.name));if(l){const o={...t[l]};o.imageProps=e,t[l]=o,$({...t})}}},se=e=>{if(t&&S){const l=Object.keys(t).find(o=>o.startsWith(S.file.name));if(l){const o=t[l];let f=M||R;if(f){const ne=process.env.NODE_ENV||"development";f=(f.startsWith("http")?"":xe.API_CONFIG.STATIC_HOST[ne])+f,ue.put(f,o).then(ae=>{ae.status===200?j({message:"Image updaetd successfully!",type:a.ArAlertType.SUCCESS,uid:C.v4()}):j({message:"Failed to update image!",type:a.ArAlertType.ERROR,uid:C.v4()})})}else j({message:"Missing image update URL",type:a.ArAlertType.WARNING,uid:C.v4()})}}},H=s.jsxs("div",{className:`ar-Uploader__file-input flex-v-center${y?" disabled":""}${r!=="compact"&&!y&&!u?" cursor-pointer":""}${r==="large"?" flex-h-center flex-column p-3":" justify-content-between"}${r==="image-circle"?" border-radius-50":""}`,onClick:()=>{var e;return r!=="compact"&&!y&&!u&&((e=m.current)==null?void 0:e.click())},children:[h?s.jsx(P,{clearImage:E,demo:T,variant:r==="image-circle"?"circle":"rect",item:S,onChange:te,onCommit:se,size:J,uploadButtonText:w,uploadingButtonText:z}):s.jsxs(s.Fragment,{children:[s.jsxs("div",{className:"ar-Uploader__file-input__prompt d-flex flex-column",children:[s.jsx("div",{className:`d-inline-flex ${r==="large"?" flex-center flex-column":"flex-v-center"}`,children:r==="compact"?s.jsxs(s.Fragment,{children:[s.jsx(W,{classes:y?"loading":"",content:y?z:w,preIcon:y?"ri.RiLoader5Fill":ee?N?"fa.FaExclamation":"fa.FaCheck":"md.MdOutlineFileUpload",onClick:()=>{var e;return(e=m.current)==null?void 0:e.click()},theme:K,disabled:u||y}),t&&Object.keys(t).length>0&&r==="compact"&&s.jsxs(s.Fragment,{children:[v?s.jsx("span",{className:"fw-bold flex-v-center ms-3",children:`(${Object.keys(t).length} file${Object.keys(t).length>1?"s":""})`}):s.jsx(fe,{classes:"fw-bold flex-v-center ms-3 text-decoration-underline",descriptor:{id:"temp-text-id",order:0,name:"Text",text:t[Object.keys(t)[0]].file.name,chunks:{}},overflowEllipsis:!0,overflowTooltip:!0}),s.jsx(_,{icon:"io5.IoClose",attributes:{colors:{fillColor:"red"},classes:`ms-2 ${u?"":"cursor-pointer"}`},events:{onClick:()=>{u&&(E(),m.current&&(m.current.value=""))}}})]})]}):s.jsxs(s.Fragment,{children:[s.jsx(_,{icon:"io5.IoFileTrayOutline",attributes:{colors:{fillColor:"#1677ff"},classes:r==="large"?"mb-2":"me-3",size:r==="large"?"3rem":"1rem"}}),s.jsx("span",{className:`ar-Uploader__upload-prompt-text${r==="large"?" h5 mb-0":""}`,children:"Click or drag files here to upload"})]})}),U&&s.jsx("small",{className:`ar-Uploader__upload-message text-decoration-underline ${r==="large"?"fw-bold f3 mt-2 mb-2":"mt-1"}`,children:U})]}),s.jsx("div",{className:"ar-Uploader__file-input__actions",children:r!=="compact"&&t&&Object.keys(t).length>0&&s.jsx(W,{containerClasses:`text-end${r==="large"?" mt-3":""}`,content:"Clear",variant:a.ArButtonVariants.DANGER,size:r==="regular"?a.ArSizes.XSMALL:a.ArSizes.SMALL,onClick:e=>{e.stopPropagation(),E(),m.current&&(m.current.value="")}})})]}),s.jsx("input",{className:"ar-Uploader__input d-none",type:"file",onChange:Z,ref:m,title:"file-uploader",accept:Array.isArray(L)?L.join(","):L,disabled:u,multiple:v})]}),re=N&&s.jsx("span",{className:"error my-1 small",children:N}),le=t&&r!=="compact"&&s.jsx("div",{className:"ar-Uploader__file-upload-progress mt-2",children:Object.entries(t).map(([e,l])=>b?b(l,()=>E(e)):s.jsx(he,{clear:()=>E(e),demo:!!T,disabled:!!u,result:l},e))});return s.jsxs("div",{className:`ar-Uploader d-flex flex-column${r?" "+r:""}${h?" flex-center":" w-100"}`,onDragOver:e=>e.preventDefault(),onDragLeave:e=>e.preventDefault(),children:[r!=="compact"?s.jsx(me,{dropHandler:e=>{m.current&&!u&&(m.current.files=e.dataTransfer.files,m.current.dispatchEvent(new Event("change",{bubbles:!0,cancelable:!0})))},acceptTypes:[oe.NativeTypes.FILE],hideHoverEffect:h||u,children:H}):H,!h&&re,!h&&le]})},(i,n)=>i.acceptedFileTypes===n.acceptedFileTypes&&i.acceptedFileCount===n.acceptedFileCount&&i.allowMultiple===n.allowMultiple&&i.disabled===n.disabled&&i.errorMessage===n.errorMessage&&i.endpoint===n.endpoint&&i.fileSizeLimit===n.fileSizeLimit&&JSON.stringify(i.files)===JSON.stringify(n.files)&&i.message===n.message&&i.avatarSize===n.avatarSize&&i.variant===n.variant&&i.theme===n.theme&&i.uploadSequential===n.uploadSequential&&i.uploadButtonText===n.uploadButtonText&&i.uploadingButtonText===n.uploadingButtonText);module.exports=ye;
package/cjs/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("./useUpload.js"),r=require("./Uploader.js");require("react");require("@armco/types");require("@armco/utils/helper");require("@armco/utils/network");require("react/jsx-runtime");require("uuid");require("react-dnd-html5-backend");require("@armco/utils/hooks");require("@armco/shared-components/Droppable");require("@armco/shared-components/Button");require("@armco/shared-components/Text");require("@armco/shared-components/ProgressIndicator");require("@armco/shared-components/Tooltip");require("@armco/configs/endpoints");require("@armco/avatar");require("@armco/icon");exports.useUpload=e;exports.Uploader=r;
@@ -0,0 +1 @@
1
+ "use strict";const f=require("react"),E=require("@armco/types"),g=require("@armco/utils/helper"),P=require("@armco/utils/network"),S={status:E.ArProgress.COMPLETED,progress:100},d={status:E.ArProgress.FAILED,progress:0},A=(i,p,h)=>{const[l,o]=f.useState(),u=f.useRef({}),c=f.useRef({});f.useEffect(()=>{if(h){const e={};h==null||h.forEach(s=>{e[g.generateFileKey(s)]={...s,progress:100,status:E.ArProgress.COMPLETED,file:typeof s=="object"?s:{name:s.name}}}),o(e)}},[h]),f.useEffect(()=>{const e=c.current;return()=>{Object.keys(e).forEach(s=>clearInterval(e[s]))}},[c]);const v=e=>{if(e){const s={...l};delete s[e],o(s),u.current[e]=!0,clearInterval(c.current[e])}else o(void 0),l&&Object.keys(l).forEach(s=>l[s].status===E.ArProgress.IN_PROGRESS&&(u.current[s]=!0)),Object.keys(c.current).forEach(s=>clearInterval(c.current[s]))},R=async e=>{const y=typeof i=="function"?i:null,r=g.generateFileKey(e);return c.current[r]=setInterval(()=>{o(n=>{const t=n&&n[r];if(!t||t.progress>=95)return c.current&&clearInterval(c.current[r]),n;const a=Math.floor(Math.random()*8)+5;return{...n,[r]:{...t,progress:t.progress+a}}})},500),y?await y(e).then(n=>{u.current[r]||(n.ok||o(t=>({...t,[r]:{file:e,...d}})),o(t=>({...t,[r]:{file:e,...S}})))}).catch(()=>{u.current[r]||o(n=>({...n,[r]:{file:e,...d}}))}).finally(()=>{c.current&&clearInterval(c.current[r])}):await P.upload(i,e).then(n=>{if(u.current[r])delete u.current[r],delete c.current[r];else{if(!n.body){o(a=>({...a,[r]:{file:e,...d,error:n.body,httpStatus:n.status}}));return}const t=n.body.saved[0];o(a=>({...a,[r]:{...t||{},file:e,...S}}))}}).catch(n=>{u.current[r]?(delete u.current[r],delete c.current[r]):o(t=>({...t,[r]:{file:e,...d,error:n}}))}).finally(()=>{c.current&&clearInterval(c.current[r])})};return{clear:v,upload:async(e,s,y)=>{const r={};e.forEach(t=>{const a=g.generateFileKey(t);r[a]={file:t,status:E.ArProgress.IN_PROGRESS,progress:p?1:Math.floor(Math.random()*10)}}),o(y?{...l,...r}:r);let n=[];for(const t of e)p?n.push(await R(t)):n.push(R(t));await Promise.allSettled(n).then(t=>s&&s(t))},results:l}};module.exports=A;
package/es/Uploader.js ADDED
@@ -0,0 +1,383 @@
1
+ (function(){"use strict";try{if(typeof document<"u"){var r=document.createElement("style");r.appendChild(document.createTextNode(".ar-Uploader .ar-Uploader__file-uploader-progress-bar{transition:max-height .3s,opacity .3s,padding .3s,margin-bottom .3s,background-color .3s;opacity:0;max-height:0}.ar-Uploader .ar-Uploader__file-uploader-progress-bar.show{opacity:1;max-height:4rem}.ar-Uploader .ar-Uploader__file-uploader-progress-bar:hover{background-color:var(--ar-bg-hover-6)}.ar-Uploader .ar-Button.loading .pre{animation:rotating .5s linear infinite}.ar-Uploader:not(.compact):not(.image-rect):not(.image-circle) .ar-Uploader__file-input{transition:border .3s ease-in-out;border:1px dashed lightgrey;border-radius:.5rem;padding:.5rem;background-color:var(--ar-bg-base)}.ar-Uploader:not(.compact):not(.image-rect):not(.image-circle) .ar-Uploader__file-input:has(.ar-Avatar.FAILED){border-color:var(--ar-color-danger-soft)}.ar-Uploader .ar-Uploader__upload-prompt-text{color:var(--ar-color-obscure-4)}.ar-Uploader .ar-Uploader__upload-message{color:var(--ar-color-obscure-2)}")),document.head.appendChild(r)}}catch(a){console.error("vite-plugin-css-injected-by-js",a)}})();
2
+ import me from "./useUpload.js";
3
+ import { jsxs as p, jsx as r, Fragment as M } from "react/jsx-runtime";
4
+ import { memo as ue, useRef as fe, useState as x, useMemo as pe, useEffect as L } from "react";
5
+ import { v4 as O } from "uuid";
6
+ import { NativeTypes as ge } from "react-dnd-html5-backend";
7
+ import { ArSizes as j, ArProgress as g, ArButtonVariants as he, ArPopoverSlots as Y, ArAlertType as R } from "@armco/types";
8
+ import { useNotification as ye } from "@armco/utils/hooks";
9
+ import { convertToBytes as be } from "@armco/utils/helper";
10
+ import { put as xe } from "@armco/utils/network";
11
+ import ve from "@armco/shared-components/Droppable";
12
+ import Q from "@armco/shared-components/Button";
13
+ import Ce from "@armco/shared-components/Text";
14
+ import Ae from "@armco/shared-components/ProgressIndicator";
15
+ import Ee from "@armco/shared-components/Tooltip";
16
+ import { API_CONFIG as Ie } from "@armco/configs/endpoints";
17
+ import Z from "@armco/avatar";
18
+ import D from "@armco/icon";
19
+ const Fe = ({
20
+ clear: n,
21
+ demo: o,
22
+ disabled: u,
23
+ result: s
24
+ }) => {
25
+ const [S, v] = x(), [T, c] = x();
26
+ L(() => {
27
+ c(!0);
28
+ }, []);
29
+ const C = s.type === "image", k = /* @__PURE__ */ r(
30
+ Ae,
31
+ {
32
+ label: s.file.name,
33
+ preIcon: C ? "" : "im.ImAttachment",
34
+ progress: s.progress,
35
+ slot: Y.ANCHOR,
36
+ rightEndContent: (S || s.status === g.FAILED) && /* @__PURE__ */ r(
37
+ D,
38
+ {
39
+ icon: "ri.RiDeleteBin6Fill",
40
+ attributes: {
41
+ colors: {
42
+ fillColor: s.status === g.FAILED ? "#ff4d4f" : "grey"
43
+ },
44
+ classes: u ? "" : "cursor-pointer"
45
+ },
46
+ events: {
47
+ onClick: () => {
48
+ u || (c(!1), setTimeout(n, 300));
49
+ }
50
+ }
51
+ }
52
+ ),
53
+ status: s.status,
54
+ thumbnailRenderer: () => C ? /* @__PURE__ */ r(
55
+ Z,
56
+ {
57
+ classes: "me-3",
58
+ item: s,
59
+ size: j.XSMALL,
60
+ variant: "circle",
61
+ viewOnly: !0
62
+ }
63
+ ) : null
64
+ }
65
+ ), N = (h) => typeof h == "string" ? h : h.error || h.message || "Server Error";
66
+ return /* @__PURE__ */ r(
67
+ "div",
68
+ {
69
+ className: `ar-Uploader__file-uploader-progress-bar position-relative ${T ? " show p-1 border-radius l1 mb-1 cursor-pointer" : " px-1"} ${s.status}`,
70
+ onMouseEnter: () => v(!0),
71
+ onMouseLeave: () => v(!1),
72
+ children: s.status === g.FAILED ? /* @__PURE__ */ p(Ee, { demo: o, children: [
73
+ k,
74
+ /* @__PURE__ */ r("span", { slot: Y.POPOVER, children: N(s.error) })
75
+ ] }) : k
76
+ }
77
+ );
78
+ }, Je = ue(
79
+ (n) => {
80
+ const {
81
+ acceptedFileTypes: o,
82
+ acceptedFileCount: u,
83
+ afterUpload: s,
84
+ allowMultiple: S,
85
+ beforeUpload: v,
86
+ demo: T,
87
+ disabled: c,
88
+ uploadEntryRenderer: C,
89
+ errorMessage: k = "Failed to upload",
90
+ endpoint: N,
91
+ fileSizeLimit: h = "5mb",
92
+ files: f,
93
+ handler: P,
94
+ message: z,
95
+ onFileSelected: B,
96
+ avatarSize: ee = j.REGULAR,
97
+ variant: l = "compact",
98
+ theme: te,
99
+ updateEndpoint: G,
100
+ uploadSequential: le,
101
+ uploadButtonText: W = "Upload",
102
+ uploadingButtonText: H = "Uploading..."
103
+ } = n, d = fe(null), { notify: A } = ye(), [t, q] = x(), [E, V] = x(), [w, J] = x(), [$, _] = x(), ae = pe(
104
+ () => E ? u !== void 0 ? f == null ? void 0 : f.slice(0, u) : f : f == null ? void 0 : f.slice(0, 1),
105
+ [f]
106
+ ), { clear: I, upload: re, results: U } = me(
107
+ N || P || "",
108
+ le,
109
+ ae
110
+ ), y = l === "image-circle" || l === "image-rect";
111
+ L(() => {
112
+ q(U), (!U || Object.keys(U).length === 0) && d.current && (d.current.value = "");
113
+ let e;
114
+ t && Object.keys(t).length > 0 && Object.keys(t).every((a) => {
115
+ const i = t[a];
116
+ return e || (e = i.status === g.FAILED), i.status === g.FAILED;
117
+ }), e && _(k);
118
+ }, [U]), L(() => {
119
+ V(S);
120
+ }, [S]), L(() => {
121
+ J(o);
122
+ }, [o]), L(() => {
123
+ y && (V(!1), J([
124
+ "image/jpeg",
125
+ "image/png",
126
+ "image/gif",
127
+ "image/svg+xml"
128
+ ]));
129
+ }, [y]);
130
+ const K = (e) => {
131
+ const a = be(h);
132
+ let i;
133
+ try {
134
+ i = u !== void 0 && (typeof u == "number" ? u : parseInt(u));
135
+ } catch {
136
+ console.warn(
137
+ "Incorrect prop acceptedFileCount supplied, should be a numeric value"
138
+ );
139
+ }
140
+ if (typeof i == "number" && e && e.length + Object.keys(t || {}).length > i)
141
+ _("Exceeded allowed number of files."), A({
142
+ message: "You've selected more then allowed number of files",
143
+ type: R.WARNING,
144
+ uid: O()
145
+ });
146
+ else if (e.findIndex((m) => m.size > a) > -1) {
147
+ const m = `${E ? "One or more files exceed " : "Selected file exceeds "}specified size limit of ${h}`;
148
+ _(m), A({
149
+ message: m,
150
+ type: R.WARNING,
151
+ uid: O()
152
+ });
153
+ } else
154
+ e && e.length > 0 && (re(e, s, E), B && B(e));
155
+ }, oe = (e) => {
156
+ var i;
157
+ _("");
158
+ const a = Array.from(
159
+ (i = e.target || e.dataTransfer) == null ? void 0 : i.files
160
+ );
161
+ (!v || v(a, () => K(a))) && K(a);
162
+ }, b = t && Object.keys(t).findIndex((e) => t[e].status === g.IN_PROGRESS) > -1, ne = !!(t && Object.keys(t).length > 0 && Object.keys(t).every((e) => {
163
+ const a = t[e];
164
+ return a.status === g.COMPLETED || a.status === g.FAILED;
165
+ })), F = t && t[Object.keys(t)[0]], X = /* @__PURE__ */ p(
166
+ "div",
167
+ {
168
+ className: `ar-Uploader__file-input flex-v-center${b ? " disabled" : ""}${l !== "compact" && !b && !c ? " cursor-pointer" : ""}${l === "large" ? " flex-h-center flex-column p-3" : " justify-content-between"}${l === "image-circle" ? " border-radius-50" : ""}`,
169
+ onClick: () => {
170
+ var e;
171
+ return l !== "compact" && !b && !c && ((e = d.current) == null ? void 0 : e.click());
172
+ },
173
+ children: [
174
+ y ? /* @__PURE__ */ r(
175
+ Z,
176
+ {
177
+ clearImage: I,
178
+ demo: T,
179
+ variant: l === "image-circle" ? "circle" : "rect",
180
+ item: F,
181
+ onChange: (e) => {
182
+ if (t && F) {
183
+ const a = Object.keys(t).find(
184
+ (i) => i.startsWith(F.file.name)
185
+ );
186
+ if (a) {
187
+ const i = { ...t[a] };
188
+ i.imageProps = e, t[a] = i, q({ ...t });
189
+ }
190
+ }
191
+ },
192
+ onCommit: (e) => {
193
+ if (t && F) {
194
+ const a = Object.keys(t).find(
195
+ (i) => i.startsWith(F.file.name)
196
+ );
197
+ if (a) {
198
+ const i = t[a];
199
+ let m = G || N;
200
+ if (m) {
201
+ const ce = process.env.NODE_ENV || "development";
202
+ m = (m.startsWith("http") ? "" : Ie.STATIC_HOST[ce]) + m, xe(m, i).then((de) => {
203
+ de.status === 200 ? A({
204
+ message: "Image updaetd successfully!",
205
+ type: R.SUCCESS,
206
+ uid: O()
207
+ }) : A({
208
+ message: "Failed to update image!",
209
+ type: R.ERROR,
210
+ uid: O()
211
+ });
212
+ });
213
+ } else
214
+ A({
215
+ message: "Missing image update URL",
216
+ type: R.WARNING,
217
+ uid: O()
218
+ });
219
+ }
220
+ }
221
+ },
222
+ size: ee,
223
+ uploadButtonText: W,
224
+ uploadingButtonText: H
225
+ }
226
+ ) : /* @__PURE__ */ p(M, { children: [
227
+ /* @__PURE__ */ p("div", { className: "ar-Uploader__file-input__prompt d-flex flex-column", children: [
228
+ /* @__PURE__ */ r(
229
+ "div",
230
+ {
231
+ className: `d-inline-flex ${l === "large" ? " flex-center flex-column" : "flex-v-center"}`,
232
+ children: l === "compact" ? /* @__PURE__ */ p(M, { children: [
233
+ /* @__PURE__ */ r(
234
+ Q,
235
+ {
236
+ classes: b ? "loading" : "",
237
+ content: b ? H : W,
238
+ preIcon: b ? "ri.RiLoader5Fill" : ne ? $ ? "fa.FaExclamation" : "fa.FaCheck" : "md.MdOutlineFileUpload",
239
+ onClick: () => {
240
+ var e;
241
+ return (e = d.current) == null ? void 0 : e.click();
242
+ },
243
+ theme: te,
244
+ disabled: c || b
245
+ }
246
+ ),
247
+ t && Object.keys(t).length > 0 && l === "compact" && /* @__PURE__ */ p(M, { children: [
248
+ E ? /* @__PURE__ */ r("span", { className: "fw-bold flex-v-center ms-3", children: `(${Object.keys(t).length} file${Object.keys(t).length > 1 ? "s" : ""})` }) : /* @__PURE__ */ r(
249
+ Ce,
250
+ {
251
+ classes: "fw-bold flex-v-center ms-3 text-decoration-underline",
252
+ descriptor: {
253
+ id: "temp-text-id",
254
+ order: 0,
255
+ name: "Text",
256
+ text: t[Object.keys(t)[0]].file.name,
257
+ chunks: {}
258
+ },
259
+ overflowEllipsis: !0,
260
+ overflowTooltip: !0
261
+ }
262
+ ),
263
+ /* @__PURE__ */ r(
264
+ D,
265
+ {
266
+ icon: "io5.IoClose",
267
+ attributes: {
268
+ colors: {
269
+ fillColor: "red"
270
+ },
271
+ classes: `ms-2 ${c ? "" : "cursor-pointer"}`
272
+ },
273
+ events: {
274
+ onClick: () => {
275
+ c && (I(), d.current && (d.current.value = ""));
276
+ }
277
+ }
278
+ }
279
+ )
280
+ ] })
281
+ ] }) : /* @__PURE__ */ p(M, { children: [
282
+ /* @__PURE__ */ r(
283
+ D,
284
+ {
285
+ icon: "io5.IoFileTrayOutline",
286
+ attributes: {
287
+ colors: {
288
+ fillColor: "#1677ff"
289
+ },
290
+ classes: l === "large" ? "mb-2" : "me-3",
291
+ size: l === "large" ? "3rem" : "1rem"
292
+ }
293
+ }
294
+ ),
295
+ /* @__PURE__ */ r(
296
+ "span",
297
+ {
298
+ className: `ar-Uploader__upload-prompt-text${l === "large" ? " h5 mb-0" : ""}`,
299
+ children: "Click or drag files here to upload"
300
+ }
301
+ )
302
+ ] })
303
+ }
304
+ ),
305
+ z && /* @__PURE__ */ r(
306
+ "small",
307
+ {
308
+ className: `ar-Uploader__upload-message text-decoration-underline ${l === "large" ? "fw-bold f3 mt-2 mb-2" : "mt-1"}`,
309
+ children: z
310
+ }
311
+ )
312
+ ] }),
313
+ /* @__PURE__ */ r("div", { className: "ar-Uploader__file-input__actions", children: l !== "compact" && t && Object.keys(t).length > 0 && /* @__PURE__ */ r(
314
+ Q,
315
+ {
316
+ containerClasses: `text-end${l === "large" ? " mt-3" : ""}`,
317
+ content: "Clear",
318
+ variant: he.DANGER,
319
+ size: l === "regular" ? j.XSMALL : j.SMALL,
320
+ onClick: (e) => {
321
+ e.stopPropagation(), I(), d.current && (d.current.value = "");
322
+ }
323
+ }
324
+ ) })
325
+ ] }),
326
+ /* @__PURE__ */ r(
327
+ "input",
328
+ {
329
+ className: "ar-Uploader__input d-none",
330
+ type: "file",
331
+ onChange: oe,
332
+ ref: d,
333
+ title: "file-uploader",
334
+ accept: Array.isArray(w) ? w.join(",") : w,
335
+ disabled: c,
336
+ multiple: E
337
+ }
338
+ )
339
+ ]
340
+ }
341
+ ), ie = $ && /* @__PURE__ */ r("span", { className: "error my-1 small", children: $ }), se = t && l !== "compact" && /* @__PURE__ */ r("div", { className: "ar-Uploader__file-upload-progress mt-2", children: Object.entries(t).map(
342
+ ([e, a]) => C ? C(a, () => I(e)) : /* @__PURE__ */ r(
343
+ Fe,
344
+ {
345
+ clear: () => I(e),
346
+ demo: !!T,
347
+ disabled: !!c,
348
+ result: a
349
+ },
350
+ e
351
+ )
352
+ ) });
353
+ return /* @__PURE__ */ p(
354
+ "div",
355
+ {
356
+ className: `ar-Uploader d-flex flex-column${l ? " " + l : ""}${y ? " flex-center" : " w-100"}`,
357
+ onDragOver: (e) => e.preventDefault(),
358
+ onDragLeave: (e) => e.preventDefault(),
359
+ children: [
360
+ l !== "compact" ? /* @__PURE__ */ r(
361
+ ve,
362
+ {
363
+ dropHandler: (e) => {
364
+ d.current && !c && (d.current.files = e.dataTransfer.files, d.current.dispatchEvent(
365
+ new Event("change", { bubbles: !0, cancelable: !0 })
366
+ ));
367
+ },
368
+ acceptTypes: [ge.FILE],
369
+ hideHoverEffect: y || c,
370
+ children: X
371
+ }
372
+ ) : X,
373
+ !y && ie,
374
+ !y && se
375
+ ]
376
+ }
377
+ );
378
+ },
379
+ (n, o) => n.acceptedFileTypes === o.acceptedFileTypes && n.acceptedFileCount === o.acceptedFileCount && n.allowMultiple === o.allowMultiple && n.disabled === o.disabled && n.errorMessage === o.errorMessage && n.endpoint === o.endpoint && n.fileSizeLimit === o.fileSizeLimit && JSON.stringify(n.files) === JSON.stringify(o.files) && n.message === o.message && n.avatarSize === o.avatarSize && n.variant === o.variant && n.theme === o.theme && n.uploadSequential === o.uploadSequential && n.uploadButtonText === o.uploadButtonText && n.uploadingButtonText === o.uploadingButtonText
380
+ );
381
+ export {
382
+ Je as default
383
+ };
package/es/index.js ADDED
@@ -0,0 +1,22 @@
1
+ import { default as h } from "./useUpload.js";
2
+ import { default as k } from "./Uploader.js";
3
+ import "react";
4
+ import "@armco/types";
5
+ import "@armco/utils/helper";
6
+ import "@armco/utils/network";
7
+ import "react/jsx-runtime";
8
+ import "uuid";
9
+ import "react-dnd-html5-backend";
10
+ import "@armco/utils/hooks";
11
+ import "@armco/shared-components/Droppable";
12
+ import "@armco/shared-components/Button";
13
+ import "@armco/shared-components/Text";
14
+ import "@armco/shared-components/ProgressIndicator";
15
+ import "@armco/shared-components/Tooltip";
16
+ import "@armco/configs/endpoints";
17
+ import "@armco/avatar";
18
+ import "@armco/icon";
19
+ export {
20
+ k as Uploader,
21
+ h as useUpload
22
+ };
@@ -0,0 +1,123 @@
1
+ import { useState as I, useRef as S, useEffect as v } from "react";
2
+ import { ArProgress as d } from "@armco/types";
3
+ import { generateFileKey as m } from "@armco/utils/helper";
4
+ import { upload as b } from "@armco/utils/network";
5
+ const R = {
6
+ status: d.COMPLETED,
7
+ progress: 100
8
+ }, p = {
9
+ status: d.FAILED,
10
+ progress: 0
11
+ }, C = (E, y, f) => {
12
+ const [l, o] = I(), a = S({}), c = S({});
13
+ v(() => {
14
+ if (f) {
15
+ const t = {};
16
+ f == null || f.forEach((n) => {
17
+ t[m(n)] = {
18
+ ...n,
19
+ progress: 100,
20
+ status: d.COMPLETED,
21
+ file: typeof n == "object" ? n : { name: n.name }
22
+ };
23
+ }), o(t);
24
+ }
25
+ }, [f]), v(() => {
26
+ const t = c.current;
27
+ return () => {
28
+ Object.keys(t).forEach((n) => clearInterval(t[n]));
29
+ };
30
+ }, [c]);
31
+ const g = (t) => {
32
+ if (t) {
33
+ const n = { ...l };
34
+ delete n[t], o(n), a.current[t] = !0, clearInterval(c.current[t]);
35
+ } else
36
+ o(void 0), l && Object.keys(l).forEach(
37
+ (n) => l[n].status === d.IN_PROGRESS && (a.current[n] = !0)
38
+ ), Object.keys(c.current).forEach(
39
+ (n) => clearInterval(c.current[n])
40
+ );
41
+ }, i = async (t) => {
42
+ const h = typeof E == "function" ? E : null, r = m(t);
43
+ return c.current[r] = setInterval(() => {
44
+ o((s) => {
45
+ const e = s && s[r];
46
+ if (!e || e.progress >= 95)
47
+ return c.current && clearInterval(c.current[r]), s;
48
+ const u = Math.floor(Math.random() * 8) + 5;
49
+ return {
50
+ ...s,
51
+ [r]: {
52
+ ...e,
53
+ progress: e.progress + u
54
+ }
55
+ };
56
+ });
57
+ }, 500), h ? await h(t).then((s) => {
58
+ a.current[r] || (s.ok || o((e) => ({
59
+ ...e,
60
+ [r]: { file: t, ...p }
61
+ })), o((e) => ({
62
+ ...e,
63
+ [r]: { file: t, ...R }
64
+ })));
65
+ }).catch(() => {
66
+ a.current[r] || o((s) => ({
67
+ ...s,
68
+ [r]: { file: t, ...p }
69
+ }));
70
+ }).finally(() => {
71
+ c.current && clearInterval(c.current[r]);
72
+ }) : await b(E, t).then((s) => {
73
+ if (a.current[r])
74
+ delete a.current[r], delete c.current[r];
75
+ else {
76
+ if (!s.body) {
77
+ o((u) => ({
78
+ ...u,
79
+ [r]: {
80
+ file: t,
81
+ ...p,
82
+ error: s.body,
83
+ httpStatus: s.status
84
+ }
85
+ }));
86
+ return;
87
+ }
88
+ const e = s.body.saved[0];
89
+ o((u) => ({
90
+ ...u,
91
+ [r]: { ...e || {}, file: t, ...R }
92
+ }));
93
+ }
94
+ }).catch((s) => {
95
+ a.current[r] ? (delete a.current[r], delete c.current[r]) : o((e) => ({
96
+ ...e,
97
+ [r]: { file: t, ...p, error: s }
98
+ }));
99
+ }).finally(() => {
100
+ c.current && clearInterval(c.current[r]);
101
+ });
102
+ };
103
+ return { clear: g, upload: async (t, n, h) => {
104
+ const r = {};
105
+ t.forEach((e) => {
106
+ const u = m(e);
107
+ r[u] = {
108
+ file: e,
109
+ status: d.IN_PROGRESS,
110
+ progress: y ? 1 : Math.floor(Math.random() * 10)
111
+ };
112
+ }), o(h ? { ...l, ...r } : r);
113
+ let s = [];
114
+ for (const e of t)
115
+ y ? s.push(await i(e)) : s.push(i(e));
116
+ await Promise.allSettled(s).then(
117
+ (e) => n && n(e)
118
+ );
119
+ }, results: l };
120
+ };
121
+ export {
122
+ C as default
123
+ };
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "@armco/uploader",
3
+ "version": "0.0.1",
4
+ "type": "module",
5
+ "main": "cjs/index.js",
6
+ "module": "es/index.js",
7
+ "types": "types/index.d.ts",
8
+ "scripts": {
9
+ "*": "rm -rf build && tsc && vite build",
10
+ "format": "prettier --write .",
11
+ "lint": "eslint .",
12
+ "publish:sh": "./publish.sh",
13
+ "publish:local": "./publish-local.sh"
14
+ },
15
+ "dependencies": {
16
+ "@armco/avatar": "^0.0.1",
17
+ "@armco/configs": "^0.0.7",
18
+ "@armco/icon": "^0.0.4",
19
+ "@armco/shared-components": "^0.0.52",
20
+ "@armco/types": "^0.0.11",
21
+ "@armco/utils": "^0.0.17",
22
+ "react": ">16.8.0",
23
+ "react-dnd-html5-backend": "^16.0.1",
24
+ "react-dom": ">16.8.0",
25
+ "uuid": "^10.0.0"
26
+ },
27
+ "devDependencies": {
28
+ "@testing-library/dom": "^9.2.0",
29
+ "@testing-library/jest-dom": "^5.11.4",
30
+ "@testing-library/react": "^14.0.0",
31
+ "@testing-library/user-event": "^14.2.5",
32
+ "@types/react": "^18.0.15",
33
+ "@types/react-dom": "^18.0.6",
34
+ "@types/testing-library__jest-dom": "^5.14.5",
35
+ "@types/uuid": "^10.0.0",
36
+ "@vitejs/plugin-react": "^4.3.1",
37
+ "eslint": "^8.0.0",
38
+ "eslint-config-react-app": "^7.0.1",
39
+ "eslint-plugin-prettier": "^4.2.1",
40
+ "glob": "^11.0.0",
41
+ "jsdom": "^21.1.0",
42
+ "prettier": "^2.7.1",
43
+ "prettier-config-nick": "^1.0.2",
44
+ "sass": "^1.63.4",
45
+ "typescript": "^5.0.2",
46
+ "vite": "^4.0.0",
47
+ "vite-plugin-css-injected-by-js": "^3.5.1",
48
+ "vite-plugin-dts": "^4.2.2",
49
+ "vite-plugin-externalize-deps": "^0.8.0",
50
+ "vitest": "^0.30.1"
51
+ },
52
+ "peerDependencies": {
53
+ "react": ">16.8.0",
54
+ "react-dom": ">16.8.0"
55
+ },
56
+ "eslintConfig": {
57
+ "extends": [
58
+ "react-app",
59
+ "react-app/jest"
60
+ ],
61
+ "plugins": [
62
+ "prettier"
63
+ ],
64
+ "rules": {
65
+ "prettier/prettier": "error",
66
+ "react/jsx-no-target-blank": "off"
67
+ }
68
+ },
69
+ "prettier": "prettier-config-nick",
70
+ "repository": {
71
+ "type": "git",
72
+ "url": "git+https://github.com/ReStruct-Corporate-Advantage/uploader.git"
73
+ },
74
+ "keywords": [
75
+ "components",
76
+ "atomic",
77
+ "building-blocks",
78
+ "foundation"
79
+ ],
80
+ "license": "ISC",
81
+ "bugs": {
82
+ "url": "https://github.com/ReStruct-Corporate-Advantage/uploader/issues"
83
+ },
84
+ "homepage": "https://github.com/ReStruct-Corporate-Advantage/uploader#readme"
85
+ }
@@ -0,0 +1,3 @@
1
+ import { UploaderProps } from '@armco/types';
2
+ declare const Uploader: import('react').MemoExoticComponent<(props: UploaderProps) => JSX.Element>;
3
+ export default Uploader;
@@ -0,0 +1,2 @@
1
+ export { default as useUpload } from './useUpload';
2
+ export { default as Uploader } from './Uploader';
@@ -0,0 +1,10 @@
1
+ import { FunctionType, UploadHandler, UploadResults } from '@armco/types';
2
+ declare const useUpload: (endpointOrHandler: string | UploadHandler, isSequential?: boolean, files?: Array<File | {
3
+ name: string;
4
+ url?: string;
5
+ }>) => {
6
+ clear: (fileId?: string) => void;
7
+ upload: (newFiles: File[], callback?: FunctionType, shouldAppend?: boolean) => Promise<void>;
8
+ results: UploadResults | undefined;
9
+ };
10
+ export default useUpload;