diff --git a/.changeset/rotten-zebras-admire.md b/.changeset/rotten-zebras-admire.md new file mode 100644 index 00000000..25205e7c --- /dev/null +++ b/.changeset/rotten-zebras-admire.md @@ -0,0 +1,6 @@ +--- +'react-native-bottom-tabs': patch +'@bottom-tabs/react-navigation': patch +--- + +feat: introduce scene style diff --git a/docs/docs/docs/guides/standalone-usage.md b/docs/docs/docs/guides/standalone-usage.md index 72ddb643..3d253e57 100644 --- a/docs/docs/docs/guides/standalone-usage.md +++ b/docs/docs/docs/guides/standalone-usage.md @@ -213,6 +213,7 @@ Each route in the `routes` array can have the following properties: - `lazy`: Whether to lazy load this tab's content - `freezeOnBlur`: Whether to freeze the tab's content when it's not visible - `role`: A value that defines the purpose of the tab +- `style`: Style object for the component wrapping the screen content ### Helper Props @@ -267,3 +268,9 @@ Function to get the test ID for a tab item. Function to get the role for a tab item. - Default: Uses `route.role` + +#### `getSceneStyle` + +Function to get the style for a tab scene. + +- Default: Uses `route.style` diff --git a/docs/docs/docs/guides/usage-with-react-navigation.mdx b/docs/docs/docs/guides/usage-with-react-navigation.mdx index 97a16d2b..bc470fea 100644 --- a/docs/docs/docs/guides/usage-with-react-navigation.mdx +++ b/docs/docs/docs/guides/usage-with-react-navigation.mdx @@ -334,6 +334,20 @@ Available options: - `search` - The search role. +#### `sceneStyle` + +Style object for the component wrapping the screen content. + +```tsx + +``` + ### Events The navigator can emit events on certain actions. Supported events are: diff --git a/packages/react-native-bottom-tabs/src/TabView.tsx b/packages/react-native-bottom-tabs/src/TabView.tsx index d1e34302..7b1d5fb2 100644 --- a/packages/react-native-bottom-tabs/src/TabView.tsx +++ b/packages/react-native-bottom-tabs/src/TabView.tsx @@ -10,8 +10,10 @@ import { type DimensionValue, Image, Platform, + type StyleProp, StyleSheet, View, + type ViewStyle, processColor, } from 'react-native'; import { BottomTabBarHeightContext } from './utils/BottomTabBarHeightContext'; @@ -139,6 +141,11 @@ interface Props { */ getFreezeOnBlur?: (props: { route: Route }) => boolean | undefined; + /** + * Get style for the scene, uses `route.style` by default. + */ + getSceneStyle?: (props: { route: Route }) => StyleProp; + tabBarStyle?: { /** * Background color of the tab bar. @@ -196,6 +203,7 @@ const TabView = ({ getActiveTintColor = ({ route }: { route: Route }) => route.activeTintColor, getTestID = ({ route }: { route: Route }) => route.testID, getRole = ({ route }: { route: Route }) => route.role, + getSceneStyle = ({ route }: { route: Route }) => route.style, hapticFeedbackEnabled = false, // Android's native behavior is to show labels when there are less than 4 tabs. We leave it as undefined to use the platform default behavior. labeled = Platform.OS !== 'android' ? true : undefined, @@ -374,12 +382,15 @@ const TabView = ({ const focused = route.key === focusedKey; const freeze = !focused ? getFreezeOnBlur({ route }) : false; + const customStyle = getSceneStyle({ route }); + return ( ; }; export type NavigationState = { diff --git a/packages/react-navigation/src/types.ts b/packages/react-navigation/src/types.ts index 32c48064..6713f841 100644 --- a/packages/react-navigation/src/types.ts +++ b/packages/react-navigation/src/types.ts @@ -7,7 +7,7 @@ import type { TabActionHelpers, TabNavigationState, } from '@react-navigation/native'; -import type { ImageSourcePropType } from 'react-native'; +import type { ImageSourcePropType, StyleProp, ViewStyle } from 'react-native'; import type TabView from 'react-native-bottom-tabs'; import type { AppleIcon, TabRole } from 'react-native-bottom-tabs'; @@ -101,6 +101,11 @@ export type NativeBottomTabNavigationOptions = { * Whether inactive screens should be suspended from re-rendering. Defaults to `false`. */ freezeOnBlur?: boolean; + + /** + * Style object for the component wrapping the screen content. + */ + sceneStyle?: StyleProp; }; export type NativeBottomTabDescriptor = Descriptor< @@ -139,6 +144,7 @@ export type NativeBottomTabNavigationConfig = Partial< | 'getRole' | 'tabBar' | 'getFreezeOnBlur' + | 'getSceneStyle' > > & { tabBar?: (props: BottomTabBarProps) => React.ReactNode; diff --git a/packages/react-navigation/src/views/NativeBottomTabView.tsx b/packages/react-navigation/src/views/NativeBottomTabView.tsx index ffc3b41e..fd1c17b3 100644 --- a/packages/react-navigation/src/views/NativeBottomTabView.tsx +++ b/packages/react-navigation/src/views/NativeBottomTabView.tsx @@ -67,6 +67,7 @@ export default function NativeBottomTabView({ getFreezeOnBlur={({ route }) => descriptors[route.key]?.options.freezeOnBlur } + getSceneStyle={({ route }) => descriptors[route.key]?.options.sceneStyle} onTabLongPress={(index) => { const route = state.routes[index]; if (!route) {