artisanpack-ui/livewire-drag-and-drop
A Livewire drag-and-drop component from ArtisanPack UI for building sortable lists and moving items between lists without custom JavaScript. It handles reordering and drag events server-side through Livewire, making it easy to add interactive, sortable interfaces to Laravel apps.
data-drag-items drop zones) plus nested contexts with isolated events mean a column-reorder-over-card-reorder board is a configuration exercise, not a subsystem. Sequence the roadmap as: single-list reorder → connected containers with rules → nested kanban with keyboard and i18n.data-drag-disabled / { disabled } and the { accepts: (detail) => boolean } callback let us encode permissions, plan entitlements, WIP limits, and workflow state machines in the interface — locked columns, refusal styling via data-drag-disallowed, and announced cancellations — instead of letting users complete a gesture and then eating a server error.moveId, LivewireDragAndDrop.revert(moveId) / revertItem(itemId) / $dragRevert(itemId) let us commit the move instantly, persist via Livewire, and roll back with a message on rejection. That's the decision "can we afford optimistic UI?" answered yes, with a rollback story.drag:start cancelable, drag:over, drag:drop cancelable with detail.reject(message), drag:cancel with reason, drag:revert) plus the enriched drag:end payload (moveId, fromContext/toContext, fromIndex/toIndex, fromOrderedIds/toOrderedIds) give us adoption analytics ("do users actually reorder?"), audit trails for regulated workflows, and pre-mutation validation hooks.role="button"/role="group" semantics, aria-describedby usage hints, data-drag-label, and fully translatable announcement templates remove the usual "we'll do a11y in v2" commitment from WCAG 2.1 AA, Section 508, and European Accessibility Act conversations.{placeholder} template settable globally via configure({ messages }) or per context via data-drag-messages, so localization ships with the feature rather than after it.data-dragging, data-drag-active, data-drag-over, data-drag-disallowed, body[data-drag-in-progress]) and the --drag-indicator-color property let design tune drag affordances and "you can't drop here" feedback without engineering tickets.Consider it when:
morphed-hook fix specifically targets Livewire 3/4 re-render behavior, and the value proposition collapses outside that stack.Look elsewhere when:
x-drag-context element, not an ancestor, document, or a Livewire #[On] listener), native HTML5 DnD attributes are gone, aria-grabbed is no longer set, and the UMD global is now the plugin function rather than a module namespace. Budget a per-surface regression pass plus a screen-reader check. Counterweight: 2.0's message.processed hook never fired, leaving moved items permanently __livewire_ignore'd, so 2.0 installs should upgrade regardless.Lowest-risk adoption path: one reorderable list on a non-critical screen → connected containers with drop rules → nested kanban with keyboard and localized announcements. Each stage ships independently.
Executives. This is a buy-not-build call. Drag-and-drop ordering looks trivial and isn't: mouse/pen/touch handling, edge auto-scroll, keyboard equivalents, and screen-reader announcements are weeks of fiddly work with a long tail of browser-specific bugs. The package supplies all of it, plus a server-authoritative pattern — optimistic move, revert on rejection — that keeps data correct when the server disagrees. It shortens kanban and reordering roadmap items from a project to a task, and it clears an accessibility gate that recurs in enterprise and public-sector reviews. The cost is a dependency, not a licence; the trade-off is that we self-support it and pin versions. Worth noting for planning: the 2.1.0 upgrade carries a small, well-documented breaking surface, and it fixes a defect in 2.0 that silently blocked server re-renders of moved items — so upgrading is corrective, not just cosmetic.
Engineering. It's an Alpine plugin that registers itself on alpine:init (and can be installed explicitly via Alpine.plugin(...)), hooks Livewire's morphed lifecycle so ordered moves survive re-renders, and preserves the 2.0 directives and drag:end → orderedIds contract. The upgrade is small but not silent: events no longer bubble (listen on the context element), HTML5 draggable attributes are gone, the UMD global's shape changed, and registerDirectives is now the default export. Test plan: re-verify every existing drag surface, run their headless-Chrome browser suite (npm run test:browser) in CI, and check keyboard paths and announcements. Their cancelable drag:drop with detail.reject(message) and revert(moveId) give us clean hooks for validation and error toasts instead of hand-rolled rollback — that's the piece that usually gets written badly and then rewritten.
Design and UX. State attributes and the --drag-indicator-color property let you style drag states without filing engineering tickets, and drop indicators plus data-drag-disallowed styling mean we can visually teach the rules — a locked column, a full WIP limit — instead of failing at submit. Translatable messages mean the microcopy is yours to own, not hard-coded English.
How can I help you explore Laravel packages today?