shadcn.io is not affiliated with official shadcn/ui
Sortable List Form Block for React Aria
A runbook's steps reordered without a drag library: Move up and Move down buttons per step, Alt plus arrow keys in the text, a status line that says where a step went, and a preview that renumbers the steps they point at.
Installation
Overview
Reorder a list with buttons and keys instead of a drag handle, with this sortable list form for React with React Aria. A header with an Add step button sits over a hairline frame with a plus mark on each corner. The editor is a numbered list of steps, each with a text field, a small select that says which other step it points at, and three buttons named for the step: Move up, Move down and Remove. Alt plus the up or down arrow does the same from inside the text, and the moved step keeps focus either way. The polite line says where it went, "Moved Lock the side door to 3 of 5", and a step already first or last says so instead of failing silently. The pointer is the step itself, not a number: the side cell, Preview order, prints each step with "see step 2" resolved from where that step is now, so moving a step renumbers every pointer to it, and removing a step clears the pointers to it and says how many. Removing the last step shows an Empty state in the same held box. The foot holds the Shine Button Save runbook, the only colored control, and a Reset order button. Both wait for a change. On a phone the preview is hidden and the list stays numbered. It's built from Input, Native Select, Empty, Button, Shine Button and Guides, with a CSS entrance only. For runbooks, checklists, playlists, onboarding steps and any ordered list that has to work without a pointer.
FAQ
How do I change the steps and the limit?
Edit START for the first steps and MAX for the most a runbook can hold. Each step is { id, text, ref }: ref holds the id of the step it points at, or an empty string. The numbers you see are always the position in the list, so nothing in the data needs renumbering when order changes.
How do keyboard and screen reader users reorder?
Each step has Move up and Move down buttons that name the step ("Move Lock the side door up"). In the text field, Alt+ArrowUp and Alt+ArrowDown move the step without leaving the field. The buttons at the ends stay focusable and say the step is already first or last. After a move, focus stays on the same button or field, and the status line, which is the block's one polite region, reads "Moved Lock the side door to 3 of 5".
Why do pointers survive a reorder?
Because a pointer stores the target step's id, never its number. The preview and the select options look the number up from the current order each time they render. Remove a step and the pointers to it are cleared in the same update, with the count in the status line, so the list never points at nothing.
Can I add drag and drop as well?
Yes, as an extra. Keep these buttons and keys as the accessible path and call the same move function from your drag library's drop handler with the id and the distance. The status line and the focus rule then work for both.
What stays local, and how do I connect it for real?
Everything: Save runbook keeps the order in this tab's state and says "Saved 5 steps in this demo. Nothing was sent." To make it real, post the ordered ids and texts from the submit handler, and let the server confirm the order so the status line can report a failure.