import React, { useCallback } from 'react'; import { KeyboardAvoidingView, Modal as RNModal, Platform, Pressable, ScrollView, StyleSheet, Text, View, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { COLORS, FONT_SIZE, SPACING } from '../constants'; import Toast from './Toast'; interface Props { visible: boolean; title: string; onClose: () => void; children: React.ReactNode; // 全屏表单模式:顶部 取消/标题/保存 导航栏 + 滚动内容 + 键盘避让。 // 所有含输入框的表单弹窗统一走全屏,符合 iOS/Android 主流「新建页」交互。 // (此前的底部 sheet 分支在 v0.7.1 全面转全屏后已无调用方,v0.11.8 删除; // 顺带去掉了 sheet 的「轻扫即关」——表单填一半时被误滑直接丢弃,且没有二次确认) saveLabel?: string; // 右上角保存按钮文字(默认「保存」) onSave?: () => void; // 存在则右上角显示保存按钮 saveDisabled?: boolean; } export default function Modal({ visible, title, onClose, children, saveLabel = '保存', onSave, saveDisabled, }: Props) { const close = useCallback(() => { onClose(); }, [onClose]); return ( {/* 顶部导航栏:左取消 / 中标题 / 右保存(可选) */} 取消 {title} {onSave ? ( {saveLabel} ) : ( )} {children} {/* 表单在自己的 Dialog 窗口里,提示层必须挂在同一窗口内才盖得住(App 根的那层在它下面) */} ); } const styles = StyleSheet.create({ fullRoot: { flex: 1, backgroundColor: COLORS.background, }, fullHeader: { flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', paddingHorizontal: SPACING.md, // 导航按钮的触摸高度靠 paddingVertical 撑到 44dp 上下 paddingVertical: SPACING.md, borderBottomWidth: StyleSheet.hairlineWidth, borderBottomColor: COLORS.border, }, fullHeaderBtn: { minWidth: 56, alignItems: 'center', paddingVertical: SPACING.xs, }, fullCancel: { fontSize: FONT_SIZE.md, color: COLORS.textSecondary, fontWeight: '600', }, fullTitle: { fontSize: FONT_SIZE.lg, fontWeight: '800', color: COLORS.text, flexShrink: 1, textAlign: 'center', }, fullSave: { fontSize: FONT_SIZE.md, color: COLORS.accent, fontWeight: '700', }, fullSaveDisabled: { opacity: 0.4, }, fullBody: { flex: 1, }, fullScroll: { flex: 1, }, fullContent: { padding: SPACING.lg, paddingBottom: SPACING.xxl, }, });