This commit is contained in:
2025-11-11 00:48:07 +01:00
parent 992d7038e5
commit 70b9443e66
11 changed files with 258 additions and 137 deletions
@@ -29,6 +29,10 @@ const useDocumentDragHandlers = ({
({ documents = [], folders = [] } = {}) => {
destroyDragPreview();
if (typeof document === 'undefined') {
return null;
}
const docEntries = (documents || []).filter(Boolean);
const folderEntries = (folders || []).filter(Boolean);
const totalCount = docEntries.length + folderEntries.length;
@@ -54,6 +58,8 @@ const useDocumentDragHandlers = ({
const wrapper = document.createElement('div');
wrapper.className = 'document-drag-preview';
wrapper.style.setProperty('--drag-preview-size', `${canvasSize}px`);
wrapper.style.width = `${canvasSize}px`;
wrapper.style.height = `${canvasSize}px`;
visibleItems.forEach((item, index) => {
const layer = document.createElement('div');
@@ -101,15 +107,23 @@ const useDocumentDragHandlers = ({
layer.textContent = doc?.title || 'Document';
}
} else {
const folderId = item.payload;
const rowEl = folderId ? document.getElementById(`folder-row-${folderId}`) : null;
const iconEl = rowEl?.querySelector('.thumb-icon');
const payload = item.payload;
const folderId = typeof payload === 'string' ? payload : payload?.id;
const rowEl = folderId
? document.getElementById(`folder-row-${folderId}`)
|| document.getElementById(`folder-card-${folderId}`)
: null;
const iconEl = rowEl?.querySelector('.thumb-icon, .folder-card__icon');
layer.style.width = `${size}px`;
layer.style.height = `${size}px`;
layer.classList.add('document-drag-preview__item--folder');
let content = null;
if (iconEl instanceof HTMLElement) {
content = iconEl.cloneNode(true);
const cloneSource = iconEl.classList.contains('folder-card__icon')
? iconEl.querySelector('svg') || iconEl
: iconEl;
content = cloneSource.cloneNode(true);
content.classList.add('document-drag-preview__folder-thumb');
const svg = content.querySelector('svg');
if (svg) {
@@ -276,11 +290,19 @@ const useDocumentDragHandlers = ({
console.warn('[documents] Failed to populate folder drag payload', error);
}
const previewDocs = effectiveDocumentSelection
.map((id) => documentLookup.get(id) || null)
.filter(Boolean);
createDragPreview({ documents: previewDocs, folders: uniqueFolders });
const previewNode = createDragPreview({
documents: effectiveDocumentSelection
.map((id) => documentLookup.get(id) || null)
.filter(Boolean),
folders: uniqueFolders,
});
event.currentTarget.classList.add('dragging');
if (previewNode) {
const width = previewNode.offsetWidth || 96;
const height = previewNode.offsetHeight || 96;
event.dataTransfer.setDragImage(previewNode, width / 2, height / 2);
}
},
[
selectedFolderIds,
@@ -50,6 +50,11 @@ import useDocumentDragHandlers from './useDocumentDragHandlers';
import useDocumentMutations from './useDocumentMutations';
import useDetailWorkspace from '../../detail/useDetailWorkspace';
const EntryType = Object.freeze({
document: 'document',
folder: 'folder',
});
const noop = () => {};
const useDocumentsWorkspace = ({
@@ -1185,19 +1190,15 @@ const useDocumentsWorkspace = ({
const handleEntryPointerCore = useEntryPointerCore({
resolveDocumentRowKey,
resolveFolderRowKey,
onSelectDocument: (documentId, event, { rowKey }) => {
const key = rowKey || resolveDocumentRowKey(documentId);
onSelectEntry: (entry, event, { rowKey, modifierClick, primaryClick }) => {
const { type, id } = entry;
const key = rowKey
|| (type === EntryType.document ? resolveDocumentRowKey(id) : resolveFolderRowKey(id));
if (key) {
handleEntrySelection(key, event);
}
},
onSelectFolder: (folderId, event, { modifierClick, primaryClick, rowKey }) => {
const key = rowKey || resolveFolderRowKey(folderId);
if (key) {
handleEntrySelection(key, event);
}
if (!modifierClick && primaryClick) {
selectFolder(folderId);
if (type === EntryType.folder && !modifierClick && primaryClick) {
selectFolder(id);
}
},
});
@@ -85,9 +85,8 @@ const useFolderTree = ({
})();
setFocusedDocumentId(nextFocus);
selectionAnchorRef.current = nextDocKeys.length
? nextDocKeys[nextDocKeys.length - 1]
: null;
const nextAnchor = mergedSelection.length ? mergedSelection[mergedSelection.length - 1] : null;
selectionAnchorRef.current = nextAnchor;
selectionOrderRef.current = mergedSelection;
setSelectionOrder(mergedSelection);
},