Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
68d0309
chore(test): new test-tabs-dark-experimental-userInterfaceStyle with …
LKuchno Apr 8, 2026
4abf899
Merge branch 'main' of github.com:software-mansion/react-native-scree…
LKuchno Apr 8, 2026
b3c8132
scenario cutted to main steps
LKuchno Apr 8, 2026
bc8b93d
scenario remove wrong text
LKuchno Apr 8, 2026
469b768
scenario update vol3
LKuchno Apr 8, 2026
12a1eb9
scenario update
LKuchno Apr 9, 2026
037d6ef
Update apps/src/tests/single-feature-tests/tabs/test-tabs-tab-bar-dar…
LKuchno Apr 9, 2026
5f35a93
merge two screens for dark and light into one start screen with mode …
LKuchno Apr 9, 2026
77adca3
Merge branch '@lkuchno/test-tabs-dark-experimental-userInterfaceStyle…
LKuchno Apr 9, 2026
ceb8e5a
ThemeProvider introduce
sgaczol Apr 9, 2026
4584591
Example.tsx import fix
sgaczol Apr 9, 2026
42fb29f
TestThemeProvider.tsx added
sgaczol Apr 9, 2026
fdac2a1
update extensions
sgaczol Apr 9, 2026
da31816
Merge branch '@sgaczol/theme-provider' of github.com:software-mansion…
LKuchno Apr 10, 2026
246e8f9
ThemeProvider introduce
sgaczol Apr 9, 2026
796fb05
TestThemeProvider.tsx added
sgaczol Apr 9, 2026
082d082
update extensions
sgaczol Apr 9, 2026
972d1fc
module rename to 'theme', delete 'TestThemeProvider.tsx'
sgaczol Apr 10, 2026
4646e59
add useReactNavigationTheme
sgaczol Apr 10, 2026
e41bfe9
log message in useReactNavigationTheme update
sgaczol Apr 10, 2026
4ba07d9
pass full theme objects as context payload instead of theme name only…
sgaczol Apr 10, 2026
5b37ce9
useTheme no longer called in useReactNavigationTheme
sgaczol Apr 10, 2026
cfff0ad
Merge branch '@sgaczol/theme-provider' of github.com:software-mansion…
LKuchno Apr 13, 2026
f444cb7
Revert "Merge branch '@sgaczol/theme-provider' of github.com:software…
LKuchno Apr 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -361,12 +361,6 @@ internal class TabsContainer(

val isRepeated = nextSelectedFragment === currSelectedFragment

// If this is user action we test whether it should be prevented before we progress the state.
if (!isRepeated && !isInExternalOperationContext && nextSelectedFragment.isPreventNativeSelectionEnabled) {
delegate.onNavStateUpdatePrevented(navState, nextSelectedFragment.requireScreenKey)
return false
}

val stateChanged = updateSelectedFragment(nextSelectedFragment)

val hasTriggeredSpecialEffect =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,4 @@ internal interface TabsContainerDelegate {
rejectedNavState: TabsNavState,
reason: TabsNavStateUpdateRejectionReason,
)

/**
* Called when a native user action (tap) attempts to select a tab that has
* [com.swmansion.rnscreens.gamma.tabs.screen.TabsScreen.preventNativeSelection] enabled.
* The navigation state remains unchanged.
*
* @param currentNavState The currently active navigation state that was kept.
* @param preventedScreenKey The screen key of the tab whose selection was prevented.
*/
fun onNavStateUpdatePrevented(
currentNavState: TabsNavState,
preventedScreenKey: String,
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -182,13 +182,6 @@ class TabsHost(
)
}

override fun onNavStateUpdatePrevented(
currentNavState: TabsNavState,
preventedScreenKey: String,
) {
eventEmitter.emitOnTabSelectionPreventedEvent(currentNavState, preventedScreenKey)
}

override fun didMountItems(uiManager: UIManager) {
container.performContainerUpdateIfNeeded()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import com.swmansion.rnscreens.gamma.common.event.BaseEventEmitter
import com.swmansion.rnscreens.gamma.tabs.container.TabsNavState
import com.swmansion.rnscreens.gamma.tabs.container.TabsNavStateUpdateRejectionReason
import com.swmansion.rnscreens.gamma.tabs.host.event.TabsHostTabSelectedEvent
import com.swmansion.rnscreens.gamma.tabs.host.event.TabsHostTabSelectionPreventedEvent
import com.swmansion.rnscreens.gamma.tabs.host.event.TabsHostTabSelectionRejectedEvent

internal class TabsHostEventEmitter(
Expand Down Expand Up @@ -54,22 +53,4 @@ internal class TabsHostEventEmitter(
),
)
}

/**
* Emits `onTabSelectionPrevented` event to JS when a tab selection is prevented
* because the target screen has `preventNativeSelection` enabled.
*/
fun emitOnTabSelectionPreventedEvent(
currentNavState: TabsNavState,
preventedScreenKey: String,
) {
reactEventDispatcher.dispatchEvent(
TabsHostTabSelectionPreventedEvent(
surfaceId,
viewTag,
currentNavState,
preventedScreenKey,
),
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import com.swmansion.rnscreens.gamma.common.colorscheme.ColorScheme
import com.swmansion.rnscreens.gamma.helpers.makeEventRegistrationInfo
import com.swmansion.rnscreens.gamma.tabs.container.TabsNavState
import com.swmansion.rnscreens.gamma.tabs.host.event.TabsHostTabSelectedEvent
import com.swmansion.rnscreens.gamma.tabs.host.event.TabsHostTabSelectionPreventedEvent
import com.swmansion.rnscreens.gamma.tabs.host.event.TabsHostTabSelectionRejectedEvent
import com.swmansion.rnscreens.gamma.tabs.screen.TabsScreen

Expand Down Expand Up @@ -60,7 +59,6 @@ class TabsHostViewManager :
override fun getExportedCustomDirectEventTypeConstants(): MutableMap<String, Any> =
mutableMapOf(
makeEventRegistrationInfo(TabsHostTabSelectedEvent),
makeEventRegistrationInfo(TabsHostTabSelectionPreventedEvent),
makeEventRegistrationInfo(TabsHostTabSelectionRejectedEvent),
)

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,6 @@ class TabsScreen(
var shouldUseRepeatedTabSelectionScrollToTopSpecialEffect: Boolean = true
var shouldUseRepeatedTabSelectionPopToRootSpecialEffect: Boolean = true

var preventNativeSelection: Boolean = false

private fun <T> updateMenuItemAttributesIfNeeded(
oldValue: T,
newValue: T,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ class TabsScreenFragment(
internal val tabsScreen: TabsScreen,
) : Fragment() {
internal val requireScreenKey: String by tabsScreen::requireScreenKey
internal val isPreventNativeSelectionEnabled: Boolean by tabsScreen::preventNativeSelection

override fun onCreateView(
inflater: LayoutInflater,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,13 +97,6 @@ class TabsScreenViewManager :
view.shouldUseRepeatedTabSelectionScrollToTopSpecialEffect = scrollToTop
}

override fun setPreventNativeSelection(
view: TabsScreen,
value: Boolean,
) {
view.preventNativeSelection = value
}

override fun setTabBarItemTestID(
view: TabsScreen,
value: String?,
Expand Down
2 changes: 1 addition & 1 deletion apps/Example.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler';
import {
ScreensDarkTheme,
ScreensLightTheme,
} from './src/shared/styling/adapter/react-navigation';
} from './src/shared/styling/Colors';

import IssueTestsScreen from './src/tests/IssueTestsScreen';
import SingleFeatureTests from './src/tests/single-feature-tests';
Expand Down
2 changes: 1 addition & 1 deletion apps/src/shared/Alert.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { Text, StyleSheet, Dimensions, View, Pressable } from 'react-native';
import { useNavigation } from '@react-navigation/native';
import useThemeColorPallette from './styling/adapter/react-navigation/useColorPallette';
import useThemeColorPallette from './styling/theme-provider/useColorPallette';

export const Alert = (): React.JSX.Element => {
const navigation = useNavigation();
Expand Down
4 changes: 2 additions & 2 deletions apps/src/shared/ThemedText.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { useTheme } from '@react-navigation/native';
import React from 'react';
import { Text, TextProps } from 'react-native';
import useThemeColorPallette from './styling/theme-provider/useColorPallette';

export const ThemedText = ({ children, style, ...props }: TextProps) => {
const { colors } = useTheme();
const { colors } = useThemeColorPallette();

return (
<Text style={[{ color: colors.text }, style]} {...props}>
Expand Down
6 changes: 3 additions & 3 deletions apps/src/shared/ThemedTextInput.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { useTheme } from '@react-navigation/native';
import React from 'react';
import { TextInput, TextInputProps } from 'react-native';
import useThemeColorPallette from './styling/theme-provider/useColorPallette';

export const ThemedTextInput = ({ style, ...props }: TextInputProps) => {
const { colors } = useTheme();
const { colors } = useThemeColorPallette();

return (
<TextInput
style={[{ borderColor: colors.border, color: colors.text }, style]}
style={[{ borderColor: colors.cardBorder, color: colors.text }, style]}
{...props}
/>
);
Expand Down
2 changes: 1 addition & 1 deletion apps/src/shared/ThemedView.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react';
import { View, ViewProps } from 'react-native';
import useThemeColorPallette from './styling/adapter/react-navigation/useColorPallette';
import useThemeColorPallette from './styling/theme-provider/useColorPallette';

export const ThemedView = ({ children, style, ...props }: ViewProps) => {
const { colors } = useThemeColorPallette();
Expand Down
36 changes: 30 additions & 6 deletions apps/src/shared/styling/Colors.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { ColorValue } from 'react-native';
import { DarkTheme, DefaultTheme } from '@react-navigation/native';

export const Palette = {
NavyLight100: '#001a72',
Expand Down Expand Up @@ -97,18 +98,20 @@ export const Palette = {
} as const;

export type ColorPallette = typeof Palette & {
background: ColorValue,
offBackground: ColorValue,
primary: ColorValue,
cardBackground: ColorValue,
cardBorder: ColorValue,
background: ColorValue;
offBackground: ColorValue;
primary: ColorValue;
text: ColorValue;
cardBackground: ColorValue;
cardBorder: ColorValue;
};

export const Colors: ColorPallette = {
...Palette,
background: Palette.White,
offBackground: Palette.OffWhite,
primary: Palette.NavyLight100,
text: Palette.NavyLight100,
cardBackground: Palette.White,
cardBorder: Palette.NavyLight20,
};
Expand All @@ -120,10 +123,31 @@ export const DarkColors: ColorPallette = {
background: Palette.Navy,
offBackground: Palette.OffNavy,
primary: Palette.NavyLight10,
text: Palette.NavyLight10,
cardBackground: Palette.Navy,
cardBorder: Palette.NavyDark60,
};

export default Colors;
export const ScreensLightTheme = {
...DefaultTheme,
colors: {
...DefaultTheme.colors,
primary: LightColors.primary as string,
background: LightColors.background as string,
card: LightColors.cardBackground as string,
border: LightColors.cardBorder as string,
},
};

export const ScreensDarkTheme = {
...DarkTheme,
colors: {
...DarkTheme.colors,
primary: DarkColors.primary as string,
background: DarkColors.background as string,
card: DarkColors.cardBackground as string,
border: DarkColors.cardBorder as string,
},
};

export default Colors;
25 changes: 0 additions & 25 deletions apps/src/shared/styling/adapter/react-navigation/index.ts

This file was deleted.

This file was deleted.

9 changes: 9 additions & 0 deletions apps/src/shared/styling/theme-provider/ThemeContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import * as React from 'react';

export type ThemeName = 'light' | 'dark';

export const ThemeContext = React.createContext<ThemeName | undefined>(
undefined,
);

ThemeContext.displayName = 'ThemeContext';
15 changes: 15 additions & 0 deletions apps/src/shared/styling/theme-provider/ThemeProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import * as React from 'react';

import { ThemeContext } from './ThemeContext';
import type { ThemeName } from './ThemeContext';

type Props = {
theme: ThemeName;
children: React.ReactNode;
};

export function ThemeProvider({ theme, children }: Props) {
return (
<ThemeContext.Provider value={theme}>{children}</ThemeContext.Provider>
);
}
27 changes: 27 additions & 0 deletions apps/src/shared/styling/theme-provider/useColorPallette.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as React from 'react';
import { ThemeContext } from './ThemeContext';
import type { ThemeName } from './ThemeContext';
import { ColorPallette, DarkColors, LightColors } from '../Colors';
import { useTheme } from '@react-navigation/native';

/**
* Requires `ThemeContext` (from react-navigation) presence.
* However, it is possible to override theme by wrapping part of the app in `ThemeProvider` and passing desired theme as a prop.
* Use this to get whole collor pallete current theme is based on.
*/
export default function useThemeColorPallette(): {
theme: ThemeName;
colors: ColorPallette;
} {
const navigationTheme = useTheme();
let theme: ThemeName = navigationTheme.dark ? 'dark' : 'light';

const providedTheme = React.useContext(ThemeContext);
if (providedTheme !== undefined) {
theme = providedTheme;
}
return {
theme: theme,
colors: theme === 'dark' ? DarkColors : LightColors,
};
}
2 changes: 1 addition & 1 deletion apps/src/tests/IssueTestsScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { ListItem } from '@apps/shared';
import {
ScreensDarkTheme,
ScreensLightTheme,
} from '@apps/shared/styling/adapter/react-navigation';
} from '@apps/shared/styling/Colors';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const SCREENS: Record<
Expand Down
Loading