Skip to content

Domma v0.45.0

Choose a tag to compare

@github-actions github-actions released this 27 Sep 17:59
· 305 commits to main since this release

v0.45.0 - Lists That Make Room (2026-09-27)

E.sortable(selector, options) is drag-to-reorder for the children of one container, by mouse,
pen, touch and keyboard. Bind it once to the container: items rendered later are sortable without a
refresh, and every item is identified by a key (data-id by default), so an order can be reported,
saved and put back.

↕️ Two modes

  • Live (the default): the other items slide out of the way while you drag, and the component
    moves the element itself. onSort reports {item, from, to, order, previous}. axis: 'x' sorts
    a row instead of a column.

  • Indicator (nest: true, or live: false): nothing moves until the drop. A marker shows
    where the item would land - before, after, or with nest into another item - and onDrop
    hands you {key, targetKey, zone} to update your data and re-render. The component then
    animates the re-render: every item is matched by its key and glides from where it was to where
    it now is, so a full redraw of a tree still reads as one movement. Return false to refuse a
    drop, or a promise to wait for the server first.

  • accepts(item, target, zone) vetoes a drop - a node dropped into its own subtree, say. A
    refused "into" falls back to the nearer edge before giving up.

📌 An order that sticks

  • persist: 'tasks' saves the keys through Domma storage (sortable:tasks) after every move
    and restores them when the component is created. Items added since keep their place.
    forget() drops the saved order; sort(keys) and restore() put one on screen.

  • animate(mutate) is useful on its own: wrap any change to a keyed list - a filter, a column
    sort, an insert - and it glides instead of jumping.

⌨️ Keyboard, touch and motion

  • Alt+Arrow moves the focused item one place, and each move is announced to screen readers.
    Esc cancels a drag, and in live mode everything slides back.

  • On touch a handle drags at once. An item with no handle needs a short press-and-hold
    (touchDelay, 220 ms), so a list full of draggable items can still be scrolled with a finger.

  • Pointer events rather than the HTML5 drag-and-drop API, which cannot animate its neighbours,
    draws its own ghost and does not exist on touch screens at all.

  • prefers-reduced-motion skips every glide. The ghost, the empty slot and the drop marker are
    themed through --dm-sortable-* custom properties with theme tokens as their fallbacks.

🧭 Where it is already used

  • The Domma CMS menu editor now uses E.sortable() for reordering and nesting menu items.

  • Docs in docs/Sortable.md, and a showcase page with a tutorial and four live demos: a list
    that remembers its order, a horizontal row, a tree that re-renders from data, and a list
    dragged by its handles.