The active state in the wrapping x-data attribute can be used to determine which accordion item is open.


source: https://alpinejs.dev/component/accordion

This component is subject to a product license.

  • Handle: @alpine-components-accordion
  • Preview:
  • Filesystem Path: components/10-other-examples/alpine-components/03-accordion/accordion.hbs
<!-- Alpine Plugins -->
<script defer src="https://unpkg.com/@alpinejs/[email protected]/dist/cdn.min.js"></script>

<!-- Alpine Core -->
<script defer src="https://unpkg.com/[email protected]/dist/cdn.min.js"></script>

<style>
    [x-cloak] {
        display: none !important;
    }
</style>
<!--<h1 x-data="{ message: 'I ❤️ Alpine' }" x-text="message"></h1>-->

<div class="h-screen flex justify-center items-center">

    <div class="mx-auto max-w-3xl w-full min-h-[16rem] space-y-4">

        <div x-data="{ active: null}" class="space-y-4">

            <!--  Accordion -->
            <div x-data="{
        id: 1,
        get expanded() {
          return this.active === this.id
        },
        set expanded(value) {
          this.active = value ? this.id : null
        }
      }" role="region" class="rounded-lg bg-white shadow">
                <h2>
                    <button @click="expanded = !expanded" :aria-expanded="expanded" class="flex w-full items-center justify-between px-6 py-4 text-xl font-bold">
                        <span>Question #1</span>
                        <span x-show="expanded" x-cloak aria-hidden="true" class="ml-4">&minus;</span>
                        <span x-show="!expanded" aria-hidden="true" class="ml-4">&plus;</span>
                    </button>
                </h2>

                <div x-show="expanded" x-collapse x-cloak>
                    <div class="px-6 pb-4">
                        Lorem ipsum dolor sit amet consectetur adipisicing elit. In magnam quod natus deleniti
                        architecto eaque consequuntur ex, illo neque iste repellendus modi, quasi ipsa commodi saepe? Provident ipsa
                        nulla earum.
                    </div>
                </div>
            </div>

            <!--  Accordion -->
            <div x-data="{
        id: 2,
        get expanded() {
          return this.active === this.id
        },
        set expanded(value) {
          this.active = value ? this.id : null
        }
      }" role="region" class="rounded-lg bg-white shadow">
                <h2>
                    <button @click="expanded = !expanded" :aria-expanded="expanded" class="flex w-full items-center justify-between px-6 py-4 text-xl font-bold">
                        <span>Question #2</span>
                        <span x-show="expanded" x-cloak aria-hidden="true" class="ml-4">&minus;</span>
                        <span x-show="!expanded" aria-hidden="true" class="ml-4">&plus;</span>
                    </button>
                </h2>

                <div x-show="expanded" x-collapse x-cloak>
                    <div class="px-6 pb-4">
                        Lorem ipsum dolor sit amet consectetur adipisicing elit. In magnam quod natus deleniti
                        architecto eaque consequuntur ex, illo neque iste repellendus modi, quasi ipsa commodi saepe? Provident ipsa
                        nulla earum.
                    </div>
                </div>
            </div>

        </div>

    </div>

</div>
<!-- Alpine Plugins -->
<script defer src="https://unpkg.com/@alpinejs/[email protected]/dist/cdn.min.js"></script>

<!-- Alpine Core -->
<script defer src="https://unpkg.com/[email protected]/dist/cdn.min.js"></script>

<style>
  [x-cloak] {
    display: none !important;
  }
</style>
<!--<h1 x-data="{ message: 'I ❤️ Alpine' }" x-text="message"></h1>-->


<div class="h-screen flex justify-center items-center">

  <div class="mx-auto max-w-3xl w-full min-h-[16rem] space-y-4">

    <div x-data="{ active: null}"
         class="space-y-4"
    >

      <!--  Accordion -->
      <div x-data="{
        id: 1,
        get expanded() {
          return this.active === this.id
        },
        set expanded(value) {
          this.active = value ? this.id : null
        }
      }"
           role="region"
           class="rounded-lg bg-white shadow"
      >
        <h2>
          <button
                  @click="expanded = !expanded"
                  :aria-expanded="expanded"
                  class="flex w-full items-center justify-between px-6 py-4 text-xl font-bold"
          >
            <span>Question #1</span>
            <span x-show="expanded" x-cloak aria-hidden="true" class="ml-4">&minus;</span>
            <span x-show="!expanded" aria-hidden="true" class="ml-4">&plus;</span>
          </button>
        </h2>

        <div x-show="expanded" x-collapse x-cloak>
          <div class="px-6 pb-4">
            Lorem ipsum dolor sit amet consectetur adipisicing elit. In magnam quod natus deleniti
            architecto eaque consequuntur ex, illo neque iste repellendus modi, quasi ipsa commodi saepe? Provident ipsa
            nulla earum.
          </div>
        </div>
      </div>

       <!--  Accordion -->
      <div x-data="{
        id: 2,
        get expanded() {
          return this.active === this.id
        },
        set expanded(value) {
          this.active = value ? this.id : null
        }
      }"
           role="region"
           class="rounded-lg bg-white shadow"
      >
        <h2>
          <button
                  @click="expanded = !expanded"
                  :aria-expanded="expanded"
                  class="flex w-full items-center justify-between px-6 py-4 text-xl font-bold"
          >
            <span>Question #2</span>
            <span x-show="expanded" x-cloak aria-hidden="true" class="ml-4">&minus;</span>
            <span x-show="!expanded" aria-hidden="true" class="ml-4">&plus;</span>
          </button>
        </h2>

        <div x-show="expanded" x-collapse x-cloak>
          <div class="px-6 pb-4">
            Lorem ipsum dolor sit amet consectetur adipisicing elit. In magnam quod natus deleniti
            architecto eaque consequuntur ex, illo neque iste repellendus modi, quasi ipsa commodi saepe? Provident ipsa
            nulla earum.
          </div>
        </div>
      </div>


    </div>

  </div>

</div>
/* No context defined. */