# Avatar A person, as a circle, with initials until the image lands. - Group: Display - Import: `import { Avatar } from '@misoto22/folio'` - Page: https://ui.misoto22.com/components/avatar/ ## Anatomy - **Circle** (required) — The Radix root: a --rule hairline over --stone, overflow hidden, and one of three fixed squares — 28px, 36px or 48px. It carries role="img" and alt as its own name, because it is the one element in here that is always rendered. - **Image** — Rendered only when src is given, object-cover so a portrait crops to the circle instead of distorting. Its own alt is empty on purpose — the circle around it is what names the person, and a second name here is the same person read twice. - **Initials** — The Radix fallback: mono, uppercase, --ink-3-aa, and aria-hidden. Radix shows it while the image is loading and once it has failed, which is why it does not flash on every render the way a hand-rolled onError swap does. ## Best practices ### Do - Write alt for the person, not for the row: the circle carries it whether or not a photograph ever arrives, so a list where photographs are optional announces every person rather than every second one. - Pass initials that hold up on their own: fallback is required because the image is the optional half, and most rows of a real list render as this element rather than as a photograph. - Let Radix own the swap rather than reaching for onError — it flips to the fallback only once the image has actually failed, which is what keeps the initials from appearing for a frame before the cache answers. ### Don’t - The avatar is not the control. sm is 28px and md is 36px, both under the 44px pointer-target floor (WCAG 2.5.8), and the root is a nothing has made focusable — an account menu made by hanging onClick on it is unreachable and undersized at once. - children is deliberately omitted from the props: the image and the fallback are the only two things that go in the circle, and the root is overflow-hidden, so a presence dot placed inside it is clipped by the very border that makes it round. ## Accessibility - alt names the circle itself, as role="img", so an avatar with no photograph still says who it is. - An empty alt is correct when the name is already printed beside it: the circle then takes no role at all rather than an unnamed one, and leaves the tree entirely. - The initials are aria-hidden — read aloud beside a name the root already gives, they are noise. ## Avatar A person, as a circle. Wraps Radix so the fallback appears only after the image has actually failed or is still loading — a hand-rolled `onError` swap flashes the initials on every render before the cache answers. The ROOT carries the accessible name, not the image. `alt` on the image reaches the DOM only when `src` does, and the initials are aria-hidden, so an avatar with no photograph announced nothing at all however carefully `alt` was written — and a user list where photographs are optional is full of them. ### Props - `src` — `string`. - `alt` (required) — `string`. Describes the person, not the picture. It names the circle itself rather than the image inside it, because the image is the optional half and most rows of a real list render as initials. Empty string is correct and deliberate when the name is already printed beside the avatar: the circle then leaves the accessibility tree entirely, rather than repeating a name a screen reader has just read. - `fallback` (required) — `string`. Shown while the image loads and if it never does. Usually initials. - `size` — `'sm' | 'md' | 'lg'` default `'md'`. Also accepts: `Omit, 'children'>`. ## Example — sizes ```tsx import { Avatar } from '@misoto22/folio'
``` ## Example — a name beside it ```tsx import { Avatar, Text } from '@misoto22/folio' ``` ## Example — inside the control ```tsx import { Avatar, Button } from '@misoto22/folio'
```