react-native-true-sheet icon indicating copy to clipboard operation
react-native-true-sheet copied to clipboard

How to handle Keyboard when footer contains TextInput

Open spicy-xili opened this issue 6 months ago • 1 comments

I have put a TextInput in the footer component but I don't know how to properly handle the keyboard so that it doesn't hide the input itself. Normally I use KeyboardAvoidingView but it is not working at all. I also have tried keyboardMode="resize" but it didn't work. Any ideas? Thanks in advance! PS: I use Android.

https://github.com/user-attachments/assets/cae44391-dfdc-485e-9893-0304e2a4ed0f

This is my code:

import React, { forwardRef, useRef, useState, type Ref } from "react";
import { View, TextInput, TouchableOpacity, Text, StyleSheet, type ViewStyle } from "react-native";
import { TrueSheet, type TrueSheetProps } from "@lodev09/react-native-true-sheet";
import { FlatList } from "react-native-gesture-handler";
import { KeyboardAvoidingView } from "react-native-keyboard-controller";

import { DemoContent } from "./DemoContent";

const DARK = "#282e37";
const DARK_GRAY = "#333b48";
const SPACING = 16;
const INPUT_HEIGHT = SPACING * 3;

interface FlatListSheetProps extends TrueSheetProps {
  postId: string;
  userId: string;
}

const times = <T,>(length: number, iteratee: (index: number) => T): T[] => Array.from({ length }, (_, k) => iteratee(k));

export const CommentsSheet = forwardRef((props: FlatListSheetProps, ref: Ref<TrueSheet>) => {
  const { postId, userId, ...rest } = props;
  const flatListRef = useRef<FlatList>(null);
  const [comment, setComment] = useState("");

  const resetScroll = () => {
    flatListRef.current?.scrollToOffset({ animated: false, offset: 0 });
  };

  const handleSend = () => {
    console.log("Comment by user ${userId} on post ${postId}: ${comment}");
    setComment(""); // Clear the input after sending
  };

  const resetTextInput = () => {
    setComment(""); // Reset the text input
  };

  return (
    <TrueSheet
      ref={ref}
      scrollRef={flatListRef}
      sizes={["medium", "large"]}
      cornerRadius={20}
      dimmed={true}
      blurTint="dark"
      backgroundColor={DARK}
      keyboardMode="pan"
      grabber={false}
      name={postId}
      onDismiss={() => {
        console.log("Sheet FlatList dismissed!");
        resetScroll(); // Reset scroll position on dismiss
        resetTextInput(); // Reset text input on dismiss
      }}
      onPresent={() => console.log("Sheet FlatList presented!")}
      FooterComponent={
        <View style={styles.footerContainer}>
          <TextInput
            style={styles.input}
            placeholder="Write a comment..."
            placeholderTextColor="#999"
            value={comment}
            onChangeText={setComment}
          />
          <TouchableOpacity style={styles.sendButton} onPress={handleSend}>
            <Text style={styles.sendButtonText}>Send</Text>
          </TouchableOpacity>
        </View>
      }
      {...rest}
    >
      <FlatList<number>
        ref={flatListRef}
        nestedScrollEnabled
        data={times(50, (i) => i)}
        contentContainerStyle={$content}
        indicatorStyle="black"
        renderItem={() => <DemoContent color={DARK_GRAY} />}
      />
    </TrueSheet>
  );
});

CommentsSheet.displayName = "CommentsSheet";

const $content: ViewStyle = {
  padding: SPACING,
  paddingTop: INPUT_HEIGHT + SPACING * 4,
};

const styles = StyleSheet.create({
  footerContainer: {
    flexDirection: "row",
    alignItems: "center",
    padding: SPACING,
    backgroundColor: DARK,
  },
  input: {
    flex: 1,
    height: INPUT_HEIGHT,
    backgroundColor: DARK_GRAY,
    borderRadius: 20,
    paddingHorizontal: SPACING,
    color: "#fff",
  },
  sendButton: {
    marginLeft: SPACING,
    backgroundColor: "#1DA1F2",
    borderRadius: 20,
    paddingVertical: SPACING / 2,
    paddingHorizontal: SPACING,
  },
  sendButtonText: {
    color: "#fff",
    fontWeight: "bold",
  },
});

spicy-xili avatar Aug 01 '24 11:08 spicy-xili