Skip to content
Component installs need the registry setup
VegaStack Design

Person Hover Card

Overlapping 24px avatars with a compact hover card per person (a 32px avatar, the name and a muted email) and a "+N" count; the stack lists everyone.

Status
stable
Since
0.23.19
Accessibility pattern
named buttons, hover card on hover and focus, tap on touch

Last updated

Install

Add Person Hover Card from the VegaStack registry. The CLI verifies the item's integrity hash before writing it.

pnpm dlx shadcn@latest add @vegastack/person-hover-card

The same command installs the registry items it composes: @vegastack/avatar, @vegastack/button, @vegastack/hover-card, @vegastack/popover, @vegastack/searchable-select.

Usage

import { AvatarStack } from "@/components/ui/person-hover-card";

<AvatarStack people={participants} label="Participants" />;

AvatarStack stacks up to max (5) 24px avatars — overlapping, each ringed in the background colour — with the rest counted in a "+N". Hovering an avatar previews that person: a compact 240px card with a 32px avatar and, beside it, the name over a smaller muted email (always shown when known). The stack is one button: click, tap or Enter lists everyone in the same format. Someone without an account (a free-text participant such as "Northwind FM leads") has no email: their avatar shows initials and the card just the name.

Anatomy

AvatarStack — data-slot="avatar-stack"
PersonHoverCard
PersonCard — data-slot="person-card"
PersonAvatar

Examples

One person

PersonHoverCard wraps any trigger — usually a PersonAvatar — in a round ghost button named by the person.

The card

PersonCard is the card's body (layout="card") and a compact list row (layout="row").

AR
Asha Raoasha@acme.com
NF
Northwind FM leads
DM
Dev Menondev@acme.com

Inactive member

badge on the person puts a status right after the name — a string such as "Inactive" is a small muted outline badge. It shows in PersonCard, the hover card and the AvatarStack list. For a table's person cell, compose PersonAvatar with the name and PersonBadge.

RK
Ravi KumarInactiveravi@acme.com

API Reference

AvatarStack

PropTypeDefaultDescription
people*readonly Person[]—The people, in order.
classNamestring—Classes for the group.
labelstring"People"The group's accessible name.
maxnumber5How many avatars show before the rest go behind "+N".

Data attributes and CSS variables on AvatarStack

AttributeValues
data-slot"avatar-stack"

PersonHoverCard

PropTypeDefaultDescription
children*React.ReactNode—The trigger — usually a PersonAvatar. It is wrapped in a round ghost button named by the person.
person*Person—The person.
classNamestring—Classes for the trigger button.

PersonCard

PropTypeDefaultDescription
person*Person—The person.
layout"card" | "row""card"card — the hover card's body: a 32px avatar with the name and email stacked beside it. row — one line of a list: a smaller avatar beside them.

Data attributes and CSS variables on PersonCard

AttributeValues
data-layoutmirrors a prop or state value
data-slot"person-card"

PersonAvatar

PropTypeDefaultDescription
person*Person—The person.
classNamestring—Classes for the avatar.
size"default" | "lg" | "sm""sm"Avatar size.

Accessibility

  • The stack is one button named "{label}: {names}"; it opens the full list, so keyboard and touch users reach every person without the hover previews.
  • PersonHoverCard on its own is a round button named by the person; its card opens on hover and on keyboard focus, a tap toggles it, and Esc closes it.
KeyAction
TabMove to the stack
Enter / SpaceList everyone (or open a person's card)
EscClose the list or the card
ContractStates tested
Behaviourstack, overflow, hover-card
Accessibilitylabeled, browser-accessibility-test
Visualdefault, open

Do / Don't

Do
Pass an email only for people with an account; a free-text participant is just a name.
Don't
Put actions in the hover card — it is a preview; link to the person's page instead.

On this page