@dnd-kit-svelte/svelte

中文文档
0.2.0发布于 2026/11/05MITTypeScriptES Module构建来源已验证近 30 天下载 4.6万

dnd-kit for Svelte 5: draggable, droppable and sortable primitives, a drag overlay and modifiers, built on @dnd-kit/dom with runes and attachments

原始使用文档
文档目录6 节
  1. Install
  2. Quick start
  3. Differences from React
  4. API
  5. Development
  6. License

dnd-kit-svelte

npm

dnd kit for Svelte 5: draggable, droppable and sortable primitives, a drag overlay and modifiers, built on @dnd-kit/dom with runes and attachments. The API follows @dnd-kit/react, so its documentation applies here, with the Svelte differences below.

Docs and examples

Install

npm i @dnd-kit-svelte/svelte

Requires Svelte 5.40 or later. Helpers such as move come from @dnd-kit/helpers; plugins such as Feedback from @dnd-kit/dom.

Quick start

Hooks find their manager through context, so call them in components rendered inside DragDropProvider.

<!-- draggable.svelte -->
<script lang="ts">
    import { useDraggable } from "@dnd-kit-svelte/svelte";

    const { ref } = useDraggable({ id: "draggable" });
</script>

<button {@attach ref}>Drag me</button>
<!-- droppable.svelte -->
<script lang="ts">
    import { useDroppable } from "@dnd-kit-svelte/svelte";
    import type { Snippet } from "svelte";

    let { id, children }: { id: string; children?: Snippet } = $props();

    const { ref, isDropTarget } = useDroppable({ id: () => id });
</script>

<div {@attach ref} data-over={isDropTarget.current}>
    {@render children?.()}
</div>
<script lang="ts">
    import { DragDropProvider } from "@dnd-kit-svelte/svelte";
    import Draggable from "./draggable.svelte";
    import Droppable from "./droppable.svelte";

    let dropped = $state(false);
</script>

