An avatar that widens into the account panel: who's signed in, the workspace (switched in a step that slides in), links, the theme and sign out.
Installation
When to use
- The avatar in an app's header, or the account at a sidebar's foot (showName, side top): everything about the person signed in, in one place.
- Apps with several workspaces or teams: switching happens inside the same panel, without a page.
When not to use
- A site with no accounts: a plain link to sign in is enough.
- Many settings to change at once: they belong on a settings page the menu links to.
Usage
Account Menu with your own data: a whole component you can paste as a page.
"use client"
import { AccountMenu } from "@/components/dashral/pro/account-menu"
import { useState } from "react"
import { Settings, UserRound } from "lucide-react"
const workspaces = [
{ id: "halcyon", name: "Halcyon Studio", detail: "Pro · 12 members" },
{ id: "orbit", name: "Orbit Labs", detail: "Team · 28 members" },
]
const items = [
{ id: "profile", label: "Profile", icon: <UserRound />, href: "/profile" },
{ id: "settings", label: "Settings", icon: <Settings />, href: "/settings" },
]
export default function Account() {
const [workspace, setWorkspace] = useState("halcyon")
const [theme, setTheme] = useState<"light" | "dark" | "system">("system")
return (
<AccountMenu
user={{ name: "Maya Lindqvist", email: "maya@halcyon.studio" }}
workspaces={workspaces}
workspace={workspace}
onWorkspaceChange={setWorkspace}
items={items}
theme={{ value: theme, onValueChange: setTheme }}
onSignOut={() => console.log("signed out")}
/>
)
}API reference
AccountMenu
An avatar that widens into the account panel: who's signed in, the workspace (switched in a step that slides in), links, the theme and sign out (checked in a step of its own). Shrinks back onto the avatar when done.
| Prop | Type | Default |
|---|---|---|
user | AccountUserRequired. | — |
workspaces | AccountWorkspace[] | — |
workspace | stringThe workspace in use, by id (controlled), or the first. | — |
defaultWorkspace | string | — |
onWorkspaceChange | (id: string) => void | — |
onCreateWorkspace | () => voidAdds "Create workspace" under the workspaces. | — |
items | AccountItem[] | [] |
theme | { value: AccountTheme; onValueChange: (theme: AccountTheme) => void }A theme switch in the panel: light, dark or system. | — |
onSignOut | () => voidAdds Sign out, after a check inside the panel. | — |
showName | booleanThe button: the avatar alone (default), or the avatar with the name, for a sidebar's foot. | false |
side | "bottom" | "top"Where it opens: down from the button (default) or up from it. | "bottom" |
align | "start" | "end"Which edge it keeps: the button's end (default) or its start. | "end" |
width | numberThe panel's width, in px (never wider than the screen). | 300 |
linkAs | React.ElementTypeYour router's link for items with an href; a plain <a> by default. | "a" |
className | string | — |
classNames | AccountMenuClassNames | — |
type AccountUser
| Prop | Type | Default |
|---|---|---|
name | string | — |
email | string | — |
avatar | stringA picture; initials from the name until (or instead of) it. | — |
status | AvatarStatus | — |
type AccountWorkspace
| Prop | Type | Default |
|---|---|---|
id | string | — |
name | string | — |
logo | React.ReactNodeIts mark: a logo or an initial. The first letter of its name on a tile by default. | — |
detail | stringA line under its name: its plan, its members. | — |
type AccountItem
| Prop | Type | Default |
|---|---|---|
id | string | — |
label | string | — |
icon | React.ReactNode | — |
shortcut | string[]Its keys, shown beside it (["mod", ","]). Shown only: wire them in your app if they should work outside. | — |
href | stringA link (rendered with | — |
onSelect | () => void…an action. | — |
group | stringItems of the same group sit together; a line separates groups. | — |
type AccountTheme
= "light" | "dark" | "system"type AccountMenuClassNames
| Prop | Type | Default |
|---|---|---|
root | string | — |
button | string | — |
panel | string | — |
Keyboard
| Keys | Action |
|---|---|
| ↑or↓ | Through the rows |
| HomeorEnd | The first or last row |
| →orEnter | On the workspace: open the workspaces; on Sign out: open the check |
| ←or→ | On Theme: light, dark or system |
| ← | In a step: back to the menu |
| Esc | Back from a step, or close; the focus returns to the avatar |
Accessibility
- The button is named "Account: <name>" (or shows the name, with showName) and says whether its panel is open.
- The panel is a dialog (aria-modal); its rows are menu items with one tab stop, the workspaces menu item radios with aria-checked, the theme a radiogroup.
- Sign out asks first, inside the panel, so it can't happen by a stray press.
Motion
- The avatar widens into the panel (0.42 s) and, closing, the panel shrinks back while the two crossfade.
- One highlight glides from row to row; the workspaces and the sign-out check slide in as the panel reshapes. A picked workspace's check moves first, then the step slides back. The theme thumb glides (right to left too).
- Smooth tweens on [0.4, 0, 0.2, 1], never springs, except the small press. With reduced motion it only fades.