Accordion A set of collapsible sections for showing one or many panels.
React Native
Native source Markup CSS
Copy <div mlk-accordion-root data-type="single" data-collapsible>
<div mlk-accordion-item>
<h3 mlk-accordion-header>
<a mlk-accordion-trigger draggable="false" href="#native-content">Native package</a>
</h3>
<div mlk-accordion-content id="native-content" data-open>
<div class="demo__content-inner">@milkui/core/accordion</div>
</div>
</div>
<div mlk-accordion-item>
<h3 mlk-accordion-header>
<a mlk-accordion-trigger draggable="false" href="#react-content">React adapter</a>
</h3>
<div mlk-accordion-content id="react-content" hidden="until-found">
<div class="demo__content-inner">@milkui/react/accordion</div>
</div>
</div>
<div mlk-accordion-item>
<h3 mlk-accordion-header>
<a mlk-accordion-trigger draggable="false" href="#primitive-content">Shared primitive</a>
</h3>
<div mlk-accordion-content id="primitive-content" hidden="until-found">
<div class="demo__content-inner">@milkui/core/primitive</div>
</div>
</div>
</div>
<script type="module">
import { Root, Item, Header, Trigger, Content } from '@milkui/core/accordion';
Root.define(document);
Item.define(document);
Header.define(document);
Trigger.define(document);
Content.define(document);
</script>Features Fragment links work before JavaScript loads. Single or multiple item selection. Controlled or uncontrolled value state. Collapsible single-item mode. Disabled roots and disabled items. Vertical or horizontal orientation with direction support. Anatomy Triggers link to content marked hidden="until-found" before JavaScript. Following a link reveals that panel without resetting others. Enhancement adds toggle and keyboard behavior.
Native anatomy Copy <div mlk-accordion-root>
<div mlk-accordion-item>
<h3 mlk-accordion-header>
<a mlk-accordion-trigger></a>
</h3>
<div mlk-accordion-content></div>
</div>
</div>API reference Closed content uses hidden="until-found"; initially open content uses data-open without hidden. Use instance.update() for later state changes.
Root Prop Type Default Description type"single" | "multiple""single"Selection mode. valuestring | string[]undefinedControlled value. defaultValuestring | string[]undefinedInitial uncontrolled value. onValueChange(value) => voidundefinedValue change request callback. collapsiblebooleanfalseAllow the open single item to close. disabledbooleanfalseDisable every item. orientation"vertical" | "horizontal""vertical"Keyboard orientation. dir"ltr" | "rtl""ltr"Direction for horizontal navigation.
Item Prop Type Default Description disabledbooleanfalseDisable this item.
Header Prop Type Default Description elementh3h3Heading wrapper for the trigger.
Trigger Prop Type Default Description hrefstringContent fragmentLink enhanced with disclosure behavior.
Content Prop Type Default Description idstringrequired for fragment linksUnique content ID; also its native selection value.
Data attribute Values [data-open]Present when the item is open [data-disabled]Present when disabled [mlk-accordion-root]Root marker [mlk-accordion-item]Item marker [mlk-accordion-header]Header marker [mlk-accordion-trigger]Trigger marker [mlk-accordion-content]Content marker
CSS variable Description --mlk-accordion-content-widthMeasured content width. --mlk-accordion-content-heightMeasured content height.
Examples Independent accordions Disable JavaScript and reload, then open Returns and Privacy. Both remain visible. Links reveal panels without closing others. Enhancement adds independent single-selection toggling.
Native source Copy <div class="independent-accordions">
<section>
<h3>Delivery</h3>
<div mlk-accordion-root data-type="single" data-collapsible>
<div mlk-accordion-item>
<h3 mlk-accordion-header><a mlk-accordion-trigger draggable="false" href="#delivery-shipping-content">Shipping</a></h3>
<div mlk-accordion-content id="delivery-shipping-content" data-open><div class="demo__content-inner">Shipping information.</div></div>
</div>
<div mlk-accordion-item>
<h3 mlk-accordion-header><a mlk-accordion-trigger draggable="false" href="#delivery-returns-content">Returns</a></h3>
<div mlk-accordion-content id="delivery-returns-content" hidden="until-found"><div class="demo__content-inner">Returns information.</div></div>
</div>
</div>
</section>
<section>
<h3>Account</h3>
<div mlk-accordion-root data-type="single" data-collapsible>
<div mlk-accordion-item>
<h3 mlk-accordion-header><a mlk-accordion-trigger draggable="false" href="#account-billing-content">Billing</a></h3>
<div mlk-accordion-content id="account-billing-content" data-open><div class="demo__content-inner">Billing information.</div></div>
</div>
<div mlk-accordion-item>
<h3 mlk-accordion-header><a mlk-accordion-trigger draggable="false" href="#account-privacy-content">Privacy</a></h3>
<div mlk-accordion-content id="account-privacy-content" hidden="until-found"><div class="demo__content-inner">Privacy information.</div></div>
</div>
</div>
</section>
</div>Controlled value The root requests value changes. Your state decides whether to accept them.
Native source Copy <script type="module">
import { Root, Item, Header, Trigger, Content } from '@milkui/core/accordion';
Root.define(document);
Item.define(document);
Header.define(document);
Trigger.define(document);
Content.define(document);
await Promise.resolve();
let value = Root.get(document.getElementById('accordion-controlled')).values[0] ?? '';
const root = Root.mount(document.getElementById('accordion-controlled'), {
type: 'single',
value,
onValueChange(nextValue) {
if (accept.checked) setValue(nextValue);
},
});
function setValue(nextValue: string) {
value = nextValue;
root.update({ value });
}
</script>Multiple items Multiple accordions can keep more than one item open at a time.
Native source Copy <div mlk-accordion-root data-type="multiple">
<div mlk-accordion-item>
<h3 mlk-accordion-header>
<a mlk-accordion-trigger draggable="false" href="#multiple-native-content">Native package</a>
</h3>
<div mlk-accordion-content id="multiple-native-content" data-open>
<div class="demo__content-inner">@milkui/core/accordion</div>
</div>
</div>
<div mlk-accordion-item>
<h3 mlk-accordion-header>
<a mlk-accordion-trigger draggable="false" href="#multiple-react-content">React adapter</a>
</h3>
<div mlk-accordion-content id="multiple-react-content" data-open>
<div class="demo__content-inner">@milkui/react/accordion</div>
</div>
</div>
<div mlk-accordion-item>
<h3 mlk-accordion-header>
<a mlk-accordion-trigger draggable="false" href="#multiple-primitive-content">Shared primitive</a>
</h3>
<div mlk-accordion-content id="multiple-primitive-content" hidden="until-found">
<div class="demo__content-inner">@milkui/core/primitive</div>
</div>
</div>
</div>Horizontal orientation Orientation is a root-level option for keyboard navigation and layout.
Native source Copy <div
mlk-accordion-root
class="accordion-horizontal"
data-type="single"
data-orientation="horizontal"
dir="ltr"
>
<div mlk-accordion-item>
<h3 mlk-accordion-header>
<a mlk-accordion-trigger draggable="false" href="#horizontal-one-content">One</a>
</h3>
<div mlk-accordion-content id="horizontal-one-content" data-open>
<div class="demo__content-inner">Horizontal item one.</div>
</div>
</div>
<div mlk-accordion-item>
<h3 mlk-accordion-header>
<a mlk-accordion-trigger draggable="false" href="#horizontal-two-content">Two</a>
</h3>
<div mlk-accordion-content id="horizontal-two-content" hidden="until-found">
<div class="demo__content-inner">Horizontal item two.</div>
</div>
</div>
</div>Keyboard interactions Before enhancement, triggers are links to sections. Once enhanced, Enter and Space toggle them without changing the URL.
Key Description SpaceOpens or closes the focused trigger. EnterOpens or closes the focused trigger. ArrowDown / ArrowRightMoves focus to the next enabled trigger. ArrowUp / ArrowLeftMoves focus to the previous enabled trigger. HomeMoves focus to the first enabled trigger. EndMoves focus to the last enabled trigger.