Aether JS AetherJS

Tab

The tab components below are built using AetherJS state management. The data-aether-ui="tab-group" container automatically pairs the triggers and panels within it. AetherUI manages accessibility attributes such as role, aria-selected, and aria-hidden for you.


01 Simple Tab

A standard tab structure. The data-aether-default-open attribute is added to the trigger intended to be open by default.

Project Overview

AetherUI provides a set of unstyled, accessible UI primitives for building robust web applications. It handles the logic, you handle the design.

Key Features

  • Headless Architecture
  • WAI-ARIA Compliant
  • Tiny Footprint

Simple Pricing

Open source and free for personal and commercial projects under the MIT license.

index.html
<!-- Wrapper -->
<div class="w-full max-w-2xl" data-aether-ui="tab-group">

    <!-- Tab List -->
    <div class="flex border-b border-primary mb-6">
        <button
            class="px-6 py-3 text-sm font-medium border-b-2 transition-colors duration-200"
            data-aether-trigger="tab"
            data-aether-target="tab-overview"
            data-aether-default-open
            data-aether-active-class="border-accent text-accent"
            data-aether-inactive-class="border-transparent text-secondary hover:text-primary hover:border-primary-interactive">
            Overview
        </button>
        <button
            class="px-6 py-3 text-sm font-medium border-b-2 transition-colors duration-200"
            data-aether-trigger="tab"
            data-aether-target="tab-features"
            data-aether-active-class="border-accent text-accent"
            data-aether-inactive-class="border-transparent text-secondary hover:text-primary hover:border-primary-interactive">
            Features
        </button>
        <button
            class="px-6 py-3 text-sm font-medium border-b-2 transition-colors duration-200"
            data-aether-trigger="tab"
            data-aether-target="tab-pricing"
            data-aether-active-class="border-accent text-accent"
            data-aether-inactive-class="border-transparent text-secondary hover:text-primary hover:border-primary-interactive">
            Pricing
        </button>
    </div>

    <!-- Panels -->
    <div class="bg-secondary rounded-2xl p-6 min-h-[160px] border border-primary">
        <div id="tab-overview" data-aether-ui="tab-panel">
            <h3 class="text-lg font-bold text-primary mb-2">Project Overview</h3>
            <p class="text-sm text-secondary leading-relaxed">
                AetherUI provides a set of unstyled, accessible UI primitives for building robust web applications. It handles the logic, you handle the design.
            </p>
        </div>
        <div id="tab-features" data-aether-ui="tab-panel">
            <h3 class="text-lg font-bold text-primary mb-2">Key Features</h3>
            <ul class="text-sm text-secondary space-y-2 list-disc list-inside">
                <li>Headless Architecture</li>
                <li>WAI-ARIA Compliant</li>
                <li>Tiny Footprint</li>
            </ul>
        </div>
        <div id="tab-pricing" data-aether-ui="tab-panel">
            <h3 class="text-lg font-bold text-primary mb-2">Simple Pricing</h3>
            <p class="text-sm text-secondary leading-relaxed">
                Open source and free for personal and commercial projects under the MIT license.
            </p>
        </div>
    </div>

</div>

02 Nested Tabs

Thanks to AetherUI's scoping logic, you can create nested tabs.

Account Details

General Preferences

Manage your language and region settings.

Security Config

Update your password and 2FA settings.

index.html
<!-- Outer Tab Group -->
<div class="w-full max-w-3xl flex flex-col xl:flex-row gap-2.5" data-aether-ui="tab-group">

    <!-- Sidebar Triggers -->
    <div class="xl:w-1/4 flex flex-col gap-1">
        <button
            class="w-full text-left px-4 py-3 text-sm font-medium rounded-lg transition-all"
            data-aether-trigger="tab"
            data-aether-target="nt-account"
            data-aether-default-open
            data-aether-active-class="bg-tertiary text-white shadow-md"
            data-aether-inactive-class="text-secondary hover:text-primary hover:bg-tertiary">
            Account
        </button>
        <button
            class="w-full text-left px-4 py-3 text-sm font-medium rounded-lg transition-all"
            data-aether-trigger="tab"
            data-aether-target="nt-settings"
            data-aether-active-class="bg-tertiary text-white shadow-md"
            data-aether-inactive-class="text-secondary hover:text-primary hover:bg-tertiary">
            Settings
        </button>
    </div>

    <!-- Main Content Area -->
    <div class="xl:w-3/4 bg-secondary rounded-lg border border-primary p-6 min-h-[300px]">

        <!-- Account Panel -->
        <div id="nt-account" data-aether-ui="tab-panel">
            <h3 class="text-lg font-bold text-primary mb-4">Account Details</h3>
            <div class="space-y-4">
                <div class="flex gap-4 items-center">
                    <div class="size-12 rounded-full bg-tertiary border border-primary"></div>
                    <div>
                        <div class="h-3 w-32 bg-tertiary rounded mb-2"></div>
                        <div class="h-2 w-24 bg-tertiary rounded"></div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Settings Panel (Nested Tabs) -->
        <div id="nt-settings" data-aether-ui="tab-panel">
            <div data-aether-ui="tab-group">
                <div class="flex space-x-2 bg-tertiary p-1 rounded-lg mb-6 w-fit">
                    <button
                        class="px-4 py-1.5 text-xs font-medium rounded-md transition-all"
                        data-aether-trigger="tab"
                        data-aether-target="nt-general"
                        data-aether-default-open
                        data-aether-active-class="bg-secondary text-primary shadow-sm"
                        data-aether-inactive-class="text-tertiary hover:text-secondary">
                        General
                    </button>
                    <button
                        class="px-4 py-1.5 text-xs font-medium rounded-md transition-all"
                        data-aether-trigger="tab"
                        data-aether-target="nt-security"
                        data-aether-active-class="bg-secondary text-primary shadow-sm"
                        data-aether-inactive-class="text-tertiary hover:text-secondary">
                        Security
                    </button>
                </div>

                <div id="nt-general" data-aether-ui="tab-panel">
                    <h4 class="font-bold text-primary text-sm mb-2">General Preferences</h4>
                    <p class="text-xs text-secondary">Manage your language and region settings.</p>
                </div>
                <div id="nt-security" data-aether-ui="tab-panel">
                    <h4 class="font-bold text-primary text-sm mb-2">Security Config</h4>
                    <p class="text-xs text-secondary">Update your password and 2FA settings.</p>
                </div>
            </div>
        </div>

    </div>
</div>