Coder Social home page Coder Social logo

wire-elements / spotlight Goto Github PK

View Code? Open in Web Editor NEW
912.0 15.0 71.0 458 KB

Livewire component that brings Spotlight/Alfred-like functionality to your Laravel application.

License: MIT License

PHP 58.52% Blade 18.16% JavaScript 22.89% CSS 0.44%
laravel livewire livewire-components

spotlight's Introduction

Total Downloads Total Downloads Latest Stable Version License

About Wire Elements Spotlight

Wire Elements Spotlight is a Livewire component that provides Spotlight/Alfred-like functionality to your Laravel application. View demo video.

Installation

Laravel Spotlight Tutorial

Click the image above to read a full article on using the Wire Elements Spotlight package or follow the instructions below.

To get started, require the package via Composer:

composer require wire-elements/spotlight

Livewire directive

Add the Livewire directive @livewire('livewire-ui-spotlight'):

<html>
<body>
<!-- content -->

@livewire('livewire-ui-spotlight')
</body>
</html>

Alpine (only when using Livewire v2)

Spotlight requires Alpine. You can use the official CDN to quickly include Alpine:

<script defer src="https://unpkg.com/[email protected]/dist/cdn.min.js"></script>

Opening Spotlight

To open the Spotlight input bar you can use one of the following shortcuts:

  • CTRL + K
  • CMD + K
  • CTRL + /
  • CMD + /

You can customize the keybindings in the configuration file (see below). It's also possible to toggle Spotlight from any other Livewire component or via Javascript.

In any Livewire component you can use the dispatchBrowserEvent or dispatch helper.

// Livewire v2
$this->dispatchBrowserEvent('toggle-spotlight');

// Livewire v3
$this->dispatch('toggle-spotlight');

You can also use the $dispatch helper from Alpine to trigger the same browser event from your markup.

<button @click="$dispatch('toggle-spotlight')">Toggle Spotlight</button>

Creating your first Spotlight command

You can create your first Spotlight command by creating a new class and have it extend LivewireUI\Spotlight\SpotlightCommand. Start by defining a $name and $description for your command. The name and description will be visible when searching through commands.

To help you get started you can use the php artisan make:spotlight <command-name> command.

use LivewireUI\Spotlight\SpotlightCommand;

class Logout extends SpotlightCommand
{
    protected string $name = 'Logout';

    protected string $description = 'Logout out of your account';

}

The execute method is called when a command is chosen, and the command has no dependencies. Let's for example take a look at the Logout command execute method:

use Illuminate\Contracts\Auth\StatefulGuard;
use LivewireUI\Spotlight\Spotlight;
use LivewireUI\Spotlight\SpotlightCommand;

class Logout extends SpotlightCommand
{
    protected string $name = 'Logout';

    protected string $description = 'Logout out of your account';

    public function execute(Spotlight $spotlight, StatefulGuard $guard): void
    {
        $guard->logout();
        $spotlight->redirect('/');
    }
}

As you can see, you can type-hint your dependencies and have them resolved by Laravel. If you type-hint Spotlight $spotlight, you will get access to the Livewire Spotlight component. This gives you access to all the Livewire helpers, so you can redirect users, emit events, you name it.

How to define search synonyms

Sometimes you may want to include additional search terms (often called synonyms) when searching for commands. This can be useful if users refer to something by multiple names or the command may include more than one piece of functionality (for example, a settings page that has multiple types of settings on it). You can add as many synonyms as you want directly on a command by defining a $synonyms array:

use LivewireUI\Spotlight\Spotlight;
use LivewireUI\Spotlight\SpotlightCommand;

class ViewBillingSettings extends SpotlightCommand
{
    protected string $name = 'View Billing Settings';

    protected string $description = 'Update your billing settings';

    protected array $synonyms = [
        'subscription',
        'credit card',
        'payment',
    ];

    public function execute(Spotlight $spotlight): void
    {
        $spotlight->redirect('/settings/billing');
    }
}

When searching, users can now enter "credit card" and they'll be shown a search result for the View Billing Settings command.

How to define command dependencies

In some cases your command might require dependencies. Let's say we want to create a new user and add it to a specific team. In this case we would need to define a team dependency. To define any dependencies, add a new method to your command and name the method dependencies.

