Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Reorder Items Dialog Block for React

A landing-page builder's reorder dialog shown open: five page sections with grips you lift with Space and move with the arrow keys, Move up and down buttons, a spoken position, and the page behind it rearranging on save.

Framework
UI library

Preview

Preview width

Installation

Part of Pro
Pro unlocks the code and one-line install of every Pro button and text effect, plus the MCP for your AI editor.
Have Pro already? Sign in to open it.Opens here as soon as you're Pro.

Overview

Let people put things in order without a mouse, with this reorder dialog for React with Base UI. It opens from the Home page of Brickfold, a landing-page builder: the page's header holds an outline Reorder sections Button, and the page itself, a browser frame with five labelled bands, Hero, Logos, Features, Pricing and FAQ, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog lists the five sections as rows, each with a grip that is a real button, a position number, the section's name and one line about it, and Move up and Move down buttons. Focus a grip and Space lifts the row, the arrow keys, Home and End move it, Space drops it and Escape puts it back, while a line under the list says where it is, "Pricing moved to position 2 of 5". A pointer can drag the same grip. Reset order goes back to the order Brickfold ships with, and the only Shine Button, Save order, rearranges the bands of the drawn page. For preview the dialog is drawn open in place when the page loads; the header button opens the real Dialog, with the same list. For page builders, menus, playlists and any list whose order is the content.

FAQ

Why is the dialog already open, and what do I keep?

So you can see it without a click. On load the dialog is a copy drawn in place over the page: a native dialog element that isn't modal, so nothing is trapped, hidden or focused, and the page around the preview keeps working. The Reorder sections button opens the real Dialog, modal, with its focus trap, Escape and focus return, and the copy stays closed until a reload. Both show the same OrderBody component and share the block's state, so what you moved in the copy is there in the real one. In your app keep the Dialog and drop the copy: the "in-place" state, the scrim and the dialog element inside the frame.

How do the keys work, and what does Escape do?

Tab to a row's grip. Space or Enter lifts it (the grip shows as pressed and a line says "Lifted Pricing, position 4 of 5"), Up and Down move it one place, Home and End send it to the first or last place, and Space or Enter drops it. Escape while a row is lifted puts the list back as it was when you lifted it and keeps the dialog open; a second Escape closes the dialog. Focus stays on the grip as the row moves, and each move is said in a polite message with the new position out of five.

What about touch and the mouse?

Every row has Move up and Move down buttons, which are the whole interaction for a phone and for anyone who prefers pressing to holding: focus stays on the button you pressed, or moves to its partner when the row reaches an end. The grip also takes a pointer drag, written with pointer events and a transform, no drag library: the row follows the pointer, the others step aside, and releasing drops it. Drag is the extra, never the only way.

What is saved, and how do I wire it up?

Nothing leaves the tab. Save order copies the order into the drawn page's bands and says so in a polite message, and says "nothing to save" when the order is unchanged. Reset order goes back to the shipped order, and Cancel or Escape throws the unsaved order away. In your app keep the list of ids in state as here and post it from save; the server's order is the one to render back.

Is it accessible from the keyboard and a screen reader?

Yes. The real dialog is named by its title and described by its sentence, focus starts on the first grip and stays inside until it closes, and Escape, Cancel and the close button return focus to Reorder sections. Every grip is named with its section and position, "Reorder Pricing, position 4 of 5", and described by the key instructions, so nothing depends on seeing the drag. The trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange. The copy shown on load moves no focus; Escape inside it, Cancel and its close button close it and put focus on the button.

  • Pro

    Sort Options Dialog

    Notes and editing

    A data-grid tool's sort dialog shown open: up to three rules with a field and a direction each, Move up, Move down and Remove, a sorted five-row preview with the sorted columns numbered, and the table re-sorting on apply.

  • Pro

    A list of five digest sections with Move up and Move down buttons and a pointer-drag grip; a drawn digest preview follows the order, and each move is announced.

  • Pro

    Eight drawn portfolio pages in a framed grid that you reorder by dragging a grip, by Space and the arrow keys, or with Move earlier and Move later buttons, with every move announced and logged.

  • Pro

    A priority backlog you reorder by dragging a grip or pressing Move up and Move down, with a live numbered Order list beside it and the new position announced after every move.

  • Pro

    Column Reorder Table

    Columns and paging

    A pipeline table with a Column order list beside it: Move earlier and Move later buttons reorder the columns and announce the move, a grip drags as an extra, and Reset restores the default order.

  • Pro

    A vinyl shop's records page with its filter panel shown open as a sheet from the start edge: genre chips, a decade list, a two-thumb price range, conditions, an in-stock switch and a sort order, all changing the grid behind it as you touch them.