onLongPress property not working in Button component

1. Summary

onLongPress property not working in Button component

App Name:
FrndlyTv App

Bug Severity
Select one that applies

  • Impacts operation of app

3. Observed Behaviour

In the login screen, when performing a long press on the Clear button, the onLongPress callback does not trigger.
Instead, the onPress event fires immediately, resulting in only a single character being cleared.

Because onLongPress never fires, the intended functionality—clearing the entire text in the TextInput—is not working.

4. Expected Behavior

If the user presses and holds the button for more than 250 ms, the onLongPress event should trigger, allowing the app to clear all the entered text as expected.

6. Environment

Please fill out the fields related to your bug below:

  • SDK Version: o0.20.3351

7. Example Code Snippet / Screenshots / Screengrabs

Include any relevant code or component setup in React Native that can help reproduce the bug.

  import { Button } from '@amzn/kepler-ui-components';
 {othrbtns.map((item, index) => (
            <Button
              key={index}
               label={
                item === 'x' || item === 'space' ? '' : item
              }
              iconSource={
                item === 'x'
                  ? backspaceIcon
                  : item === 'space'
                  ? spaceIcon // <-- Use your custom space icon here
                  : undefined
              }
              iconSize={'sm'}
              iconPosition="start"
              style={[
                styles.key,
                styles.twocol_btn,
                item === 'x' && { width: 235 },
                (item === '!#$' || item === 'abc') && { width: 176 },
                 item === 'space' && { width: 400 }
              ]}
              focusedStyle={[{
                width: 126,
                height: 72,
                justifyContent: 'center',
                alignItems: 'center',
                backgroundColor: '#00AD50',
                margin: 4,
                borderWidth: 0,
                borderRadius: 0,
              },
              item === 'x' && { width: 235 },
              (item === '!#$' || item === 'abc') && { width: 176 },
               item === 'space' && { width: 400 }
              ]}
              onPress={() =>
              item === 'x'
                ? handleBackspace()
                : item === '!#$' || item === 'abc'
                ? handleSpecialChar()
                : item === 'space'
                ? onKeyPress(' ')
                : onKeyPress(item)
            }
            onLongPress={()=>{console.log("triggering long Press");
            }}
              variant={'primary'}
            />
          ))}
const handleBackspace = () => {

    if (emailArrowVisible) {

setEmailTextInputValue((prevValue: string) => prevValue.slice(0, -1));

    } else {

setpassword(prevValue => prevValue.slice(0, -1));

    }

setPswErrorBorderVisible(false);

setemailErrorBorderVisible(false);

  };

Hey @vittalmaradi

Thanks for letting us know.
I’ll try to reproduce this issue and update you with my findings soon.

Warm regards,
Ivy

@vittalmaradi I used the code snippet you shared but was not able to reproduce your issue.
Let me share my App.tsx and LongPressTest.tsx code snippets.

App.tsx

import React, {useState} from 'react';
import {SafeAreaView, StyleSheet, TextInput, View, Text, TouchableOpacity} from 'react-native';

const App = () => {
  const [text, setText] = useState('');
  const [focusedKey, setFocusedKey] = useState('');

  const keys = [
    ['Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P'],
    ['A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L'],
    ['Z', 'X', 'C', 'V', 'B', 'N', 'M'],
    ['SPACE', 'CLEAR']
  ];

  const [clearTimer, setClearTimer] = useState(null);

  const handleKeyPress = (key) => {
    console.log('Key pressed:', key);
    if (key === 'CLEAR') {
      setText(prev => prev.slice(0, -1));
    } else if (key === 'SPACE') {
      setText(text + ' ');
    } else {
      setText(text + key);
    }
  };

  const handleClearLongPress = () => {
    console.log('Clear long press started');
    const timer = setInterval(() => {
      setText(prev => prev.slice(0, -1));
    }, 100);
    setClearTimer(timer);
  };

  const handleClearPressOut = () => {
    if (clearTimer) {
      clearInterval(clearTimer);
      setClearTimer(null);
    }
  };

  return (
    <SafeAreaView style={styles.container}>
      <TextInput
        style={styles.textInput}
        value={text}
        onChangeText={setText}
        placeholder="Type here..."
        showSoftInputOnFocus={false}
      />
      <View style={styles.keyboard}>
        {keys.map((row, rowIndex) => (
          <View key={rowIndex} style={styles.row}>
            {row.map((key) => (
              <TouchableOpacity
                key={key}
                style={[styles.key, key === 'SPACE' && styles.spaceKey]}
                onPress={() => handleKeyPress(key)}
                onLongPress={key === 'CLEAR' ? handleClearLongPress : undefined}
                onPressOut={key === 'CLEAR' ? handleClearPressOut : undefined}
                onFocus={() => setFocusedKey(key)}
                onBlur={() => setFocusedKey('')}
              >
                <Text style={styles.keyText}>{key === 'SPACE' ? '___' : key}</Text>
              </TouchableOpacity>
            ))}
          </View>
        ))}
      </View>
    </SafeAreaView>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#000',
    padding: 20,
  },
  textInput: {
    backgroundColor: '#fff',
    padding: 15,
    fontSize: 18,
    borderRadius: 5,
    marginBottom: 20,
  },
  keyboard: {
    flex: 1,
    justifyContent: 'center',
  },
  row: {
    flexDirection: 'row',
    justifyContent: 'center',
    marginBottom: 10,
  },
  key: {
    backgroundColor: '#333',
    padding: 15,
    margin: 5,
    borderRadius: 5,
    minWidth: 50,
    alignItems: 'center',
  },
  spaceKey: {
    minWidth: 200,
  },
  keyText: {
    color: '#fff',
    fontSize: 16,
    fontWeight: 'bold',
  },
});

