Skip to main content

SortableList

SortableList

Vertical list reordered by drag handle or keyboard, with announcements

Tags: component list reorder drag

View Demo

SortableList renders a list whose items people can reorder - questions, options, slides, steps. Each item renders its own drag handle by spreading handle on a button. The list never changes items itself; it calls onReorder(from, to).

Import​

<script>
  import { SortableList } from '@classic-homes/theme-svelte';
</script>

Basic Usage​

<script>
  import { SortableList, Icon } from '@classic-homes/theme-svelte';

  let steps = $state([
    { id: 'a', label: 'Frame inspection' },
    { id: 'b', label: 'Drywall' },
    { id: 'c', label: 'Final walk' },
  ]);

  function move(from, to) {
    const [item] = steps.splice(from, 1);
    steps.splice(to, 0, item);
  }
</script>

<SortableList
  items={steps}
  getKey={(s) => s.id}
  getItemLabel={(s) => s.label}
  onReorder={move}
  label="Steps"
  class="space-y-1"
>
  {#snippet item({ item, handle, dragging })}
    <div class="flex items-center gap-2 rounded border p-2" class:shadow-lg={dragging}>
      <button {...handle} class="cursor-grab touch-none"><Icon name="grip" size={14} /></button>
      {item.label}
    </div>
  {/snippet}
</SortableList>

Props​

Prop Type Default Description
items T[] required Items in order (required)
getKey (item, index) => string | number required Stable key (required)
onReorder (from: number, to: number) => void required Move item from to index to (required)
item Snippet<[{ item, index, handle, dragging }]> required Renders one item (required)
label string required Accessible name of the list (required)
getItemLabel (item, index) => string "Item n" Name used in announcements and handle labels
disabled boolean false Turns reordering off
class string - Classes for the ul
itemClass string - Classes for each li

Keyboard Navigation​

  • Space / Enter on a handle - Pick up / drop
  • ArrowUp / ArrowDown - Move the picked-up item
  • Home / End - Move it to the start / end
  • Escape - Cancel and put it back
  • Alt+ArrowUp / Alt+ArrowDown - Move one step without picking up

Accessibility​

  • Handles are buttons named "Reorder {item}" with aria-pressed while picked up and instructions linked by aria-describedby.
  • Every move, drop and cancel is announced in a live region.
  • Pointer capture is taken on the handle only, so clicks elsewhere in the item keep working.
  • Studio - Its outline is a SortableList
On this page