@teppen/react-ui 1.8.10 → 1.8.12

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.
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("../../node_modules/tslib/tslib.es6.js"),r=require("react/jsx-runtime"),s=require("react"),n=require("./hook.js"),a=require("../../node_modules/react-icons/lu/index.js");exports.FileUploader=function(i){var l=s.useState([]),d=l[0],t=l[1],o=s.useState([]),c=o[0],u=o[1],p=n.useFileUploader({addFiles:function(r){t((function(s){return e.__spreadArray(e.__spreadArray([],s,!0),r,!0)}))},onValidationError:function(e){u(e)}}),g=p.inputProps,m=p.dropSpaceProps,x=p.isDragging;return r.jsxs(r.Fragment,{children:[r.jsxs("div",{className:"w-full mx-auto border-2 border-dashed border-gray-300 rounded-lg bg-gray-50",children:[r.jsxs("div",e.__assign({},m,{className:"cursor-pointer w-full h-40 flex flex-col gap-5 items-center justify-center rounded-lg transition-colors hover:bg-blue-100 ".concat(x?"bg-blue-100":""),children:[r.jsx("div",{children:r.jsx(a.LuUpload,{size:48})}),r.jsx("p",{children:x?"ここにファイルをドロップ":"ファイルの選択"})]})),r.jsx("input",e.__assign({},g))]}),d.length>0&&r.jsx("ul",{className:"space-y-2 mt-4",children:d.map((function(e){return r.jsx("li",{className:"bg-white border border-gray-300 p-2 rounded-lg",children:e.name},e.name)}))}),c.length>0&&r.jsxs("div",{className:"mt-4 text-red-500",children:[r.jsx("p",{children:"These files are not accepted:"}),r.jsx("ul",{className:"space-y-2",children:c.map((function(e){return r.jsx("li",{className:"bg-red-100 border border-red-300 p-2 rounded-lg",children:e.name},e.name)}))})]})]})};
1
+ "use strict";var e=require("../../node_modules/tslib/tslib.es6.js"),r=require("react/jsx-runtime"),i=require("react"),s=require("./hook.js"),d=require("../../node_modules/react-icons/lu/index.js");exports.FileUploader=function(l){var a=l.className,n=void 0===a?"":a,t=l.dropAreaClassName,o=void 0===t?"":t,c=l.dragActiveText,u=void 0===c?"ここにファイルをドロップ":c,p=l.defaultText,m=void 0===p?"ファイルの選択":p,x=l.icon,g=void 0===x?r.jsx(d.LuUpload,{size:48}):x,j=l.multiple,h=void 0===j||j,v=l.acceptedFileTypes,b=l.allowedExtensions,f=l.maxFileSize,F=l.files,y=l.rejectedFiles,_=l.onFilesAdded,N=l.onFilesRejected,w=l.useInternalState,A=void 0===w?void 0===F:w,S=l.showFileList,T=void 0===S||S,q=l.showRejectedFiles,z=void 0===q||q,E=l.rejectedFilesText,I=void 0===E?"These files are not accepted:":E,R=l.renderFileItem,U=l.renderRejectedFileItem,L=l.dropAreaHeight,M=void 0===L?"h-40":L,P=i.useState([]),k=P[0],C=P[1],D=i.useState([]),H=D[0],V=D[1],B=A?k:F||[],G=A?H:y||[],J=s.useFileUploader({addFiles:function(r){A&&C((function(i){return e.__spreadArray(e.__spreadArray([],i,!0),r,!0)})),null==_||_(r)},onValidationError:function(e){A&&V(e),null==N||N(e)},acceptedFileTypes:v,allowedExtensions:b,maxFileSize:f}),K=J.inputProps,O=J.dropSpaceProps,Q=J.isDragging;return r.jsxs(r.Fragment,{children:[r.jsxs("div",{className:"w-full mx-auto border-2 border-dashed border-gray-300 rounded-lg bg-gray-50 ".concat(n),children:[r.jsxs("div",e.__assign({},O,{className:"cursor-pointer w-full ".concat(M," flex flex-col gap-5 items-center justify-center rounded-lg transition-colors hover:bg-blue-100 ").concat(Q?"bg-blue-100":""," ").concat(o),children:[r.jsx("div",{children:g}),r.jsx("p",{children:Q?u:m})]})),r.jsx("input",e.__assign({},K,{multiple:h}))]}),T&&B.length>0&&r.jsx("ul",{className:"space-y-2 mt-4",children:B.map((function(e){return r.jsx("li",{className:"bg-white border border-gray-300 p-2 rounded-lg",children:R?R(e):e.name},"".concat(e.name,"-").concat(e.lastModified))}))}),z&&G.length>0&&r.jsxs("div",{className:"mt-4 text-red-500",children:[r.jsx("p",{children:I}),r.jsx("ul",{className:"space-y-2",children:G.map((function(e){return r.jsx("li",{className:"bg-red-100 border border-red-300 p-2 rounded-lg",children:U?U(e):e.name},"".concat(e.name,"-").concat(e.lastModified))}))})]})]})};
2
2
  //# sourceMappingURL=component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"component.js","sources":["../../../../src/file-uploader/component.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useFileUploader } from \"./hook\";\nimport { LuUpload } from \"react-icons/lu\";\n\ninterface FileUploaderProps {}\n\nexport function FileUploader(props: FileUploaderProps) {\n const [files, setFiles] = useState<File[]>([]);\n const [rejectedFiles, setRejectedFiles] = useState<File[]>([]);\n const { inputProps, dropSpaceProps, isDragging } = useFileUploader({\n addFiles: (files) => {\n setFiles((f) => [...f, ...files]);\n },\n onValidationError: (rejectedFiles) => {\n setRejectedFiles(rejectedFiles);\n },\n });\n\n return (\n <>\n <div className=\"w-full mx-auto border-2 border-dashed border-gray-300 rounded-lg bg-gray-50\">\n <div\n {...dropSpaceProps}\n className={`cursor-pointer w-full h-40 flex flex-col gap-5 items-center justify-center rounded-lg transition-colors hover:bg-blue-100 ${\n isDragging ? \"bg-blue-100\" : \"\"\n }`}\n >\n <div>\n <LuUpload size={48} />\n </div>\n <p>{isDragging ? \"ここにファイルをドロップ\" : \"ファイルの選択\"}</p>\n </div>\n <input {...inputProps} />\n </div>\n\n {files.length > 0 && (\n <ul className=\"space-y-2 mt-4\">\n {files.map((file) => (\n <li\n key={file.name}\n className=\"bg-white border border-gray-300 p-2 rounded-lg\"\n >\n {file.name}\n </li>\n ))}\n </ul>\n )}\n\n {rejectedFiles.length > 0 && (\n <div className=\"mt-4 text-red-500\">\n <p>These files are not accepted:</p>\n <ul className=\"space-y-2\">\n {rejectedFiles.map((file) => (\n <li\n key={file.name}\n className=\"bg-red-100 border border-red-300 p-2 rounded-lg\"\n >\n {file.name}\n </li>\n ))}\n </ul>\n </div>\n )}\n </>\n );\n}\n"],"names":["props","_a","useState","files","setFiles","_b","rejectedFiles","setRejectedFiles","_c","useFileUploader","addFiles","f","__spreadArray","onValidationError","inputProps","dropSpaceProps","isDragging","_jsxs","jsxs","_Fragment","Fragment","children","className","__assign","concat","_jsx","jsx","LuUpload","size","length","map","file","name"],"mappings":"0NAMM,SAAuBA,GACrB,IAAAC,EAAoBC,EAAAA,SAAiB,IAApCC,EAAKF,EAAA,GAAEG,EAAQH,EAAA,GAChBI,EAAoCH,EAAAA,SAAiB,IAApDI,EAAaD,EAAA,GAAEE,EAAgBF,EAAA,GAChCG,EAA6CC,EAAAA,gBAAgB,CACjEC,SAAU,SAACP,GACTC,GAAS,SAACO,GAAM,OAAAC,EAAAA,cAAAA,EAAAA,cAAA,GAAID,GAAC,GAAKR,GAAK,EAAC,GACjC,EACDU,kBAAmB,SAACP,GAClBC,EAAiBD,EAClB,IANKQ,EAAUN,EAAAM,WAAEC,EAAcP,EAAAO,eAAEC,EAAUR,EAAAQ,WAS9C,OACEC,EAAAC,KAAAC,EAAAC,SAAA,CAAAC,SAAA,CACEJ,EAAKC,KAAA,MAAA,CAAAI,UAAU,8EAA6ED,SAAA,CAC1FJ,EAAAA,KACM,MAAAM,EAAAA,SAAA,CAAA,EAAAR,EACJ,CAAAO,UAAW,6HAAAE,OACTR,EAAa,cAAgB,IAG/BK,SAAA,CAAAI,EAAAC,IAAA,MAAA,CAAAL,SACEI,EAAAA,IAACE,EAAAA,SAAS,CAAAC,KAAM,OAElBH,EAAAA,IAAI,IAAA,CAAAJ,SAAAL,EAAa,eAAiB,gBAEpCS,EAAAA,IAAW,QAAAF,EAAAA,SAAA,CAAA,EAAAT,OAGZX,EAAM0B,OAAS,GACdJ,EAAIC,IAAA,KAAA,CAAAJ,UAAU,0BACXnB,EAAM2B,KAAI,SAACC,GAAS,OACnBN,EAAAA,IAEE,KAAA,CAAAH,UAAU,0DAETS,EAAKC,MAHDD,EAAKC,KAKb,MAIJ1B,EAAcuB,OAAS,GACtBZ,cAAKK,UAAU,oBAAmBD,SAAA,CAChCI,EAAAA,oDACAA,EAAAA,IAAA,KAAA,CAAIH,UAAU,YAAWD,SACtBf,EAAcwB,KAAI,SAACC,GAAS,OAC3BN,EAEEC,IAAA,KAAA,CAAAJ,UAAU,kDAAiDD,SAE1DU,EAAKC,MAHDD,EAAKC,KAFe,WAazC"}
