Angular Sortable-список и Drag & Drop | ng-hub-ui-sortable
Sortable-список и утилиты drag-and-drop для Angular для массивов, интеграции с FormArray, рабочих процессов на Signals и связанных списков.
Последнее обновление 16 сент. 2026 г.
Обзор
Почему команды ищут эту библиотеку
Выбирайте эту библиотеку sortable для Angular, когда нужна сортировка drag and drop, работающая с массивами, реактивными формами, Signals и сложными конструкторами интерфейсов.
Установка
npm install ng-hub-ui-sortableПерейти к
Идеально для
- упорядочивание задач
- редакторы на FormArray
- конструкторы компоновки
- управление приоритетами
О библиотеке sortable
ng-hub-ui-sortable помогает командам Angular естественным образом переупорядочивать данные в продуктах, где важен порядок: задачи, приоритеты, конструкторы компоновки или динамические блоки форм. Он особенно полезен, когда нужен drag and drop без потери контроля над обновлениями состояния.
Руководства по возможностям
Основное использование
Базовые сценарии использования для sortable-списков.
Примеры:
Простой массив
Изменение порядка простых массивов.
Sortable - Simple Arrays
Make any array sortable with a single directive. Every layout below shares the same model, so each drag updates them all.
Button groups
Cards
Navigation
Current model
[
"Ankara",
"Moscow",
"Munich",
"Paris",
"Washington"
]Код
Signals
Привязка sortable-данных к изменяемым signals Angular.
Sortable - Signals
Bind a writable signal as the sortable model. Reordering updates the signal value instantly, keeping reactive state in sync.
- Angular
v18 - React
v19 - Vue
v3 - Svelte
v5
Current signal value:
[
"Angular",
"React",
"Vue",
"Svelte"
]Код
Интеграция с формами
Использование sortable с реактивными формами Angular.
Примеры:
Интеграция с FormArray
Изменение порядка контролов FormArray с помощью drag and drop.
Sortable - Reactive FormArray
Bind directly to a reactive FormArray. Edit the inputs and drag to reorder — the form value always reflects the current order.
Current FormArray value:
[
"Ankara",
"Moscow",
"Munich",
"Paris",
"Washington"
]Код
Расширенная настройка
Настройка поведения и взаимодействий SortableJS.
Примеры:
Пользовательские опции
Настройка handles, фильтров, анимации и событий.
Sortable - Options
Pass any SortableJS options through the directive: filter non-draggable items, hook into events and tune autoscroll.
Filtered (disabled) items
- Element 1
- Element 2
- Element 3
- Element 4
- Element 5
[
"1",
"2",
"3",
"4",
"5"
]Events
- Element 1
- Element 2
- Element 3
- Element 4
- Element 5
Autoscroll
Drag near the edges of the list to trigger autoscroll.
- Element 1
- Element 2
- Element 3
- Element 4
- Element 5
- Element 6
- Element 7
- Element 8
- Element 9
- Element 10
- Element 11
- Element 12
- Element 13
- Element 14
- Element 15
- Element 16
- Element 17
- Element 18
- Element 19
- Element 20
- Element 21
- Element 22
- Element 23
- Element 24
- Element 25
- Element 26
- Element 27
- Element 28
- Element 29
- Element 30
Код
Несколько списков
Связывание списков, клонирование элементов и управление правилами переноса.
Sortable - Multiple Lists
Connect lists with the group option to transfer items across containers. Build kanban boards, clone factories and constrained drop targets.
Transfer between lists
- Element 1
- Element 2
- Element 3
- Element 4
- Element 5
[
"1",
"2",
"3",
"4",
"5"
]- Element 6
- Element 7
- Element 8
- Element 9
- Element 10
[
"6",
"7",
"8",
"9",
"10"
]Clone items
List 1 is a clone factory; list 2 is its target.
- Element 1
- Element 2
- Element 3
- Element 4
- Element 5
- Element 6
- Element 7
- Element 8
- Element 9
- Element 10
Constrained groups
- Element 1
- Element 2
- Element 3
- Element 4
- Element 5
- Element 6
- Element 7
- Element 8
- Element 9
- Element 10
- Element 11
- Element 12
- Element 13
Код
Конструктор раскладки
Вложенные sortable-контейнеры с tabs и виджетами.
Sortable - Layout Builder
Build hierarchical, nested drag-and-drop layouts with grouped containers for generics, tabs and widgets.
Build advanced visual layout builders with nested drag and drop in Angular. This powerful example demonstrates nested sortable lists with drag handles and component slots, perfect for creating page builders and dashboard designers.
Create hierarchical structures with drag-and-drop functionality—ideal for layout builders, dashboard organizers, and visual editors. Supports multi-level nesting with full control over handles and constraints.
Demo: Generic, Tabs & Widgets
No events yet.
Код
Ручной режим
Отключите автоматические обновления с помощью `autoUpdateArray=false` и применяйте изменения самостоятельно с помощью помощников `moveItemInArray`, `transferArrayItem` и `copyArrayItem`.
Sortable - Manual Mode
Disable automatic array updates and apply each reorder yourself with the moveItemInArray and transferArrayItem helpers.
Manual Control Mode
This example demonstrates manual array control by setting [autoUpdateArray]="false". This gives you complete control over when and how arrays are updated, similar to Angular CDK's approach.
Benefits: Perform validation, make API calls, implement undo/redo, or use immutable patterns before updating your data.
Single List - Manual Reordering
Drag and drop tasks to reorder them. Notice how we manually update the array using the moveItemInArray helper function.
- Design UI mockups
- Implement authentication
- Write unit tests
- Deploy to production
Current State:
[
{
"id": 1,
"title": "Design UI mockups",
"completed": false
},
{
"id": 2,
"title": "Implement authentication",
"completed": false
},
{
"id": 3,
"title": "Write unit tests",
"completed": false
},
{
"id": 4,
"title": "Deploy to production",
"completed": false
}
]Multiple Lists - Kanban Board Style
Drag tasks between different status columns. The transferArrayItem helper makes it easy to move items between arrays while maintaining full control.
- Review pull requestsPriority: high
- Update documentationPriority: medium
- Refactor legacy codePriority: low
- Fix bug #123Priority: high
- Add new featurePriority: medium
- Initial setupPriority: high
Operations Log
No operations yet. Start dragging items to see the log!
Code Example
import { moveItemInArray, transferArrayItem } from 'ng-hub-ui-sortable';
onTasksUpdate(event: SortableEvent): void {
// Manually update the array with full control
moveItemInArray(this.tasks, event.oldIndex, event.newIndex);
// You can add validation, API calls, etc. here
console.log('Task reordered!');
}
onListAdd(event: SortableEvent, targetList: any[], listName: string): void {
const sourceList = this.getListByElement(event.from);
// Transfer item between arrays
transferArrayItem(sourceList, targetList, event.oldIndex, event.newIndex);
// Perfect place for API calls to persist the change
this.apiService.updateTaskStatus(item.id, listName);
}Why Use Manual Control?
Validation
Validate changes before updating your data model. Prevent invalid operations or apply business rules.
API Integration
Make API calls to persist changes immediately. Handle success/error responses appropriately.
Undo/Redo
Implement undo/redo functionality by maintaining operation history before committing changes.
Immutability
Use immutable data patterns with OnPush change detection for optimal performance.
Код
Ключевые возможности
Последние изменения
Version 22.2.1 - 9/16/26, 12:00 AM
changed: Repository, issue and README links follow the move to the hub-env organization. Issues for every Hub UI package are now gathered in hub-env/hub-ui, and the repository and bugs fields of the manifest point at the new addresses. No code, types or styles change.
fixed: The migration guide and both READMEs placed the point where ngx-sortablejs stops compiling at Angular 13. Angular kept converting View Engine libraries with ngcc up to v15, so the real limit is Angular 16, and the guide now opens with the two paths: the maintained @worktile/ngx-sortablejs fork, or this package.
Version 22.2.0 - 9/8/26, 12:00 AM
added: The list can be reordered from the keyboard. SortableJS binds mousedown and touchstart and nothing else, so until now hubSortable simply did not work for anyone who does not drag. Each item, or its handle when one is configured, is now a tab stop, and from there the interaction is the grab / move / drop model of the WAI-ARIA authoring practices: Enter or Space picks the item up, the arrows move it, Home and End send it to either end, Enter or Space drops it and Escape puts it back. Every step is announced through a polite live region. Reordering this way obeys the same rules a drag does: off while disabled is true or sort is false, honouring autoUpdateArray, and emitting the same update and sortEvent with both indexes filled in.
added: keyboardSorting turns that path off for an application that already ships its own, and keyboardMessages translates what is announced. The sentences are functions rather than templates with placeholders, so a language whose word order differs is not forced through an English shape.
added: SortableBindings and SortableBinding are exported. SortableBindings keeps several parallel arrays in step through one drag, and [hubSortable] has always accepted an instance in place of an array, but it was never listed in public-api.ts: nobody outside the package could construct one or type a field holding one. Both READMEs gained the connected-lists section that explains what to do with it.
changed: BREAKING. SortableData is a list type instead of any. It was written any | any[] | WritableSignal<any[]>, and a union containing any is any, so the published type accepted a number, a string or a plain object without a word from the compiler. It is now T[] | WritableSignal<T[]> | SortableFormArrayLike<T>, with T defaulting to unknown. Nothing changes at runtime; see BREAKING_CHANGES.md for what stops compiling and what to write instead.
Version 22.1.4 - 9/6/26, 12:00 AM
changed: The library no longer writes into the consuming application's console. Eight guard rails, the out-of-range check in moveItemInArray, the three in transferArrayItem, the three in copyArrayItem and the directive's container lookup, used to report invalid input with console.warn or console.error. A dependency has no standing to put noise in an application's console, least of all in a production build, and the message was addressed to whoever wrote the call rather than to whoever runs the app. Every guard keeps the behaviour it always had: the call is a no-op and the arrays are left untouched. A container selector that matches nothing likewise leaves the directive inert, now without a message, so audit those selectors (see MIGRATION.md, 5.6) instead of waiting for the console to point at them.
fixed: The directive's JSDoc examples teach the @for block rather than *ngFor. Those snippets ship in the published typings, so they are what a consumer's editor shows on hover over hubSortable, and they contradicted the README's Quick Start, leaving the reader to work out which surface of the same library to believe. Each @for sits on the line that opens the host element on purpose, because TypeScript reads a line-initial @for inside a JSDoc comment as a tag and splits the example in two.
Version 22.1.3 - 9/1/26, 12:00 AM
changed: The homepage in the manifest points at this library's own documentation page rather than at the site root, and eleven keywords were added covering the vocabulary someone actually searches with when they do not already know this package's name: dnd, drag-drop, reorder, reorderable, sortable-list, list, formarray, component, reusable, ui-library. Metadata only — no code, no types, no styles change, and nothing a consumer imports is affected.
Version 22.1.2 - 8/8/26, 12:00 AM
fixed: Documentation links now point at the canonical localized URLs. The README linked to https://hubui.dev/<path> with no locale prefix and no trailing slash, and both forms are 301-redirected, so every reader arriving from npm or GitHub landed on a redirect instead of the canonical page.
Version 22.1.1 - 7/28/26, 12:00 AM
added: Documented the pointer-only accessibility limitation of SortableJS drag-and-drop and the recommended keyboard alternative (move up/down controls on the same array).
Version 22.1.0 - 6/29/26, 12:00 AM
added: `provideSortable()` standalone provider function to register global SortableJS options without `SortableModule`.
added: Public type exports for the directive payloads (`SortableData`, `SortableEventName`, `SortableMoveEventPayload`).
deprecated: `SortableModule` and `SortableModule.forRoot()` — import the standalone `SortableDirective` and use `provideSortable()` instead.
changed: Aligned package scaffolding and documentation with the rest of the ng-hub-ui ecosystem.
Version 22.0.0 - 6/17/26, 12:00 AM
changed: Rebranded the package and standardized its metadata and README to match the ng-hub-ui family. The version was cut in the repository but never published to npm: the registry goes straight from 21.3.0 to 22.1.0, which is where the rebranding reached consumers.
Version 21.3.0 - 3/31/26, 12:00 AM
added: Improved binding support for writable signals and FormArrays, plus comprehensive test coverage for the directive.
Version 21.2.0 - 2/10/26, 12:00 AM
added: The SortableJS types are re-exported from the library root — `Sortable`, `SortableEvent`, `Options`, `MoveEvent`, `GroupOptions`, `PullResult` and `PutResult` — so typing a handler no longer means importing from two packages.
changed: `sortablejs` moved from peer dependencies to dependencies, so it installs with this package instead of being one more thing to remember.
Version 21.1.1 - 2/10/26, 12:00 AM
fixed: `update` and `add` emit once per drop in manual mode. SortableJS calls its own handlers more than once when the DOM is rearranged inside them, and those extra emissions used to reach the consumer.
fixed: The DOM and the bound array no longer disagree in manual mode: the directive reverts SortableJS's move so Angular renders from the array it was actually given.
fixed: Native SortableJS CustomEvents are suppressed at the container, so a template listener no longer fires twice for a single drop.
Version 21.1.0 - 2/9/26, 12:00 AM
added: Manual control mode via the `autoUpdateArray` input (default `true`); set it to `false` and the directive stops mutating the bound array and only reports what happened, which is what validation, persistence, undo and immutable state all need.
added: Array helper functions `moveItemInArray`, `transferArrayItem` and `copyArrayItem`, so manual mode does not mean rewriting index arithmetic in every application.
added: An events guide and a manual-control example covering a single list and a Kanban board.
Version 21.0.1 - 12/12/25, 12:00 AM
added: A README inside the package. The npm page had been blank since the first release.
Version 21.0.0 - 12/12/25, 12:00 AM
added: Writable signal support in the sortable bindings, alongside arrays and FormArrays, with hardened detection so neither shape trips TypeScript.
Version 20.0.0 - 12/10/25, 12:00 AM
added: First version published as `ng-hub-ui-sortable`, with the groundwork for Angular 20 compatibility. Everything the registry serves under this name starts here.
Связанные библиотеки
Часто задаваемые вопросы
Как сделать список сортируемым перетаскиванием в Angular?
Установите ng-hub-ui-sortable и поставьте [hubSortable] на элемент-контейнер, привязав его к массиву, который стоит за списком. Перетаскивание элемента переупорядочивает этот массив на месте, поэтому шаблон следует за ним без собственных обработчиков. Тот же вход принимает WritableSignal или FormArray — каждый переупорядочивается через собственный API.
Можно ли перетаскивать элементы между двумя списками?
Да. Дайте обоим контейнерам одно имя группы — через вход [group] или через полный объект опций SortableJS — и элементы будут переходить из одного массива в другой. Выходы add и remove сообщают, какой список элемент покинул и какой его принял, оба несут oldIndex и newIndex.
Работает ли сортировка с клавиатуры?
Да, и включена по умолчанию. Enter или Пробел берёт элемент в фокусе, стрелки перемещают его, Home и End отправляют к краям, Escape отменяет, и каждый шаг озвучивается в области aria-live, которой управляет сама директива. Сам SortableJS слушает только mousedown и touchstart, так что это надстройка сверху; [keyboardSorting]="false" её убирает.
Чем это отличается от drag and drop из Angular CDK?
Библиотека оборачивает SortableJS, а не CDK: нет пары cdkDropList и cdkDrag, один атрибут на контейнере — это вся настройка, а привязанный массив обновляется за вас. CSS она тоже не поставляет, поэтому вид при перетаскивании задают имена классов, которые вы передаёте в ghostClass, chosenClass и dragClass. Если нужен явный стиль CDK, поставьте [autoUpdateArray]="false" и переупорядочивайте сами экспортированными помощниками moveItemInArray, transferArrayItem и copyArrayItem.