Drag & Drop
Drag a row by its handle and drop it onto another row to move it (and its whole subtree) under a new parent. Dropping a row into its own descendants is rejected automatically.
Every drag has a keyboard twin (WCAG 2.1.1 / 2.5.7): with a cell focused, Ctrl+↑/Ctrl+↓ move the row among its siblings, Ctrl+→ indents it under the previous sibling and Ctrl+← outdents it to its parent's level. The move runs the same drop path and fires the same reparent event, the focus stays on the row, and a polite live region announces its new level and position.
rowDragging rowReparented
reparenting descendant guard
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { OgeTreeList } from '@oge-ui/tree-list';
import type { OgeTreeRowReparentEvent } from '@oge-ui/tree-list';
@Component({
selector: 'demo-root',
imports: [OgeTreeList],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<oge-tree-list
[data]="org"
keyExpr="id"
parentIdExpr="parentId"
[autoExpandAll]="true"
[rowDragging]="true"
(rowReparented)="onReparent($event)"
/>
`,
})
export class Demo {
readonly org = [
{ id: 1, parentId: null, name: 'Aylin Koç', title: 'CEO', office: 'İstanbul', headcount: 4 },
{ id: 2, parentId: 1, name: 'Baran Ateş', title: 'VP Engineering', office: 'İstanbul', headcount: 2 },
{ id: 3, parentId: 2, name: 'Ceren Aksu', title: 'Team Lead', office: 'İzmir', headcount: 1 },
{ id: 4, parentId: 3, name: 'Deniz Ünal', title: 'Engineer', office: 'İzmir', headcount: 0 },
{ id: 5, parentId: 1, name: 'Elif Barış', title: 'VP Sales', office: 'Ankara', headcount: 0 },
];
protected onReparent(event: OgeTreeRowReparentEvent<unknown>): void {
console.log(event.key, 'moved under', event.toParentKey);
}
}Notes
- Plain-array data is updated in place (the parent field is rewritten); with a DataSource, handle
rowReparentedand persist the move yourself. - The new parent expands automatically so the dropped row stays visible.
- State persistence (
stateKey) also captures the expansion produced by moves.