You can use the SpotlightCommandDependencies::collection() method to create a new collection of dependencies. Call the add method to register a new dependency. You can add as many of dependencies as you like. The user input prompt follows the order in which you add the commands.

SpotlightCommandDependencies::collection()
    ->add(SpotlightCommandDependency::make('team')->setPlaceholder('For which team do you want to create a user?'))
    ->add(SpotlightCommandDependency::make('foobar')->setPlaceholder('Input from user')->setType(SpotlightCommandDependency::INPUT));

For every dependency, Spotlight will check if a search{dependency-name} method exists on the command. This method provides the search query given by the user. For example, to search for our team dependency:

public function searchTeam($query)
{
    return Team::where('name', 'like', "%$query%")
        ->get()
        ->map(function(Team $team) {
            return new SpotlightSearchResult(
                $team->id,
                $team->name,
                sprintf('Create license for %s', $team->name)
            );
        });
}

Spotlight expects a collection of SpotlightSearchResult objects. The SpotlightSearchResult object consists out of the result identifier, name and description.

Every dependency will have access to the already defined dependencies. So in the example below, you can see that searchFoobar has access to the Team the user has chosen. This allows for scoped dependency searching.

use LivewireUI\Spotlight\Spotlight;
use LivewireUI\Spotlight\SpotlightCommand;
use LivewireUI\Spotlight\SpotlightCommandDependencies;
use LivewireUI\Spotlight\SpotlightCommandDependency;
use LivewireUI\Spotlight\SpotlightSearchResult;

class CreateUser extends SpotlightCommand
{
    protected string $name = 'Create user';

    protected string $description = 'Create new team user';

    public function dependencies(): ?SpotlightCommandDependencies
    {
        return SpotlightCommandDependencies::collection()
            ->add(SpotlightCommandDependency::make('team')->setPlaceholder('For which team do you want to create a user?'))
            ->add(SpotlightCommandDependency::make('foobar')->setPlaceholder('Search for second dependency')
            );
    }

    public function searchFoobar($query, Team $team)
    {
        // Given Foobar is the second dependency it will have access to any resolved depedencies defined earlier. In this case we can access the Team which was chosen.
    }

    public function searchTeam($query)
    {
        return Team::where('name', 'like', "%$query%")
            ->get()
            ->map(function(Team $team) {
                return new SpotlightSearchResult(
                    $team->id,
                    $team->name,
                    sprintf('Create user for %s', $team->name)
                );
            });
    }

    public function execute(Spotlight $spotlight, Team $team, string $name)
    {
        $spotlight->emit('openModal', 'user-create', ['team' => $team->id, 'name' => $name]);
    }
}

Register commands

You can register commands by adding these to the livewire-ui-spotlight.php config file:

<?php

return [
    'commands' => [
        \App\SpotlightCommands\CreateUser::class
    ]
];

It's also possible to register commands via one of your service providers:

use \App\SpotlightCommands\CreateUser;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Spotlight::registerCommand(CreateUser::class);

        // You can also register commands conditionally
        Spotlight::registerCommandIf(true, CreateUser::class);
        Spotlight::registerCommandUnless(false, CreateUser::class);
    }

}

Alternatively, you can also conditionally show or hide a command from the command itself. (Note: you will still need to register your command in your config file or in a service provider.) Add the shouldBeShown method to your command and add any logic to resolve if the command should be shown. Dependencies are resolved from the container, so you can for example verify if the currently authenticated user has the required permissions to access given command:

use Illuminate\Http\Request;
use LivewireUI\Spotlight\Spotlight;
use LivewireUI\Spotlight\SpotlightCommand;

class CreateUser extends SpotlightCommand
{
    protected string $name = 'Create user';

    protected string $description = 'Create new team user';

    public function execute(Spotlight $spotlight)
    {
        $spotlight->emit('openModal', 'user-create');
    }

    public function shouldBeShown(Request $request): bool
    {
        return $request->user()->can('create user');
    }
}