export {App};
export default App;

LongPressTest.tsx

import React, { useState } from 'react';
import { StyleSheet, Text, View, TouchableOpacity } from 'react-native';

const LongPressTest = () => {
  const [inputValue, setInputValue] = useState('');
  const [longPressCount, setLongPressCount] = useState(0);
  const [lastEvent, setLastEvent] = useState('');

  const othrbtns = ['a', 'b', 'c', 'x', 'space', '!#$', 'abc'];

  const onKeyPress = (key: string) => {
    setInputValue(prev => prev + key);
    setLastEvent(`Key pressed: ${key} at ${new Date().toLocaleTimeString()}`);
    console.log('🔘 onPress triggered:', key);
  };

  const handleBackspace = () => {
    setInputValue(prevValue => prevValue.slice(0, -1));
    setLastEvent(`Backspace at ${new Date().toLocaleTimeString()}`);
    console.log('🔙 Backspace triggered');
  };

  const handleSpecialChar = () => {
    console.log('🔣 Special char mode');
    setLastEvent(`Special char mode at ${new Date().toLocaleTimeString()}`);
  };

  const handleLongPress = () => {
    setLongPressCount(prev => prev + 1);
    setLastEvent(`LongPress #${longPressCount + 1} at ${new Date().toLocaleTimeString()}`);
    console.log('🔥 triggering long Press');
  };

  return (
    <View style={styles.container}>
      <Text style={styles.title}>OnLongPress Kepler Button Test</Text>
      
      <Text style={styles.input}>{inputValue || 'Type here...'}</Text>
      
      <View style={styles.buttonGrid}>
        {othrbtns.map((item, index) => (
          <TouchableOpacity
            key={index}
            style={[
              styles.key,
              item === 'x' && { width: 235 },
              (item === '!#$' || item === 'abc') && { width: 176 },
              item === 'space' && { width: 400 }
            ]}
            onPress={() =>
              item === 'x'
                ? handleBackspace()
                : item === '!#$' || item === 'abc'
                ? handleSpecialChar()
                : item === 'space'
                ? onKeyPress(' ')
                : onKeyPress(item)
            }
            onLongPress={handleLongPress}
          >
            <Text style={styles.keyText}>
              {item === 'x' ? '⌫' : item === 'space' ? 'SPACE' : item}
            </Text>
          </TouchableOpacity>
        ))}
      </View>

      <View style={styles.stats}>
        <Text style={styles.statText}>Input: {inputValue}</Text>
        <Text style={styles.statText}>Long Press Count: {longPressCount}</Text>
        <Text style={styles.eventText}>{lastEvent}</Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    padding: 20,
  },
  title: {
    color: '#fff',
    fontSize: 24,
    fontWeight: 'bold',
    marginBottom: 20,
    textAlign: 'center',
  },
  input: {
    color: '#fff',
    fontSize: 18,
    backgroundColor: '#333',
    padding: 15,
    borderRadius: 5,
    marginBottom: 20,
    minWidth: 300,
    textAlign: 'center',
  },
  buttonGrid: {
    flexDirection: 'row',
    flexWrap: 'wrap',
    justifyContent: 'center',
    marginBottom: 20,
  },
  key: {
    width: 126,
    height: 72,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: '#007AFF',
    margin: 4,
    borderRadius: 5,
  },
  keyText: {
    color: '#fff',
    fontSize: 18,
    fontWeight: 'bold',
  },
  stats: {
    alignItems: 'center',
  },
  statText: {
    color: '#fff',
    fontSize: 16,
    marginBottom: 10,
  },
  eventText: {
    color: '#00ff00',
    fontSize: 14,
    textAlign: 'center',
  },
});

export default LongPressTest;

Please try this way and let me know if you still observe this issue.
FYI: I have kept ‘onLongpress’ event activation time to 100ms in the shared code snippet. However I have tried with 250ms activation time as well and it works.

Warm regards,
Ivy


Screen recording of the same.

Hi Team, thanks for the response.

In our keyboard component, we are using the Button component from @amzn/kepler-ui-components. We need onLongPress support directly in the Kepler Button. When we replace only the backspace key with TouchableOpacity to emulate long-press behavior, it introduces focus issues with the rest of the buttons on the screen.

Could you please provide the updated code or guidance for enabling onLongPress within the Kepler Button component itself, so that long-press can be handled without having to switch to TouchableOpacity?

Thanks.

We are checking @vittalmaradi , I’ll update you ASAP.