77 lines
2.1 KiB
TypeScript
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;
|