Skip to content

SortableList

Rows that editors reorder by dragging, like list fields.

HeroAutumn collection
ProductsNew in linen
QuoteFrom the workshop
SortableList.tsx
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>

PropTypeDefaultDescription
onReorder(event: DragMoveEvent) => voidDefault –Enables reordering: items with an 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>

PropTypeDefaultDescription
idKeyDefault –Identifies the item within its list. Items with an id can be dragged when the list has onReorder. The id is not rendered as a DOM id.
currentbooleanDefault –Highlights the item, eg. while its settings are open next to the list

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

PropTypeDefaultDescription
expanded*booleanDefault –Whether the item content is shown, picks the unfold icon

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

PropTypeDefaultDescription
variant'default' | 'actions'Default 'default'actions removes the padding around a group of ghost buttons

Also 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.