<!-- GENERATED by scripts/build-llms.mjs from llms/media.md — do not edit this file. -->

# `lr-avatar`

- **Import** `import '@aceshooting/lyra-ui/components/lr-avatar.js';` (stable tag alias; registers the tag)
- **Class** `LyraAvatar`, also available unregistered from `@aceshooting/lyra-ui/components/media/avatar/avatar.class.js`
- **Family** `components/media/` — see `llms/index.md` for its siblings
- **Status** `stable` since `4.0.0` — see the maturity and deprecation policy in `llms/shared.md`
- **Release history** [CHANGELOG.md](../../CHANGELOG.md); family-wide breaking-change summaries: [llms-full.txt](../../llms-full.txt)
- **Deprecations** none
- **Optional peers** none
- **Themeable via** 4 parts, 5 custom properties — see this component's own `@csspart`/`@cssprop` list below
- **Library-wide behavior** (events, form association, `locale`/`strings`, tokens, TS types): `llms/shared.md`

---

## `lr-avatar`

A small, fixed-size identity marker: an image, an `icon`-slotted fallback glyph, or initials — in
that priority order. Mirrors `wa-avatar` / `sl-avatar` (`image`, `initials`, `loading`, `shape`, the
named `icon` slot, label and image-load error event) and adds this library's shared `size` and
`variant` vocabulary. Purely presentational, with no built-in interactivity; wrap it in a
`<button>`/`<lr-menu>` trigger for a user-menu affordance.

Removing the attribute consumes the label as absent while preserving its `null` property readback.
Explicit empty labels remain empty, host `aria-label` precedence remains intact, and later label
values restore the image or fallback name.

**Properties:**

- `initials: string = ''` — fallback text (typically 1-2 characters), shown whenever no glyph and no
  image is set, or the image fails to load and no `icon` slot content is provided.
- `image: string = ''` — image URL; takes priority over the `icon` slot and `initials` when set and
  loads successfully, falling back to them on a load
  error. **Renamed from `src` in 8.0.0** to match `wa-avatar`: a mechanical `wa-` → `lr-` rename
  used to leave the property unset, so a migrated avatar silently dropped its photo and rendered
  initials instead.
- `label: string = ''` — upstream-compatible accessible description. A host `aria-label` wins.
  The same resolved name reaches the image `alt` and every fallback tier.
- host `aria-label` — overrides `label` as the image/fallback accessible name without changing the
  visible initials or image
- `loading: 'eager' | 'lazy' = 'eager'` (new in 8.0.0) — passthrough to the rendered `<img>`'s
  native `loading` attribute. `'lazy'` defers the request until the avatar approaches the viewport,
  which is worth setting for avatars far down a long list and never for one above the fold. It only
  reaches the DOM while the image tier is the one rendering; the default matches the native default,
  so an avatar that never sets it behaves exactly as it did before the property existed.
- `size: LyraSize = 'medium'` (reflected) — `'2xs' | 'xs' | 's' | 'm' | 'l' | 'xl' |
'small' | 'medium' | 'large'`. Every tier renders a distinct diameter: 1.5rem (`2xs`), 2rem
  (`xs`), 2.5rem (`s`/`small`), 3rem (`m`/`medium`, the mirrored default), 4rem (`l`/`large`,
  matching `--lr-icon-button-size`), and 5rem (`xl`). Invalid and removed `sm`/`md`/`lg` writes
  normalize to `medium`.
- `shape: 'circle' | 'rounded' | 'square' = 'circle'` (reflected) — three distinct corner radii:
  `circle` (the pill radius), `rounded` (the shared `--lr-radius`), `square` (no radius at all).
  **`rounded` is new in 8.0.0.**
- `variant: 'neutral' | 'brand' | 'success' | 'warning' | 'danger' = 'neutral'` (reflected) —
  recolors the initials-fallback background/text on the library's one semantic-tone vocabulary;
  `neutral` (the default) reads as a plain, unaccented circle. **Renamed from `tone` in 8.0.0**,
  with no alias: `tone="brand"` is an unknown attribute now and renders the neutral circle.

