Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Edit Profile Dialog Block for React Aria

A community profile page with its edit dialog shown open: a display name, a username checked against the names already taken, a main craft you type or pick, a bio with a 160 character count, and a strip of chips that says what changed.

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 fix how they appear, with this profile editor for React with React Aria. It opens from the profile page of Emberhall, a community for people who work with fire and clay: the page's header holds an outline Edit profile Button, and the profile itself, a hatched cover, an initials avatar, a name, a handle, a craft and a bio, is drawn under a soft scrim inside a hairline frame with a plus mark on each corner. The Dialog has a display name Input, a username in an Input Group with an at sign that says at once whether it is yours, free or taken ("@ember is taken. Try @ember_", with a button that takes the suggestion), a main craft in a Combobox you can type into or pick from, and a bio Textarea with a count. A strip under the fields lists what changed as chips, with Reset, and Save changes, the only Shine Button, stays quiet until something has. For preview the dialog is drawn open in place when the page loads; the Edit profile button opens the real Dialog, with the same fields. For community, social and member pages, and any app with a public profile.

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 Edit profile 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 ProfileFields component and share the block's state, so what you typed 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 is the username checked?

Against TAKEN, a typed list, as you type: three to twenty letters, numbers, dots and underscores, in lower case, with spaces and a leading at sign removed. Your own name is "your username today", a name on the list is taken and offers the first free variant (@ember_, then _1, _2), and anything else is available. The line under the field changes at once; what a screen reader hears is said 600 ms after the typing stops, and only when it changes. In your app ask your server in verdictOf, and treat its answer on save as the last word, since a name can be taken between the check and the save.

What does the strip under the fields say?

What differs from the saved profile, derived from the draft: "2 unsaved changes:" and one chip for each of Display name, Username, Main craft and Bio. Reset puts the saved values back and moves focus to the name. Save changes is quiet and pressable while nothing has changed, and answers "No changes to save." instead of closing. With a problem it stays open, says what is wrong under that field and puts focus in it.

How does the craft field work?

It is a Combobox over a typed list of fourteen crafts: type to narrow the list, pick one, or clear it with the button in the field. A word that matches nothing shows "No craft with that name here." Picking a craft changes the draft and the strip; the saved profile changes when you save, and then the drawn profile's craft chip changes too.

What stays local in the demo, and how do I wire it up?

All of it. The saved profile and the taken names are typed constants, and Save changes only updates the drawn profile and says in a polite message that nothing was stored. In your app send the changed fields from save, replace the drawn profile with the response, and show your server's reason in the field it names.

Is it accessible from the keyboard?

Yes. The real dialog is named by its title and described by its sentence, focus starts in the display name and stays inside until it closes, and Escape, Cancel and the close button return focus to Edit profile. The button and the dialog sit inside DialogTrigger, controlled with isOpen and onOpenChange, React Aria focuses the dialog itself so a frame later focus moves to the display name, and the title is a level 2 heading. The bio's count is said at 20 and 10 characters to go, at none and when over, never on every key.