npm package: @nvoyy/expo-function-keys
Description: My new module
Author: Will Garrod
Latest version: 0.1.4

# expo-function-keys

An Expo module for handling function key events in React Native applications. This module is designed specifically for Android devices and supports both key down and key up events.

## Features

- Listen to function key press events (F1-F12) on Android
- Support for both key down and key up events
- Get information about modifier keys (Shift, Ctrl, Alt, Meta)
- Debug mode to log all keyboard activity
- Easy-to-use React hooks for component integration
- Fully typed TypeScript API

## Installation

```bash
npm install expo-function-keys
```

or

```bash
yarn add expo-function-keys
```

## Platform Support

| Platform | Support                     |
|----------|------------------------------|
| Android  | ✅ Full support             |
| iOS      | ❌ Not supported            |

## Requirements

- **Android**: External keyboard connected to device

## Usage

### Basic Example

```javascript
import React, { useState } from 'react';
import { View, Text } from 'react-native';
import FunctionKeysModule, { useFunctionKey } from 'expo-function-keys';

export default function App() {
  const [keyPressed, setKeyPressed] = useState('None');
  
  // Listen for F2 key
  const { isListening } = useFunctionKey(
    FunctionKeysModule.FUNCTION_KEY_F2, 
    (event) => {
      setKeyPressed(`${event.keyName} pressed with modifiers: ${
        [
          event.shiftKey ? 'Shift' : '',
          event.ctrlKey ? 'Ctrl' : '',
          event.altKey ? 'Alt' : '',
          event.metaKey ? 'Meta' : ''
        ].filter(Boolean).join(', ') || 'None'
      }`);
    }
  );
  
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>Listening for F2: {isListening ? 'Yes' : 'No'}</Text>
      <Text>Last key: {keyPressed}</Text>
    </View>
  );
}
```

### Key Down and Key Up Events

```javascript
import React, { useState } from 'react';
import { View, Text } from 'react-native';
import FunctionKeysModule, { useFunctionKey, KeyEventAction } from 'expo-function-keys';

export default function KeyDownUpExample() {
  const [keyState, setKeyState] = useState('Released');
  
  // Listen for both key down and key up events
  const { isListening } = useFunctionKey(
    FunctionKeysModule.FUNCTION_KEY_F2, 
    (event) => {
      if (event.action === KeyEventAction.DOWN) {
        setKeyState('Pressed');
      } else if (event.action === KeyEventAction.UP) {
        setKeyState('Released');
      }
    },
    {
      // Listen for both down and up events
      events: [KeyEventAction.DOWN, KeyEventAction.UP]
    }
  );
  
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>F2 Key State: {keyState}</Text>
    </View>
  );
}
```

### Using Debug Mode

```javascript
import React, { useState } from 'react';
import { View, Text, Switch } from 'react-native';
import FunctionKeysModule, { useFunctionKey, KeyEventAction } from 'expo-function-keys';

export default function DebugModeExample() {
  const [debugEnabled, setDebugEnabled] = useState(false);
  
  // Enable debug mode through the hook options
  const { isListening, setDebugMode } = useFunctionKey(
    FunctionKeysModule.FUNCTION_KEY_F2, 
    (event) => {
      console.log('F2 event:', event.action);
    },
    { 
      debug: debugEnabled,
      events: [KeyEventAction.DOWN, KeyEventAction.UP]
    }
  );
  
  // Toggle debug mode
  const toggleDebug = (value) => {
    setDebugEnabled(value);
    setDebugMode(value);
  };
  
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text style={{ marginBottom: 20 }}>Function Keys Debug Example</Text>
      
      <View style={{ flexDirection: 'row', alignItems: 'center', marginBottom: 20 }}>
        <Text style={{ marginRight: 10 }}>Debug Mode:</Text>
        <Switch value={debugEnabled} onValueChange={toggleDebug} />
      </View>
      
      <Text>
        {debugEnabled 
          ? "Debug mode ON - check console for all keypresses" 
          : "Debug mode OFF - only F2 events will be handled"}
      </Text>
    </View>
  );
}
```

### Multiple Function Keys

