实现首页功能,添加体育项目和今日比赛数据的加载,更新国际化文本,新增选择和日历模态框组件
This commit is contained in:
111
components/selection-modal.tsx
Normal file
111
components/selection-modal.tsx
Normal file
@@ -0,0 +1,111 @@
|
||||
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",
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user