JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices
npx @tessl/cli install tessl/npm-sortablejs@1.15.0Sortable is a JavaScript library for reorderable drag-and-drop lists on modern browsers and touch devices. It provides smooth animations, multi-drag support, and framework-agnostic integration without requiring jQuery.
npm install sortablejsimport Sortable from "sortablejs";For CommonJS:
const Sortable = require("sortablejs");Core Build (without default plugins):
import Sortable from "sortablejs/modular/sortable.core.esm.js";Complete Build (with all plugins):
import Sortable from "sortablejs/modular/sortable.complete.esm.js";Default Build (with standard plugins):
import Sortable from "sortablejs/modular/sortable.esm.js";// Import with specific plugins
import Sortable, { MultiDrag, AutoScroll, Swap } from "sortablejs";
// Mount plugins before use
Sortable.mount(new MultiDrag(), new AutoScroll(), new Swap());
// From core build
import Sortable, { AutoScroll } from "sortablejs/modular/sortable.core.esm.js";
Sortable.mount(new AutoScroll());import Sortable from "sortablejs";
// Create a sortable list
const el = document.getElementById('items');
const sortable = Sortable.create(el, {
animation: 150,
ghostClass: 'sortable-ghost',
onEnd: function(evt) {
console.log('Item moved from index', evt.oldIndex, 'to', evt.newIndex);
}
});
// Get the current order
const order = sortable.toArray();
// Programmatically sort
sortable.sort(['item-1', 'item-3', 'item-2']);
// Cleanup
sortable.destroy();Sortable is built around several key components that work together to provide comprehensive drag-and-drop functionality:
Sortable Class: Central controller that manages all drag-and-drop behavior and instance lifecycleSortable.create()) and global utilities (Sortable.get(), Sortable.mount())Main constructor, static methods, and instance methods for creating and managing sortable lists.
function Sortable(el: HTMLElement, options?: SortableOptions): Sortable;
Sortable.create(el: HTMLElement, options?: SortableOptions): Sortable;
Sortable.get(element: HTMLElement): Sortable | undefined;Comprehensive configuration system with 25+ options for customizing drag behavior, visual feedback, and interaction patterns.
interface SortableOptions {
group?: string | GroupOptions;
sort?: boolean;
disabled?: boolean;
animation?: number;
handle?: string;
draggable?: string;
// ... 20+ additional options
}Rich event lifecycle with callbacks for drag start/end, list changes, and custom interactions.
interface EventCallbacks {
onStart?: (evt: SortableEvent) => void;
onEnd?: (evt: SortableEvent) => void;
onAdd?: (evt: SortableEvent) => void;
onUpdate?: (evt: SortableEvent) => void;
// ... 8+ additional events
}Extensible plugin architecture for advanced functionality like multi-drag, auto-scroll, and element swapping.
Sortable.mount(...plugins: SortablePlugin[]): void;
// Available plugins
import { MultiDrag, AutoScroll, Swap, OnSpill } from "sortablejs";Collection of DOM manipulation and helper functions for advanced integrations and custom implementations.
interface SortableUtils {
on(el: HTMLElement, event: string, fn: Function): void;
off(el: HTMLElement, event: string, fn: Function): void;
css(el: HTMLElement, prop: string, value?: string): string | void;
find(ctx: HTMLElement, tagName: string, iterator?: Function): HTMLElement[];
// ... 15+ additional utilities
}interface SortableEvent {
to: HTMLElement;
from: HTMLElement;
item: HTMLElement;
clone?: HTMLElement;
oldIndex: number;
newIndex: number;
oldDraggableIndex: number;
newDraggableIndex: number;
pullMode?: string | boolean;
}
interface GroupOptions {
name: string;
pull?: boolean | string | string[] | ((to: Sortable, from: Sortable) => boolean);
put?: boolean | string | string[] | ((to: Sortable, from: Sortable) => boolean);
revertClone?: boolean;
}
class Sortable {
constructor(el: HTMLElement, options?: SortableOptions);
el: HTMLElement;
options: SortableOptions;
// Instance methods
toArray(): string[];
sort(order: string[], useAnimation?: boolean): void;
save(): void;
closest(el: HTMLElement, selector?: string): HTMLElement | null;
option(name: string, value?: any): any;
destroy(): void;
handleEvent(evt: Event): void;
}