PHP code example of hdaklue / naptab

1. Go to this page and download the library: Download hdaklue/naptab library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

hdaklue / naptab example snippets




namespace App\Livewire;

use Hdaklue\NapTab\Livewire\NapTab;
use Hdaklue\NapTab\UI\Tab;
use Hdaklue\NapTab\Enums\Direction;

class DashboardTabs extends NapTab
{
    // Choose your preferred layout direction
    protected function direction(): Direction
    {
        return Direction::Horizontal; // Default: traditional top tabs
        // return Direction::Aside;   // Modern sidebar layout for dashboard-style interfaces
    }
    
    // CONTAINER-LEVEL CONTENT HOOKS (NEW FEATURE!)
    public function beforeContent(): string
    {
        return '<div class="bg-blue-50 border-l-4 border-blue-400 p-4 mb-6">
            <p class="text-blue-700">🚀 Welcome to your performance dashboard!</p>
        </div>';
    }
    
    public function afterContent(): \Closure
    {
        return fn() => view('partials.dashboard-footer', [
            'totalUsers' => \App\Models\User::count(),
            'lastUpdate' => now()
        ]);
    }
    
    protected function tabs(): array
    {
        return [
            // Controller method approach (recommended for dynamic content)
            Tab::make('overview')
                ->label('Overview')
                ->icon('chart-bar')
                ->beforeContent('<p class="text-sm text-gray-600 mb-4">📊 Real-time overview</p>'),
                
            // Direct content with live data + tab-level hooks
            Tab::make('analytics')
                ->label('Analytics')
                ->icon('presentation-chart-line')
                ->badge(fn() => $this->getPendingReports())
                ->beforeContent('<div class="alert alert-info mb-4">Analytics updated every 5 min</div>')
                ->afterContent(fn() => '<small class="text-gray-500">Last sync: ' . now()->format('H:i') . '</small>')
                ->content(fn() => view('dashboard.analytics', [
                    'data' => $this->getAnalyticsData() // Only loads when clicked!
                ])),
                
            // Livewire component integration
            Tab::make('settings')
                ->label('Settings')
                ->icon('cog-6-tooth')
                ->afterContent('<div class="mt-4 p-3 bg-gray-50 rounded">
                    <p class="text-xs text-gray-600">Changes are saved automatically</p>
                </div>')
                ->livewire(\App\Livewire\UserSettings::class, ['userId' => auth()->id()]),
        ];
    }

    // This method only runs when the Overview tab is clicked
    public function overview()
    {
        $metrics = [
            'users' => \App\Models\User::count(),
            'orders' => \App\Models\Order::today()->count(),
            'revenue' => \App\Models\Order::today()->sum('total'),
        ];
        
        return view('dashboard.overview', compact('metrics'));
    }
    
    private function getAnalyticsData()
    {
        // Complex analytics only computed when user accesses this tab
        return collect([
            'pageviews' => 15420,
            'conversions' => 342,
            'revenue' => 28750
        ]);
    }
    
    private function getPendingReports()
    {
        return \App\Models\Report::where('status', 'pending')->count();
    }
}



namespace App\Livewire;

use Hdaklue\NapTab\Livewire\NapTab;
use Hdaklue\NapTab\UI\Tab;
use Illuminate\View\View;
use Closure;

class DashboardTabs extends NapTab
{
    // CONTAINER-LEVEL HOOKS - Applied to entire tabs container
    
    public function beforeContent(): View
    {
        return view('partials.dashboard-header', [
            'user' => auth()->user(),
            'lastLogin' => auth()->user()->last_login_at
        ]);
    }
    
    public function afterContent(): Closure
    {
        return fn() => view('partials.dashboard-stats', [
            'totalTabs' => count($this->tabs()),
            'activeUsers' => \App\Models\User::online()->count(),
            'systemStatus' => $this->getSystemStatus()
        ]);
    }
    
    protected function tabs(): array
    {
        return [
            // TAB-LEVEL HOOKS - Applied to individual tab content
            Tab::make('analytics')
                ->label('Analytics Dashboard')
                ->beforeContent('<div class="bg-blue-50 border-l-4 border-blue-400 p-4 mb-4">
                    <p class="text-sm text-blue-700">📊 Analytics data is updated every 5 minutes</p>
                </div>')
                ->afterContent(fn() => '<div class="mt-4 text-sm text-gray-500 text-center">
                    Last updated: ' . now()->format('M j, Y \a\t g:i A') . '
                </div>')
                ->content(fn() => view('dashboard.analytics', [
                    'metrics' => $this->calculateAnalytics() // Only loads when clicked!
                ])),
                
            Tab::make('users')
                ->label('User Management') 
                ->beforeContent(fn() => $this->renderUserAlert())
                ->afterContent('<div class="bg-gray-50 p-3 rounded mt-4">
                    <p class="text-xs text-gray-600">Need help? Contact support</p>
                </div>')
                ->livewire(\App\Livewire\UserManagement::class),
        ];
    }
    
    private function renderUserAlert(): string
    {
        $pendingUsers = \App\Models\User::where('status', 'pending')->count();
        
        if ($pendingUsers > 0) {
            return "<div class='bg-yellow-50 border border-yellow-200 rounded-md p-3 mb-4'>
                <p class='text-sm text-yellow-800'>⚠️ {$pendingUsers} users pending approval</p>
            </div>";
        }
        
        return '';
    }
}

// Static HTML content
public function beforeContent(): string
{
    return '<div class="alert alert-info">Welcome to your dashboard!</div>';
}

// Dynamic Blade view
public function afterContent(): View
{
    return view('partials.footer', [
        'timestamp' => now(),
        'version' => config('app.version')
    ]);
}

// Closure for conditional content
public function beforeContent(): Closure
{
    return function() {
        if (auth()->user()->hasUnreadNotifications()) {
            return '<div class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-4">
                You have ' . auth()->user()->unreadNotifications()->count() . ' unread notifications.
            </div>';
        }
        
        return '';
    };
}

// Htmlable object
public function afterContent(): \Illuminate\Support\HtmlString
{
    return new \Illuminate\Support\HtmlString('<div>Custom HTML content</div>');
}

Tab::make('reports')
    ->label('Reports')
    
    // Alert header for this tab only
    ->beforeContent('<div class="bg-green-100 border border-green-400 text-green-700 px-4 py-3 rounded mb-4">
        Reports are generated in real-time
    </div>')
    
    // Dynamic footer with live data
    ->afterContent(fn() => view('components.report-footer', [
        'totalReports' => \App\Models\Report::count(),
        'lastGenerated' => \App\Models\Report::latest()->first()?->created_at
    ]))
    
    ->content(fn() => view('reports.index'));

Tab::make('settings')
    ->label('Settings')
    
    // Conditional warning
    ->beforeContent(function() {
        if (!auth()->user()->hasVerifiedEmail()) {
            return '<div class="bg-yellow-100 border border-yellow-400 text-yellow-700 px-4 py-3 rounded mb-4">
                Please verify your email address to access all features.
            </div>';
        }
        return null;
    })
    
    // Help link
    ->afterContent('<div class="mt-6 text-center">
        <a href="/help/settings" class="text-blue-600 hover:text-blue-800">Need help with settings?</a>
    </div>')
    
    ->livewire(\App\Livewire\UserSettings::class);

Tab::make('reviews')
    ->beforeContent(fn() => $this->renderTrustBadges())
    ->afterContent('<div class="mt-4 p-3 bg-blue-50 rounded">
        <p class="text-sm text-blue-700">All reviews are verified purchases</p>
    </div>')
    ->content(fn() => view('product.reviews'));

public function beforeContent(): string
{
    return view('admin.breadcrumbs', ['section' => 'Dashboard'])->render();
}

public function afterContent(): Closure
{
    return fn() => '<div class="mt-8 text-xs text-gray-500 text-center">
        Session expires in: <span id="session-timer">' . session()->getMaxLifetime() . '</span> minutes
    </div>';
}

Tab::make('step-2')
    ->beforeContent('<div class="progress-bar mb-4">
        <div class="progress-fill" style="width: 40%"></div>
    </div>')
    ->afterContent('<div class="flex justify-between mt-6">
        <button wire:click="previousStep" class="btn-secondary">Previous</button>  
        <button wire:click="nextStep" class="btn-primary">Next Step</button>
    </div>');



namespace App\Livewire;

use Hdaklue\NapTab\Livewire\NapTab;
use Hdaklue\NapTab\UI\Tab;
use App\Livewire\UserSettings;
use Illuminate\Support\Facades\Gate;

class ComprehensiveTabs extends NapTab
{
    protected function tabs(): array
    {
        return [
            // Method 1: Controller Method (Recommended for complex logic)
            Tab::make('dashboard')
                ->icon('chart-bar')
                ->badge(fn() => $this->getNotificationCount())
                ->visible(fn() => auth()->check())
                ->disabled(fn() => $this->isMaintenanceMode())
                ->beforeLoad(fn(Tab $tab) => $this->logTabAccess($tab->getId()))
                ->afterLoad(fn(Tab $tab, string $content) => $this->trackPerformance($tab->getId())),
                
            // Method 2: Direct Content (Simple HTML/Blade)
            Tab::make('about')
                ->icon('information-circle')
                ->content(fn() => '<div class="p-4">
                    <h2>About Our Company</h2>
                    <p>We are a leading provider...</p>
                </div>'),
                
            // Method 3: Blade View (Static content)
            Tab::make('contact')
                ->icon('envelope')
                ->content(fn() => view('pages.contact')),
                
            // Method 4: Livewire Component (Interactive content)
            Tab::make('settings')
                ->icon('cog-6-tooth')
                ->livewire(UserSettings::class, ['userId' => auth()->id()])
                ->visible(fn() => auth()->user()->can('manage-settings'))
                ->onError(fn(Tab $tab, Exception $error) => logger()->error('Settings tab error', [
                    'tab' => $tab->getId(),
                    'error' => $error->getMessage()
                ])),
                
            // Method 5: Advanced Configuration with Authorization
            Tab::make('analytics')
                ->icon('presentation-chart-line')
                ->badge('Pro')
                ->onSwitch(fn(Tab $tab, string $from, string $to) => $this->trackTabSwitch($from, $to)),
        ];
    }

    // Controller method for Method 1
    public function dashboard()
    {
        // Heavy computation only runs when tab is clicked
        $metrics = $this->calculateDashboardMetrics();
        $charts = $this->generateChartData();
        
        return view('dashboard.overview', compact('metrics', 'charts'));
    }
}



namespace App\Livewire;

use Hdaklue\NapTab\Livewire\NapTab;
use Hdaklue\NapTab\Enums\Direction;
use Hdaklue\NapTab\UI\Tab;

class ResponsiveSettings extends NapTab
{
    // Override the direction method to control layout
    protected function direction(): Direction
    {
        return Direction::Aside; // Sidebar layout for dashboard-style interfaces
        // return Direction::Horizontal; // Traditional top tabs (default)
    }
    
    protected function tabs(): array
    {
        return [
            Tab::make('profile')
                ->icon('user-circle'),
            Tab::make('privacy')
                ->label('Privacy')
                ->icon('shield-check'),
            Tab::make('billing')
                ->label('Billing')
                ->icon('credit-card')
                ->badge(fn() => $this->hasPendingInvoices() ? 'Action Required' : null),
        ];
    }
}

// Traditional horizontal layout (default)
protected function direction(): Direction
{
    return Direction::Horizontal;
}

// Modern aside/sidebar layout  
protected function direction(): Direction
{
    return Direction::Aside;
}

Tab::make('id')           // Creates a new tab instance
    ->label('Custom Label')        // Set tab label (string|Closure)
    ->icon('heroicon-name')        // Set Heroicon name (string|Closure|null)  
    ->badge('New')                 // Display badge text (string|Closure|null)
    ->disabled(true)               // Disable tab (bool|Closure, default: false)

Tab::make('admin')
    ->label('Admin Panel')
    ->visible(fn() => auth()->user()->isAdmin())           // Control visibility (bool|Closure)

// Option 1: Controller method (recommended for dynamic content)
Tab::make('dashboard') // Automatically calls $this->dashboard() method

// Option 2: Direct content with closure
Tab::make('about')
    ->label('About')
    ->content(fn() => view('pages.about'))  // Returns Htmlable content

// Option 3: Livewire component
Tab::make('settings')
    ->label('Settings')
    ->livewire(UserSettings::class, ['userId' => 123]) // Component class and params

Tab::make('profile')
    ->label('Profile')
    // Content placed before tab content
    ->beforeContent('<div class="alert alert-info mb-4">Profile information</div>')
    
    // Content placed after tab content (supports closures)
    ->afterContent(fn() => view('components.profile-footer', [
        'lastUpdated' => $user->updated_at
    ]))

Tab::make('analytics')
    ->label('Analytics')
    ->beforeLoad(function(Tab $tab) {
        // Called before tab content loads
        logger()->info("Loading tab: {$tab->getId()}");
    })
    ->afterLoad(function(Tab $tab, string $content) {
        // Called after content is loaded
        $this->trackTabView($tab->getId());
    })
    ->onError(function(Tab $tab, Exception $error) {
        // Called when tab loading fails
        $this->logTabError($tab->getId(), $error->getMessage());
    })
    ->onSwitch(function(Tab $tab, string $fromTabId, string $toTabId) {
        // Called when switching to this tab
        $this->analyzeTabFlow($fromTabId, $toTabId);
    });

public function reports()
{
    // Database queries only execute when user clicks this tab
    $reports = Report::with('author')
        ->where('status', 'published')
        ->latest()
        ->paginate(20);
        
    return view('tabs.reports', compact('reports'));
}

Tab::make('terms')
    ->label('Terms of Service')
    ->content('<div class="prose max-w-none">
        <h1>Terms of Service</h1>
        <p>By using our service...</p>
    </div>')

Tab::make('faq')
    ->label('FAQ')
    ->content(view('pages.faq', ['categories' => $this->getFaqCategories()]))

Tab::make('chat')
    ->label('Live Chat')
    ->livewire(ChatWidget::class, [
        'room' => 'support',
        'user' => auth()->user()
    ])

Tab::make('inbox')
    ->label('Messages')
    ->badge(fn() => auth()->user()->unreadMessages()->count())
    ->visible(fn() => auth()->check())
    
Tab::make('notifications')
    ->label('Notifications')
    ->badge(function() {
        $count = auth()->user()->unreadNotifications()->count();
        return $count > 99 ? '99+' : (string) $count;
    })
    ->beforeLoad(fn(Tab $tab) => $this->markNotificationsAsRead())



namespace App\Providers;

use Hdaklue\NapTab\Services\NapTabConfig;
use Hdaklue\NapTab\Enums\{
    TabStyle, TabColor, TabBorderRadius, Shadow, 
    TabSpacing, TabBorderWidth, TabTransition, 
    TabTransitionTiming, BadgeSize, ContentAnimation, Direction
};
use Illuminate\Support\ServiceProvider;

class NapTabServiceProvider extends ServiceProvider
{
    public function register()
    {
        $this->app->singleton('naptab.config', function () {
            return NapTabConfig::create()
                // Preset styles - applies multiple settings at once
                ->style(TabStyle::Modern)                    // Modern | Minimal | Sharp | Pills
                
                // Visual customization
                ->color(TabColor::Blue, TabColor::Gray)      // Primary & secondary colors
                ->radius(TabBorderRadius::Medium)            // Border radius
                ->shadow(Shadow::Large, 'shadow-blue-500/20 dark:shadow-blue-400/30')
                ->border(TabBorderWidth::Thick, true)        // Width & double border
                ->spacing(TabSpacing::Normal)                // Tab spacing
                ->transition(TabTransition::Duration300, TabTransitionTiming::EaseInOut)
                
                // Badge customization  
                ->badgeRadius(TabBorderRadius::Full)
                ->badgeSize(BadgeSize::Medium)
                
                // Content animation
                ->contentAnimation(ContentAnimation::Fade)
                
                // Mobile navigation
                ->navModalOnMobile(false);                   // true = modal, false = scroll
        });
    }
    
    public function boot()
    {
        // Service provider boot logic
    }
}

NapTabConfig::create()                              // Create new config instance
    ->style(TabStyle $style)                        // Modern | Minimal | Sharp | Pills preset
    ->color(TabColor $primary, TabColor $secondary) // Theme colors  
    ->radius(TabBorderRadius $radius)               // Border radius
    ->shadow(Shadow $shadow, ?string $color)        // Shadow size and custom color
    ->border(TabBorderWidth $width, ?bool $double)  // Border width and double border
    ->spacing(TabSpacing $spacing)                  // Small | Normal | Large
    ->transition(TabTransition $duration, ?TabTransitionTiming $timing)

->badgeRadius(TabBorderRadius $radius)              // Badge border radius
->badgeSize(BadgeSize $size)                        // Small | Medium | Large

->contentAnimation(ContentAnimation $animation)     // Content transition animation
->navModalOnMobile(bool $useModal = true)          // Mobile modal navigation

->style(TabStyle::Modern)
// Rich visual experience with shadows, thick borders, large badges

->style(TabStyle::Minimal)
// Clean design with no shadows, thin borders, small badges, compact spacing

->style(TabStyle::Sharp) 
// Bold geometric design with no shadows, no borders, no rounded corners

->style(TabStyle::Pills)
// Modern pill-shaped tabs with full borders, rounded corners, and no container underline

// Configuration is cached as singleton in service container
$this->app->singleton('naptab.config', function () {
    return NapTabConfig::create()->style(TabStyle::Pills);
});

// config/app.php
'providers' => [
    // ...
    App\Providers\NapTabServiceProvider::class,
],

->navModalOnMobile(true)

// In your tab component class
class DashboardTabs extends NapTab
{
    protected function isRoutable(): bool
    {
        return true; // Enable routing for this component
    }
    
    // Or disable routing for specific components
    protected function isRoutable(): bool
    {
        return false; // This component won't use URL routing
    }
}

// routes/web.php
Route::get('/dashboard/{activeTab?}', DashboardTabs::class)->name('dashboard');

// Dashboard with routing (bookmarkable tabs)
class DashboardTabs extends NapTab
{
    protected function isRoutable(): bool
    {
        return true;
    }
}

// Modal or sidebar tabs without routing
class UserSettingsTabs extends NapTab
{
    protected function isRoutable(): bool
    {
        return false; // No URL changes for these tabs
    }
}
bash
php artisan naptab:install