Giter VIP home page Giter VIP logo

ssleptsov / ninja-keys Goto Github PK

View Code? Open in Web Editor NEW
1.6K 10.0 58.0 1.44 MB

Keyboard shortcuts interface for your website. Working with static HTML, Vanilla JS, Vue, React, Svelte.

Home Page: https://ninja-keys-demo.vercel.app/

License: MIT License

JavaScript 4.44% HTML 21.78% TypeScript 73.78%
web-components lit-element typescript keyboard hotkeys shortcut hotkey vue react typescript-library

ninja-keys's People

Contributors

0xflotus avatar atayl16 avatar excid3 avatar fossabot avatar gaejabong avatar oddcelot avatar ssleptsov avatar wobsoriano 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

ninja-keys's Issues

feature request: prevent open event via listener or callback

Is there currently a way to prevent the menu from opening when the hotkey (ctrl + k) is invoked?

I have a scenario where the component which mounts the ninja-key element has an initial loading state, and I would like to be able to prevent the command menu from opening while in the loading state.

Thanks

lit-html dependancy error

Getting the following when installing with html/js

<script type="module" src="https://unpkg.com/ninja-keys?module"></script>

       GET https://unpkg.com/[email protected]/async-directive.js?module net::ERR_ABORTED 500 (Internal Server Error)
ref.js:1 
        
        
       GET https://unpkg.com/[email protected]/lit-html.js?module net::ERR_ABORTED 500 (Internal Server Error)

Close button

Hi @ssleptsov
Awesome library! I love it very much!

Could you please add "Close" button to dialog header? I can't close menu on phone and tablet. Also I would like to close dialog with mouse sometimes.

Thank you!

Can I change breadcrumbs?

Hi,
can I change breadcrumbs depending on the URL? So if browser is on '/exercises' page ninja-keys menu breadcrumbs would be 'Main / Exercises '?
Thank you

Petr R.

Is there any way to listen modal open or close?

Great library! It makes building cmd tools super easy!
I recently got a situation when I use ninja-keys to work with my react project. I use global storage to store the state of ninja-keys, but I don't know when should I set the state to false and I couldn't find any eventListener to check modal is open ore close.
If there is any way to listen modal state will be great!

Hotkeys are triggered within the ninja-keys search input

Hello!

First of all thank you for such a nice library. I'm facing the following issue, steps to reproduce:

  • Register a hotkey with single letter, like "c"
  • If you search within ninja-keys and use the letter "c", it's triggering the hotkey which in my case redirects to another page

Relevant details

  • Using the hotkeys in any other input or textarea doesn't trigger handler

Thank you!

--ninja-font-family

🇺🇦

Huge thanks for making this very nice library! Is there any way to set the font-family for the whole modal?

I've tried

.ninja-keys {
    --ninja-font-family: 'Titillium';
    &::part(ninja-input) {
      font-family: var(--ninja-font-family);
    }
}

...but have found no way of setting the font for the breadcrumbs.

Items listed after an item with children aren't displayed

I'm using this with Vue2, so not sure if it's related to that.... It seems which ever items has children: [], any item below that never gets rendered, but is still searchable.

data() {
    return {
      hotkeys: [
        {id: 'Home', title: 'Home'},
        {id: 'Publish', title: 'Publish'},
        {id: 'Settings', title: 'Settings'},
        {id: 'Theme', title: 'Theme', children: [{id: 'Light', title: 'Light Theme'}]}
     ]
  }
}

Screenshot from 2022-06-15 11-30-05

data() {
    return {
      hotkeys: [
        {id: 'Home', title: 'Home', children: [{id: 'Notifications', title: 'Notifications'}]},
        {id: 'Publish', title: 'Publish'},
        {id: 'Settings', title: 'Settings'},
        {id: 'Theme', title: 'Theme'}
     ]
  }
}

Screenshot from 2022-06-15 11-35-57
Screenshot from 2022-06-15 11-36-21

This may just be a configuration setup issue, but I'm not sure what I'm missing.

Using version 1.2.1

Export css variable of content zIndex

Hi, I have some zIndex > 1 elements, and the modal is hidden behind them.
Since, there is no shadow for outer div.modal, it cannot be styled with shadow part method.
Is it possible to export zIndex varaible to be overwrited ?

Thanks for your great work.

Can't get command palette to open when <input>, <select>, or <textarea> have focus

I couldn't figure out how to get cmd+k or other keyboard shortcuts to work when these elements had the focus within ninja-keys.