If you need to do logic that can't be done in a service provider (for example, any logic that needs to use the currently authenticated user) to determine if your command should be shown in the Spotlight component, you can add a shouldBeShown method on your command. You can type-hint any dependencies you need and they'll be resolved out of the container for you. (Note: you will still need to register your command in your config file or in a service provider.)

use Illuminate\Http\Request;
use LivewireUI\Spotlight\Spotlight;
use LivewireUI\Spotlight\SpotlightCommand;

class CreateUser extends SpotlightCommand
{
    protected string $name = 'Create user';

    protected string $description = 'Create new team user';

    public function execute(Spotlight $spotlight)
    {
        $spotlight->emit('openModal', 'user-create');
    }

    public function shouldBeShown(Request $request): bool
    {
        return $request->user()->can('create user');
    }
}

Configuration

You can customize Spotlight via the livewire-ui-spotlight.php config file. This includes some additional options like including CSS if you don't use TailwindCSS for your application. To publish the config run the vendor:publish command:

php artisan vendor:publish --tag=livewire-ui-spotlight-config
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Shortcuts
    |--------------------------------------------------------------------------
    |
    | Define which shortcuts will activate Spotlight CTRL / CMD + key
    | The default is CTRL/CMD + K or CTRL/CMD + /
    |
    */

    'shortcuts' => [
        'k',
        'slash',
    ],

    /*
    |--------------------------------------------------------------------------
    | Commands
    |--------------------------------------------------------------------------
    |
    | Define which commands you want to make available in Spotlight.
    | Alternatively, you can also register commands in your AppServiceProvider
    | with the Spotlight::registerCommand(Logout::class); method.
    |
    */

    'commands' => [
        \LivewireUI\Spotlight\Commands\Logout::class
    ],

    /*
    |--------------------------------------------------------------------------
    | Include CSS
    |--------------------------------------------------------------------------
    |
    | Spotlight uses TailwindCSS, if you don't use TailwindCSS you will need
    | to set this parameter to true. This includes the modern-normalize css.
    |
    */
    'include_css' => false,

    /*
    |--------------------------------------------------------------------------
    | Include JS
    |--------------------------------------------------------------------------
    |
    | Spotlight will inject the required Javascript in your blade template.
    | If you want to bundle the required Javascript you can set this to false
    | run `npm install --save fuse.js` and add `require('vendor/wire-elements/spotlight/resources/js/spotlight');`
    | to your script bundler like webpack.
    |
    */
    'include_js' => true,
];

If you want to translate or change default the placeholder you will need to publish the translation file.

php artisan vendor:publish --tag=livewire-ui-spotlight-translations
<?php

return [
    'placeholder' => 'What do you want to do?',
];

If you want to change the spotlight view, you can also publish the views.

php artisan vendor:publish --tag=livewire-ui-spotlight-views

Credits

License

Wire Elements is open-sourced software licensed under the MIT license.

Beautiful components crafted with Livewire

spotlight's People

Contributors

dvanscott avatar freekmurze avatar jplhomer avatar laravel-shift avatar owenvoke avatar philonl avatar riasvdv avatar shuvroroy avatar usernotnull avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

spotlight's Issues

Can't search on other fields then name

If I have in my dependency a filter to search on name or email, I don't see any results in the spotlight if I search on the email address. I do see that the result is returned in the debug bar.

Schermafbeelding 2021-11-25 om 13 27 33
Schermafbeelding 2021-11-25 om 13 27 10

Alpine 3

We are all waiting for Alpine3 compability...

Invalid argument supplied for foreach()

Error at : SpotlightServiceProvider.php:35

Error:

foreach (config('livewire-ui-spotlight.commands') as $command) {

            Spotlight::registerCommand($command);

        }

Commands work but search gives console errors

Love the package and sure this is something with my setup but I've tried a number of things and hit the same wall. When you search an indigo bar appears but it doesn't activate and the console fills with errors:
image
I have alpine installed as a module, it was 3.2 and now 3.9.1 - alpine components work.
Any thoughts?
Thanks.

Automatic deployment and problem with css

Hi,

I am trying this package out locally and it works flawlessly, however when we run automatic deployment on our server this is how it looks:

image

Showing the console takes whole screen like some css was not built. When I manually run npm run prod on the vps all is good. Dont you know what might be wrong? Other css and js in the project works just fine.

