Css Top Z-index cover bottom Scroll View

Viewed 278

I am using React Native Typescript for my. In My app there are three elements one is Map, bottom-sheet (which position is absolute) and One button. I have created one custom bottom sheet. Bottom-sheet is animated Scrollable. Inside the Bottom-sheet I used Custom search bar and under the search bar there is Flat-list where I am rendering the data. In IOS simulator I can see the FlatList card under the Button. which is really bad from UI (IOS-Image) but in Android it looks perfect Android-simulator. I want to hide the flat-List data which is coming under the button. I tried background color white and tried with height, width, bottom.But none of of work. I want to make efficient css position instead of hard code position. But I don't know how to fixed it.

I share my code in Expo-snacks

This is my custom Bottom-sheet

 import React from "react";
    import {
      SafeAreaView,
      StyleSheet,
      Text,
      useWindowDimensions,
      TouchableOpacity,
      View,
    } from "react-native";
    import Animated, {
      Extrapolate,
      interpolate,
      useAnimatedGestureHandler,
      useAnimatedStyle,
      withTiming,
    } from "react-native-reanimated";
    import { PanGestureHandler } from "react-native-gesture-handler";
    import styled from "styled-components/native";
    
    interface Props {
      panY: number;
      children: React.ReactNode;
    }
    export default function BottomSheet({ panY, children }: Props) {
      const { height } = useWindowDimensions();
    
      const gestureHandler = useAnimatedGestureHandler(
        {
          onStart(_, context) {
            context.startY = panY.value;
          },
          onActive(event, context) {
            panY.value = context.startY + event.translationY;
          },
          onEnd() {
            if (panY.value < -height * 0.4) {
              panY.value = withTiming(-(height * 0.6));
            } else {
              panY.value = withTiming(0);
            }
          },
        },
        [height]
      );
    
      const animatedStyle = useAnimatedStyle(() => {
        return {
          transform: [
            {
              translateY: interpolate(panY.value, [-1, 0], [-1, 0], {
                extrapolateLeft: Extrapolate.EXTEND,
                extrapolateRight: Extrapolate.CLAMP,
              }),
            },
          ],
        };
      });
    
      return (
        <PanGestureHandler onGestureEvent={gestureHandler}>
          <Animated.View
            style={[styles.container, { top: height * 0.7 }, animatedStyle]}
          >
            {children}
          </Animated.View>
        </PanGestureHandler>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        position: "absolute",
        top: 0,
        left: 0,
        right: 0,
        backgroundColor: "white",
        shadowColor: "black",
        shadowOffset: {
          height: -6,
          width: 0,
        },
        shadowOpacity: 0.1,
        shadowRadius: 5,
        borderTopEndRadius: 15,
        borderTopLeftRadius: 15,
      },
    });

This is My App component