<DragDropProvider onDragEnd={(event) => !event.canceled && (dropped = event.operation.target?.id === "droppable")}>
    {#if !dropped}
        <Draggable />
    {/if}

    <Droppable id="droppable">
        {#if dropped}
            <Draggable />
        {/if}
    </Droppable>
</DragDropProvider>

A sortable list:

<!-- sortable-item.svelte -->
<script lang="ts">
    import { useSortable } from "@dnd-kit-svelte/svelte/sortable";

    let { id, index }: { id: string; index: number } = $props();

    const { ref, isDragging } = useSortable({ id: () => id, index: () => index });
</script>

<li {@attach ref} data-dragging={isDragging.current}>{id}</li>
<script lang="ts">
    import { DragDropProvider } from "@dnd-kit-svelte/svelte";
    import { move } from "@dnd-kit/helpers";
    import SortableItem from "./sortable-item.svelte";

    let items = $state(["a", "b", "c"]);
</script>

<DragDropProvider onDragOver={(event) => (items = move(items, event))}>
    <ul>
        {#each items as id, index (id)}
            <SortableItem {id} {index} />
        {/each}
    </ul>
</DragDropProvider>

When each item is one element, you can skip its component and call the hook in a {const …} tag inside {#each} (Svelte 5.56 or later):

<script lang="ts">
    import { DragDropProvider } from "@dnd-kit-svelte/svelte";
    import { useSortable } from "@dnd-kit-svelte/svelte/sortable";
    import { move } from "@dnd-kit/helpers";

    let items = $state(["a", "b", "c"]);
</script>

<DragDropProvider onDragOver={(event) => (items = move(items, event))}>
    <ul>
        {#each items as id, index (id)}
            {const { ref } = useSortable({ id, index: () => index })}
            <li {@attach ref}>{id}</li>
        {/each}
    </ul>
</DragDropProvider>

Differences from React

Svelte components don't re-render, so values that change reach the hooks as functions, and values that the hooks produce are read through .current.

Inputs are values or getters. Any input field can be a value, read once, or a function returning it, read whenever it changes:

useSortable({
    id: item.id, // fixed
    index: () => index, // follows `index`
    data: () => item,
});

Getter properties (get index() { return index; }) and a component's rest props work the same way. A field whose value is itself a function (accept, collisionDetector, plugins: (defaults) => …) must be wrapped in a getter:

import { Feedback } from "@dnd-kit/dom";

useSortable({
    id,
    index: () => index,
    plugins: () => (defaults) => [...defaults, Feedback.configure({ feedback: "clone" })],
});

State is read through .current. isDragging, isDropping, isDragSource and isDropTarget are lenses (Lens<boolean>): their current updates the template on its own.

<div {@attach ref}>{isDragging.current ? "Dragging" : "Idle"}</div>

Refs are attachments. ref, handleRef, sourceRef and targetRef go on elements with {@attach}.

Lists sort through state. dnd kit's OptimisticSortingPlugin reorders DOM nodes during a drag, which a keyed {#each} can't recover from, so useSortable leaves it out of its default plugins (and out of the defaults a plugins: () => (defaults) => … callback receives). Move items in onDragOver to sort while dragging, as above, or in onDragEnd to sort on drop. Sort columns or groups the same way, with their own array in state.

DragOverlay renders a snippet. It receives the drag source:

<DragOverlay>
    {#snippet children(source)}
        <Item id={source.id} />
    {/snippet}
</DragOverlay>

API

ExportFrom
DragDropProvider, DragOverlay@dnd-kit-svelte/svelte
useDraggable, useDroppable@dnd-kit-svelte/svelte
useDragDropManager, useDragDropMonitor, useDragOperation, useInstance@dnd-kit-svelte/svelte
KeyboardSensor, PointerSensor, event types (DragEndEvent…)@dnd-kit-svelte/svelte
useSortable, isSortable, isSortableOperation@dnd-kit-svelte/svelte/sortable
dnd kit's modifiers, SnapCenterToCursor, AlignTopLeftToCursor, OffsetBottomRight@dnd-kit-svelte/svelte/modifiers

For what each one does, see the documentation.

Development

This is a Bun workspace: the package lives in packages/svelte, the examples site in docs.

bun install
bun run dev    # the package in watch mode and the examples site
bun run check  # build and type-check everything

License

MIT © Haniel Ubogu. Contains code adapted from dnd kit, see NOTICE.txt.

版本与发布记录

@dnd-kit-svelte/svelte 共发布 8 个版本,首次发布于 2025/09/04;过去 12 个月发布了 4 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.2.0latest2026/11/058 天前
0.1.62026/02/069 个月前
0.1.52025/11/2011 个月前
0.1.42025/11/2011 个月前
0.1.32025/09/071.2 年前
0.1.22025/09/071.2 年前

关于 @dnd-kit-svelte/svelte 的常见问题

@dnd-kit-svelte/svelte 是什么?

dnd-kit for Svelte 5: draggable, droppable and sortable primitives, a drag overlay and modifiers, built on @dnd-kit/dom with runes and attachments

如何安装 @dnd-kit-svelte/svelte?

在项目目录运行 npm install @dnd-kit-svelte/svelte,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:svelte(^5.40.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

@dnd-kit-svelte/svelte 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@dnd-kit-svelte/svelte 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@dnd-kit-svelte/svelte 可以商用吗?

@dnd-kit-svelte/svelte 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@dnd-kit-svelte/svelte 的下载量有多少?

根据 npm 官方下载统计,@dnd-kit-svelte/svelte 在 2026/10/13 – 2026/11/11 这 30 天内被下载 46,105 次,日均约 1,537 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@dnd-kit-svelte/svelte 还在维护吗?

最新版本 0.2.0 发布于 2026/11/05(8 天前);至今共发布 8 个版本,其中过去 12 个月发布了 4 个;首次发布于 2025/09/04。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。