Content & disclosure
Accordion
Panels that unfold with a chevron
detent-accordion
Port status
- Catalog status
- implemented
- Origin
- upstream
- Phase
- 1
- Wave
- phase-1-pilot
- Group
- Content & disclosure
3.6 KB gzip for the class module
Recorded states
expandedrecorded state; no setterdark themerecorded state; no setter
Usage
Import
import '/components/accordion/define.js';
// or register it yourself
import { DetentAccordion } from '/components/accordion/accordion.js';
Attributes
allow-multiple
Properties
defaultOpenitems
Slots
No slots are recorded for this component.
Events
No events are recorded for this component.
Example
Runnable example: site/examples/accordion.ts. The snippet below is generated from the catalogued attributes.
<detent-accordion
allow-multiple
></detent-accordion>
Property-only values
const element = document.querySelector('detent-accordion');
if (element !== null) {
// items: UnfoldAccordionItem[]
element.items = [];
// defaultOpen: string[]
element.defaultOpen = [];
}
Source
The pinned upstream source for this row:
src/components/ui/UnfoldAccordion.tsxsha256 e174326057ff…
Native files
The native module and its artifacts:
src/components/accordion/accordion.tssrc/components/accordion/styles.csssrc/components/accordion/define.tsdocs/components/accordion.mdsite/examples/accordion.tstests/browser/accordion.spec.tsevidence/components/accordion.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 |
|---|---|---|---|---|
allow-multiple | allowMultiple | boolean | false | Presence semantics: present means true, absent means false. |
Properties
| Property | Type | Default | Notes |
|---|---|---|---|
defaultOpen | string[] | [] | Property-only: assign from script; not accepted as an attribute. |
items | UnfoldAccordionItem[] | [] | 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.
- item.content is text (string) rendered with textContent; upstream accepted React.ReactNode. The row records no slots and PC-11.1 forbids parsing consumer strings as HTML.
- Trigger/panel are not wrapped in a heading/region landmark; upstream semantics (button + following content) are preserved exactly.
- Content block uses symmetric 1rem block padding; upstream pt-0 left the content text 2px below the trigger's hover surface while the item border sat 16px below it, so the block read as top-cropped.
What it does
An accordion whose panel height and chevron unfold together; single-open by default, allowMultiple for multi-open.
Upstream behaviour
- Chevron rotation, content height, and inner content slide are tuned to overlap
- Inner content uses a slightly faster ease so it "leads" the chevron by a hair
- Spring-based height expansion (springGentle) for a calm, continuous feel
- Single-open by default; allowMultiple for multi-open mode
- Light/dark theme aware — works in both palettes
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.
- item.content is text (string) rendered with textContent; upstream accepted React.ReactNode. The row records no slots and PC-11.1 forbids parsing consumer strings as HTML.
- Trigger/panel are not wrapped in a heading/region landmark; upstream semantics (button + following content) are preserved exactly.
- Content block uses symmetric 1rem block padding; upstream pt-0 left the content text 2px below the trigger's hover surface while the item border sat 16px below it, so the block read as top-cropped.