Tabs

A set of layered sections of content—known as tab panels—that are displayed one at a time.

Account

Make changes to your account here. Click save when you're done.

Usage

HTML + Javascript

This component requires Javascript.

The component is structured as such:

  • A <div class="tabs"> which wraps around the entire component and holds it state (e.g. open/close).
  • A <nav role="tablist"> that holds the tab buttons (<button role="tab">).
  • A series of <div role="tabpanel"> that holds the tab panels corresponding to each tab button.

You can include the Javascript code provided below, load it as an individual file or use the CLI. Some Alpine.js properties are also required on certain elements (e.g. x-bind, x-data, @click).

<div class="tabs w-full" x-data="tabs(0)" id="demo-tabs-with-panels">
  <nav role="tablist" aria-orientation="horizontal" x-bind="$tablist" class="w-full">
    <button type="button" role="tab" id="-tab-1" aria-controls="-panel-1" aria-selected="true" tabindex="0">Account</button>

    <button type="button" role="tab" id="-tab-2" aria-controls="-panel-2" aria-selected="false" tabindex="0">Password</button>
  </nav>

  <div role="tabpanel" id="-panel-1" aria-labelledby="-tab-1" tabindex="-1" aria-selected="true">
    <div class="card">
      <header>
        <h2>Account</h2>
        <p>Make changes to your account here. Click save when you're done.</p>
      </header>
      <section>
        <form class="form grid gap-6">
          <div class="grid gap-3">
            <label for="demo-tabs-account-name">Name</label>
            <input type="text" id="demo-tabs-account-name" value="Pedro Duarte" />
          </div>
          <div class="grid gap-3">
            <label for="demo-tabs-account-username">Username</label>
            <input type="text" id="demo-tabs-account-username" value="@peduarte" />
          </div>
        </form>
      </section>
      <footer>
        <button type="button" class="btn">Save changes</button>
      </footer>
    </div>
  </div>

  <div role="tabpanel" id="-panel-2" aria-labelledby="-tab-2" tabindex="-1" aria-selected="false" hidden>
    <div class="card">
      <header>
        <h2>Password</h2>
        <p>Change your password here. After saving, you'll be logged out.</p>
      </header>
      <section>
        <form class="form grid gap-6">
          <div class="grid gap-3">
            <label for="demo-tabs-password-current">Current password</label>
            <input type="password" id="demo-tabs-password-current" />
          </div>
          <div class="grid gap-3">
            <label for="demo-tabs-password-new">New password</label>
            <input type="password" id="demo-tabs-password-new" />
          </div>
        </form>
      </section>
      <footer>
        <button type="button" class="btn">Save Password</button>
      </footer>
    </div>
  </div>
</div>

Jinja and Nunjucks

You can use the tabs() Nunjucks or Jinja macro for this component.

{% set account_panel %}
<div class="card">
  <header>
    <h2>Account</h2>
    <p>Make changes to your account here. Click save when you're done.</p>
  </header>
  <section>
    <form class="form grid gap-6">
      <div class="grid gap-3">
        <label for="demo-tabs-account-name">Name</label>
        <input type="text" id="demo-tabs-account-name" value="Pedro Duarte" />
      </div>
      <div class="grid gap-3">
        <label for="demo-tabs-account-username">Username</label>
        <input type="text" id="demo-tabs-account-username" value="@peduarte" />
      </div>
    </form>
  </section>
  <footer>
    <button type="button" class="btn">Save changes</button>
  </footer>
</div>
{% endset %}

{% set password_panel %}
<div class="card">
  <header>
    <h2>Password</h2>
    <p>Change your password here. After saving, you'll be logged out.</p>
  </header>
  <section>
    <form class="form grid gap-6">
      <div class="grid gap-3">
        <label for="demo-tabs-password-current">Current password</label>
        <input type="password" id="demo-tabs-password-current" />
      </div>
      <div class="grid gap-3">
        <label for="demo-tabs-password-new">New password</label>
        <input type="password" id="demo-tabs-password-new"/>
      </div>
    </form>
  </section>
  <footer>
    <button type="button" class="btn">Save Password</button>
  </footer>
</div>
{% endset %}

{% set tabsets_demo = [
{ tab: "Account", panel: account_panel },
{ tab: "Password", panel: password_panel }
] %}

{{ tabs(
  id='demo-tabs-with-panels',
  tabsets=tabsets_demo,
  main_attrs={ "class": "w-full" },
  tablist_attrs={ "class": "w-full" },
  register_on=["alpine:init", "htmx:afterSwap"]
) }}