Drag and Drop List

Allows users to create vertically sortable lists supporting drag and drop, touch or keyboard input.

When to use

  • When a user wants to change a collection order.

Accessibility

  • tab and shift+tab to focus items
  • space to lift or drop the item
  • j or arrow down to move the lifted item down
  • k or arrow up to move the lifted item up
  • escape to cancel the lift and return the item to its initial position

This component also supports iOS and Android browsers and screen readers.

Drag and Drop basic usage

  • Grab
    Item 1
  • Grab
    Item 2
  • Grab
    Item 3
  • Grab
    Item 4
  • Grab
    Item 5
  • Grab
    Item 6

Drag and Drop stateless usage

  • Grab
    Item 1
  • Grab
    Item 2
  • Grab
    Item 3
  • Grab
    Item 4
  • Grab
    Item 5
  • Grab
    Item 6

Drag and Drop with removable items

  • Grab
    Item 1
  • Grab
    Item 2
  • Grab
    Item 3
  • Grab
    Item 4
  • Grab
    Item 5
  • Grab
    Item 6

Drag and Drop with varying heights

  • Grab
    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
  • Grab
    Donec ornare.
  • Grab
    Morbi malesuada id ante ac tincidunt. Phasellus at varius enim, fringilla pretium lorem. Integer placerat, est in aliquam tempus, ex urna hendrerit quam, eu sagittis nulla lorem eu magna.
  • Grab
    Morbi nibh nunc.
  • Grab
    Nunc consequat erat id ante mollis tincidunt in a nulla.

Drag and Drop with custom drag handle

  • Arrow Right
    Item 1
  • Arrow Right
    Item 2
  • Arrow Right
    Item 3
  • Arrow Right
    Item 4
  • Arrow Right
    Item 5
  • Arrow Right
    Item 6

Drag and Drop with label override

  • Grab
    Item 1
  • Grab
    Item 2
  • Grab
    Item 3
  • Grab
    Item 4
  • Grab
    Item 5
  • Grab
    Item 6

Overrides

Additionally, you can fully customize any part of the Drag and Drop List through the overrides prop. The Drag and Drop List consists of multiple subcomponents that are listed bellow and you can override each one of them. To help you identify the names of these subcomponents, you can highlight them through this selector:

  • Grab
    Item 1
  • Grab
    Item 2
  • Grab
    Item 3
  • Grab
    Item 4

Note: You should always use longhand CSS properties. Mixing shorthands and longhands will lead into strange behaviors!

List API

removable boolean

Set if the list items should be removable

removableByMove boolean

Set if the list items should be removable by dragging them far left or right

items Array<Node> = []

Items (labels) to be rendered

ArrayNode

onChange function = () => undefined

Handler for when drag and drop is finished and order changed or item is deleted (newIndex would be -1 in that case)

oldIndex number required
newIndex number required
=> mixed

overrides object

Root { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
List { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
Item { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
DragHandle { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
CloseHandle { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
Label { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node

Stateful List API

initialState object = { items: [] }

Initial state populated into the component

items required ArrayNode

stateReducer function = (type, nextState) => undefined

Reducer function to manipulate internal state updates.

function
$Values{ change: "change" },
items required ArrayNode
,
items required ArrayNode
=>
items required ArrayNode

removable boolean

Set if the list items should be removable

removableByMove boolean

Set if the list items should be removable by dragging them far left or right

onChange function

Handler for when drag and drop is finished and order changed or item is deleted (newIndex would be -1 in that case)

newState required ArrayNode
oldIndex number required
newIndex number required
targetRect required ClientRect
=> mixed

overrides object

Root { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
List { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
Item { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
DragHandle { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
CloseHandle { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
Label { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node

Stateful List Container API

initialState object = { items: [] }

items required ArrayNode

children function required

$Diff
removable boolean
removableByMove boolean
items required ArrayNode
onChange function required
oldIndex number required
newIndex number required
=> mixed
overrides
Root { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
List { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
Item { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
DragHandle { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
CloseHandle { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
Label { component: ?ComponentType<<T> & { children: Node }>, props: ?{} | ({}) => ?{}, style: ?{} | ({}) => ?{} }<<T>> | ComponentType<<T> & { children: Node }>
$isDragged boolean required
$isSelected boolean required
$isRemovable boolean required
$isRemovableByMove boolean required
$isOutOfBounds boolean required
$value required Node
,
children required ArrayNode
=> Node