mrshanebarron / tabs
Tabs component for Laravel - supports Livewire and Vue
Installs: 10
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Language:Blade
pkg:composer/mrshanebarron/tabs
Requires
- php: ^8.1
- illuminate/support: ^10.0|^11.0|^12.0
README
A flexible tabbed interface component for Laravel applications. Supports multiple visual styles and accessibility features. Works with Livewire and Vue 3.
Installation
composer require mrshanebarron/tabs
Livewire Usage
Basic Usage
<livewire:sb-tabs :tabs="['tab1' => 'Overview', 'tab2' => 'Details', 'tab3' => 'Settings']"> <div x-show="$wire.active === 'tab1'"> Overview content here. </div> <div x-show="$wire.active === 'tab2'"> Details content here. </div> <div x-show="$wire.active === 'tab3'"> Settings content here. </div> </livewire:sb-tabs>
With Default Active Tab
<livewire:sb-tabs :tabs="['info' => 'Information', 'history' => 'History']" default-active="history" />
Different Variants
<!-- Default underline style --> <livewire:sb-tabs :tabs="$tabs" variant="default" /> <!-- Pill buttons --> <livewire:sb-tabs :tabs="$tabs" variant="pills" /> <!-- Boxed/segmented style --> <livewire:sb-tabs :tabs="$tabs" variant="boxed" />
Livewire Props
| Prop | Type | Default | Description |
|---|---|---|---|
tabs |
array | required | Key-value pairs of tab keys and labels |
default-active |
string | first tab | Initially active tab key |
variant |
string | 'default' |
Style: default, pills, boxed |
Vue 3 Usage
Setup
import { SbTabs, SbTabPanel } from './vendor/sb-tabs'; app.component('SbTabs', SbTabs); app.component('SbTabPanel', SbTabPanel);
Basic Usage
<template> <SbTabs :tabs="{ tab1: 'Overview', tab2: 'Details', tab3: 'Settings' }"> <template #default="{ active }"> <div v-show="active === 'tab1'"> Overview content here. </div> <div v-show="active === 'tab2'"> Details content here. </div> <div v-show="active === 'tab3'"> Settings content here. </div> </template> </SbTabs> </template>
Variants
<template> <!-- Default: underline style --> <SbTabs :tabs="tabs" variant="default"> ... </SbTabs> <!-- Pills: button style --> <SbTabs :tabs="tabs" variant="pills"> ... </SbTabs> <!-- Boxed: segmented control style --> <SbTabs :tabs="tabs" variant="boxed"> ... </SbTabs> </template> <script setup> const tabs = { overview: 'Overview', features: 'Features', pricing: 'Pricing' }; </script>
With Change Event
<template> <SbTabs :tabs="tabs" default-active="features" @change="handleTabChange" > <template #default="{ active }"> <div v-show="active === 'overview'">Overview</div> <div v-show="active === 'features'">Features</div> </template> </SbTabs> </template> <script setup> const handleTabChange = (tabKey) => { console.log('Active tab:', tabKey); }; </script>
Dynamic Tabs
<template> <SbTabs :tabs="dynamicTabs"> <template #default="{ active }"> <div v-for="(tab, key) in dynamicTabs" :key="key"> <div v-show="active === key"> Content for {{ tab }} </div> </div> </template> </SbTabs> </template> <script setup> import { computed } from 'vue'; const items = ref([ { id: 'item1', name: 'First Item' }, { id: 'item2', name: 'Second Item' } ]); const dynamicTabs = computed(() => { return items.value.reduce((acc, item) => { acc[item.id] = item.name; return acc; }, {}); }); </script>
Vue Props
| Prop | Type | Default | Description |
|---|---|---|---|
tabs |
Object | required | { key: 'Label' } pairs |
defaultActive |
String | first key | Initially active tab |
variant |
String | 'default' |
Style variant |
Events
| Event | Payload | Description |
|---|---|---|
change |
string |
Emitted when active tab changes |
Scoped Slot
The default slot receives:
active: Current active tab key
Variants
Default (Underline)
Traditional tab style with underline indicator on active tab.
Pills
Button-style tabs with background color on active tab.
Boxed
Segmented control style with contained background.
Accessibility
- Proper
role="tablist"androle="tab"attributes aria-selectedindicates active statearia-controlslinks tabs to panels- Keyboard navigation support
Styling
Uses Tailwind CSS:
- Border-based underline for default
- Rounded backgrounds for pills
- Gray background container for boxed
Requirements
- PHP 8.1+
- Laravel 10, 11, or 12
- Tailwind CSS 3.x
License
MIT License