1
+ {"version":3,"file":"component.js","sources":["../../../../src/file-uploader/component.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useFileUploader } from \"./hook\";\nimport { LuUpload } from \"react-icons/lu\";\n\nexport interface FileUploaderProps {\n /**\n * Custom class name for the container\n */\n className?: string;\n /**\n * Custom class name for the drop area\n */\n dropAreaClassName?: string;\n /**\n * Text displayed when dragging files over the drop area\n */\n dragActiveText?: string;\n /**\n * Default text for the uploader\n */\n defaultText?: string;\n /**\n * Custom icon component to display instead of the default upload icon\n */\n icon?: React.ReactNode;\n /**\n * Whether to accept multiple files (default: true)\n */\n multiple?: boolean;\n /**\n * List of accepted file types (MIME types or extensions)\n * If not provided, defaults to a predefined list of common formats\n */\n acceptedFileTypes?: string[];\n /**\n * List of allowed file extensions (e.g. ['.jpg', '.pdf'])\n * If not provided, defaults to a predefined list\n */\n allowedExtensions?: string[];\n /**\n * Maximum allowed file size in bytes\n */\n maxFileSize?: number;\n /**\n * External controlled array of files\n */\n files?: File[];\n /**\n * External controlled array of rejected files\n */\n rejectedFiles?: File[];\n /**\n * Callback when files are added (and pass validation)\n */\n onFilesAdded?: (files: File[]) => void;\n /**\n * Callback when files are rejected\n */\n onFilesRejected?: (rejectedFiles: File[]) => void;\n /**\n * Whether to use internal state for files management (default: true if files prop not provided)\n */\n useInternalState?: boolean;\n /**\n * Whether to show the file list below the uploader (default: true)\n */\n showFileList?: boolean;\n /**\n * Whether to show rejected files list (default: true)\n */\n showRejectedFiles?: boolean;\n /**\n * Custom text for rejected files section\n */\n rejectedFilesText?: string;\n /**\n * Custom function to render each file item\n */\n renderFileItem?: (file: File) => React.ReactNode;\n /**\n * Custom function to render each rejected file item\n */\n renderRejectedFileItem?: (file: File) => React.ReactNode;\n /**\n * Height of the drop area (default: \"h-40\")\n */\n dropAreaHeight?: string;\n}\n\nexport function FileUploader({\n className = \"\",\n dropAreaClassName = \"\",\n dragActiveText = \"ここにファイルをドロップ\", // \"Drop files here\"\n defaultText = \"ファイルの選択\", // \"Select files\"\n icon = <LuUpload size={48} />,\n multiple = true,\n acceptedFileTypes,\n allowedExtensions,\n maxFileSize,\n files: externalFiles,\n rejectedFiles: externalRejectedFiles,\n onFilesAdded,\n onFilesRejected,\n useInternalState = externalFiles === undefined,\n showFileList = true,\n showRejectedFiles = true,\n rejectedFilesText = \"These files are not accepted:\",\n renderFileItem,\n renderRejectedFileItem,\n dropAreaHeight = \"h-40\",\n}: FileUploaderProps) {\n // Internal state for files if not controlled externally\n const [internalFiles, setInternalFiles] = useState<File[]>([]);\n const [internalRejectedFiles, setInternalRejectedFiles] = useState<File[]>(\n []\n );\n\n // Use either external or internal state based on props\n const files = useInternalState ? internalFiles : externalFiles || [];\n const rejectedFiles = useInternalState\n ? internalRejectedFiles\n : externalRejectedFiles || [];\n\n const { inputProps, dropSpaceProps, isDragging } = useFileUploader({\n addFiles: (newFiles) => {\n if (useInternalState) {\n setInternalFiles((f) => [...f, ...newFiles]);\n }\n onFilesAdded?.(newFiles);\n },\n onValidationError: (rejectedFiles) => {\n if (useInternalState) {\n setInternalRejectedFiles(rejectedFiles);\n }\n onFilesRejected?.(rejectedFiles);\n },\n acceptedFileTypes,\n allowedExtensions,\n maxFileSize,\n });\n\n return (\n <>\n <div\n className={`w-full mx-auto border-2 border-dashed border-gray-300 rounded-lg bg-gray-50 ${className}`}\n >\n <div\n {...dropSpaceProps}\n className={`cursor-pointer w-full ${dropAreaHeight} flex flex-col gap-5 items-center justify-center rounded-lg transition-colors hover:bg-blue-100 ${\n isDragging ? \"bg-blue-100\" : \"\"\n } ${dropAreaClassName}`}\n >\n <div>{icon}</div>\n <p>{isDragging ? dragActiveText : defaultText}</p>\n </div>\n <input {...inputProps} multiple={multiple} />\n </div>\n\n {showFileList && files.length > 0 && (\n <ul className=\"space-y-2 mt-4\">\n {files.map((file) => (\n <li\n key={`${file.name}-${file.lastModified}`}\n className=\"bg-white border border-gray-300 p-2 rounded-lg\"\n >\n {renderFileItem ? renderFileItem(file) : file.name}\n </li>\n ))}\n </ul>\n )}\n\n {showRejectedFiles && rejectedFiles.length > 0 && (\n <div className=\"mt-4 text-red-500\">\n <p>{rejectedFilesText}</p>\n <ul className=\"space-y-2\">\n {rejectedFiles.map((file) => (\n <li\n key={`${file.name}-${file.lastModified}`}\n className=\"bg-red-100 border border-red-300 p-2 rounded-lg\"\n >\n {renderRejectedFileItem\n ? renderRejectedFileItem(file)\n : file.name}\n </li>\n ))}\n </ul>\n </div>\n )}\n </>\n );\n}\n"],"names":["_a","_b","className","_c","dropAreaClassName","_d","dragActiveText","_e","defaultText","_f","icon","_jsx","jsx","LuUpload","size","_g","multiple","acceptedFileTypes","allowedExtensions","maxFileSize","externalFiles","files","externalRejectedFiles","onFilesAdded","onFilesRejected","_h","useInternalState","undefined","_j","showFileList","_k","showRejectedFiles","_l","rejectedFilesText","renderFileItem","renderRejectedFileItem","_m","dropAreaHeight","_o","useState","internalFiles","setInternalFiles","_p","internalRejectedFiles","setInternalRejectedFiles","rejectedFiles","_q","useFileUploader","addFiles","newFiles","f","__spreadArray","onValidationError","inputProps","dropSpaceProps","isDragging","_jsxs","_Fragment","children","concat","__assign","length","map","file","name","lastModified"],"mappings":"0NAyFM,SAAuBA,OAC3BC,EAAcD,EAAAE,UAAdA,OAAY,IAAAD,EAAA,KACZE,EAAAH,EAAAI,kBAAAA,OAAiB,IAAAD,EAAG,GAAEA,EACtBE,mBAAAC,aAAiB,eAAcD,EAC/BE,EAAAP,EAAAQ,YAAAA,OAAc,IAAAD,EAAA,UAASA,EACvBE,EAAAT,EAAAU,KAAAA,aAAOC,EAACC,IAAAC,EAAQA,SAAC,CAAAC,KAAM,KAAML,EAC7BM,aAAAC,OAAW,IAAAD,KACXE,EAAiBjB,EAAAiB,kBACjBC,EAAiBlB,EAAAkB,kBACjBC,EAAWnB,EAAAmB,YACJC,EAAapB,EAAAqB,MACLC,kBACfC,iBACAC,oBACAC,EAAAzB,EAAA0B,iBAAAA,kBAAqCC,IAAlBP,EAA2BK,EAC9CG,EAAmB5B,EAAA6B,aAAnBA,OAAY,IAAAD,GAAOA,EACnBE,sBAAAC,cAAwBD,EACxBE,EAAAhC,EAAAiC,kBAAAA,OAAiB,IAAAD,EAAG,gCAA+BA,EACnDE,EAAclC,EAAAkC,eACdC,2BACAC,EAAApC,EAAAqC,eAAAA,OAAc,IAAAD,EAAG,OAAMA,EAGjBE,EAAoCC,EAAAA,SAAiB,IAApDC,EAAaF,EAAA,GAAEG,EAAgBH,EAAA,GAChCI,EAAoDH,EAAAA,SACxD,IADKI,EAAqBD,EAAA,GAAEE,EAAwBF,EAAA,GAKhDrB,EAAQK,EAAmBc,EAAgBpB,GAAiB,GAC5DyB,EAAgBnB,EAClBiB,EACArB,GAAyB,GAEvBwB,EAA6CC,EAAAA,gBAAgB,CACjEC,SAAU,SAACC,GACLvB,GACFe,GAAiB,SAACS,GAAM,OAAAC,EAAAA,cAAAA,EAAAA,cAAA,GAAID,GAAC,GAAKD,GAAQ,EAAC,IAE7C1B,SAAAA,EAAe0B,EAChB,EACDG,kBAAmB,SAACP,GACdnB,GACFkB,EAAyBC,GAE3BrB,SAAAA,EAAkBqB,EACnB,EACD5B,kBAAiBA,EACjBC,kBAAiBA,EACjBC,YAAWA,IAfLkC,EAAUP,EAAAO,WAAEC,EAAcR,EAAAQ,eAAEC,EAAUT,EAAAS,WAkB9C,OACEC,EAAAA,KAAAC,EAAAA,SAAA,CAAAC,SAAA,CACEF,EAAAA,KACE,MAAA,CAAAtD,UAAW,+EAA+EyD,OAAAzD,GAAWwD,SAAA,CAErGF,2BACMF,EAAc,CAClBpD,UAAW,gCAAyBmC,EAAc,oGAAAsB,OAChDJ,EAAa,cAAgB,GAAE,KAAAI,OAC7BvD,aAEJO,EAAMC,IAAA,MAAA,CAAA8C,SAAAhD,IACNC,EAAAA,kBAAI4C,EAAajD,EAAiBE,QAEpCG,EAAAC,IAAA,QAAAgD,EAAAA,SAAA,CAAA,EAAWP,EAAY,CAAArC,SAAUA,QAGlCa,GAAgBR,EAAMwC,OAAS,GAC9BlD,EAAAC,IAAA,KAAA,CAAIV,UAAU,iBACXwD,SAAArC,EAAMyC,KAAI,SAACC,GAAS,OACnBpD,EAAAC,IAAA,KAAA,CAEEV,UAAU,iDAETwD,SAAAxB,EAAiBA,EAAe6B,GAAQA,EAAKC,MAHzC,GAAAL,OAAGI,EAAKC,KAAQ,KAAAL,OAAAI,EAAKE,cAK7B,MAIJlC,GAAqBc,EAAcgB,OAAS,GAC3CL,EAAAA,KAAK,MAAA,CAAAtD,UAAU,oBAAmBwD,SAAA,CAChC/C,EAAAA,IAAI,IAAA,CAAA+C,SAAAzB,IACJtB,EAAAC,IAAA,KAAA,CAAIV,UAAU,YACXwD,SAAAb,EAAciB,KAAI,SAACC,GAAS,OAC3BpD,EAEEC,IAAA,KAAA,CAAAV,UAAU,2DAETiC,EACGA,EAAuB4B,GACvBA,EAAKC,MALJ,UAAGD,EAAKC,KAAI,KAAAL,OAAII,EAAKE,yBAa1C"}
@@ -1,2 +1,2 @@
1
- "use strict";var e=require("react"),i=["image/*","text/*","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.ms-outlook","application/json","application/xml","application/pdf","application/x-compressed","application/x-zip-compressed","application/x-gzip","application/x-bzip2","application/x-tar","application/x-rar-compressed","application/x-7z-compressed","application/zip"],a=[".msg"];exports.useFileUploader=function(n){var t=e.useRef(null),o=e.useState(!1),r=o[0],p=o[1],c=function(e){var t=function(e){var n=[],t=[];return e.forEach((function(e){var o=e.name.split(".").pop();o&&a.includes(".".concat(o))||i.some((function(i){return e.type.match(i)}))?n.push(e):t.push(e)})),{validFiles:n,rejectedFiles:t}}(e),o=t.validFiles,r=t.rejectedFiles;o.length>0&&n.addFiles(o),r.length>0&&n.onValidationError&&n.onValidationError(r)};return{inputProps:{ref:t,type:"file",multiple:!0,className:"hidden",accept:i.join(","),onChange:function(e){if(e.target.files){var i=Array.from(e.target.files);c(i)}}},isDragging:r,dropSpaceProps:{onClick:function(){var e;return null===(e=t.current)||void 0===e?void 0:e.click()},onDrop:function(e){if(e.preventDefault(),p(!1),e.dataTransfer.files){var i=Array.from(e.dataTransfer.files);c(i)}},onDragOver:function(e){e.preventDefault(),p(!0)},onDragLeave:function(e){p(!1)}}}};
1
+ "use strict";var e=require("react"),i=["image/*","text/*","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.ms-outlook","application/json","application/xml","application/pdf","application/x-compressed","application/x-zip-compressed","application/x-gzip","application/x-bzip2","application/x-tar","application/x-rar-compressed","application/x-7z-compressed","application/zip"],a=[".msg",".jpg",".jpeg",".png",".pdf",".xlsx",".docx",".txt",".zip"];exports.useFileUploader=function(t){var n=e.useRef(null),o=e.useState(!1),r=o[0],p=o[1],s=t.acceptedFileTypes||i,l=t.allowedExtensions||a,c=function(e){var i=function(e){var i=[],a=[];return e.forEach((function(e){if(t.maxFileSize&&e.size>t.maxFileSize)a.push(e);else{var n=e.name.split(".").pop();n&&l.some((function(e){return e.toLowerCase()===".".concat(n.toLowerCase())||e.toLowerCase()===n.toLowerCase()}))||s.some((function(i){if(i.endsWith("/*")){var a=i.split("/")[0];return e.type.startsWith("".concat(a,"/"))}return e.type===i}))?i.push(e):a.push(e)}})),{validFiles:i,rejectedFiles:a}}(e),a=i.validFiles,n=i.rejectedFiles;a.length>0&&t.addFiles(a),n.length>0&&t.onValidationError&&t.onValidationError(n)};return{inputProps:{ref:n,type:"file",className:"hidden",accept:s.join(","),onChange:function(e){if(e.target.files){var i=Array.from(e.target.files);c(i)}}},isDragging:r,dropSpaceProps:{onClick:function(){var e;return null===(e=n.current)||void 0===e?void 0:e.click()},onDrop:function(e){if(e.preventDefault(),p(!1),e.dataTransfer.files){var i=Array.from(e.dataTransfer.files);c(i)}},onDragOver:function(e){e.preventDefault(),p(!0)},onDragLeave:function(e){p(!1)}}}};
2
2
  //# sourceMappingURL=hook.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hook.js","sources":["../../../../src/file-uploader/hook.ts"],"sourcesContent":["import { useRef, useState } from \"react\";\n\ninterface IPropsFileUploader {\n addFiles: (files: File[]) => void;\n onValidationError?: (rejectedFiles: File[]) => void;\n}\n\ninterface IReturnFileUploader {\n inputProps: {\n ref: React.RefObject<HTMLInputElement>;\n type: \"file\";\n multiple?: boolean;\n accept?: string;\n className?: string;\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n };\n isDragging: boolean;\n dropSpaceProps: {\n onClick?: React.MouseEventHandler;\n onDrop: (e: React.DragEvent) => void;\n onDragOver: (e: React.DragEvent) => void;\n onDragLeave: (e: React.DragEvent) => void;\n };\n}\n\nconst ACCEPTED_TYPES = [\n \"image/*\", // image\n \"text/*\", // .txt\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\", // .xlsx\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\", // .pptx\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", // .docx\n \"application/vnd.ms-excel\", // .xls\n \"application/vnd.ms-outlook\", // .msg\n \"application/json\", // .json\n \"application/xml\", // .xml\n \"application/pdf\", // .pdf\n \"application/x-compressed\", // .tgz\n \"application/x-zip-compressed\", // .zip\n \"application/x-gzip\", // .gz\n \"application/x-bzip2\", // .bz2\n \"application/x-tar\", // .tar\n \"application/x-rar-compressed\", // .rar\n \"application/x-7z-compressed\", // .7z\n \"application/zip\", // .zip\n];\n\nconst ALLOWED_EXTENSIONS = [\".msg\"];\n\nexport function useFileUploader(\n props: IPropsFileUploader\n): IReturnFileUploader {\n const inputRef = useRef<HTMLInputElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n const validateFiles = (\n files: File[]\n ): { validFiles: File[]; rejectedFiles: File[] } => {\n const validFiles: File[] = [];\n const rejectedFiles: File[] = [];\n\n files.forEach((file) => {\n const extension = file.name.split(\".\").pop();\n if (extension && ALLOWED_EXTENSIONS.includes(`.${extension}`)) {\n validFiles.push(file);\n return;\n }\n if (ACCEPTED_TYPES.some((type) => file.type.match(type))) {\n validFiles.push(file);\n } else {\n rejectedFiles.push(file);\n }\n });\n\n return { validFiles, rejectedFiles };\n };\n\n const addFiles = (files: File[]) => {\n const { validFiles, rejectedFiles } = validateFiles(files);\n if (validFiles.length > 0) {\n props.addFiles(validFiles);\n }\n if (rejectedFiles.length > 0 && props.onValidationError) {\n props.onValidationError(rejectedFiles);\n }\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n if (e.dataTransfer.files) {\n const droppedFiles = Array.from(e.dataTransfer.files);\n addFiles(droppedFiles);\n }\n };\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(true);\n };\n\n const handleDragLeave = (e: React.DragEvent) => {\n setIsDragging(false);\n };\n\n return {\n inputProps: {\n ref: inputRef,\n type: \"file\",\n multiple: true,\n className: \"hidden\",\n accept: ACCEPTED_TYPES.join(\",\"),\n onChange: (e) => {\n if (e.target.files) {\n const selectedFiles = Array.from(e.target.files);\n addFiles(selectedFiles);\n }\n },\n },\n isDragging,\n dropSpaceProps: {\n onClick: () => inputRef.current?.click(),\n onDrop: handleDrop,\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n },\n };\n}\n"],"names":["ACCEPTED_TYPES","ALLOWED_EXTENSIONS","props","inputRef","useRef","_a","useState","isDragging","setIsDragging","addFiles","files","validFiles","rejectedFiles","forEach","file","extension","name","split","pop","includes","concat","some","type","match","push","validateFiles","length","onValidationError","inputProps","ref","multiple","className","accept","join","onChange","e","target","selectedFiles","Array","from","dropSpaceProps","onClick","current","click","onDrop","preventDefault","dataTransfer","droppedFiles","onDragOver","onDragLeave"],"mappings":"oCAyBMA,EAAiB,CACrB,UACA,SACA,oEACA,4EACA,0EACA,2BACA,6BACA,mBACA,kBACA,kBACA,2BACA,+BACA,qBACA,sBACA,oBACA,+BACA,8BACA,mBAGIC,EAAqB,CAAC,gCAEtB,SACJC,GAEA,IAAMC,EAAWC,SAAyB,MACpCC,EAA8BC,EAAAA,UAAS,GAAtCC,EAAUF,EAAA,GAAEG,EAAaH,EAAA,GAwB1BI,EAAW,SAACC,GACV,IAAAL,EAvBc,SACpBK,GAEA,IAAMC,EAAqB,GACrBC,EAAwB,GAe9B,OAbAF,EAAMG,SAAQ,SAACC,GACb,IAAMC,EAAYD,EAAKE,KAAKC,MAAM,KAAKC,MACnCH,GAAad,EAAmBkB,SAAS,IAAAC,OAAIL,KAI7Cf,EAAeqB,MAAK,SAACC,GAAS,OAAAR,EAAKQ,KAAKC,MAAMD,EAAK,IAHrDX,EAAWa,KAAKV,GAMhBF,EAAcY,KAAKV,EAEvB,IAEO,CAAEH,WAAUA,EAAEC,cAAaA,EACpC,CAGwCa,CAAcf,GAA5CC,EAAUN,EAAAM,WAAEC,EAAaP,EAAAO,cAC7BD,EAAWe,OAAS,GACtBxB,EAAMO,SAASE,GAEbC,EAAcc,OAAS,GAAKxB,EAAMyB,mBACpCzB,EAAMyB,kBAAkBf,EAE5B,EAoBA,MAAO,CACLgB,WAAY,CACVC,IAAK1B,EACLmB,KAAM,OACNQ,UAAU,EACVC,UAAW,SACXC,OAAQhC,EAAeiC,KAAK,KAC5BC,SAAU,SAACC,GACT,GAAIA,EAAEC,OAAO1B,MAAO,CAClB,IAAM2B,EAAgBC,MAAMC,KAAKJ,EAAEC,OAAO1B,OAC1CD,EAAS4B,EACV,CACF,GAEH9B,WAAUA,EACViC,eAAgB,CACdC,QAAS,WAAM,IAAApC,EAAA,OAAkB,QAAlBA,EAAAF,EAASuC,eAAS,IAAArC,OAAA,EAAAA,EAAAsC,OAAO,EACxCC,OAnCe,SAACT,GAGlB,GAFAA,EAAEU,iBACFrC,GAAc,GACV2B,EAAEW,aAAapC,MAAO,CACxB,IAAMqC,EAAeT,MAAMC,KAAKJ,EAAEW,aAAapC,OAC/CD,EAASsC,EACV,CACH,EA6BIC,WA3BmB,SAACb,GACtBA,EAAEU,iBACFrC,GAAc,EAChB,EAyBIyC,YAvBoB,SAACd,GACvB3B,GAAc,EAChB,GAwBF"}
