/** * Minimal react-native mock for Vitest. * Provides lightweight stubs for components and APIs used in the mobile app. */ import React from 'react'; function createMockComponent(name: string) { const Component = (props: Record) => React.createElement(name, props, props.children as React.ReactNode); Component.displayName = name; return Component; } export const View = createMockComponent('View'); export const Text = createMockComponent('Text'); export const TextInput = createMockComponent('TextInput'); export const Pressable = createMockComponent('Pressable'); export const ScrollView = createMockComponent('ScrollView'); export const Modal = createMockComponent('Modal'); export const Image = createMockComponent('Image'); export const FlatList = createMockComponent('FlatList'); export const TouchableOpacity = createMockComponent('TouchableOpacity'); export const SafeAreaView = createMockComponent('SafeAreaView'); export const ActivityIndicator = createMockComponent('ActivityIndicator'); export const Alert = { alert: () => {}, }; export const StyleSheet = { create: >(styles: T): T => styles, flatten: (style: unknown) => style, hairlineWidth: 1, }; export const Platform = { OS: 'ios' as const, Version: '17.0', select: (specifics: Record) => specifics.ios ?? specifics.default, }; export const AppState = { currentState: 'active', addEventListener: (_type: string, _handler: unknown) => ({ remove: () => {}, }), }; export const Dimensions = { get: () => ({ width: 375, height: 812, scale: 2, fontScale: 1 }), addEventListener: () => ({ remove: () => {} }), }; export const Keyboard = { dismiss: () => {}, addListener: () => ({ remove: () => {} }), }; export const Linking = { openURL: async () => {}, canOpenURL: async () => true, getInitialURL: async () => null, addEventListener: () => ({ remove: () => {} }), }; export const Animated = { View: createMockComponent('Animated.View'), Text: createMockComponent('Animated.Text'), Image: createMockComponent('Animated.Image'), Value: class { _value: number; constructor(val: number) { this._value = val; } setValue(val: number) { this._value = val; } interpolate() { return this; } }, timing: () => ({ start: (cb?: () => void) => cb?.() }), spring: () => ({ start: (cb?: () => void) => cb?.() }), parallel: () => ({ start: (cb?: () => void) => cb?.() }), sequence: () => ({ start: (cb?: () => void) => cb?.() }), event: () => () => {}, }; export default { View, Text, TextInput, Pressable, ScrollView, Modal, Image, FlatList, TouchableOpacity, SafeAreaView, ActivityIndicator, Alert, StyleSheet, Platform, AppState, Dimensions, Keyboard, Linking, Animated, };