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) {