<bmx-accordion-item>
A heading with a panel under it that opens and closes. Usable on its own -
one of these is a disclosure, which is a pattern in its own right and the
right one for "advanced options" or a single "show more" - and usable in a
bmx-accordion, which coordinates a set of them.
7 properties · 1 events · 2 methods · 7 parts
Example
On its own, an item is a disclosure — the right pattern for one "show more":
bmxToggle when it opens or closes.
Inside a bmx-accordion, the accordion owns whether it may be open at the same time as its neighbours:
Show markup
<div class="row">
<p style="margin: 0">On its own, an item is a disclosure — the right pattern for one "show more":</p>
</div>
<div class="row">
<bmx-accordion-item
id="ex-item"
heading="Advanced options"
style="max-inline-size: 40rem; border: 1px solid var(--bmx-border); border-radius: var(--bmx-radius-lg)"
>
<bmx-switch label="Send anonymous usage statistics"></bmx-switch>
</bmx-accordion-item>
</div>
<div class="row">
<span class="note" id="ex-item-out">It reports <code>bmxToggle</code> when it opens or closes.</span>
</div>
<div class="row">
<p style="margin: 0">Inside a <code>bmx-accordion</code>, the accordion owns whether it may be open at the same time as its neighbours:</p>
</div>
<div class="row">
<bmx-accordion style="max-inline-size: 40rem">
<bmx-accordion-item heading="First" open>Content of the first section.</bmx-accordion-item>
<bmx-accordion-item heading="Second">Content of the second section.</bmx-accordion-item>
</bmx-accordion>
</div>
<script type="module">
await customElements.whenDefined('bmx-accordion-item');
const item = document.getElementById('ex-item');
const out = document.getElementById('ex-item-out');
item.addEventListener('bmxToggle', event => {
out.textContent = `bmxToggle: value="${event.detail.value}", open ${event.detail.open}`;
});
</script>
WHY THIS ONE OWNS BOTH HALVES AND bmx-tab-panel DOES NOT
The same constraint, answered the other way round. Both patterns need two
IDREFs between a control and its panel, and an IDREF cannot cross a shadow
boundary - so both ends must live in one root. For tabs that root has to be
the parent's, because the tabs are drawn as a strip away from their panels.
Here the heading sits directly above its own panel, so the natural root is
this element's: the button and the region are both drawn here, the references
resolve, and bmx-accordion never has to reach across a boundary to wire
anything.
That is also what makes this usable standalone. A bmx-tab-panel alone is
nothing; one of these alone is a working disclosure.
THE HEADING IS A HEADING
The button is wrapped in an element carrying role="heading" and
aria-level, because a screen-reader user navigates a long page by its
headings and an accordion whose sections are invisible to that navigation is
a page they have to read linearly. heading-level is a property rather than
a fixed 3, because the right level depends on what is above it on the page,
which this component cannot know.
Properties
| Property | Attribute | Type | Default | Description |
|---|---|---|---|---|
badge |
badge |
string |
— | A short count or status, rendered after the heading text. |
disabled |
disabled |
boolean |
false |
Whether it can be opened. |
heading |
heading |
string |
— | The heading's text. |
headingLevel |
heading-level |
number |
3 |
The heading level this section sits at, as aria-level. Set by bmx-accordion from its own heading-level so a whole accordion is consistent; set it here when using an item on its own. |
icon |
icon |
string |
— | An inline SVG string, rendered before the heading text. |
open |
open |
boolean |
false |
Whether the panel is showing. Mutable, so pressing the heading changes it. Inside a bmx-accordion the accordion owns this - it is the thing that knows whether another panel has to close first - and writes it on every item. |
value |
value |
string |
— | What this item is identified by in the accordion's expanded and in events. Falls back to the heading and then to its position, so a set of items written with headings alone still reports something distinguishable. |
Events
| Event | Detail | Description |
|---|---|---|
bmxToggle |
BmxAccordionToggleDetail |
Fired when the item opens or closes. |
Methods
| Method | Signature | Description |
|---|---|---|
setFocus |
setFocus(options?: FocusOptions) => Promise<void> |
Focus this item's heading button. |
toggle |
toggle() => Promise<void> |
Open or close it, as pressing the heading would. |
Slots
| Slot | Description |
|---|---|
(default) |
The panel's content. |
heading |
Rich heading content, in place of the heading property. |
CSS shadow parts
| Part | Description |
|---|---|
badge |
The badge after it. |
content |
The clipping box inside the panel. Its padding is on an inner element, so that a closed panel collapses to nothing. |
header |
The element carrying role="heading". |
icon |
The icon before the heading text. |
marker |
The chevron that turns. |
region |
The panel. |
trigger |
The button inside it. |
CSS custom properties
| Property | Description |
|---|---|
--bmx-accordion-heading-font-size |
Size of the heading text. |
--bmx-accordion-heading-weight |
Weight of the heading text. |
--bmx-accordion-hover |
Background of a heading under the pointer. |
--bmx-accordion-marker-size |
Size of the chevron. |
--bmx-accordion-padding-block |
Space inside the heading, down. |
--bmx-accordion-padding-inline |
Space inside the heading and the panel, across. |