Skip to content

feat(list): drag and drop reordering (#DS-4454) - #1911

Draft
lskramarov wants to merge 2 commits into
mainfrom
feat/DS-4454
Draft

feat(list): drag and drop reordering (#DS-4454)#1911
lskramarov wants to merge 2 commits into
mainfrom
feat/DS-4454

Conversation

@lskramarov

Copy link
Copy Markdown
Contributor

Options of kbq-list-selection can be reordered by dragging or with Alt + arrow keys once draggable is set, and moved between lists connected via connectedTo.

The list never mutates the projected data: it reports the move through the dropped event and the consumer applies it. The new position is announced to assistive tech only once that move has actually been applied, and aria-keyshortcuts advertises the keyboard alternative to dragging.

Dragging inside kbq-optgroup or cdk-virtual-scroll-viewport reports indices that do not address the backing array, so both now warn in development mode.

Options of `kbq-list-selection` can be reordered by dragging or with `Alt` + arrow
keys once `draggable` is set, and moved between lists connected via `connectedTo`.

The list never mutates the projected data: it reports the move through the
`dropped` event and the consumer applies it. The new position is announced to
assistive tech only once that move has actually been applied, and
`aria-keyshortcuts` advertises the keyboard alternative to dragging.

Dragging inside `kbq-optgroup` or `cdk-virtual-scroll-viewport` reports indices
that do not address the backing array, so both now warn in development mode.
@lskramarov lskramarov self-assigned this Aug 17, 2026
Copilot AI lite review requested due to automatic review settings August 17, 2026 18:33
@lskramarov lskramarov added the enhancement New feature or request label Aug 17, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds opt-in drag-and-drop (and keyboard) reordering/transfer for kbq-list-selection, including accessible announcements and documentation/examples, while keeping the list “data-immutable” (consumer applies reorders based on a dropped event).

Changes:

  • Introduces draggable, connectedTo, and dropped on KbqListSelection, plus keyboard reordering/transfer via Alt + arrow keys and live-region announcements.
  • Adds styling for drag preview/placeholder/animations and updates a11y locale strings to support move announcements.
  • Adds docs examples, dev-app demos, and unit/e2e coverage for drag/drop + keyboard flows.

Reviewed changes

Copilot reviewed 23 out of 23 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
tools/public_api_guard/components/list.api.md Public API snapshot updated for new list drag/drop inputs/outputs and types.
tools/public_api_guard/components/core.api.md Public API snapshot updated for new a11y locale key (listOptionMoved).
packages/e2e/routes.ts Registers new list drag-and-drop E2E route/component.
packages/docs-examples/example-module.ts Adds new live examples entries for draggable list variants.
packages/docs-examples/components/list/list-draggable/list-draggable-example.ts New docs example: in-list reordering via dropped.
packages/docs-examples/components/list/list-draggable-connected/list-draggable-connected-example.ts New docs example: transferring options between connected lists.
packages/docs-examples/components/list/index.ts Exports and registers the new list draggable examples module-side.
packages/components/list/list.scss Adds drag/drop interaction styling (placeholder, preview, cursor, transitions).
packages/components/list/list.ru.md Documents draggable lists + keyboard shortcuts (RU).
packages/components/list/list.en.md Documents draggable lists + keyboard shortcuts (EN).
packages/components/list/list-tokens.scss Adds tokens for drag preview surface/shadow; ensures preview inherits tokens in <body>.
packages/components/list/list-selection.component.ts Core implementation: CDK drag/drop wiring, keyboard move/transfer, dropped event, live-region announcements, dev warnings.
packages/components/list/list-selection.component.spec.ts Unit + axe coverage for drag/drop opt-in, keyboard behavior, announcements, and shortcuts.
packages/components/list/e2e.ts Adds E2E fixture component with two connected draggable lists and consumer-applied reorder/transfer.
packages/components/list/e2e.playwright-spec.ts Adds Playwright coverage for pointer drag, keyboard reorder/transfer, and transition settling behavior.
packages/components/core/locales/types.ts Extends KbqA11yLocaleConfiguration with listOptionMoved announcement template.
packages/components/core/locales/tk-TM.ts Adds listOptionMoved locale string (tk-TM).
packages/components/core/locales/ru-RU.ts Adds listOptionMoved locale string (ru-RU).
packages/components/core/locales/pt-BR.ts Adds listOptionMoved locale string (pt-BR).
packages/components/core/locales/es-LA.ts Adds listOptionMoved locale string (es-LA).
packages/components/core/locales/en-US.ts Adds listOptionMoved locale string (en-US).
packages/components-dev/list/template.html Adds dev-app demos for draggable reorder and connected transfer.
packages/components-dev/list/module.ts Wires demo data + handlers for the new draggable behaviors in dev app.
Suppressed comments (1)

packages/components/list/list-selection.component.ts:814

  • To ensure unsupported-container warnings are emitted when draggable becomes enabled after initial render (e.g. dynamic bindings), call warnOnUnsupportedDragContainer() from syncDraggableState(), which already runs when draggable/disabled change.
    /** Keeps the underlying CDK directives in sync with the resolved `draggable` state. */
    private syncDraggableState(): void {
        this.dropList.disabled = !this.draggable;
        this.options?.forEach((option) => option.syncDraggableState());
        this.changeDetectorRef.markForCheck();
    }

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +115 to +121
/**
* Data attached to the underlying `CdkDrag` while a list option is being dragged.
*
* @docs-private
*/
export type KbqListOptionDragData = { option: KbqListOption };

Comment on lines +787 to +790
private warnOnUnsupportedDragContainer(): void {
if (!isDevMode() || !this.draggable) {
return;
}
@github-actions

github-actions Bot commented Aug 17, 2026

Copy link
Copy Markdown

Visit the preview URL for this PR (updated for commit e6fbf46):

https://koobiq-next--prs-1911-o55jwo31.web.app

(expires Fri, 21 Aug 2026 10:22:02 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: c9e37e518febda70d0317d07e8ceb35ac43c534c

@lskramarov
lskramarov marked this pull request as draft August 18, 2026 08:19
`KbqListOptionDragData` is only read inside the component file, so it no longer
leaves the package and no longer widens the public API surface.

`warnOnUnsupportedDragContainer()` now also runs from `syncDraggableState()`, so
enabling `draggable` after the initial render still warns. It tolerates being
called before the content children exist and reports each list only once.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants