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

# `lr-avatar-group`

- **Import** `import '@aceshooting/lyra-ui/components/lr-avatar-group.js';` (stable tag alias; registers the tag)
- **Class** `LyraAvatarGroup`, also available unregistered from `@aceshooting/lyra-ui/components/media/avatar-group/avatar-group.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** 3 parts, 7 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-group`

Stacks slotted `<lr-avatar>` children into one overlapping row and, past `max`, collapses the
excess into a localized "+N" badge. Composed over `<lr-avatar>` via plain light-DOM slotted content
(no `.items` array); it does **not** import/register `<lr-avatar>` — the consumer does that.

**Properties:**

- `max?: number` — how many assigned children stay visible before the rest collapse behind the
  badge. Unset (the default) means no limit. Any assigned value is sanitized to a finite,
  non-negative integer. Flattened slot-forwarded children count the same as direct children.
- `size: LyraSize = 'medium'` (reflected) — reused from `<lr-avatar>`'s canonical six-step ladder.
- `shape: LyraAvatarShape = 'circle'` (reflected) — `'circle' | 'rounded' | 'square'`.
- `variant: LyraVariant = 'neutral'` (reflected) — `'neutral' | 'brand' | 'success' | 'warning' |
'danger'`.

`size`/`shape`/`variant` style the overflow badge and provide defaults only to assigned avatars
that omit the corresponding attribute. Explicit child attributes remain authoritative; owned
defaults are restored without overwriting later author writes across removal, reparenting,
disconnect and reconnect.

- `label: string = ''` — the group's `role="group"` accessible name. A host-level `aria-label` wins
  if both are set; with neither, no `aria-label` is rendered.

**Events:** `lr-overflow-click` (frozen
`detail: { readonly hiddenCount: number; readonly hiddenAvatars: readonly LyraAvatar[] }`) —
the badge was activated by click or Enter/Space. Non-cancelable, purely informational: the
component keeps rendering the same collapsed stack, and a host typically wires this to its own
popover/dialog listing the hidden members. There is no `expanded` state and no `aria-expanded`.

**Slots:** default slot — direct or forwarded `<lr-avatar>` elements. Other elements are ignored
and remain untouched. Author-hidden/inert avatars do not consume visible capacity. Excess eligible
avatars are hidden through reversible component-owned state.

**CSS parts:** `base` (the outer inline-flex container holding the slot and the badge),
`overflow-badge` (the 40px-minimum action surface; only rendered while `max` is actively
overflowing), and `overflow-badge-visual` (the avatar-tier-sized painted disc inside it).

**Themeable custom properties:** `--lr-avatar-group-avatar-size` (default `var(--lr-size-3rem)`,
with a private default stepped across the same six tiers as `<lr-avatar>`'s `--lr-avatar-size`,
from `var(--lr-size-1-5rem)` at `2xs`, through `var(--lr-size-2rem)`/
`var(--lr-size-2-5rem)`/`var(--lr-size-3rem)`/`var(--lr-size-4rem)`, to
`var(--lr-size-5rem)` at `xl`),
`--lr-avatar-group-overlap` (default `var(--lr-size-neg-6px)`, whose private default follows `size`;
a logical `margin-inline-start`, so it auto-mirrors
under `dir="rtl"` — setting `0` or a positive length turns the stack into normal spacing),
`--lr-avatar-group-ring-color` (default `var(--lr-color-surface)`),
`--lr-avatar-group-ring-width` (default `var(--lr-border-width-medium)`),
`--lr-avatar-group-badge-bg` (default `var(--lr-color-border)`, with a private default that follows
`variant`), `--lr-avatar-group-badge-color` (default `var(--lr-color-text)`, with a private default
that follows `variant`),
`--lr-avatar-group-badge-font-size` (default `var(--lr-font-size-m)`) — the font size of the "+N"
badge label. Its private default follows `size` alongside the badge diameter, matching
`<lr-avatar>`'s own `--lr-avatar-font-size` scale (`xs`/`sm`/`md-sm`/`m`/`lg`/`xl` font tokens from
the `2xs` through `xl` size tiers), so the badge and the avatars it caps read at the same optical
weight. An inherited or direct public value remains authoritative for every hook.

The overflow badge keeps a `--lr-icon-button-size` minimum activation target at every tier while
the nested visual disc stays exactly avatar-sized, so small tiers do not paint as oversized 40px
circles.

**Optional peer deps:** none.

```html
<lr-avatar-group max="3" label="Project members">
  <lr-avatar initials="JS"></lr-avatar>
  <lr-avatar initials="AM"></lr-avatar>
  <lr-avatar initials="RT"></lr-avatar>
  <lr-avatar initials="KL"></lr-avatar>
</lr-avatar-group>
```

**Known gotchas:**

- group defaults only fill omitted child attributes; they deliberately do not overwrite explicit
  heterogeneous child presentation.
- the row never wraps (`flex-wrap` stays `nowrap`) — wrapping an overlapping stack breaks the
  visual.
- avatars are non-interactive, so there is no roving tabindex / arrow-key handling; the badge is the
  only tab stop.
