Go back to @angular-skyhook/core
Make sure you have @angular-skyhook/core and a backend installed, ideally @angular-skyhook/multi-backend. Read the core docs first, and make sure you have a firm grasp on it.
yarn add @angular-skyhook/sortableThen add SkyhookSortableModule where required.
import { SkyhookSortableModule } from '@angular-skyhook/sortable';
@NgModule({
imports: [
// ...
// SkyhookDndModule.forRoot( ... ),
SkyhookSortableModule,
]
})
export class AppModule {}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-skyhook/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.
- 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<skyhook-preview>) like any other Skyhook 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.
- 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 Skyhook 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).
- 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.
- item: an
@angular-skyhook/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
<skyhook-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.
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
<skyhook-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.