# Avatar

Shows a person's photo, falling back to initials or an anonymous person icon.

## Installation

```tsx
import { Avatar } from "@makeplane/propel/components/avatar";
```
## Usage

```tsx
import { Avatar } from "@makeplane/propel/components/avatar";

export default function BasicDemo() {
  return (
    <Avatar size="md" alt="Ada Lovelace" fallback="AL" src="https://i.pravatar.cc/128?img=47" />
  );
}
```
## Examples

At `2xs` (16px), derived initials and string `fallback` values display only their first Unicode grapheme. Larger sizes retain their initials. Custom React fallback content is rendered as supplied; keep it suitable for the available space.

### Sizes

`size` is an optical ramp of eight steps — `2xs` 16 / `xs` 20 / `sm` 24 / `md` 28 / `lg` 32 /
`xl` 40 / `2xl` 56 / `3xl` 64 px — not the control ladder. The four middle steps happen to agree
with the ladder's labels; the extremes are Avatar's own. `md` is the default, and inside an
[AvatarGroup](/components/avatar-group) the group's size wins unless an avatar sets its own.

```tsx
import { Avatar, type AvatarSize } from "@makeplane/propel/components/avatar";

const SIZES: AvatarSize[] = ["2xs", "xs", "sm", "md", "lg", "xl", "2xl", "3xl"];

export default function SizesDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      {SIZES.map((size) => (
        <Avatar key={size} size={size} alt="Ada Lovelace" fallback="AL" />
      ))}
    </div>
  );
}
```

### Variants

The initials background variant is derived stably from `alt` (falling back to the initials themselves), so every member gets a consistent color automatically — it is not a consumer prop.

```tsx
import { Avatar } from "@makeplane/propel/components/avatar";

const MEMBERS = [
  { alt: "Aarav Sharma", fallback: "AS" },
  { alt: "Brenda Lee", fallback: "BL" },
  { alt: "Chen Wei", fallback: "CW" },
  { alt: "Diya Patel", fallback: "DP" },
  { alt: "Elena Garcia", fallback: "EG" },
  { alt: "Farhan Khan", fallback: "FK" },
];

export default function VariantsDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      {MEMBERS.map(({ alt, fallback }) => (
        <Avatar key={alt} size="lg" alt={alt} fallback={fallback} />
      ))}
    </div>
  );
}
```

### States

The three fallback states side by side: photo, initials, and the anonymous person icon. Content resolves in that fixed order, so a photo that fails to load drops to initials rather than leaving a broken frame.

Initials are derived from `alt` when you don't pass `fallback` — up to two characters, the first letter of the first and last name token, uppercased. A single-token name yields one letter. The anonymous icon is reached only when no name resolves at all.

```tsx
import { Avatar } from "@makeplane/propel/components/avatar";

export default function StatesDemo() {
  return (
    <div className="flex flex-wrap items-center gap-3">
      <Avatar size="lg" alt="Ada Lovelace" fallback="AL" src="https://i.pravatar.cc/128?img=47" />
      <Avatar size="lg" alt="Ada Lovelace" fallback="AL" />
      <Avatar size="lg" />
    </div>
  );
}
```

### With tooltip

Pass `tooltip` to show the person's name on hover. `true` reuses `alt`; a string is the label and works without `alt`.

An avatar stays presentational either way: a tooltip does not put it in the tab order. When the avatar is genuinely interactive — opening a profile, a menu, a member picker — wrap it in a button or link and let the wrapper own focus, so the focus ring is not clipped by the circular mask.

```tsx
import { Avatar } from "@makeplane/propel/components/avatar";

export default function WithTooltipDemo() {
  return (
    <Avatar
      size="md"
      alt="Ada Lovelace"
      tooltip
      fallback="AL"
      src="https://i.pravatar.cc/128?img=47"
    />
  );
}
```

### Interactive avatar

Put the tooltip on the actionable wrapper so keyboard focus reveals the same information as hover. The wrapper owns the accessible action name and a target of at least 24px; the avatar inside is decorative. Connect the button's `onClick` to the consumer's profile action.

```tsx
import { Avatar } from "@makeplane/propel/components/avatar";
import { IconButton } from "@makeplane/propel/components/icon-button";

export default function InteractiveDemo() {
  return (
    <IconButton
      variant="ghost"
      size="sm"
      aria-label="Open Ada Lovelace’s profile"
      icon={<Avatar size="xs" fallback="AL" />}
    />
  );
}
```

Consumer `tabIndex` is forwarded for compatibility, but avoid adding tab stops to avatar artwork, especially decorative `aria-hidden` avatars. Put interaction, focus and tooltip semantics on a named button or link wrapper.

Migration guidance is maintained in the [0.5.0 changelog entry](https://github.com/makeplane/propel/blob/main/packages/propel/CHANGELOG.md#050).

## API Reference

### Avatar

The ready-made avatar: an image that falls back to initials (or an anonymous person icon),
composed from the `elements/avatar` parts (`Avatar` root + `AvatarImage` + `AvatarFallback`).
Pass `src` for the photo and `fallback` for initials; the initials color is chosen automatically
and is not a consumer prop.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `render` | `ReactElement<unknown, string \| JSXElementConstructor<any>> \| ComponentRenderFn<HTMLProps, {}>` | — | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
| `size` | `"2xs" \| "xs" \| "sm" \| "md" \| "lg" \| "xl" \| "2xl" \| "3xl"` | `"md"` | Avatar size. Optional here — resolved from the `AvatarGroup` context, else `md`. |
| `src` | `string` | — | Image URL. When omitted, or while it is loading/failing, the fallback shows. |
| `alt` | `string` | — | Accessible name for the avatar (the person it represents). |
| `fallback` | `ReactNode` | — | Initials shown when there is no image. When omitted too, a person icon shows. |
| `delay` | `number` | — | Milliseconds before the fallback shows, to avoid a flash while `src` loads quickly. |
| `tooltip` | `string \| boolean` | — | Name shown in a tooltip on hover. Pass `true` to reuse `alt`, or a string for the label (works without `alt`). Omit for no tooltip. |