Scoped dependency searching executes a query on every keystroke

If I use the example;

public function searchTeam($query)
  {
      return Team::where('name', 'like', "%$query%")
          ->get()
          ->map(function(Team $team) {
              return new SpotlightSearchResult(
                  $team->id,
                  $team->name,
                  sprintf('Create user for %s', $team->name)
              );
          });
  }
    

It does a query every keystroke, is there a way to fix this?

Can't access auth()->user() in AppServiceProvider boot()

The documentation mentions that you can register the command in the boot() method of the AppServiceProvider file.

use \App\SpotlightCommands\CreateUser;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Spotlight::registerCommand(CreateUser::class);

        // You can also register commands conditionally
        Spotlight::registerCommandIf($user->isAdmin(), CreateUser::class);
        Spotlight::registerCommandUnless($user->isSuspended(), CreateUser::class);
    }

}

This is not working because $user or auth()->user() cannot be accessed during the boot() method.

Any ideas on how to conditionally register commands based on the user?

Langs support

Hi,

Is there any way how to use laravel langs and their values in defining for the command name and description?

For me this does not work:
image

Thank you!

Commands specific to a route

Hi,
It would be interesting to have something that allows some commands to appear only on one route, for example:

Command 1 -> all
Command 2 -> dashboard
Command 3 -> profile.*

Alpine Error: "SyntaxError: Unexpected token '}'"

I'm running v1.0.0 of Spotlight and have implemented the example logout command.

When typing 'Logout', the dropdown does not appear and the following error is sent to the console:

[Warning] Alpine Error: "SyntaxError: Unexpected token '}'" (app.js, line 123)

Expression: ""
Element: – 
<template x-for="(item, i) in filteredItems()" :key>…</template>

<template x-for="(item, i) in filteredItems()" :key>…</template>
[Error] SyntaxError: Unexpected token '}'
	handleError (app.js:130)
	tryCatch (app.js:142)
	(anonymous function) (app.js:563)
	forEach
	handleForDirective (app.js:561)
	(anonymous function) (app.js:1751)
	forEach
	resolveBoundAttributes (app.js:1711)
	updateElement (app.js:1687)
	(anonymous function) (app.js:1643)
	walk (app.js:98)
	walk (app.js:102)
	walk (app.js:102)
	walk (app.js:102)
	walk (app.js:102)
	walkAndSkipNestedComponents (app.js:1598)
	updateElements (app.js:1640)
	(anonymous function) (app.js:1548)
	later (app.js:114)

Spotlight v0.1.8 does not exhibit this behaviour.

I'm using:

Livewire v2.5.1
Alpine v3.2.1
Laravel v8.49.1

Love the component and will be using it in several projects.
Thanks

Issue with resolution of models with two words

In this case, this is my example spotlight command:

<?php

namespace App\Spotlight;

use App\Models\CrashCourse;
use LivewireUI\Spotlight\Spotlight;
use LivewireUI\Spotlight\SpotlightCommand;
use LivewireUI\Spotlight\SpotlightCommandDependencies;
use LivewireUI\Spotlight\SpotlightCommandDependency;
use LivewireUI\Spotlight\SpotlightSearchResult;

class FindCrashCourse extends SpotlightCommand
{
    protected string $name = 'Find crash course';
    protected string $description = 'Find a crash course';

    /**
     * Defining dependencies is optional. If you don't have any dependencies you can remove this method.
     * Dependencies are asked from your user in the order you add the dependencies.
     */
    public function dependencies(): ?SpotlightCommandDependencies
    {
        return SpotlightCommandDependencies::collection()
            ->add(
                SpotlightCommandDependency::make('crash course')
                ->setPlaceholder('What is the title or ID of the crash course you are looking for')
            );
    }

    /**
     * Spotlight will resolve dependencies by calling the search method followed by your dependency name.
     * The method will receive the search query as the parameter.
     */
    public function searchCrashCourse($query)
    {
        $input = "%$query%";

        return CrashCourse::query()
            ->orWhere('title', 'LIKE', $input)
            ->take(10)
            ->orderByDesc('created_at')
            ->get()
            ->map(function(CrashCourse $crashCourse) {
                return new SpotlightSearchResult(
                    $crashCourse->id,
                    $crashCourse->title,
                    'View crash course'
                );
            });
    }