import React, { useState } from "react";
    import {
      StyleSheet,
      Text,
      View,
      Dimensions,
      useWindowDimensions,
      SafeAreaView,
      StatusBar,
      RefreshControl,
    } from "react-native";
    import styled from "styled-components/native";
    import MapView from "react-native-maps";
    import { useSharedValue } from "react-native-reanimated";
    import { FlatList } from "react-native-gesture-handler";
    
    import BottomSheet from "./ActionSheet";
    import BottomButton from "./BottomButton";
    import SafeAreaWrapper from "./SafeAreaWrapper";
    import SearchBar from "./SearchBar";
    
    const { width, height } = Dimensions.get("screen");
    const api =
      "http://open-api.myhelsinki.fi/v1/events/?distance_filter=60.1699%2C24.9384%2C10&language_filter=en&limit=100";
    
    const initialRegion = {
      latitudeDelta: 15,
      longitudeDelta: 15,
      latitude: 60.1098678,
      longitude: 24.7385084,
    };
    
    export default function App() {
      const { width, height } = useWindowDimensions();
      const [loading, setLoading] = useState(false);
      const [data, setData] = React.useState([]);
    
      const updateState = async () => {
        try {
          const response = await fetch(api);
          const data = await response.json();
          setData(data.data);
        } catch (error) {
          console.log("failed to catch", error);
        }
      };
    
      React.useEffect(() => {
        updateState();
      }, []);
    
      const y = useSharedValue(0);
      return (
        <SafeAreaWrapper>
          <Container>
            <MapContent>
              <MapView style={styles.mapStyle} initialRegion={initialRegion} />
            </MapContent>
            <BottomSheet panY={y}>
              <Content>
                <SearchContainer>
                  <SearchBar placeholder={"write some thing"} />
                </SearchContainer>
                {data && data === undefined ? (
                  <Text>loading</Text>
                ) : (
                  <HeroFlatList
                    data={data}
                    showsVerticalScrollIndicator={false}
                    refreshControl={
                      <RefreshControl
                        enabled={true}
                        refreshing={loading}
                        onRefresh={updateState}
                      />
                    }
                    keyExtractor={(_, index) => index.toString()}
                    renderItem={({ item, index }) => {
                      const image = item?.description.images.map((img) => img.url);
                      const startDate = item?.event_dates?.starting_day;
    
                      return (
                        <EventContainer key={index}>
                          <EventImage
                            source={{
                              uri:
                                image[0] ||
                                "https://res.cloudinary.com/drewzxzgc/image/upload/v1631085536/zma1beozwbdc8zqwfhdu.jpg",
                            }}
                          />
                          <DescriptionContainer>
                            <Title ellipsizeMode="tail" numberOfLines={1}>
                              {item?.name?.en}
                            </Title>
                            <DescriptionText>
                              {item?.description?.intro ||
                                "No description available"}
                            </DescriptionText>
                            <DateText>{startDate}</DateText>
                          </DescriptionContainer>
                        </EventContainer>
                      );
                    }}
                  />
                )}
              </Content>
            </BottomSheet>
            <ButtonContainer>
              <BottomButton
                title={"Save"}
                onPress={() => {
                  console.log("jjj");
                }}
              />
            </ButtonContainer>
          </Container>
        </SafeAreaWrapper>
      );
    }
    
    const styles = StyleSheet.create({
      mapStyle: {
        width: width,
        height: height, // I DON'T KNOW HOW TO CONVERT THEM INTO STYLED COMPONENT
      },
    });
    
    const HeroFlatList = styled(FlatList).attrs({
      contentContainerStyle: {
        paddingTop: 20,
        paddingBottom: 2000, // BAD PRACTICE
        flexGrow: 1, //SEEMS LIKE IT DOES NOT WORK
      },
    })`
      height: 2000px; // BAD PRACTICE
    `;
    
    const MapContent = styled.View`
      flex: 1;
    `;
    
    const Content = styled.View`
      flex: 1;
      padding: 20px;
    `;
    
    const Container = styled.View`
      flex: 1;
    `;
    
    const ButtonContainer = styled.View`
      background-color: #fdfbfb; // My Button container
    `;
    
    const TextName = styled.Text`
      color: orange;
      font-weight: bold;
    `;
    
    const SearchContainer = styled.View`
      margin-bottom: 5px;
    `;
    
    const Title = styled.Text`
      font-size: 16px;
      font-weight: 700;
      margin-bottom: 5px;
    `;
    
    const DescriptionText = styled(Title)`
      font-size: 14px;
      opacity: 0.7;
    `;
    
    const DateText = styled(Title)`
      font-size: 14px;
      opacity: 0.8;
      color: #0099cc;
    `;
    
    const EventImage = styled.Image`
      width: 70px;
      height: 70px;
      border-radius: 70px;
      margin-right: 20px;
    `;
    
    const DescriptionContainer = styled.View`
      width: 200px;
    `;
    
    const EventContainer = styled.View`
      flex-direction: row;
      padding: 20px;
      margin-bottom: 10px;
      border-radius: 20px;
      background-color: rgba(0, 0, 0, 0.8);
    `;

0 Answers
Related