Installation:
composer require jibaymcs/tabbed
Add to PanelProvider:
use JibayMcs\Tabbed\TabbedPlugin;
public function panel(Panel $panel): Panel {
return $panel->plugins([TabbedPlugin::make()]);
}
First Use Case:
Add HasTabbedActions trait to a resource (e.g., UserResource):
use JibayMcs\Tabbed\Traits\HasTabbedActions;
class UserResource extends Resource {
use HasTabbedActions;
}
Now, every table row will have an "Open in Tab" action.
use JibayMcs\Tabbed\Traits\HasTabbedActions;
class PostResource extends Resource {
use HasTabbedActions; // Auto-adds "Open in Tab" to all rows
}
use JibayMcs\Tabbed\Actions\OpenInTabAction;
public static function table(Table $table): Table {
return $table->recordActions([
OpenInTabAction::make()
->tabName(fn ($record) => "Draft: {$record->title}")
->tabColor(Color::Yellow)
->background(), // Open without switching
]);
}
tabName(): Customize tab labels dynamically.tabColor()/tabBackground(): Visual hierarchy (e.g., urgent tabs in red).openFor(): Resolve related records (e.g., open a Comment from a Post).confirmOnClose(): Prevent accidental closure of unsaved tabs.Post).OpenInTabAction::make()
->resource(AuthorResource::class)
->openFor(fn ($post) => $post->author) // Resolve related record
->tabName(fn ($author) => $author->name);
->visible(fn ($post) => $post->author) to avoid null errors.OpenInTabAction::make()
->canRename(fn ($record) => auth()->user()->isAdmin())
->canPin(fn ($record) => $record->is_pinned);
allowReorder(false) in TabbedPlugin) act as master switches.OpenInTabAction::make()
->hoverCardContent(fn ($record) => view('filament.tab-preview', ['record' => $record]))
->hoverCardPosition(HoverCardPosition::Bottom);
e() or htmlspecialchars().// Open a tab
window.dispatchEvent(new CustomEvent('tabbed:open', {
detail: {
resource: 'App\\Filament\\Resources\\UserResource',
recordId: 1,
label: 'User Profile',
}
}));
// Close a tab
window.dispatchEvent(new CustomEvent('tabbed:close', { detail: { id: 'tab-uuid' } }));
tabbed:tab-opened, tabbed:tab-closed, etc., for reactivity.TabbedPlugin::make()
->lazyLoad() // Load content only on activation
->destroyInactive(); // Unmount components when not visible
Alt+W to close tabs).TabbedPlugin::make()->keyboardShortcuts([
closeTab: 'ctrl+w', // Override defaults
]);
openFor Misuse:
openFor with visible() checks:
->openFor(fn ($parent) => $parent->relation)
->visible(fn ($parent) => $parent->relation)
Dirty State Conflicts:
confirmOnClose() sparingly or disable globally:
TabbedPlugin::make()->confirmClose(false);
Lazy Loading + Redirects:
TabbedPlugin::make()->interceptRedirects();
CSS Conflicts:
!important in your CSS or inspect the generated classes (e.g., .tabbed-tab--active).LocalStorage Key Collisions:
tabbed_tabs) overwrite each other.TabbedPlugin::make()->persistKey('panel_name_tabs');
Tab Not Opening?
tabbed:open event errors.Hover Cards Not Showing?
hoverCardDelay isn’t set too high (default: 600ms).->hoverCardContent(fn () => "Test")
Drag & Drop Not Working?
allowReorder(true) is set in TabbedPlugin.Permissions Overrides:
allowPin(false)) take precedence over per-tab closures.dd(TabbedPlugin::make()->getOptions());
Custom Tab Components:
renderHook:
TabbedPlugin::make()->renderHook(PanelsRenderHook::TOPBAR_LOGO_AFTER);
TabbedTab view in your theme:
@source '../../../../vendor/jibaymcs/tabbed/resources/views/tabbed/tab.blade.php'
Tab Metadata:
OpenInTabAction:
->extraData(fn ($record) => ['priority' => $record->urgency]);
event.detail.tab.extraData.Tab Events:
tabbed:tab-activated to trigger side effects (e.g., load related data):
document.addEventListener('tabbed:tab-activated', (e) => {
console.log('Active tab ID:', e.detail.tabId);
});
Dark Mode:
.dark).->tabColor(Color::Gray[500]) // Light mode
->tabBackground(Color::Gray[800]) // Dark mode
Tab Search:
TabbedPlugin::make()->dropdownMode();
Pinned Tabs:
OpenInTabAction::make()->
How can I help you explore Laravel packages today?