Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Tabs Laravel Package

eminiarts/nova-tabs

View on GitHub
Deep Wiki
Context7

Getting Started

First Steps

  1. Installation: Run composer require eminiarts/nova-tabs in your Nova project (Nova 4+ only).
  2. Basic Setup: Add use Eminiarts\Tabs\Traits\HasTabs; to your Nova resource class.
  3. First Tab: Define a tabs() method returning a Tabs collection. Example:
    public function tabs()
    {
        return Tabs::make('User Details', [
            Tab::make('Basic Info', [
                Text::make('Name'),
                Text::make('Email'),
            ]),
            Tab::make('Profile', [
                Textarea::make('Bio'),
                Select::make('Role'),
            ]),
        ]);
    }
    
  4. View Result: Refresh your Nova resource page to see the new tabbed interface.

Quick Use Case

Problem: A resource with many fields cluttering the UI. Solution: Organize fields into logical tabs (e.g., "Basic Info," "Profile," "Permissions") for cleaner UX.


Implementation Patterns

Core Workflows

  1. Field Grouping by Context:

    • Use tabs to separate edit vs. detail views (e.g., hide sensitive fields in detail view but include them in an "Advanced" edit tab).
    • Example:
      public function fields(Request $request)
      {
          return [
              // ... default fields ...
              $this->tabs()->toFields($request),
          ];
      }
      
  2. Dynamic Tabs:

    • Conditionally load tabs based on user roles or resource state:
      public function tabs()
      {
          return Tabs::make('Settings', [
              Tab::make('Admin Only', [
                  // Fields visible only to admins
              ])->visible(fn () => auth()->user()->isAdmin()),
          ]);
      }
      
  3. Relationship Tabs:

    • Group related resources (e.g., "Orders" tab for a User resource):
      Tab::make('Orders', [
          BelongsToMany::make('Orders'),
      ])->relationship('orders'),
      
  4. Action Isolation:

    • Place destructive actions (e.g., "Delete") in a dedicated tab to reduce accidental clicks:
      Tab::make('Danger Zone', [
          Actions::make('Delete User', 'delete'),
      ]),
      

Integration Tips

  • Nova Tool Integration: Combine with other Nova tools (e.g., nova-impersonate) by overriding the tabs() method in child resources.
  • Form Requests: Use Tabs::make() in NovaFormRequest to validate tab-specific fields:
    public function rules()
    {
        return array_merge(
            parent::rules(),
            $this->tabs()->rules()
        );
    }
    
  • API Resources: Extend the package’s Tab class to add custom logic (e.g., API-only fields):
    class ApiTab extends Tab
    {
        public function apiFields()
        {
            return [...];
        }
    }
    

Gotchas and Tips

Common Pitfalls

  1. Tab Ordering:

    • Tabs render in the order defined in Tabs::make(). Use ->sortBy() or ->sortDesc() for dynamic ordering:
      Tabs::make('Settings')->sortBy(fn (Tab $tab) => $tab->name);
      
  2. Field Duplication:

    • Avoid adding the same field to multiple tabs. Use ->onlyOnForms() or ->onlyOnDetail() to scope fields:
      Text::make('Name')->onlyOnForms(),
      
  3. Relationship Caching:

    • Eager-load relationships for tabs to prevent N+1 queries:
      public function fields(Request $request)
      {
          $resource = $this->newModelInstance()->resolveRelationships();
          return $this->tabs()->toFields($request, $resource);
      }
      
  4. CSS Conflicts:

    • Nova’s default tab styling may clash with custom themes. Override via:
      /* resources/css/nova-custom.css */
      .tabs-panel .tab-content { /* Adjust padding/margins */ }
      

Debugging Tips

  • Tab Not Rendering?:

    • Verify HasTabs trait is used and tabs() returns a Tabs collection.
    • Check for PHP errors in Nova’s storage/logs/nova.log.
  • Field Data Missing:

    • Ensure fields are properly hydrated in the tabs() method. Use dd($this->tabs()) to inspect the structure.
  • Performance Issues:

    • Profile tab-heavy resources with Laravel Debugbar. Optimize by:
      • Lazy-loading tabs (e.g., only load "Advanced" tab on demand).
      • Using ->hideFromIndex() for tabs with expensive queries.

Extension Points

  1. Custom Tab Classes:

    • Extend Eminiarts\Tabs\Tab to add metadata or logic:
      class CustomTab extends Tab
      {
          public function isActive()
          {
              return request()->query('active_tab') === $this->name;
          }
      }
      
  2. Global Tab Events:

    • Listen for tab changes via the tab-changed event:
      Nova::serving(function () {
          Nova::script('nova-tabs-event', function () {
              window.addEventListener('tab-changed', (e) => {
                  console.log('Active tab:', e.detail.tabName);
              });
          });
      });
      
  3. Override Default Search:

    • Modify the search behavior in app/Providers/NovaServiceProvider.php:
      public function boot()
      {
          Nova::serving(function () {
              Nova::provideToApiRequest(function ($request) {
                  $request->merge([
                      'search' => $request->input('search', 'default-search-term'),
                  ]);
              });
          });
      }
      
  4. Localization:

    • Translate tab names dynamically:
      Tab::make(__('tabs.basic_info'), [
          // Fields...
      ]),
      
    • Publish and modify the language file:
      php artisan vendor:publish --provider="Eminiarts\Tabs\TabsServiceProvider" --tag="nova-tabs-lang"
      
  5. More Than 5 Tabs:

    • Disable the default limit by publishing the config:
      php artisan vendor:publish --provider="Eminiarts\Tabs\TabsServiceProvider" --tag="nova-tabs-config"
      
    • Update config/nova-tabs.php:
      'max_tabs' => null, // Remove the limit
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky