SortableList
Rows that editors reorder by dragging, like list fields.
import {
Badge,
type DragMoveEvent,
SortableList,
SortableListItem,
SortableListItemDescription,
SortableListItemHeader,
SortableListItemTitle
} from 'alinea/components'
import {useState} from 'react'
const initial = [
{id: 'hero', type: 'Hero', label: 'Autumn collection'},
{id: 'products', type: 'Products', label: 'New in linen'},
{id: 'quote', type: 'Quote', label: 'From the workshop'}
]
export function SortableListExample() {
const [sections, setSections] = useState(initial)
function reorder({keys, target}: DragMoveEvent) {
const moved = sections.filter(section => keys.has(section.id))
const rest = sections.filter(section => !keys.has(section.id))
const index = rest.findIndex(section => section.id === target.key)
rest.splice(target.position === 'before' ? index : index + 1, 0, ...moved)
setSections(rest)
}
return (
<SortableList
aria-label="Sections"
onReorder={reorder}
style={{width: 400}}
>
{sections.map(section => (
<SortableListItem key={section.id} id={section.id} role="listitem">
<SortableListItemHeader>
<SortableListItemTitle>
<Badge size="sm">{section.type}</Badge>
<SortableListItemDescription>
{section.label}
</SortableListItemDescription>
</SortableListItemTitle>
</SortableListItemHeader>
</SortableListItem>
))}
</SortableList>
)
}Props
<SortableList>
id follow the pointer when their SortableListItemHeader is dragged, the other items move aside as it passes them. With focus in the header, Alt+ArrowUp and Alt+ArrowDown move an item. Called with the key of the moved item and the item it was dropped before or after. Update the order synchronously: the dropped item glides into the place it renders in right after this returns.Also accepts every prop of a <div> element.
<SortableListItem>
onReorder. The id is not rendered as a DOM id.Also accepts every prop of a <div> element.
<SortableListItemHeader>
Top bar of an item, holds its title and actions. Drags the item when the list has onReorder, a press that does not move still clicks.
Accepts every prop of a <div> element.
<SortableListItemTitle>
Row of the toggle, badges and description of an item, fills the header
Accepts every prop of a <div> element.
<SortableListItemDescription>
Muted, truncated text next to the badges of an item, eg. its label
Accepts every prop of a <span> element.
<SortableListItemActions>
Accepts every prop of a <div> element.
<SortableListItemToggle>
Folds the content of an item
Also accepts every prop of Button.
<SortableListItemContent>
The fields of an expanded item
Accepts every prop of a <div> element.
<SortableListItemFooter>
A summary under the header, eg. of a folded item
Accepts every prop of a <div> element.
<SortableListItemSettings>
A group of settings or actions in the popover of an item
actions removes the padding around a group of ghost buttonsAlso accepts every prop of a <div> element.
<SortableListAdd>
Last row of the list holding the buttons that add items
Accepts every prop of a <div> element.