Accordion
A single-open accordion driven by one openId in state. Each panel’s visibility
is a data-show reading a method, so opening one item closes the rest with no
manual DOM juggling.
Markup
<template data-each="items" data-key="id">
<div>
<button @click="toggle" data-bind="data-id:item.id, aria-expanded:expanded(item.id)">
<span data-text="item.q"></span>
<span data-text="expanded(item.id) === 'true' ? '–' : '+'"></span>
</button>
<div data-show="item.id === openId" data-text="item.a"></div>
</div>
</template>
Component
Micra.define("accordion", {
state: {
openId: 1,
items: [
{ id: 1, q: "Does Micra need a build step?", a: "No. Add a script tag or import the module; nothing to compile or bundle." },
{ id: 2, q: "Can I use it inside Rails or Laravel?", a: "Yes. The server renders the markup and Micra makes it reactive in place." },
{ id: 3, q: "How big is it?", a: "About 7 KB gzip, with zero dependencies and no virtual DOM." },
],
},
expanded(id) {
return this.state.openId === id ? "true" : "false";
},
toggle(e) {
const id = Number(e.currentTarget.dataset.id);
this.state.openId = this.state.openId === id ? 0 : id;
},
});
openId is the single source of truth. expanded(id) returns the
aria-expanded string straight from it, and the panel’s data-show compares
against the same openId — so opening one item closes the rest with no second
flag to keep in sync.