Skip to content

Account Menu

Give signed-in users a menu for their account, workspaces, theme and sign-out action.

import { AccountMenu, AccountMenuUser, AccountMenuWorkspace } from '@youj/react'

Installation & usage

npm i @youj/react

For an app already set up with npx @youj/cli init, which installs the peers (@youj/core, @youj/motion, motion and Base UI) and wires the provider. New app? Start at Installation.

Use it at the end of an App Header or at the foot of a Sidebar: the one place a person finds their profile, settings, theme and the way out. It's a Dropdown Menu with the account parts already laid out, so build your own dropdown when the menu isn't about the signed-in user. When switching workspaces is a main job in the app, give it a Workspace Switcher of its own.

import {
  AccountMenu,
  DropdownMenuGroup,
  DropdownMenuItem,
  DropdownMenuShortcut,
  type AccountMenuUser,
} from '@youj/react'

export function Account({ user, onSignOut }: { user: AccountMenuUser; onSignOut: () => void }) {
  return (
    <AccountMenu user={user} onSignOut={onSignOut}>
      <DropdownMenuGroup>
        <DropdownMenuItem>Profile</DropdownMenuItem>
        <DropdownMenuItem>
          Settings
          <DropdownMenuShortcut>⌘,</DropdownMenuShortcut>
        </DropdownMenuItem>
      </DropdownMenuGroup>
    </AccountMenu>
  )
}

The trigger is the user's avatar, with their initials until the image loads (or if it fails). The menu opens with a profile header: a larger avatar, the name and the email, each truncated when it runs long. Then, in order and each behind a separator:

  1. Workspaces, when you pass workspaces: a radio group of logos and names, with a check on workspace. onWorkspaceChange reports a choice.
  2. Your items: children, any Dropdown Menu rows and groups.
  3. Theme, when you pass theme or colorMode: a submenu with the built-in presets, each wearing its accent, and an appearance choice of light, dark or system.
  4. Sign out, when you pass onSignOut.

Reference

Propsuser, workspaces, workspace… (14)

Props

AccountMenu props
PropType
userRequiredAccountMenuUser–
workspacesAccountMenuWorkspace[]

Workspaces to switch between, shown as a radio group.

–
workspacestring–
onWorkspaceChange(id: string) => void–
themestring

The active preset's id (graphite, terminal…). The Theme submenu shows when this or colorMode is set.

–
onThemeChange(id: string) => void–
colorModeColorMode
'system''light''dark'
–
onColorModeChange(mode: ColorMode) => void–
onSignOut() => void

Adds Sign out at the end.

–
childrenReactNode

Your own rows, between the profile and the theme: DropdownMenuItem, DropdownMenuShortcut, groups.

–
alignAlign
'end''start''center'

default 'end'

'end'
sideSide
'left''right''top''bottom''inline-end''inline-start'
–
triggerReactElement<Record<string, unknown>>

Your own trigger in place of the avatar, e.g. a sidebar's account card or a status pill: an element the trigger renders as, with its content inside. It keeps the menu's accessible name unless it brings its own.

–
classNamestring

The trigger's class.

–
MotionOpen, close, highlight… · reduced motion

Motion

The motion is the Dropdown Menu's.

Motion tokens
MomentTokens
Opengrows out of the avatar: scale .96 → 1 and fade (yj-pop)
duration.fastease.enter

140ms · cubic-bezier(0.16, 1, 0.3, 1)

140mscubic-bezier(0.16, 1, 0.3, 1)
Close
duration.instantease.exit

80ms · cubic-bezier(0.4, 0, 1, 1)

80mscubic-bezier(0.4, 0, 1, 1)
Highlightone Sliding Indicator glides between rows
spring.smooth

0.36s, bounce 0

0.36s, bounce 0
Checkdraws in on the chosen workspace, preset or appearance
duration.slowease.emphasized

340ms · cubic-bezier(0.6, 0, 0.1, 1)

340mscubic-bezier(0.6, 0, 0.1, 1)
Trigger ringappears around the avatar while the menu is open
duration.fastease.standard

140ms · cubic-bezier(0.2, 0, 0, 1)

140mscubic-bezier(0.2, 0, 0, 1)
Theme and Sign out iconsplay as their row is highlighted
no token

per icon

per icon

Reduced motion

The menu and its submenu appear at once, the highlight jumps between rows, and checks appear already drawn.

Reduced motion

The menu opens and closes at once, the highlight moves from row to row without gliding, and checks appear already drawn. Keyboard handling and submenus work the same.

AccessibilityKeyboard, focus, announcements

Accessibility

  • The trigger is a button named "Account: " and the user's name. The avatars inside are decorative.
  • Everything else is the Dropdown Menu's: roving focus with ↑ and ↓, typeahead, Home and End, and Escape to close and return focus to the avatar.
  • The Theme row opens its submenu on → (← to come back), mirrored in right-to-left layouts. Workspaces, presets and appearance are radio groups, so the chosen one is announced as checked.
  • Each preset's color dot is decorative; its name is the label.