Sortable
Sortable lets users reorder the items of a list, a table or a grid by dragging them. It wraps SortableJS in a Tabler component and styles the dragged item.
Overview
Use Sortable where the order is up to the user, such as a task list, table rows or dashboard cards. The component is part of tabler.js. The dragging itself comes from SortableJS, which you load separately.
Installation
Install the SortableJS library:
npm install sortablejsyarn add sortablejspnpm install sortablejsbun install sortablejsIf you use a bundler, put the library on window before Tabler loads. The component reads window.Sortable and does nothing without it. Imports run before the rest of a file, so do it in a file of its own and import that one first:
// sortable-global.js
import Sortable from 'sortablejs'
window.Sortable = Sortable
import './sortable-global.js'
import '@tabler/core'
Or include it from a CDN, before tabler.js:
<script src="https://cdn.jsdelivr.net/npm/@tabler/[email protected]/dist/libs/sortablejs/Sortable.min.js"></script>
Usage
Basic list
Add data-sortable to the parent element. Its direct children become draggable.
- Design the landing page
- Write the release notes
- Review open pull requests
<ul class="list-group" data-sortable="true">
<li class="list-group-item">Design the landing page</li>
<li class="list-group-item">Write the release notes</li>
<li class="list-group-item">Review open pull requests</li>
</ul>Options
Pass SortableJS options as JSON in the attribute. This list animates the items as they move.
- First
- Second
- Third
<ul class="list-group" data-sortable="{"animation":150}">
<li class="list-group-item">First</li>
<li class="list-group-item">Second</li>
<li class="list-group-item">Third</li>
</ul>Drag handle
Set handle to a selector to start the drag only from that element. The rest of the item stays clickable.
<ul class="list-group" data-sortable='{"animation":150,"handle":".sortable-handle"}'>
<li class="list-group-item d-flex gap-2">
<span class="sortable-handle cursor-move">⋮⋮</span>
Design the landing page
</li>
</ul>
Table rows
Put data-sortable on the tbody to reorder the rows of a table.
<table class="table">
<tbody data-sortable='{"animation":150}'>
<tr><td>First row</td></tr>
<tr><td>Second row</td></tr>
</tbody>
</table>
Drag styles
Tabler styles the classes SortableJS adds while dragging: .sortable-ghost marks the drop position, .sortable-chosen the picked item and .sortable-drag the copy that follows the pointer.
The browser draws the dragged item itself by default, and CSS cannot style that image. Turn on the forceFallback option and SortableJS drags an HTML copy of the item instead, which .sortable-drag tilts and lifts with a shadow:
<ul class="list-group" data-sortable='{"forceFallback":true}'>
…
</ul>
JavaScript
Tabler wraps the plugin in a Sortable component that works like the Bootstrap components: it is created once per element and stored on it. On page load Tabler creates one for every element with data-sortable. This is the code that runs:
initAll(SELECTOR_DATA_SORTABLE, Sortable)Create the component yourself for a list added later. Options come from data-sortable, from the config object, or both. The object wins.
const list = new tabler.Sortable(document.getElementById('tasks'), { animation: 150 });
| Method | Description |
|---|---|
toArray() |
Returns the data-id of every item, in the current order. |
sort(order, useAnimation) |
Reorders the items to match an array of ids. |
dispose() |
Destroys the SortableJS instance and removes the component. |
The sortable getter returns the SortableJS instance, so everything from the SortableJS API is available:
const list = tabler.Sortable.getOrCreateInstance(document.getElementById('tasks'));
list.sortable.option('disabled', true);
Accessibility
- Dragging needs a pointer. SortableJS has no keyboard support, so give keyboard users another way to change the order, such as "Move up" and "Move down" buttons.
- Use a drag handle when the items contain links or buttons, so a click on them does not start a drag.
- Save the new order only after the drop, and tell the user when saving fails.
CSS
Sass variables
Override these variables before importing Tabler to change the defaults. Source: core/scss/_variables.scss.
$sortable-ghost-bg: var(--primary-lt);
$sortable-ghost-border-color: var(--primary);
$sortable-ghost-opacity: 0.6;
$sortable-outline-width: 1px;
$sortable-selected-bg: var(--primary-lt);
$sortable-drag-bg: var(--bg-surface);
$sortable-drag-rotate: 1.5deg;
$sortable-drag-box-shadow: $box-shadow-lg;
