wezlo/filament-search-spotlight
Full-screen Spotlight/command-palette search for Filament panels (⌘K/Ctrl+K). Aggregates global search records plus resources, pages, and actions, with recent/pinned items stored in localStorage. Keyboard navigation, configurable per panel and via config.
Installation:
composer require wezlo/filament-search-spotlight
Register the plugin in your Filament panel:
->plugins([
FilamentSearchSpotlightPlugin::make(),
])
First Use Case:
⌘K (or configured shortcut) to open the Spotlight overlay.create page).Enter, or close with Esc.Where to Look First:
php artisan vendor:publish --tag=filament-search-spotlight-config
theme.css scans the package’s views:
@source '../../../../vendor/wezlo/filament-search-spotlight/resources/views/**/*';
Rebuild with npm run build.Plugin Registration: Configure globally or per-panel using the fluent API:
FilamentSearchSpotlightPlugin::make()
->keyBinding('mod+k')
->placeholder('Jump to…')
->excludeResources([AuditLogResource::class])
->action(SpotlightAction::make('custom-action')->url('/path'));
Search Categories:
GlobalSearchProvider (attaches resource icons).Category contract (e.g., for settings or reports):
class MyCategory implements Category {
public function search(string $query, int $limit): array { ... }
}
Actions:
AppServiceProvider):
SpotlightAction::make('clear-cache')->register();
->action(SpotlightAction::make('log-out')->url(fn () => filament()->getLogoutUrl()))
Exclusions:
->excludeResources([Resource::class])
->records(false)->actionsEnabled(false)
->disableDefaultGlobalSearch()
->keyBinding(['mod+k', 'ctrl+k'])
maxWidth() or inline styles (not purged by Tailwind):
->maxWidth('40rem')
php artisan test --compact tests/Feature/FilamentSearchSpotlight
Tailwind Purging:
theme.css doesn’t scan the package’s views.@source directive and rebuild:
@source '../../../../vendor/wezlo/filament-search-spotlight/resources/views/**/*';
Resource Exclusions:
excludeResources() or disable Create actions separately:
->excludeResources([Resource::class]) // Hides all
->disableCreateActions() // Only hides Create actions
Action Overrides:
name.overrideActions() to hide without replacing:
->overrideActions(['legacy-action'])
LocalStorage Dependencies:
localStorage on logout if needed (client-side JS).Fuzzy Matching:
str_contains() for fuzzy matching. Complex queries may yield unexpected results.search() method for custom logic (e.g., regex or library like fuzzy-matcher).Empty Results:
GlobalSearchProvider is implemented for records.excluded_resources in config/plugin.Styling Issues:
maxWidth is set and not overridden by Tailwind.Keyboard Shortcuts:
mod+k handlers).localStorage.Custom Categories:
Category contract for new data sources (e.g., API endpoints):
class ApiCategory implements Category {
public function search(string $query, int $limit): array {
return collect($this->fetchFromApi($query))
->map(fn ($item) => new SpotlightResult(
id: 'api:'.$item['id'],
title: $item['name'],
url: $item['url'],
// ...
));
}
}
Dynamic Actions:
->action(SpotlightAction::make('dynamic-action')
->url(fn () => route('admin.user.edit', ['user' => auth()->id()]))
)
Translations:
resources/lang/en/spotlight.php) or publish them:
php artisan vendor:publish --tag=filament-search-spotlight-lang
Recent/Pinned Logic:
resources/js/filament-search-spotlight.js).Power User Shortcuts: Add frequently used actions to the global registry:
SpotlightAction::make('toggle-dark-mode')
->keywords(['dark', 'light'])
->url(fn () => route('admin.settings.toggle-theme'))
->register();
Panel-Specific Config: Use the fluent API to override global settings per panel:
FilamentSearchSpotlightPlugin::make()
->placeholder('Admin: Jump to…')
->keyBinding('ctrl+shift+k')
Performance: Limit results per category to avoid UI lag:
->resultLimitPerCategory(5)
Accessibility:
Ensure keyboard navigation works (arrow keys, Enter, Esc) and test with screen readers. The package handles this out-of-the-box, but custom categories should follow these patterns.
How can I help you explore Laravel packages today?