Skip to content

[Bug]: TextInput is being covered by keyboard inside BottomSheetModal #2658

@Lundeg

Description

@Lundeg

Version

v5

Reanimated Version

v3

Gesture Handler Version

v2

Platforms

iOS

What happened?

In version 5.2.10, when a TextInput is placed inside the BottomSheetModal, the sheet does not properly adjust its position when the keyboard appears. As a result, the keyboard overlaps the input field, making it impossible for users to see what they are typing. This persists even when keyboardBehavior is set to extend or interactive.

Reproduction steps

  • import { Fonts, Spacing } from "@/constants/theme";
    import { useBottomSheetStyles } from "@/hooks/use-bottom-sheet-styles";
    import { useTheme } from "@/hooks/use-theme";
    import Category from "@/model/category";
    import { deleteCategory } from "@/services/category";
    import { BottomSheetModal, BottomSheetView } from "@gorhom/bottom-sheet";
    import { ShieldAlert } from "lucide-react-native";
    import { forwardRef, useImperativeHandle, useRef, useState } from "react";
    import { useTranslation } from "react-i18next";
    import { StyleSheet, View } from "react-native";
    import { useSafeAreaInsets } from "react-native-safe-area-context";
    import bottomsheetBackdrop from "../ui/bottomsheet-backdrop";
    import Button from "../ui/button";
    import { Text } from "../ui/text";
    import { ThemedView } from "../ui/themed-view";

type Props = {
item: Category;
onClose: () => void;
};

const DeleteCategoryBottomSheet = forwardRef<BottomSheetModal, Props>(
({ item, onClose }, ref) => {
const { bottom } = useSafeAreaInsets();
const [isLoading, setLoading] = useState(false);
const { t } = useTranslation();
const theme = useTheme();
const innerRef = useRef(null);

useImperativeHandle(ref, () => innerRef.current!);

const { backgroundStyle, handleIndicatorStyle } = useBottomSheetStyles();
const onDeleteCategory = async () => {
  try {
    setLoading(true);
    await deleteCategory(item.id);
    innerRef.current?.dismiss();
  } catch (error) {
    console.log(error);
  } finally {
    setLoading(false);
  }
};
return (
  <BottomSheetModal
    ref={innerRef}
    backdropComponent={bottomsheetBackdrop}
    backgroundStyle={backgroundStyle}
    handleIndicatorStyle={handleIndicatorStyle}
    onDismiss={onClose}
  >
    <BottomSheetView
      style={[styles.container, { paddingBottom: Spacing.four + bottom }]}
    >
      <ThemedView themeColor="red20" style={styles.iconContainer}>
        <ShieldAlert color={theme.red} size={60} />
      </ThemedView>
      <View>
        <Text style={styles.title}>
          {t("components.category.deleteCategoryBottomSheet.title", {
            unicode: item.unicode,
            name: item.name,
          })}
        </Text>
        <Text themeColor="grey5" style={styles.description}>
          {t("components.category.deleteCategoryBottomSheet.description")}
        </Text>
      </View>
      <View style={styles.footer}>
        <Button
          style={styles.footerButton}
          type="secondary"
          disabled={isLoading}
          onPress={onClose}
        >
          {t("common.cancel")}
        </Button>
        <Button
          style={styles.footerButton}
          type="delete"
          onPress={onDeleteCategory}
        >
          {t("common.delete")}
        </Button>
      </View>
    </BottomSheetView>
  </BottomSheetModal>
);

},
);

export default DeleteCategoryBottomSheet;

const styles = StyleSheet.create({
container: {
paddingHorizontal: Spacing.four,
gap: Spacing.four,
},
iconContainer: {
width: 100,
height: 100,
justifyContent: "center",
alignItems: "center",
marginHorizontal: "auto",
borderRadius: 100,
},

title: {
fontFamily: Fonts.manrope.extraBold,
fontSize: 18,
textAlign: "center",
lineHeight: 24,
marginTop: Spacing.four,
paddingHorizontal: Spacing.four,
marginBottom: Spacing.two,
},
description: {
fontFamily: Fonts.manrope.regular,
paddingHorizontal: Spacing.two,
fontSize: 14,
textAlign: "center",
lineHeight: 16,
marginBottom: Spacing.four,
},
footer: {
flexDirection: "row",
gap: Spacing.two,
},
footerButton: {
flex: 1,
},
});

Reproduction sample

https://snack.expo.dev/@gorhom/bottom-sheet---issue-reproduction-template

Relevant log output

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions