GithubHelp home page GithubHelp logo

johannesklauss / react-hotkeys-hook Goto Github PK

View Code? Open in Web Editor NEW
2.4K 4.0 107.0 11.12 MB

React hook for using keyboard shortcuts in components.

Home Page: https://react-hotkeys-hook.vercel.app/

License: MIT License

TypeScript 98.92% JavaScript 1.08%
react hooks hook react-hooks javascript typescript hotkeys hotkey

react-hotkeys-hook's Introduction


useHotkeys(keys, callback)

Bundlephobia Types NPM Version MIT License

Sponsored by Spaceteams

npm i react-hotkeys-hook

A React hook for using keyboard shortcuts in components in a declarative way.


Quick Start

The easiest way to use the hook.

import { useHotkeys } from 'react-hotkeys-hook'

export const ExampleComponent = () => {
  const [count, setCount] = useState(0)
  useHotkeys('ctrl+k', () => setCount(count + 1), [count])

  return (
    <p>
      Pressed {count} times.
    </p>
  )
}

Scopes

Scopes allow you to group hotkeys together. You can use scopes to prevent hotkeys from colliding with each other.

const App = () => {
  return (
    <HotkeysProvider initiallyActiveScopes={['settings']}>
      <ExampleComponent />
    </HotkeysProvider>
  )
}

export const ExampleComponent = () => {
  const [count, setCount] = useState(0)
  useHotkeys('ctrl+k', () => setCount(prevCount => prevCount + 1), { scopes: ['settings'] })

  return (
    <p>
      Pressed {count} times.
    </p>
  )
}

Changing a scope's active state

You can change the active state of a scope using the disableScope, enableScope and toggleScope functions returned by the useHotkeysContext() hook. Note that you have to have your app wrapped in a <HotkeysProvider> component.

const App = () => {
  return (
    <HotkeysProvider initiallyActiveScopes={['settings']}>
      <ExampleComponent />
    </HotkeysProvider>
  )
}

export const ExampleComponent = () => {
  const { toggleScope } = useHotkeysContext()

  return (
    <button onClick={() => toggleScope('settings')}>
      Change scope active state
    </button>
  )
}

Focus trap

This will only trigger the hotkey if the component is focused.

export const ExampleComponent = () => {
  const [count, setCount] = useState(0)
  const ref = useHotkeys<HTMLParagraphElement>('ctrl+k', () => setCount(prevCount => prevCount + 1))

  return (
    <p tabIndex={-1} ref={ref}>
      Pressed {count} times.
    </p>
  )
}

Documentation & Live Examples

API

useHotkeys(keys, callback)

useHotkeys(keys: string | string[], callback: (event: KeyboardEvent, handler: HotkeysEvent) => void, options: Options = {}, deps: DependencyList = [])
Parameter Type Required? Default value Description
keys string or string[] required - set the hotkeys you want the hook to listen to. You can use single or multiple keys, modifier combinations, etc. This will either be a string or an array of strings. To separate multiple keys, use a colon. This split key value can be overridden with the splitKey option.
callback (event: KeyboardEvent, handler: HotkeysEvent) => void required - This is the callback function that will be called when the hotkey is pressed. The callback will receive the browsers native KeyboardEvent and the libraries HotkeysEvent.
options Options optional {} Object to modify the behavior of the hook. Default options are given below.
dependencies DependencyList optional [] The given callback will always be memoised inside the hook. So if you reference any outside variables, you need to set them here for the callback to get updated (Much like useCallback works in React).

Options

All options are optional and have a default value which you can override to change the behavior of the hook.

