Detent web components
By Shane Logsdon

Overlays & menus

Avatar Stack

Implemented

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

  • hover recorded 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

  • max
  • overlap
  • show-count
  • show-tooltip
  • size

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.tsx sha256 991544113349…

Native files

The native module and its artifacts:

  • src/components/avatar-stack/avatar-stack.ts
  • src/components/avatar-stack/styles.css
  • src/components/avatar-stack/define.ts
  • docs/components/avatar-stack.md
  • site/examples/avatar-stack.ts
  • tests/browser/avatar-stack.spec.ts
  • evidence/components/avatar-stack.md

API

Boolean attributes follow HTML presence semantics: present means true, absent means false, and disabled="false" still means disabled.

Attributes

Attributes
AttributePropertyTypeDefaultNotes
maxmaxnumber5Kebab-case attribute; camelCase property.
overlapoverlap'sm' | 'md' | 'lg''md'Kebab-case attribute; camelCase property.
show-countshowCountbooleantruePresence semantics: present means true, absent means false.
show-tooltipshowTooltipbooleantruePresence semantics: present means true, absent means false.
sizesize'sm' | 'md' | 'lg' | 'xl''lg'Kebab-case attribute; camelCase property.

Properties

Properties
PropertyTypeDefaultNotes
avatarsAvatarStackItem[][]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.
Previous: Animated Tabs Next: Badge

Docs

Components

Project