All components (204)
Sortable list
Management · SortableList · .amset-sortable
What it is and when to use it
A list that is reordered by dragging and with the keyboard, which is the half that almost everyone leaves out. It is a grid (role="grid") and not a plain list because each row needs its own focus to be moved without a mouse. The drag is the browser's native one.
When to use it
- Sorting the lines of an invoice, the sections of the store's front page, the priorities of a task list.
- It is controlled:
onSortarrives with the whole order (the keys), not "from here to there", and whoever uses it saves the order. SortableListInnerkeeps the order inside (starting frominitial), for when there is no need to save it outside on every move (a settings panel that is submitted at the end).- Above it goes a line with the instructions;
hintchanges it if the application uses other keys.
When not to
- A hierarchy (categories within categories):
Tree. - Choosing rows, not sorting them:
SelectableList.
Keyboard: the list is a single Tab stop; the up and down arrows move from row to row, and Home and End go to the ends. With focus on a row, Control (or Cmd) and the up and down arrows move it up or down one place, and focus stays on it. Each move is announced with the position where it lands ("Insured shipping, position 3 of 4").
Accessibility: the list is named by label and each row is announced by its own. Each row carries draggable: that it can be picked up is stated by the attribute, not only by the cursor. The grip of dots and the icon are decorative. With no items, it says empty ("Nothing to sort") instead of leaving a gap.
Fine-tuning: CSS variables --amset-sortable-*: -detail, -font, -gap, -grip, -icon, -padding, -radius, -row-gap, -row-padding, -row-radius. The size changes the padding of the row, the gap and the font size, and the side of the grip and the icon.
What it looks like
Drag the rows or, with one focused, move it with Control and the arrow keys.
<SortableList label="Column order" items={items} onSort={setOrden} />Props
Import it with import { SortableList } from '@amset/ui'. Required props are marked.
| Prop | Type | What it does |
|---|---|---|
itemsrequired | readonly SortableItem[] | — |
labelrequired | string | What is being sorted: "Invoice lines". Required. |
onSortrequired | (keys: readonly string[]) => void | It arrives with the whole new order, not with "from here to there". |
className | string | Merged with the library classes; it does not replace them. |
empty | ReactNode | Text when the list is empty. |
hint | string | The instructions line. Change it if your app uses other keys. |
size | "sm" | "md" | "lg" | — |
It also accepts the attributes of the element it renders: className, style, data-*, aria-* and its events.
CSS variables
These CSS variables are how you adapt it. Declare them on the component's selector, not on :root: the stylesheet redeclares them in the rule itself, and a declaration on the same element always wins.
| Variable | Default |
|---|---|
--amset-sortable-gap | var(--amset-space-1) |
--amset-sortable-padding | var(--amset-space-1) |
--amset-sortable-row-padding | var(--amset-space-2) var(--amset-space-3) |
--amset-sortable-row-gap | var(--amset-space-3) |
--amset-sortable-radius | var(--amset-radius) |
--amset-sortable-row-radius | var(--amset-radius-sm) |
--amset-sortable-font | var(--amset-text-base) |
--amset-sortable-detail | var(--amset-text-sm) |
--amset-sortable-grip | 1rem |
--amset-sortable-icon | 1.125rem |
How to change it
.amset-sortable {
--amset-sortable-gap: ...;
--amset-sortable-padding: ...;
}In the test bench
Every state and variant, to try one at a time, on its page at ui.amset.tech:
