112 lines
2.8 KiB
TypeScript
112 lines
2.8 KiB
TypeScript
import { ThemedText } from "@/components/themed-text";
|
|
import { Colors } from "@/constants/theme";
|
|
import { useTheme } from "@/context/ThemeContext";
|
|
import React from "react";
|
|
import { Modal, Pressable, ScrollView, StyleSheet, View } from "react-native";
|
|
import { SafeAreaView } from "react-native-safe-area-context";
|
|
|
|
interface SelectionOption {
|
|
id: number | string;
|
|
label: string;
|
|
value: any;
|
|
}
|
|
|
|
interface SelectionModalProps {
|
|
visible: boolean;
|
|
onClose: () => void;
|
|
title: string;
|
|
options: SelectionOption[];
|
|
onSelect: (value: any) => void;
|
|
selectedValue: any;
|
|
}
|
|
|
|
export function SelectionModal({
|
|
visible,
|
|
onClose,
|
|
title,
|
|
options,
|
|
onSelect,
|
|
selectedValue,
|
|
}: SelectionModalProps) {
|
|
const { theme } = useTheme();
|
|
const isDark = theme === "dark";
|
|
const bg = isDark ? "#1C1C1E" : "#FFFFFF";
|
|
const text = isDark ? "#FFFFFF" : "#000000";
|
|
|
|
return (
|
|
<Modal
|
|
visible={visible}
|
|
transparent
|
|
animationType="slide"
|
|
onRequestClose={onClose}
|
|
>
|
|
<Pressable style={styles.overlay} onPress={onClose}>
|
|
<View />
|
|
</Pressable>
|
|
|
|
<View style={[styles.sheet, { backgroundColor: bg }]}>
|
|
<SafeAreaView edges={["bottom"]}>
|
|
<View style={styles.header}>
|
|
<ThemedText type="subtitle">{title}</ThemedText>
|
|
<Pressable onPress={onClose}>
|
|
<ThemedText style={{ color: Colors[theme].tint }}>
|
|
Done
|
|
</ThemedText>
|
|
</Pressable>
|
|
</View>
|
|
<ScrollView style={{ maxHeight: 300 }}>
|
|
{options.map((opt) => (
|
|
<Pressable
|
|
key={opt.id}
|
|
style={[
|
|
styles.option,
|
|
selectedValue === opt.value && {
|
|
backgroundColor: isDark ? "#333" : "#F0F0F0",
|
|
},
|
|
]}
|
|
onPress={() => {
|
|
onSelect(opt.value);
|
|
onClose();
|
|
}}
|
|
>
|
|
<ThemedText
|
|
style={{
|
|
fontWeight: selectedValue === opt.value ? "bold" : "normal",
|
|
}}
|
|
>
|
|
{opt.label}
|
|
</ThemedText>
|
|
</Pressable>
|
|
))}
|
|
</ScrollView>
|
|
</SafeAreaView>
|
|
</View>
|
|
</Modal>
|
|
);
|
|
}
|
|
|
|
const styles = StyleSheet.create({
|
|
overlay: {
|
|
flex: 1,
|
|
backgroundColor: "rgba(0,0,0,0.5)",
|
|
},
|
|
sheet: {
|
|
borderTopLeftRadius: 16,
|
|
borderTopRightRadius: 16,
|
|
padding: 16,
|
|
maxHeight: "60%",
|
|
},
|
|
header: {
|
|
flexDirection: "row",
|
|
justifyContent: "space-between",
|
|
alignItems: "center",
|
|
marginBottom: 16,
|
|
},
|
|
option: {
|
|
paddingVertical: 16,
|
|
paddingHorizontal: 12,
|
|
borderBottomWidth: StyleSheet.hairlineWidth,
|
|
borderBottomColor: "#ccc",
|
|
},
|
|
});
|