HTML5 drag and drop backend for React DnD, enabling sophisticated drag-and-drop interactions using the native HTML5 Drag and Drop API
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Utilities for customizing drag preview behavior, specifically the creation of transparent images to hide the default browser drag preview and enable custom drag preview implementations.
Create a transparent 1x1 pixel image for hiding the default browser drag preview, allowing for custom drag preview implementations.
/**
* Returns a transparent 1x1 pixel image for drag preview customization
* The image is cached and reused across calls for performance
* @returns HTMLImageElement with transparent GIF data
*/
function getEmptyImage(): HTMLImageElement;Usage Examples:
import { useDragPreview } from "react-dnd";
import { getEmptyImage } from "react-dnd-html5-backend";
import { useEffect } from "react";
// Hide default drag preview to show custom preview
function DragSourceWithCustomPreview() {
const [, drag, preview] = useDrag({
type: "ITEM",
item: { id: "123", name: "Custom Item" },
});
// Hide the default browser drag preview
useEffect(() => {
preview(getEmptyImage(), { captureDraggingState: true });
}, [preview]);
return (
<div ref={drag} style={{ cursor: "move" }}>
Drag me (custom preview will show)
</div>
);
}
// Connect empty image immediately
function SimpleCustomPreview() {
const [, drag, preview] = useDrag({
type: "ITEM",
item: { id: "456" },
});
// Connect empty image to hide default preview
const emptyImage = getEmptyImage();
preview(emptyImage);
return <div ref={drag}>Drag with no default preview</div>;
}
// Use with custom drag layer for complete control
function CustomDragLayer() {
const [, drag, preview] = useDrag({
type: "CUSTOM_ITEM",
item: { id: "custom" },
});
// Hide native preview and use custom drag layer
useEffect(() => {
preview(getEmptyImage(), { captureDraggingState: true });
}, [preview]);
return <div ref={drag}>Drag with custom layer</div>;
}When using getEmptyImage() with React DnD's preview connection, you can provide positioning options:
interface DragPreviewOptions {
/** Horizontal anchor point (0 = left edge, 0.5 = center, 1 = right edge) */
anchorX?: number;
/** Vertical anchor point (0 = top edge, 0.5 = center, 1 = bottom edge) */
anchorY?: number;
/** Manual horizontal offset in pixels (overrides anchor-based positioning) */
offsetX?: number;
/** Manual vertical offset in pixels (overrides anchor-based positioning) */
offsetY?: number;
/** Whether to capture the dragging state for the preview */
captureDraggingState?: boolean;
}Usage Examples:
import { useDrag } from "react-dnd";
import { getEmptyImage } from "react-dnd-html5-backend";
// Different anchor point configurations
function AnchorPointExamples() {
const [, drag1, preview1] = useDrag({ type: "TOP_LEFT", item: {} });
const [, drag2, preview2] = useDrag({ type: "CENTER", item: {} });
const [, drag3, preview3] = useDrag({ type: "BOTTOM_RIGHT", item: {} });
// Top-left anchored preview
preview1(getEmptyImage(), { anchorX: 0, anchorY: 0 });
// Center anchored preview
preview2(getEmptyImage(), { anchorX: 0.5, anchorY: 0.5 });
// Bottom-right anchored preview
preview3(getEmptyImage(), { anchorX: 1, anchorY: 1 });
return (
<div>
<div ref={drag1}>Top-Left Anchor</div>
<div ref={drag2}>Center Anchor</div>
<div ref={drag3}>Bottom-Right Anchor</div>
</div>
);
}
// Manual offset positioning
function ManualOffsetExample() {
const [, drag, preview] = useDrag({
type: "MANUAL_OFFSET",
item: { id: "manual" },
});
// Position preview 20px right and 10px down from cursor
preview(getEmptyImage(), {
offsetX: 20,
offsetY: 10,
captureDraggingState: true,
});
return <div ref={drag}>Drag with manual offset</div>;
}
// Capture dragging state for custom drag layers
function DragStateCapture() {
const [, drag, preview] = useDrag({
type: "STATE_CAPTURE",
item: { id: "state" },
});
// Enable dragging state capture for custom drag layer integration
preview(getEmptyImage(), {
captureDraggingState: true,
});
return <div ref={drag}>Drag with state capture</div>;
}getEmptyImage() function returns a cached HTMLImageElement containing a transparent 1x1 pixel GIFInstall with Tessl CLI
npx tessl i tessl/npm-react-dnd-html5-backend