Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Listing Editor Form With Sidebar Block for Radix UI

A listing editor in a fixed-height window with a section index that follows the scroll, statuses worked out from the fields, and one Save listing action in the top bar.

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

Edit a long listing without losing your place with this form-with-sidebar window for React with Radix UI. A hairline frame with a plus mark on each corner holds a fixed-height window with no header above it: a top bar with the title "Edit listing" and the one primary, Save listing, then a plain index at the start and the form beside it. The index lists five sections (Basics, Location, Rooms, Rules, Pricing), each with a tick or an alert icon and a status word worked out from the fields ("1 to fix", "Done"); the form scrolls inside the window, the section in view is the one marked in the index, and pressing an entry scrolls to it and puts focus on its heading. On a phone the index is a Select that does the same. Fields check themselves when you leave them; Save listing shows every message, says how many sections need fixing and focuses the first field to fix. A licence number is needed only while alcohol is served. It's built from Field, Input, Textarea, Select, Switch, Input Group and Shine Button, with a CSS entrance only. For long records, settings with many sections and any editor that needs an index.

FAQ

How do I add a section or a field?

Add a Section (its id, name, a line and the fields it holds) to SECTIONS, a key to FieldKey, a rule to problemsOf and a Block with its fields to the form. The index, the statuses, the jump Select and the "sections to fix" count all come from SECTIONS and problemsOf, so nothing is typed twice. A status is the number of the section's fields that have a problem, whether or not you have touched them.

How does the index follow the scroll?

A scroll handler on the form's region works out which section's top has passed, and marks that entry with aria-current; at the very end of the scroll the last section is the current one, so a short last section is still reachable. Pressing an entry scrolls the region (never the page) to that section and holds the mark there while the scroll settles; with reduced motion it jumps instead of gliding. The heading takes focus so a keyboard or screen reader user lands where the page did.

What happens on a phone?

The index is hidden and a Select named "Jump to a section" sits under the top bar, with the section's status beside it. Choosing a section scrolls to it and moves focus to its heading once the list has closed. The window keeps its height and only the form scrolls; the one primary stays in the top bar. The Select is named "Jump to a section".

When do the problems show?

A field shows its problem once you have left it, and Save listing shows all of them: the foot says "Not saved: 2 sections to fix." and focus moves to the first field in reading order that has a problem. Each field has one reserved line for its hint or its problem, so nothing moves as messages appear, and a problem is a warning icon plus words, never colour alone. Turning alcohol off locks the licence field and clears its problem.

What stays local, and how do I connect it for real?

Nothing is saved: Save listing says "Saved here only. Nothing was sent." Replace the body of submit with a call that stores the listing, and run the same problemsOf on the server. With react-hook-form or TanStack Form the values are the fields of Listing; keep problemsOf as the validator so the statuses and the form agree.