Aether JS AetherJS

Modal

The following components were built using AetherJS. The design is entirely based on the theme variables (CSS Variables) you provide.


01 Simple Modal

A simple modal featuring scroll locking (data-aether-scroll-lock), focus trapping (data-aether-focus-trap), automatic focus on a specific component upon opening (data-aether-autofocus), and URL synchronization (data-aether-sync-url).

index.html
<!-- Trigger -->
<button
    class="px-4 py-2 cursor-pointer bg-primary border border-primary rounded-lg text-primary hover:text-primary-interactive hover:border-primary-interactive transition-colors flex items-center gap-2"
    data-aether-trigger="ui-control"
    data-aether-target="example-modal-1"
    data-aether-sync-url>
    Open
</button>

<!-- Wrapper -->
<div id="example-modal-1"
    class="hidden fixed inset-0 z-[60] flex items-center justify-center p-4"
    data-aether-scroll-lock
    data-aether-focus-trap
    data-aether-active-class="flex"
    data-aether-inactive-class="hidden">

    <!-- Backdrop -->
    <div class="absolute inset-0 bg-primary/50 backdrop-blur-sm"
        data-aether-trigger="ui-control"
        data-aether-target="example-modal-1"
        data-aether-action="close"></div>

    <!-- Content -->
    <div class="relative bg-secondary border border-primary w-full max-w-md p-6 rounded-2xl shadow-2xl scale-100 transition-all">
        <h3 class="text-xl font-bold text-primary mb-2">Confirm the Transaction</h3>
        <p class="text-secondary mb-6">This transaction cannot be undone. Are you sure you want to proceed?</p>

        <div class="flex justify-end gap-3">
            <button class="px-4 py-2 cursor-pointer text-secondary hover:text-primary hover:bg-tertiary rounded-lg transition-colors"
                data-aether-trigger="ui-control"
                data-aether-target="example-modal-1"
                data-aether-action="close">
                Cancel
            </button>

            <button class="px-4 py-2 cursor-pointer bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors"
                data-aether-autofocus>
                Confirm
            </button>
        </div>
    </div>

</div>

02 Multi-Level (Nested)

AetherUI manages open windows using a "Stack" logic.

index.html
<!-- Trigger Level 1 -->
<button
    class="px-4 py-2 cursor-pointer bg-primary border border-primary rounded-lg text-primary hover:text-primary-interactive hover:border-primary-interactive transition-colors flex items-center gap-2"
    data-aether-trigger="ui-control"
    data-aether-target="modal-level-1"
    data-aether-sync-url>
    Open
</button>

<!-- Wrapper Level 1 -->
<div id="modal-level-1"
    class="hidden fixed inset-0 z-[60] flex items-center justify-center p-4"
    data-aether-scroll-lock
    data-aether-focus-trap
    data-aether-active-class="flex"
    data-aether-inactive-class="hidden">

    <!-- Backdrop -->
    <div class="absolute inset-0 bg-primary/50 backdrop-blur-sm"
        data-aether-trigger="ui-control"
        data-aether-target="modal-level-1"
        data-aether-action="close"></div>

    <!-- Content -->
    <div class="relative bg-secondary border border-primary w-full max-w-lg p-0 rounded-2xl shadow-2xl overflow-hidden scale-100 transition-all">
        <div class="p-6 border-b border-primary flex justify-between items-center bg-primary/30">
            <div>
                <h3 class="text-lg font-bold text-primary">Active Projects</h3>
                <p class="text-xs text-tertiary">A total of 1 project was found</p>
            </div>
            <button class="text-tertiary cursor-pointer hover:text-primary transition-colors"
                data-aether-trigger="ui-control"
                data-aether-target="modal-level-1"
                data-aether-action="close">
                <svg class="size-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                </svg>
            </button>
        </div>

        <div class="p-6 space-y-3">
            <div class="group flex items-center justify-between p-4 border border-primary rounded-xl hover:bg-primary/40 transition-colors">
                <div class="flex items-center gap-4">
                    <div class="size-10 rounded-lg bg-accent/10 border border-accent/20 flex items-center justify-center text-accent">
                        <svg class="size-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 18h.01M8 21h8a2 2 0 002-2V5a2 2 0 00-2-2H8a2 2 0 00-2 2v14a2 2 0 002 2z" />
                        </svg>
                    </div>
                    <div>
                        <div class="text-sm font-bold text-primary">Mobile Application</div>
                        <div class="text-xs text-tertiary">Last update: 2 hours ago</div>
                    </div>
                </div>
                <!-- Trigger Level 2 -->
                <button class="px-4 py-2 cursor-pointer text-xs font-medium bg-tertiary border border-primary text-secondary rounded-lg hover:border-primary-interactive hover:text-secondary-interactive transition-colors"
                    data-aether-trigger="ui-control"
                    data-aether-target="modal-level-2">
                    Settings
                </button>
            </div>
        </div>

        <div class="p-6 bg-primary/30 border-t border-primary flex justify-end">
            <button class="text-sm font-medium cursor-pointer text-tertiary hover:text-primary transition-colors"
                data-aether-trigger="ui-control"
                data-aether-target="modal-level-1"
                data-aether-action="close">Close</button>
        </div>
    </div>
