UNPKG

@hitachivantara/uikit-react-core

Version:
151 lines (150 loc) 5.6 kB
import { setId } from "../../utils/setId.js"; import { HvFormElementContext } from "../../FormElement/context.js"; import { useUniqueId } from "../../hooks/useUniqueId.js"; import { HvIcon } from "../../icons.js"; import { HvLabelContainer } from "../../FormElement/LabelContainer.js"; import { useLabels } from "../../hooks/useLabels.js"; import { uniqueId } from "../../utils/helpers.js"; import { convertUnits } from "../utils.js"; import { useClasses } from "./DropZone.styles.js"; import { useDefaultProps } from "@hitachivantara/uikit-react-utils"; import { useContext, useRef, useState } from "react"; import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime"; //#region src/FileUploader/DropZone/DropZone.tsx var DEFAULT_LABELS = { /** Extensions of the accepted file types */ acceptedFiles: "", /** Size file warning label. */ sizeWarning: "Max. file size:", /** Size file warning label. */ drag: "Drop files here or", /** Size file warning label. */ selectFiles: "click to upload", /** Theming sheet used to style components */ dropFiles: "Drop files here", /** Message to display when file size is greater than allowed */ fileSizeError: "The file exceeds the maximum upload size", /** Message to display when file type is greater than allowed */ fileTypeError: "File type not allowed for upload", removeFileButtonLabel: "Remove File" }; function validateAccept(file, acceptAttr) { if (!file || !acceptAttr) return true; const acceptEntries = acceptAttr.split(","); const fileName = file.name || ""; const mimeType = (file.type || "").toLowerCase(); const baseMimeType = mimeType.replace(/\/.*$/, ""); return acceptEntries.some((type) => { const validType = type.trim().toLowerCase(); if (validType.charAt(0) === ".") return fileName.toLowerCase().endsWith(validType); if (validType.endsWith("/*")) return baseMimeType === validType.replace(/\/.*$/, ""); return mimeType === validType; }); } var HvDropZone = (props) => { const { id: idProp, classes: classesProp, label = "Label", labels: labelsProp, accept, maxFileSize, inputProps, hideLabels, multiple = true, onFilesAdded } = useDefaultProps("HvDropZone", props); const id = useUniqueId(idProp); const labels = useLabels(DEFAULT_LABELS, labelsProp); const { classes, cx } = useClasses(classesProp); const { disabled } = useContext(HvFormElementContext); const [dragState, setDragState] = useState(false); const inputRef = useRef(null); const handleDragLeave = () => { setDragState(false); }; const handleDragEnter = (event) => { if (disabled) return; event.stopPropagation(); event.preventDefault(); setDragState(true); }; const onChangeHandler = (filesList) => { const newFiles = Object.values(filesList).map((file) => { const newFile = new File([file], file.name, { type: file.type, lastModified: file.lastModified }); newFile.id = uniqueId("uploaded-file-data-"); const isSizeAllowed = file.size <= maxFileSize; if (!(!accept || validateAccept(file, accept))) { newFile.errorMessage = labels?.fileTypeError; newFile.status = "fail"; } else if (!isSizeAllowed) { newFile.errorMessage = labels?.fileSizeError; newFile.status = "fail"; } return newFile; }); onFilesAdded?.(newFiles); }; const description = /* @__PURE__ */ jsxs(Fragment$1, { children: [Number.isInteger(maxFileSize) && `${labels.sizeWarning} ${convertUnits(maxFileSize)}`, labels.acceptedFiles || accept && `\u00A0(${accept?.replaceAll(",", ", ")})`] }); return /* @__PURE__ */ jsxs(Fragment$1, { children: [!hideLabels && /* @__PURE__ */ jsx(HvLabelContainer, { id, label, description, inputId: setId(id, "input-file"), classes: { root: classes.dropZoneLabelsGroup, label: classes.dropZoneLabel } }), /* @__PURE__ */ jsxs("div", { className: cx(classes.dropZoneContainer, { [classes.dragAction]: dragState, [classes.dropZoneContainerDisabled]: disabled }), children: [/* @__PURE__ */ jsx("input", { id: setId(id, "input-file"), className: classes.inputArea, type: "file", multiple, disabled, title: !disabled ? `${labels?.drag}\xa0${labels?.selectFiles}` : "", onClick: () => { if (inputRef.current) inputRef.current.value = ""; }, onChange: () => { if (!disabled && inputRef.current?.files) onChangeHandler(inputRef.current.files); }, onDragEnter: handleDragEnter, onDragOver: handleDragEnter, onDragLeave: handleDragLeave, onDropCapture: handleDragLeave, onDrop: (event) => { if (disabled) return; const { files } = event.dataTransfer; if (multiple === true || files.length === 1) { event.stopPropagation(); event.preventDefault(); onChangeHandler(files); } }, ref: inputRef, accept, ...inputProps }), /* @__PURE__ */ jsx("div", { className: classes?.dropArea, children: dragState ? /* @__PURE__ */ jsx("div", { className: classes.dropZoneAreaLabels, children: /* @__PURE__ */ jsx("div", { className: classes.dragText, children: labels?.dropFiles }) }) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(HvIcon, { name: "Doc", size: "md", className: classes.dropZoneAreaIcon }), /* @__PURE__ */ jsx("div", { className: classes.dropZoneAreaLabels, children: /* @__PURE__ */ jsxs("div", { className: classes.dragText, children: [labels?.drag, /* @__PURE__ */ jsx("span", { className: classes.selectFilesText, children: `\xa0${labels?.selectFiles}` })] }) })] }) })] })] }); }; //#endregion export { HvDropZone };