openreader/src/components/doclist/dnd/DocumentDndProvider.tsx
Richard R 2e74e79e2c refactor(dnd): unify drag-and-drop backend and add custom drag layer for documents
Replace dual HTML5/Touch backend logic with a single TouchBackend configured to
handle both mouse and touch events, ensuring consistent drag-and-drop behavior
across all devices. Introduce a custom DocumentDragLayer to render drag previews
universally, as the touch backend does not provide a native drag image.

Update document tile, gallery, and list views to suppress native long-press
previews on iOS and prevent accidental document opening after drag actions.
Revise drag-and-drop test helpers to simulate pointer gestures compatible with
the new backend, improving reliability of automated tests.
2026-06-04 18:09:36 -06:00

37 lines
1.3 KiB
TypeScript

'use client';
import type { ReactNode } from 'react';
import { DndProvider } from 'react-dnd';
import { TouchBackend } from 'react-dnd-touch-backend';
import { DocumentDragLayer } from './DocumentDragLayer';
/**
* Single DnD backend for every input type. HTML5 drag-and-drop doesn't fire
* from touch input, so rather than maintaining two backends and swapping per
* device, we run the touch backend everywhere with `enableMouseEvents` so mouse
* drags work too. One code path, identical behavior across devices.
*
* The touch backend renders no native drag image, so {@link DocumentDragLayer}
* supplies the preview (a lightweight card) on all platforms.
*/
export function DocumentDndProvider({ children }: { children: ReactNode }) {
return (
<DndProvider
backend={TouchBackend}
options={{
enableMouseEvents: true,
enableTouchEvents: true,
// Long-press to start a touch drag; mouse drags start immediately.
delayTouchStart: 220,
delayMouseStart: 0,
// Require real movement before a drag begins, so a plain click (mouse or
// tap) can never accidentally arm a drag and swallow the click/navigation.
touchSlop: 10,
ignoreContextMenu: true,
}}
>
{children}
<DocumentDragLayer />
</DndProvider>
);
}