Resortable - v2.1.5
    Preparing search index...

    Interface SortableOptions

    interface SortableOptions {
        ghostClass?: string;
        chosenClass?: string;
        dragClass?: string;
        animation?: number;
        easing?: string;
        group?: string | SortableGroup;
        sort?: boolean;
        controlled?: boolean;
        disabled?: boolean;
        multiDrag?: boolean;
        multiDragKey?: null | "ctrl" | "meta" | "shift" | "alt";
        duplicateKey?: "ctrl" | "meta" | "shift" | "alt";
        selectedClass?: string;
        scroll?: boolean;
        scrollSensitivity?: number;
        scrollSpeed?: number;
        deselectOnClickOutside?: boolean;
        onEnd?: (event: SortableEvent) => void;
        onStart?: (event: SortableEvent) => void;
        onAdd?: (event: SortableEvent) => void;
        onUpdate?: (event: SortableEvent) => void;
        onRemove?: (event: SortableEvent) => void;
        enableAccessibility?: boolean;
        focusClass?: string;
        onSelect?: (event: Partial<SortableEvent>) => void;
        handle?: string;
        filter?: string;
        onFilter?: (event: Event) => void;
        ignore?: string;
        draggable?: string;
        delay?: number;
        delayOnTouchOnly?: number;
        touchStartThreshold?: number;
        swapThreshold?: number;
        invertSwap?: boolean;
        invertedSwapThreshold?: number;
        direction?: "vertical" | "horizontal";
        forceFallback?: boolean;
        fallbackClass?: string;
        fallbackOnBody?: boolean;
        fallbackTolerance?: number;
        fallbackOffsetX?: number;
        fallbackOffsetY?: number;
        dragoverBubble?: boolean;
        dropBubble?: boolean;
        removeCloneOnHide?: boolean;
        emptyInsertThreshold?: number;
        hitArea?: string;
        preventOnFilter?: boolean;
        dataIdAttr?: string;
        onChoose?: (event: SortableEvent) => void;
        onUnchoose?: (event: SortableEvent) => void;
        onSort?: (event: SortableEvent) => void;
        onMove?: (
            event: MoveEvent,
            originalEvent: Event,
        ) => boolean | void | 1 | -1;
        onClone?: (event: SortableEvent) => void;
        onChange?: (event: SortableEvent) => void;
        onSpill?: (event: SortableEvent) => void;
        revertOnSpill?: boolean;
        removeOnSpill?: boolean;
        setData?: (dataTransfer: DataTransfer, dragEl: HTMLElement) => void;
        store?: {
            set?: (sortable: SortableInstanceForStore) => void;
            get?: (sortable: SortableInstanceForStore) => string[];
        };
    }
    Index

    Properties

    ghostClass?: string

    CSS class applied to the ghost element during drag

    'sortable-ghost'
    
    { ghostClass: 'my-ghost-style' }
    
    chosenClass?: string

    CSS class applied to the chosen element when drag starts

    'sortable-chosen'
    
    dragClass?: string

    CSS class applied to the dragging element

    'sortable-drag'
    
    animation?: number

    Animation duration in milliseconds. Set to 0 to disable animations.

    150
    
    easing?: string

    CSS easing function for animations

    'cubic-bezier(0.4, 0.0, 0.2, 1)'
    
    { easing: 'ease-in-out' }
    { easing: 'cubic-bezier(0.25, 0.1, 0.25, 1)' }
    group?: string | SortableGroup

    Group name or configuration for sharing items between lists

    'default'
    
    { group: 'my-group' }
    
    {
    group: {
    name: 'shared',
    pull: 'clone',
    put: ['other-group']
    }
    }
    sort?: boolean

    Whether sorting is enabled within the list

    true
    
    controlled?: boolean

    Controlled (framework-friendly) mode

    When true, the library NEVER changes the structural position of consumer-owned nodes. During a drag it only manages its own overlay ghost, a single placeholder element, and hide/show styling on the dragged items. When end (and add/remove/update) fire, the DOM structure is identical to pre-drag; the events carry the full intent (including SortableEvent.oldIndexes / SortableEvent.newIndexes) and the consumer commits it by updating state and re-rendering.

    Designed for declarative frameworks (React, Vue, Svelte) that own the list DOM. See docs/plans/2026-07-09-controlled-mode-design.md.

    Note: sort() and store are no-ops in controlled mode — order is consumer state.

    false
    
    disabled?: boolean

    Whether the sortable is disabled

    false
    
    multiDrag?: boolean

    Enable multi-drag functionality

    false
    
    multiDragKey?: null | "ctrl" | "meta" | "shift" | "alt"

    Modifier key required for click-to-select in multi-drag mode.

    When set, selection becomes an explicit gesture: <key>+click toggles an item in/out of the selection and Shift+click extends a range, while a PLAIN click does nothing — no selection, no focus steal — leaving plain-click semantics (activating / triggering the item) to the app.

    When null (default), plain clicks toggle selection additively — appropriate for lists where clicking has no other meaning.

    Keyboard selection (Space) and dragging an existing selection are unaffected. Legacy parity: SortableJS MultiDrag's multiDragKey.

    null
    
    duplicateKey?: "ctrl" | "meta" | "shift" | "alt"

    Modifier key that, when held at drop time, duplicates the dragged item(s) instead of moving them.

    Off by default. Pointer drags only — keyboard-driven accessibility drags ignore it. The modifier is evaluated live: it's the state at drop time that decides, not the state at drag start. A cross-zone drop behaves like group.pull: 'clone'; a same-zone drop inserts a copy at the drop position while the original returns to its start index (see the clone event, where to === from marks this in-place case). The clone keeps the original's data attributes (e.g. data-id) — mint new ids in the clone event handler.

    A same-list duplicate also fires sort, update and change with pullMode: 'clone' and clone set — handlers must insert a copy, not move the item. See the SortableEvents.update docs.

    With sort: false reordering is blocked, so the copy simply lands adjacent to the original. That is intended, not a bug.

    'alt' is the recommended value. With multiDrag: true, only 'alt' may be held at drag START, since ctrl/meta/shift are selection gestures there; all four still arm duplicate mode if pressed after the drag begins. And with enableAccessibility (on by default) click selection is live, so ctrl/meta/shift do double duty: the click that ends a duplicate drag also reaches the selection handler and toggles the item's selected state. Nothing suppresses that — pick 'alt' unless you want both effects.

    The sortable-duplicate CSS class is applied to the ghost and placeholder while duplicate mode is armed.

    undefined
    
    { duplicateKey: 'alt' } // Alt+drop duplicates instead of moving
    
    selectedClass?: string

    CSS class for selected items in multi-drag mode

    'sortable-selected'
    
    scroll?: boolean

    Auto-scroll scrollable ancestors (and the window) when dragging near their edges. Legacy parity: SortableJS Scroll plugin's scroll: true. Internally installs an instance-owned AutoScrollPlugin.

    false
    
    scrollSensitivity?: number

    Distance in px from a scrollable edge at which auto-scroll kicks in. Only meaningful with scroll: true.

    100
    
    scrollSpeed?: number

    Auto-scroll speed in px per frame. Only meaningful with scroll: true.

    10
    
    deselectOnClickOutside?: boolean

    Clear selection when clicking outside the sortable container

    true
    
    onEnd?: (event: SortableEvent) => void

    Callback fired when drag operation ends

    Type Declaration

    {
    onEnd: (evt) => {
    console.log(`Moved from ${evt.oldIndex} to ${evt.newIndex}`);
    console.log('Item:', evt.item);
    }
    }
    onStart?: (event: SortableEvent) => void

    Callback fired when drag operation starts

    Type Declaration

    onAdd?: (event: SortableEvent) => void

    Callback fired when an item is added from another list

    Type Declaration

    onUpdate?: (event: SortableEvent) => void

    Callback fired when sorting changes within the same list

    Type Declaration

    onRemove?: (event: SortableEvent) => void

    Callback fired when an item is removed to another list

    Type Declaration

    enableAccessibility?: boolean

    Enable accessibility features (keyboard navigation, ARIA attributes)

    true
    
    focusClass?: string

    CSS class for focused items during keyboard navigation

    'sortable-focused'
    
    onSelect?: (event: Partial<SortableEvent>) => void

    Callback fired when items are selected/deselected

    Type Declaration

    handle?: string

    CSS selector for drag handle When specified, drag can only be initiated from matching elements

    undefined
    
    // Only allow dragging from elements with class 'drag-handle'
    { handle: '.drag-handle' }

    // Multiple handles using a more complex selector
    { handle: '.drag-handle, .drag-icon' }
    filter?: string

    CSS selector for elements that should not trigger drag

    undefined
    
    // Prevent dragging when clicking on input elements
    { filter: 'input, textarea, button' }
    onFilter?: (event: Event) => void

    Callback fired when a filtered element is clicked

    Type Declaration

      • (event: Event): void
      • Parameters

        • event: Event

          The original mouse/touch event

        Returns void

    ignore?: string

    CSS selector for descendants of draggable items that should NOT initiate a drag. Used to allow click-through on interactive elements like links and images so users can follow an <a> or drag an <img> natively without a sortable drag starting underneath them. Matches the legacy Sortable.js v1 behaviour and default value.

    Pass an empty string ('') to disable the default and allow drags to start from any descendant.

    'a, img'

    // Default — links and images do not start a drag
    new Sortable(el, {})

    // Extend the default
    new Sortable(el, { ignore: 'a, img, input, button' })

    // Disable the default entirely
    new Sortable(el, { ignore: '' })
    draggable?: string

    CSS selector for draggable items

    '.sortable-item'
    
    // Only allow specific items to be draggable
    { draggable: '.draggable-item' }
    delay?: number

    Delay in milliseconds before drag starts

    0
    
    // 300ms delay before drag starts
    { delay: 300 }
    delayOnTouchOnly?: number

    Delay on touch devices (fallback to delay if not specified)

    delay || 0
    
    // Different delays for mouse and touch
    { delay: 0, delayOnTouchOnly: 300 }
    touchStartThreshold?: number

    Pixels of movement allowed before cancelling delayed drag event

    5
    
    // Allow 10px of movement before cancelling delayed drag
    { touchStartThreshold: 10 }
    swapThreshold?: number

    Threshold of the swap zone (0-1)

    When unset (the default), the overlap gate is disabled — swaps are not constrained by overlap amount. Setting this property enforces a minimum overlap for a swap to occur.

    // Swap when dragged element overlaps 50% with target
    { swapThreshold: 0.5 }

    Legacy Sortable.js compatibility: The original Sortable.js defaults to a swap threshold of 1 (100% overlap), making items much stickier. To replicate that behavior in Resortable, explicitly set swapThreshold: 1. Leaving unset enables the responsive default (no minimum-overlap requirement).

    invertSwap?: boolean

    Inverts the swap threshold behavior

    false
    
    // Invert swap behavior for drop zones
    { invertSwap: true }
    invertedSwapThreshold?: number

    Threshold when swap is inverted (0-1)

    swapThreshold
    
    // Different threshold when inverted
    { invertedSwapThreshold: 0.3 }
    direction?: "vertical" | "horizontal"

    Direction of sortable ('vertical' or 'horizontal')

    'vertical'
    
    // Horizontal sorting for image gallery
    { direction: 'horizontal' }
    forceFallback?: boolean

    Enable fallback for browsers without native drag support

    true
    
    // Disable fallback to use native HTML5 drag only
    { forceFallback: false }
    fallbackClass?: string

    CSS class for fallback ghost element

    'sortable-fallback'
    
    fallbackOnBody?: boolean

    Use fallback on touch devices

    false
    
    fallbackTolerance?: number

    Pixels the pointer must travel from pointerdown before the pointer pipeline commits the drag (ghost, placeholder, start event). 0 commits immediately on pointerdown. choose fires at pointerdown either way. Recommended for apps where plain click has its own meaning (e.g. triggering the item): a few px keeps clicks from churning a full drag start/teardown.

    0
    
    fallbackOffsetX?: number

    X-axis offset for fallback ghost

    0
    
    fallbackOffsetY?: number

    Y-axis offset for fallback ghost

    0
    
    dragoverBubble?: boolean

    Allow dragover event to bubble. When false (default), the library calls e.stopPropagation() after handling so that ancestor sortables don't double-process the event. Set true to support nested sortables.

    false
    
    dropBubble?: boolean

    Allow drop event to bubble. When false (default), the library calls e.stopPropagation() after handling. Set true to let ancestor sortables observe drop completions (e.g. for nested-sortable layouts).

    false
    
    removeCloneOnHide?: boolean

    Remove clone element when it's not showing.

    Currently a no-op: Resortable does not yet implement clone hide/show cycles — clones are always created on drag start and removed on drag end. Tracked in the v1.x parity work under #44.

    true
    
    emptyInsertThreshold?: number

    Distance mouse must move from empty sortable to insert drag element into it

    5
    
    hitArea?: string

    CSS selector for a surrounding region that also accepts drops for this zone. When a drop lands anywhere inside zoneEl.closest(hitArea) but outside the zone's own rect — and over no other zone/item — it resolves to this zone and inserts at the nearest end (index 0 when the pointer is before the zone's start edge, else append). Generalizes emptyInsertThreshold to a large, caller-defined region around a populated list (#126). Fallback only: a pointer directly over a zone or its items always wins, and group put/pull rules are still enforced.

    preventOnFilter?: boolean

    Call preventDefault when filter is triggered

    true
    
    dataIdAttr?: string

    HTML attribute used to track element IDs

    'data-id'
    
    onChoose?: (event: SortableEvent) => void

    Callback fired when an element is chosen

    Type Declaration

    onUnchoose?: (event: SortableEvent) => void

    Callback fired when an element is unchosen

    Type Declaration

    onSort?: (event: SortableEvent) => void

    Callback fired when sorting changes

    Type Declaration

    onMove?: (event: MoveEvent, originalEvent: Event) => boolean | void | 1 | -1

    Callback fired during move operations

    Type Declaration

      • (event: MoveEvent, originalEvent: Event): boolean | void | 1 | -1
      • Parameters

        • event: MoveEvent

          The move event with related element

        • originalEvent: Event

          The original drag event

        Returns boolean | void | 1 | -1

        • false to cancel the move (no placeholder shift; no sort / update / change emission for that tick)
        • -1 to force inserting BEFORE the related item
        • 1 to force inserting AFTER the related item
        • true / void to proceed with the natural heuristic
    onClone?: (event: SortableEvent) => void

    Callback fired when an element is cloned

    Type Declaration

    onChange?: (event: SortableEvent) => void

    Callback fired when the sort order has changed

    Type Declaration

    onSpill?: (event: SortableEvent) => void

    Callback fired when an item is dropped outside all sortable containers

    Type Declaration

    revertOnSpill?: boolean

    Revert item to its original position when dropped outside sortable areas Requires the OnSpill plugin to be installed.

    false
    
    removeOnSpill?: boolean

    Remove item from the DOM when dropped outside sortable areas Requires the OnSpill plugin to be installed.

    false
    
    setData?: (dataTransfer: DataTransfer, dragEl: HTMLElement) => void

    Custom function to set data on the DataTransfer object during drag start

    Type Declaration

      • (dataTransfer: DataTransfer, dragEl: HTMLElement): void
      • Parameters

        • dataTransfer: DataTransfer

          The DataTransfer object from the drag event

        • dragEl: HTMLElement

          The element being dragged

        Returns void

    {
    setData: (dataTransfer, dragEl) => {
    dataTransfer.setData('text/html', dragEl.outerHTML);
    }
    }
    store?: {
        set?: (sortable: SortableInstanceForStore) => void;
        get?: (sortable: SortableInstanceForStore) => string[];
    }

    Key to use when saving/restoring sort order via localStorage Used by the save() method.

    Type Declaration

    undefined