Skip to content

shadcn.io is an independent project built on shadcn/ui

Free

Edit Profile Dialog for Vue

An Edit Profile dialog with a gradient cover, Margaret Villard's photo, her name, a username with a check, a website, and a bio count.

UI library: Ark UI

Edit Profile opens Edit profile. A gradient cover has buttons to change or remove it, and Margaret Villard's photo overlaps the corner. The fields show Margaret, Villard, margaret-villard-69 with a check, a website prefixed https://, and a biography with characters left.

Use it to edit a profile without a settings page. The check does not look the name up. A longer editor fits a Sheet. In Vue, Ark UI does not save the profile.

Preview

Preview width

Installation

MCP · Pro
Make your AI a shadcn expert
Your agent installs components, builds pages and restyles your app from one prompt, in Claude Code, Cursor or VS Code.
Part of Pro

Anatomy

Dialog anatomy: content, title, description, close, footer

Usage

<Dialog>
  <DialogTrigger :asChild="true">
    <Button variant="outline">Edit Profile</Button>
  </DialogTrigger>
  <DialogContent class="gap-0 p-0 sm:max-w-2xl">
    <DialogHeader class="px-6 py-4">
      <DialogTitle>Edit profile</DialogTitle>
    </DialogHeader>
    <div class="relative">
      <div class="h-40 bg-linear-to-r from-primary/30 via-primary/15 to-muted"></div>
      <div class="absolute end-4 top-4 flex gap-2">
        <Button aria-label="Change cover image" :pill="true" size="icon-sm" variant="secondary">
          <ImageIcon aria-hidden="true" />
        </Button>
        <Button aria-label="Remove cover image" :pill="true" size="icon-sm" variant="secondary">
          <XIcon aria-hidden="true" />
        </Button>
      </div>
      <div class="absolute start-6 -bottom-12">
        <Avatar class="size-24 ring-4 ring-background">
          <AvatarImage alt="Margaret Villard" src="https://github.com/shadcn.png" />
          <AvatarFallback>MV</AvatarFallback>
        </Avatar>
        <Button
          aria-label="Change profile photo"
          class="absolute end-0 bottom-0"
          :pill="true"
          size="icon-sm"
        >
          <ImageIcon aria-hidden="true" />
        </Button>
<!-- The rest of the file is under Installation. -->

FAQ

How do the image buttons upload?

They're icon buttons with an aria-label and no handler. Have each open a hidden file input with accept="image/*", preview the file, and upload it when people save.

Does the check mean the username is available?

It's a static text-success check in an InputGroupAddon. Check availability as people type, with a short debounce, and swap the icon for a spinner or an error while it runs.

How does the character counter work?

The textarea is controlled with maxLength of 200, and a FieldDescription under it shows 200 minus the current length.

How is the https:// prefix built?

An InputGroup with the InputGroupInput and an InputGroupAddon holding InputGroupText. The addon comes after the input in the markup, so clicking it focuses the input, and align="inline-start" shows it first.

How do I warn about unsaved changes?

Compare the values with what you loaded and, when someone closes with changes, ask before discarding. Control the dialog to intercept the close. Bind v-model:open.

How is the cover styled?

A soft gradient of the theme's primary color, bg-linear-to-r from-primary/30 via-primary/15 to-muted, so it works in light and dark mode. Replace it with the person's image.

API Reference

Dialog

Sets asChild. The rest is on the Dialog page.

Button

Sets variant="outline", aria-label="Change cover image", pill, size="icon-sm", variant="secondary" and aria-label="Remove cover image". The rest is on the Button page.

Avatar

Sets alt="Margaret Villard" and src="https://github.com/shadcn.png". The rest is on the Avatar page.

Field

No extra props in this demo. The rest is on the Field page.

Input

Sets defaultValue="Margaret", name="first-name", type="text", defaultValue="Villard" and name="last-name". The rest is on the Input page.

Input Group

Sets name="username", input="handleUsernameChange", type="text", value="username", align="inline-end" and defaultValue="www.margaret.com". The rest is on the Input Group page.

Textarea

Sets maxLength="maxBioLength", name="bio", input="handleBioChange" and value="bio". The rest is on the Textarea page.