Detent web components
By Shane Logsdon

Content & disclosure

Animated Accordion

Implemented

Collapsible panels with eased height

detent-animated-accordion

Port status
Catalog status
implemented
Origin
upstream
Phase
2
Wave
phase-2-disclosure
Group
Content & disclosure

3.8 KB gzip for the class module

Variants

Press Enter or Space on a header to expand it. The preview above keeps one panel open; this one allows several. With reduced motion the panel reaches its final height immediately.

Recorded states

  • open recorded state; no setter
  • expanded recorded state; no setter

Usage

Import

import '/components/animated-accordion/define.js';

// or register it yourself
import { DetentAnimatedAccordion } from '/components/animated-accordion/animated-accordion.js';

Attributes

  • allow-multiple

Properties

  • items
  • defaultOpen

Slots

No slots are recorded for this component.

Events

No events are recorded for this component.

Example

Runnable example: site/examples/animated-accordion.ts. The snippet below is generated from the catalogued attributes.

<detent-animated-accordion
  allow-multiple
></detent-animated-accordion>

Property-only values

const element = document.querySelector('detent-animated-accordion');
if (element !== null) {
  // items: AccordionItem[]
  element.items = [];
  // defaultOpen: string[]
  element.defaultOpen = [];
}

Source

The pinned upstream source for this row:

  • src/components/ui/SmoothAccordion.tsx sha256 fbeff8241c25…

Native files

The native module and its artifacts:

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

API

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

Attributes

Attributes
AttributePropertyTypeDefaultNotes
allow-multipleallowMultiplebooleanfalsePresence semantics: present means true, absent means false.

Properties

Properties
PropertyTypeDefaultNotes
itemsAccordionItem[][]Property-only: assign from script; not accepted as an attribute.
defaultOpenstring[][]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.
  • `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • `content` is `string` text, not a React node.
  • Accessibility correction (PC-12.6): upstream set only `aria-expanded`; the port adds `aria-controls` on the button plus `role="region"` and `aria-labelledby` on the open panel.
  • The trigger is explicitly `type="button"`.

What it does

Zero-jank collapsible panels: the height interpolates from 0fr to 1fr and the chevron rotates in the same transition. Single-open by default, multi-open through allow-multiple.

Upstream behaviour
  • Spring physics height interpolation
  • Zero content clipping or layout jumps
  • Single or multi-panel open mode
Differences from upstream
  • Framer Motion springs/AnimatePresence ported to CSS transitions, WAAPI or the shared rAF spring helper.
  • `lucide-react` icon components replaced with local SVG assets (ISC notice retained).
  • React state/hooks replaced by element-owned state with pre-upgrade property preservation.
  • `content` is `string` text, not a React node.
  • Accessibility correction (PC-12.6): upstream set only `aria-expanded`; the port adds `aria-controls` on the button plus `role="region"` and `aria-labelledby` on the open panel.
  • The trigger is explicitly `type="button"`.
Previous: Comparison Table Next: Sparkles

Docs

Components

Project