1
+ {"version":3,"file":"hook.js","sources":["../../../../src/file-uploader/hook.ts"],"sourcesContent":["import { useRef, useState } from \"react\";\n\ninterface IPropsFileUploader {\n addFiles: (files: File[]) => void;\n onValidationError?: (rejectedFiles: File[]) => void;\n acceptedFileTypes?: string[];\n allowedExtensions?: string[];\n maxFileSize?: number;\n}\n\ninterface IReturnFileUploader {\n inputProps: {\n ref: React.RefObject<HTMLInputElement>;\n type: \"file\";\n accept?: string;\n className?: string;\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n };\n isDragging: boolean;\n dropSpaceProps: {\n onClick?: React.MouseEventHandler;\n onDrop: (e: React.DragEvent) => void;\n onDragOver: (e: React.DragEvent) => void;\n onDragLeave: (e: React.DragEvent) => void;\n };\n}\n\n// Default accepted file types\nconst DEFAULT_ACCEPTED_TYPES = [\n \"image/*\", // image\n \"text/*\", // .txt\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\", // .xlsx\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\", // .pptx\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", // .docx\n \"application/vnd.ms-excel\", // .xls\n \"application/vnd.ms-outlook\", // .msg\n \"application/json\", // .json\n \"application/xml\", // .xml\n \"application/pdf\", // .pdf\n \"application/x-compressed\", // .tgz\n \"application/x-zip-compressed\", // .zip\n \"application/x-gzip\", // .gz\n \"application/x-bzip2\", // .bz2\n \"application/x-tar\", // .tar\n \"application/x-rar-compressed\", // .rar\n \"application/x-7z-compressed\", // .7z\n \"application/zip\", // .zip\n];\n\n// Default allowed extensions\nconst DEFAULT_ALLOWED_EXTENSIONS = [\n \".msg\",\n \".jpg\",\n \".jpeg\",\n \".png\",\n \".pdf\",\n \".xlsx\",\n \".docx\",\n \".txt\",\n \".zip\",\n];\n\nexport function useFileUploader(\n props: IPropsFileUploader\n): IReturnFileUploader {\n const inputRef = useRef<HTMLInputElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n const acceptedTypes = props.acceptedFileTypes || DEFAULT_ACCEPTED_TYPES;\n const allowedExtensions =\n props.allowedExtensions || DEFAULT_ALLOWED_EXTENSIONS;\n\n const validateFiles = (\n files: File[]\n ): { validFiles: File[]; rejectedFiles: File[] } => {\n const validFiles: File[] = [];\n const rejectedFiles: File[] = [];\n\n files.forEach((file) => {\n // Check file size if maxFileSize is specified\n if (props.maxFileSize && file.size > props.maxFileSize) {\n rejectedFiles.push(file);\n return;\n }\n\n const extension = file.name.split(\".\").pop();\n if (\n extension &&\n allowedExtensions.some(\n (ext) =>\n ext.toLowerCase() === `.${extension.toLowerCase()}` ||\n ext.toLowerCase() === extension.toLowerCase()\n )\n ) {\n validFiles.push(file);\n return;\n }\n\n if (\n acceptedTypes.some((type) => {\n if (type.endsWith(\"/*\")) {\n const mainType = type.split(\"/\")[0];\n return file.type.startsWith(`${mainType}/`);\n }\n return file.type === type;\n })\n ) {\n validFiles.push(file);\n } else {\n rejectedFiles.push(file);\n }\n });\n\n return { validFiles, rejectedFiles };\n };\n\n const addFiles = (files: File[]) => {\n const { validFiles, rejectedFiles } = validateFiles(files);\n if (validFiles.length > 0) {\n props.addFiles(validFiles);\n }\n if (rejectedFiles.length > 0 && props.onValidationError) {\n props.onValidationError(rejectedFiles);\n }\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n if (e.dataTransfer.files) {\n const droppedFiles = Array.from(e.dataTransfer.files);\n addFiles(droppedFiles);\n }\n };\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(true);\n };\n\n const handleDragLeave = (e: React.DragEvent) => {\n setIsDragging(false);\n };\n\n return {\n inputProps: {\n ref: inputRef,\n type: \"file\",\n className: \"hidden\",\n accept: acceptedTypes.join(\",\"),\n onChange: (e) => {\n if (e.target.files) {\n const selectedFiles = Array.from(e.target.files);\n addFiles(selectedFiles);\n }\n },\n },\n isDragging,\n dropSpaceProps: {\n onClick: () => inputRef.current?.click(),\n onDrop: handleDrop,\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n },\n };\n}\n"],"names":["DEFAULT_ACCEPTED_TYPES","DEFAULT_ALLOWED_EXTENSIONS","props","inputRef","useRef","_a","useState","isDragging","setIsDragging","acceptedTypes","acceptedFileTypes","allowedExtensions","addFiles","files","validFiles","rejectedFiles","forEach","file","maxFileSize","size","push","extension","name","split","pop","some","ext","toLowerCase","type","endsWith","mainType","startsWith","concat","validateFiles","length","onValidationError","inputProps","ref","className","accept","join","onChange","e","target","selectedFiles","Array","from","dropSpaceProps","onClick","current","click","onDrop","preventDefault","dataTransfer","droppedFiles","onDragOver","onDragLeave"],"mappings":"oCA4BMA,EAAyB,CAC7B,UACA,SACA,oEACA,4EACA,0EACA,2BACA,6BACA,mBACA,kBACA,kBACA,2BACA,+BACA,qBACA,sBACA,oBACA,+BACA,8BACA,mBAIIC,EAA6B,CACjC,OACA,OACA,QACA,OACA,OACA,QACA,QACA,OACA,gCAGI,SACJC,GAEA,IAAMC,EAAWC,SAAyB,MACpCC,EAA8BC,EAAAA,UAAS,GAAtCC,EAAUF,EAAA,GAAEG,EAAaH,EAAA,GAE1BI,EAAgBP,EAAMQ,mBAAqBV,EAC3CW,EACJT,EAAMS,mBAAqBV,EA8CvBW,EAAW,SAACC,GACV,IAAAR,EA7Cc,SACpBQ,GAEA,IAAMC,EAAqB,GACrBC,EAAwB,GAqC9B,OAnCAF,EAAMG,SAAQ,SAACC,GAEb,GAAIf,EAAMgB,aAAeD,EAAKE,KAAOjB,EAAMgB,YACzCH,EAAcK,KAAKH,OADrB,CAKA,IAAMI,EAAYJ,EAAKK,KAAKC,MAAM,KAAKC,MAErCH,GACAV,EAAkBc,MAChB,SAACC,GACC,OAAAA,EAAIC,gBAAkB,WAAIN,EAAUM,gBACpCD,EAAIC,gBAAkBN,EAAUM,kBAQpClB,EAAcgB,MAAK,SAACG,GAClB,GAAIA,EAAKC,SAAS,MAAO,CACvB,IAAMC,EAAWF,EAAKL,MAAM,KAAK,GACjC,OAAON,EAAKW,KAAKG,WAAW,GAAGC,OAAAF,EAAW,KAC3C,CACD,OAAOb,EAAKW,OAASA,KAVvBd,EAAWM,KAAKH,GAehBF,EAAcK,KAAKH,EA1BpB,CA4BH,IAEO,CAAEH,WAAUA,EAAEC,cAAaA,EACpC,CAGwCkB,CAAcpB,GAA5CC,EAAUT,EAAAS,WAAEC,EAAaV,EAAAU,cAC7BD,EAAWoB,OAAS,GACtBhC,EAAMU,SAASE,GAEbC,EAAcmB,OAAS,GAAKhC,EAAMiC,mBACpCjC,EAAMiC,kBAAkBpB,EAE5B,EAoBA,MAAO,CACLqB,WAAY,CACVC,IAAKlC,EACLyB,KAAM,OACNU,UAAW,SACXC,OAAQ9B,EAAc+B,KAAK,KAC3BC,SAAU,SAACC,GACT,GAAIA,EAAEC,OAAO9B,MAAO,CAClB,IAAM+B,EAAgBC,MAAMC,KAAKJ,EAAEC,OAAO9B,OAC1CD,EAASgC,EACV,CACF,GAEHrC,WAAUA,EACVwC,eAAgB,CACdC,QAAS,WAAM,IAAA3C,EAAA,OAAkB,QAAlBA,EAAAF,EAAS8C,eAAS,IAAA5C,OAAA,EAAAA,EAAA6C,OAAO,EACxCC,OAlCe,SAACT,GAGlB,GAFAA,EAAEU,iBACF5C,GAAc,GACVkC,EAAEW,aAAaxC,MAAO,CACxB,IAAMyC,EAAeT,MAAMC,KAAKJ,EAAEW,aAAaxC,OAC/CD,EAAS0C,EACV,CACH,EA4BIC,WA1BmB,SAACb,GACtBA,EAAEU,iBACF5C,GAAc,EAChB,EAwBIgD,YAtBoB,SAACd,GACvBlC,GAAc,EAChB,GAuBF"}
@@ -1,2 +1,2 @@
1
- import{__assign as e,__spreadArray as r}from"../../node_modules/tslib/tslib.es6.js";import{jsxs as n,Fragment as o,jsx as i}from"react/jsx-runtime";import{useState as l}from"react";import{useFileUploader as d}from"./hook.js";import{LuUpload as t}from"../../node_modules/react-icons/lu/index.js";function a(a){var c=l([]),s=c[0],m=c[1],u=l([]),p=u[0],h=u[1],g=d({addFiles:function(e){m((function(n){return r(r([],n,!0),e,!0)}))},onValidationError:function(e){h(e)}}),f=g.inputProps,b=g.dropSpaceProps,x=g.isDragging;return n(o,{children:[n("div",{className:"w-full mx-auto border-2 border-dashed border-gray-300 rounded-lg bg-gray-50",children:[n("div",e({},b,{className:"cursor-pointer w-full h-40 flex flex-col gap-5 items-center justify-center rounded-lg transition-colors hover:bg-blue-100 ".concat(x?"bg-blue-100":""),children:[i("div",{children:i(t,{size:48})}),i("p",{children:x?"ここにファイルをドロップ":"ファイルの選択"})]})),i("input",e({},f))]}),s.length>0&&i("ul",{className:"space-y-2 mt-4",children:s.map((function(e){return i("li",{className:"bg-white border border-gray-300 p-2 rounded-lg",children:e.name},e.name)}))}),p.length>0&&n("div",{className:"mt-4 text-red-500",children:[i("p",{children:"These files are not accepted:"}),i("ul",{className:"space-y-2",children:p.map((function(e){return i("li",{className:"bg-red-100 border border-red-300 p-2 rounded-lg",children:e.name},e.name)}))})]})]})}export{a as FileUploader};
1
+ import{__spreadArray as e,__assign as i}from"../../node_modules/tslib/tslib.es6.js";import{jsx as r,jsxs as o,Fragment as d}from"react/jsx-runtime";import{useState as l}from"react";import{useFileUploader as t}from"./hook.js";import{LuUpload as n}from"../../node_modules/react-icons/lu/index.js";function a(a){var c=a.className,s=void 0===c?"":c,m=a.dropAreaClassName,u=void 0===m?"":m,p=a.dragActiveText,h=void 0===p?"ここにファイルをドロップ":p,f=a.defaultText,g=void 0===f?"ファイルの選択":f,v=a.icon,b=void 0===v?r(n,{size:48}):v,x=a.multiple,F=void 0===x||x,j=a.acceptedFileTypes,N=a.allowedExtensions,y=a.maxFileSize,w=a.files,T=a.rejectedFiles,A=a.onFilesAdded,S=a.onFilesRejected,z=a.useInternalState,E=void 0===z?void 0===w:z,I=a.showFileList,R=void 0===I||I,M=a.showRejectedFiles,P=void 0===M||M,_=a.rejectedFilesText,k=void 0===_?"These files are not accepted:":_,C=a.renderFileItem,D=a.renderRejectedFileItem,H=a.dropAreaHeight,L=void 0===H?"h-40":H,V=l([]),q=V[0],B=V[1],G=l([]),J=G[0],K=G[1],O=E?q:w||[],Q=E?J:T||[],U=t({addFiles:function(i){E&&B((function(r){return e(e([],r,!0),i,!0)})),null==A||A(i)},onValidationError:function(e){E&&K(e),null==S||S(e)},acceptedFileTypes:j,allowedExtensions:N,maxFileSize:y}),W=U.inputProps,X=U.dropSpaceProps,Y=U.isDragging;return o(d,{children:[o("div",{className:"w-full mx-auto border-2 border-dashed border-gray-300 rounded-lg bg-gray-50 ".concat(s),children:[o("div",i({},X,{className:"cursor-pointer w-full ".concat(L," flex flex-col gap-5 items-center justify-center rounded-lg transition-colors hover:bg-blue-100 ").concat(Y?"bg-blue-100":""," ").concat(u),children:[r("div",{children:b}),r("p",{children:Y?h:g})]})),r("input",i({},W,{multiple:F}))]}),R&&O.length>0&&r("ul",{className:"space-y-2 mt-4",children:O.map((function(e){return r("li",{className:"bg-white border border-gray-300 p-2 rounded-lg",children:C?C(e):e.name},"".concat(e.name,"-").concat(e.lastModified))}))}),P&&Q.length>0&&o("div",{className:"mt-4 text-red-500",children:[r("p",{children:k}),r("ul",{className:"space-y-2",children:Q.map((function(e){return r("li",{className:"bg-red-100 border border-red-300 p-2 rounded-lg",children:D?D(e):e.name},"".concat(e.name,"-").concat(e.lastModified))}))})]})]})}export{a as FileUploader};
2
2
  //# sourceMappingURL=component.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"component.js","sources":["../../../../src/file-uploader/component.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useFileUploader } from \"./hook\";\nimport { LuUpload } from \"react-icons/lu\";\n\ninterface FileUploaderProps {}\n\nexport function FileUploader(props: FileUploaderProps) {\n const [files, setFiles] = useState<File[]>([]);\n const [rejectedFiles, setRejectedFiles] = useState<File[]>([]);\n const { inputProps, dropSpaceProps, isDragging } = useFileUploader({\n addFiles: (files) => {\n setFiles((f) => [...f, ...files]);\n },\n onValidationError: (rejectedFiles) => {\n setRejectedFiles(rejectedFiles);\n },\n });\n\n return (\n <>\n <div className=\"w-full mx-auto border-2 border-dashed border-gray-300 rounded-lg bg-gray-50\">\n <div\n {...dropSpaceProps}\n className={`cursor-pointer w-full h-40 flex flex-col gap-5 items-center justify-center rounded-lg transition-colors hover:bg-blue-100 ${\n isDragging ? \"bg-blue-100\" : \"\"\n }`}\n >\n <div>\n <LuUpload size={48} />\n </div>\n <p>{isDragging ? \"ここにファイルをドロップ\" : \"ファイルの選択\"}</p>\n </div>\n <input {...inputProps} />\n </div>\n\n {files.length > 0 && (\n <ul className=\"space-y-2 mt-4\">\n {files.map((file) => (\n <li\n key={file.name}\n className=\"bg-white border border-gray-300 p-2 rounded-lg\"\n >\n {file.name}\n </li>\n ))}\n </ul>\n )}\n\n {rejectedFiles.length > 0 && (\n <div className=\"mt-4 text-red-500\">\n <p>These files are not accepted:</p>\n <ul className=\"space-y-2\">\n {rejectedFiles.map((file) => (\n <li\n key={file.name}\n className=\"bg-red-100 border border-red-300 p-2 rounded-lg\"\n >\n {file.name}\n </li>\n ))}\n </ul>\n </div>\n )}\n </>\n );\n}\n"],"names":["FileUploader","props","_a","useState","files","setFiles","_b","rejectedFiles","setRejectedFiles","_c","useFileUploader","addFiles","f","__spreadArray","onValidationError","inputProps","dropSpaceProps","isDragging","_jsxs","_Fragment","children","className","__assign","concat","_jsx","LuUpload","size","length","map","file","name"],"mappings":"uSAMM,SAAUA,EAAaC,GACrB,IAAAC,EAAoBC,EAAiB,IAApCC,EAAKF,EAAA,GAAEG,EAAQH,EAAA,GAChBI,EAAoCH,EAAiB,IAApDI,EAAaD,EAAA,GAAEE,EAAgBF,EAAA,GAChCG,EAA6CC,EAAgB,CACjEC,SAAU,SAACP,GACTC,GAAS,SAACO,GAAM,OAAAC,EAAAA,EAAA,GAAID,GAAC,GAAKR,GAAK,EAAC,GACjC,EACDU,kBAAmB,SAACP,GAClBC,EAAiBD,EAClB,IANKQ,EAAUN,EAAAM,WAAEC,EAAcP,EAAAO,eAAEC,EAAUR,EAAAQ,WAS9C,OACEC,EAAAC,EAAA,CAAAC,SAAA,CACEF,EAAK,MAAA,CAAAG,UAAU,8EAA6ED,SAAA,CAC1FF,EACM,MAAAI,EAAA,CAAA,EAAAN,EACJ,CAAAK,UAAW,6HAAAE,OACTN,EAAa,cAAgB,IAG/BG,SAAA,CAAAI,EAAA,MAAA,CAAAJ,SACEI,EAACC,EAAS,CAAAC,KAAM,OAElBF,EAAI,IAAA,CAAAJ,SAAAH,EAAa,eAAiB,gBAEpCO,EAAW,QAAAF,EAAA,CAAA,EAAAP,OAGZX,EAAMuB,OAAS,GACdH,EAAI,KAAA,CAAAH,UAAU,0BACXjB,EAAMwB,KAAI,SAACC,GAAS,OACnBL,EAEE,KAAA,CAAAH,UAAU,0DAETQ,EAAKC,MAHDD,EAAKC,KAKb,MAIJvB,EAAcoB,OAAS,GACtBT,SAAKG,UAAU,oBAAmBD,SAAA,CAChCI,kDACAA,EAAA,KAAA,CAAIH,UAAU,YAAWD,SACtBb,EAAcqB,KAAI,SAACC,GAAS,OAC3BL,EAEE,KAAA,CAAAH,UAAU,kDAAiDD,SAE1DS,EAAKC,MAHDD,EAAKC,KAFe,WAazC"}
1
+ {"version":3,"file":"component.js","sources":["../../../../src/file-uploader/component.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport { useFileUploader } from \"./hook\";\nimport { LuUpload } from \"react-icons/lu\";\n\nexport interface FileUploaderProps {\n /**\n * Custom class name for the container\n */\n className?: string;\n /**\n * Custom class name for the drop area\n */\n dropAreaClassName?: string;\n /**\n * Text displayed when dragging files over the drop area\n */\n dragActiveText?: string;\n /**\n * Default text for the uploader\n */\n defaultText?: string;\n /**\n * Custom icon component to display instead of the default upload icon\n */\n icon?: React.ReactNode;\n /**\n * Whether to accept multiple files (default: true)\n */\n multiple?: boolean;\n /**\n * List of accepted file types (MIME types or extensions)\n * If not provided, defaults to a predefined list of common formats\n */\n acceptedFileTypes?: string[];\n /**\n * List of allowed file extensions (e.g. ['.jpg', '.pdf'])\n * If not provided, defaults to a predefined list\n */\n allowedExtensions?: string[];\n /**\n * Maximum allowed file size in bytes\n */\n maxFileSize?: number;\n /**\n * External controlled array of files\n */\n files?: File[];\n /**\n * External controlled array of rejected files\n */\n rejectedFiles?: File[];\n /**\n * Callback when files are added (and pass validation)\n */\n onFilesAdded?: (files: File[]) => void;\n /**\n * Callback when files are rejected\n */\n onFilesRejected?: (rejectedFiles: File[]) => void;\n /**\n * Whether to use internal state for files management (default: true if files prop not provided)\n */\n useInternalState?: boolean;\n /**\n * Whether to show the file list below the uploader (default: true)\n */\n showFileList?: boolean;\n /**\n * Whether to show rejected files list (default: true)\n */\n showRejectedFiles?: boolean;\n /**\n * Custom text for rejected files section\n */\n rejectedFilesText?: string;\n /**\n * Custom function to render each file item\n */\n renderFileItem?: (file: File) => React.ReactNode;\n /**\n * Custom function to render each rejected file item\n */\n renderRejectedFileItem?: (file: File) => React.ReactNode;\n /**\n * Height of the drop area (default: \"h-40\")\n */\n dropAreaHeight?: string;\n}\n\nexport function FileUploader({\n className = \"\",\n dropAreaClassName = \"\",\n dragActiveText = \"ここにファイルをドロップ\", // \"Drop files here\"\n defaultText = \"ファイルの選択\", // \"Select files\"\n icon = <LuUpload size={48} />,\n multiple = true,\n acceptedFileTypes,\n allowedExtensions,\n maxFileSize,\n files: externalFiles,\n rejectedFiles: externalRejectedFiles,\n onFilesAdded,\n onFilesRejected,\n useInternalState = externalFiles === undefined,\n showFileList = true,\n showRejectedFiles = true,\n rejectedFilesText = \"These files are not accepted:\",\n renderFileItem,\n renderRejectedFileItem,\n dropAreaHeight = \"h-40\",\n}: FileUploaderProps) {\n // Internal state for files if not controlled externally\n const [internalFiles, setInternalFiles] = useState<File[]>([]);\n const [internalRejectedFiles, setInternalRejectedFiles] = useState<File[]>(\n []\n );\n\n // Use either external or internal state based on props\n const files = useInternalState ? internalFiles : externalFiles || [];\n const rejectedFiles = useInternalState\n ? internalRejectedFiles\n : externalRejectedFiles || [];\n\n const { inputProps, dropSpaceProps, isDragging } = useFileUploader({\n addFiles: (newFiles) => {\n if (useInternalState) {\n setInternalFiles((f) => [...f, ...newFiles]);\n }\n onFilesAdded?.(newFiles);\n },\n onValidationError: (rejectedFiles) => {\n if (useInternalState) {\n setInternalRejectedFiles(rejectedFiles);\n }\n onFilesRejected?.(rejectedFiles);\n },\n acceptedFileTypes,\n allowedExtensions,\n maxFileSize,\n });\n\n return (\n <>\n <div\n className={`w-full mx-auto border-2 border-dashed border-gray-300 rounded-lg bg-gray-50 ${className}`}\n >\n <div\n {...dropSpaceProps}\n className={`cursor-pointer w-full ${dropAreaHeight} flex flex-col gap-5 items-center justify-center rounded-lg transition-colors hover:bg-blue-100 ${\n isDragging ? \"bg-blue-100\" : \"\"\n } ${dropAreaClassName}`}\n >\n <div>{icon}</div>\n <p>{isDragging ? dragActiveText : defaultText}</p>\n </div>\n <input {...inputProps} multiple={multiple} />\n </div>\n\n {showFileList && files.length > 0 && (\n <ul className=\"space-y-2 mt-4\">\n {files.map((file) => (\n <li\n key={`${file.name}-${file.lastModified}`}\n className=\"bg-white border border-gray-300 p-2 rounded-lg\"\n >\n {renderFileItem ? renderFileItem(file) : file.name}\n </li>\n ))}\n </ul>\n )}\n\n {showRejectedFiles && rejectedFiles.length > 0 && (\n <div className=\"mt-4 text-red-500\">\n <p>{rejectedFilesText}</p>\n <ul className=\"space-y-2\">\n {rejectedFiles.map((file) => (\n <li\n key={`${file.name}-${file.lastModified}`}\n className=\"bg-red-100 border border-red-300 p-2 rounded-lg\"\n >\n {renderRejectedFileItem\n ? renderRejectedFileItem(file)\n : file.name}\n </li>\n ))}\n </ul>\n </div>\n )}\n </>\n );\n}\n"],"names":["FileUploader","_a","_b","className","_c","dropAreaClassName","_d","dragActiveText","_e","defaultText","_f","icon","_jsx","LuUpload","size","_g","multiple","acceptedFileTypes","allowedExtensions","maxFileSize","externalFiles","files","externalRejectedFiles","onFilesAdded","onFilesRejected","_h","useInternalState","undefined","_j","showFileList","_k","showRejectedFiles","_l","rejectedFilesText","renderFileItem","renderRejectedFileItem","_m","dropAreaHeight","_o","useState","internalFiles","setInternalFiles","_p","internalRejectedFiles","setInternalRejectedFiles","rejectedFiles","_q","useFileUploader","addFiles","newFiles","f","__spreadArray","onValidationError","inputProps","dropSpaceProps","isDragging","_jsxs","_Fragment","children","concat","__assign","length","map","file","name","lastModified"],"mappings":"uSAyFM,SAAUA,EAAaC,OAC3BC,EAAcD,EAAAE,UAAdA,OAAY,IAAAD,EAAA,KACZE,EAAAH,EAAAI,kBAAAA,OAAiB,IAAAD,EAAG,GAAEA,EACtBE,mBAAAC,aAAiB,eAAcD,EAC/BE,EAAAP,EAAAQ,YAAAA,OAAc,IAAAD,EAAA,UAASA,EACvBE,EAAAT,EAAAU,KAAAA,aAAOC,EAACC,EAAS,CAAAC,KAAM,KAAMJ,EAC7BK,aAAAC,OAAW,IAAAD,KACXE,EAAiBhB,EAAAgB,kBACjBC,EAAiBjB,EAAAiB,kBACjBC,EAAWlB,EAAAkB,YACJC,EAAanB,EAAAoB,MACLC,kBACfC,iBACAC,oBACAC,EAAAxB,EAAAyB,iBAAAA,kBAAqCC,IAAlBP,EAA2BK,EAC9CG,EAAmB3B,EAAA4B,aAAnBA,OAAY,IAAAD,GAAOA,EACnBE,sBAAAC,cAAwBD,EACxBE,EAAA/B,EAAAgC,kBAAAA,OAAiB,IAAAD,EAAG,gCAA+BA,EACnDE,EAAcjC,EAAAiC,eACdC,2BACAC,EAAAnC,EAAAoC,eAAAA,OAAc,IAAAD,EAAG,OAAMA,EAGjBE,EAAoCC,EAAiB,IAApDC,EAAaF,EAAA,GAAEG,EAAgBH,EAAA,GAChCI,EAAoDH,EACxD,IADKI,EAAqBD,EAAA,GAAEE,EAAwBF,EAAA,GAKhDrB,EAAQK,EAAmBc,EAAgBpB,GAAiB,GAC5DyB,EAAgBnB,EAClBiB,EACArB,GAAyB,GAEvBwB,EAA6CC,EAAgB,CACjEC,SAAU,SAACC,GACLvB,GACFe,GAAiB,SAACS,GAAM,OAAAC,EAAAA,EAAA,GAAID,GAAC,GAAKD,GAAQ,EAAC,IAE7C1B,SAAAA,EAAe0B,EAChB,EACDG,kBAAmB,SAACP,GACdnB,GACFkB,EAAyBC,GAE3BrB,SAAAA,EAAkBqB,EACnB,EACD5B,kBAAiBA,EACjBC,kBAAiBA,EACjBC,YAAWA,IAfLkC,EAAUP,EAAAO,WAAEC,EAAcR,EAAAQ,eAAEC,EAAUT,EAAAS,WAkB9C,OACEC,EAAAC,EAAA,CAAAC,SAAA,CACEF,EACE,MAAA,CAAArD,UAAW,+EAA+EwD,OAAAxD,GAAWuD,SAAA,CAErGF,aACMF,EAAc,CAClBnD,UAAW,gCAAyBkC,EAAc,oGAAAsB,OAChDJ,EAAa,cAAgB,GAAE,KAAAI,OAC7BtD,aAEJO,EAAM,MAAA,CAAA8C,SAAA/C,IACNC,gBAAI2C,EAAahD,EAAiBE,QAEpCG,EAAA,QAAAgD,EAAA,CAAA,EAAWP,EAAY,CAAArC,SAAUA,QAGlCa,GAAgBR,EAAMwC,OAAS,GAC9BjD,EAAA,KAAA,CAAIT,UAAU,iBACXuD,SAAArC,EAAMyC,KAAI,SAACC,GAAS,OACnBnD,EAAA,KAAA,CAEET,UAAU,iDAETuD,SAAAxB,EAAiBA,EAAe6B,GAAQA,EAAKC,MAHzC,GAAAL,OAAGI,EAAKC,KAAQ,KAAAL,OAAAI,EAAKE,cAK7B,MAIJlC,GAAqBc,EAAcgB,OAAS,GAC3CL,EAAK,MAAA,CAAArD,UAAU,oBAAmBuD,SAAA,CAChC9C,EAAI,IAAA,CAAA8C,SAAAzB,IACJrB,EAAA,KAAA,CAAIT,UAAU,YACXuD,SAAAb,EAAciB,KAAI,SAACC,GAAS,OAC3BnD,EAEE,KAAA,CAAAT,UAAU,2DAETgC,EACGA,EAAuB4B,GACvBA,EAAKC,MALJ,UAAGD,EAAKC,KAAI,KAAAL,OAAII,EAAKE,yBAa1C"}
@@ -1,2 +1,2 @@
1
- import{useRef as i,useState as n}from"react";var a=["image/*","text/*","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.ms-outlook","application/json","application/xml","application/pdf","application/x-compressed","application/x-zip-compressed","application/x-gzip","application/x-bzip2","application/x-tar","application/x-rar-compressed","application/x-7z-compressed","application/zip"],e=[".msg"];function o(o){var t=i(null),r=n(!1),p=r[0],c=r[1],l=function(i){var n=function(i){var n=[],o=[];return i.forEach((function(i){var t=i.name.split(".").pop();t&&e.includes(".".concat(t))||a.some((function(n){return i.type.match(n)}))?n.push(i):o.push(i)})),{validFiles:n,rejectedFiles:o}}(i),t=n.validFiles,r=n.rejectedFiles;t.length>0&&o.addFiles(t),r.length>0&&o.onValidationError&&o.onValidationError(r)};return{inputProps:{ref:t,type:"file",multiple:!0,className:"hidden",accept:a.join(","),onChange:function(i){if(i.target.files){var n=Array.from(i.target.files);l(n)}}},isDragging:p,dropSpaceProps:{onClick:function(){var i;return null===(i=t.current)||void 0===i?void 0:i.click()},onDrop:function(i){if(i.preventDefault(),c(!1),i.dataTransfer.files){var n=Array.from(i.dataTransfer.files);l(n)}},onDragOver:function(i){i.preventDefault(),c(!0)},onDragLeave:function(i){c(!1)}}}}export{o as useFileUploader};
1
+ import{useRef as e,useState as i}from"react";var a=["image/*","text/*","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/vnd.openxmlformats-officedocument.presentationml.presentation","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.ms-outlook","application/json","application/xml","application/pdf","application/x-compressed","application/x-zip-compressed","application/x-gzip","application/x-bzip2","application/x-tar","application/x-rar-compressed","application/x-7z-compressed","application/zip"],n=[".msg",".jpg",".jpeg",".png",".pdf",".xlsx",".docx",".txt",".zip"];function o(o){var t=e(null),r=i(!1),p=r[0],c=r[1],l=o.acceptedFileTypes||a,s=o.allowedExtensions||n,f=function(e){var i=function(e){var i=[],a=[];return e.forEach((function(e){if(o.maxFileSize&&e.size>o.maxFileSize)a.push(e);else{var n=e.name.split(".").pop();n&&s.some((function(e){return e.toLowerCase()===".".concat(n.toLowerCase())||e.toLowerCase()===n.toLowerCase()}))||l.some((function(i){if(i.endsWith("/*")){var a=i.split("/")[0];return e.type.startsWith("".concat(a,"/"))}return e.type===i}))?i.push(e):a.push(e)}})),{validFiles:i,rejectedFiles:a}}(e),a=i.validFiles,n=i.rejectedFiles;a.length>0&&o.addFiles(a),n.length>0&&o.onValidationError&&o.onValidationError(n)};return{inputProps:{ref:t,type:"file",className:"hidden",accept:l.join(","),onChange:function(e){if(e.target.files){var i=Array.from(e.target.files);f(i)}}},isDragging:p,dropSpaceProps:{onClick:function(){var e;return null===(e=t.current)||void 0===e?void 0:e.click()},onDrop:function(e){if(e.preventDefault(),c(!1),e.dataTransfer.files){var i=Array.from(e.dataTransfer.files);f(i)}},onDragOver:function(e){e.preventDefault(),c(!0)},onDragLeave:function(e){c(!1)}}}}export{o as useFileUploader};
2
2
  //# sourceMappingURL=hook.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hook.js","sources":["../../../../src/file-uploader/hook.ts"],"sourcesContent":["import { useRef, useState } from \"react\";\n\ninterface IPropsFileUploader {\n addFiles: (files: File[]) => void;\n onValidationError?: (rejectedFiles: File[]) => void;\n}\n\ninterface IReturnFileUploader {\n inputProps: {\n ref: React.RefObject<HTMLInputElement>;\n type: \"file\";\n multiple?: boolean;\n accept?: string;\n className?: string;\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n };\n isDragging: boolean;\n dropSpaceProps: {\n onClick?: React.MouseEventHandler;\n onDrop: (e: React.DragEvent) => void;\n onDragOver: (e: React.DragEvent) => void;\n onDragLeave: (e: React.DragEvent) => void;\n };\n}\n\nconst ACCEPTED_TYPES = [\n \"image/*\", // image\n \"text/*\", // .txt\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\", // .xlsx\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\", // .pptx\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", // .docx\n \"application/vnd.ms-excel\", // .xls\n \"application/vnd.ms-outlook\", // .msg\n \"application/json\", // .json\n \"application/xml\", // .xml\n \"application/pdf\", // .pdf\n \"application/x-compressed\", // .tgz\n \"application/x-zip-compressed\", // .zip\n \"application/x-gzip\", // .gz\n \"application/x-bzip2\", // .bz2\n \"application/x-tar\", // .tar\n \"application/x-rar-compressed\", // .rar\n \"application/x-7z-compressed\", // .7z\n \"application/zip\", // .zip\n];\n\nconst ALLOWED_EXTENSIONS = [\".msg\"];\n\nexport function useFileUploader(\n props: IPropsFileUploader\n): IReturnFileUploader {\n const inputRef = useRef<HTMLInputElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n const validateFiles = (\n files: File[]\n ): { validFiles: File[]; rejectedFiles: File[] } => {\n const validFiles: File[] = [];\n const rejectedFiles: File[] = [];\n\n files.forEach((file) => {\n const extension = file.name.split(\".\").pop();\n if (extension && ALLOWED_EXTENSIONS.includes(`.${extension}`)) {\n validFiles.push(file);\n return;\n }\n if (ACCEPTED_TYPES.some((type) => file.type.match(type))) {\n validFiles.push(file);\n } else {\n rejectedFiles.push(file);\n }\n });\n\n return { validFiles, rejectedFiles };\n };\n\n const addFiles = (files: File[]) => {\n const { validFiles, rejectedFiles } = validateFiles(files);\n if (validFiles.length > 0) {\n props.addFiles(validFiles);\n }\n if (rejectedFiles.length > 0 && props.onValidationError) {\n props.onValidationError(rejectedFiles);\n }\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n if (e.dataTransfer.files) {\n const droppedFiles = Array.from(e.dataTransfer.files);\n addFiles(droppedFiles);\n }\n };\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(true);\n };\n\n const handleDragLeave = (e: React.DragEvent) => {\n setIsDragging(false);\n };\n\n return {\n inputProps: {\n ref: inputRef,\n type: \"file\",\n multiple: true,\n className: \"hidden\",\n accept: ACCEPTED_TYPES.join(\",\"),\n onChange: (e) => {\n if (e.target.files) {\n const selectedFiles = Array.from(e.target.files);\n addFiles(selectedFiles);\n }\n },\n },\n isDragging,\n dropSpaceProps: {\n onClick: () => inputRef.current?.click(),\n onDrop: handleDrop,\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n },\n };\n}\n"],"names":["ACCEPTED_TYPES","ALLOWED_EXTENSIONS","useFileUploader","props","inputRef","useRef","_a","useState","isDragging","setIsDragging","addFiles","files","validFiles","rejectedFiles","forEach","file","extension","name","split","pop","includes","concat","some","type","match","push","validateFiles","length","onValidationError","inputProps","ref","multiple","className","accept","join","onChange","e","target","selectedFiles","Array","from","dropSpaceProps","onClick","current","click","onDrop","preventDefault","dataTransfer","droppedFiles","onDragOver","onDragLeave"],"mappings":"6CAyBA,IAAMA,EAAiB,CACrB,UACA,SACA,oEACA,4EACA,0EACA,2BACA,6BACA,mBACA,kBACA,kBACA,2BACA,+BACA,qBACA,sBACA,oBACA,+BACA,8BACA,mBAGIC,EAAqB,CAAC,QAEtB,SAAUC,EACdC,GAEA,IAAMC,EAAWC,EAAyB,MACpCC,EAA8BC,GAAS,GAAtCC,EAAUF,EAAA,GAAEG,EAAaH,EAAA,GAwB1BI,EAAW,SAACC,GACV,IAAAL,EAvBc,SACpBK,GAEA,IAAMC,EAAqB,GACrBC,EAAwB,GAe9B,OAbAF,EAAMG,SAAQ,SAACC,GACb,IAAMC,EAAYD,EAAKE,KAAKC,MAAM,KAAKC,MACnCH,GAAaf,EAAmBmB,SAAS,IAAAC,OAAIL,KAI7ChB,EAAesB,MAAK,SAACC,GAAS,OAAAR,EAAKQ,KAAKC,MAAMD,EAAK,IAHrDX,EAAWa,KAAKV,GAMhBF,EAAcY,KAAKV,EAEvB,IAEO,CAAEH,WAAUA,EAAEC,cAAaA,EACpC,CAGwCa,CAAcf,GAA5CC,EAAUN,EAAAM,WAAEC,EAAaP,EAAAO,cAC7BD,EAAWe,OAAS,GACtBxB,EAAMO,SAASE,GAEbC,EAAcc,OAAS,GAAKxB,EAAMyB,mBACpCzB,EAAMyB,kBAAkBf,EAE5B,EAoBA,MAAO,CACLgB,WAAY,CACVC,IAAK1B,EACLmB,KAAM,OACNQ,UAAU,EACVC,UAAW,SACXC,OAAQjC,EAAekC,KAAK,KAC5BC,SAAU,SAACC,GACT,GAAIA,EAAEC,OAAO1B,MAAO,CAClB,IAAM2B,EAAgBC,MAAMC,KAAKJ,EAAEC,OAAO1B,OAC1CD,EAAS4B,EACV,CACF,GAEH9B,WAAUA,EACViC,eAAgB,CACdC,QAAS,WAAM,IAAApC,EAAA,OAAkB,QAAlBA,EAAAF,EAASuC,eAAS,IAAArC,OAAA,EAAAA,EAAAsC,OAAO,EACxCC,OAnCe,SAACT,GAGlB,GAFAA,EAAEU,iBACFrC,GAAc,GACV2B,EAAEW,aAAapC,MAAO,CACxB,IAAMqC,EAAeT,MAAMC,KAAKJ,EAAEW,aAAapC,OAC/CD,EAASsC,EACV,CACH,EA6BIC,WA3BmB,SAACb,GACtBA,EAAEU,iBACFrC,GAAc,EAChB,EAyBIyC,YAvBoB,SAACd,GACvB3B,GAAc,EAChB,GAwBF"}
1
+ {"version":3,"file":"hook.js","sources":["../../../../src/file-uploader/hook.ts"],"sourcesContent":["import { useRef, useState } from \"react\";\n\ninterface IPropsFileUploader {\n addFiles: (files: File[]) => void;\n onValidationError?: (rejectedFiles: File[]) => void;\n acceptedFileTypes?: string[];\n allowedExtensions?: string[];\n maxFileSize?: number;\n}\n\ninterface IReturnFileUploader {\n inputProps: {\n ref: React.RefObject<HTMLInputElement>;\n type: \"file\";\n accept?: string;\n className?: string;\n onChange: React.ChangeEventHandler<HTMLInputElement>;\n };\n isDragging: boolean;\n dropSpaceProps: {\n onClick?: React.MouseEventHandler;\n onDrop: (e: React.DragEvent) => void;\n onDragOver: (e: React.DragEvent) => void;\n onDragLeave: (e: React.DragEvent) => void;\n };\n}\n\n// Default accepted file types\nconst DEFAULT_ACCEPTED_TYPES = [\n \"image/*\", // image\n \"text/*\", // .txt\n \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\", // .xlsx\n \"application/vnd.openxmlformats-officedocument.presentationml.presentation\", // .pptx\n \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\", // .docx\n \"application/vnd.ms-excel\", // .xls\n \"application/vnd.ms-outlook\", // .msg\n \"application/json\", // .json\n \"application/xml\", // .xml\n \"application/pdf\", // .pdf\n \"application/x-compressed\", // .tgz\n \"application/x-zip-compressed\", // .zip\n \"application/x-gzip\", // .gz\n \"application/x-bzip2\", // .bz2\n \"application/x-tar\", // .tar\n \"application/x-rar-compressed\", // .rar\n \"application/x-7z-compressed\", // .7z\n \"application/zip\", // .zip\n];\n\n// Default allowed extensions\nconst DEFAULT_ALLOWED_EXTENSIONS = [\n \".msg\",\n \".jpg\",\n \".jpeg\",\n \".png\",\n \".pdf\",\n \".xlsx\",\n \".docx\",\n \".txt\",\n \".zip\",\n];\n\nexport function useFileUploader(\n props: IPropsFileUploader\n): IReturnFileUploader {\n const inputRef = useRef<HTMLInputElement>(null);\n const [isDragging, setIsDragging] = useState(false);\n\n const acceptedTypes = props.acceptedFileTypes || DEFAULT_ACCEPTED_TYPES;\n const allowedExtensions =\n props.allowedExtensions || DEFAULT_ALLOWED_EXTENSIONS;\n\n const validateFiles = (\n files: File[]\n ): { validFiles: File[]; rejectedFiles: File[] } => {\n const validFiles: File[] = [];\n const rejectedFiles: File[] = [];\n\n files.forEach((file) => {\n // Check file size if maxFileSize is specified\n if (props.maxFileSize && file.size > props.maxFileSize) {\n rejectedFiles.push(file);\n return;\n }\n\n const extension = file.name.split(\".\").pop();\n if (\n extension &&\n allowedExtensions.some(\n (ext) =>\n ext.toLowerCase() === `.${extension.toLowerCase()}` ||\n ext.toLowerCase() === extension.toLowerCase()\n )\n ) {\n validFiles.push(file);\n return;\n }\n\n if (\n acceptedTypes.some((type) => {\n if (type.endsWith(\"/*\")) {\n const mainType = type.split(\"/\")[0];\n return file.type.startsWith(`${mainType}/`);\n }\n return file.type === type;\n })\n ) {\n validFiles.push(file);\n } else {\n rejectedFiles.push(file);\n }\n });\n\n return { validFiles, rejectedFiles };\n };\n\n const addFiles = (files: File[]) => {\n const { validFiles, rejectedFiles } = validateFiles(files);\n if (validFiles.length > 0) {\n props.addFiles(validFiles);\n }\n if (rejectedFiles.length > 0 && props.onValidationError) {\n props.onValidationError(rejectedFiles);\n }\n };\n\n const handleDrop = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(false);\n if (e.dataTransfer.files) {\n const droppedFiles = Array.from(e.dataTransfer.files);\n addFiles(droppedFiles);\n }\n };\n\n const handleDragOver = (e: React.DragEvent) => {\n e.preventDefault();\n setIsDragging(true);\n };\n\n const handleDragLeave = (e: React.DragEvent) => {\n setIsDragging(false);\n };\n\n return {\n inputProps: {\n ref: inputRef,\n type: \"file\",\n className: \"hidden\",\n accept: acceptedTypes.join(\",\"),\n onChange: (e) => {\n if (e.target.files) {\n const selectedFiles = Array.from(e.target.files);\n addFiles(selectedFiles);\n }\n },\n },\n isDragging,\n dropSpaceProps: {\n onClick: () => inputRef.current?.click(),\n onDrop: handleDrop,\n onDragOver: handleDragOver,\n onDragLeave: handleDragLeave,\n },\n };\n}\n"],"names":["DEFAULT_ACCEPTED_TYPES","DEFAULT_ALLOWED_EXTENSIONS","useFileUploader","props","inputRef","useRef","_a","useState","isDragging","setIsDragging","acceptedTypes","acceptedFileTypes","allowedExtensions","addFiles","files","validFiles","rejectedFiles","forEach","file","maxFileSize","size","push","extension","name","split","pop","some","ext","toLowerCase","type","endsWith","mainType","startsWith","concat","validateFiles","length","onValidationError","inputProps","ref","className","accept","join","onChange","e","target","selectedFiles","Array","from","dropSpaceProps","onClick","current","click","onDrop","preventDefault","dataTransfer","droppedFiles","onDragOver","onDragLeave"],"mappings":"6CA4BA,IAAMA,EAAyB,CAC7B,UACA,SACA,oEACA,4EACA,0EACA,2BACA,6BACA,mBACA,kBACA,kBACA,2BACA,+BACA,qBACA,sBACA,oBACA,+BACA,8BACA,mBAIIC,EAA6B,CACjC,OACA,OACA,QACA,OACA,OACA,QACA,QACA,OACA,QAGI,SAAUC,EACdC,GAEA,IAAMC,EAAWC,EAAyB,MACpCC,EAA8BC,GAAS,GAAtCC,EAAUF,EAAA,GAAEG,EAAaH,EAAA,GAE1BI,EAAgBP,EAAMQ,mBAAqBX,EAC3CY,EACJT,EAAMS,mBAAqBX,EA8CvBY,EAAW,SAACC,GACV,IAAAR,EA7Cc,SACpBQ,GAEA,IAAMC,EAAqB,GACrBC,EAAwB,GAqC9B,OAnCAF,EAAMG,SAAQ,SAACC,GAEb,GAAIf,EAAMgB,aAAeD,EAAKE,KAAOjB,EAAMgB,YACzCH,EAAcK,KAAKH,OADrB,CAKA,IAAMI,EAAYJ,EAAKK,KAAKC,MAAM,KAAKC,MAErCH,GACAV,EAAkBc,MAChB,SAACC,GACC,OAAAA,EAAIC,gBAAkB,WAAIN,EAAUM,gBACpCD,EAAIC,gBAAkBN,EAAUM,kBAQpClB,EAAcgB,MAAK,SAACG,GAClB,GAAIA,EAAKC,SAAS,MAAO,CACvB,IAAMC,EAAWF,EAAKL,MAAM,KAAK,GACjC,OAAON,EAAKW,KAAKG,WAAW,GAAGC,OAAAF,EAAW,KAC3C,CACD,OAAOb,EAAKW,OAASA,KAVvBd,EAAWM,KAAKH,GAehBF,EAAcK,KAAKH,EA1BpB,CA4BH,IAEO,CAAEH,WAAUA,EAAEC,cAAaA,EACpC,CAGwCkB,CAAcpB,GAA5CC,EAAUT,EAAAS,WAAEC,EAAaV,EAAAU,cAC7BD,EAAWoB,OAAS,GACtBhC,EAAMU,SAASE,GAEbC,EAAcmB,OAAS,GAAKhC,EAAMiC,mBACpCjC,EAAMiC,kBAAkBpB,EAE5B,EAoBA,MAAO,CACLqB,WAAY,CACVC,IAAKlC,EACLyB,KAAM,OACNU,UAAW,SACXC,OAAQ9B,EAAc+B,KAAK,KAC3BC,SAAU,SAACC,GACT,GAAIA,EAAEC,OAAO9B,MAAO,CAClB,IAAM+B,EAAgBC,MAAMC,KAAKJ,EAAEC,OAAO9B,OAC1CD,EAASgC,EACV,CACF,GAEHrC,WAAUA,EACVwC,eAAgB,CACdC,QAAS,WAAM,IAAA3C,EAAA,OAAkB,QAAlBA,EAAAF,EAAS8C,eAAS,IAAA5C,OAAA,EAAAA,EAAA6C,OAAO,EACxCC,OAlCe,SAACT,GAGlB,GAFAA,EAAEU,iBACF5C,GAAc,GACVkC,EAAEW,aAAaxC,MAAO,CACxB,IAAMyC,EAAeT,MAAMC,KAAKJ,EAAEW,aAAaxC,OAC/CD,EAAS0C,EACV,CACH,EA4BIC,WA1BmB,SAACb,GACtBA,EAAEU,iBACF5C,GAAc,EAChB,EAwBIgD,YAtBoB,SAACd,GACvBlC,GAAc,EAChB,GAuBF"}
package/dist/index.d.ts CHANGED
@@ -164,18 +164,104 @@ type TPropsTable<T extends DataRecord> = {
164
164
  declare function Table<T extends DataRecord>(props: TPropsTable<T>): react_jsx_runtime.JSX.Element;
165
165
 
166
166
  interface FileUploaderProps {
167
+ /**
168
+ * Custom class name for the container
169
+ */
170
+ className?: string;
171
+ /**
172
+ * Custom class name for the drop area
173
+ */
174
+ dropAreaClassName?: string;
175
+ /**
176
+ * Text displayed when dragging files over the drop area
177
+ */
178
+ dragActiveText?: string;
179
+ /**
180
+ * Default text for the uploader
181
+ */
182
+ defaultText?: string;
183
+ /**
184
+ * Custom icon component to display instead of the default upload icon
185
+ */
186
+ icon?: React.ReactNode;
187
+ /**
188
+ * Whether to accept multiple files (default: true)
189
+ */
190
+ multiple?: boolean;
191
+ /**
192
+ * List of accepted file types (MIME types or extensions)
193
+ * If not provided, defaults to a predefined list of common formats
194
+ */
195
+ acceptedFileTypes?: string[];
196
+ /**
197
+ * List of allowed file extensions (e.g. ['.jpg', '.pdf'])
198
+ * If not provided, defaults to a predefined list
199
+ */
200
+ allowedExtensions?: string[];
201
+ /**
202
+ * Maximum allowed file size in bytes
203
+ */
204
+ maxFileSize?: number;
205
+ /**
206
+ * External controlled array of files
207
+ */
208
+ files?: File[];
209
+ /**
210
+ * External controlled array of rejected files
211
+ */
212
+ rejectedFiles?: File[];
213
+ /**
214
+ * Callback when files are added (and pass validation)
215
+ */
216
+ onFilesAdded?: (files: File[]) => void;
217
+ /**
218
+ * Callback when files are rejected
219
+ */
220
+ onFilesRejected?: (rejectedFiles: File[]) => void;
221
+ /**
222
+ * Whether to use internal state for files management (default: true if files prop not provided)
223
+ */
224
+ useInternalState?: boolean;
225
+ /**
226
+ * Whether to show the file list below the uploader (default: true)
227
+ */
228
+ showFileList?: boolean;
229
+ /**
230
+ * Whether to show rejected files list (default: true)
231
+ */
232
+ showRejectedFiles?: boolean;
233
+ /**
234
+ * Custom text for rejected files section
235
+ */
236
+ rejectedFilesText?: string;
237
+ /**
238
+ * Custom function to render each file item
239
+ */
240
+ renderFileItem?: (file: File) => React.ReactNode;
241
+ /**
242
+ * Custom function to render each rejected file item
243
+ */
244
+ renderRejectedFileItem?: (file: File) => React.ReactNode;
245
+ /**
246
+ * Height of the drop area (default: "h-40")
247
+ */
248
+ dropAreaHeight?: string;
167
249
  }
168
- declare function FileUploader(props: FileUploaderProps): react_jsx_runtime.JSX.Element;
250
+ declare function FileUploader({ className, dropAreaClassName, dragActiveText, // "Drop files here"
251
+ defaultText, // "Select files"
252
+ icon, multiple, acceptedFileTypes, allowedExtensions, maxFileSize, files: externalFiles, rejectedFiles: externalRejectedFiles, onFilesAdded, onFilesRejected, useInternalState, showFileList, showRejectedFiles, rejectedFilesText, renderFileItem, renderRejectedFileItem, dropAreaHeight, }: FileUploaderProps): react_jsx_runtime.JSX.Element;
169
253
 
170
254
  interface IPropsFileUploader {
171
255
  addFiles: (files: File[]) => void;
172
256
  onValidationError?: (rejectedFiles: File[]) => void;
257
+ acceptedFileTypes?: string[];
258
+ allowedExtensions?: string[];
259
+ maxFileSize?: number;
173
260
  }
174
261
  interface IReturnFileUploader {
175
262
  inputProps: {
176
263
  ref: React.RefObject<HTMLInputElement>;
177
264
  type: "file";
178
- multiple?: boolean;
179
265
  accept?: string;
180
266
  className?: string;
181
267
  onChange: React.ChangeEventHandler<HTMLInputElement>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@teppen/react-ui",
3
- "version": "1.8.10",
3
+ "version": "1.8.12",
4
4
  "description": "React UI Component",
5
5
  "main": "dist/cjs/src/index.js",
6
6
  "module": "dist/esm/src/index.js",