Native iOS 18+ zoom transitions. The destination screen expands from a source element with a fluid animation.
import { One, Stack, useParams, useRouter } from 'one'import { Pressable, Text, View } from 'react-native'
// source screen: wrap the tappable elementfunction ListScreen() { const router = useRouter() return ( <One.iOS.ZoomTransitionSource identifier="item-1"> <Pressable onPress={() => router.push('/detail?id=item-1')}> <Text>Mountain View</Text> </Pressable> </One.iOS.ZoomTransitionSource> )}
// destination screen: place the enabler anywherefunction DetailScreen() { const { id } = useParams() return ( <View> <Stack.Screen options={{ headerShown: false }} /> <One.iOS.ZoomTransitionEnabler zoomTransitionSourceIdentifier={id} /> <Text>Detail for {id}</Text> </View> )}headerShown: false on the detail screen to avoid the header overlapping during the zoom animationidentifier must match between ZoomTransitionSource and ZoomTransitionEnablerOne.iOS.ZoomTransitionAlignmentRectDetector on the destination to align the zoom to a specific elementZoomTransitionSource takes a required identifier, an optional
alignment rect (x, y, width, height), and
animateAspectRatioChange. ZoomTransitionEnabler takes the required
zoomTransitionSourceIdentifier plus an optional dismissalBoundsRect
(minX, maxX, minY, maxY) that bounds the dismiss gesture.
ZoomTransitionAlignmentRectDetector takes the matching identifier and
wraps the destination element.
Edit this page on GitHub.