Profile Modal

Tabbed user account settings modal dialog built on Radix Dialog primitive with two-column side avatar layout.

// Radix — @radix-ui/react-dialog
import { ProfileModal } from "@shavin/ui";

With tabs + avatar column

{open && (
  <ProfileModal
    title="Account"
    onClose={() => setOpen(false)}
    tabs={TABS}
    activeTab={tab}
    onTabChange={setTab}
    avatar={
      <div className="flex flex-col items-center gap-2 border-r border-hairline p-6 pt-8">
        <span className="flex h-24 w-24 items-center justify-center rounded-full bg-accent text-2xl font-semibold text-accent-fg">
          J
        </span>
      </div>
    }
  >
    <div className="divide-y divide-hairline">
      <CardRow label="Name">
        <span>Jordan Rivera</span>
      </CardRow>
      <CardRow label="Email">
        <span className="text-fg-muted">jordan@example.com</span>
      </CardRow>
    </div>
  </ProfileModal>
)}

Without tabs, no avatar column

{open && (
  <ProfileModal title="Backup" onClose={() => setOpen(false)}>
    <div className="p-5 text-sm text-fg-muted">
      Single content, no tab strip, no avatar column.
    </div>
  </ProfileModal>
)}

Props

PropTypeDefault
title*string
onClose*() => void
tabsreadonly ProfileModalTab<T>[]
activeTabT
onTabChange(key: T) => void
avatarReactNode
children*ReactNode
dismissibleboolean

* required

Configure Theme
Theme
Accent Color
Custom
Gray Family
Appearance
Radius
Scaling
Panel Style
Heading Font
Body Font