Option Type Default value Description
enabled boolean or (keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => boolean true This option determines whether the hotkey is active or not. It can take a boolean (for example a flag from a state outside) or a function which gets executed once the hotkey is pressed. If the function returns false the hotkey won't get executed and all browser events are prevented.
enableOnFormTags boolean or FormTags[] false By default hotkeys are not registered if a focus focuses on an input field. This will prevent accidental triggering of hotkeys when the user is typing. If you want to enable hotkeys, use this option. Setting it to true will enable on all form tags, otherwise you can give an array of form tags to enable the hotkey on (possible options are: ['input', 'textarea', 'select'])
enableOnContentEditable boolean false Set this option to enable hotkeys on tags that have set the contentEditable prop to true
combinationKey string + Character to indicate keystrokes like shift+c. You might want to change this if you want to listen to the + character like ctrl-+.
splitKey string , Character to separate different keystrokes like ctrl+a, ctrl+b.
scopes string or string[] * With scopes you can group hotkeys together. The default scope is the wildcard * which matches all hotkeys. Use the <HotkeysProvider> component to change active scopes.
keyup boolean false Determines whether to listen to the browsers keyup event for triggering the callback.
keydown boolean true Determines whether to listen to the browsers keydown event for triggering the callback. If you set both keyupand keydown to true, the callback will trigger on both events.
preventDefault boolean or (keyboardEvent: KeyboardEvent, hotkeysEvent: HotkeysEvent) => boolean false Set this to a true if you want the hook to prevent the browsers default behavior on certain keystrokes like meta+s to save a page. NOTE: Certain keystrokes are not preventable, like meta+w to close a tab in chrome.
description string undefined Use this option to describe what the hotkey does. this is helpful if you want to display a list of active hotkeys to the user.

Overloads

The hooks call signature is very flexible. For example if you don't need to set any special options you can use the dependency array as your third parameter:

useHotkeys('ctrl+k', () => console.log(counter + 1), [counter])

isHotkeyPressed(keys: string | string[], splitKey?: string = ',')

This function allows us to check if the user is currently pressing down a key.

import { isHotkeyPressed } from 'react-hotkeys-hook'

isHotkeyPressed('esc') // Returns true if Escape key is pressed down.

You can also check for multiple keys at the same time:

isHotkeyPressed(['esc', 'ctrl+s']) // Returns true if Escape or Ctrl+S are pressed down.

Support

  • Ask your question in the Github Discussions
  • Ask your question on StackOverflow

Found an issue or have a feature request?

Open up an issue or pull request and participate.

Local Development

Checkout this repo, run yarn or npm i and then run the test script to test the behavior of the hook.

Contributing

Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.

  1. Fork the Project
  2. Create your Feature Branch (git checkout -b feature/AmazingFeature)
  3. Commit your Changes (git commit -m 'Add some AmazingFeature')
  4. Push to the Branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

License

Distributed under the MIT License. See LICENSE for more information.

Contact

Johannes Klauss - @JohannesKlauss - [email protected]

Project Link: https://github.com/JohannesKlauss/react-hotkeys-hook

Contributors

react-hotkeys-hook's People

Contributors

alpinagyok avatar ampit avatar animify avatar brendanlaschke avatar dependabot[bot] avatar dimovym avatar fineup avatar johannesklauss avatar jvn4dev avatar kachkaev avatar louisrli avatar luanscudeler avatar minoyu avatar ocavue avatar ondrejsevcik avatar pandanoir avatar paullexen avatar pcorpet avatar pyatyispyatil avatar raiyansarker avatar renovate-bot avatar renovate[bot] avatar rewbs avatar rosalie-liu avatar suttonjack avatar t3dotgg avatar tbezman avatar travisl12 avatar wheeler avatar zenzen-sol 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

react-hotkeys-hook's Issues

Don't set wrong examples without warning

The first code example in the section Memoisation seems to be wrong on purpose.

This is very dangerous from a drive-through point of view, many devs will arrive from Google and copy/paste the example, which actually works once so they might call it a day. Users don't read the text so I'd recommend either not displaying broken code snippets or adding a big warning in a comment like // DOES NOT WORK.

how Dynamic Settings shortcuts?

If I get the shortcut key I need in an asynchronous request, but I iterate through the requested data in the FC and iterate over it, an exception will be thrown.
keyCustomArr.forEach((item) => { useHotkeys(item.key, item.fn); });
image
image

Combination Hotkeys

I have created three child components, each component I assign to a hotkey.
Child component A hotkey q
Child component B hotkey w
Child component C hotkey e
When useHotkeys on hotkey it will changing the component color. I want to create a combination of q+w+e to change color on child components. Is there any way to do it without creating new useHotkeys

Thanks

Remove node limitation

Hello,

In our project, we are using node v10, so we can't use node v12 that you added in engine. But it don't mean that your library won't work on node with smaller version.
Can we please do one of the options?
1.) remove this engine section in pre-publish
2.) or remove it in section and simply add it to documentation?

