import type { PropsWithChildren } from 'react'; import type { ColorValue, ImageSourcePropType, StyleProp, TextStyle, ViewStyle } from 'react-native'; import type { TabsHostProps, TabsScreenProps } from 'react-native-screens'; import type { SFSymbol } from 'sf-symbols-typescript'; import type { DefaultRouterOptions, ParamListBase, RouteProp, ScreenListeners, TabNavigationState } from '../react-navigation/native'; import type { ScreenProps } from '../useScreens'; import type { ErrorBoundaryProps } from '../views/Try'; /** * Event map for `NativeTabs` navigation events. * Only `tabPress` is currently supported. */ export type NativeTabNavigationEventMap = { tabPress: { data: { __internalTabsType: 'native'; /** * `true` when the native side prevented the selection because the target * tab is `disabled`. The event is still emitted so listeners are notified, * but no navigation occurs. */ isPrevented: boolean; }; canPreventDefault: false; }; }; export type NativeScreenProps = Partial>; /** * Props passed to the underlying tab host implementation in `react-native-screens`. */ export type NativeTabsHostNativeProps = Partial>; export interface NativeTabOptions extends DefaultRouterOptions { /** * @platform android * @platform iOS */ icon?: SymbolOrImageSource; /** * @platform android * @platform iOS */ selectedIcon?: SymbolOrImageSource; /** * @platform android * @platform iOS * @platform web */ title?: string; /** * @platform android * @platform iOS * @platform web */ badgeValue?: string; /** * @platform android * @platform iOS * @platform web */ selectedLabelStyle?: NativeTabsLabelStyle; /** * @platform android * @platform iOS * @platform web */ labelStyle?: NativeTabsLabelStyle; /** * @platform iOS */ role?: NativeTabsTabBarItemRole; /** * @platform android * @platform iOS */ selectedIconColor?: ColorValue; /** * @platform iOS */ selectedBadgeBackgroundColor?: ColorValue; /** * @platform android * @platform iOS * @platform web */ badgeBackgroundColor?: ColorValue; /** * @platform android * @platform web */ badgeTextColor?: ColorValue; /** * @platform android * @platform iOS * @platform web */ backgroundColor?: ColorValue; /** * @platform iOS */ blurEffect?: NativeTabsBlurEffect; /** * @platform iOS */ shadowColor?: ColorValue; /** * @platform android * @platform iOS */ iconColor?: ColorValue; /** * @platform android */ tintColor?: ColorValue; /** * @platform iOS */ disableTransparentOnScrollEdge?: boolean; /** * @platform iOS */ titlePositionAdjustment?: { horizontal?: number; vertical?: number; }; /** * @platform iOS */ selectedTitlePositionAdjustment?: { horizontal?: number; vertical?: number; }; /** * @platform android * @platform web */ indicatorColor?: ColorValue; /** * @platform android */ rippleColor?: ColorValue; /** * @platform android */ disableIndicator?: boolean; /** * @platform android */ labelVisibilityMode?: NativeTabsTabBarItemLabelVisibilityMode; /** * @platform android * @platform iOS * @platform web */ hidden?: boolean; /** * @platform android * @platform iOS */ disabled?: boolean; /** * @platform android * @platform iOS */ tabBarItemTestID?: string; /** * @platform android * @platform iOS */ tabBarItemAccessibilityLabel?: string; /** * @platform iOS */ specialEffects?: TabsScreenProps['specialEffects']; /** * @platform android * @platform iOS */ nativeProps?: NativeScreenProps; /** * @platform android * @platform iOS */ disableAutomaticContentInsets?: boolean; /** * @platform android * @platform iOS */ contentStyle?: Pick; } /** * How an image-based icon is tinted on iOS: `template` lets the tab bar recolor the icon, * `original` keeps the image's own colors. SF Symbols are always tinted by the system. * @platform ios */ export type IconRenderingMode = 'template' | 'original'; export type SymbolOrImageSource = { /** * The name of the SF Symbol to use as an icon. * @platform iOS */ sf?: SFSymbol; /** * The name of the iOS asset catalog image to use as an icon. * @platform iOS */ xcasset?: string; /** * The name of the drawable resource to use as an icon. * @platform android */ drawable?: string; } | { /** * The image source to use as an icon. */ src?: ImageSourcePropType | Promise; /** * Controls how the icon is rendered on iOS. * @platform ios * @default 'template' */ renderingMode?: IconRenderingMode; }; export type NativeTabsLabelStyle = Pick; export declare const SUPPORTED_BLUR_EFFECTS: readonly ["none", "systemDefault", "extraLight", "light", "dark", "regular", "prominent", "systemUltraThinMaterial", "systemThinMaterial", "systemMaterial", "systemThickMaterial", "systemChromeMaterial", "systemUltraThinMaterialLight", "systemThinMaterialLight", "systemMaterialLight", "systemThickMaterialLight", "systemChromeMaterialLight", "systemUltraThinMaterialDark", "systemThinMaterialDark", "systemMaterialDark", "systemThickMaterialDark", "systemChromeMaterialDark"]; /** * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uiblureffect/style) */ export type NativeTabsBlurEffect = (typeof SUPPORTED_BLUR_EFFECTS)[number]; export interface NativeTabsProps extends PropsWithChildren { /** A component to render when an individual tab screen throws an error. */ unstable_screenErrorBoundary?: React.ComponentType; /** * The style of the every tab label in the tab bar. */ labelStyle?: StyleProp | { default?: StyleProp; selected?: StyleProp; }; /** * The color of every tab icon in the tab bar. */ iconColor?: ColorValue | { default?: ColorValue; selected?: ColorValue; }; /** * The tint color of the tab icon. * * Can be overridden by icon color and label color for each tab individually. */ tintColor?: ColorValue; /** * The background color of the tab bar. */ backgroundColor?: ColorValue; /** * The background color of every badge in the tab bar. */ badgeBackgroundColor?: ColorValue; /** * When set to `true`, hides the tab bar. * * @default false */ hidden?: boolean; /** * Specifies the minimize behavior for the tab bar. * * Available starting from iOS 26. * * The following values are currently supported: * * - `automatic` - resolves to the system default minimize behavior * - `never` - the tab bar does not minimize * - `onScrollDown` - the tab bar minimizes when scrolling down and * expands when scrolling back up * - `onScrollUp` - the tab bar minimizes when scrolling up and expands * when scrolling back down * * @see The supported values correspond to the official [Apple documentation](https://developer.apple.com/documentation/uikit/uitabbarcontroller/minimizebehavior). * * @default automatic * * @platform iOS 26+ */ minimizeBehavior?: NativeTabsTabBarMinimizeBehavior; /** * The blur effect applied to the tab bar. * * @platform iOS */ blurEffect?: NativeTabsBlurEffect; /** * The color of the shadow. * * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uibarappearance/shadowcolor) * * @platform iOS */ shadowColor?: ColorValue; /** * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uitabbaritem/titlepositionadjustment) * * @platform iOS */ titlePositionAdjustment?: { horizontal?: number; vertical?: number; }; /** * When set to `true`, the tab bar will not become transparent when scrolled to the edge. * * @platform iOS */ disableTransparentOnScrollEdge?: boolean; /** * When set to `true`, enables the sidebarAdaptable tab bar style on iPadOS and macOS. This prop has no effect on iPhone. * * @platform iOS 18+ */ sidebarAdaptable?: boolean; /** * Disables the active indicator for the tab bar. * * @platform android */ disableIndicator?: boolean; /** * The behavior when navigating back with the back button. * * @platform android */ backBehavior?: 'none' | 'initialRoute' | 'history'; /** * The visibility mode of the tab item label. * * @see [Material Components documentation](https://github.com/material-components/material-components-android/blob/master/docs/components/BottomNavigation.md#making-navigation-bar-accessible) * * @platform android */ labelVisibilityMode?: NativeTabsTabBarItemLabelVisibilityMode; /** * The color of the ripple effect when the tab is pressed. * * @platform android */ rippleColor?: ColorValue; /** * The color of the tab indicator. * * @platform android * @platform web */ indicatorColor?: ColorValue; /** * The color of the badge text. * * @platform android * @platform web */ badgeTextColor?: ColorValue; /** * When `true`, the tab bar lifts above the keyboard (input method editor, or IME) instead of being overlaid by it. By default, the keyboard overlays the tab bar. * * Requires `windowSoftInputMode="adjustResize"`. Has no effect on Android API levels earlier than 30 (Android 11). * * @default false * @platform android */ tabBarRespectsIMEInsets?: boolean; /** * Listeners for navigation events on all tabs. * * Supported events: * - `tabPress` - called when a tab is pressed * - `focus` - called when the screen comes into focus * - `blur` - called when the screen loses focus * * @example * ```tsx * { * console.log('Any tab pressed'); * }, * }} * > * ... * * ``` */ screenListeners?: ScreenListeners, NativeTabNavigationEventMap> | ((prop: { route: RouteProp; }) => ScreenListeners, NativeTabNavigationEventMap>); /** * Props passed to the underlying native tab host implementation in `react-native-screens`. * Use this to configure props that are not directly exposed by Expo Router. * * > **Note**: This is an unstable API and may change or be removed in minor versions. * * @platform android * @platform ios */ unstable_nativeProps?: NativeTabsHostNativeProps; } export interface InternalNativeTabsProps extends NativeTabsProps { nonTriggerChildren?: React.ReactNode; } export interface OnTabChangeEventPayload { /** * The route key of the tab the native side has just selected. */ selectedKey: string; /** * The provenance value reported by the native side for this selection. * * The navigator echoes this back via `navStateRequest.baseProvenance` on * subsequent JS-driven updates so the native side can distinguish stale * updates from fresh ones. See `TabsHostNavStateRequest` in * `react-native-screens` for the full contract. */ provenance: number; isNativeAction: boolean; /** * Whether the native side prevented this selection because the target tab is * `disabled`. When `true`, the navigator emits `tabPress` but skips navigation. * * @default false */ isPrevented?: boolean; } export interface NativeTabsViewProps extends Omit { focusedIndex: number; /** * Provenance counter associated with the currently rendered `focusedIndex`. */ provenance: number; tabs: NativeTabsViewTabItem[]; onTabChange: (event: OnTabChangeEventPayload) => void; } export interface NativeTabsViewTabItem { options: NativeTabOptions; routeKey: string; name: string; contentRenderer: () => React.ReactNode; } export declare const SUPPORTED_TAB_BAR_ITEM_LABEL_VISIBILITY_MODES: readonly ["auto", "selected", "labeled", "unlabeled"]; /** * @see [Material Components documentation](https://github.com/material-components/material-components-android/blob/master/docs/components/BottomNavigation.md#making-navigation-bar-accessible) * * @platform android */ export type NativeTabsTabBarItemLabelVisibilityMode = (typeof SUPPORTED_TAB_BAR_ITEM_LABEL_VISIBILITY_MODES)[number]; export declare const SUPPORTED_TAB_BAR_MINIMIZE_BEHAVIORS: readonly ["automatic", "never", "onScrollDown", "onScrollUp"]; /** * @see [Apple documentation](https://developer.apple.com/documentation/uikit/uitabbarcontroller/minimizebehavior) * * @platform iOS 26 */ export type NativeTabsTabBarMinimizeBehavior = (typeof SUPPORTED_TAB_BAR_MINIMIZE_BEHAVIORS)[number]; export interface NativeTabTriggerProps { /** * The name of the route. * * This is required when used inside a Layout component. * * When used in a route it has no effect. */ name?: string; /** * If true, the tab will be hidden from the tab bar. * * > **Note**: Marking a tab as `hidden` means it cannot be navigated to in any way. * * > **Note**: Dynamically hiding tabs will remount the navigator and the state will be reset. */ hidden?: boolean; /** * Props passed to the underlying native tab screen implementation. * Use this to configure props not directly exposed by Expo Router, but available in `react-native-screens`. * * > **Note**: This will override any other props set by Expo Router and may lead to unexpected behavior. * * > **Note**: This is an unstable API and may change or be removed in minor versions. * * @platform android * @platform iOS */ unstable_nativeProps?: NativeScreenProps; /** * If true, the tab will not pop stack to the root when selected again. * * @default false * @platform iOS */ disablePopToTop?: boolean; /** * If true, the tab will not scroll to the top when selected again. * @default false * * @platform iOS */ disableScrollToTop?: boolean; /** * If `true`, the tab is shown but cannot be selected by tapping it in the * tab bar. * * > **Note:** This only suppresses the native tap interaction. JavaScript * > navigation such as `router.push()` or `` still navigates to * > the tab. Use this for tabs that should appear visible but be temporarily inert, * > and gate navigation in your own code if you need to fully prevent access. * * Unlike `hidden`, the tab remains visible in the tab bar. * * @default false * * @platform android * @platform ios */ disabled?: boolean; /** * A test identifier for the tab bar item. * * On iOS it maps to the item's accessibility identifier, which XCUITest and Maestro match. * On Android it maps to the item's view tag, which Espresso-based drivers like Detox read * but Maestro and Appium do not. Use `accessibilityLabel` to match the tab by id there. * * @platform android * @platform iOS */ testID?: string; /** * The accessibility label of the tab bar item, announced by screen readers. * Defaults to the visible tab label. * * On Android, maps to the item's `contentDescription` and requires API 26 or above. * * @platform android * @platform iOS */ accessibilityLabel?: string; /** * The children of the trigger. * * Use `Icon`, `Label`, and `Badge` components to customize the tab. */ children?: React.ReactNode; /** * System-provided tab bar item with predefined icon and title * * Uses Apple's built-in tab bar items (e.g., bookmarks, contacts, downloads) with * standard iOS styling and localized titles. Custom `icon` or `selectedIcon` * properties will override the system icon, but the system-defined title cannot * be customized. * * @see The supported values correspond to the official [Apple documentation](https://developer.apple.com/documentation/uikit/uitabbaritem/systemitem). * @platform ios */ role?: NativeTabsTabBarItemRole; /** * The default behavior differs between iOS and Android. * * On **Android**, the content of a native tabs screen is automatically wrapped in a `SafeAreaView`, * and the **bottom** inset is applied. Other insets must be handled manually. * * On **iOS**, the first scroll view nested inside a native tabs screen has * [automatic content inset adjustment](https://reactnative.dev/docs/scrollview#contentinsetadjustmentbehavior-ios) enabled * * When this property is set to `true`, automatic content inset adjustment is disabled for the screen * and must be managed manually. You can use `SafeAreaView` from `react-native-screens/experimental` * to handle safe area insets. * * @platform android * @platform ios */ disableAutomaticContentInsets?: boolean; /** * The style applied to the content of the tab * * Note: Only certain style properties are supported. */ contentStyle?: NativeTabOptions['contentStyle']; /** * When set to `true`, the tab bar will not become transparent when scrolled to the edge. * * When set on a trigger, it takes precedence over the value set on `NativeTabs`. * * @platform iOS */ disableTransparentOnScrollEdge?: boolean; /** * The color of the ripple effect when this tab is selected - will be visible when other tabs are pressed. * * When set on a trigger, it takes precedence over the value set on `NativeTabs`. * * @platform android */ rippleColor?: ColorValue; /** * The color of the active indicator for this tab. * * When set on a trigger, it takes precedence over the value set on `NativeTabs`. * * @platform android */ indicatorColor?: ColorValue; /** * When set to `true`, disables the active indicator for this tab. * * When set on a trigger, it takes precedence over the value set on `NativeTabs`. * * @default false * * @platform android */ disableIndicator?: boolean; /** * The visibility mode of the tab item label for this tab. * * When set on a trigger, it takes precedence over the value set on `NativeTabs`. * * @see [Material Components documentation](https://github.com/material-components/material-components-android/blob/master/docs/components/BottomNavigation.md#making-navigation-bar-accessible) * * @platform android */ labelVisibilityMode?: NativeTabsTabBarItemLabelVisibilityMode; /** * Listeners for navigation events on this tab. * * Supported events: * - `tabPress` - called when this tab is pressed * - `focus` - called when this screen comes into focus * - `blur` - called when this screen loses focus * * @example * ```tsx * { * console.log('Home tab pressed'); * }, * }} * /> * ``` */ listeners?: ScreenProps, NativeTabNavigationEventMap>['listeners']; } declare const SUPPORTED_TAB_BAR_ITEM_ROLES: readonly ["bookmarks", "contacts", "downloads", "favorites", "featured", "history", "more", "mostRecent", "mostViewed", "recents", "search", "topRated"]; export type NativeTabsTabBarItemRole = (typeof SUPPORTED_TAB_BAR_ITEM_ROLES)[number]; export {}; //# sourceMappingURL=types.d.ts.map