import { MaterialIcons } from "@expo/vector-icons"; import { useState, useRef } from "react"; import Button from "@/components/Button"; import { View, Text, TouchableOpacity, Dimensions, Modal, type StyleProp, type ViewStyle, Pressable, type DimensionValue, ScrollView, type ColorValue, } from "react-native"; interface Item { name: string; id: string; color?: ColorValue; iconColor?: ColorValue; disabled?: boolean; icon?: keyof typeof MaterialIcons.glyphMap; onPress: () => Promise | void; } interface DropdownPosition { top: number; left: number; } interface Props { data: Array; containerStyle?: StyleProp; width?: DimensionValue; height?: DimensionValue; iconColor?: ColorValue; iconSize?: number; icon: keyof typeof MaterialIcons.glyphMap; margin?: { top?: DimensionValue; bottom?: DimensionValue; left?: DimensionValue; right?: DimensionValue; }; dropdown?: { width?: number; maxHeight?: number; margin?: { top?: DimensionValue; bottom?: DimensionValue; left?: DimensionValue; right?: DimensionValue; }; }; } const minimumMargin = 15; export default function Dropdown({ data, containerStyle, height, width, icon, iconSize = 25, iconColor = "#575DB5", dropdown, margin = {}, }: Props) { const [visible, setVisible] = useState(false); const [dropdownPosition, setDropdownPosition] = useState({ top: 0, left: 0, }); const dropdownButtonRef = useRef(null); const screen = Dimensions.get("window"); const screenWidth = screen.width; const dropdownWidth = dropdown?.width || screenWidth * 0.4; return ( { if (visible) { setVisible(false); } else { dropdownButtonRef.current?.measure( ( _fx: number, _fy: number, _elementWidth: number, elementHeight: number, px: number, py: number, ) => { let left = px; const spaceBelow = screen.height - (py + elementHeight); const spaceAbove = py; const dropdownHeight = (data.length * 50 > (dropdown?.maxHeight || 325) ? dropdown?.maxHeight || 325 : data.length * 50) + (typeof height === "number" ? height : 40) + minimumMargin; let top = py + elementHeight; if (spaceAbove > spaceBelow && spaceAbove > dropdownHeight) { top = py - dropdownHeight; } if (left < minimumMargin) { left = minimumMargin; } else if (left + dropdownWidth > screenWidth - minimumMargin) { left = screenWidth - dropdownWidth - minimumMargin; } setDropdownPosition({ top: top, left: left }); setVisible(true); }, ); } }} > setVisible(false)} > {data.map((item) => (