If you are busy I can create PR on it.

image

Handling "?" key

I'm trying to add a HotKey for ?. In my keyboard, ? appears above / (common American layout). I was expecting this to work:

useHotkeys('?', callback)

But it didn't. The only way I was able to make it work was using:

useHotkeys('shift+/', callback)

The issue with this approach is that it is tied to the keyboard layout. In some layouts, the ? is not on top of /, like in this one:
unnamed

Is there a way to handle ? independently of the keyboard layout? Thanks

React Context issue

Hey there,
I really liked the idea of your API, but I have ran into an issue.
React version: "16.8.1"

This is the component where I use it.
cart is from my Context and toggleShowCart is a method on it, which works just fine.
"esc" gets logged to the console when I press it.

const Cart = ({ fixed, pinned, cart }) => {
  useHotKeys('esc', () => console.log('esc') || cart.toggleShowCart);
  return (
    <Wrapper
      fixed={fixed}
      pinned={pinned}
    >
      <Overlay isVisible={cart.isOpen} onClick={cart.toggleShowCart} />
      <Base
        fixed={fixed}
        pinned={pinned}
        isOpen={cart.isOpen}
      />
      . . .

Regards,
Milos

Best practice for curried handlers?

I have a set of handler functions that look like this:

  const handler = foo => evt => {
    evt.preventDefault();
    doSomethingWithFoo(foo);
  };

If I use this as a callback for useHotkeys, the hotkey is going to reset every render, because the callback will change. For example:

useHotkeys('space', handler('bar'))

Is there a best practice I should be using to handle this kind of case?

Thanks!

It seems options are not getting passed through.

Following the example from the hotkeys documentation referenced in the react-hotkeys-hook documentation here, and taking into account the switched position of deps and options docs, I have tried the following code:

useHotkeys('enter', function(event, handler) {
 console.log(handler);
}, [],  {keyup: true});

However, this returns the following to the console:
Screenshot 2020-10-26 at 1 13 49 AM

I've also tried other combinations, but none work (thinking of these lines: https://github.com/JohannesKlauss/react-hotkeys-hook/blob/master/src/useHotkeys.ts#L15-L22). Am I doing something wrong?

Infinite Loop

I think I'm getting an infinite loop because you're not adding the second parameter [] at the end of the useEffect in your code. This will only register the event handler (hotkey) once instead of every single render.

Ability to get all hotkeys

A feature that would be helpful is the ability to get all hotkeys that are registered. This is useful for showing dialogs w/ all the key shortcuts a user can do.

Suggestion: Implement hotkeys version into hook itself

It might probably a good idea to not depend on the hotkeys package, but to implement it directly into the hook module.
That way we could add our own features and ideas to make this hook more suitable. Also we could probably reduce the module size by not depending on an other library.

Filters seem scoped, but aren't

An example:

useHotkeys('Delete', () => {
    // do something
}, { filter: ignoreInputElements });

useHotkeys('Ctrl+Shift+Delete', () => {
    // do something
}, { filter: () => true });

You might want to have different filters for different shortcuts. Here, for example, 'Delete' is something you might press during input, so needs to be filtered to ignore input elements, but 'Ctrl+Shift+Delete' is not.

Unfortunately, the hotkey filter functionality is global, so the last filter that's set always wins. In the above example, 'Delete' will fire everywhere, even in input elements, which is not what the author intended.

This isn't very react-y/declarative, as different render orders/rerenderings elsewhere can produce all sorts of strange behaviours here. It'd be better to either scope the filters to the specific shortcut somehow, or to make this behaviour obvious in the useHotkeys API. Setting the filter via useHotkeys.filter = ... would make the fact that it's global much clearer, for example.

Feature request: support an enabled option

Since this is a hook, and therefore can't be made conditional, it would be extremely useful if there was an enabled or disabled option in the Options. There are times when I don't want to add keybindings for a reusable component because I know that they'll clash with other ones that are in scope, right now I add them in a junk scope, but it would be much clearer to have an option to just disable the call.

Research: Find a way to memo callback

When the callback gets passed by a anon function, it will be recreated every time, thus the reference will be gone and useEffect will be called on every render. Find a way to memo the callback within the hook.

Stale state when using Context API

When using the Context API, it does not use the updated value and sticks to the initial one.

Here is some example code where this happens:

const Component = () => {
	const {state, setState} = useContext(ContextObject);
	
	// Initial state is:
    // { a: 1 }

	// Update state to { a: 2 }
	useEffect(()=>{
		setState({
			a: 2			
		});
	}, []);

	useHotkeys('ctrl+b', ()=>{
		console.log(state); //Logs: { a: 1 }
	});
}

Am I doing something wrong or is this a bug?

Latest version on NPM?

Hey!

I'm willing to use your package, but I'm seeing some console.log messages that seems to be already patched yet not available on NPM.

Would you mind to publish a new version with the updates, @JohannesKlauss?

Testing these hooks inside a component

Could you give an example of how you could test these hooks if they're used inside a component?

For example, I can't figure out how to test a component that uses this with react testing library fireEvent.

It looks like the original lib somehow creates a dummy component or something that events get fired against; any tips on how to find that component to listen to it in my test?

2.1.0 broken?

I upgraded from 1.6.1 to 2.1.0 and the hook has stopped working. Doesn't seem to get triggered by the keys any more.

I'm able to reproduce in a vanilla CRA TypeScript project.

Note: Reproduced using Node 12.16.1 (LTS) on Windows 10.

npx create-react-app test --template typescript
cd test
npm i react-hotkeys-hook

Modify App.tsx to documented 'usage' example:

import React, { useState } from "react";
import { useHotkeys } from "react-hotkeys-hook";
function App() {
  const [count, setCount] = useState(0);
  useHotkeys("ctrl+m", () => setCount((prevCount) => prevCount + 1));
  return <div>Pressed {count} times.</div>;
}
export default App;

Run it and "ctrl+m" doesn't increment the count as expected.

If you do:

then it works as expected.

Ability to scope to elements

It would be nice if it had to ability to scope based on a ref. Example:

  const ref = useHotkeys('ctrl+k', () => setCount(prevCount => prevCount + 1));
    
  return (
    <p ref={ref} tabindex={-1}>
      Pressed {count} times.
    </p>
  );

Question : Callback is being executed infinitely

Hi, this is more of a question than an issue.
I'm having this weird issue where the callback for useHotkeys is being executed endlessly even though the button is only pressed once.
Example Try to press the space key.

Shouldn't the callback be called only once (if the button got pressed once), regardless of what's going on in the component ?
I'm pretty sure I'm missing something here, but I'm not sure what it is.

Edit : This only happens when you update multiple state variables in the callback

Thanks in advance.

Incorrect URLs in docs

Incorrect links in docz menu e.g.:

Instead of https://johannesklauss.github.io/react-hotkeys-hook/docs-use-hotkeys/ I get https://johannesklauss.github.io/docs-use-hotkeys

This is probably a problem with base in doczrc

How to ignore repeating keyboard event

I am trying to migrate my Application from react-hotkeys.

I am wondering by any chance to have a options like

ignoreRepeatedEventsWhenKeyHeldDown: boolean

in react-hotkeys-hook?

Statically type 'keys' argument

Hey, thank you so much for this library. I was about to create my own module when I found your library which closely resembled what I had in mind. 😍

Is it possible to add static types to the keys argument? I always look up the event key names here and I'd much rather be using intellisense if possible.

Support for hotkey-js scope is missing

hotkey-js allows you to set a scope with hotkeys.setScope and retrieve it via hotkeys.getScope. With the new options passing added in, I can define a scope. However, I cannot change from the default all scope. If you'd like me to make a PR to add this in, let me know!

Using wildcard (*) gives 'length' of undefined at dispatch error.

I am building a functionality where a user can customize their hotkeys in a settings menu, and is picking up the wanted hotkeys by using the wildstar property to do so.

When React changes from this settings page, to any other page, it does not seem like the hotkeys hook unmounts.
I am using v.3 of the library.

This is the hook setup I use on the settings page.
And pick up the keys in input fields using the bindingReferance value.

useHotkeys(
    '*',
    ({ key, altKey, ctrlKey, shiftKey }: KeyboardEvent) => {
      const keyBind: string[] = [];

      if (ctrlKey) keyBind.push('ctrl');

      // This is to sort out key presses
      if (!['Control'].includes(key)) keyBind.push(key);

      const binding = keyBind.join('+');
      bindingReferance.current = binding || null;
    },
    { enableOnTags: ['INPUT'] }
  );

But as I said, when changing from this page to any other page,
I would get this error

hotkeys.common.js:429 Uncaught TypeError: Cannot read property 'length' of undefined
at dispatch (hotkeys.common.js:429)
at HTMLDocument. (hotkeys.common.js:516)

This is the use for the other buttons, for example in the navigation menu.
useHotkeys(hotkey, () => push(to));

So my theory is that it doesn't unmount the wildstar useHotkeys hook, and maybe overwrites the useHotkeys hooks I placed in my navigation buttons

docz:dev target fails

To be honest this isn't likely to be your bug, but as I know nothing about gatsby I'm thinking that you'll have a better idea if there's an easy way to fix things.

This was a fresh clone, followed by a yarn install then yarn docz:dev

❯ yarn docz:dev
yarn run v1.22.5
$ gatsby develop
success open and validate gatsby-configs - 0.918s
warn Plugin gatsby-source-filesystem is not compatible with your gatsby version 3.0.2 - It requires gatsby@^2.2.0
warn Plugin gatsby-plugin-react-helmet-async is not compatible with your gatsby version 3.0.2 - It requires [email protected]
warn Plugin gatsby-plugin-emotion is not compatible with your gatsby version 3.0.2 - It requires gatsby@^2.0.0
success load plugins - 1.213s
success onPreInit - 0.035s
success initialize cache - 0.025s
success copy gatsby files - 0.166s
success onPreBootstrap - 0.351s
success createSchemaCustomization - 0.028s
success Checking for changed pages - 0.001s
success source and transform nodes - 1.670s

 ERROR

Missing onError handler for invocation 'building-schema', error was 'Error: TypeError[File.publicURL]: Cannot convert to OutputType the following value: Object({ type: String, args: Object({  }),
description: "Copy file to static directory and return public url to it", resolve: [function resolve] })'. Stacktrace was 'Error: TypeError[File.publicURL]: Cannot convert to OutputType the
following value: Object({ type: String, args: Object({  }), description: "Copy file to static directory and return public url to it", resolve: [function resolve] })
    at TypeMapper.convertOutputFieldConfig (/Users/ggp/dev/git/react-hotkeys-hook/node_modules/gatsby/node_modules/graphql-compose/lib/TypeMapper.js:320:13)
    at ObjectTypeComposer.setField (/Users/ggp/dev/git/react-hotkeys-hook/node_modules/gatsby/node_modules/graphql-compose/lib/ObjectTypeComposer.js:215:114)
    at /Users/ggp/dev/git/react-hotkeys-hook/node_modules/gatsby/node_modules/graphql-compose/lib/ObjectTypeComposer.js:242:14
    at Array.forEach (<anonymous>)
    at ObjectTypeComposer.addNestedFields (/Users/ggp/dev/git/react-hotkeys-hook/node_modules/gatsby/node_modules/graphql-compose/lib/ObjectTypeComposer.js:235:28)
    at forEach (/Users/ggp/dev/git/react-hotkeys-hook/node_modules/gatsby/src/schema/schema.js:758:39)
    at Array.forEach (<anonymous>)
    at /Users/ggp/dev/git/react-hotkeys-hook/node_modules/gatsby/src/schema/schema.js:758:18
    at async Promise.all (index 31)
    at updateSchemaComposer (/Users/ggp/dev/git/react-hotkeys-hook/node_modules/gatsby/src/schema/schema.js:190:3)
    at buildSchema (/Users/ggp/dev/git/react-hotkeys-hook/node_modules/gatsby/src/schema/schema.js:65:3)
    at build (/Users/ggp/dev/git/react-hotkeys-hook/node_modules/gatsby/src/schema/index.js:105:18)
    at buildSchema (/Users/ggp/dev/git/react-hotkeys-hook/node_modules/gatsby/src/services/build-schema.ts:19:3)'

