Blocks
Profile card
Account card that opens an action menu: the trigger is a rich identity chip (avatar over name and handle), the popup a grouped menu ending in a destructive sign-out.
Preview and props
Expand Props below the centered preview to change the component’s properties.
Examples
Switch presentation variants and identity options, then explore the profile actions.
Example controls
no selection yet
Usage
import { ProfileCardBlock, useAuthSession, useAuthSessionActions } from "@exegia/corpora-ui"
// The signed-in IAuthUser from the shared session drops straight in, and
// signOut clears the session and returns the auth flow to the login step.
const { user } = useAuthSession()
const { signOut } = useAuthSessionActions()
<ProfileCardBlock
user={user ?? { name: "Jenny Hamilton", username: "@jennycodes", avatar: src }}
items={[
{ type: "label", label: "Management" },
{ id: "profile", label: "Profile", icon: <UserIcon />, onSelect: () => navigate("/profile") },
{ type: "separator" },
{ id: "sign-out", label: "Log out", icon: <LogOutIcon />, variant: "destructive", onSelect: signOut },
]}
/>API notes
| Prop | Type | Default | Description |
|---|---|---|---|
| user (required) | IProfileCardUser | — | Identity on the card ({ name, username?, avatar?, initials?, presence? }). Initials fall back to the name's first and last word. |
| items | TProfileCardItem[] | defaultProfileCardItems | The whole menu, flat: actions ({ id, label, icon?, shortcut?, disabled?, variant?, onSelect? }) plus { type: “separator” } and { type: “label”, label } entries. Each run between separators becomes its own group, headed by the label inside it. |
| onSelect | () => void | Promise<void> | — | Per item. Returning a promise puts the card in its loading state until it settles; a rejection goes to onError. |
| align / side / sideOffset | "center" | "start" | "end" / Side / number | "center" / "bottom" / 8 | Menu placement relative to the card. |
| menuWidth | "content" | "card" | "content" | “content” sizes the menu to its items; “card” locks it to the trigger's width. |
| variant | "expanded" | "collapsed" | — | collapsed folds the card to its avatar for an icon rail — name, handle and chevron animate to zero width, the avatar stays, title names the tile on hover, the accessible name is unchanged. Controlled when passed; unset, it follows the AnimatedPanel it sits in (a SidebarBlock footer folds with ⌘B on its own), else defaultVariant. |
| defaultVariant / onVariantChange | "expanded" | "collapsed" / (variant) => void | "expanded" | Uncontrolled start value, and the change report (fires for store-driven changes too). |
| profileCardId | string | — | Names this card's slice of the Jotai store: useProfileCardState(id) reads variant / menuOpen / busy, useProfileCardActions(id) folds it or opens its menu from anywhere under ExegiaProvider. Unnamed cards key off useId and are dropped on unmount. |
| presence | "online" | "idle" | "offline" | — | Presence badge on the avatar (presence overrides user.presence). |
| open / defaultOpen / onOpenChange | boolean / boolean / (open, details) => void | — | Control the menu, or observe it. |
| sound | boolean | true | Press/release cues on the card plus open/close cues on the menu. Inert until the app calls bindSounds(). |
Last updated on
Auth flow
Orchestrator over the auth blocks: renders the right block for the flow's current step (login, signup, verify-code, forgot-password, update-password, onboarding, success) with the store wiring built in — the switchboard every host app was hand-rolling around `useAuthFlow`.
Navbar
Application top navigation with branding and user menu.