Skip to content

[listbox] Add sorting providers using the drag engine - #3

Open
flaviendelangle wants to merge 25 commits into
listbox-drag-engine-basefrom
listbox-base-ui-dnd
Open

flaviendelangle wants to merge 25 commits into
listbox-drag-engine-basefrom
listbox-base-ui-dnd

Conversation

@flaviendelangle

@flaviendelangle flaviendelangle commented Aug 14, 2026

Copy link
Copy Markdown
Owner

This builds on Michal's original Listbox PR, replacing its Pragmatic DnD integration with the Base UI drag engine and aligning sorting and external-drop APIs with Tree.

The PR targets listbox-drag-engine-base, which combines the Listbox and drag-engine parent branches. Their unrelated changes are excluded from this diff.

Changes compared with the original Listbox implementation:

  • Replace DragAndDropProvider with KeyboardSortableProvider for keyboard-only sorting and SortableProvider for keyboard and pointer sorting. Ordinary items and keyboard-only sorting do not import the pointer drag implementation. Remove the Pragmatic DnD dependencies and Listbox-specific registration hook.
  • Replace the moved-items/reference-item/edge reorder event with onItemsReorder(values, eventDetails). It proposes the complete order, supports cancellation, reports keyboard or drag reasons, and includes group membership in eventDetails.order. Applications accept a move by rendering the proposed order; focus and announcements follow the accepted update.
  • Use canMoveItems and isItemSortingDisabled for shared keyboard and pointer restrictions. Sorting can be disabled without disabling selection. Movement metadata exposes item IDs, values, indices, and group IDs; disabled state stays internal.
  • Add reorderOn="move" alongside the default drop-time reordering. Cancellation restores the previous order when it does not conflict with external reorders, while preserving item edits, deletions, and newly inserted items. Transaction helpers handle deferred updates, unmounting, and conflicting external reorders. Accepted external drops restore any live sorting preview before the application performs the transfer.
  • Add ItemExternalDropTarget, a complete option that accepts incoming drags and retains selection and keyboard behavior. Each row has one drop-target registration: same-list drags belong to sorting, and incoming drags use the explicit target. accept, canDrop, dropDisabled, getDropPosition, and onDraggableDrop control acceptance and insertion. Native onDrop remains available for HTML drag-and-drop events. Disabled sorting targets reject ancestor fallback through the common sorting adapter.
  • Support outgoing and cross-list drags through an explicit provider kind. Payloads contain picked-up item values, item IDs, collection identity, and application data from getDragPayload. Sorting and external-drop callbacks both expose a DragSource through source, with application payloads under source.payload. Transfers remain application-owned.
  • Replace ItemDragHandle with SortHandle, add SortPreview, and expose Item.draggableProps for activation, modifiers, and drag callbacks. Custom placement uses normalized row coordinates and supports horizontal layouts and RTL. onDropPositionChange exposes placement updates; onSortEnd reports the final pointer outcome.
  • Distinguish all items participating in a drag (data-moving) from the physically picked-up item (data-dragging). Replace data-drop-target and data-drop-target-edge with data-drag-over and logical data-drop-position="before" | "after" states, shared by sorting and external drops.
  • Support explicit group IDs and group-aware reorder proposals. Destination indices remain relative to the entire Listbox, including groups; Tree indices are parent-relative. Use stable per-item sorting IDs independently of application values and mutable positions.
  • Add configurable completion announcements through getAnnouncement. Preserve nested controls' keyboard behavior and let handled sorting shortcuts bubble with their default prevented. Keep nested Listbox sorting contexts isolated and preserve selection and focus through reorders.
  • Add keyboard-sorting, live-reordering, cross-list transfer, and library/archive demos in CSS Modules and Tailwind. Update existing sorting demos, fix dark mode across all ten demos, and document the APIs and transfer responsibilities.
  • Add regression coverage for controlled and deferred updates, selected-item moves, groups, cancellation, external targets, callback types, and keyboard event ownership, plus Chromium interaction tests for both styling variants of the transfer demos.

Validation: focused Listbox/shared-target/demo Chromium tests pass, along with the corresponding jsdom checks, TypeScript, formatting, stylelint, and generated API documentation. ESLint passes with the pre-existing local docs/CLAUDE.md issue excluded.

@flaviendelangle
flaviendelangle deleted the branch listbox-drag-engine-base August 19, 2026 09:59
@flaviendelangle
flaviendelangle deleted the listbox-base-ui-dnd branch August 19, 2026 10:04
@flaviendelangle
flaviendelangle restored the listbox-base-ui-dnd branch August 20, 2026 07:01
@flaviendelangle flaviendelangle changed the title [listbox] Use Base UI drag engine [listbox] Add sorting providers using the drag engine Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant