SnapSort
Versatile and Extensible
A wide variety of core components are available out of the box to provide building blocks for any type of drag and drop UI.
Get started
npm install @snap-engine/snapsort @snap-engine/asset-base <script lang="ts">
import { Engine } from "@snap-engine/asset-base/svelte";
import { Container, Ghost, Item } from "@snap-engine/snapsort/svelte";
import {
createRenderEntries,
createRenderTree,
reduceRenderTree,
type ContainerCallbacks,
type GhostLifecycleEvent,
type ItemMoveEvent,
} from "@snap-engine/snapsort";
let tasks = $state.raw(
createRenderTree(createRenderEntries([
{ id: "design", label: "Design" },
{ id: "build", label: "Build" },
{ id: "ship", label: "Ship" },
], (task) => task.id)),
);
function onItemMove(event: ItemMoveEvent) {
tasks = reduceRenderTree(tasks, event);
}
function onGhostMove(event: GhostLifecycleEvent) {
tasks = reduceRenderTree(tasks, event);
}
const callbacks = {
onItemMove,
onGhostInsert: onGhostMove,
onGhostMove,
onGhostRemove: onGhostMove,
} satisfies ContainerCallbacks;
</script>
<Engine id="quick-start">
<Container
itemId="quick-start-root"
config={{ callbacks }}
>
{#each tasks.entries as entry (entry.itemId)}
{#if entry.isGhost}
<Ghost ghost={entry.ghost} />
{:else}
<Item itemId={entry.itemId}>{entry.value.label}</Item>
{/if}
{/each}
</Container>
</Engine>