@gravity-ui/uikit
Version:
Gravity UI base styling and components
128 lines (127 loc) • 4.44 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import * as React from 'react';
import { useActionHandlers, useFileInput } from "../../../hooks/index.js";
import { useDropZone } from "../../../hooks/lab/useDropZone/index.js";
import { getSeparatedItems } from "./utils.js";
const FileDropZoneContext = React.createContext(null);
export const FileDropZoneProvider = ({ accept = [], onUpdate, onUpdateAccepted, onUpdateRejected, title, description, buttonText, icon, errorIcon, disabled, errorMessage, validationState, children, multiple, }) => {
const [isInvalidDrag, setIsInvalidDrag] = React.useState(false);
const handleUpdate = React.useCallback((acceptedItems, rejectedItems) => {
onUpdate?.(acceptedItems, rejectedItems);
if (acceptedItems.length > 0) {
onUpdateAccepted?.(acceptedItems);
}
if (rejectedItems.length > 0) {
onUpdateRejected?.(rejectedItems);
}
}, [onUpdate, onUpdateAccepted, onUpdateRejected]);
const getFilesFromItems = React.useCallback((items) => {
const files = [];
for (const item of items) {
const file = item.getAsFile();
if (!file) {
continue;
}
files.push(file);
}
return files;
}, []);
const getFileRejections = React.useCallback((items) => {
const fileRejections = [];
for (const rejectionObject of items) {
const { item, reasons } = rejectionObject;
const file = item.getAsFile();
if (!file) {
continue;
}
fileRejections.push({ file, reasons });
}
return fileRejections;
}, []);
const handleDragEnter = React.useCallback((event) => {
const dataTransfer = event.dataTransfer;
if (!dataTransfer?.items) {
return;
}
const { accepted } = getSeparatedItems(dataTransfer, {
accept,
multiple,
});
setIsInvalidDrag(accepted.length < 1);
}, [accept, multiple]);
const handleDropEvent = React.useCallback((event) => {
const dataTransfer = event.dataTransfer;
setIsInvalidDrag(false);
if (!dataTransfer?.items) {
return;
}
const { accepted, rejected } = getSeparatedItems(dataTransfer, {
accept,
multiple,
});
const acceptedItems = getFilesFromItems(accepted);
const rejectedItems = getFileRejections(rejected);
if (acceptedItems.length > 0 || rejectedItems.length > 0) {
handleUpdate(acceptedItems, rejectedItems);
}
}, [accept, getFileRejections, getFilesFromItems, handleUpdate, multiple]);
const { isDraggingOver, getDroppableProps } = useDropZone({
disabled,
onDragEnter: handleDragEnter,
onDrop: handleDropEvent,
});
React.useEffect(() => {
if (!isDraggingOver) {
setIsInvalidDrag(false);
}
}, [isDraggingOver]);
const handleFileInputUpdate = React.useCallback((files) => {
handleUpdate(files, []);
}, [handleUpdate]);
const { controlProps, triggerProps } = useFileInput({ onUpdate: handleFileInputUpdate });
const { onKeyDown } = useActionHandlers(disabled ? undefined : triggerProps.onClick);
const contextValue = React.useMemo(() => ({
accept,
title,
description,
buttonText,
multiple,
disabled,
icon,
errorIcon,
errorMessage,
validationState,
controlProps,
triggerProps,
isDraggingOver,
isInvalidDrag,
getDroppableProps,
onKeyDown,
}), [
accept,
title,
description,
buttonText,
multiple,
disabled,
icon,
errorIcon,
errorMessage,
validationState,
controlProps,
triggerProps,
isDraggingOver,
isInvalidDrag,
getDroppableProps,
onKeyDown,
]);
return (_jsx(FileDropZoneContext.Provider, { value: contextValue, children: children }));
};
export const useFileZoneContext = () => {
const contextValue = React.useContext(FileDropZoneContext);
if (contextValue === null) {
throw new Error('FileDropZone context not found');
}
return contextValue;
};
//# sourceMappingURL=FileDropZone.Provider.js.map