LayoutExtension

Sortable

A list that people reorder by dragging a grip handle or with the keyboard, with each move announced to screen readers.

Class nameTypeDescription
sortableplf:sortableComponentThe reorderable list
sortable-itemplf:sortable-itemPartAn item in the list
sortable-handleplf:sortable-handlePartThe grip button that starts a move
sortable-iconplf:sortable-iconPartYour own SVG, in place of the drawn grip; an icon class there doesn't need it
sortable-nameplf:sortable-namePartThe item's text
sortable-metaplf:sortable-metaPartSecondary details at the end
sortable-mediaplf:sortable-mediaPartA media item's square image
sortable-item-mediaplf:sortable-item-mediaModifierAn item with an image above its name

Default

Name the list with aria-label or aria-labelledby. Each item’s button is its handle, the only place a move starts: name it after the item, such as “Reorder Item one”.

  • Item one Today
  • Item two Tomorrow
  • Item three Friday
  • One
  • Two
  • Three
  • Four

Grid

Keep draggable="false" on each image, or Firefox drags the picture instead of moving the item.

  1. Desert dunes Photo one
  2. A garden in bloom Photo two
  3. An event venue Photo three

Saving the order

Sortable moves the real items, so their hidden inputs submit in the new order; to save after every move, read event.detail.order in plf:sortable:change.

  1. Step one
  2. Step two
  3. Step three

JavaScript

Sortable needs JavaScript and is an extension: the Full script and Full CSS leave it out. The Full script (pelatform-ui.min.js) and the extension scripts after it start every component on page load, with no code of your own; with Core and single files, the last line starts them. For markup you add later, see Dynamic content.

<link rel="stylesheet" href="pelatform-ui.min.css">
<link rel="stylesheet" href="extensions/sortable.min.css">
<script src="pelatform-ui.min.js" defer></script>
<script src="extensions/sortable.min.js" defer></script>
<link rel="stylesheet" href="pelatform-ui.prefixed.min.css">
<link rel="stylesheet" href="extensions/sortable.prefixed.min.css">
<script src="pelatform-ui.min.js" defer></script>
<script src="extensions/sortable.min.js" defer></script>

Items are read once, so after adding or removing items call PLF.destroy(list), then PLF.init(list). With ESM imports, import Sortable from @pelatform/ui/extensions/sortable and call use(Sortable) before init().

Hooks

Attribute Purpose
data-plf-sortable The named <ul> or <ol>
data-plf-value Each item’s unique value, reported by getState() and events
data-plf-sortable-handle Optional; marks the handle in an item that holds more than one button. A disabled handle cannot start a move
data-plf-sortable-name Optional; the text announcements use instead of the whole item
data-plf-orientation vertical (default), horizontal (one row that scrolls sideways) or grid
data-plf-instructions, data-plf-grabbed-message, data-plf-moved-message, data-plf-dropped-message, data-plf-cancelled-message On the list, translated messages, English by default; {item}, {position} and {count} are replaced

The script adds hidden instructions to each handle’s aria-describedby and a role="status" region (data-plf-part="sortable-status") after the list.

Methods

Method Behavior
PLF.Sortable.getOrCreateInstance(list) Returns the instance, creating it for valid markup
PLF.Sortable.getInstance(list) Returns the instance or null
instance.getState() Returns {order, active}: the values in order, and the item being moved or null
instance.move(item, index) Moves an item, or the item with that value, to a zero-based index. Returns false when canceled, unchanged, invalid or during another move
instance.destroy() Cancels an active move and removes listeners, the instructions and the live region; the order stays
Event When
plf:sortable:before-change After a drop or move(); cancelable, which puts the item back
plf:sortable:change After the new order is kept

Each event’s detail:

Property Value
instance The Sortable instance
item The moved item
from The item’s zero-based index before the move
to The item’s zero-based index after the move
order The values in the new order
reason pointer, keyboard or api
trigger The item’s handle, or null from move()
Key Action
Space, Enter On a handle, picks the item up; pressed again, drops it
Up Arrow, Down Arrow Move the item one place, or one row in a grid
Left Arrow, Right Arrow In a horizontal list or grid, move the item one place; reversed right to left
Home, End Move the item to the first or last place
Escape, Tab Cancel the move and return the item
Variable Default
--plf-sortable-gap --plf-space-2, 0.5rem (8px)
--plf-sortable-columns 3, in a grid
--plf-sortable-bg Surface
--plf-sortable-border --plf-color-border-subtle
--plf-sortable-radius --plf-radius-lg, 0.5rem (8px)
--plf-sortable-grabbed-bg --plf-color-primary-subtle, on an item picked up from the keyboard

Built with Pelatform UIv0.1.0

Components

Getting started

Foundations

Components

Actions

Data display

Navigation

Feedback

Data input

Layout

Advanced

Integrations

Blocks

Application

Authentication

Icons