Skip to content

Expensify/react-native-key-command

Folders and files

NameName
Last commit message
Last commit date

Latest commit

d7c304e · Jan 27, 2025
Aug 15, 2022
Oct 24, 2024
May 15, 2023
Sep 23, 2023
Apr 19, 2023
Apr 19, 2023
Oct 2, 2023
Oct 17, 2024
Aug 15, 2022
Jul 13, 2022
Apr 19, 2023
Aug 15, 2022
Aug 15, 2022
Jan 27, 2025
Jan 27, 2025
Jan 17, 2024

Repository files navigation

react-native-key-command

A cross-platform module that registers and listens to specified keyboard events, dispatching the payload to JavaScript.

✅ Android ✅ iOS ✅ Web

Installation

npm install react-native-key-command

iOS

cd ios && pod install

Changes required in your AppDelegate.m

// add library imports in the top of your file 
#import <HardwareShortcuts.h>

@implementation AppDelegate

..

// Add keyCommands and handleKeyCommand methods in AppDelegate class
- (NSArray *)keyCommands {
  return [HardwareShortcuts sharedInstance].keyCommands;
}

- (void)handleKeyCommand:(UIKeyCommand *)keyCommand {
  [[HardwareShortcuts sharedInstance] handleKeyCommand:keyCommand];
}

@end

Android

Changes required in your MainActivity.java

// add library imports in the top of your file 
import android.view.KeyEvent;
import com.expensify.reactnativekeycommand.KeyCommandModule;

public class MainActivity extends ReactActivity {

  ..

  // Add a new onKeyDown method in MainActivity class
  @Override
  public boolean onKeyDown(int keyCode, KeyEvent event) {
    KeyCommandModule.getInstance().onKeyDownEvent(keyCode, event);
    return super.onKeyDown(keyCode, event);
  }

Usage

import * as KeyCommand from 'react-native-key-command';

// ...

/**
 * [CMD + F] combination listener
 */
React.useEffect(() => {
    const SEARCH_COMMAND = {input: 'f', modifierFlags: KeyCommand.constants.keyModifierCommand};
    return KeyCommand.addListener(SEARCH_COMMAND, console.log);
}, []);

/**
 * [Esc] key listener
 */
React.useEffect(() => {
    const ESCAPE_COMMAND = {input: KeyCommand.constants.keyInputEscape};
    return KeyCommand.addListener(ESCAPE_COMMAND, console.log);
}, []);

Constants

List of available modifier flags. Values on Android may vary.

KeyCommand.constants = {
  "keyInputDownArrow": 20,
  "keyInputEscape": 111,
  "keyInputLeftArrow": 21,
  "keyInputRightArrow": 22,
  "keyInputUpArrow": 19,
  "keyModifierCapsLock": 65536,
  "keyModifierCommand": 1048576,
  "keyModifierControl": 262144,
  "keyModifierControlCommand": 1310720,
  "keyModifierControlOption": 786432,
  "keyModifierControlOptionCommand": 1835008,
  "keyModifierNumericPad": 78,
  "keyModifierOption": 524288,
  "keyModifierOptionCommand": 1572864,
  "keyModifierShift": 131072,
  "keyModifierShiftCommand": 1179648
}

Imperative API provides you with granular control over the library, e.g:

  • Declare multiple commands at once.
  • Declare command in your React component (components/Shortcuts.js) and attach listener globally in your root component (Router.js).
  • Implement decoupled Register / Unregister commands.
import * as KeyCommand from 'react-native-key-command';

// ...

const SEARCH_COMMAND = {input: 'd', modifierFlags: KeyCommand.constants.keyModifierCommand};

/**
 * Register a command for [k + CMD] combination
 */
KeyCommand.registerKeyCommands([SEARCH_COMMAND]);

/**
 * Add a global event listener that will trigger when any
 * registered keycommand is pressed
 */
KeyCommand.eventEmitter.addListener('onKeyCommand', console.log);

/**
 * Add a global event listener that will trigger when any
 * registered keycommand is pressed
 */
KeyCommand.eventEmitter.addListener('onKeyCommand', console.log);

/**
 * Unregister keycommand
 */
KeyCommand.unregisterKeyCommands([SEARCH_COMMAND]);

Contributing

See the contributing guide to learn how to contribute to the repository and the development workflow.

License

MIT