UNPKG

@pdftron/webviewer-react-toolkit

Version:

A React component library for integrating with PDFTron WebViewer API.

158 lines (157 loc) 7.11 kB
import { __spreadArrays } from "tslib"; import { useCallback, useEffect, useMemo, useState } from 'react'; import { moveMultiFromIndexToIndex } from '../utils'; /** * Combines most of the necessary functionality to manage files for the * `FileOrganizer` component. * @param options Options for managing files. */ export function useManagedFiles(_a) { var _b = _a === void 0 ? {} : _a, initialFiles = _b.initialFiles, preventMultiDrag = _b.preventMultiDrag, preventDeselectOnDragOther = _b.preventDeselectOnDragOther, preventSelectOnDrag = _b.preventSelectOnDrag, preventMultiSelect = _b.preventMultiSelect, easyMultiSelect = _b.easyMultiSelect; var _c = useState(initialFiles !== null && initialFiles !== void 0 ? initialFiles : []), files = _c[0], setFiles = _c[1]; var addFile = useCallback(function (file, index) { setFiles(function (prev) { if (prev.includes(file)) return prev; if (index === undefined) return __spreadArrays(prev, [file]); return __spreadArrays(prev.slice(0, index), [file], prev.slice(index)); }); }, []); var removeFile = useCallback(function (file) { return setFiles(function (prev) { return prev.filter(function (f) { return f !== file; }); }); }, []); /* --- Selection. --- */ // Note: this is also an ordered stack, with the most recently selected last. // This allows us to do shift-range selection from the most recent. var _d = useState([]), selectedIds = _d[0], setSelectedIds = _d[1]; var toggleSelectedId = useCallback(function (id, event) { var multiKey = !preventMultiSelect && ((event === null || event === void 0 ? void 0 : event.ctrlKey) || (event === null || event === void 0 ? void 0 : event.metaKey) || false); var rangeKey = !preventMultiSelect && ((event === null || event === void 0 ? void 0 : event.shiftKey) || false); setSelectedIds(function (prev) { var toggleIndex = prev.indexOf(id); if (!multiKey && rangeKey && prev.length) { var lastSelectedIndex = files.findIndex(function (f) { return f.id === prev[prev.length - 1]; }); var toggleFileIndex = files.findIndex(function (f) { return f.id === id; }); var selectedFiles = []; if (toggleFileIndex < lastSelectedIndex) { selectedFiles = files.slice(toggleFileIndex, lastSelectedIndex + 1); } else { selectedFiles = files.slice(lastSelectedIndex, toggleFileIndex + 1).reverse(); } return selectedFiles.map(function (f) { return f.id; }); } if (toggleIndex === -1) { if (easyMultiSelect || multiKey) return __spreadArrays(prev, [id]); return [id]; } if (toggleIndex !== -1) { if (easyMultiSelect || multiKey) return __spreadArrays(prev.slice(0, toggleIndex), prev.slice(toggleIndex + 1)); if (prev.length > 1) return [id]; return []; } return prev; }); }, [easyMultiSelect, files, preventMultiSelect]); var onDeselectAll = useCallback(function () { return setSelectedIds([]); }, []); var onSelectAll = useCallback(function () { return setSelectedIds(files.map(function (file) { return file.id; })); }, [files]); var _setMovingSelectedId = useCallback(function (id) { setSelectedIds(function (prev) { if (prev.includes(id)) return prev; if (preventDeselectOnDragOther) return preventSelectOnDrag ? prev : __spreadArrays(prev, [id]); return preventSelectOnDrag ? [] : [id]; }); }, [preventDeselectOnDragOther, preventSelectOnDrag]); /* --- Multiple drag items. --- */ var _e = useState([]), draggingIds = _e[0], setDraggingIds = _e[1]; var onDragChange = useCallback(function (id) { if (!id) return setDraggingIds([]); if (selectedIds.length === 0) return; _setMovingSelectedId(id); if (!preventMultiDrag) { var toDragIds = selectedIds.includes(id) ? selectedIds : [id]; setDraggingIds(toDragIds); } else { setDraggingIds([id]); } }, [selectedIds, _setMovingSelectedId, preventMultiDrag]); /* --- Moving items. --- */ var onMove = useCallback(function (fromIndex, toIndex) { var fromFile = files[fromIndex]; if (!fromFile) return false; // Update selections. _setMovingSelectedId(fromFile.id); // If multi drag is permitted, and multiple items are selected, and // there are no items being dragged, do a multi move. This will be a // keyboard-specific operation, as multi dragging is managed by the // dragging handlers. if (!preventMultiDrag && selectedIds.includes(fromFile.id) && selectedIds.length > 1) { var next = moveMultiFromIndexToIndex(files, selectedIds, fromIndex, toIndex); if (next === files) return false; setFiles(next); return true; } // Don't allow "wrapping". if (toIndex < 0 || toIndex >= files.length) return false; var clone = files.slice(); var item = clone.splice(fromIndex, 1)[0]; clone.splice(toIndex, 0, item); setFiles(clone); return true; }, [_setMovingSelectedId, files, preventMultiDrag, selectedIds]); // Remove selected items if the file is removed. useEffect(function () { setSelectedIds(function (prev) { var toRemove = new Set(prev); files.forEach(function (file) { if (toRemove.has(file.id)) toRemove.delete(file.id); }); return prev.filter(function (id) { return !toRemove.has(id); }); }); }, [files]); var managedFiles = useMemo(function () { return ({ fileOrganizerProps: { files: files, onMove: onMove, onDragChange: onDragChange, onDeselectAll: onDeselectAll, onSelectAll: onSelectAll, draggingIds: draggingIds, }, getThumbnailSelectionProps: function (id) { return ({ selected: selectedIds.includes(id), onClick: function (event) { return toggleSelectedId(id, event); }, }); }, files: files, setFiles: setFiles, selectedIds: selectedIds, setSelectedIds: setSelectedIds, toggleSelectedId: toggleSelectedId, addFile: addFile, removeFile: removeFile, draggingIds: draggingIds, }); }, [ addFile, draggingIds, files, onMove, onDragChange, removeFile, onSelectAll, selectedIds, toggleSelectedId, onDeselectAll, ]); return managedFiles; }