JSPM

react-native-physical-keyboard-detector

1.1.4
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 18
  • Score
    100M100P100Q77218F
  • License MIT

Cross-platform Expo module that detects physical keyboard connections and provides detailed keyboard information on iOS and Android devices

Package Exports

  • react-native-physical-keyboard-detector
  • react-native-physical-keyboard-detector/lib/commonjs/index.js
  • react-native-physical-keyboard-detector/lib/module/index.js

This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (react-native-physical-keyboard-detector) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

Readme

React Native Physical Keyboard

npm Downloads CI

Cross-platform React Native + Expo module for detecting physical keyboards on mobile devices. This library can be useful for detecting external keyboards when implementing accessibility features.

Features

🔌 Real-time keyboard connection detection

⌨️ Key press and release event monitoring

📊 Hardware information (vendor, model, type)

🎣 Simple React Hooks API

📘 Full TypeScript support

⚡ Zero configuration required

📦 Zero unnecessary dependencies

🍎 iOS and Android support

🎨 Expo compatible (SDK 50+)

Installation

npm install react-native-physical-keyboard-detector
bun add react-native-physical-keyboard-detector

⚠️ Requires native rebuild - run expo prebuild after installation.

📱 Testing Note - For best results, test on physical devices. Simulators may not properly detect key press events, though keyboard connection detection should work correctly.

Usage

Basic Setup

import { PhysicalKeyboardProvider } from 'react-native-physical-keyboard-detector';

export default function App() {
  return (
    <PhysicalKeyboardProvider>
      <YourApp />
    </PhysicalKeyboardProvider>
  );
}

Detect Connection

function MyComponent() {
  const isConnected = usePhysicalKeyboardConnected();
  
  return (
    <Text>
      Keyboard: {isConnected ? 'Connected' : 'Not Connected'}
    </Text>
  );
}

Get Keyboard Details

function KeyboardInfo() {
  const keyboard = usePhysicalKeyboardDetails();
  
  if (!keyboard) return <Text>No external hardware keyboard</Text>;
  
  return (
    <View>
      <Text>Name: {keyboard.name}</Text>
      <Text>Connected: {new Date(keyboard.connectedAt).toLocaleString()}</Text>
      {/* iOS specific */}
      {keyboard.vendorName && <Text>Vendor: {keyboard.vendorName}</Text>}
      {/* Android specific */}
      {keyboard.keyboardType && <Text>Type: {keyboard.keyboardTypeName}</Text>}
    </View>
  );
}

Listen to Key Events

function KeyListener() {
  const keyEvent = usePhysicalKeyboardEvents();
  
  if (!keyEvent) return null;
  
  return (
    <Text>
      Last key: {keyEvent.keyCode} ({keyEvent.action})
    </Text>
  );
}

API

Provider

  • <PhysicalKeyboardProvider> - Wrap your app to enable keyboard detection

Hooks

  • usePhysicalKeyboardConnected() - Returns boolean
  • usePhysicalKeyboardDetails() - Returns keyboard info or null
  • usePhysicalKeyboardEvents() - Returns last key event or null

Note: All hooks must be used within PhysicalKeyboardProvider

Types

interface IOSPhysicalKeyboardInfo {
  name: string;
  connectedAt: number;
  vendorName?: string;
  productCategory?: string;
  availableButtonKeys?: string[];
  buttonCount?: number;
}

interface AndroidPhysicalKeyboardInfo {
  name: string;
  connectedAt: number;
  id?: number;
  vendorId?: number;
  productId?: number;
  controllerNumber?: number;
  descriptor?: string;
  isVirtual?: boolean;
  isExternal?: boolean;
  sources?: number;
  keyboardType?: number;
  keyboardTypeName?: string;
}

interface KeyPressEventPayload {
  keyCode: number;
  timestamp: number;
  action: 'up' | 'down';
}

Platform Support

  • iOS: Uses GameController framework for connection detection, UIKit for key events
  • Android: Uses InputDevice API
  • Expo: SDK 50+

Known Limitations

iOS - Arrow Keys, Tab, and Space with Full Keyboard Access

Platform: iOS only (Android is not affected)

When Full Keyboard Access (FKA) is enabled on iOS (Settings > Accessibility > Keyboards > Full Keyboard Access), the system intercepts arrow keys, tab, and space for accessibility navigation. This is a system-level behavior that cannot be overridden by third-party apps.

Impact on iOS:

  • ✅ Keyboard connection detection works normally
  • ✅ All other keys (letters, numbers, function keys, etc.) work normally
  • ❌ Arrow keys (up, down, left, right) are not detected when FKA is enabled
  • ❌ Tab key is not detected when FKA is enabled
  • ❌ Space key is not detected when FKA is enabled

Android: All keys including arrows, tab, and space should work correctly regardless of accessibility settings.

Technical Details: This limitation exists because iOS uses these keys for system-wide accessibility features. Apple's UIKit APIs (UIKeyCommand, pressesBegan) and even the GameController framework cannot bypass FKA. This affects all iOS apps that attempt to capture these specific keys.

🤝 Contributing

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

License

MIT