Component / Layout
Animated Accordion
Reveal variable-height detail with stable trigger and region semantics, retained closing content, interruption-safe transitions, and complete keyboard navigation.
System details / controlled
The panel measures its rendered body, animates to that exact height, then restores authored styles.
- State
- Retained
- Cleanup
- Scoped
Stable trigger and region IDs preserve aria-controls and aria-labelledby in every state.
- State
- Retained
- Cleanup
- Scoped
Opening and closing transitions can reverse without accepting stale animation completions.
- State
- Retained
- Cleanup
- Scoped
This disabled item marks the next catalog milestone without entering the keyboard sequence.
- State
- Retained
- Cleanup
- Scoped
Delivery contract
Install it
pnpm add easecraft@0.1.0The component imports stable APIs from easecraft.
Files / 00
Dependencies / 03
- easecraft
- npm / 0.1.0
- react
- peer / >=18.2.0 <20.0.0
- react-dom
- peer / >=18.2.0 <20.0.0
Package usage
Use it
import { AnimatedAccordion } from "easecraft";
<AnimatedAccordion
aria-label="Project details"
items={details}
getValue={(detail) => detail.id}
getLabel={(detail) => detail.label}
defaultValue="overview"
>
{(detail) => <ProjectDetail detail={detail} />}
</AnimatedAccordion>Typed contract
API
| Prop | Type | Default | Purpose |
|---|---|---|---|
| items | readonly Item[] | required | Accordion item data |
| getValue | (item) => string | required | Stable item value |
| getLabel | (item) => ReactNode | required | Trigger label renderer |
| children | (item) => ReactNode | required | Panel renderer |
| mode | "single" | "multiple" | "single" | Expansion model |
| value | string | readonly string[] | uncontrolled | Controlled expanded values |
| defaultValue | string | readonly string[] | none | Initial expanded values |
| onValueChange | mode-dependent callback | none | Expansion change callback |
| collapsible | boolean | true | Allow all single panels to close |
| disabled | boolean | false | Disable the full accordion |
| isDisabled | (item) => boolean | none | Disable individual items |
| headingLevel | 2 | 3 | 4 | 5 | 6 | 3 | Semantic trigger heading |
| duration | duration token | number | "normal" | Opening duration |
| easing | easing token | string | "enter" | Opening easing |
| exitDuration | duration token | number | "fast" | Closing duration |
| exitEasing | easing token | string | "exit" | Closing easing |
| as | HTML tag | "div" | Polymorphic host element |
Release requirement
Accessibility
- Semantic linkage
- Every heading trigger controls one persistently identified, labelled region.
- Keyboard
- Arrow keys, Home, End, Enter, and Space follow the accordion APG pattern.
- Retained exit
- Closing content becomes inert and hidden from assistive technology before exit.
- Focus safety
- Programmatic closure moves focus from panel content back to its trigger.
- Reduced motion
- Expanded state and semantics settle immediately without creating an animation.
- Server rendering
- Default expanded content and closed panel semantics render deterministically.