Relative View overlay in web - React Native

17 Views Asked by At

I recently crafted a Dropdown component in React Native. However, I faced a challenge where the Flatlist content ended up positioned beneath the subsequent Dropdown component. This positioning issue prompted me to review my code. Here's the code snippet for reference:

Dropdown Component:

export const DropDown = ({
  className,
  setSelectedValue,
  label,
  defaultValue,
  padding,
  options,
}) => {
  const [value, setValue] = useState({});
  const [show, setShow] = useState(false);
  const labelTranslateY = new Animated.Value(
    value?.label || defaultValue ? -7 : 11
  );

  const handleToggle = () => {
    setShow((prev) => !prev);
  };

  const handlePress = (item) => {
    setValue(item);
    setSelectedValue(item);
    setShow((prev) => !prev);
  };

  const renderItem = ({ item }) => (
    <TouchableOpacity onPress={() => handlePress(item)}>
      <View
        style={{}}
        className=" hover:bg-black cursor-pointer border-b border-gray-600/25 w-full flex flex-wrap flex-row "
      >
        <Text className="flex-1 py-1 px-2 text-left text-base  ">
          {item?.label || ""}
        </Text>
      </View>
    </TouchableOpacity>
  );

  return (
    <View
      className={`w-full h-full z-10 border-2 border-[#A7A7A7] ${
        value?.label || defaultValue ? `bg-white` : `bg-[#E8E8E8]`
      }  rounded-md flex flex-row justify-between items-center p y-1 px-2 ${className}`}
    >
      <TouchableOpacity className="w-full z-10" onPress={handleToggle}>
        <View className="w-full flex z-10 flex-row justify-between items-center">
          <Text className="text-xs z-10">{value?.label || defaultValue}</Text>
          <FontAwesomeIcon
            icon={show ? faCaretUp : faCaretDown}
            style={{ width: "1.5rem", height: "1.5rem", color: "#A7A7A7" }}
          />
        </View>
      </TouchableOpacity>
      <Animated.Text
        style={[
          styles.label,
          {
            transform: [{ translateY: labelTranslateY }],
            backgroundColor:
              value?.label || defaultValue ? "white" : "transparent",
          },
        ]}
      >
        {label}
      </Animated.Text>

      {show ? (
        <View
          className={
            `${Platform.OS ==="web" ? "w-full" : "w-[106%]"} z-10 rounded-md overflow-hidden absolute  right-0 top-[100%]`
          }
        >
          <FlatList
            data={options}
            className=" w-full border z-10 border-gray-300 rounded-sm  bg-gray-100 shadow-2xl "
            renderItem={renderItem}
            keyExtractor={(item, index) => item.value}
          />
        </View>
      ) : (
        <View></View>
      )}
    </View>
  );
};

index.js

const OverlapExample = () => {
  const [filters, setFilters] = useState({});

  const options = [
    { label: "jjjjj", value: "1" },
    { label: "kkkkk", value: "2" },
    { label: "lllll", value: "3" },
  ];

  const structData = [
    {
      options: options,
      value: 55,
      class: "h-12 p-1 w-1/4",
      name: "counter",
      label: "Counter",
    },
    {
      options: options,
      value: 55,
      class: "h-12 p-1 w-1/4",
      name: "category",
      label: "Category",
    },
    {
      options: options,
      value: 55,
      class: "h-12 p-1 w-1/4",
      name: "collection",
      label: "Collection",
    },
  ];

  const handleChange = (e, name) => {
    setFilters((prev) => {
      const newObject = { ...prev };
      newObject[`${name}`] = e;

      return newObject;
    });
  };

  return (
    <View className="w-full">
      {structData?.map((item, index) => {
        return (
          <View key={index} className={`${item.class}`}>
            <DropDown
              setSelectedValue={(e) => handleChange(e, item.name)}
              options={item.options}
              label={item.label}
              className={`border-2 border-[#A7A7A7] rounded-md py-1 px-2`}
              defaultValue={item.label || ""}
            />
          </View>
        );
      })}
    </View>
  );
};

Result:

enter image description here

enter image description here

I'm currently exploring ways to address this problem and ensure that the Flatlist content properly aligns with the Dropdown component as intended in the layout.

1

There are 1 best solutions below

0
Aqeel Ahmad On BEST ANSWER

Just add greater zIndex property to top level dropdown and decrease it to lower level dropdown.

Example

counter dropdown have : zIndex: 10000

category dropdown have : zIndex: 1000

collection dropdown have : zIndex: 100

hope it will help.