@hitachivantara/uikit-react-core
Version:
Core React components for the NEXT Design System.
194 lines (193 loc) • 7.36 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const React = require("react");
const uikitReactUtils = require("@hitachivantara/uikit-react-utils");
const LabelContainer = require("../../FormElement/LabelContainer.cjs");
const useLabels = require("../../hooks/useLabels.cjs");
const useUniqueId = require("../../hooks/useUniqueId.cjs");
const icons = require("../../icons.cjs");
const helpers = require("../../utils/helpers.cjs");
const setId = require("../../utils/setId.cjs");
const utils = require("../utils.cjs");
const DropZone_styles = require("./DropZone.styles.cjs");
const context = require("../../FormElement/context.cjs");
const DEFAULT_LABELS = {
/** Extensions of the accepted file types */
acceptedFiles: "",
/** Dropzone area label. @deprecated use `label` prop instead */
dropzone: "Label",
/** 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;
});
}
const HvDropZone = (props) => {
const {
id: idProp,
classes: classesProp,
label,
labels: labelsProp,
accept,
maxFileSize,
inputProps,
hideLabels,
multiple = true,
onFilesAdded
} = uikitReactUtils.useDefaultProps("HvDropZone", props);
const id = useUniqueId.useUniqueId(idProp);
const labels = useLabels.useLabels(DEFAULT_LABELS, labelsProp);
const { classes, cx } = DropZone_styles.useClasses(classesProp);
const { disabled } = React.useContext(context.HvFormElementContext);
const [dragState, setDragState] = React.useState(false);
const inputRef = React.useRef(null);
const handleDragLeave = () => {
setDragState(false);
};
const handleDragEnter = (event) => {
if (disabled) return;
event.stopPropagation();
event.preventDefault();
setDragState(true);
};
const onChangeHandler = (filesList) => {
const filesToProcess = Object.values(filesList);
const newFiles = filesToProcess.map((file) => {
const newFile = new File([file], file.name, {
type: file.type,
lastModified: file.lastModified
});
newFile.id = helpers.uniqueId("uploaded-file-data-");
const isSizeAllowed = file.size <= maxFileSize;
const isFileAccepted = !accept || accept.includes(file.type?.split("/")[1]) || // TODO: remove in v6
validateAccept(file, accept);
if (!isFileAccepted) {
newFile.errorMessage = labels?.fileTypeError;
newFile.status = "fail";
} else if (!isSizeAllowed) {
newFile.errorMessage = labels?.fileSizeError;
newFile.status = "fail";
}
return newFile;
});
onFilesAdded?.(newFiles);
};
const description = /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
Number.isInteger(maxFileSize) && `${labels.sizeWarning} ${utils.convertUnits(maxFileSize)}`,
labels.acceptedFiles || accept && ` (${accept?.replaceAll(",", ", ")})`
] });
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
!hideLabels && /* @__PURE__ */ jsxRuntime.jsx(
LabelContainer.HvLabelContainer,
{
id,
label: label ?? labels.dropzone,
description,
inputId: setId.setId(id, "input-file"),
labelId: setId.setId(id, "input-file-label"),
descriptionId: setId.setId(id, "description"),
classes: {
root: classes.dropZoneLabelsGroup,
label: classes.dropZoneLabel
}
}
),
/* @__PURE__ */ jsxRuntime.jsxs(
"div",
{
id: setId.setId(id, "input-file-container"),
className: cx(classes.dropZoneContainer, {
[classes.dragAction]: dragState,
[classes.dropZoneContainerDisabled]: disabled
}),
children: [
/* @__PURE__ */ jsxRuntime.jsx(
"input",
{
id: setId.setId(id, "input-file"),
className: classes.inputArea,
type: "file",
multiple,
disabled,
title: !disabled ? `${labels?.drag} ${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__ */ jsxRuntime.jsx("div", { className: classes?.dropArea, children: dragState ? /* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.dropZoneAreaLabels, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.dragText, children: labels?.dropFiles }) }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(
icons.HvIcon,
{
name: "Doc",
size: "md",
className: classes.dropZoneAreaIcon
}
),
/* @__PURE__ */ jsxRuntime.jsx("div", { className: classes.dropZoneAreaLabels, children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: classes.dragText, children: [
labels?.drag,
/* @__PURE__ */ jsxRuntime.jsx(
"span",
{
className: classes.selectFilesText,
children: ` ${labels?.selectFiles}`
}
)
] }) })
] }) })
]
}
)
] });
};
exports.dropZoneClasses = DropZone_styles.staticClasses;
exports.HvDropZone = HvDropZone;