Skip to content

Commit

Permalink
fix: Hot reload in web-example, improve navigation (#6947)
Browse files Browse the repository at this point in the history
## Summary

This PR:
- fixes hot reload on web,
- improves navigation (uses proper screen title, better back button name
(adds space between words)),
- fixes web url to navigation state mapping (proper page is displayed on
refresh or when navigating to a screen via url change)
  • Loading branch information
MatiPl01 authored Jan 29, 2025
1 parent 210159e commit 5784672
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 30 deletions.
37 changes: 19 additions & 18 deletions apps/common-app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
NavigationContainer,
} from '@react-navigation/native';
import { useCallback, useEffect, useState } from 'react';
import { ActivityIndicator, Linking, Platform, View } from 'react-native';
import { ActivityIndicator, Linking, View } from 'react-native';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';

Expand Down Expand Up @@ -38,18 +38,23 @@ export default function App() {
getPathFromState(state, options).replace(/%2F/g, '/'),
getStateFromPath: (path) => {
const chunks = path.split('/').filter(Boolean);
const routes = chunks.reduce<Array<{ name: string }>>(
(result, chunk) => {
const lastRoute = result[result.length - 1];
const route = {
name: lastRoute ? `${lastRoute.name}/${chunk}` : chunk,
};
result.push(route);
return result;
},
[]
);
return { routes };
if (chunks.length === 0) return { routes: [] };

const drawerRoute = chunks[0];
const stackRoutes = chunks.slice(1).map((_, index, array) => ({
name: array.slice(0, index + 1).join('/'),
}));

return {
routes: [
{
name: drawerRoute,
state: {
routes: stackRoutes,
},
},
],
};
},
prefixes: [],
}}
Expand Down Expand Up @@ -124,11 +129,7 @@ function useNavigationState() {
try {
const initialUrl = await Linking.getInitialURL();

if (
Platform.OS !== 'web' &&
Platform.OS !== 'macos' &&
initialUrl === null
) {
if (!IS_MACOS && !IS_WEB && initialUrl === null) {
// Only restore state if there's no deep link and we're not on web
const savedStateString = await AsyncStorage.getItem(PERSISTENCE_KEY);
// Erase the state immediately after fetching it.
Expand Down
2 changes: 1 addition & 1 deletion apps/common-app/src/apps/css/examples/animations/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const appearanceRoutes = {
name: 'Color Formats',
Component: animatedProperties.appearance.colors.ColorFormats,
},
ColorFunctions: {
ColorProperties: {
name: 'Color Properties',
Component: animatedProperties.appearance.colors.ColorProperties,
},
Expand Down
13 changes: 10 additions & 3 deletions apps/common-app/src/apps/css/navigation/Navigator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ type StackScreensOptions = {

function createStackScreens(
routes: Routes,
name: string,
pathChunks: Array<string>,
reducedMotion: boolean,
options?: StackScreensOptions
Expand All @@ -150,7 +151,7 @@ function createStackScreens(
options={{
...sharedOptions,
animation: reducedMotion || depth === 0 ? 'none' : 'default',
title: pathChunks[pathChunks.length - 1],
title: name,
}}
/>
),
Expand All @@ -160,6 +161,7 @@ function createStackScreens(
if (isRouteWithRoutes(value)) {
return createStackScreens(
value.routes,
value.name,
[...pathChunks, key],
reducedMotion,
{
Expand All @@ -177,7 +179,7 @@ function createStackScreens(
options={{
...sharedOptions,
animation: 'slide_from_right',
title: key,
title: value.name,
}}
/>
);
Expand Down Expand Up @@ -211,7 +213,12 @@ function Navigator() {
statusBarStyle: 'dark',
}}>
{Object.entries(tabRoutes).flatMap(([key, value]) =>
createStackScreens(value.routes, [key], shouldReduceMotion)
createStackScreens(
value.routes,
value.name,
[key],
shouldReduceMotion
)
)}
</Stack.Navigator>
<BottomTabBar currentRoute={currentRoute} routes={tabRoutesArray} />
Expand Down
3 changes: 2 additions & 1 deletion apps/common-app/src/apps/css/navigation/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ export function isRouteWithRoutes(route: Route): route is RouteWithRoutes {

export function getScreenTitle(path: string): string {
const parts = path.split('/');
return parts[parts.length - 1] ?? '';
const lastPart = parts[parts.length - 1] ?? '';
return lastPart.replace(/([A-Z])/g, ' $1').trim();
}
16 changes: 12 additions & 4 deletions apps/common-app/src/components/navigation/BackButton.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { faChevronLeft } from '@fortawesome/free-solid-svg-icons';
import { FontAwesomeIcon } from '@fortawesome/react-native-fontawesome';
import { useNavigation } from '@react-navigation/native';
import { memo } from 'react';
import { useFocusEffect, useNavigation } from '@react-navigation/native';
import { memo, useCallback, useState } from 'react';
import { StyleSheet } from 'react-native';
import { Pressable } from 'react-native-gesture-handler';
import Animated, { FadeInRight } from 'react-native-reanimated';
Expand All @@ -13,9 +13,17 @@ import { IS_WEB } from '@/utils';

function BackButton() {
const navigation = useNavigation();
const [prevRouteName, setPrevRouteName] = useState<string | undefined>(() => {
const routes = navigation.getState()?.routes;
return routes?.[routes.length - 2]?.name;
});

const routes = navigation.getState()?.routes;
const prevRouteName = routes?.[routes.length - 2]?.name;
useFocusEffect(
useCallback(() => {
const routes = navigation.getState()?.routes;
setPrevRouteName(routes?.[routes.length - 2]?.name);
}, [navigation])
);

if (!prevRouteName || !navigation.canGoBack()) {
return null;
Expand Down
4 changes: 2 additions & 2 deletions apps/web-example/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
"strict": true,
"baseUrl": "../..",
"paths": {
"@/*": ["./apps/common-app/src/*"]
// "react-native-reanimated": ["./packages/react-native-reanimated/src"]
"@/*": ["./apps/common-app/src/*"],
"react-native-reanimated": ["./packages/react-native-reanimated/src"]
}
},
"include": ["**/*.ts", "**/*.tsx"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ export function kebabize<T extends string>(property: T) {

function easingMapper(easing: CSSTimingFunction) {
if (typeof easing === 'string') {
return kebabize(easing);
return easing;
}

if (easing instanceof StepsEasing) {
Expand Down

0 comments on commit 5784672

Please sign in to comment.