View this page with live demos!
The reorder-list
and reorder-item
elements represent an ordered list of items that can be reordered. They are built with accessibility in mind and implement the WAI-ARIA guidelines for rearrangable listboxes.
<reorder-list>
<reorder-item>Apple</reorder-item>
<reorder-item>Orange</reorder-item>
<reorder-item>Banana</reorder-item>
<reorder-item>Lime</reorder-item>
<reorder-item>Blueberry</reorder-item>
<reorder-item>Plum</reorder-item>
</reorder-list>
You can import through CDN:
<script type="module" src="https://unpkg.com/@auroratide/reorder-list/lib/define.js"></script>
Or, you may install through NPM and include it as part of your build process:
$ npm i @auroratide/reorder-list
import '@auroratide/reorder-list/lib/define.js'
reorder-list
and reorder-item
are markup elements that you can use in your HTML document. To use them together, it is best to follow these guidelines:
-
reorder-item
elements must be direct descendents of areorder-list
element. This is similar to howli
must directly descendol
.
By default, orientation
is "vertical", meaning you drag items up and down. Setting orientation
to "horizontal" will allow you to reorder items left and right instead.
<reorder-list orientation="horizontal">
<reorder-item>Apple</reorder-item>
<reorder-item>Orange</reorder-item>
<reorder-item>Banana</reorder-item>
<reorder-item>Kiwi</reorder-item>
</reorder-list>
Note: Bidirectional reordering is not possible with this component. reorder-list
is for lists, whereas bidirectional reordering would be for a grid of some kind; they are different semantics.
You may have an element within a reorder-item
that you do not want triggering a reorder. For instance, an input
element should not start dragging, and it should instead focus on the input
.
Use the data-ignore-reorder
attribute on any element within reorder-item
in order to make that element not start dragging.
<reorder-list>
<reorder-item>Drag: <input data-ignore-reorder type="text" value="Apple" /></reorder-item>
<reorder-item>Drag: <input data-ignore-reorder type="text" value="Orange" /></reorder-item>
<reorder-item>Drag: <input data-ignore-reorder type="text" value="Banana" /></reorder-item>
<reorder-item>Drag: <input data-ignore-reorder type="text" value="Kiwi" /></reorder-item>
</reorder-list>
Since these are native custom elements, they can be styled the same way as regular HTML elements.
Of note:
-
reorder-item[data-dragging]
will style the currently dragged item.
Here's an example of a customized list meant to look like reorderable cards.
reorder-list {
list-style: none;
background: #ddd;
border-radius: 0.5em;
width: min(400px, 100%);
padding: 0.5em;
display: flex;
flex-direction: column;
gap: 0.5em;
}
reorder-item {
background: #fff;
border-radius: 0.25em;
padding: 0.5em;
box-shadow: 0 0.1em 0.15em #0002;
}
reorder-item ul {
list-style: none;
display: flex;
flex-wrap: wrap;
gap: 0.5em;
padding: 0;
margin: 0;
font-size: 90%;
color: #2573C1;
}
The reorder-list
element dispatches the following events:
Name | When Triggered |
---|---|
change |
Whenever an item in the list is reordered |
commit |
At the end of an item being dragged |
Both events contain a reference to the item that was reordered, its previous position in the list, and its new position.
list.addEventListener('change', e => {
console.log(e.detail.item)
console.log(e.detail.oldIndex)
console.log(e.detail.newIndex)
})
The difference between change
and commit
is the change
event happens any time an element changes order, including in the middle of a drag. The commit
event only triggers at the end of a drag, so the old index in that event's details will represent the position of that item prior to the drag being started.
Nothing stops you from putting lists inside of lists.
<reorder-list orientation="horizontal">
<reorder-item>
<strong>Fruit</strong>
<reorder-list>
<reorder-item>Apple</reorder-item>
<reorder-item>Orange</reorder-item>
<reorder-item>Banana</reorder-item>
<reorder-item>Kiwi</reorder-item>
</reorder-list>
</reorder-item>
<reorder-item>
<strong>Vegetable</strong>
<reorder-list>
<reorder-item>Tomato</reorder-item>
<reorder-item>Carrot</reorder-item>
<reorder-item>Squash</reorder-item>
<reorder-item>Lettuce</reorder-item>
</reorder-list>
</reorder-item>
<reorder-item>
<strong>Grain</strong>
<reorder-list>
<reorder-item>Wheat</reorder-item>
<reorder-item>Barley</reorder-item>
<reorder-item>Rye</reorder-item>
<reorder-item>Rice</reorder-item>
</reorder-list>
</reorder-item>
</reorder-list>
This custom element is build with accessibility in mind! It follows the WAI-ARIA guidelines for rearrangable listboxes (the listbox
and option
roles).
- When focus enters the list, focus goes to the currently active list item.
- Up and Down can be used to navigate the list, focusing on an element that will be reordered.
- Alt + Up/Down moves the currently selected list item up or down in the order.
- If orientation is horizontal, then Left and Right are used instead.