From c9d1aaa4683722e4f45e84875b880249dc48a30c Mon Sep 17 00:00:00 2001 From: Damiano Plebani Date: Mon, 9 Dec 2024 16:01:44 +0100 Subject: [PATCH] Add animated divider to the `HeaderFirstLevel` component --- src/components/layout/HeaderFirstLevel.tsx | 43 ++++++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/src/components/layout/HeaderFirstLevel.tsx b/src/components/layout/HeaderFirstLevel.tsx index 3cba07d3..c43d03e6 100644 --- a/src/components/layout/HeaderFirstLevel.tsx +++ b/src/components/layout/HeaderFirstLevel.tsx @@ -1,5 +1,5 @@ import * as React from "react"; -import { useEffect, useLayoutEffect } from "react"; +import { createRef, useEffect, useLayoutEffect } from "react"; import { AccessibilityInfo, findNodeHandle, @@ -7,7 +7,9 @@ import { View } from "react-native"; import Animated, { + AnimatedRef, useAnimatedStyle, + useScrollViewOffset, useSharedValue, withTiming } from "react-native-reanimated"; @@ -30,6 +32,8 @@ type CommonProps = WithTestID<{ // This Prop will be removed once all the screens on the first level routing will be refactored backgroundColor?: "light" | "dark"; ignoreSafeAreaMargin?: boolean; + animatedRef?: AnimatedRef; + animatedFlatListRef?: AnimatedRef>; }>; interface Base extends CommonProps { @@ -72,6 +76,14 @@ const styles = StyleSheet.create({ flexDirection: "row", alignItems: "center", justifyContent: "space-between" + }, + headerDivider: { + position: "absolute", + width: "100%", + height: StyleSheet.hairlineWidth, + left: 0, + right: 0, + bottom: 0 } }); @@ -80,12 +92,14 @@ export const HeaderFirstLevel = ({ type, testID, backgroundColor = "light", - ignoreSafeAreaMargin = false, firstAction, secondAction, - thirdAction + thirdAction, + ignoreSafeAreaMargin = false, + animatedRef, + animatedFlatListRef }: HeaderFirstLevel) => { - const titleRef = React.createRef(); + const titleRef = createRef(); const insets = useSafeAreaInsets(); const theme = useIOTheme(); const paddingTop = useSharedValue(ignoreSafeAreaMargin ? 0 : insets.top); @@ -97,6 +111,12 @@ export const HeaderFirstLevel = ({ } }); + /* We show the divider only when the header is scrolled down */ + const offset = useScrollViewOffset( + (animatedRef as AnimatedRef) || + (animatedFlatListRef as AnimatedRef>) + ); + useEffect(() => { // eslint-disable-next-line functional/immutable-data paddingTop.value = withTiming( @@ -109,6 +129,10 @@ export const HeaderFirstLevel = ({ paddingTop: paddingTop.value })); + const animatedDivider = useAnimatedStyle(() => ({ + opacity: withTiming(offset.value > 0 ? 1 : 0, { duration: 200 }) + })); + return ( + {/* Divider */} + +