import { Component } from '@angular/core';
import { WrDragHandle, WrSortableItem, WrSortableList } from 'ngwr/sortable-list';
@Component({ imports: [WrDragHandle, WrSortableItem, WrSortableList] })
export class MyComponent {}Sortable List
A list the user reorders by drag or keyboard.
Installation
Import the class, and @use the entry point in your global styles: without it the component renders unstyled.
Peer dependencies
Needs @angular/cdk.
pnpm add @angular/cdkBasic usage
Bind [(items)] and write one <wr-sortable-item> per item in your own loop. A row has no padding, border or background: style it yourself.
<wr-sortable-list [(items)]="rows" (reorder)="onReorder($event)">
@for (row of rows(); track row.id; let i = $index) {
<wr-sortable-item>
<div class="row">
<span class="row__index">#{{ i + 1 }}</span>
<span>{{ row.label }}</span>
</div>
</wr-sortable-item>
}
</wr-sortable-list>.row {
display: flex;
align-items: center;
gap: 0.75rem;
padding: 0.75rem 1rem;
border: 1px solid var(--wr-border-base);
border-radius: var(--wr-border-radius-base);
background: var(--wr-color-surface);
}With a drag handle
Put wrDragHandle on one element in the row, and only that element starts a drag.
<wr-sortable-list [(items)]="rows">
@for (row of rows(); track row.id) {
<wr-sortable-item>
<div class="row">
<span wrDragHandle aria-label="Reorder">≡</span>
<span>{{ row.label }}</span>
</div>
</wr-sortable-item>
}
</wr-sortable-list>Keyboard
Every row is a tab stop.
| Name | Description | Type | Default |
|---|---|---|---|
Space / Enter | Pick the focused row up, or drop the one being held. | key | — |
Arrow keys | Move the held row. Follows the reading direction when horizontal. | key | — |
Escape | Put the held row back where it started. | key | — |
API
| Name | Description | Type | Default |
|---|---|---|---|
itemsrequired | Items to render. Two-way — emits the reordered array on drop. | T[] | — |
orientation | Layout direction. Drives CDK's cdkDropListOrientation. | 'vertical' | 'horizontal' | 'vertical' |
disabled | Disable all dragging. | boolean | false |
lockAxis | Locked axis — restrict drag movement to one axis even diagonally. | 'x' | 'y' | undefined | undefined |
dragStartDelay | Delay (ms) before a drag begins after the pointer goes down. The touch delay is the fix for the classic CDK touch snag: without it, the touch-action: none CDK puts on each item blocks scrolling the list on a phone. With a small touch delay, a quick swipe scrolls and a brief hold starts the drag; mouse stays instant. Pass a single number to apply one delay to both pointers. | number | { touch: number; mouse: number } | { touch: 150, mouse: 0 } |
(reorder) | Fired after a successful reorder with the new array + indices. | WrSortableReorderEvent<T> | — |
Related
| Name | Description | Type | Default |
|---|---|---|---|
<wr-sortable-item> | One row. Write one per item in your own loop. | component | — |
[wrDragHandle] | Only this element starts a drag. | directive | — |
CSS variables
Set these on the component's selector or a wrapper, not on :root: the defaults are declared on ngwr/sortable-list's own element.
| Variable | Default | Declared on |
|---|---|---|
--wr-sortable-list-gap | var(--wr-space-sm) | .wr-sortable-list |
--wr-sortable-list-item-font-family | var(--wr-font-family-base) | .wr-sortable-list__item |
--wr-sortable-list-placeholder-radius | var(--wr-border-radius-base) | .wr-sortable-list |
Dependencies
| Angular CDK | drag-drop |
|---|