```javascript
import React, { useState } from 'react';
import { View, Text } from 'react-native';
import FunctionKeysModule, { useFunctionKeys, KeyEventAction } from 'expo-function-keys';

export default function App() {
  const [lastKey, setLastKey] = useState('');
  
  // Listen for multiple function keys
  const { isListening, isFullySupported, debugMode, setDebugMode } = useFunctionKeys({
    'F1': (event) => {
      if (event.action === KeyEventAction.DOWN) {
        setLastKey('F1 - Help pressed');
      } else {
        setLastKey('F1 - Help released');
      }
    },
    'F2': (event) => {
      if (event.action === KeyEventAction.DOWN) {
        setLastKey('F2 - Edit pressed');
      } else {
        setLastKey('F2 - Edit released');
      }
    }
  }, { 
    debug: true, 
    events: [KeyEventAction.DOWN, KeyEventAction.UP]
  });
  
  return (
    <View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
      <Text>Function Keys {isFullySupported ? 'Supported' : 'Not Supported'}</Text>
      <Text>Debug Mode: {debugMode ? 'Enabled' : 'Disabled'}</Text>
      <Text>Last Action: {lastKey}</Text>
    </View>
  );
}
```

## API Reference

### Events

#### `KeyEventAction.DOWN`

Triggered when a key is pressed down.

#### `KeyEventAction.UP`

Triggered when a key is released.

### Hooks

#### `useFunctionKeys(keyHandlers, options)`

A hook for listening to multiple function keys.

**Parameters:**
- `keyHandlers`: An object mapping key names (e.g., 'F1', 'F2') to handler functions.
- `options`: Configuration options object:
    - `debug`: Boolean indicating whether debug mode should be enabled.
    - `events`: Array of KeyEventAction values to listen for (default: [KeyEventAction.DOWN])

**Returns:**
- `isListening`: Boolean indicating if the listener is active.
- `isFullySupported`: Boolean indicating if the current platform supports the module (true on Android, false on iOS).
- `debugMode`: Boolean indicating if debug mode is currently enabled.
- `setDebugMode`: Function to enable or disable debug mode.

#### `useFunctionKey(keyCode, handler, options)`

A simplified hook for listening to a single function key.

**Parameters:**
- `keyCode`: The key code to listen for (use constants from `FunctionKeysModule`).
- `handler`: A function to call when the key is pressed.
- `options`: Configuration options object:
    - `debug`: Boolean indicating whether debug mode should be enabled.
    - `events`: Array of KeyEventAction values to listen for (default: [KeyEventAction.DOWN])

**Returns:**
- Same as `useFunctionKeys`.

### Event Object

The event object passed to key event handlers has the following properties:

- `keyCode`: The numeric key code.
- `keyName`: The key name (e.g., 'F1', 'F2', etc.).
- `action`: The key action (KeyEventAction.DOWN or KeyEventAction.UP).
- `altKey`: Boolean indicating if the Alt key is pressed.
- `ctrlKey`: Boolean indicating if the Ctrl key is pressed.
- `shiftKey`: Boolean indicating if the Shift key is pressed.
- `metaKey`: Boolean indicating if the Meta key is pressed.

### Constants

- `FunctionKeysModule.FUNCTION_KEY_F1` through `FunctionKeysModule.FUNCTION_KEY_F12`: Key codes for F1-F12 keys.
- `FunctionKeysModule.KEY_DOWN` and `FunctionKeysModule.KEY_UP`: Key action constants.

### Module Methods

#### `FunctionKeysModule.setDebugMode(enabled)`

Enables or disables debug mode at the module level.

**Parameters:**
- `enabled`: Boolean indicating whether debug mode should be enabled.

#### `FunctionKeysModule.isDebugMode()`

Checks if debug mode is currently enabled.

**Returns:**
- Boolean indicating if debug mode is enabled.

## Debug Mode

When debug mode is enabled:

1. **Console Logging**: All keypresses will be logged to the console, not just function keys.
2. **Native Logging**: The Android module will log additional information about the keyboard state and events.
3. **Troubleshooting**: Helpful for diagnosing issues with keyboard handling or understanding what keys are being pressed.

Debug mode is particularly useful when:
- Setting up the module for the first time
- Troubleshooting why certain keys aren't being detected
- Understanding the flow of keyboard events in your application
- Testing with different keyboard types

## Notes

- This module works best with physical keyboards connected to Android devices.
- Function keys are typically available on external keyboards, not on-screen keyboards.
- If you attempt to use this module on iOS, warning messages will be shown and the module will not function.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## License

MIT