Svelte — 두 목록 사이 이동
항목을 같은 목록 안에서 재정렬하거나 다른 목록으로 이동합니다. 두 영역은 같은 scope와 group="tasks"를 공유하고 각 areaId는 고유합니다. 항목 ID는 이동 후에도 유지됩니다.
직접 실행
섹션 제목: “직접 실행”항목 왼쪽 손잡이를 잡고 오른쪽 빈 목록에 놓으십시오. 완료 수가 늘어나고 왼쪽 목록에서 해당 항목이 제거됩니다. 초기화는 모든 항목을 원래 순서로 되돌립니다. 이 예제의 이동 조작은 포인터 기반입니다.
<script lang="ts"> import { onDestroy } from 'svelte'; import { createSortableScope, sortable } from 'comins-sortable/svelte'; export let lang = 'ko'; const ko = lang === 'ko'; type Item = { id: string; label: string }; const initial = [{ id: 'plan', label: ko ? '문서 설계' : 'Design the docs' }, { id: 'build', label: ko ? '예제 구현' : 'Build an example' }, { id: 'review', label: ko ? '코드 검토' : 'Review the code' }]; let todo: Item[] = [...initial]; let done: Item[] = []; const scope = createSortableScope<Item>(); onDestroy(() => scope.destroy()); $: todoOptions = { scope, areaId: 'todo', group: 'tasks', items: todo, itemKey: 'id' as const, handle: '.task-handle', onItemsChange: (next: readonly Item[]) => { todo = [...next]; } }; $: doneOptions = { scope, areaId: 'done', group: 'tasks', items: done, itemKey: 'id' as const, handle: '.task-handle', onItemsChange: (next: readonly Item[]) => { done = [...next]; } };</script><div class="demo" data-demo="sortable-svelte"> <div class="demo-toolbar"><span>{ko ? '손잡이를 잡고 다른 목록으로 이동하세요.' : 'Drag a handle into the other list.'}</span><button on:click={() => { todo = [...initial]; done = []; }}>{ko ? '초기화' : 'Reset'}</button></div> <div class="transfer-board"> <section class="transfer-column"> <div class="list-heading">{ko ? '진행 예정' : 'To do'}<span>{todo.length}</span></div> <div class="task-list" aria-label={ko ? '진행 예정' : 'To do'} use:sortable={todoOptions}> {#each todo as item (item.id)}<div class="task" data-task={item.id}><button class="task-handle" aria-label={`${ko ? '드래그' : 'Drag'}: ${item.label}`}>⠿</button><span>{item.label}</span></div>{/each} </div> </section> <section class="transfer-column"> <div class="list-heading">{ko ? '완료' : 'Done'}<span>{done.length}</span></div> <div class="task-list" aria-label={ko ? '완료' : 'Done'} use:sortable={doneOptions}> {#each done as item (item.id)}<div class="task" data-task={item.id}><button class="task-handle" aria-label={`${ko ? '드래그' : 'Drag'}: ${item.label}`}>⠿</button><span>{item.label}</span></div>{/each} </div> </section> </div> <p role="status" class="demo-status">{ko ? '완료' : 'Done'}: {done.length} / 3</p></div>Svelte 상태 계약
섹션 제목: “Svelte 상태 계약”createSortableScope<Item>()로 만든 같은 scope를 두 use:sortable action에 전달합니다. scope를 생략하면 action마다 독립 scope가 생성되어 목록 사이 이동을 공유하지 않습니다. onItemsChange에서 배열을 반영하고 페이지 해제 시 공유 scope를 destroy합니다.
각 핸들의 touch-action: none과 user-select: none은 드래그 중 터치 스크롤·텍스트 선택 충돌을 줄입니다.
검색어
섹션 제목: “검색어”다른 목록으로 이동, 목록 간 이동, 항목 옮기기, 드래그 앤 드롭, 재정렬, 공유 scope, transfer.