PHPackages                             amjadiqbal/laravel-ninja-keys - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. amjadiqbal/laravel-ninja-keys

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

amjadiqbal/laravel-ninja-keys
=============================

Laravel integration for the ninja-keys web component with a fluent PHP API and Blade directive.

00PHP

Since Feb 22Pushed 4mo agoCompare

[ Source](https://github.com/amjadiqbal/laravel-ninja-keys)[ Packagist](https://packagist.org/packages/amjadiqbal/laravel-ninja-keys)[ RSS](/packages/amjadiqbal-laravel-ninja-keys/feed)WikiDiscussions main Synced today

READMEChangelogDependenciesVersions (1)Used By (0)

Laravel Ninja Keys
==================

[](#laravel-ninja-keys)

[![Packagist Version](https://camo.githubusercontent.com/5580b2106ee4ff4dac4ff7a9c5a47f77cc31faba1b60f9d526020eb6c92420b8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f616d6a6164697162616c2f6c61726176656c2d6e696e6a612d6b6579732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/amjadiqbal/laravel-ninja-keys)[![License](https://camo.githubusercontent.com/6c711032aff1ca0eb6b211aa6cb3649ce7fd64a7714e1181d4bb457f9680e7cf/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e2e7376673f7374796c653d666c61742d737175617265)](LICENSE)[![PHP Version](https://camo.githubusercontent.com/ab1a455f784a80cc321cc3fb6cea6df99a7e5df05526968b9d5031383fdb218c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f616d6a6164697162616c2f6c61726176656c2d6e696e6a612d6b6579732e7376673f7374796c653d666c61742d737175617265)](https://packagist.org/packages/amjadiqbal/laravel-ninja-keys)[![Laravel](https://camo.githubusercontent.com/727dbc6d2e4a1e33a6e4d8d9e100759a5de7c4e9e702062fe33fb871fd01cedb/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c61726176656c2d253545313025323025374325323025354531312d7265643f7374796c653d666c61742d737175617265)](#requirements)[![Tests](https://camo.githubusercontent.com/ec042c66ced85c122f363ff5a07276688480511f6d3324080d0f24c361d12e4b/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f746573746564253230776974682d506573742d6f72616e67653f7374796c653d666c61742d737175617265)](#testing)

Laravel integration for the [ninja-keys](https://github.com/ssleptsov/ninja-keys) web component. Ships a fluent PHP API, a Blade directive for rendering and JS-bridge logic, and Gate-based authorization filtering for server-side visibility.

Table of Contents
-----------------

[](#table-of-contents)

- Overview
- Requirements
- Installation
- Quickstart
- Configuration
- Rendering Options
- Fluent API
- Authorization
- Event Hooks
- Styling
- Data Model Mapping
- Testing
- Versioning
- Contributing
- Security
- License
- Credits

Overview
--------

[](#overview)

- Keyboard command palette powered by ninja-keys (Web Component).
- Laravel-friendly API for building actions via PHP.
- Server-side filtering using Gate abilities (hide unauthorized actions).
- CDN or local asset loading; Material Icons support.
- Theme handling (auto/dark/light) and optional footer control.
- Works with flat or tree action data structures.
- Bridges string handlers to global window functions safely.

Requirements
------------

[](#requirements)

- PHP: ^8.1
- Laravel: ^10.0 or ^11.0

Installation
------------

[](#installation)

```
composer require amjadiqbal/laravel-ninja-keys
```

Auto-discovery registers the service provider and facade.

If you use Pest for tests:

```
composer config --no-plugins allow-plugins.pestphp/pest-plugin true
```

Quickstart
----------

[](#quickstart)

Publish config:

```
php artisan vendor:publish --tag=config
```

Add to your layout:

```
@ninjaKeysScripts
```

Register actions:

```
use AmjadIqbal\NinjaKeys\Facades\NinjaKeys;

NinjaKeys::addAction('create-post')
    ->title('New Post')
    ->description('Create a post')
    ->shortcut('ctrl+n')     // normalized to JS hotkey
    ->parent('posts')
    ->mdIcon('note_add')
    ->handler('onCreatePost') // window.onCreatePost(detail) will be called
    ->can(['create-post', 'manage-posts']); // visible if any ability allows
```

Add global handlers:

```

  window.onCreatePost = (detail) => { /* your logic */ };

```

Configuration
-------------

[](#configuration)

Key options (config/ninja-keys.php):

- use\_cdn (bool) — load from CDN; otherwise asset\_path
- cdn\_url (string) — default
- asset\_path (string|null) — published asset path if not using CDN
- material\_icons\_url (string|null) — Google Fonts URL to load Material Icons
- placeholder, searchPlaceholder (string|null) — search input placeholders
- disableHotkeys, hideBreadcrumbs, hotKeysJoinedView, noAutoLoadMdIcons (bool)
- openHotkey, hotKeys (string) — hotKeys is an alias for openHotkey
- navigationUpHotkey, navigationDownHotkey, closeHotkey, goBackHotkey, selectHotkey (string)
- theme (light|dark|auto)
- noHeader, noFooter (bool)
- onChange (string|null) — window function name to receive change events
- onOpen (string|null) — window function name called before ninja.open()

Publish and edit:

```
php artisan vendor:publish --tag=config
```

Rendering Options
-----------------

[](#rendering-options)

- Blade directive

```
@ninjaKeysScripts
```

- Blade component (optional)
    - Component class exists at `src/Components/NinjaKeys.php`
    - Register alias manually if desired: ```
        // in a service provider
        \Illuminate\Support\Facades\Blade::component('ninja-keys', \AmjadIqbal\NinjaKeys\Components\NinjaKeys::class);
        ```

#### Load from local asset instead of CDN

[](#load-from-local-asset-instead-of-cdn)

Publish assets to your public directory (or bundle in your build), then set:

```
// config/ninja-keys.php
'use_cdn' => false,
'asset_path' => '/assets/js/ninja-keys.js', // example path
```

Fluent API
----------

[](#fluent-api)

```
use AmjadIqbal\NinjaKeys\Facades\NinjaKeys;

NinjaKeys::addActions([
    ['id' => 'Theme', 'title' => 'Change theme...', 'hotkey' => 'ctrl+t', 'children' => ['Light', 'Dark', 'System']],
    ['id' => 'Light', 'title' => 'Light Theme', 'parent' => 'Theme', 'mdIcon' => 'light_mode', 'handler' => 'setLightTheme'],
    ['id' => 'Dark', 'title' => 'Dark Theme', 'parent' => 'Theme', 'mdIcon' => 'dark_mode', 'handler' => 'setDarkTheme'],
]);
```

Convenience fields:

- href(string) and target(string) are included for your own handlers/UI logic (they are not executed automatically by the component).

Authorization
-------------

[](#authorization)

- Use `can(string|array)` to attach Gate abilities.
- If any provided ability allows, the action is included; otherwise excluded server-side.
- Gate definitions in tests or app boot: ```
    Gate::define('create-post', fn ($user = null) => true);
    ```

Event Hooks
-----------

[](#event-hooks)

- onChange: listen to component change and receive `{ search, actions }`.
- onOpen: called before `ninja.open(...)` with `{ args }`.
- Handler bridging:
    - If an action’s `handler` is a string (e.g., `"myFunction"`), the directive listens to `selected` and calls `window[handler](event.detail)` when present.
    - Recommended: keep handlers small and side-effect free; heavy logic can be deferred.

Styling
-------

[](#styling)

- Theme:
    - `theme = auto`: toggles dark class based on `prefers-color-scheme`.
    - `theme = dark`: forces `class="dark"` on the component.
- Footer:
    - `noFooter = true` renders an empty footer slot.
- Material Icons:
    - Load via `material_icons_url` or disable with `noAutoLoadMdIcons`.
- CSS Shadow Parts (from ninja-keys):
    - `actions-list`, `ninja-action`, `ninja-selected`, `ninja-input`, `ninja-input-wrapper`
    - Example: ```
        ninja-keys::part(ninja-action) { border-radius: 8px; }
        ```

#### CSS Variables (examples)

[](#css-variables-examples)

```
ninja-keys {
  --ninja-width: 640px;
  --ninja-accent-color: #6e5ed2;
  --ninja-icon-size: 1.2em;
  --ninja-selected-background: #f8f9fb;
}
```

Data Model Mapping
------------------

[](#data-model-mapping)

ActionBuilder → Ninja Keys fields:

- addAction(id) → id
- title(string) → title
- description(string) → description
- icon(string) → icon (HTML/SVG)
- mdIcon(string) → mdIcon (Material icon name)
- parent(string) → parent
- children(array) → children
- shortcut(string) → normalized to hotkey
- hotkey(string) → hotkey
- section(string) → section
- keywords(string) → keywords
- handler(string) → handler (global window function name)
- href(string), target(string) → convenience extras (not auto-executed)
- can(string|array) → Gate abilities for server-side filtering

Manager:

- addActions(array) → bulk registration
- getActions() → normalized and authorization-filtered array

#### Flat vs Tree

[](#flat-vs-tree)

- Flat: use `parent` and `children` ids to nest menus.
- Tree: provide nested `children` arrays; library supports both.

Testing
-------

[](#testing)

Pest and Testbench included:

```
composer config --no-plugins allow-plugins.pestphp/pest-plugin true
composer update
./vendor/bin/pest
```

Run a single test:

```
./vendor/bin/pest tests/ManagerTest.php
```

Static analysis, style and coverage (optional suggestions):

- phpstan: `vendor/bin/phpstan analyse src`
- pint: `vendor/bin/pint`
- coverage: `./vendor/bin/pest --coverage-html coverage/`

Troubleshooting
---------------

[](#troubleshooting)

- Handler not firing:
    - Ensure `handler` is a string and the global function exists: `window.myFunction = (detail) => { ... }`
- Action hidden unexpectedly:
    - Check `can()` abilities; Gate must return true for at least one ability.
- Material Icons missing:
    - Ensure `material_icons_url` is set, or disable with `noAutoLoadMdIcons`.
- Theme not switching on auto:
    - Confirm browser supports `prefers-color-scheme`; ensure no CSS overrides are preventing `.dark` class effects.
- CDN blocked:
    - Switch to local asset by setting `use_cdn=false` and `asset_path`.

Performance
-----------

[](#performance)

- Avoid registering an excessive number of actions; use `keywords` for better searchability.
- Group actions logically via `section` to improve UX.
- Prefer short, deterministic handlers; delegate long work to async functions if needed.
- Cache computed action arrays on the server if you build them dynamically on each request.

FAQ
---

[](#faq)

- Difference between `shortcut` and `hotkey`?
    - `shortcut` is normalized to `hotkey`. You can use either, but only `hotkey` is sent to the component.
- Can I navigate externally?
    - Store `href` and `target` on actions and implement logic in your handler to perform navigation.
- How to hide breadcrumbs?
    - Set `hideBreadcrumbs=true` in config.
- How to disable registering action hotkeys?
    - Set `disableHotkeys=true` in config to stop auto-registering action hotkeys.
- Flat vs Tree data?
    - Use `parent`/`children` in flat mode or nested arrays in tree mode; pick whichever suits your data model.

CI &amp; Publishing
-------------------

[](#ci--publishing)

- Validate and test: ```
    composer validate
    ./vendor/bin/pest
    ```
- Tag a release (after publishing to Packagist):
    - Follow SemVer; update composer version range if needed.
- GitHub Actions (suggested):
    - Setup PHP matrix (^8.1), run `composer install`, `composer validate`, `./vendor/bin/pest`.

Versioning
----------

[](#versioning)

- Follows semantic versioning once published.
- Compatibility targets: PHP ^8.1, Laravel ^10|^11.

Contributing
------------

[](#contributing)

- PRs and issues are welcome. Please include tests where appropriate.

Security
--------

[](#security)

- No secrets stored; do not commit keys/tokens. Report vulnerabilities privately.

License
-------

[](#license)

- MIT © AmjadIqbal

Credits
-------

[](#credits)

- Built on top of the excellent [ninja-keys](https://github.com/ssleptsov/ninja-keys) by Sergei Sleptsov.

###  Health Score

18

—

LowBetter than 8% of packages

Maintenance52

Moderate activity, may be stable

Popularity0

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity12

Early-stage or recently created project

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

### Community

Maintainers

![](https://www.gravatar.com/avatar/a7bf302435a7ec2ff19aa5995f1baf92d6d0a4dcafbced1f3e8609fa848a4e6e?d=identicon)[amjadiqbal](/maintainers/amjadiqbal)

---

Top Contributors

[![amjadiqbal](https://avatars.githubusercontent.com/u/36040604?v=4)](https://github.com/amjadiqbal "amjadiqbal (2 commits)")

### Embed Badge

![Health badge](/badges/amjadiqbal-laravel-ninja-keys/health.svg)

```
[![Health](https://phpackages.com/badges/amjadiqbal-laravel-ninja-keys/health.svg)](https://phpackages.com/packages/amjadiqbal-laravel-ninja-keys)
```

###  Alternatives

[robotusers/cakephp-excel

Robotusers CakePHP Excel plugin

2312.8k](/packages/robotusers-cakephp-excel)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
