Skip to content

DragPreview ​

A Solid component that portals content into drag preview proxy elements. When a Draggable has dragPreview: true enabled, this component renders your content directly into the proxy element that moves during the drag, using Solid's <Portal> to project into non-Solid DOM nodes without breaking reactivity.

Usage ​

Use a render function to access drag metadata and render dynamic content per proxy element. This is especially useful for multi-element drags.

tsx
/** @jsxImportSource solid-js */
import { usePointerSensor, useDraggable, DragPreview } from 'dragdoll-solid';

function DraggableBox() {
  let element: HTMLDivElement | null = null;
  const [pointerSensor, setPointerSensorRef] = usePointerSensor();

  const draggable = useDraggable([pointerSensor], () => ({
    elements: () => (element ? [element] : []),
    dragPreview: true,
  }));

  return (
    <>
      <div
        ref={(node) => {
          element = node;
          setPointerSensorRef(node);
        }}
        style={{ width: '100px', height: '100px', background: 'red' }}
      >
        Drag me
      </div>
      <DragPreview draggable={draggable}>
        {({ sourceElement, exiting }) => (
          <div style={{ padding: '10px', background: exiting ? 'gray' : 'blue', color: 'white' }}>
            Dragging: {sourceElement.textContent}
          </div>
        )}
      </DragPreview>
    </>
  );
}

Static children ​

If you don't need access to drag metadata, you can pass static children. The same content is rendered into every proxy element.

tsx
<DragPreview draggable={draggable}>
  <div style={{ padding: '10px', background: 'blue', color: 'white' }}>
    I am rendering inside the proxy!
  </div>
</DragPreview>

Props ​

draggable ​

ts
type draggable = MaybeAccessor<AnyDraggable | null>;

The Draggable instance to track. Pass the accessor returned by useDraggable. Accepts either an accessor or a raw value. The component renders nothing when null or when the draggable has no active drag preview.

  • Required.

children ​

ts
type children = ((props: DragPreviewRenderProps) => JSX.Element) | JSX.Element;

The content to render inside each proxy element. If a function is provided, it is called once per proxy element with a DragPreviewRenderProps object, allowing you to render dynamic content based on drag state.

  • Optional.

Types ​

DragPreviewProps ​

ts
// Import
import type { DragPreviewProps } from 'dragdoll-solid';

// Interface
interface DragPreviewProps {
  draggable: MaybeAccessor<AnyDraggable | null>;
  children?: ((props: DragPreviewRenderProps) => JSX.Element) | JSX.Element;
}

DragPreviewRenderProps ​

ts
// Import
import type { DragPreviewRenderProps } from 'dragdoll-solid';

// Interface
interface DragPreviewRenderProps {
  draggable: AnyDraggable;
  item: DraggableDragItem | null;
  index: number;
  sourceElement: HTMLElement | SVGSVGElement;
  exiting: boolean;
  done: () => void;
}

draggable ​

The active Draggable instance.

item ​

The DraggableDragItem for this proxy element. Contains position data, client rect, and per-item drag state. null if the drag has ended (during exit animation).

index ​

The index of this proxy element in the items array. Useful for multi-element drags to differentiate between items.

sourceElement ​

The original DOM element that this proxy represents. This is the element returned by the elements setting that stays in place while its proxy moves.

exiting ​

true when the drag has ended but the proxy is still alive for exit animation (requires dragPreviewExitTimeout). Use this to trigger CSS transitions or animations.

done ​

Call this when your exit animation finishes to remove the proxy element. Only meaningful when exiting is true. If not called within the configured timeout, cleanup happens automatically as a safety fallback.

How It Works ​

Internally, <DragPreview> uses useDragPreview to subscribe to the drag preview store. When proxies are active, the component uses Solid's <Show> and <For> to iterate over the proxy elements, and <Portal> to mount children into each proxy DOM node. This keeps your Solid reactivity intact while rendering into non-Solid-managed proxy elements.

DragDoll is released under the MIT License.