Navigation
AccountMenu
The signed-in identity and the actions that belong to it, at the end of the app header.
Where it goes
In the header, not in the sidebar foot. The sidebar is already the full height of the window, so a menu opened in its last row grows past the bottom edge, and the entry that gets cut is Sign out every time. The header has room below it by construction.
Basic
The menu is your content. It takes links and forms rather than a list of callbacks, because the
things an account menu holds are mostly navigations and one form post. Each entry is an AccountMenuItem, and the form that ends the session goes in footer,
under a rule after the rows.
Ada Lovelace
Ada Lovelace
ada@example.com
Rows
An AccountMenuItem is drawn like a resting SidebarNav row: its icon in a
16px column of its own, and a muted label that turns to full text color on a surface-2 fill under
the pointer, with no border, shadow or fill at rest. The account menu reads as the same kind of
list as the navigation beside it. Sign out is an ordinary row, because ending a session loses
nothing. While a sign-out posts, loading refuses a second press and turns the icon into
a spinner of the same size, so the label does not move. The menu closes on the press, so the spinner
shows when the reader opens it again before the submit ends.
It works without script
A native details, not a menu assembled from buttons. The panel holds links and a form
post, and both have to keep working when hydration fails or never runs, which is exactly the
moment somebody most needs to be able to sign out. Closing on Escape, on an outside click and on a
pick are enhancements on top. A pick is a link or a button that posts a form, and the menu gives
focus back to its trigger. A click canceled by a listener on the row itself never reaches the menu
and leaves it open. A Svelte onclick runs later, at the app's root, so the menu closes
first and a dialog it opens gives focus back to the trigger. The disclosure still opens and closes without
any of these.
Initials
Derived from name when you do not pass them, splitting on spaces and on the
separators an email address uses. An account with no display name shows its email here, and ada@example.com reads as AE rather than as ad. The avatar is aria-hidden: the initials are paint, and left readable they prefix the trigger's
accessible name with two letters nobody would speak at it. Initials given a tone read at
4.5:1 or better on the trigger at rest and under the pointer or a finger.
ada.lovelace@example.com
ada.lovelace@example.com
Ada Lovelace
Ada Lovelace
API
| Prop | Type | Default | Description |
|---|---|---|---|
name required | string | no default | The line people recognize themselves by: a display name, or the email. |
secondary | string | no default | Under it. The email when the name is a name, otherwise a role or a plan. |
initials | string | no default | The avatar letters. Derived from name when absent. |
tone | 'neutral' | 'brand' | 'success' | 'warn' | 'danger' | 'violet' | 'brand' | The avatar accent. Follows the app, not the person. Its type is AccentTone. |
class | string | no default | Extra classes on the disclosure. |
children required | Snippet | no default | The menu: AccountMenuItem rows. |
footer | Snippet | no default | Under a rule after the rows: the form that ends the session. |
AccountMenuItem
| Prop | Type | Default | Description |
|---|---|---|---|
href | string | no default | A link when given, otherwise a button. |
target | string | no default | The link target, such as _blank. |
rel | string | no default | The link relation, such as noreferrer noopener. |
type | 'button' | 'submit' | 'button' | Only for the button. submit posts the form around it. |
icon | Component | no default | An icon component, drawn at 16px in its own column. |
loading | boolean | false | The submit is in flight: the button refuses a second press and the icon turns into a spinner. |
class | string | no default | Extra classes on the row. |
children required | Snippet | no default | The label. |