Skip to content

Commit

Permalink
[expo][refactor] improve defineScreen signature
Browse files Browse the repository at this point in the history
**Summary**

the current signature causes the code readability issue since the option can be passed after the looooong function component.

to avoid this issue, remove the option parameter and use `nav.setOptions()` with `useEffect` to configure the screen options.

**Test**

- N/A, no ts error

**Issue**

- N/A
  • Loading branch information
yssk22 committed Oct 20, 2023
1 parent 808f1a6 commit a1c5885
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 108 deletions.
76 changes: 37 additions & 39 deletions expo/features/home/HomeScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { StyleSheet } from "react-native";
import { createBottomTabNavigator } from "@react-navigation/bottom-tabs";
import { defineScreen } from "@hpapp/features/root/protected/stack";
import {
defineScreen,
useNavigationOption,
} from "@hpapp/features/root/protected/stack";
import HomeTab from "@hpapp/features/home/HomeTab";
import EventsTab from "@hpapp/features/home/Events";
import SettingsTab from "@hpapp/features/settings/SettingsTab";
Expand Down Expand Up @@ -70,44 +73,39 @@ function getTabBarIconFn(iconName: string) {
};
}

export default defineScreen(
"/",
function () {
const [primary, contrast] = useColor("primary");
return (
<Tab.Navigator
screenOptions={({ route }) => {
return {
headerStyle: {
backgroundColor: primary,
},
headerTintColor: contrast,
headerTitleStyle: {
fontWeight: "bold",
fontFamily: Fonts.Main,
},
};
}}
>
{Tabs.map((tab) => {
return (
<Tab.Screen
key={tab.name}
name={t(tab.name)}
component={tab.component}
options={{
tabBarIcon: getTabBarIconFn(tab.icon),
}}
/>
);
})}
</Tab.Navigator>
);
},
{
headerShown: false,
}
);
export default defineScreen("/", function () {
useNavigationOption({ headerShown: false });
const [primary, contrast] = useColor("primary");
return (
<Tab.Navigator
screenOptions={({ route }) => {
return {
headerStyle: {
backgroundColor: primary,
},
headerTintColor: contrast,
headerTitleStyle: {
fontWeight: "bold",
fontFamily: Fonts.Main,
},
};
}}
>
{Tabs.map((tab) => {
return (
<Tab.Screen
key={tab.name}
name={t(tab.name)}
component={tab.component}
options={{
tabBarIcon: getTabBarIconFn(tab.icon),
}}
/>
);
})}
</Tab.Navigator>
);
});

const styles = StyleSheet.create({
container: {
Expand Down
35 changes: 27 additions & 8 deletions expo/features/root/protected/stack/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { forwardRef, useCallback, useMemo } from "react";
import React, { forwardRef, useCallback, useEffect, useMemo } from "react";
import {
createNativeStackNavigator as createNavigator,
NativeStackNavigationOptions,
Expand Down Expand Up @@ -197,16 +197,35 @@ const useNavigation = () => {

type Navigation = ReturnType<typeof useNavigation>;

function defineScreen<P>(
path: string,
component: React.ElementType<P>,
options?: NativeStackNavigationOptions
) {
function defineScreen<P>(path: string, component: React.ElementType<P>) {
return {
path,
component,
options,
};
}

export { createStackNavigator, useNavigation, Navigation, defineScreen };
// shortcut for useNavigationOption({title: title})
function useScreenTitle(title: string) {
const navigation = useNavigation();
useEffect(() => {
navigation.setOptions({
title,
});
}, [title]);
}

function useNavigationOption(options: Partial<NativeStackNavigationOptions>) {
const navigation = useNavigation();
useEffect(() => {
navigation.setOptions(options);
}, [options]);
}

export {
createStackNavigator,
useNavigation,
Navigation,
defineScreen,
useScreenTitle,
useNavigationOption,
};
120 changes: 59 additions & 61 deletions expo/features/settings/theme/ThemeSettingsScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,77 +1,75 @@
import { useLogout } from "@hpapp/features/auth";
import { View, StyleSheet } from "react-native";
import { ListItem } from "@rneui/themed";
import { defineScreen } from "@hpapp/features/root/protected/stack";
import {
defineScreen,
useScreenTitle,
} from "@hpapp/features/root/protected/stack";
import NavigationListItem from "@hpapp/features/common/components/list/NavigationListItem";
import ThemeColorSelectorScreen from "@hpapp/features/settings/theme/ThemeColorSelectorScreen";
import { t } from "@hpapp/system/i18n";
import { ColorScheme, useColor } from "@hpapp/contexts/settings/theme";
import { Spacing } from "@hpapp/features/common/constants";
import Text from "@hpapp/features/common/components/Text";

export default defineScreen(
"/settings/theme/",
function ThemeSettngsScreen() {
const [primary, primaryContrast] = useColor("primary");
const [secondary, secondaryContrast] = useColor("secondary");
const [background, backgroundContrast] = useColor("background");
return (
<View style={styles.container}>
<NavigationListItem
screen={ThemeColorSelectorScreen}
params={{
title: t("Primary Color"),
scheme: "primary" as ColorScheme,
}}
export default defineScreen("/settings/theme/", function ThemeSettngsScreen() {
useScreenTitle(t("Theme Settings"));
const [primary, primaryContrast] = useColor("primary");
const [secondary, secondaryContrast] = useColor("secondary");
const [background, backgroundContrast] = useColor("background");
return (
<View style={styles.container}>
<NavigationListItem
screen={ThemeColorSelectorScreen}
params={{
title: t("Primary Color"),
scheme: "primary" as ColorScheme,
}}
>
<Text
style={[
styles.text,
{ backgroundColor: primary, color: primaryContrast },
]}
>
<Text
style={[
styles.text,
{ backgroundColor: primary, color: primaryContrast },
]}
>
{t("Primary Color")}
</Text>
</NavigationListItem>
<NavigationListItem
screen={ThemeColorSelectorScreen}
params={{
title: t("Secondary Color"),
scheme: "secondary" as ColorScheme,
}}
{t("Primary Color")}
</Text>
</NavigationListItem>
<NavigationListItem
screen={ThemeColorSelectorScreen}
params={{
title: t("Secondary Color"),
scheme: "secondary" as ColorScheme,
}}
>
<Text
style={[
styles.text,
{ backgroundColor: secondary, color: secondaryContrast },
]}
>
<Text
style={[
styles.text,
{ backgroundColor: secondary, color: secondaryContrast },
]}
>
{t("Secondary Color")}
</Text>
</NavigationListItem>
<NavigationListItem
screen={ThemeColorSelectorScreen}
params={{
title: t("Background Color"),
scheme: "background" as ColorScheme,
}}
{t("Secondary Color")}
</Text>
</NavigationListItem>
<NavigationListItem
screen={ThemeColorSelectorScreen}
params={{
title: t("Background Color"),
scheme: "background" as ColorScheme,
}}
>
<Text
style={[
styles.text,
{ backgroundColor: background, color: backgroundContrast },
]}
>
<Text
style={[
styles.text,
{ backgroundColor: background, color: backgroundContrast },
]}
>
{t("Background Color")}
</Text>
</NavigationListItem>
</View>
);
},
{
title: t("Theme Settings"),
}
);
{t("Background Color")}
</Text>
</NavigationListItem>
</View>
);
});

const styles = StyleSheet.create({
container: {
Expand Down

0 comments on commit a1c5885

Please sign in to comment.