Skip to content

Accordion

A stack of sections, each with a header button that shows or hides its panel. It uses the Bootstrap collapse plugin bundled in tabler.js. By default, opening a section closes the one that was open.

items is an array of {title, text, open?, icon?, id?, level?, toggleIcon?}. Each item gets the id <id>-<n>, starting at 1, unless it has its own id, and uses the accordion id as its data-bs-parent, so that opening one closes the others. Without an id, the accordion gets a random one (accordion-<n>): set your own when the ids must stay the same between renders, for example to link to a section or to restore the open one.

Accordion:Item renders one section from its props. Give each item an id for its panel, and the id of the accordion as parent: opening the item then closes the others. Mark the section to show on load open.

The header is an <h3> by default. Set level on the item (1 to 6, any other value falls back to 3) to fit the outline of the page. The button inherits the font size of the heading, so the level changes the size of the label too. With items, set level on the accordion for every generated item, or on an entry for that item only. toggleIcon works the same way.

alwaysOpen leaves out data-bs-parent on the generated items, so several sections can stay open at once. Several items can then be open on load. With Accordion:Item, leave out parent instead.

flush removes the outer border and the rounded corners, to fit the accordion edge to edge in a card or a list:

tabs spaces the items out and gives each one its own border and rounded corners:

inverted moves the toggle indicator to the start of the header, before the label:

icon adds a leading Tabler icon before the label. plus swaps the chevron for a plus that turns into a close icon when the section opens. On the accordion, plus applies to every generated item; icon is set per item.

toggleIcon on Accordion:Item (or Accordion:Button) picks another icon for the indicator. It rotates half a turn when the section opens:

The title and body blocks of Accordion:Item replace the label and the panel content, while the item keeps the header, the button and the collapse wiring. Wrap the body block in Accordion:Body to keep the padding:

See Composition for how blocks work.

To build a section from its parts, pass children to Accordion:Item: they replace its content block. Keep the ids in sync: the target of Accordion:Button is the id of Accordion:Collapse, without #. The icon and toggle blocks of Accordion:Button frame its label:

Accordion:Button is a <button type="button"> with aria-controls set to the panel id and aria-expanded set from open. Bootstrap updates aria-expanded and the collapsed class when the section opens or closes. The leading icon and the toggle indicator are aria-hidden="true". Each button sits in a heading (Accordion:Header), so screen reader users can jump from section to section.

Accordion:

Prop Type Default Description
id string? null DOM id, the data-bs-parent of the generated items and the prefix of their ids; random when null
items array? null {title, text, open?, icon?, id?, level?, toggleIcon?} entries, rendered with Accordion:Item
flush bool false No outer border nor rounded corners (accordion-flush)
inverted bool false Toggle indicator at the start of the header (accordion-inverted)
tabs bool false Spaced items, each fully bordered (accordion-tabs)
alwaysOpen bool false Generated items stay open when another one opens (no data-bs-parent)
plus bool false Generated items use the plus indicator (accordion-button-toggle-plus)
level int 3 Heading level of the generated items, 1 to 6; an entry’s level wins
toggleIcon string? null Toggle indicator icon of the generated items; an entry’s toggleIcon wins

Other attributes go to the root <div class="accordion">.

Accordion:Item:

Prop Type Default Description
id string? null Id of the panel, targeted by the button
parent string? null Id of the accordion: when set, opening this item closes the others (data-bs-parent)
title string? null Button label
text string? null Panel text, rendered with Accordion:Body
open bool false Expanded on load
icon string? null Leading Tabler icon name, rendered with Accordion:Icon
plus bool false Plus indicator that turns into a close icon (accordion-button-toggle-plus)
toggleIcon string? null Tabler icon name of the indicator (default chevron-down, or plus)
level int 3 Heading level of the header, 1 to 6; any other value renders an <h3>

Other attributes go to the <div class="accordion-item">.

Accordion:Button takes target (the panel id, without #), open, icon, plus and toggleIcon, as on the item. Accordion:Collapse takes id, parent and open (show). Accordion:Toggle takes plus and icon (the indicator icon name). Accordion:Header takes level (default 3). On each of them, other attributes go to the rendered element.

Component Renders
Accordion:Item <div class="accordion-item">: one section, with its header and its panel
Accordion:Header <h3 class="accordion-header"> (or the level set): holds the button
Accordion:Button <button class="accordion-button" data-bs-toggle="collapse">: the label and indicator
Accordion:Icon <span class="accordion-button-icon">: a leading icon before the label
Accordion:Toggle <span class="accordion-button-toggle">: the indicator at the end, a chevron by default
Accordion:Collapse <div class="accordion-collapse collapse">: the panel the button opens
Accordion:Body <div class="accordion-body">: the padded content of the panel

Accordion:

Block Default
content An Accordion:Item for each entry of the items prop

Accordion:Item:

Block Default
title The title prop
body Accordion:Body with the text prop, when set
header Accordion:Header with an Accordion:Button holding the title block
content header, then Accordion:Collapse holding the body block: replace it to compose freely

Accordion:Button:

Block Default
icon Accordion:Icon with the icon prop, when set
toggle Accordion:Toggle, with the plus and toggleIcon props

The content of Accordion:Button is its label. Accordion:Toggle has a content block too: it holds the indicator icon, so pass children to use your own SVG.