import type { ReactElement } from 'react'; import type { ImageSourcePropType } from 'react-native'; import type { BottomTabNavigationOptions } from '@react-navigation/bottom-tabs'; import type { NativeBottomTabNavigationOptions } from '@react-navigation/bottom-tabs/unstable'; /** * Structural mirror of the `image` arm of `NativeBottomTabIcon` from * `@react-navigation/bottom-tabs/unstable`. Declared locally so * `@cdx-ui/components` carries no runtime React Navigation dependency — * the drift guards below fail the build if the upstream shape changes. */ export interface ForgeNativeBottomTabIcon { type: 'image'; /** Metro-resolved asset (e.g. a static `require('./icon.png')`). */ source: ImageSourcePropType; /** * Render as a template image tinted with the tab bar's active/inactive * tint color. iOS-only flag — Android always tints tab icons. */ tinted?: boolean; } /** * The value `forgeTabIcon()` returns — callable as `tabBarIcon` on **both** * React Navigation bottom tab navigators. The intersection carries both call * signatures; the platform-split implementation guarantees the matching one * at runtime: * * - `createBottomTabNavigator` (web/JS) invokes it with * `{ focused, color, size }` and renders the returned element. * - `createNativeBottomTabNavigator` (iOS/Android) invokes it with * `{ focused }` and receives a native icon descriptor. */ export type ForgeTabBarIcon = ((props: { focused: boolean; color: string; size: number; }) => ReactElement) & ((props: { focused: boolean }) => ForgeNativeBottomTabIcon); /** * Compile-time drift guards (see `useForgeBottomTabScreenOptions` for the * pattern): `ForgeTabBarIcon` must stay assignable to the `tabBarIcon` * option of both navigators. The `null as any` casts keep the runtime * values `null` so tree-shakers eliminate them entirely. */ const _rnDriftGuardWeb: BottomTabNavigationOptions['tabBarIcon'] = // eslint-disable-next-line @typescript-eslint/no-explicit-any null as any as ForgeTabBarIcon; const _rnDriftGuardNative: NativeBottomTabNavigationOptions['tabBarIcon'] = // eslint-disable-next-line @typescript-eslint/no-explicit-any null as any as ForgeTabBarIcon;