Amazon Developer

as

Settings
Sign out
Notifications
Alexa
Amazon Appstore
Ring
AWS
Documentation
Support
Contact Us
My Cases
Get Started
Design and Develop
Publish
Reference
Support

UserInputManager

UserInputManager allows app to override the default behavior when D-pad events are received.

UserInputManager is deprecated in React Native Vega, and will be removed in a future release. Please use TVEventHandler instead.

Please use this API with caution

As soon as a listener for a specific keyEvent is registered via UserInputManager, it will replace all the existing listeners, even those that are responsible for the platform behavior. App will have to commit to handling the keypress for the entire lifecycle of the app. Its better to use TVEventHandler if you only need a callback when keys are pressed.

Usage Vega

Copied to clipboard.


import {
    EventSubscription,
    useAddUserInputListenerCallback,
    UserInputEvent,
    UserInputEventName
} from '@amazon-devices/react-native-kepler';
import * as React from 'react';
import { useEffect, useState } from 'react';
import { StyleSheet, Text, View } from 'react-native';

import { DEFAULT_COLORS, DEFAULT_STYLES } from '../../components/Constants';

const styles = StyleSheet.create({
    innerContainer: {
        display: 'flex',
        alignItems: 'center',
        flex: 1
    },
    noteText: {
        color: DEFAULT_COLORS.TEXT,
        fontSize: 20,
        padding: 8,
        display: 'flex'
    },
    itemContainer: {
        display: 'flex',
        flex: 1,
        flexWrap: 'wrap',
        justifyContent: 'flex-start',
        flexDirection: 'column'
    },
    item: {
        backgroundColor: DEFAULT_COLORS.SURFACE,
        padding: 4,
        margin: 8,
        borderRadius: 8,
        minWidth: 210,
        height: 100,
        alignItems: 'center',
        justifyContent: 'center'
    },
    itemPressed: {
        backgroundColor: DEFAULT_COLORS.PRIMARY
    },
    itemKeyText: {
        color: DEFAULT_COLORS.TEXT,
        fontFamily: 'monospace',
        fontWeight: 'bold',
        fontSize: 24
    },
    itemSubText: {
        paddingTop: 8,
        color: DEFAULT_COLORS.TEXT,
        opacity: 0.5,
        fontSize: 18
    }
});

const supportedEvents = [
    UserInputEventName.Up,
    UserInputEventName.Down,
    UserInputEventName.Left,
    UserInputEventName.Right,
    UserInputEventName.Select,
    UserInputEventName.Back,
    UserInputEventName.Menu,
    UserInputEventName.PlayPause,
    UserInputEventName.SkipBackward,
    UserInputEventName.SkipForward,
    UserInputEventName.PageUp,
    UserInputEventName.PageDown,
    UserInputEventName.PageLeft,
    UserInputEventName.PageRight,
    UserInputEventName.Info,
    UserInputEventName.More
];

type KeyUsageMap = {
    [key in UserInputEventName]?: { pressed: boolean; count: number };
};

const App = () => {
    const addUserInputListenerCallback = useAddUserInputListenerCallback();
    const eventSubscriptions: EventSubscription[] = [];
    const [state, setKeyState] = useState<KeyUsageMap>(
        supportedEvents.reduce(
            (obj, event: UserInputEventName) => ({
                ...obj,
                [event]: { pressed: false, count: 0 }
            }),
            {}
        )
    );

    useEffect(() => {
        supportedEvents.forEach((name, index) => {
            eventSubscriptions.push(
                addUserInputListenerCallback(name, (event: UserInputEvent) => {
                    console.log(name, event);
                    update(name, event);
                    return true;
                })
            );
        });
        return () => {
            eventSubscriptions.forEach((eventSubscription) =>
                eventSubscription.remove()
            );
        };
    }, []);

    const update = (name: UserInputEventName, event: UserInputEvent) => {
        setKeyState((oldState: KeyUsageMap) => {
            const newState = { ...oldState };
            const oldCount = oldState[name]?.count ?? 0;
            if (event.phase === 'PRESSED') {
                newState[name] = { count: oldCount + 1, pressed: true };
            } else if (event.phase === 'RELEASED') {
                newState[name] = { count: oldCount, pressed: false };
            }
            return newState;
        });
    };

    return (
        <View style={DEFAULT_STYLES.CONTAINER}>
            <View style={styles.innerContainer}>
                <Text style={styles.noteText}>
                    Press a key on the remote. To navigate back, press the
                    "Back" button twice.
                </Text>

                <View style={styles.itemContainer}>
                    {Object.entries(state).map(([name, info]: any) => (
                        <View
                            style={[
                                styles.item,
                                info.pressed ? styles.itemPressed : {}
                            ]}>
                            <Text style={styles.itemKeyText}>{name}</Text>
                            <Text style={styles.itemSubText}>
                                Press Count: {info.count}
                            </Text>
                        </View>
                    ))}
                </View>
            </View>
        </View>
    );
};

export default App;


Reference

Methods

Deprecated. Use the useAddUserInputListenerCallback() hook instead.

UserInputManager.addListener(eventName, callback) Vega

This method allows app to registers listener for specific event, following is a list of all supported events in Vega


UserInputEventName.Up,
UserInputEventName.Down,
UserInputEventName.Left,
UserInputEventName.Right,
UserInputEventName.Select,
UserInputEventName.Back,
UserInputEventName.Menu,
UserInputEventName.PlayPause,
UserInputEventName.SkipBackward,
UserInputEventName.SkipForward,
UserInputEventName.PageUp,
UserInputEventName.PageDown,
UserInputEventName.PageLeft,
UserInputEventName.PageRight,
UserInputEventName.Info,
UserInputEventName.More

useAddUserInputListenerCallback = UserInputListenerCallback Vega

This custom hook returns a callback that, when invoked, will register a listener for specific event. Please make sure to also obey the Rules of Hooks, when calling this hook. The returned callback function takes two paramenters: the UserInputEventName to listen to, and a callback function to invoke when the desired UserInputEventName is pressed.

The following is a list of all supported events in Vega:


UserInputEventName.Up,
UserInputEventName.Down,
UserInputEventName.Left,
UserInputEventName.Right,
UserInputEventName.Select,
UserInputEventName.Back,
UserInputEventName.Menu,
UserInputEventName.PlayPause,
UserInputEventName.SkipBackward,
UserInputEventName.SkipForward,
UserInputEventName.PageUp,
UserInputEventName.PageDown,
UserInputEventName.PageLeft,
UserInputEventName.PageRight,
UserInputEventName.Info,
UserInputEventName.More


Last updated: May 13, 2026