Log inGet started
World

Builtin Library

Branchmain
Branchesmainpublish
Commitdd348ac6c3

README.md

dndList

Drag-and-drop reorderable list. Each child renders inside a vbox of two stacked nodes — the original child plus an overlay canvas sized to the row that captures drag and pointer-move events. Built on onDrag

  • onPointerMove canvas interactions; the engine has no dedicated dnd-list arm.

Exports

  • dndList(id: string?, children: { any }?, opts: DndListOpts?) -> WidgetNode — build a drag-reorderable list widget node.

Types:

  • DndListOpts = { rowHeight?, rowWidth?, style?, app?, onReorder?, classes?, barColor?, dragStroke?, label? }

Usage

local dndList = require("@builtin::modules.zui.widget.dndList")

dndList("playlist", {
    Z.lbl("Track 1"),
    Z.lbl("Track 2"),
    Z.lbl("Track 3"),
}, { onReorder = "playlist:reorder" })

-- Then in `onCallback`:
--   data.value = { from = 1, to = 3, value = "1,3" }
-- Caller re-renders with the children rearranged.

Notes

  • Reorder events fire only on drag stop (dragStopped = true) and only when from ≠ to. The payload includes both numeric from / to and a legacy "from,to" string that the engine test suite asserts on.
  • Defaults: rowHeight = 28, rowWidth = 240, barColor = "#78b4ff", dragStroke = "#78b4ff78".
  • Auto-registers <id>:drag:<index> and <id>:hover:<index> handlers on the surrounding Z.app, deduped by id. Drag state lives in app._dndListState[id] and persists across renders.
  • Outside Z.app (no app in scope), the widget renders but the overlay never draws the insertion bar — drag interaction is inert.
  • The outer Panel exposes role = "list" and ariaLabel = opts.label or "Reorderable list" for accessibility.