⠧ building schema

react-hotkeys-hook js distributions don't support IE.

Hello!

First of all, thanks for creating this useful package.

Unfortunately, default parameters aren't supported by any version of IE, so any project that is consuming this project won't be able to support IE. While I dream of a world where web devs will no longer have to support IE, this is sadly not going to be a reality for years to come.

The problem is that the current build for react-hotkeys-hook is targeting es2018 which outputs a javascript dist that contains the usage of default parameters:

import hotkeys from 'hotkeys-js';
import { useCallback, useEffect } from "react";
export function useHotkeys(keys, callback, deps = []) {
    const memoisedCallback = useCallback(callback, deps);
    useEffect(() => {
        hotkeys(keys, memoisedCallback);
        return () => hotkeys.unbind(keys, memoisedCallback);
    }, [memoisedCallback]);
}

Fortunately, the fix here would be to simply change the target parameter within the tsconfig.json to target es2015 instead. This would ensure that the distributed js would be supported by more antiquated browsers like IE.

Issue with focusing element after key combo press

Thanks for your work on this! One little problem I'm encountering though:

I'm presenting my user with the option of entering a key combo to create an item as an alternative to pressing a button to accomplish the same. The functions passed to useHotKeys() is the same that exists in my onClick for the button - the add() mutation here:

  useHotkeys(
    "command+k, ctrl+k",
    e => !e.repeat && add({ user, ids, newId: uuidv1() }),
    { filter: () => true },
    [newId]
  )

