Skip to content

useDnDProvider ​

useDnDProvider returns the current DnD context (the same object that DnDProvider provides). Use it in any descendant of DnDProvider when you need access to preview, pointer, state, entities, keyboard, or collision. Must be called inside a provider; otherwise the internal inject fails.

Signature ​

ts
useDnDProvider(): IDnDProviderExternal

Returns IDnDProviderExternal — the public provider API.


Return value ​

PropertyTypeDescription
stateRef<TDnDState | undefined>Current phase: 'dragging', 'selecting', 'activating', 'pending', or null / undefined.
pointerRef<TPointerState | undefined>Pointer state with start, current, and offset coordinates.
entitiesReactive<IEntities>Maps and sets: draggableMap, droppableMap, draggingMap, selectedSet, visibleDraggableSet, etc.
keyboard{ keys, step, moveFaster }keys.pressedKeys, keys.forDrag, forCancel, forDrop, forMove, forMoveFaster; step sizes for keyboard drag.
scrollPositionReactive<ICoordinates>Current scroll position (x, y). Updated as the user scrolls.
delayReactive<IDelay>Activation delay progress: { progress: number, startTime: number }.
distanceProgressComputedRef<number>Progress of distance-based activation (0–1).
preview{ ref, position, size, render, to }Preview container ref, position (x/y), size (DOMRect), current render component, and teleport target.
hoveredIHovered{ draggable: Map, droppable: Map } — elements under cursor during drag (with their placement).
collision{ throttle }Collision detection throttle interval (Ref<number>).
autoScrollViewportComputedRef<IAutoScrollOptions | true | false | null | undefined>Viewport auto-scroll config from the DnDProvider prop.

preview detail ​

ts
preview: {
  ref: Ref<HTMLElement | null>;              // the mounted preview DOM element
  position: ComputedRef<ICoordinates>;      // current x/y position (use for translate3d)
  size: ShallowRef<DOMRect>;               // size of the preview element (updated by DragPreview on mount/change)
  render: Ref<Component | undefined>;       // active render component (from makeDraggable's render option)
  to: WritableComputedRef<string | false | null | undefined>; // teleport target (from previewTo prop)
}

preview.position is the primary source of truth for positioning the drag ghost. Use it in custom preview implementations:

ts
const provider = useDnDProvider();
// preview position as CSS variables
const style = computed(() => ({
  transform: `translate3d(${provider.preview.position.value.x}px, ${provider.preview.position.value.y}px, 0)`,
}));

TDnDState ​

ts
type TDnDState =
  | 'dragging'    // active drag
  | 'selecting'   // box selection in progress
  | 'activating'  // distance/delay threshold being evaluated
  | 'pending'     // awaiting async onDrop resolution
  | null
  | undefined;

Example ​

vue
<script setup lang="ts">
  import { useDnDProvider } from '@vue-dnd-kit/core';

  const provider = useDnDProvider();

  // React to drag state
  watchEffect(() => {
    if (provider.state.value === 'dragging') {
      console.log('dragging', provider.pointer.value?.current);
    }
  });
</script>

Reading preview position in a custom preview:

vue
<script setup lang="ts">
  import { computed } from 'vue';
  import { useDnDProvider } from '@vue-dnd-kit/core';

  const provider = useDnDProvider();

  const style = computed(() => {
    const { x, y } = provider.preview.position.value;
    return { transform: `translate3d(${x}px, ${y}px, 0)` };
  });
</script>

<template>
  <div v-if="provider.state.value === 'dragging'" :style="style" class="my-preview">
    <component :is="provider.preview.render.value" />
  </div>
</template>


injectionKey — advanced use only ​

injectionKey is the Vue injection key under which DnDProvider stores its context. It is exported from the public API but should not be used in normal application code — useDnDProvider covers all typical needs.

Typical use cases:

  • Bridging a separately mounted Vue app (e.g. inside a shadow root) into the same DnD context
  • Building custom integrations that need direct access to the internal provider
  • Exploring or debugging what the library holds at runtime

Example — sharing context with a shadow root app:

ts
import { inject, createApp, h } from 'vue';
import { injectionKey } from '@vue-dnd-kit/core';

// Inside a component that is a descendant of DnDProvider:
const outerProvider = inject(injectionKey);

onMounted(() => {
  const shadow = host.attachShadow({ mode: 'open' });
  const container = document.createElement('div');
  shadow.appendChild(container);

  // Share the outer provider with the inner app — no DnDProvider wrapper needed
  createApp({ render: () => h(YourComponent) })
    .provide(injectionKey, outerProvider)
    .mount(container);
});

Elements inside the shadow root will register into the same draggableMap / droppableMap as the outer app and participate in the same drag sessions.

Do not use injectionKey + inject as a replacement for useDnDProvider. The value behind the key is an internal type — its shape is not part of the public API contract and may change between minor versions.


See also ​

Released under the MIT License.