apps/docs/svelte/primitives/create-sortable.mdx
import {Story} from '/snippets/story.mdx';
<Story id="sortable-vertical-list--basic-setup" framework="svelte" height="320" hero />The createSortable primitive combines draggable and droppable behavior with sorting logic. Import it from @dnd-kit/svelte/sortable.
<script>
import {DragDropProvider} from '@dnd-kit/svelte';
import {createSortable} from '@dnd-kit/svelte/sortable';
import {move} from '@dnd-kit/helpers';
let items = $state([1, 2, 3, 4]);
function onDragEnd(event) {
items = move(items, event);
}
</script>
<DragDropProvider {onDragEnd}>
<ul>
{#each items as id, index (id)}
{@const sortable = createSortable({id, index: () => index})}
<li {@attach sortable.attach}>
Item {id}
</li>
{/each}
</ul>
</DragDropProvider>
The example above uses the move helper from @dnd-kit/helpers, a convenience function that takes your items and a drag event and returns a new array with the item moved to its new position. It supports flat arrays and grouped records, handles canceled drags, and works with optimistic sorting out of the box.
If you need more control over state updates, you can manage state manually using the isSortable type guard and the sortable properties (initialIndex, index).
With optimistic sorting enabled (the default), you only need to handle the dragend event:
<script>
import {DragDropProvider} from '@dnd-kit/svelte';
import {createSortable, isSortable} from '@dnd-kit/svelte/sortable';
let items = $state([1, 2, 3, 4]);
function onDragEnd(event) {
if (event.canceled) return;
const {source} = event.operation;
if (isSortable(source)) {
const {initialIndex, index} = source;
if (initialIndex !== index) {
const newItems = [...items];
const [removed] = newItems.splice(initialIndex, 1);
newItems.splice(index, 0, removed);
items = newItems;
}
}
}
</script>
<DragDropProvider {onDragEnd}>
<ul>
{#each items as id, index (id)}
{@const sortable = createSortable({id, index: () => index})}
<li {@attach sortable.attach}>
Item {id}
</li>
{/each}
</ul>
</DragDropProvider>
All input properties accept plain values or getter functions for reactivity.
<ParamField path="id" type="UniqueIdentifier | (() => UniqueIdentifier)" required> A unique identifier for this sortable instance. </ParamField> <ParamField path="index" type="number | (() => number)" required> The current index of this item in the sorted list. </ParamField> <ParamField path="group" type="string | (() => string)" optional> The group this sortable belongs to. Used for sorting across multiple lists. </ParamField> <ParamField path="accept" type="string | string[] | (() => string | string[])" optional> The types of draggable elements this sortable accepts. </ParamField> <ParamField path="type" type="string | (() => string)" optional> The type of this sortable element. </ParamField> <ParamField path="plugins" type="PluginDescriptor[] | (() => PluginDescriptor[])" optional> An array of plugin descriptors for per-entity plugin configuration. Use `Plugin.configure()` to create descriptors. For example, `Feedback.configure({ feedback: 'clone' })`. </ParamField> <ParamField path="transition" type="SortableTransition | (() => SortableTransition)" optional> Animation transition configuration for sort operations. </ParamField> <ParamField path="modifiers" type="Modifier[] | (() => Modifier[])" optional> Modifiers to apply to this sortable instance. </ParamField> <ParamField path="sensors" type="Sensor[] | (() => Sensor[])" optional> Sensors to use for this sortable instance. </ParamField> <ParamField path="collisionDetector" type="CollisionDetector | (() => CollisionDetector)" optional> A custom collision detection algorithm. </ParamField> <ParamField path="collisionPriority" type="number | (() => number)" optional> The collision priority of this sortable element. Higher values take precedence when multiple droppable elements overlap. </ParamField> <ParamField path="disabled" type="boolean | (() => boolean)" optional> Whether the sortable is disabled. </ParamField> <ParamField path="data" type="Data | (() => Data)" optional> Custom data to attach to this sortable instance. </ParamField>