(The !e.repeat is just the best method I've encountered to disallow repeated function calls is the user holds the key combo - the onKeyUp option in configs, or whatever it is, didn't seem to work for me.)

In this mutation function, I am setting focus to the newly created element. When I call this mutation with my button, the focus works exactly as expected. But when I call this mutation with the useHotKeys(), it doesn't work. Is there some option or something I'm missing in docs that would allow my focus to work as expected when using useHotKeys()?

useHotkeys props order

Hi, Would like to suggest a code change... implications may be huge... But still valid the effort i think.

Most of the time I am in a situation where need to pass {} to options due to it's place in Function props order....

useHotkeys('f5', () => {
        history.replace(`/customer/${customer.id}/order`)
 }, {}, [ customer ])

Honestly Callback's memoization is more important than options... I mean, in almost 99.99% cases I find myself using the options' default values...

Here snipped that reflects the change applied to project's code..

[...]
useHotkeys(
  keys: string,
  callback: KeyHandler,
  deps?: any[],
  options?: Options,
)
[...]

Going back to my example... simple change but may have a great impact on code.

useHotkeys('f5', () => {
        history.replace(`/customer/${customer.id}/order`)
}, [ customer ])

BTW, I am only suggesting this change since sometimes, coding fast I completely forget to pass {} or null as options; then I get error messages like this...

