ethanworker
ethanworker

Reputation: 15

Modal getting squished on Mobile (Top Left) in React Native

The modal is stuck at the top left of my mobile device, but not on a website. It could be Carousel contributing to the issue, as modal works on other pages. Moreover, the modal appears in the center as per normal when isVisible is set to true and there isn't any animations for the modal, when reloading the page.

import * as React from "react";
import { Dimensions, View, ImageBackground, StyleSheet, TouchableOpacity, Text, Modal } from "react-native";
import { useSharedValue } from "react-native-reanimated";
import Carousel, {
  ICarouselInstance,
  Pagination,
} from "react-native-reanimated-carousel";
import { LinearGradient } from "expo-linear-gradient";
import { useRouter } from "expo-router";
import { saveToSecureStorage } from "../../utils/SecureStorage";

const width = Dimensions.get("window").width;
const height = Dimensions.get("window").height;

const slides = [
  { id: "1", background: require("../../assets/images/onboard/Slide_1.jpg") },
  { id: "2", background: require("../../assets/images/onboard/Slide_2.jpg") },
  { id: "3", background: require("../../assets/images/onboard/Slide_3.jpg") },
];

export default function App() {
  const ref = React.useRef<ICarouselInstance>(null);
  const progress = useSharedValue<number>(0);
  const router = useRouter();

  const onPressPagination = (index: number) => {
    ref.current?.scrollTo({
      count: index - progress.value,
      animated: true,
    });
  };

  const handleSelection = async (Id: string) => {
    await saveToSecureStorage("Id", Id);
    router.push("/(tabs)/chat");
  };

  const renderItem = ({ item }: { item: typeof slides[0] }) => (
    <ImageBackground source={item.background} style={styles.backgroundImage}>
      <TouchableOpacity
        style={styles.button}
        onPress={() => handleSelection(item.id)}
      >
        <LinearGradient colors={["#6A0DAD", "#FF69B4"]} style={styles.gradient}>
          <Text style={styles.buttonText}>Start</Text>
        </LinearGradient>
      </TouchableOpacity>
    </ImageBackground>
  );

  return (
    <View style={styles.container}>
      <Carousel
        ref={ref}
        width={width}
        height={height}
        data={slides}
        onProgressChange={progress}
        loop
        renderItem={renderItem}
      />
      <Pagination.Basic
        progress={progress}
        data={slides}
        dotStyle={styles.dot}
        activeDotStyle={styles.activeDot}
        containerStyle={styles.paginationContainer}
        onPress={onPressPagination}
      />

      {/* Always Visible Modal */}
      <Modal transparent={true} visible={true}>
        <View style={styles.modalContainer}>
          <View style={styles.modalContent}>
            <Text style={styles.modalText}>Welcome!</Text>
            <TouchableOpacity
              style={styles.closeButton}
              onPress={() => alert("Modal interaction example")}
            >
              <Text style={styles.closeButtonText}>Get Started</Text>
            </TouchableOpacity>
          </View>
        </View>
      </Modal>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: "black",
  },
  backgroundImage: {
    flex: 1,
    justifyContent: "flex-end",
    width: "100%",
    height: "100%",
  },
  button: {
    marginBottom: 50,
    alignSelf: "center",
    width: "80%",
    borderRadius: 25,
    overflow: "hidden",
  },
  gradient: {
    paddingVertical: 15,
    alignItems: "center",
    borderRadius: 25,
  },
  buttonText: {
    color: "white",
    fontSize: 18,
    fontWeight: "bold",
  },
  dot: {
    backgroundColor: "rgba(255, 255, 255, 0.5)",
    borderRadius: 50,
    width: 10,
    height: 10,
  },
  activeDot: {
    backgroundColor: "white",
    borderRadius: 50,
    width: 12,
    height: 12,
  },
  paginationContainer: {
    position: "absolute",
    bottom: 20,
    alignSelf: "center",
    flexDirection: "row",
    justifyContent: "center",
    alignItems: "center",
  },
  modalContainer: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    backgroundColor: "rgba(0, 0, 0, 0.7)",
  },
  modalContent: {
    width: "80%",
    padding: 20,
    backgroundColor: "white",
    borderRadius: 10,
    alignItems: "center",
  },
  modalText: {
    fontSize: 18,
    marginBottom: 20,
  },
  closeButton: {
    backgroundColor: "#6A0DAD",
    paddingVertical: 10,
    paddingHorizontal: 20,
    borderRadius: 5,
  },
  closeButtonText: {
    color: "white",
    fontWeight: "bold",
  },
});

Upvotes: 0

Views: 49

Answers (1)

ethanworker
ethanworker

Reputation: 15

Add the modal into the item being rendered, not on the whole page.

Upvotes: 0

Related Questions