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
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@


## [1.4.2](https://github.com/lukailun/react-native-animated-header-flat-list/compare/v1.4.1...v1.4.2) (2025-04-08)


### Bug Fixes

* optimize sticky component display after layout completion ([4a4d7e8](https://github.com/lukailun/react-native-animated-header-flat-list/commit/4a4d7e8118dab3d23ff0983c36546511c9f912ce))

## [1.4.1](https://github.com/lukailun/react-native-animated-header-flat-list/compare/v1.4.0...v1.4.1) (2025-03-19)


### Bug Fixes

* add eslint disable comment to metro config ([64f5123](https://github.com/lukailun/react-native-animated-header-flat-list/commit/64f512362359043fab1fb03120664e45b16d763d))
* convert babel config to commonjs ([4df90d8](https://github.com/lukailun/react-native-animated-header-flat-list/commit/4df90d86d4634b18433384699ff28ee25adba413))

# [1.4.0](https://github.com/lukailun/react-native-animated-header-flat-list/compare/v1.3.1...v1.4.0) (2025-03-10)


Expand Down
24 changes: 12 additions & 12 deletions example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,23 @@
},
"dependencies": {
"@expo/metro-runtime": "^4.0.1",
"@react-navigation/elements": "^2.2.6",
"@react-navigation/native": "^7.0.15",
"@react-navigation/native-stack": "^7.2.1",
"@react-navigation/elements": "^2.3.7",
"@react-navigation/native": "^7.1.5",
"@react-navigation/native-stack": "^7.3.9",
"expo": "latest",
"expo-status-bar": "^2.0.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-native": "0.76.7",
"react-native-reanimated": "3.16.1",
"react-native-safe-area-context": "4.12.0",
"react-native-screens": "4.4.0",
"react-native-web": "^0.19.13"
"react": "19.1.0",
"react-dom": "19.1.0",
"react-native": "0.78.2",
"react-native-reanimated": "^3.17.3",
"react-native-safe-area-context": "^5.3.0",
"react-native-screens": "^4.10.0",
"react-native-web": "^0.20.0"
},
"devDependencies": {
"@babel/core": "^7.26.9",
"@babel/core": "^7.26.10",
"prettier": "^3.5.3",
"react-native-builder-bob": "^0.37.0"
"react-native-builder-bob": "^0.40.3"
},
"private": true
}
34 changes: 17 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-native-animated-header-flat-list",
"version": "1.4.0",
"version": "1.4.2",
"description": "A React Native FlatList component with an animated collapsible header, featuring parallax effects, smooth title transitions, sticky component support, and customizable styles. Built with TypeScript and separate background/content layers in header.",
"source": "./src/index.tsx",
"main": "./lib/commonjs/index.js",
Expand Down Expand Up @@ -68,31 +68,31 @@
},
"devDependencies": {
"@commitlint/config-conventional": "17.7.0",
"@evilmartians/lefthook": "^1.11.3",
"@react-native/eslint-config": "0.78.0",
"@react-navigation/elements": "^2.2.6",
"@react-navigation/native": "^7.0.15",
"@react-navigation/native-stack": "^7.2.1",
"@evilmartians/lefthook": "^1.11.7",
"@react-native/eslint-config": "0.78.2",
"@react-navigation/elements": "^2.3.7",
"@react-navigation/native": "^7.1.5",
"@react-navigation/native-stack": "^7.3.9",
"@release-it/conventional-changelog": "7.0.0",
"@types/jest": "^29.5.14",
"@types/react": "^19.0.10",
"commitlint": "^19.6.1",
"@types/react": "^19.1.0",
"commitlint": "^19.8.0",
"del-cli": "^6.0.0",
"eslint": "8.57.0",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-prettier": "^5.2.3",
"eslint-plugin-prettier": "^5.2.6",
"jest": "^29.7.0",
"prettier": "^3.5.3",
"react": "19.0.0",
"react-native": "0.78.0",
"react-native-builder-bob": "^0.37.0",
"react-native-reanimated": "^3.17.1",
"react": "19.1.0",
"react-native": "0.78.2",
"react-native-builder-bob": "0.37.0",
"react-native-reanimated": "^3.17.3",
"react-native-safe-area-context": "^5.3.0",
"release-it": "16.1.5",
"typescript": "^5.8.2"
"release-it": "^18.1.2",
"typescript": "^5.8.3"
},
"resolutions": {
"@types/react": "^19.0.10"
"@types/react": "^19.1.0"
},
"peerDependencies": {
"@react-navigation/elements": ">=2.0.0",
Expand All @@ -101,7 +101,7 @@
"react": "*",
"react-native": "*",
"react-native-reanimated": ">=3.0.0",
"react-native-safe-area-context": ">=4.0.0"
"react-native-safe-area-context": ">=5.0.0"
},
"workspaces": [
"example"
Expand Down
11 changes: 8 additions & 3 deletions src/components/AnimatedHeaderFlatList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ export function AnimatedHeaderFlatList<T>({
setHeaderTitleLayout,
stickyComponentLayout,
setStickyComponentLayout,
stickyComponentAnimatedStyle,
navigationBarAnimatedStyle,
navigationTitleAnimatedStyle,
headerTitleAnimatedStyle,
Expand Down Expand Up @@ -193,14 +194,17 @@ export function AnimatedHeaderFlatList<T>({
{ListHeaderComponent}
</Animated.View>
{StickyComponent && (
<View
style={styles.stickyComponentContainer}
<Animated.View
style={[
styles.stickyComponentContainer,
stickyComponentAnimatedStyle,
]}
onLayout={(event: LayoutChangeEvent) => {
setStickyComponentLayout(event.nativeEvent.layout);
}}
>
<StickyComponent />
</View>
</Animated.View>
)}
</View>
);
Expand All @@ -214,6 +218,7 @@ export function AnimatedHeaderFlatList<T>({
flatListProps,
navigationBarHeight,
stickyComponentLayout.height,
stickyComponentAnimatedStyle,
stickyHeaderAnimatedStyle,
headerLayout.height,
ListHeaderComponent,
Expand Down
19 changes: 17 additions & 2 deletions src/hooks/useAnimatedHeaderFlatListAnimatedStyles.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useHeaderHeight } from '@react-navigation/elements';
import { useState } from 'react';
import { useCallback, useState } from 'react';
import {
useWindowDimensions,
type LayoutRectangle,
Expand Down Expand Up @@ -31,6 +31,7 @@ type AnimatedHeaderFlatListAnimatedStyles = {
setHeaderTitleLayout: (layout: LayoutRectangle) => void;
stickyComponentLayout: LayoutRectangle;
setStickyComponentLayout: (layout: LayoutRectangle) => void;
stickyComponentAnimatedStyle: AnimatedStyle<ViewStyle>;
navigationBarAnimatedStyle: AnimatedStyle<ViewStyle>;
navigationTitleAnimatedStyle: AnimatedStyle<ViewStyle>;
headerTitleAnimatedStyle: AnimatedStyle<ViewStyle>;
Expand Down Expand Up @@ -61,7 +62,7 @@ export const useAnimatedHeaderFlatListAnimatedStyles = ({
width: 0,
height: 0,
});
const [stickyComponentLayout, setStickyComponentLayout] =
const [stickyComponentLayout, updateStickyComponentLayout] =
useState<LayoutRectangle>({
x: 0,
y: 0,
Expand All @@ -74,6 +75,14 @@ export const useAnimatedHeaderFlatListAnimatedStyles = ({
navigationBarHeight;
const navigationTitleOpacity = useSharedValue(0);
const stickyHeaderOpacity = useSharedValue(0);
const stickyComponentOpacity = useSharedValue(0);
const setStickyComponentLayout = useCallback(
(layout: LayoutRectangle) => {
updateStickyComponentLayout(layout);
stickyComponentOpacity.value = layout.height > 0 ? 1 : 0;
},
[updateStickyComponentLayout, stickyComponentOpacity]
);
const navigationBarAnimatedStyle = useAnimatedStyle(() => {
return {
opacity: interpolate(
Expand Down Expand Up @@ -183,6 +192,11 @@ export const useAnimatedHeaderFlatListAnimatedStyles = ({
],
};
});
const stickyComponentAnimatedStyle = useAnimatedStyle(() => {
return {
opacity: stickyComponentOpacity.value,
};
});
const scrollHandler = useAnimatedScrollHandler((event) => {
scrollY.value = event.contentOffset.y;
navigationTitleOpacity.value =
Expand All @@ -202,6 +216,7 @@ export const useAnimatedHeaderFlatListAnimatedStyles = ({
setHeaderTitleLayout,
stickyComponentLayout,
setStickyComponentLayout,
stickyComponentAnimatedStyle,
navigationBarAnimatedStyle,
navigationTitleAnimatedStyle,
headerTitleAnimatedStyle,
Expand Down
Loading