Uncaught TypeError: Array.prototype.filter called on null or undefined
    at filter (<anonymous>)
    at dispatch (hotkeys.esm.js:338)
    at HTMLDocument.<anonymous> (hotkeys.esm.js:512)

This due to passing filter options to hotkeys-js ....

Would prefer to see this reflected on this great project than in my private Git cloned revision ;-)

Thanks!

Duplicate hotkey usages interfere with each other

I have two components, mounted simultaneously, that both register the same hotkey:

useHotkeys(
  "ctrl+f",
  useCallback(onOpen, [])
);

Whenever one of them gets unmounted, the hotkey stops working for the other component as well.

I think it's because of this line:

return () => hotkeys.unbind(keys);

Because when I change it to:

return () => hotkeys.unbind(keys, memoisedCallback);

it works as expected.

[Question] iframe hotkey

When creating a web page and then embedding an iframe, the hotkey does not work within this frame. Could you please tell me what I could do to make the parent document hotkey work inside the iframe?

Thanks in advance.

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.

Stale state

Following code behaves unexpectedly.
Prints initial value and not updated state value;

import React, {useState, useEffect} from 'react';
import { useHotkeys } from 'react-hotkeys-hook';

function Component() {
  const [test, setTest] = useState(0);
  useEffect(() => {
    setTest(1);
  }, []);
  useHotkeys('a', () => console.log(test));

  return <p>{test}</p>
}

