import type { PropsWithChildren, ReactNode } from "react"; import { ActivityIndicator, Pressable, ScrollView, StyleSheet, Text, TextInput, View, type StyleProp, type TextInputProps, type ViewStyle, } from "react-native"; import { SafeAreaView } from "react-native-safe-area-context"; import { colors, radius, spacing, typography } from "@/lib/theme"; import { t } from "@/lib/i18n"; export function Screen({ children, scroll = true, style, }: PropsWithChildren<{ scroll?: boolean; style?: StyleProp }>) { const content = scroll ? ( {children} ) : ( {children} ); return ( {content} ); } export function Title({ children }: { children: ReactNode }) { return {children}; } export function Heading({ children }: { children: ReactNode }) { return {children}; } export function Body({ children, muted = false }: { children: ReactNode; muted?: boolean }) { return {children}; } export function Small({ children }: { children: ReactNode }) { return {children}; } export function Card({ children, onPress, style, }: PropsWithChildren<{ onPress?: () => void; style?: StyleProp }>) { if (onPress) { return ( [styles.card, style, pressed && { opacity: 0.85 }]} > {children} ); } return {children}; } export function Button({ label, onPress, variant = "primary", disabled = false, loading = false, }: { label: string; onPress: () => void; variant?: "primary" | "secondary" | "ghost" | "danger"; disabled?: boolean; loading?: boolean; }) { const bg = variant === "primary" ? colors.primary : variant === "danger" ? colors.dangerSoft : variant === "secondary" ? colors.primarySoft : "transparent"; const fg = variant === "primary" ? "#fff" : variant === "danger" ? colors.danger : colors.primaryDark; return ( [ styles.button, { backgroundColor: bg, opacity: disabled ? 0.5 : pressed ? 0.85 : 1 }, variant === "ghost" && { borderWidth: 1, borderColor: colors.border }, ]} > {loading ? ( ) : ( {label} )} ); } export function Input(props: TextInputProps) { return ( ); } export function Tag({ label, tone = "neutral", }: { label: string; tone?: "neutral" | "success" | "warning" | "danger" | "accent"; }) { const palette = { neutral: { bg: colors.surfaceAlt, fg: colors.textMuted }, success: { bg: colors.primarySoft, fg: colors.primaryDark }, warning: { bg: colors.warningSoft, fg: colors.warning }, danger: { bg: colors.dangerSoft, fg: colors.danger }, accent: { bg: colors.accentSoft, fg: colors.accent }, }[tone]; return ( {label} ); } export function ProgressBar({ progress, tone = "primary", }: { progress: number; tone?: "primary" | "warning"; }) { const clamped = Math.max(0, Math.min(1, progress)); const over = progress > 1; return ( ); } export function LoadingView() { return ( {t("common.loading")} ); } export function ErrorView({ message, onRetry }: { message?: string; onRetry?: () => void }) { return ( {message ?? t("common.error")} {onRetry &&