    /**
     * When all dependencies have been resolved the execute method is called.
     * You can type-hint all resolved dependency you defined earlier.
     */
    public function execute(Spotlight $spotlight, CrashCourse $crashCourse)
    {
        // The issue here is it's returning null for $crashCourse
        dd($crashCourse);

        $spotlight->redirectRoute('admin.crash-course.details', $crashCourse);
    }
}

When diving deeper into the logic that calls the execute method, it's returning crash course with a space. I've tried multiple forms $crash_course, $CrashCourse, $crash_Course` and nothing seems to work here.

If I dump out the dependencies from Livewire's ImplicitlyBoundMethodClass I get this.

array:4 [▼
  0 => "d6651b5f3cdb0b88d94529c6355233eb"
  1 => "crash course"
  2 => "test"
  3 => array:1 [▼
    "crash course" => 1
  ]
]

Feature request: Autosuggestion dependency type

It would be really nice to have a way to provide autosuggestions to dependencies like the default search type does.
But also have it possible to continue typing and have it act as an input type where you just get the typed text back.

Get input value as string

Hey @PhiloNL hope you have a good day.

I have created a timetracker in livewire, why not use spotlight? just for fun :)

After creating the project, it asks me the name of the task, is there any way to get this string directly? The idea is to be able to create a new task.

`

public function dependencies(): ?SpotlightCommandDependencies
{
    return SpotlightCommandDependencies::collection()
        ->add(
            SpotlightCommandDependency::make('project')
            ->setPlaceholder('Choose project')
        )->add(
            SpotlightCommandDependency::make('task')
            ->setPlaceholder('Task name')
        );
}

public function searchProject($query)
{
    return Project::where('name', 'like', "%$query%")
        ->get()
        ->map(function(Project $project) {
            return new SpotlightSearchResult(
                $project->id,
                $project->name,
                sprintf('Create task for %s', $project->name)
            );
        });
}

public function searchTask($query, Project $project)
{
   // HOW I CAN RETURN THIS QUERY???? FOR EXAMPLE "DESIGN"
}

public function execute(Spotlight $spotlight, Project $project)
{
    // Yes we are here!! now I want create a new task with previous string Design
}

`

I don't know if it is possible to do this :) thanks for you time !

video.mov

Styling weird when running `npm run prod`

I'm already using Tailwind on a project so the config is set to false to include Tailwind. However when I run npm run dev and open Spotlight, it looks fine (the black popup, aligned center, etc).

It's when I run npm run prod is when the styles and positioning get funky. Here's what it looks like (aligned to the top of the page)

image

Closing Spotlight during dependency search doesn't reset flow

I am not sure if this is intentional, but I found it somewhat confusing that if I created a command with dependencies (something simple like in the readme), if I closed the Spotlight element while it was prompting me to search for a dependency, the next time I opened the spotlight (unless there had been a full page reload) it would still be asking me to search for the dependency, and then only way to clear it was to either finish searching or to reload the page.

I think it would be more intuitive if the spotlight element always reset itself when it closed, so that if the user accidentally selects the wrong option they don't get stuck in that flow and forced to reload the page.

Target [Illuminate\Contracts\Auth\StatefulGuard] is not instantiable.

`<?php

namespace LivewireUI\Spotlight\Commands;

use Illuminate\Contracts\Auth\StatefulGuard;
use LivewireUI\Spotlight\Spotlight;
use LivewireUI\Spotlight\SpotlightCommand;

