Skip to content
shadcn.io

shadcn.io is not affiliated with official shadcn/ui

Edit Profile Dialog Block for React

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 Base UI. 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 trigger is passed to DialogTrigger through render, and the dialog is controlled with open and onOpenChange. The bio's count is said at 20 and 10 characters to go, at none and when over, never on every key.

  • Pro

    Add Profile Dialog

    Account and security

    A newsletter's writers page with its byline composer shown open: a name, what they write, a 120 character bio, a mark from six drawn glyphs or initials and a switch, beside a card that shows the byline as it will print.

  • Pro

    Unsaved Changes Dialog

    Confirm and consent

    An essay editor with its leave prompt shown open: an alert dialog that lists what changed since the last save and offers Save and leave, Discard changes and Keep editing.

  • Pro

    Change Password Dialog

    Account and security

    A password manager's account page with its change-password dialog shown open: three password fields, a live checklist of five rules with a strength meter, a match line, and an Update button that stays quiet until every rule passes.

  • Pro

    A stand-up update composer whose character counter is a ring that fills to 280, shows its number only near the end, goes negative past the limit and is spoken at four stages, with a list of the latest two posts.

  • Pro

    Account Deletion Settings

    Backups and exports

    A whole-page account deletion that first asks what happens to each kind of data (delete, anonymise or transfer, with invoices locked for tax law), sums the choices in one sentence, then schedules deletion 14 days out behind a typed-email alert dialog.

  • Pro

    API Key Dialog

    Account and security

    A keys page with its create-key dialog shown open: a name, scopes and an expiry in the first step, then the secret shown once, masked behind an eye button, with a Copy button and a box that has to be ticked before Done.