Skip to content

Custom Commands

Commands are the basis of the Spotlight results. You can create custom commands to fit your needs. Every commands extends the SpotlightResult class and can be configured via setUp() method. A simple command could be a link to a specific page.

php
use pxlrbt\FilamentSpotlightPro\SpotlightResults\SpotlightResult;

class GoToDocsCommand extends SpotlightResult
{
    public function setUp()
    {
        $this
            ->label('Open Docs')
            ->icon('heroicon-o-link')
            ->order(1)
            ->url('/docs');
    }
}

Then register your command in your SpotlightPlugin:

php
use pxlrbt\FilamentSpotlightPro\SpotlightPlugin;

SpotlightPlugin::make()->registerItems([
    GoToDocsCommand::make()
])

Preloading

By default commands are preloaded. That means they are loaded when Spotlight is opened and before searching. If you only want to include certain commands when searching you can use ->preload(false).

Searching

By default all commands are filtered by their label. You can overwrite that behavior by overriding the filter() method:

php
public function filter(string $search, SpotlightContext $context): bool
{
    return true;    
}

Context

For multi-level navigation Spotlight uses a Context object so every command and query can determine whether it should be displayed or run. By default all commands are only shown for the root context. You can also change this by overriding the filter() method.

The Context objects contains of a stack which has a data array for every key. The keys are used to create a "route name". For example the resources queries are only shown on /{$recourceClass} "route". Commands and queries can be filtered by the context route name by using ->forContext($key).

Pushing Context

To add context to the stack you can use the PushContextAction. The action accepts the key that is used for the context, a label that is shown in the UI and an optional data array.

php
use pxlrbt\FilamentSpotlightPro\SpotlightResult;

class DocsCommand extends SpotlightResult
{
    public function setUp()
    {
        $this
            ->label('Docs')
            ->icon('heroicon-o-document')
            ->closeOnSelect(false)
            ->action(
                PushContextAction::make('docs', 'Docs', [])                    
            );
    }
}

You can then use the ->forContext($key) method to add commands for that context:

php
use pxlrbt\FilamentSpotlightPro\SpotlightResult;

class GoToDocsCommand extends SpotlightResult
{
    public function setUp()
    {
        $this
            ->label('Go To Docs')
            ->icon('heroicon-o-arrow-top-right-on-square')
            ->url('https://external-docs.test')
            ->forContext('/docs');            
    }
}

Running Actions

Spotlight also allows you to run Filament Actions. Instead of the PushContextAction you can use a Filament action. Make sure the Filament action name is unique. Actions that open a form should use the ->closeOnSelect(false) method to keep the Spotlight component active while running the action. You can close the component after your action ran by dispatching the spotlight-close event.

php
use Filament\Actions\Action;
use pxlrbt\FilamentSpotlightPro\SpotlightResult;

class ClearDocsCacheCommand extends SpotlightResult
{
    public function setUp()
    {
        $this
            ->label('Go To Docs')
            ->icon('heroicon-o-arrow-top-right-on-square')           
            ->forContext('/docs')
            ->closeOnSelect(false)
            ->action(
                Action::make('clearDocsCache')
                    ->requiresConfirmation()
                    ->action(function () {
                        // Clear the docs
                    })
                    ->after(fn (Component $livewire) => $livewire->dispatch('spotlight-close'))
            )
    }
}

Javascript Actions

You can directly run Javascript by using Filaments alpineClickHandler() method:

php
use Filament\Support\RawJs;use pxlrbt\FilamentSpotlightPro\SpotlightResult;

class BackCommand extends SpotlightResult
{
    public function setUp()
    {
        $this
            ->label('Go Back')
            ->icon('heroicon-o-arrow-top-right-on-square')           
            ->forContext('/docs')
            ->closeOnSelect(false)
            ->action(
                Action::make('back')
                    ->requiresConfirmation()
                    ->action(function () {
                        return $this->alpineClickHandler(new RawJs('window.history.back()'));
                    })
            )
    }
}