import { Ionicons } from "@expo/vector-icons"; import React, { ReactNode } from "react"; import { ActivityIndicator, Modal, Pressable, TextInput as RNTextInput, ScrollView, StyleProp, StyleSheet, Text, TextStyle, TouchableOpacity, View, ViewStyle, } from "react-native"; import { Device } from "../api/types"; import { colors } from "./theme"; export function Screen({ children, contentContainerStyle, }: { children: ReactNode; contentContainerStyle?: StyleProp; }) { return ( {children} ); } export function Card({ children, style, }: { children: ReactNode; style?: StyleProp; }) { return {children}; } export function H1({ children }: { children: ReactNode }) { return {children}; } export function H2({ children }: { children: ReactNode }) { return {children}; } export function Body({ children, style, }: { children: ReactNode; style?: StyleProp; }) { return {children}; } export function Muted({ children, style, }: { children: ReactNode; style?: StyleProp; }) { return {children}; } export function Pill({ label, tone = "neutral", }: { label: string; tone?: "neutral" | "good" | "attention"; }) { const backgroundColor = tone === "good" ? colors.surfaceVariant : tone === "attention" ? colors.primaryContainer : colors.surfaceVariant; const borderColor = tone === "attention" ? colors.primary : colors.outline; const textColor = tone === "attention" ? colors.onPrimary : colors.onSurface; return ( {label} ); } export function Row({ left, right }: { left: ReactNode; right?: ReactNode }) { return ( {left} {right ? {right} : null} ); } export function Divider() { return ; } export function ActionRow({ title, subtitle, onPress, right, }: { title: string; subtitle?: string; onPress?: () => void; right?: ReactNode; }) { return ( [ styles.actionRow, pressed && onPress ? styles.actionRowPressed : undefined, ]} > {title} {subtitle ? ( {subtitle} ) : null} {right ? ( {right} ) : null} ); } // ───────────────────────────────────────────────────────────────────────────── // Dialog / Modal Components // ───────────────────────────────────────────────────────────────────────────── export type DialogOption = { label: string; onPress: () => void; destructive?: boolean; }; /** * A selection dialog that shows a list of options to choose from. */ export function SelectDialog({ visible, title, options, onClose, }: { visible: boolean; title: string; options: DialogOption[]; onClose: () => void; }) { return ( {title} {options.map((option, index) => ( {option.label} ))} Cancel ); } /** * A confirmation dialog with a message and OK/Cancel buttons. */ export function ConfirmDialog({ visible, title, message, confirmLabel = "Okay", cancelLabel = "Cancel", onConfirm, onCancel, destructive = false, }: { visible: boolean; title: string; message: string; confirmLabel?: string; cancelLabel?: string; onConfirm: () => void; onCancel: () => void; destructive?: boolean; }) { return ( {title} {message} {cancelLabel} {confirmLabel} ); } /** * A prompt dialog with an input field, message, and Cancel/Submit buttons. */ export function PromptDialog({ visible, title, message, onClose, onSubmit, initialValue = "", }: { visible: boolean; title: string; message: string; onClose: () => void; onSubmit: (value: string) => void; initialValue?: string; }) { const [value, setValue] = React.useState(initialValue); React.useEffect(() => { setValue(initialValue); }, [initialValue, visible]); return (

{title}

{message}