</div>

<!-- Wrapper Level 2 -->
<div id="modal-level-2" class="hidden fixed inset-0 z-[70] flex items-center justify-center p-4"
    data-aether-focus-trap
    data-aether-active-class="flex"
    data-aether-inactive-class="hidden">

    <!-- Backdrop -->
    <div class="absolute inset-0 bg-primary/50 backdrop-blur-sm"
        data-aether-trigger="ui-control"
        data-aether-target="modal-level-2"
        data-aether-action="close"></div>

    <!-- Content -->
    <div class="relative bg-secondary border border-primary w-full max-w-md p-0 rounded-2xl shadow-2xl scale-100 transition-all">
        <div class="p-6 border-b border-primary flex justify-between items-center bg-primary/20">
            <div>
                <h3 class="text-lg font-bold text-primary">Project Settings</h3>
                <p class="text-xs text-tertiary">Mobile Application</p>
            </div>
            <button class="text-tertiary cursor-pointer hover:text-primary transition-colors"
                data-aether-trigger="ui-control"
                data-aether-target="modal-level-2"
                data-aether-action="close">
                <svg class="size-5" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
                </svg>
            </button>
        </div>
        <div class="p-6 pb-0">

            <div class="space-y-5">
                <div>
                    <label class="block text-xs font-medium text-secondary mb-1.5 ml-1">Project Name</label>
                    <input type="text" value="Mobile Application"
                        class="w-full px-3 py-2 bg-primary border border-primary rounded-lg text-primary text-sm focus:outline-none focus:border-accent transition-colors"
                        data-aether-autofocus>
                </div>

            </div>
        </div>

        <div class="p-6 mt-4 border-t border-primary flex justify-between items-center bg-primary/20 rounded-b-2xl">
            <!-- Trigger Level 3 -->
            <button class="text-sm cursor-pointer text-red-500 hover:text-red-600 font-bold flex items-center gap-1 group"
                data-aether-trigger="ui-control"
                data-aether-target="modal-level-3">
                <svg class="size-4 group-hover:scale-110 transition-transform" fill="none" viewBox="0 0 24 24" stroke="currentColor">
                    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
                </svg>
                Delete Project
            </button>
            <div class="flex gap-5">
                <button class="text-sm font-medium cursor-pointer text-tertiary hover:text-primary transition-colors"
                    data-aether-trigger="ui-control" data-aether-target="modal-level-2" data-aether-action="close">Cancel</button>
                <button class="text-sm font-medium cursor-pointer text-secondary hover:text-primary transition-colors">Save Changes</button>
            </div>
        </div>
    </div>
</div>

<!-- Wrapper Level 3 -->
<div id="modal-level-3" class="hidden fixed inset-0 z-[80] flex items-center justify-center p-4"
    data-aether-focus-trap
    data-aether-active-class="flex"
    data-aether-inactive-class="hidden">

    <!-- Backdrop  -->
    <div class="absolute inset-0 bg-primary/50 backdrop-blur-sm"
        data-aether-trigger="ui-control"
        data-aether-target="modal-level-3"
        data-aether-action="close"></div>

    <!-- Content -->
    <div class="relative bg-secondary border border-primary w-full max-w-sm p-6 rounded-2xl shadow-2xl scale-100 transition-all">
        <h3 class="text-lg font-bold text-primary mb-2">Confirm the Transaction</h3>
        <p class="text-secondary text-sm mb-6">This transaction cannot be undone. Are you sure you want to proceed?</p>

        <div class="flex justify-end gap-3">
            <button class="px-2.5 py-1.5 text-sm cursor-pointer text-secondary hover:text-primary hover:bg-tertiary rounded-lg transition-colors"
                data-aether-trigger="ui-control"
                data-aether-target="modal-level-3"
                data-aether-action="close">
                Cancel
            </button>

            <button class="px-2.5 py-1.5 text-sm cursor-pointer bg-red-500 text-white rounded-lg hover:bg-red-600 transition-colors"
                data-aether-autofocus>
                Confirm
            </button>
        </div>

    </div>
</div>