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.