@hitachivantara/uikit-react-core
Version:
UI Kit Core React components.
151 lines (150 loc) • 5.6 kB
JavaScript
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 };