UNPKG

@gravity-ui/uikit

Version:

Gravity UI base styling and components

128 lines (127 loc) 4.44 kB
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