Let's build a draggable list with smooth animations.
Complete Example
svelte<script> import { flip } from 'svelte/animate'; import { fade } from 'svelte/transition'; let items = $state([ { id: 1, name: 'Learn Svelte' }, { id: 2, name: 'Build an app' }, { id: 3, name: 'Deploy to production' } ]); let draggingId = $state(null); function dragStart(event, id) { draggingId = id; event.dataTransfer.effectAllowed = 'move'; } function dragOver(event, targetId) { event.preventDefault(); if (draggingId === targetId) return; const dragIndex = items.findIndex(i => i.id === draggingId); const targetIndex = items.findIndex(i => i.id === targetId); // Reorder array const newItems = [...items]; const [removed] = newItems.splice(dragIndex, 1); newItems.splice(targetIndex, 0, removed); items = newItems; } function dragEnd() { draggingId = null; } function removeItem(id) { items = items.filter(i => i.id !== id); } </script> <ul class="sortable"> {#each items as item (item.id)} <li animate:flip={{ duration: 200 }} out:fade={{ duration: 150 }} draggable="true" class:dragging={draggingId === item.id} ondragstart={(e) => dragStart(e, item.id)} ondragover={(e) => dragOver(e, item.id)} ondragend={dragEnd} > <span class="handle">☰</span> <span class="text">{item.name}</span> <button onclick={() => removeItem(item.id)}>×</button> </li> {/each} </ul> <style> .sortable { list-style: none; padding: 0; } li { display: flex; align-items: center; padding: 12px; background: white; border: 1px solid #ddd; margin: 4px 0; cursor: grab; } li.dragging { opacity: 0.5; } .handle { margin-right: 12px; color: #999; } .text { flex: 1; } </style>
Key Techniques
- animate:flip - Smoothly moves items to new positions
- out:fade - Animates removed items
- draggable="true" - Native HTML5 drag and drop
- Keys - Essential for tracking items