However, I was able to get around this by importing the hotkeys-js library myself and following the guidance in their docs (see https://github.com/jaywcjlove/hotkeys#filter)

  import "ninja-keys"
  import hotkeys from "hotkeys-js"
  hotkeys.filter = _event => true

How exactly you implement this for your project is going to depend on what framework you're using, but this might get you close.

Ideally, this would be exposed as an attribute off of ninja-keys or a configuration option, but I wanted to create this issue in case anyone else ran into it.

How to custom action-list scroll bar style

I use the css below:

/* chrome, edge, not work🙃 */
ninja-keys::part(actions-list)::-webkit-scrollbar-thumb {
  background-color: #bfbfbf;
  outline: none;
  border-radius: 6px;
}

ninja-keys::part(actions-list)::-webkit-scrollbar {
  width: 6px;
  height: 6px;
}

/* firefox, work🙂 */
ninja-keys::part(actions-list) {
  scrollbar-width: thin;
}

DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "ninja-header" has already been used with this registry

Hi,

I'm trying to use ninja-keys in a project with latest ninja-keys 1.2.1, latest Vue 3.2.33 and Vite 2.9.6 (using <script setup>).

While running the dev server, I get the warning "reactive-element.ts:66 Multiple versions of Lit loaded. Loading multiple versions is not recommended. See https://lit.dev/msg/multiple-versions for more information." Which might not be a big deal.

...but deployed / in production mode, I'm getting "DOMException: Failed to execute 'define' on 'CustomElementRegistry': the name "ninja-header" has already been used with this registry".

Any ideas at all what could be happening here? Are you able to set up ninja-keys using Vue/Vite/<script setup> without errors?

Dynamic commands makes ninja keys jump randomly

Hey @ssleptsov I just found out that adding keys dynamically to ninja keys make the keyboard navigation navigate randomly inside ninja keys.

Is there a way to force render the list again, I believe this is specifically happening because we are adding the hot keys dynamically when the route changes like below.

hotKeys() {
      return [...this.conversationHotKeys, ...this.goToCommandHotKeys];
    },

The conversationHotkeys array gets added only if we're on a specific page.

Here's how it behaves.

Screenshot.22-11.at.11.mp4

If there's an event to re initiate the hot keys, I think this will definitely resolve the issue.

[Improvment][Proposal] Default handle (fallback) if no command is found

Frist of all, congrats for the amazing project!

I'd like to propose a default handle/fallback when the user want to search something that's not a explicitly command. Right now it works like this:

image

Throwing a error if the user press enter.

image

I'd like to propose something like this:

const ninja = document.querySelector('ninja-keys');

ninja.defaultHandler = (query) => { /* do what you want here */ }

Using the exemple on the screenshot, the query variable would return "nothing". For instance, I could call a search function on my inside defaultHandler using the query param:

ninja.defaultHandler = (query) => {  myVeryOwnSearch(query) }

The defaultHandler method would only be called if there's no command available to select (maybe fallbackHandler is a better name).

Difficulty compiling with Webpack 5

First off I just want to say this is great, and I'm super excited to use Ninja Keys in an app I'm working on.

Webpack 5 is unable to compile a project using Ninja Keys, and needs some additional, and hopefully optional configuration.

Error when trying to compile with no Webpack configuration change:

ERROR in ./node_modules/ninja-keys/dist/ninja-keys.js 12:0-24
Module not found: Error: Can't resolve './ninja-header' in '<omitted>/node_modules/ninja-keys/dist'
Did you mean 'ninja-header.js'?
BREAKING CHANGE: The request './ninja-header' failed to resolve only because it was resolved as fully specified
(probably because the origin is strict EcmaScript Module, e. g. a module with javascript mimetype, a '*.mjs' file, or a '*.js' file where the package.json contains '"type": "module"').
The extension in the request is mandatory for it to be fully specified.
Add the extension to the request.

I found a needed configuration change in this SO article, which helped me in adding the following to my webpack.config.js file:

// most of config omitted.
module: {
    rules: [{
      test: /\.m?js$/,
      resolve: {
        fullySpecified: false
      }
    }]
  },

This isn't a problem for me right now, but I could see it becoming an issue, or at least a sticky point for others trying to get Ninja Keys up and running.

Thanks again!

How to add items to search results?

I'm looking to integrate a search in to this, and I saw #9 was fixed which allows me to do this; however, the results don't show until after I clear the search results:

https://codesandbox.io/s/ninja-keys-demo-forked-u9gprl?file=/src/App.vue

In this example, when you open the ninja keys, there's 2 items. Then you search for "test" which will add the third, but you don't see the result. Then if you clear your search, you'll see that the 3rd item was added.

How can I get this to show the result at the time the search is being made?

Can't use navigation keys (arrow keys, enter etc.)

Hey folks,

I am currently trying to integrate ninja-keys into my solidjs-app and tried to do so via the solid-wrapper as well as by using ninja-keys as standalone library. However
All basic navigation shortcuts on the modal don't seem to work for me (arrow keys, enter, esc etc.)

Any idea what I could be doing wrong?

// index.tsx
import { render } from 'solid-js/web'
import { Router } from '@solidjs/router'
import App from './App'
import './index.css'
import { hydrateStoresFromPersistence } from 'stores/hydrateStoresFromPersistence'
import CommandPalette from 'App/CommandPalette'

hydrateStoresFromPersistence()

render(
    () => (
        <Router>
            <App />
            <CommandPalette />
        </Router>
    ),
    document.getElementById('root') as HTMLElement
)
// CommandPalette
import { NinjaKeys } from 'solid-ninja-keys'

function CommandPalette() {
    return (
        <NinjaKeys
            hotkeys={[
                {
                    id: 'Overview',
                    title: 'Open Overview',
                    hotkey: 'cmd+o',
                    handler: () => {
                        console.log('navigation to overview')
                    },
                },
                {
                    id: 'Settings',
                    title: 'Open Settings',
                    hotkey: 'cmd+s',
                    handler: () => {
                        console.log('navigation to settings')
                    },
                },
            ]}
        />
    )
}

export default CommandPalette

Thanks in advance :)

