UNPKG

vue3-fileinput

Version:

A Vue 3 drag-and-drop file upload component with validation, preview, and error handling.

2 lines (1 loc) 3.16 kB
(function(e,r){typeof exports=="object"&&typeof module<"u"?module.exports=r(require("vue")):typeof define=="function"&&define.amd?define(["vue"],r):(e=typeof globalThis<"u"?globalThis:e||self,e.Vue3Fileinput=r(e.Vue))})(this,function(e){"use strict";const r=(l,c)=>{const d=l.__vccOpts||l;for(const[n,s]of c)d[n]=s;return d},k={class:"upload-text"},F={key:1,class:"preview"},v=["src","alt"],B=["accept"],T={key:0,class:"error-message"},w={key:1,class:"helper-text"},E={__name:"Vue3Fileinput",props:{modelValue:File,required:Boolean,fileType:{type:Array,default:()=>["image/png","image/jpeg","image/jpg","application/pdf","text/plain"]},placeholder:{type:String,default:"Drag and drop a file here"},helperText:{type:String,default:""},maxSize:{type:Number,default:2*1024*1024},maxFiles:{type:Number,default:1},inValid:Boolean},emits:["update:modelValue","file-reset"],setup(l,{expose:c,emit:d}){const n=l,s=d,i=e.ref(null),y=e.ref(null),o=e.ref(""),p=e.ref(!0),f=e.ref(n.modelValue||null),u=e.ref(!1),_=n.fileType.join(","),m=e.ref("");e.watch(()=>n.modelValue,t=>{t?V(t):g()});const z=()=>{y.value.click()},D=t=>{t.dataTransfer.dropEffect="copy",u.value=!0},N=()=>{u.value=!1},M=t=>{u.value=!1;const a=t.dataTransfer.files[0];h(a)},j=t=>{const a=t.target.files[0];h(a)},h=t=>{if(!t)return;if(!n.fileType.includes(t.type)){x(`Invalid file type. Only ${n.fileType.join(", ")} allowed.`);return}const a=(n.maxSize/(1024*1024)).toFixed(2);if(t.size>n.maxSize){x(`File is too large. Maximum size is ${a}MB.`);return}o.value="",p.value=!0,f.value=t,s("update:modelValue",t),V(t)},V=t=>{const a=new FileReader;t.type.startsWith("image/")?(a.onload=C=>{i.value=C.target.result,m.value="Preview"},a.readAsDataURL(t)):(i.value="",m.value="File Preview")},x=t=>{g(),o.value=t,p.value=!1},g=()=>{i.value=null,f.value=null,o.value="",p.value=!0,s("update:modelValue",null),s("file-reset")};return c({resetFile:g,selectedFile:f,isFileValid:p,preview:i}),(t,a)=>(e.openBlock(),e.createElementBlock("div",null,[e.createElementVNode("div",{class:e.normalizeClass(["drop-zone",{"error-border error-file":o.value||l.inValid,dragging:u.value}]),onClick:z,onDragover:e.withModifiers(D,["prevent"]),onDragleave:e.withModifiers(N,["prevent"]),onDrop:e.withModifiers(M,["prevent"])},[i.value?(e.openBlock(),e.createElementBlock("div",F,[e.createElementVNode("img",{src:i.value,alt:m.value,class:"preview-image"},null,8,v)])):(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass({"placeholder-error":l.inValid,placeholder:!l.inValid})},[e.renderSlot(t.$slots,"icon",{},()=>[a[0]||(a[0]=e.createElementVNode("i",{class:"fas fa-upload upload-icon fs-4"},null,-1))],!0),e.createElementVNode("p",k,e.toDisplayString(l.placeholder),1)],2)),e.createElementVNode("input",{type:"file",ref_key:"fileInput",ref:y,onChange:j,hidden:"",accept:e.unref(_)},null,40,B)],34),o.value?(e.openBlock(),e.createElementBlock("p",T,e.toDisplayString(o.value),1)):l.helperText?(e.openBlock(),e.createElementBlock("p",w,e.toDisplayString(l.helperText),1)):e.createCommentVNode("",!0)]))}},S=r(E,[["__scopeId","data-v-14a6869e"]]);return{install:(l,c)=>{l.component("Vue3Fileinput",S)}}});