**Events:** `lr-error` (`detail: { image: string }`, new in 8.0.0) — the image failed to load;
`detail.image` carries the URL that failed, so a consumer can retry or report it. Bubbling,
composed, non-cancelable, and purely informational: by the time it fires the avatar has already
fallen back to the `icon` slot or the initials on its own. It never fires for an avatar with no
`image` set, and fires once more for each replacement `image` that also fails.

**Slots:** `icon` — a
fallback glyph shown only when there is no loadable `image`; that is
the role `wa-avatar`'s `icon` slot fills, a stand-in for the `initials` text rather than an override
of the photo. Its content is decorative (`aria-hidden`) — set `label` alongside it for an
accessible name. There is no default slot.

**CSS parts:** `base` (the outer circle/rounded/square container), `icon` (wrapper around the named
fallback slot while it is the winning tier), `image` (the `<img>`, only while a safe, non-failed
`image` is usable), and `initials` (only once the image and icon tiers are unavailable).

**Themeable custom properties:** `--size` is the upstream-compatible diameter and falls back to
`--lr-avatar-size` (default `var(--lr-size-3rem)`, with a private default stepped across the ladder
from `var(--lr-size-1-5rem)` at `2xs` to `var(--lr-size-5rem)` at `xl`), `--lr-avatar-bg` (default
`var(--lr-color-border)`, whose private default changes for a non-neutral `variant` to that
variant's `-quiet` fill; there is no `--lr-color-surface-alt` token in this library, despite what
older copies of this page claimed), `--lr-avatar-color` (default `var(--lr-color-text)`, whose
private default changes for a non-neutral `variant` to that variant's loud color),
`--lr-avatar-font-size` (default `var(--lr-font-size-m)`) — the font size of the initials fallback,
and of any `em`-sized slotted glyph. Its private default follows `size` alongside the diameter
(`--lr-font-size-xs` at `2xs`, `--lr-font-size-sm` at `xs`, `--lr-font-size-md-sm` at `s`,
`--lr-font-size-m` at `m`, `--lr-font-size-lg` at `l`, and `--lr-font-size-xl` at `xl`), so the
initials track the circle instead of staying one fixed size across every tier. Every public value
above can be inherited from an ancestor or set directly on the avatar and remains authoritative
across size/variant states. Plus shared tokens
`--lr-radius`/`-pill`, `--lr-font-weight-semibold`.

The variant colors are deliberately **not** the library's generic quiet-fill/on-quiet-text pairing:
an avatar's initials _are_ the accent, so they read in the variant's own loud color on that
variant's quiet tint.

**Optional peer deps:** none.

```html
<lr-avatar initials="JS" variant="brand"></lr-avatar>
<lr-avatar image="/users/42/photo.jpg" label="Jane Smith" size="large" shape="rounded"></lr-avatar>
<lr-avatar label="Assistant"><svg slot="icon" viewBox="0 0 24 24"><!-- role glyph --></svg></lr-avatar>

<!-- Far down a long list: defer the request, fall back to a glyph, and report a broken URL. -->
<lr-avatar id="lazy-avatar" image="/users/7/photo.jpg" label="Ada Lovelace" loading="lazy">
  <svg slot="icon" viewBox="0 0 24 24"><!-- fallback glyph --></svg>
</lr-avatar>
<script type="module">
  document
    .getElementById("lazy-avatar")
    .addEventListener("lr-error", (e) => reportBrokenAvatar(e.detail.image));
</script>
```

**Known gotchas:**

- additive `alt`, default glyph content and `sm`/`md`/`lg` aliases were removed for exact mirrored
  vocabulary: migrate `alt→label`, default glyph content to `slot="icon"`, and size aliases to
  `small`/`medium`/`large`. The older `src→image` and `tone→variant` migrations still apply.
- an image load failure falls back to the `icon` slot when it has content, otherwise to `initials`.
  Changing `image` clears the failure state so the replacement URL gets its own load attempt,
  including when a later transition returns to a URL that failed previously.
- when `label` or host `aria-label` supplies a name, the base preserves that name through the glyph
  and initials fallbacks while hiding duplicate initials text from assistive technology.
- the `icon` slot yields to a loadable `image` and becomes the fallback if the image fails.

---