[typescript] type error in react

CleanShot 2022-02-16 at 15 16 47@2x


declare global {
    namespace JSX {
        interface IntrinsicElements {
            'ninja-keys': NinjaKeys
        }
    }
}

I try to add definitions, but the IDE prompts me for indeed a lot of attributes, including those of HTML elements.

CleanShot 2022-02-16 at 15 17 49@2x

Potential memory leak

I experience detached elements when using ninja keys. To show you what I mean I have made a small repro. Use MS Edge and open devtools and the panel called detached elements. Ninja keys is added on the Home page and should be removed on the other views. Ninja keys can not be removed by the garbage collector causing memory leaks. Here is a link to my repro https://lit-tiptap-example-h9lodq6rv-marcuslindblom.vercel.app

ninja.mov

requestAnimation runs even when ninja-keys isn't loaded

Related to #34

I have a page where I don't even load ninja-keys. It's a fairly static page to only display text, and never have user interaction on it.

However, since ninja keys is added in to my main.js build, this line still seems to get ran. I think that's mainly where that error is being thrown because it seems that since ninja-keys doesn't exist on this page, there's no inputRef to hook in to.

I think this should be fairly easy to duplicate. Add a page that includes the ninja-keys import, but don't actually add the <ninja-keys /> tag. Along with nothing else on the page.

Sometimes there's no value loaded when an animationFrame is requested

This may be related to mobile browser issues, but I have about 7k bugsnag reports of this._inputRef.value is undefined and Cannot read properties of undefined (reading 'focus') which I was able to trace back to this line.

requestAnimationFrame(() => this._inputRef.value!.focus());

I'm not quite sure how this part works, but my guess is maybe a guard clause is needed to ensure _inputRef exists and is the correct type?

[Suggestion] Svelte example

I think an additional svelte example could be very helpful for some people.

I could get it to work in svelte (kind of) but i think a fully working svelte example would be very helpful

how to change group-header css ?

I want to change group-header padding.
below selector not work:
ninja-keys::part(actions-list) .group-header
How can I access the group-header so that I can change its style?

Vue2 Example

Thanks for creating this package! Although I am having some trouble integrating with Vue2, it seems very useful.

I understand that you've created this package mainly to work with several of your own Vue projects, so I was wondering if you have a working example using Vue2? I am not able to use Vue3 just yet, so hoping to get this working with Vue2.

The Vue example seems to be using Vue3, and the :data with Vue2 doesn't seem to behave the same way (results in [[object Object], ...] serialized on the DOM element.

Thanks

.open() does not work with vue 2's this.$refs

I am dynamically adding new data and passing it to Ninja keys, using this way this.$refs.ninjakeys.data = this.hotKeys, but using the same ref to call the .open() method does not seem to work.

Below .open does not seem to do anything.

handler: () => {
  if (command.children) {
    this.$refs.ninjakeys.open({ parent: command.id });
    return { keepOpen: true };
  } else {
    this.openRoute(command.path(this.accountId));
  }
}

[Feature Request] Allow color configuration for placeholder text

Hey there,

Great work on this, I love it! I'm working on customizing Ninja Keys on my site and am having issues customizing the color of the placeholder text even with custom CSS.

Is it possible to have this added as a CSS variable anytime in the future or does a way to customize the placeholder already exist?

Great work again!

Highlight matched characters in results

It would be nice if we could customize the commands' HTML, or at least be able to natively highlight the matched characters in the text (using bold probably) while searching. I think this makes searching more intuitive and allows for better queries on the future.

This issue is somewhat related to #16.

The idea here to have a similar functionality to the VS Code command palette (or other IDEs like it) in this regard.

TypeError: Cannot read properties of null (reading 'map')

I get a modal open when I hit cmd + k, but wont render the list items. I used the same code from the codesandbox example which was mentioned.

Screenshot 08-11 at 18@2x

I am on vue version 2.6.12.

I am getting this below error.

TypeError: Cannot read properties of null (reading 'map') I think this below method _flattern is not getting its argument members, this is on ninja-keys.js line: 262.

    key: "_flattern",
    value: function _flattern(members, parent) {
      var children = [];
      return members.map(function (mem) {
        var alreadyFlatternByUser = mem.children && mem.children.some(function (value) {
          return typeof value == 'string';
        });

        var m = _objectSpread(_objectSpread({}, mem), {}, {
          parent: mem.parent || parent
        });

        if (alreadyFlatternByUser) {
          return m;
        } else {
          if (m.children && m.children.length) {
            parent = mem.id;
            children = [].concat(_toConsumableArray(children), _toConsumableArray(m.children));
          }

          m.children = m.children ? m.children.map(function (c) {
            return c.id;
          }) : [];
          return m;
        }
      }).concat(children.length ? this._flattern(children, parent) : children);
    }
    ```

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.