Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
95 changes: 26 additions & 69 deletions apps/e2e/app/[stackType]/overlay/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,103 +1,60 @@
// @ts-nocheck
import { interpolate } from "react-native-reanimated";
import Transition from "react-native-screen-transitions";
import {
OverlayA,
OverlayC,
OverlayE,
overlayIOSSlideOptions,
screenIOSSlideOptions,
} from "@/components/overlay-playground";
import { useResolvedStackType } from "@/components/stack-examples/stack-routing";
import { TabBarOverlay } from "@/components/tab-bar-overlay";
import { BlankStack } from "@/layouts/blank-stack";
import { Stack } from "@/layouts/stack";
import { IOSSlide } from "@/lib/screen-transitions/ios-slide";

export default function BlankStackOverlayLayout() {
export default function OverlayPlaygroundLayout() {
const stackType = useResolvedStackType();
const StackNavigator = stackType === "native-stack" ? Stack : BlankStack;
const navigatorScreenOptions =
stackType === "native-stack" ? { enableTransitions: true } : undefined;

return (
<StackNavigator screenOptions={navigatorScreenOptions}>
<StackNavigator.Screen
name="index"
options={{
overlay: TabBarOverlay,
...overlayIOSSlideOptions,
gestureEnabled: false,
overlay: OverlayA,
overlayMode: "float",
overlayShown: true,
}}
/>
<StackNavigator.Screen
name="second"
options={{
gestureEnabled: true,
gestureDirection: "horizontal",
screenStyleInterpolator: ({
progress,
layouts: {
screen: { width },
},
}) => {
"worklet";
const translateX = interpolate(
progress,
[0, 1, 2],
[width, 0, -width * 0.3],
);
return {
content: {
style: {
transform: [{ translateX }],
},
},
};
},
transitionSpec: {
open: Transition.Specs.DefaultSpec,
close: Transition.Specs.DefaultSpec,
},
// Inherit overlay from previous screen
overlay: TabBarOverlay,
overlayMode: "float",
overlayShown: true,
...screenIOSSlideOptions,
}}
/>
<StackNavigator.Screen
name="third"
options={{
...IOSSlide(),
// Overlay still visible on this screen
overlay: TabBarOverlay,
...overlayIOSSlideOptions,
overlay: OverlayC,
overlayMode: "float",
overlayShown: true,
}}
/>
<StackNavigator.Screen
name="no-overlay"
name="fourth"
options={{
gestureEnabled: true,
gestureDirection: "horizontal",
screenStyleInterpolator: ({
progress,
layouts: {
screen: { width },
},
}) => {
"worklet";
const translateX = interpolate(
progress,
[0, 1, 2],
[width, 0, -width * 0.3],
);
return {
content: {
style: {
transform: [{ translateX }],
},
},
};
},
transitionSpec: {
open: Transition.Specs.DefaultSpec,
close: Transition.Specs.DefaultSpec,
},
// No overlay on this screen
overlayShown: false,
...screenIOSSlideOptions,
}}
/>
<StackNavigator.Screen
name="fifth"
options={{
...overlayIOSSlideOptions,
overlay: OverlayE,
overlayMode: "float",
overlayShown: true,
}}
/>
</StackNavigator>
Expand Down
5 changes: 5 additions & 0 deletions apps/e2e/app/[stackType]/overlay/fifth.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { OverlayPlaygroundScreen } from "@/components/overlay-playground";

export default function OverlayFifth() {
return <OverlayPlaygroundScreen screen="E" />;
}
5 changes: 5 additions & 0 deletions apps/e2e/app/[stackType]/overlay/fourth.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { OverlayPlaygroundScreen } from "@/components/overlay-playground";

export default function OverlayFourth() {
return <OverlayPlaygroundScreen screen="D" />;
}
92 changes: 2 additions & 90 deletions apps/e2e/app/[stackType]/overlay/index.tsx
Original file line number Diff line number Diff line change
@@ -1,93 +1,5 @@
import { router } from "expo-router";
import { Pressable, StyleSheet, Text, View } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import {
buildStackPath,
useResolvedStackType,
} from "@/components/stack-examples/stack-routing";
import { screenTints, useTheme } from "@/theme";
import { OverlayPlaygroundScreen } from "@/components/overlay-playground";

export default function OverlayIndex() {
const stackType = useResolvedStackType();
const theme = useTheme();
return (
<SafeAreaView style={styles.container}>
<View style={styles.content}>
<Text style={styles.title}>Overlay Demo</Text>
<Text style={styles.description}>
A floating tab bar overlay is shown at the bottom. It animates based
on screen transitions and stack progress.
</Text>

<View style={styles.buttons}>
<Pressable
testID="push-second"
style={styles.button}
onPress={() =>
router.push(buildStackPath(stackType, "overlay/second"))
}
>
<Text style={styles.buttonText}>Push Second Screen</Text>
</Pressable>

<Pressable
testID="push-no-overlay"
style={[styles.button, styles.secondaryButton]}
onPress={() =>
router.push(buildStackPath(stackType, "overlay/no-overlay"))
}
>
<Text style={styles.buttonText}>Push Without Overlay</Text>
</Pressable>
</View>
</View>
</SafeAreaView>
);
return <OverlayPlaygroundScreen screen="A" />;
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: screenTints.navy,
},
content: {
flex: 1,
padding: 24,
justifyContent: "center",
alignItems: "center",
},
title: {
fontSize: 28,
fontWeight: "bold",
color: "#fff",
marginBottom: 16,
textAlign: "center",
},
description: {
fontSize: 16,
color: "rgba(255,255,255,0.7)",
textAlign: "center",
marginBottom: 40,
lineHeight: 24,
},
buttons: {
gap: 12,
width: "100%",
maxWidth: 280,
},
button: {
backgroundColor: "rgba(255,255,255,0.2)",
paddingVertical: 16,
paddingHorizontal: 32,
borderRadius: 999,
alignItems: "center",
},
secondaryButton: {
backgroundColor: "rgba(0,0,0,0.3)",
},
buttonText: {
fontSize: 16,
fontWeight: "600",
color: "#fff",
},
});
88 changes: 2 additions & 86 deletions apps/e2e/app/[stackType]/overlay/second.tsx
Original file line number Diff line number Diff line change
@@ -1,89 +1,5 @@
import { router } from "expo-router";
import { Pressable, StyleSheet, Text, View } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context";
import {
buildStackPath,
useResolvedStackType,
} from "@/components/stack-examples/stack-routing";
import { OverlayPlaygroundScreen } from "@/components/overlay-playground";

export default function OverlaySecond() {
const stackType = useResolvedStackType();
return (
<SafeAreaView style={styles.container}>
<View style={styles.content}>
<Text style={styles.title}>Second Screen</Text>
<Text style={styles.description}>
The overlay remains visible and shows the updated route. Notice the
tab bar dims as more screens stack.
</Text>

<View style={styles.buttons}>
<Pressable
testID="push-third"
style={styles.button}
onPress={() =>
router.push(buildStackPath(stackType, "overlay/third"))
}
>
<Text style={styles.buttonText}>Push Third Screen</Text>
</Pressable>

<Pressable
testID="go-back"
style={[styles.button, styles.secondaryButton]}
onPress={() => router.back()}
>
<Text style={styles.buttonText}>Go Back</Text>
</Pressable>
</View>
</View>
</SafeAreaView>
);
return <OverlayPlaygroundScreen screen="B" />;
}

const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#2d4a3e",
},
content: {
flex: 1,
padding: 24,
justifyContent: "center",
alignItems: "center",
},
title: {
fontSize: 28,
fontWeight: "bold",
color: "#fff",
marginBottom: 16,
textAlign: "center",
},
description: {
fontSize: 16,
color: "rgba(255,255,255,0.7)",
textAlign: "center",
marginBottom: 40,
lineHeight: 24,
},
buttons: {
gap: 12,
width: "100%",
maxWidth: 280,
},
button: {
backgroundColor: "rgba(255,255,255,0.2)",
paddingVertical: 16,
paddingHorizontal: 32,
borderRadius: 12,
alignItems: "center",
},
secondaryButton: {
backgroundColor: "rgba(0,0,0,0.3)",
},
buttonText: {
fontSize: 16,
fontWeight: "600",
color: "#fff",
},
});
Loading
Loading