@ng-dnd/core
Make sure you have @ng-dnd/core
and a backend installed, ideally @ng-dnd/multi-backend
. Read the core docs first, and make sure you have a firm grasp on it.
yarn add @ng-dnd/sortable
Then add DndSortableModule
where required.
import { DndSortableModule } from '@ng-dnd/sortable';
@NgModule({
imports: [
// ...,
// DndModule.forRoot( ... ),
DndSortableModule,
],
})
export class AppModule {}
The standalone components are available from 3.0.
Example :import { DndSortable, DndSortableList, ... } from '@ng-dnd/sortable';
@Component({
// ...,
standalone: true,
imports: [DndSortable, DndSortableList, ...],
})
export class AppComponent {}
This is different from the hundreds of other sortable libraries, because it is extremely pared back, and makes almost no limiting choices. This is NOT opinionated software.
SortableSpec
to define behaviour, much like a DragSourceSpec or DropTargetSpec but abstracted over a whole sortable and all elements in it.@ng-dnd/core
to alter visuals as you see fit.So yes, it's a bit harder to use than, say, ng2-dragula
. Does the extra implementation effort pay off? There are so many cool uses, this section needs headings.
DragSource.listen()
, so apply your own classes based on isDragging
and friends.[dragPreview]
or <dnd-preview>
) like any other DnD item. Useful for making multi-select. Or axis snapping. Or showing warning messages ('you can't drop that here') alongside your mouse. Go for your life.[dragSource]
on something else.mat-table
s, or any other list component.[dndSortableExternal]
).FormArray
or Immutable.js
, because the library doesn't care. (Although you can do native but immutable updates with immer
instead).@ngrx/store
(some helpers make this even easier).@ng-dnd/core
item, returned from beginDrag
. In sortables, all these items are DraggedItem
objects.<dnd-preview>
from the multi-backend.*ngFor
data and index.Hint: The best way to get started is by reading the example code.
Here's a rough guide:
SortableSpec
is the data backing interface for your sortable. It defines the Skyhoook type, what happens when you hover on a new spot, drop an item, etc. Maybe you want to overwrite a list on a single component, maybe you are firing @ngrx/store
actions. You must implement it according to the requirements and lifecycle.
For simpler list displays, make a container with <dnd-sortable-list>
and provide it an <ng-template dndSortableTemplate let-context>
for each element.
For more complicated rendering situations, use dndSortable
directive directly, and render an *ngFor
inside it, pulling out let i = index
as well.
In both options, for each draggable element, you need an [dndSortableRender]="context"
directive, which you need to get a reference to, and to finally attach [dragSource]="render.source"
somewhere.