# Person

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

- Name: `person`
- Status: beta
- Categories: people, display
- File: the install writes `person.tsx` to your `ui` alias, `@/components/ui` by default.
- npm packages: `class-variance-authority`. The install adds them.
- Other registry items: `@arbokui/avatar`. The install adds them.
- Gallery: https://arbokui.com/components/person
- Registry item: https://arbokui.com/r/person.json

## Install

1. Add the registry to `components.json`. Do this first, once:

   ```bash
   npx shadcn@latest registry add "@arbokui=https://arbokui.com/r/{name}.json"
   ```

   The command writes this entry. You can also add it by hand:

   ```json
   {
     "registries": {
       "@arbokui": "https://arbokui.com/r/{name}.json"
     }
   }
   ```

   Without this step, the shadcn CLI looks up `@arbokui` in a public list that Arbokui does not control.

2. Add the theme once per app. It replaces your color tokens with ones checked for contrast:

   ```bash
   npx shadcn@latest add @arbokui/theme
   ```

3. Add the component:

   ```bash
   npx shadcn@latest add @arbokui/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`: `string`. Required. The person's full name.
- `src`: `string`. Photo URL. The avatar shows initials until it loads.
- `meta`: `string`. A muted line under the name, like "Product lead · Design".
- `size`: `"sm" | "md" | "lg"`. Default `"md"`. The avatar's size, as Avatar's. The name is 11, 13, or 16px, and the meta line 11, 11, or 13px.
- `strong`: `boolean`. Default `false`. The name in the strong weight.
- `className`: `string`. Extra classes on the root. Later classes win.
- `PersonValue`: `{ person: string; photo?: string; meta?: string }`. Type. How to pass a person into a slot. Render it as \<Person name={value.person} src={value.photo} meta={value.meta} />.
- `isPersonValue`: `(value: unknown) => value is PersonValue`. Function. True for a PersonValue, false for text and elements.

## 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

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

### A row's title

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

### From a PersonValue

```tsx
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;
}
```
