Angular Drag & Drop Sortable List | ng-hub-ui-sortable
Angular sortable list and drag-and-drop utilities for arrays, FormArray integration, Signals workflows and connected lists.
API reference
Here's the full contract for sortable: everything you can bind, listen to, project and theme, gathered in one place. Wire up what you need and style what you want — it's standalone and signal-friendly.
Inputs
Dial sortable in with 39 inputs. Bind them like any Angular @Input.
| Name | Type | Default | Description |
|---|---|---|---|
hubSortable | SortableData<T> | SortableBindings | — | Data bound to the sortable container — a plain array, a reactive `FormArray` or a writable signal. Stays in sync with drag-and-drop operations. It is optional: the bare `hubSortable` attribute activates the directive too, and the outputs then report every move without anything being mutated. |
options | Options | — | Full SortableJS options object. Every SortableJS option can also be bound directly as its own input (for example `handle`, `animation` or `group`). |
autoUpdateArray | boolean | true | When `true` (default) the directive mutates the bound array automatically after each drag. Set it to `false` for manual control and update the array yourself. |
cloneFunction | (item: T) => T | — | Factory used to clone an item when the group is configured in `pull: 'clone'` mode. |
container | string | — | CSS selector of the nested element that should become sortable when the host wraps the actual list. |
keyboardSorting | boolean | true | Keyboard reordering, on by default. Each item becomes a tab stop; `Enter` or `Space` grabs it, the arrow keys move it, `Home` and `End` send it to either end and `Escape` puts it back. Set it to `false` when the application supplies its own keyboard path. |
keyboardMessages | Partial<SortableKeyboardMessages> | — | Overrides for the sentences the keyboard reorder announces through its live region. Anything left out keeps its English default. |
group | Options['group'] | — | Group name or configuration object used to connect several lists and control which ones can give or receive items. |
sort | boolean | — | Enables or disables reordering of items within the list. |
delay | number | — | Milliseconds the pointer must be held down before a drag may start. `0` by default; raise it on touch so a short press scrolls instead of dragging. |
disabled | boolean | — | Disables the sortable behaviour without removing the directive. |
draggable | string | — | CSS selector that restricts which child elements can be dragged. |
handle | string | — | CSS selector of the element inside each item that starts the drag, leaving the rest interactive. |
animation | number | — | Duration in milliseconds of the reordering animation. |
ghostClass | string | — | CSS class applied to the drop placeholder shown while dragging. |
chosenClass | string | — | CSS class applied to the item from the moment it is chosen until the drag ends. `sortable-chosen` by default. |
dragClass | string | — | CSS class applied to the element that follows the pointer while dragging. `sortable-drag` by default. |
fallbackOnBody | boolean | — | Appends the drag preview to `document.body` instead of the list, so an ancestor with `overflow: hidden` cannot clip it. |
fallbackTolerance | number | — | Pixels the pointer must travel before the fallback drag begins. `0` by default; raise it so a tap is not read as a drag. |
fallbackClass | string | — | CSS class applied to the cloned preview element used when the native HTML5 drag-and-drop is bypassed. |
fallbackOffset | { x: number; y: number } | — | Pixel offset applied to the fallback drag preview relative to the pointer. |
forceFallback | boolean | — | Ignores the browser's native HTML5 drag-and-drop and always drags a clone, which looks the same in every browser. |
filter | string | ((event, target, sortable) => boolean) | — | CSS selector (or predicate) marking elements that cannot be dragged. |
preventOnFilter | boolean | — | Calls `preventDefault()` on the event that triggered `filter`. `true` by default; turn it off when the filtered element is a control that still needs its own click. |
direction | 'vertical' | 'horizontal' | ((event, target, dragEl) => 'vertical' | 'horizontal') | — | Axis the list is laid out along. Detected automatically when unset; set it explicitly for grids and wrapped lists, where the detection can guess wrong. |
swapThreshold | number | — | Fraction of a target item (0 to 1) the pointer must cover before the two swap. `1` by default; lower values swap earlier. |
invertSwap | boolean | — | Always uses the inverted swap zone, so the swap happens as the pointer leaves an item instead of as it enters. |
invertedSwapThreshold | number | — | Threshold used while the swap zone is inverted. Falls back to `swapThreshold` when unset. |
removeCloneOnHide | boolean | — | Removes the clone from the DOM while it is hidden instead of only hiding it. `true` by default. |
ignore | string | — | CSS selector for elements inside an item that must never start a drag, such as inputs or links. |
touchStartThreshold | number | — | Pixels the finger may move before a delayed drag is cancelled — the margin between a drag and a scroll. |
emptyInsertThreshold | number | — | Distance in pixels from an empty list at which the dragged item is inserted into it. `5` by default; `0` requires the pointer to be inside the list. |
dropBubble | boolean | — | Lets the drop event keep propagating to ancestor elements. |
dragoverBubble | boolean | — | Lets the dragover event keep propagating to ancestor elements. |
dataIdAttr | string | — | HTML attribute read as each item's id by `Sortable.toArray()` and by `store`. `data-id` by default. |
delayOnTouchOnly | boolean | — | Applies `delay` only to touch input, so a mouse drag still starts immediately. |
easing | string | — | CSS easing function for the reordering animation, for example `cubic-bezier(1, 0, 0, 1)`. |
setData | (dataTransfer: DataTransfer, draggedElement: HTMLElement) => void | — | Called when the drag starts to write onto the native `DataTransfer` — the hook for dragging out of the page. |
store | { get: (sortable: Sortable) => string[]; set: (sortable: Sortable) => void } | — | Pair of `get`/`set` callbacks used to persist the order and restore it on the next load, keyed by `dataIdAttr`. |
Outputs
React to what sortable does — 13 events to hook your logic onto.
| Name | Type | Description |
|---|---|---|
init | Sortable | Emitted once the underlying SortableJS instance has been created. |
start | SortableEvent | Emitted when a drag operation starts. |
end | SortableEvent | Emitted when a drag operation ends, regardless of the result. |
add | SortableEvent | Emitted when an item is dropped into this list from another one. |
update | SortableEvent | Emitted when an item changes position within the same list. |
sortEvent | SortableEvent | Emitted whenever the list order changes (after `add` or `update`). |
remove | SortableEvent | Emitted when an item leaves this list towards another one. |
filterEvent | SortableEvent | Emitted when a filtered (non-draggable) item is attempted to be dragged. |
change | SortableEvent | Emitted when the list changes due to an add or remove operation. |
choose | SortableEvent | Emitted when an item is chosen (pointer down). |
unchoose | SortableEvent | Emitted when an item is released without being dragged. |
clone | SortableEvent | Emitted when an item is cloned in clone mode. |
move | SortableMoveEventPayload | Emitted continuously while dragging; its return value can control whether the move is allowed. |
Templates
No templates documented yet.