Overlays & menus
Avatar Stack
Overlapping avatar pile with spring-animated hover elevation and tooltips.
detent-avatar-stack
Port status
- Catalog status
- implemented
- Origin
- upstream
- Phase
- 2
- Wave
- phase-2-feedback
- Group
- Overlays & menus
3.4 KB gzip for the class module
Variants
Hover or focus an avatar: it lifts, scales, rises above its siblings and shows the name tooltip.
Recorded states
hoverrecorded state; no setter
Usage
Import
import '/components/avatar-stack/define.js';
// or register it yourself
import { DetentAvatarStack } from '/components/avatar-stack/avatar-stack.js';
Attributes
maxoverlapshow-countshow-tooltipsize
Properties
avatars
Slots
No slots are recorded for this component.
Events
No events are recorded for this component.
Example
Runnable example: site/examples/avatar-stack.ts. The snippet below is generated from the catalogued attributes.
<detent-avatar-stack
max="5"
overlap="md"
show-count
show-tooltip
size="lg"
></detent-avatar-stack>
Property-only values
const element = document.querySelector('detent-avatar-stack');
if (element !== null) {
// avatars: AvatarStackItem[]
element.avatars = [];
}
Source
The pinned upstream source for this row:
src/components/ui/AvatarStack.tsxsha256 991544113349…
Native files
The native module and its artifacts:
src/components/avatar-stack/avatar-stack.tssrc/components/avatar-stack/styles.csssrc/components/avatar-stack/define.tsdocs/components/avatar-stack.mdsite/examples/avatar-stack.tstests/browser/avatar-stack.spec.tsevidence/components/avatar-stack.md
API
Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.
Attributes
| Attribute | Property | Type | Default | Notes |
|---|---|---|---|---|
max | max | number | 5 | Kebab-case attribute; camelCase property. |
overlap | overlap | 'sm' | 'md' | 'lg' | 'md' | Kebab-case attribute; camelCase property. |
show-count | showCount | boolean | true | Presence semantics: present means true, absent means false. |
show-tooltip | showTooltip | boolean | true | Presence semantics: present means true, absent means false. |
size | size | 'sm' | 'md' | 'lg' | 'xl' | 'lg' | Kebab-case attribute; camelCase property. |
Properties
| Property | Type | Default | Notes |
|---|---|---|---|
avatars | AvatarStackItem[] | [] | Property-only: assign from script; not accepted as an attribute. |
Events
No custom events are recorded for this component.
Slots
No slots are recorded for this component.
CSS customisation
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- Framer Motion springs replaced by CSS transitions on transform/opacity/box-shadow (220ms cubic-bezier(0.2,0,0.2,1)); hover state is pure CSS :hover, so no re-render and no frame loop.
- Initials fall back to `name` when `alt` is missing (upstream read `alt` only and rendered "?"); accessibility correction, PC-12.6.
- Overflow count is announced once via a visually hidden "N more users" sentence instead of an `aria-label` on a role-less div, which AT ignores (PC-12.6).
- Default-true booleans `show-count`/`show-tooltip` keep HTML presence semantics (PC-3.2); the resolved default true is reflected into the attribute and the opt-out is the property (`showCount = false`). Declarative `show-count="false"` is true.
What it does
An overlapping pile of avatars: the hovered circle lifts, scales and rises above its siblings, its name tooltip appears, and the overflow is summarised by a +N badge.
Upstream behaviour
- Dynamic z-index elevation on hover so the hovered avatar is 100% visible and unclipped
- Spring-animated scale and lift transition powered by Framer Motion
- Floating name tooltip with spring entrance and exit
- Automatic initial extraction when images are unavailable or fail to load
- Truncation badge (+N) with customizable maximum visible avatars
Differences from upstream
- Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
- React state/hooks replaced by element-owned state with pre-upgrade property preservation.
- Framer Motion springs replaced by CSS transitions on transform/opacity/box-shadow (220ms cubic-bezier(0.2,0,0.2,1)); hover state is pure CSS :hover, so no re-render and no frame loop.
- Initials fall back to `name` when `alt` is missing (upstream read `alt` only and rendered "?"); accessibility correction, PC-12.6.
- Overflow count is announced once via a visually hidden "N more users" sentence instead of an `aria-label` on a role-less div, which AT ignores (PC-12.6).
- Default-true booleans `show-count`/`show-tooltip` keep HTML presence semantics (PC-3.2); the resolved default true is reflected into the attribute and the opt-out is the property (`showCount = false`). Declarative `show-count="false"` is true.