export default Component

How to create a hotkey for the plus character +?

Thanks for sharing useHotkeys Johannes, it works like a charm 👍

Question: how to create a hotkey for the plus key +?

Looking at the docs of hotkeys, you have to specify a custom splitKey:

hotkeys('ctrl-+', { splitKey: '-' }, function(e) {
  console.log('you pressed ctrl and +');
});

hotkeys('+', { splitKey: '-' }, function(e){
  console.log('you pressed +');
})

As far as I can see, there is currently no way to pass options via useHotkeys to hotkeys. Any idea?

[Question] How do you specify `cmd` or `ctrl` depending on the OS?

Hi there!

Is there a way to automatically assign cmd/ctrl depending if the OS is Windows/Mac/Linux?

Currently, to support both, I'm declaring this twice:

useHotkeys('ctrl+c', () => copyHandler());  // Windows
useHotkeys('cmd+c', () => copyHandler());  // Mac

This is still not ideal and the best scenario is for react-hotkeys to figure out if ctrl/cmd should be used depending on the OS

useHotkeys('<MAGIC_KEY??>+c', () => copyHandler());  // defined just once

What would be the recommended way to go about approaching this?

Thank you!

enableOnTags example

Can anyone give an example of using enableOnTags or filters option please? I'm trying to make the library work over the input field but no luck so far. Thank you

My code looks like this now


  useHotkeys(
    "command+f, ctrl+f, f3",
    (e) => {
      e.preventDefault();
      setOpenFilters((openFilters) => !openFilters);
      (document.getElementsByClassName(
        "input-sm"
      )[0] as HTMLInputElement)?.focus();
    }
  );

Use of brackets and "æøå"

I am creating a project in Norwegian, and wish to add "alt + å" as a hotkey. When i use useHotkeys('*', (e) => console.log(e)); i can see that it is listening to the keypress å and I get an output. However if I use the same hook with useHotkeys('å', (e) => console.log(foo)), i get no output.

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.