Sortable
`<pura-sortable>` is the drag-to-reorder list. Wrap a semantic `<ul>`/`<ol>` (or put items directly inside the host): grab an item with the pointer and the siblings open space with a FLIP tween at every index swap, the same WAAPI engine behind `pura-auto-animate`. On drop the item snaps into its slot and the component emits a bubbling `change` event with `{ item, from, to, order }`, where `order` is the list of item keys (`data-id`, `id`, or a stable generated key). Where `pura-kanban` covers a board with columns, this is the simple flat list. `axis="x"` makes a horizontal strip, `handle` restricts the grab zone to a selector inside each item, and the lift look is themable via `--pura-sortable-drag-scale`, `--pura-sortable-drag-shadow`, and `--pura-sortable-drag-z`. Keyboard: items are focusable, Space/Enter lifts, arrows move, Space/Enter drops and emits, Escape restores. SSR and no-JS render the plain static list; reduced motion reorders instantly with no tween. Each instance registers in `window.__puraSortables` by `data-pura-id` with `{ order(), move(from, to) }` and mirrors live state in `data-pura-sortable-*` attributes.
Preview
<!-- vertical to-do list; listen for the new order -->
<pura-sortable id="todo">
<ul>
<li data-id="a">First task</li>
<li data-id="b">Second task</li>
<li data-id="c">Third task</li>
</ul>
</pura-sortable>
<script>
document.querySelector('#todo').addEventListener('change', (e) => {
console.log(e.detail.order); // e.g. ["b", "a", "c"]
});
</script>
<!-- horizontal strip, drag only by the handle -->
<pura-sortable axis="x" handle=".grip">
<ul style="display: flex; gap: 12px;">
<li data-id="one"><span class="grip">::</span> One</li>
<li data-id="two"><span class="grip">::</span> Two</li>
<li data-id="three"><span class="grip">::</span> Three</li>
</ul>
</pura-sortable> Attributes
| Attribute | Type | Default | Description |
|---|---|---|---|
axis | "y" | "x" | y | Drag direction. y for vertical lists (ArrowUp/Down), x for horizontal strips (ArrowLeft/Right). |
handle | string | — | CSS selector inside each item that starts the drag. Empty: the whole item is draggable. |
disabled | boolean | false | Disables pointer dragging and keyboard reordering. |
duration | number | token --pura-duration-4 | FLIP and drop-snap duration in milliseconds. Overrides the token-derived default. |
Installation
pura is copy-paste and dependency-free. Load the whole library, or just this component.
<link rel="stylesheet" href="/pura/tokens.css">
<script type="module" src="/pura/lib/sortable.js"></script> import "./pura/lib/sortable.js";