@angular-dnd/sortable v0.0.18
@angular-dnd/sortable
The @angular-dnd/sortable is a for of @angular-skyhook/sortable
Installation
Make sure you have @angular-dnd/core and a backend installed, ideally @angular-dnd/multi-backend.
Read the core docs first, and make sure you have a firm grasp on it.
Installation
yarn add @angular-dnd/sortableThen add AngularDndSortableModule where required.
import { AngularDndSortableModule } from '@angular-dnd/sortable';
@NgModule({
imports: [
// ...
// AngularDndDndModule.forRoot( ... ),
AngularDndSortableModule,
]
})
export class AppModule {}A sortable with truly ridiculous levels of customizability
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.
- It does no list operations for you. You drive the reordering and reverting yourself.
- It is not coupled to DOM, so you can render your list and any previews or transit elements however you like.
- It accepts a
SortableSpecto define behaviour, much like a DragSourceSpec or DropTargetSpec but abstracted over a whole sortable and all elements in it. - It gives you the complete power of
@angular-dnd/coreto 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.
Visuals and interaction
- You can have non-sortable items inside your container. Like a header that you can still drop on when the sortable is otherwise empty.
- You control all your visuals with
DragSource.listen(), so apply your own classes based onisDraggingand friends. - Your drag previews are completely customizable (using
[dragPreview]or<angular-dnd-preview>) like any other AngularDnd 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. - Your dragged items can morph as they skip between two different lists, because they are completely re-rendered. This is great for a 'form builder' where library items/icons expand into full-size in-place templates when you drag them in.
- Drag handles are easy, just put the
[dragSource]on something else.
Integration and IO
- You can (in theory) use it with Material
mat-tables, or any other list component. - You can insert 'external' elements by creating a DragSource (see
[ssExternal]). - Each sortable item exists as a AngularDnd item that can be dropped onto a normal drop target (like a trash can).
- You don't need to use plain JS arrays, you can use Angular's
FormArrayorImmutable.js, because the library doesn't care. (Although you can do native but immutable updates withimmerinstead).
Data backing
- You can easily implement the sorting in an
@ngrx/store(some helpers make this even easier). - You don't have to hijack or revert someone else's predefined sort operations to implement 'multi-select & drag'
- If you want to build keyboard navigation on top with identical operations, you don't have to mimic someone else's library operations, just refactor your own.
Terminology
- item: an
@angular-dnd/coreitem, returned frombeginDrag. In sortables, all these items areDraggedItemobjects. - data: one of the JS objects in the backing array. It is opaque to the library, but you need a unique identifier field on it.
- preview: follows your mouse pixel by pixel. E.g. an HTML5 drag preview or a
<angular-dnd-preview>from the multi-backend. - transit: you render this as part of the list while there is an item in-flight. Must follow the mouse, but not pixel for pixel.
- context: a small set of information enabling draggable elements to know where they are (index and data wise) without being coupled to the container's DOM children. Derived from a container and
*ngFordata and index.
Usage Overview
Hint: The best way to get started is by reading the example code.
Here's a rough guide:
SortableSpecis 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/storeactions. You must implement it according to the requirements and lifecycle.For simpler list displays, make a container with
<angular-dnd-sortable-list>and provide it an<ng-template ssTemplate let-context>for each element.For more complicated rendering situations, use
ssSortabledirective directly, and render an*ngForinside it, pulling outlet i = indexas well.In both options, for each draggable element, you need an
[ssRender]="context"directive, which you need to get a reference to, and to finally attach[dragSource]="render.source"somewhere.