Skip to content

Instantly share code, notes, and snippets.

@AndreasFurster
Forked from JeffreyWay/demo.html
Last active December 5, 2025 10:28
Show Gist options
  • Select an option

  • Save AndreasFurster/42a45ba730e0b782d7014e4eb1861e88 to your computer and use it in GitHub Desktop.

Select an option

Save AndreasFurster/42a45ba730e0b782d7014e4eb1861e88 to your computer and use it in GitHub Desktop.
<x-tabs active="First">
<x-tab name="First">
First content goes here.
</x-tab>
<x-tab name="Second">
Second content goes here.
</x-tab>
<x-tab name="Third">
Third content goes here.
</x-tab>
</x-tabs>
@props(['name'])
<div x-init="registerTab(@js($name))" x-show="activeTab === @js($name)">
{{ $slot }}
</div>
@props(['active'])
<div x-data="{
activeTab: @js($active ?? null),
tabs: [],
registerTab(tab) {
this.tabs.push(tab);
this.activeTab = this.activeTab || tab;
},
}"
>
<div class="flex gap-2 mb-4 overflow-x-auto">
<template x-for="tab in tabs" :key="tab">
<button
type="button"
x-text="tab"
@click="activeTab = tab"
class="px-4 py-1 text-sm rounded"
:class="tab === activeTab ? 'bg-black text-white' : 'text-black'"
></button>
</template>
</div>
<div>
{{ $slot }}
</div>
</div>
@AndreasFurster
Copy link
Author

Modified version of Laravel Blade / Alpine.js tabs component from @JeffreyWay.

Instead of inspecting the child elements from the parent, the child components register themself to the parent component.

ARIA attributes should be added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment