Files
papercrate/frontend/src/documents/useEntryPointer.ts
T

77 lines
2.1 KiB
TypeScript

import { useCallback } from 'react';
import { createDocumentEntryKey, createFolderEntryKey } from '../app/entryKey';
export type PointerEventLike = MouseEvent | PointerEvent;
export const isPointerModifierEvent = (event?: PointerEventLike | null): boolean =>
Boolean(event && (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey));
export const isPrimaryPointerEvent = (event?: PointerEventLike | null): boolean => {
if (!event) {
return true;
}
if (event.button !== 0) {
return false;
}
const type = event?.type?.toLowerCase?.() ?? '';
return type === 'click' || type === 'pointerdown' || type === 'pointerup';
};
export type EntryType = 'document' | 'folder';
export interface WorkspaceEntry {
id: string;
key?: string;
type: EntryType;
[key: string]: unknown;
}
interface UseEntryPointerOptions {
onSelectEntry?: (entry: WorkspaceEntry, event?: PointerEventLike | null, metadata?: EntryPointerMetadata) => void;
onDocumentActivate?: (id: string, metadata?: EntryPointerMetadata) => void;
}
export interface EntryPointerMetadata {
modifierClick: boolean;
primaryClick: boolean;
rowKey: string;
type: EntryType;
id: string;
}
export const useEntryPointer = ({
onSelectEntry,
onDocumentActivate,
}: UseEntryPointerOptions) =>
useCallback(
(entry?: WorkspaceEntry | null, event?: PointerEventLike | null) => {
if (!entry || !entry.id) {
return;
}
const { type, id } = entry;
if (type !== 'document' && type !== 'folder') {
return;
}
const rowKey = entry.key
|| (type === 'document' ? createDocumentEntryKey(id) : createFolderEntryKey(id));
if (!rowKey) {
return;
}
const modifierClick = isPointerModifierEvent(event);
const primaryClick = isPrimaryPointerEvent(event);
const metadata: EntryPointerMetadata = { modifierClick, primaryClick, rowKey, type, id };
onSelectEntry?.(entry, event, metadata);
if (type === 'document' && !modifierClick && primaryClick) {
onDocumentActivate?.(id, metadata);
}
},
[onSelectEntry, onDocumentActivate],
);
export default useEntryPointer;