class Logout extends SpotlightCommand
{

protected string $name = 'Logout';
protected string $description = 'Logout out of your account';
public function execute(Spotlight $spotlight, StatefulGuard $guard): void

{

    $guard->logout();

    $spotlight->redirect('/');

}

}
`

Results not shown, but indigo border appears

When search results are found, the indigo bottom border is shown, but no results are displayed. Pressing enter will trigger the first matching command.

Screen Shot 2021-10-30 at 4 24 19 PM

In the particular example, the registered commands are EditPolicy and ViewPolicy, both of which should be shown as options in the dropdown menu.

Spotlight is not reaching to 'execute' method. (404)

Hi

I have read complete documentation and also I read tutorial blog post.

I tried using all steps mentioned in your documentation but this package is not working on final 'execute' method step in my application :(

I am able to open spotlight using shortcut command 'CTRL + K' and able to search users.

But when I select any user and press enter, I am receiving 404.

The method 'execute' never called and in console I am receiving 404 error for post request and Uncaught (in promise) undefined for livewire.js

      protected string $name = 'View Student Profile';
      protected string $description = 'Redirect to student profile page';

      public function dependencies(): ?SpotlightCommandDependencies
      {
            return SpotlightCommandDependencies::collection()
                  ->add( SpotlightCommandDependency::make('student') ->setPlaceholder('Enter student name or email.') );
      }

      public function searchStudent($query)
      {
            return User::where('name', 'like', "%$query%")
                  ->get()
                  ->map(function(User $student) {
                        return new SpotlightSearchResult(
                              $student->id,
                              $student->name,
                              sprintf('Go to profile page for %s', $student->name)
                        );
                  });
      }

      public function execute(Spotlight $spotlight, User $student)
      {
              $spotlight->redirectRoute('students.show', $student);
      }

      public function shouldBeShown(): bool
      {
            return true;
      }

I have also registered command in AppServiceProvider.

My application is built on
Laravel 8.12
Php 8
Alpinejs 3.2.2
Livewire 2.5.5

Kindly guide me.
Thank you !

Suggestions on start

Hi @PhiloNL , I got some ideas I hope you find them interesting

  1. Function suggestion on open (some people prefer clicking than typing), this could be used to show for example: latest visited pages , last search or last used function
  2. Be able to search on open (from the start), for example: show results of clients and invoices (keeping functions on the top)

Thanks for the package

Ability to customize Fuse search options

Issue

I've noticed that some of my search results aren't appearing in the spotlight search results. They're actually returned as dependencyQueryResults, which can be confirmed in alpinejs devtools, but they don't make it through Fuse to appear in the spotlight result list. By default, Fuse places importance on the beginning of the field that is being searched. Since the match is towards the end of the searched string, it is being ignored.

Example
String being searched: "TTU/JH COMM COLLEGE DESIGN CATALOG SAMPLES O# 492026578-7,8,9"

if my input search query is "492026578", this result doesn't make it to the result list. It IS however, part of the query results, but Fuse skips over it because the query string is at the end of the searched string.

Solution

Provide a way to customize the Fuse fuzzy matching options like location, distance, ignoreLocation, and threshold.

If I manually edit the spotlight.js file and set ignoreLocation to true, then the result shows on the page as expected.

I could attempt a PR, but may take a while.
I understand if you don't want to start tying your package down to the Fuse fuzzy search implementation, but maybe there's a way to add options that can be translated to those Fuse options. Then again, you may not want spotlight to be concerned with that stuff at all. If so, I understand.

Thanks for this great component.

Different Spotlight behavior depending on the page component?

Is there any way to tell Spotlight what the page component is and cater the behavior to that?

An example. If I open Spotlight on my dashboard and type "New post" it should ask me what project I want to create the post for - great, but if I'm already inside a project, can this info be pre-populated somehow? E.g. can I tell Spotlight that it was opened on a project page and now assume that you want to create the post for that project?

Thanks!

Edit // When I think about it. I may even have some options that should only show up in Spotlight if it's called from a certain component. Either way, I think both ways would be solved if I could tell Spotlight where it was called from. Maybe this is already possible?

spotlight redirect to new tab

how to perform redirection on new tab

$spotlight->redirect('/admin/sentemails');
this will redirect with same tab...
but i want to redirect with new tab

AlpineJS 3 Support

Spotlight not working with alpinejs 3

Uncaught TypeError: Object.defineProperty called on non-object
    at Function.defineProperty (<anonymous>)
    at module.esm.js:1585
    at Array.forEach (<anonymous>)
    at K (module.esm.js:1584)
    at module.esm.js:2811
    at Function.<anonymous> (module.esm.js:1931)
    at e (module.esm.js:1704)
    at module.esm.js:1708
    at Ct (module.esm.js:1887)
    at t (module.esm.js:1858)

Ability to dynamically set default placeholder

It would be great to be able to dynamically set the placeholder to morning/afternoon/evening or even based on user-type OR to include the user's name. If there's interest, I can put in a PR.

Feature Request: Option to trigger search on load

Been sending a lot of feedback, but I really love this package :)

It would be cool if you could add an option to trigger the search automatically if wanted. So in addition to the For which team do you want to create a user? placeholder it would also perform a search and show all available Teams without you having to type anything. Not as default, but I could see it handy when there are only a few options available and you want to show the user all of them right away.

Maybe there is a more elegant solution, but you get the point:

->add(SpotlightCommandDependency::make('team')->setPlaceholder('For which team do you want to create a user?')->triggerSearch(true))

Even one step further, in addition to true or '' for all results, you could add a search term triggerSearch('Seabass') or triggerSearch($user->personalTeam()->name) and that would populate as your starting point. In this case show my team as auto-selected.

Just an idea :)

add x-cloak to remove loading flash

I first want to thank you @PhiloNL for this amazing package!

Problem
I'm seeing the spotlight component flash up occasionally before its display: none seems to be applied.

Proposed solution
Add x-cloak to the component, as it is best practice in Alpine

Should you not want this, is there a way to publish the view files of the spotlight component?

Shortcut arguments

I think it could be cool for shortcuts to accept arguments.

An example might be a shortcut to visit a particular user profile, where the shortcut would be Visit user - hitting enter would allow you to enter some sort of identifier, I.e. username or email and then that would be made available to the shortcut handler.

How to persist data while Spotlight is open?

Hi,

Upon opening Spotlight & starting a command, I want to temporary store some data when when Spotlight is open.
In my case all the available Resources from Laravel Nova.

I can store some data when the page is opens, but after starting Spotlight & every keystroke after, the component refreshes and the data is lost.
My solution now is to store the data in the session, and flush it on execution, but this is not the most stable solution.

Is it possible to execute a function on start of a command, and keep this data while spotlight is open? After executing the data can be flushed.

Clicking on action with further dependencies

Logout
Since logout has no dependencies, pressing enter or clicking is the same.

View User
Since "View User" command has dependencies, I'm expecting when clicking with the mouse to proceed to that dependency asking the user name. Currently, mouse-clicking on "View User" only closes the dialog with no further action. It works properly when pressing enter, but I'm expecting ENTER and Mouseclick to yield the same result, from a UX viewpoint.

Thoughts?

Missing Tests

First of all, dope project!

Would you be open to a PR or two to start adding tests for the existing functionality?

Not able to interact with the component

HeyHey, Cool package you have there. Excited to test it out!

I just ran into a problem but I'm not able to solve it. I've livewire alrdy preinstalled and just added the component like you mentioned within the docs.

After I hit the start page, I can see the overlay but can not close or interact with it. Any ideas?

image

<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <meta name="csrf-token" content="{{ csrf_token() }}">

   <link href="{{ mix('css/app.css') }}" rel="stylesheet">
      
    @livewireStyles

</head>
<body class="bg-gray-50">
@include('layouts.partials._navigation')
@yield('content')
@include('layouts.partials._footer')
@include('layouts.partials._flash')
<script src="{{ mix('js/app.js')}}"></script>
@livewire('livewire-ui-spotlight')
@livewireScripts
</body>
</html>

I've also created the test component.

<?php

namespace App\Http\Livewire\Commands;

use Illuminate\Contracts\Auth\StatefulGuard;
use LivewireUI\Spotlight\Spotlight;
use LivewireUI\Spotlight\SpotlightCommand;

class Logout extends SpotlightCommand
{
    protected string $name = 'Logout';

    protected string $description = 'Logout out of your account';

    public function execute(Spotlight $spotlight, StatefulGuard $guard): void
    {
        $guard->logout();
        $spotlight->redirect('/');
    }
}

Cheers,

shouldBeShown

The documentation tell us to use shouldBeShown but it is really working?

[question] use command dependencies for model creation

Is it possible to use the input of a SpotlightCommandDependency to create a new model instead of searching for one?

What I'm trying to do
I would like to start with a spotlight command that opens a text input like it does now. But instead of using the input of the dependency as a search query and returning models, I'd just take the string and create a new model.

Start pretty much as it is now:

protected string $name = 'Draft';
protected string $description = 'create a quick draft right in spotlight';

public function dependencies(): ?SpotlightCommandDependencies
 {
     return SpotlightCommandDependencies::collection()
         ->add(
             SpotlightCommandDependency::make('draft')
             // user should enter the content that will fill the model
             ->setPlaceholder('Enter your draft text.')
         );
 }

Then instead of returning a collection of SpotlightSearchResult there would be an action:

/**
 * 
 */
public function createDraft($content)
{
   return auth()->user()->drafts()->create(["content" => $content]);
}

As I understand it, right now it'll automatically search for a searchDrafts method and expect a collection of SpotlightSearchResult returned. For the above use case, it probably shouldn't call the createDraft method until the user submits what they typed into the input.

I understand if it's out of scope for this package & feel free to close the issue.

But I'm curious if it is maybe somehow possible already?

Search dependency - prevent active search

Awesome package by the way!

I made one with a dependency where users are able to enter a keyword search through thousands of row table. however since this is an active search, as expected, memory issues are encountered each time a user types.

Is there a way to prevent active-search and only triggers on-Enter?
or something similar to Livewire's defer property?

Bootstrap styles

Hello!

First again, thanks for this amazing tool!

I love tailwind but for an admin project I choose a Boostrap dashboard theme. How can I customize the style? Yes, I can use include_css. option. But This styles are failing for some views.

Can be possible to add ids to the divs? Then we will be able to override the styles. Or, other idea?

Thank you!

How I can add multiple (bulk) actions

If I want to bulk add multiple actions to the search and to have one class how to do it?
For example:

  • I have multiple services but I want all of them to be added to the initial spotlight
  • On select of any of the service to redirect to the page of the service

"Invalid argument supplied for foreach()" on composer require

Amazing package, first of all! 👏

I've tried installing the package in a fresh new Laravel project and it works fine.
The issue is with an existing Laravel project, composer require returns this error. Any ideas? Thank you!

ErrorException 

  Invalid argument supplied for foreach()

  at vendor/livewire-ui/spotlight/src/SpotlightServiceProvider.php:35
     31▕                 $view->cssPath = __DIR__ . '/../public/spotlight.css';
     32▕             }
     33▕         });
     34▕ 
  ➜  35▕         foreach (config('livewire-ui-spotlight.commands') as $command) {
     36▕             Spotlight::registerCommand($command);
     37▕         }
     38▕     }
     39▕ }

      +9 vendor frames 
  10  [internal]:0
      Illuminate\Foundation\Application::Illuminate\Foundation\{closure}(Object(LivewireUI\Spotlight\SpotlightServiceProvider))

RegisterCommandIf Not working

` public function boot()
{

   Spotlight::registerCommandIf(Auth::check() && Auth::user()->role == 'A',Logout::class);
}`

Alpine JS class error in 7.4

I received this error,

alpine.js:144 Uncaught SyntaxError: Unexpected token 'class'
    at new Function (<anonymous>)
    at d.el (alpine.js:144)
    at d (alpine.js:131)
    at f (alpine.js:139)
    at be.evaluateReturnExpression (alpine.js:1754)
    at alpine.js:1730
    at Array.forEach (<anonymous>)
    at be.resolveBoundAttributes (alpine.js:1703)
    at be.initializeElement (alpine.js:1628)
    at alpine.js:1612

I'm using tag "dev-php-7.4-support"

How to solve this?

Close already open modals when a new modal opens with Spotlight?

This is really cool!

I'm trying it out with modals and it works pretty well, but is there any way to close all other modals if I open a new one with Spotlight? This didn't work:

public function execute(Spotlight $spotlight)
{
    $spotlight->emit('closeModal'); // forceful too if possible
    $spotlight->emit('openModal', 'create-user');
}

Also, is there any way to change the standard Logout out of your account to Log out of your account.

Edit // I guess I can just re-create that class in my Spotlight folder.

Thanks again, love it!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.