Peek Person
betaAn avatar and a name that opens the person's PeekCard on hover, focus, or tap.
Preview
rows
- Sam Carter
- Josh Tait
- Kate Clarke
size
Install
1. Add the registry to
components.json, once per app. Without it, the shadcn CLI looks up@txbrendanin a public list that txbrendan/ui does not control.npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"2. Add the theme, once per app. It replaces your color tokens with ones checked for contrast.
npx shadcn@latest add @txbrendan/theme3. Add the component.
npx shadcn@latest add @txbrendan/peek-person
Use it for
- Naming a person where people want more without leaving the page: a list row, a comment, an assignee.
- It looks like Person and takes the same props, plus peek: the PeekCard to show, like status, facts, and actions.
- The peek's person comes from name and src. meta is its subtitle unless peek sets one.
- Mark each row of a list with data-peek-row, so the peek opens beside the row.
Avoid it for
- A name with nothing more to show. Use Person.
- A name that is itself a link to the profile. Put the link in the peek's more, so the name stays a peek.
Props
- name
Required. The person's full name. It titles the peek too.
string
- src
Photo URL, for the avatar and the peek.
string
- meta
A muted line under the name. It is the peek's subtitle unless peek sets one.
string
- size
Avatar and name size.
"sm" | "md" | "lg" · default "md"
- strong
The name in the strong weight, as a row's title.
boolean · default false
- peek
The PeekCard to show: status, facts, people, actions, and more.
Omit<PeekCardProps, "person" | "photo">
- open
Controlled. The peek shows while true. Hover, focus, and Esc only ask, through onOpenChange.
boolean
- defaultOpen
Starts with the peek open, without taking focus.
boolean · default false
- onOpenChange
Hears the peek open and close, or what it asks for when controlled.
(open: boolean) => void
- className
Extra classes on the trigger. Later classes win.
string
| Prop | Type | Default | What it does |
|---|---|---|---|
| name | string | - | Required. The person's full name. It titles the peek too. |
| src | string | - | Photo URL, for the avatar and the peek. |
| meta | string | - | A muted line under the name. It is the peek's subtitle unless peek sets one. |
| size | "sm" | "md" | "lg" | "md" | Avatar and name size. |
| strong | boolean | false | The name in the strong weight, as a row's title. |
| peek | Omit<PeekCardProps, "person" | "photo"> | - | The PeekCard to show: status, facts, people, actions, and more. |
| open | boolean | - | Controlled. The peek shows while true. Hover, focus, and Esc only ask, through onOpenChange. |
| defaultOpen | boolean | false | Starts with the peek open, without taking focus. |
| onOpenChange | (open: boolean) => void | - | Hears the peek open and close, or what it asks for when controlled. |
| className | string | - | Extra classes on the trigger. Later classes win. |
Accessibility
- The trigger is a focusable button that opens a dialog. Its name is the person's name and meta.
- The avatar is hidden, so the name is read once.
- The peek is named by the person's name, its PeekCard title. Enter moves into it, and Esc closes it and puts focus back.
Examples
In a list row, with a status and an action
<PeekPerson
name="Josh Tait"
meta="Engineer · Mobile app"
peek={{
status: { label: "Off sick", tone: "danger" },
facts: [["Back", "Mon 19 Oct"]],
actions: [{ label: "Message" }],
more: { label: "Profile", href: "/people/josh-tait" },
}}
/>