npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

react-native-keyboard-flatlist

v1.0.0

Published

A cross-platform React Native FlatList that supports hardware keyboard navigation (Up, Down, Left, Right, Enter) for iOS, Android, and Web.

Readme

react-native-keyboard-flatlist

A cross-platform React Native FlatList component that supports native hardware keyboard and TV remote navigation (Arrow Up, Arrow Down, Arrow Left, Arrow Right, Enter, D-Pad Center).

Built using the Expo Modules API and modern React Native architecture, it seamlessly intercepts physical key presses on iOS, Android (including Android TV / Fire TV), and Web.

Features

  • Cross-Platform: Works on iOS (via UIKeyCommand), Android (including TV D-Pads via dispatchKeyEvent), and Web.
  • TV & Gamepad Remote Ready: Native support for D-Pad Center (KEYCODE_DPAD_CENTER), Gamepad A (KEYCODE_BUTTON_A), Numpad Enter, and Arrow keys.
  • 2D Grid Layout Navigation: Full support for multi-column grids (numColumns > 1), automatically calculating row and column movement.
  • Auto-Scrolling: Automatically scrolls to center the currently focused item.
  • Circular Looping: Optional loop prop to wrap around navigation from end to start.
  • Pause/Resume Control: Easily disable keyboard interception when dialogs, modals, or text inputs are open via enabled.
  • Accessibility Friendly: Passes isFocused to renderItem so you can apply styles and update accessibilityState.

Installation

npm install react-native-keyboard-flatlist

Or using Yarn:

yarn add react-native-keyboard-flatlist

Expo Projects

This library includes an Expo Config Plugin to automatically inject D-Pad key interception into Android's MainActivity.

Add it to your app.json or app.config.js:

{
  "expo": {
    "plugins": ["react-native-keyboard-flatlist"]
  }
}

Then rebuild your app:

npx expo prebuild
npx expo run:android
npx expo run:ios

Usage

Simple List Navigation

Replace standard FlatList with KeyboardFlatList. Your renderItem callback receives isFocused.

import React from 'react';
import { Text, TouchableOpacity, StyleSheet } from 'react-native';
import { KeyboardFlatList } from 'react-native-keyboard-flatlist';

const DATA = [
  { id: '1', title: 'First Item' },
  { id: '2', title: 'Second Item' },
  { id: '3', title: 'Third Item' },
];

export default function App() {
  const handleItemPress = (item, index) => {
    console.log('Pressed item:', item.title, 'at index:', index);
  };

  return (
    <KeyboardFlatList
      data={DATA}
      keyExtractor={(item) => item.id}
      initialFocusedIndex={0}
      onEnterPress={handleItemPress}
      renderItem={({ item, isFocused }) => (
        <TouchableOpacity 
          style={[styles.item, isFocused && styles.focusedItem]}
          accessible={true}
          accessibilityState={{ selected: isFocused }}
        >
          <Text style={[styles.text, isFocused && styles.focusedText]}>
            {item.title}
          </Text>
        </TouchableOpacity>
      )}
    />
  );
}

const styles = StyleSheet.create({
  item: { padding: 16, backgroundColor: 'white' },
  focusedItem: { backgroundColor: '#007AFF' },
  text: { fontSize: 18, color: '#333' },
  focusedText: { color: 'white', fontWeight: 'bold' },
});

2D Grid Layout (TV / Dashboard)

Set numColumns to navigate multi-column grids smoothly with Arrow keys / D-Pad:

<KeyboardFlatList
  data={DATA}
  numColumns={3}
  loop={true}
  onFocusIndexChange={(index, item) => console.log('Focused:', item.title)}
  renderItem={({ item, isFocused }) => (
    // Your grid item UI
  )}
/>

API Reference

<KeyboardFlatList> Props

Inherits all standard FlatListProps.

| Prop | Type | Default | Description | |---|---|---|---| | data | ItemT[] | Required | Array of items to render. | | renderItem | ({ item: ItemT, index: number, isFocused: boolean }) => ReactElement | Required | Renders each item in the list with isFocused status. | | initialFocusedIndex | number | 0 | Index to highlight when the list first mounts. | | numColumns | number | 1 | Number of grid columns for 2D layout navigation. | | loop | boolean | false | When true, navigating past list boundaries loops around. | | enabled | boolean | true | Set to false to pause key interception (e.g. when a modal is open). | | onEnterPress | (item: ItemT, index: number) => void | undefined | Callback fired when Enter / D-Pad select is pressed. | | onFocusIndexChange | (index: number, item: ItemT) => void | undefined | Callback fired whenever the focused item changes. |


License

MIT