skip to Main Content

I have a react app with a group of components. I have a group of cards and a popup. What I want is, that whenever a user clicks on a card it should show the popup.
My current structure is:

<CardWrapper>
   <Popup></Popup>
   <Card>...</Card>
   <Card>...</Card>
   <Card>...</Card>
</CardWrapper>

Right now the CardWrapper position is relative and the Popup position is absolute. And whenever a user clicks on a card it will show the Popup.
But, right now the position to display the Popup is relative to Cardwrapper.
no matter where the user clicks the Popup will always be displayed as

enter image description here

But, I want it to be relative to the card clicked on. like:

if the user clicks on card 2

enter image description here

or if the user clicks on card 4

enter image description here

I don’t know how to achieve that. My popup should not be inside my cards. Is there any way to achieve this?

2

Answers


  1. If you need a component to be in the parent but rendered in the child you can pass it as a prop,

    ie

    const popup = () => {
      return <Popup/>
    }
    
    const Parent = () => {
    return (
      <CardWrapper>
       <Card popup={popup}>...</Card>
       <Card popup={popup}>...</Card>
       <Card popup={popup}>...</Card>
      </CardWrapper>
    )
    

    Then the Card can render the popup and position is absolutely relative to itself

    Login or Signup to reply.
  2. Ahh , finally thanks to your question , i learned so many things. ive finally achieved what exactly your question is

    THis is the working solution Expo link

    import * as React from 'react';
    import { Text, View, StyleSheet ,FlatList ,TouchableOpacity } from 'react-native';
    import Constants from 'expo-constants';
    import {useRef , createRef , useState} from 'react'
    
    
    export default function App() {
    
      const data = [1,2,3,4,5,6,7,8,9,10];
    
      const [topH,setTop] = useState(0)
    
      const elementsRef = useRef(data.map(() => createRef()));
    
      const onCardPress = (item,newRef) => {
    
     newRef?.current?.measureInWindow( (fx, fy, width, height, px, py) => {
                console.log('Component width is: ' + width)
                console.log('Component height is: ' + height)
                console.log('X offset to frame: ' + fx)
                console.log('Y offset to frame: ' + fy)
                console.log('X offset to page: ' + px)
                console.log('Y offset to page: ' + py)
    
                setTop(fy)
            })        
      }
    
    const renderEach = ({item,index}) => {
    
    
      return(
        <TouchableOpacity onPress={() => onCardPress (item,elementsRef?.current[index])} style={styles.eachCard} ref={elementsRef?.current[index]} >
        <Text>{item}</Text>
        </TouchableOpacity>
      )
    }
    
    const Popup = () => {
      if(topH === 0 ){
        return null
      }
      return(
        <View style={{backgroundColor:'yellow' , position:'absolute',zIndex:3 , height:60,width:60 , right:30 , top:topH}} >
        <Text> popup </Text>
        </View>
      )
    }
    
      return (
        <View style={styles.container}>
          <View style={{flex:1}} >
          <Popup />
          <FlatList 
          style={{flex:1}}
          data={data}
          renderItem={renderEach}
           />
          </View>
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        // justifyContent: 'center',
        paddingTop: Constants.statusBarHeight,
        backgroundColor: '#ecf0f1',
        padding: 8,
      },
      eachCard:{
        height:100,
        margin:10,
        justifyContent:'center',
        alignItems:'center',
        backgroundColor:'#850D5F'
      },
      paragraph: {
        margin: 24,
        fontSize: 18,
        fontWeight: 'bold',
        textAlign: 'center',
      },
    });

    so here basically if you see we have dynamic refs and also newRef?.current?.measureInWindow is the one which gives us layout position wrt to Y which is relative to frame, and im setting the same in top position

    Please feel free for doubts. also see the results of what ive achieved. hope its your doubt

    enter image description here

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search