Data Display

SortableList

Keyboard-and-pointer reorderable list that emits onReorder when the user drags or arrow-keys an item into a new position with announcer feedback.

import { SortableList } from '@lostgradient/cinder/sortable-list';
data-displayreorder
01

Overview

Drag-and-drop reorderable list that emits the new order on each change.

Usage

svelte
<script lang="ts">
  import SortableList from '@lostgradient/cinder/sortable-list';
  import type { SortableListProps } from '@lostgradient/cinder/sortable-list';

  type Task = { id: string; label: string };

  let items = $state<Task[]>([
    { id: 'task-1', label: 'Write release notes' },
    { id: 'task-2', label: 'Review pull requests' },
    { id: 'task-3', label: 'Update dependencies' },
    { id: 'task-4', label: 'Deploy to staging' },
  ]);

  function getKey(item: Task): string {
    return item.id;
  }

  function getItemLabel(item: Task, _originalIndex: number): string {
    return item.label;
  }

  // `onReorder` receives the reordered items AND a `change` descriptor (from/to
  // indices, moved key). This example only needs the new order, but the full
  // signature is shown so the canonical call shape is accurate.
  const handleReorder: SortableListProps<Task>['onReorder'] = (nextItems, _change) => {
    items = nextItems;
  };
</script>

<SortableList {items} {getKey} {getItemLabel} onReorder={handleReorder} label="Task priority">
  {#snippet children(item, _context)}
    <span style="padding: 0.5rem 0.75rem; display: block;">{item.label}</span>
  {/snippet}
</SortableList>
Live preview
02

When to use

Use when
  • Letting users manually reorder a small to medium list of items via drag handle or keyboard.
  • Surfacing live region announcements during a reorder for accessible feedback.
Avoid when
  • Showing a read-only list with no reorder affordance — use grid-list instead.
  • Sorting by a column or computed key — sort the source array and rerender.
03

Examples

Basic sortable list

Keyboard and pointer reorderable list with announcer feedback.

04

Props

Props for sortable-list
NameTypeDefaultDescription
items required Item[] The list of items to render.
getKey required (item: Item) => stringnumber Returns a stable key for each item. Must not change across reorders.
getItemLabel required (item: Item, originalIndex: number) => string Returns an accessible label for each item (e.g., "Buy milk"). The second argument is the item's original index in the items array (not its current visual position during a drag). Used in handle aria-label and announcements.
formatHandleLabel (itemLabel: string) => string Optional formatter for the drag handle's accessible name. Default: "Reorder {itemLabel}".
handle snippet Optional snippet rendered inside the drag-handle button. Receives { pressed, label }.
onReorder required (nextItems: Item[], change: import('../../utilities/sortable-controller.types.ts').SortableReorderChange, ) => void Fires with the full reordered array and change metadata on drop.
announcements Partial<import('../../utilities/sortable-controller.types.ts').SortableAnnouncements > Optional overrides for announcement strings.
children required snippet Row content snippet. Receives the item and a per-row context.
label text Accessible name for the list (applied as aria-label on the list root).