@pagamio/frontend-commons-lib
Version:
Pagamio library for Frontend reusable components like the form engine and table container
46 lines (45 loc) • 3.22 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { forwardRef, useState } from 'react';
import { Button, Icon } from '../../components';
const UploadField = forwardRef(({ onChange, id, type = 'file', hideUploadButton = false, className = '', disabled = false, allowedFileTypes, helperText, value, // Explicitly exclude value prop becuase it's not allowed for security reasons.
...props }, ref) => {
const [fileName, setFileName] = useState(null);
const [key, setKey] = useState(0);
const [error, setError] = useState(null);
const handleFileChange = (event) => {
setError(null);
const file = event.target.files?.[0];
if (file) {
if (allowedFileTypes && allowedFileTypes.length > 0) {
const fileExtension = file.name.split('.').pop()?.toLowerCase();
const isValidExtension = fileExtension && allowedFileTypes.includes(fileExtension);
if (!isValidExtension) {
setError(`Invalid file type. Allowed types: ${allowedFileTypes.join(', ')}`);
setFileName(null);
onChange(null);
setKey((prev) => prev + 1);
return;
}
}
setFileName(file.name);
onChange(file);
}
else {
setFileName(null);
onChange(null);
}
};
const handleClearFile = () => {
setFileName(null);
onChange(null);
setKey((prev) => prev + 1);
};
const acceptValue = allowedFileTypes?.map((ext) => `.${ext}`).join(',');
return (_jsxs("div", { className: `flex flex-col gap-3 w-full ${className}`, children: [_jsxs("div", { className: "flex gap-3 w-full items-center", children: [_jsxs("label", { htmlFor: id, className: "flex items-center gap-2 cursor-pointer flex-1", children: [_jsx("div", { className: "bg-primary-500 rounded-full h-10 w-10 flex items-center justify-center", children: _jsx(Icon, { name: "FiUpload", size: 20, className: "text-white" }) }), _jsx("span", { className: "text-sm font-medium text-gray-700", children: "Choose file" }), _jsx("input", { type: type, onChange: handleFileChange, className: "hidden", id: id, ref: ref, disabled: disabled, accept: acceptValue, ...props }, key)] }), !hideUploadButton && (_jsx(Button, { onClick: () => {
if (ref && typeof ref === 'object' && ref.current) {
ref.current.click();
}
}, disabled: disabled, children: "Upload" }))] }), fileName && (_jsxs("div", { className: "flex items-center gap-2", children: [_jsxs("span", { className: "text-sm text-gray-500", children: ["Selected: ", fileName] }), _jsx(Button, { variant: "destructive", size: "sm", onClick: handleClearFile, disabled: disabled, children: "Clear" })] })), helperText && (_jsx("div", { className: "w-full", children: _jsx("p", { className: "text-sm text-gray-500 w-full md:w-[65%]", children: helperText }) })), error && _jsx("div", { className: "text-red-500 text-sm", children: error })] }));
});
UploadField.displayName = 'UploadField';
export default UploadField;