Skip to content
txbrendan/ui

Person

beta

An avatar and a name, with an optional meta line. The way to name a person anywhere.

Preview

size

Sam CarterSam CarterSam Carter

with meta

Sam CarterProduct lead · DesignSam CarterProduct lead · DesignSam CarterProduct lead · Design

strong

Kate ClarkeTeam leadJosh TaitEngineer · on leave

no photo

Mia OkaforTom HaleRecruiter

narrow

Priya Shahrazad-MontgomeryAssistant manager · Sales and Marketing

Install

  1. 1. Add the registry to components.json, once per app. Without it, the shadcn CLI looks up @txbrendan in a public list that txbrendan/ui does not control.

    npx shadcn@latest registry add "@txbrendan=https://txbrendan.dev/r/{name}.json"
  2. 2. Add the theme, once per app. It replaces your color tokens with ones checked for contrast.

    npx shadcn@latest add @txbrendan/theme
  3. 3. Add the component.

    npx shadcn@latest add @txbrendan/person

Use it for

  • Naming a person anywhere: table cells, list rows, comments, cards, and popovers. A name always has its avatar beside it.
  • meta adds a muted line under the name, like a role and a team.
  • Set strong when the name is the row's title.
  • A slot that takes a person, like a PeekCard fact or a table cell, takes a PersonValue, { person, photo, meta }, and renders Person from it. isPersonValue tells it apart from text.

Avoid it for

  • A bare name with no avatar, in a place that names people. Use Person.
  • A count of people. Use AvatarStack.
  • A name that opens the person's details on hover. Use PeekPerson.
  • Long meta text. It cuts off with an ellipsis on one line.

Props

  • name

    Required. The person's full name.

    string

  • src

    Photo URL. The avatar shows initials until it loads.

    string

  • meta

    A muted line under the name, like "Product lead · Design".

    string

  • size

    The avatar's size, as Avatar's. The name is 11, 13, or 16px, and the meta line 11, 11, or 13px.

    "sm" | "md" | "lg" · default "md"

  • strong

    The name in the strong weight.

    boolean · default false

  • className

    Extra classes on the root. Later classes win.

    string

  • PersonValue

    Type. How to pass a person into a slot. Render it as <Person name={value.person} src={value.photo} meta={value.meta} />.

    { person: string; photo?: string; meta?: string }

  • isPersonValue

    Function. True for a PersonValue, false for text and elements.

    (value: unknown) => value is PersonValue

Accessibility

  • The avatar is hidden from screen readers, so the name is read once.
  • Renders plain <span> elements, so it reads in line inside a link, a button, or a table cell.
  • The name and meta cut off with an ellipsis when there is no room. Give the full text somewhere, like the person's page or a peek.
  • The meta line uses the muted text color, held to 4.5:1 on the page, cards, and popovers.

Examples

Name and role

<Person name="Sam Carter" meta="Product lead · Design" />

A row's title

<Person name="Kate Clarke" src="/people/kate.jpg" strong />

From a PersonValue

import { Person, isPersonValue, type PersonValue } from "@/components/ui/person";

function Cell({ value }: { value: string | PersonValue }) {
  return isPersonValue(value) ? <Person name={value.person} src={value.photo} meta={value.meta} size="sm" /> : value;
}