0

I was trying to create a longpress and swipe/pan to focus/select element.

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

const GestureItemRenderer = (
  props: ViewProps & {
    items: number[];
    selectedItem: number | null;
    setViewItems: React.Dispatch<React.SetStateAction<boolean>>;
    handleSelection: (item: number) => void;
  },
) => {
  const itemArea = 30;
  const [focusedItem, setFocusedItem] = useState<number | null>(null);

  const handleFocus = (item: number | null) => {
    setFocusedItem(item);
  };

  const styles = StyleSheet.create({
    container: {
      flexDirection: 'row',
      padding: 6,
      gap: 6,
      borderWidth: 1,
      borderColor: 'red',
    },
    itemContainer: {
      borderWidth: 1,
      borderColor: 'black',
      height: itemArea,
      width: itemArea,
    },
    selectedItem: {
      backgroundColor: 'red',
    },
    focusedItem: {
      backgroundColor: 'blue',
    },
  });

  return (
    <View style={styles.container} {...props}>
      {props.items.map((item, index) => (
        <TouchableOpacity
          onPress={() => props.handleSelection(item)}
          style={[
            styles.itemContainer,
            item === props.selectedItem && styles.selectedItem,
            item === focusedItem && styles.focusedItem,
          ]}
          key={index}>
          <Text>{item}</Text>
        </TouchableOpacity>
      ))}
    </View>
  );
};

const SelectorComponent = () => {
  const items = [1, 2, 3, 4, 5, 6, 7, 8];

  const [selectedItem, setSelectedItem] = useState<number | null>(null);
  const [viewItems, setViewItems] = useState(false);

  const styles = StyleSheet.create({
    container: {},
  });

  const handleSelectionFromSelectButton = () => {
    if (selectedItem) {
      setSelectedItem(null);
    } else {
      setSelectedItem(items[0]);
    }
  };

  const handleSelection = (value: number) => {
    setSelectedItem(value);
    setViewItems(false);
  };

  const handleLongPress = () => {
    // I want these functionalities when the user long presses:
    // If user long presses on the select button and doesn't move their finger, show the item and let user lift their finger to select it
    // If user long presses on the select button and moves their finger, show the item and let user move their finger inside the gesture area to focus on an item and lift their finger to select it
    // If user long presses on the select button and moves their finger outside the gesture area, unfocus the item
    // If user long presses on the select button and moves their finger outside the gesture area and lifts their finger, unfocus the item and hide the gesture area
    // If user long presses on the select button and moves their finger outside the gesture area and moves their finger back inside the gesture area, show the gesture area and let user move their finger inside the gesture area to focus on an item and lift their finger to select it
  };

  return (
    <View style={styles.container}>
      {viewItems && (
        <GestureItemRenderer
          items={items}
          selectedItem={selectedItem}
          setViewItems={setViewItems}
          handleSelection={handleSelection}
        />
      )}
      <TouchableOpacity
        onPress={handleSelectionFromSelectButton}
        onLongPress={handleLongPress}>
        <Text>Select</Text>
      </TouchableOpacity>
    </View>
  );
};

export default SelectorComponent;

I want these functionalities to add whenever I longpress the select button

  • If user long presses on the select button and doesn't move their finger, show the item and let user lift their finger to select it
  • If user long presses on the select button and moves their finger, show the item and let user move their finger inside the gesture area to focus on an item and lift their finger to select it
  • If user long presses on the select button and moves their finger outside the gesture area, unfocus the item
  • If user long presses on the select button and moves their finger outside the gesture area and lifts their finger, unfocus the item and hide the gesture area
  • If user long presses on the select button and moves their finger outside the gesture area and moves their finger back inside the gesture area, show the gesture area and let user move their finger inside the gesture area to focus on an item and lift their finger to select it

I tried adding panresponder on the GestureItemRenderer but the pan doesn't work when the component renders.

        <GestureItemRenderer
          items={items}
          selectedItem={selectedItem}
          setViewItems={setViewItems}
          handleSelection={handleSelection}
          {...panResponder.panHandlers}
        />

Can anyone suggest me what should I do, or how to implement this functionality? Or some piece of code that might help? I'm planning to create something like the react button of facebook/linkedin app.

Thanks

Raybi
  • 1
  • 3

0 Answers0