import { Ionicons } from "@expo/vector-icons"; import { useState } from "react"; import { Modal, Pressable, ScrollView, StyleSheet, Text, View, } from "react-native"; import { fonts, radii, spacing } from "@/constants/theme"; import { useAppTheme } from "@/contexts/ThemeContext"; export type SelectOption = { label: string; value: string; }; type SelectFieldProps = { label: string; placeholder: string; value: string; options: SelectOption[]; disabled?: boolean; onValueChange: (value: string) => void; }; export function SelectField({ label, placeholder, value, options, disabled, onValueChange, }: SelectFieldProps) { const { colors } = useAppTheme(); const [open, setOpen] = useState(false); const selected = options.find((option) => option.value === value); return ( {label} setOpen(true)} style={({ pressed }) => [ styles.trigger, { borderColor: colors.borderGlass, backgroundColor: colors.cardGlass, }, disabled && styles.triggerDisabled, pressed && !disabled && styles.triggerPressed, ]} > {selected?.label ?? placeholder} setOpen(false)} transparent visible={open} > setOpen(false)}> event.stopPropagation()} > {label} setOpen(false)}> Done {options.map((option) => { const isSelected = option.value === value; return ( { onValueChange(option.value); setOpen(false); }} style={({ pressed }) => [ styles.option, isSelected && { backgroundColor: colors.muted }, pressed && styles.optionPressed, ]} > {option.label} {isSelected ? ( ) : null} ); })} ); } const styles = StyleSheet.create({ wrapper: { gap: spacing.sm, }, label: { fontSize: 14, fontFamily: fonts.bodyMedium, }, trigger: { minHeight: 44, borderWidth: 1, borderRadius: radii.md, paddingHorizontal: spacing.md, flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: spacing.sm, }, triggerDisabled: { opacity: 0.55, }, triggerPressed: { opacity: 0.92, }, triggerText: { flex: 1, fontSize: 14, fontFamily: fonts.body, }, backdrop: { flex: 1, justifyContent: "flex-end", backgroundColor: "rgba(0, 0, 0, 0.45)", }, sheet: { maxHeight: "70%", borderTopLeftRadius: radii.xl, borderTopRightRadius: radii.xl, paddingBottom: spacing.lg, }, sheetHeader: { flexDirection: "row", alignItems: "center", justifyContent: "space-between", paddingHorizontal: spacing.md, paddingVertical: spacing.md, borderBottomWidth: StyleSheet.hairlineWidth, }, sheetTitle: { fontSize: 16, fontFamily: fonts.bodySemiBold, }, done: { fontSize: 15, fontFamily: fonts.bodyMedium, }, option: { minHeight: 48, paddingHorizontal: spacing.md, flexDirection: "row", alignItems: "center", justifyContent: "space-between", gap: spacing.sm, }, optionPressed: { opacity: 0.9, }, optionText: { flex: 1, fontSize: 15, fontFamily: fonts.body, }, optionTextSelected: { fontFamily: fonts.bodySemiBold, }, });