react-native-animated-header-flat-list 1.5.1 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/lib/module/components/AnimatedHeaderFlatList.js +11 -9
- package/lib/module/components/AnimatedHeaderFlatList.js.map +1 -1
- package/lib/module/hooks/useAnimatedHeaderFlatListAnimatedStyles.js +11 -3
- package/lib/module/hooks/useAnimatedHeaderFlatListAnimatedStyles.js.map +1 -1
- package/lib/module/utils/styleUtils.js +1 -1
- package/lib/module/utils/styleUtils.js.map +1 -1
- package/lib/typescript/src/components/AnimatedHeaderFlatList.d.ts +5 -3
- package/lib/typescript/src/components/AnimatedHeaderFlatList.d.ts.map +1 -1
- package/lib/typescript/src/hooks/useAnimatedHeaderFlatListAnimatedStyles.d.ts.map +1 -1
- package/package.json +14 -13
- package/src/components/AnimatedHeaderFlatList.tsx +94 -77
- package/src/hooks/useAnimatedHeaderFlatListAnimatedStyles.ts +21 -4
- package/src/utils/styleUtils.ts +1 -1
package/README.md
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
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.
|
|
8
8
|
|
|
9
|
-
English | [简体中文](./
|
|
9
|
+
English | [简体中文](./README-zh.md)
|
|
10
10
|
|
|
11
11
|
## Preview
|
|
12
12
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
import
|
|
3
|
+
import { forwardRef } from 'react';
|
|
4
4
|
import { StatusBar, StyleSheet, View } from 'react-native';
|
|
5
5
|
import { useLayoutEffect, useCallback, useMemo } from 'react';
|
|
6
6
|
import Animated from 'react-native-reanimated';
|
|
@@ -9,7 +9,7 @@ import { getFontSizeFromStyle } from "../utils/styleUtils.js";
|
|
|
9
9
|
import { useNavigation } from '@react-navigation/native';
|
|
10
10
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
11
11
|
const HEADER_ITEM = 'REACT_NATIVE_ANIMATED_HEADER_FLAT_LIST_HEADER';
|
|
12
|
-
|
|
12
|
+
function AnimatedHeaderFlatListInner({
|
|
13
13
|
title,
|
|
14
14
|
navigationBarColor,
|
|
15
15
|
headerTitleStyle,
|
|
@@ -21,7 +21,7 @@ export function AnimatedHeaderFlatList({
|
|
|
21
21
|
navigationTitleTranslateX = 0,
|
|
22
22
|
navigationTitleTranslateY = 0,
|
|
23
23
|
...flatListProps
|
|
24
|
-
}) {
|
|
24
|
+
}, ref) {
|
|
25
25
|
const navigation = useNavigation();
|
|
26
26
|
const {
|
|
27
27
|
scrollHandler,
|
|
@@ -59,7 +59,7 @@ export function AnimatedHeaderFlatList({
|
|
|
59
59
|
headerTitleAlign: 'center'
|
|
60
60
|
});
|
|
61
61
|
}, [navigationTitle, navigation]);
|
|
62
|
-
const
|
|
62
|
+
const createHeaderComponent = useCallback(key => {
|
|
63
63
|
return /*#__PURE__*/_jsx(View, {
|
|
64
64
|
style: styles.headerWrapper,
|
|
65
65
|
children: /*#__PURE__*/_jsxs(View, {
|
|
@@ -89,9 +89,9 @@ export function AnimatedHeaderFlatList({
|
|
|
89
89
|
numberOfLines: 1,
|
|
90
90
|
style: [headerTitleAnimatedStyle, styles.headerTitle, headerTitleStyle],
|
|
91
91
|
children: title
|
|
92
|
-
})]
|
|
92
|
+
}, `${key}-title`)]
|
|
93
93
|
})
|
|
94
|
-
});
|
|
94
|
+
}, key);
|
|
95
95
|
}, [navigationBarHeight, parallax, headerBackgroundAnimatedStyle, HeaderBackground, HeaderContent, headerContentAnimatedStyle, headerTitleAnimatedStyle, headerTitleStyle, title, setHeaderLayout, setHeaderTitleLayout, navigationBarAnimatedStyle, navigationBarColor]);
|
|
96
96
|
const renderItem = useCallback(({
|
|
97
97
|
item
|
|
@@ -105,7 +105,7 @@ export function AnimatedHeaderFlatList({
|
|
|
105
105
|
style: [stickyHeaderAnimatedStyle, styles.stickyHeader, {
|
|
106
106
|
bottom: headerLayout.height - navigationBarHeight * 2 + stickyComponentLayout.height
|
|
107
107
|
}],
|
|
108
|
-
children:
|
|
108
|
+
children: createHeaderComponent('sticky')
|
|
109
109
|
}), StickyComponent && /*#__PURE__*/_jsx(Animated.View, {
|
|
110
110
|
style: [styles.stickyComponentContainer, stickyComponentAnimatedStyle],
|
|
111
111
|
onLayout: event => {
|
|
@@ -118,7 +118,7 @@ export function AnimatedHeaderFlatList({
|
|
|
118
118
|
return flatListProps.renderItem && typeof flatListProps.renderItem === 'function' ? flatListProps.renderItem({
|
|
119
119
|
item
|
|
120
120
|
}) : null;
|
|
121
|
-
}, [flatListProps, navigationBarHeight, stickyComponentLayout.height, stickyComponentAnimatedStyle, stickyHeaderAnimatedStyle, headerLayout.height,
|
|
121
|
+
}, [flatListProps, navigationBarHeight, stickyComponentLayout.height, stickyComponentAnimatedStyle, stickyHeaderAnimatedStyle, headerLayout.height, createHeaderComponent, StickyComponent, setStickyComponentLayout]);
|
|
122
122
|
const data = useMemo(() => {
|
|
123
123
|
const listData = Array.isArray(flatListProps.data) ? flatListProps.data : [];
|
|
124
124
|
return [HEADER_ITEM, ...listData];
|
|
@@ -129,6 +129,7 @@ export function AnimatedHeaderFlatList({
|
|
|
129
129
|
translucent: true
|
|
130
130
|
}), /*#__PURE__*/_jsx(Animated.FlatList, {
|
|
131
131
|
...flatListProps,
|
|
132
|
+
ref: ref,
|
|
132
133
|
stickyHeaderIndices: [1],
|
|
133
134
|
ListHeaderComponent: /*#__PURE__*/_jsx(Animated.View, {
|
|
134
135
|
style: [styles.mainHeaderContainer, {
|
|
@@ -137,7 +138,7 @@ export function AnimatedHeaderFlatList({
|
|
|
137
138
|
translateY: navigationBarHeight
|
|
138
139
|
}]
|
|
139
140
|
}],
|
|
140
|
-
children:
|
|
141
|
+
children: createHeaderComponent('main')
|
|
141
142
|
}),
|
|
142
143
|
onScroll: scrollHandler,
|
|
143
144
|
data: data,
|
|
@@ -192,4 +193,5 @@ const styles = StyleSheet.create({
|
|
|
192
193
|
bottom: 0
|
|
193
194
|
}
|
|
194
195
|
});
|
|
196
|
+
export const AnimatedHeaderFlatList = /*#__PURE__*/forwardRef(AnimatedHeaderFlatListInner);
|
|
195
197
|
//# sourceMappingURL=AnimatedHeaderFlatList.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["forwardRef","StatusBar","StyleSheet","View","useLayoutEffect","useCallback","useMemo","Animated","useAnimatedHeaderFlatListAnimatedStyles","getFontSizeFromStyle","useNavigation","jsx","_jsx","jsxs","_jsxs","Fragment","_Fragment","HEADER_ITEM","AnimatedHeaderFlatListInner","title","navigationBarColor","headerTitleStyle","navigationTitleStyle","HeaderBackground","HeaderContent","StickyComponent","parallax","navigationTitleTranslateX","navigationTitleTranslateY","flatListProps","ref","navigation","scrollHandler","navigationBarHeight","headerLayout","setHeaderLayout","setHeaderTitleLayout","stickyComponentLayout","setStickyComponentLayout","stickyComponentAnimatedStyle","navigationBarAnimatedStyle","navigationTitleAnimatedStyle","headerTitleAnimatedStyle","stickyHeaderAnimatedStyle","headerContentAnimatedStyle","headerBackgroundAnimatedStyle","headerTitleFontSize","navigationTitleFontSize","navigationTitle","Text","style","numberOfLines","children","setOptions","headerShown","headerStyle","styles","navigationBar","headerShadowVisible","headerTransparent","headerTitle","headerTitleAlign","createHeaderComponent","key","headerWrapper","headerContainer","top","onLayout","event","nativeEvent","layout","height","undefined","headerContentContainer","animatedNavigationBar","backgroundColor","renderItem","item","stickyHeaderContainer","stickyHeader","bottom","stickyComponentContainer","data","listData","Array","isArray","translucent","FlatList","stickyHeaderIndices","ListHeaderComponent","mainHeaderContainer","transform","translateY","onScroll","create","overflow","position","left","right","width","AnimatedHeaderFlatList"],"sourceRoot":"../../../src","sources":["components/AnimatedHeaderFlatList.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import { useHeaderHeight } from '@react-navigation/elements';
|
|
4
|
-
import { useCallback, useState } from 'react';
|
|
4
|
+
import { useCallback, useState, useEffect } from 'react';
|
|
5
5
|
import { useWindowDimensions } from 'react-native';
|
|
6
|
-
import { interpolate, useAnimatedScrollHandler, useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
|
|
6
|
+
import { interpolate, useAnimatedScrollHandler, useAnimatedStyle, useSharedValue, cancelAnimation } from 'react-native-reanimated';
|
|
7
7
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
8
8
|
export const useAnimatedHeaderFlatListAnimatedStyles = ({
|
|
9
9
|
headerTitleFontSize,
|
|
@@ -35,7 +35,7 @@ export const useAnimatedHeaderFlatListAnimatedStyles = ({
|
|
|
35
35
|
width: 0,
|
|
36
36
|
height: 0
|
|
37
37
|
});
|
|
38
|
-
const distanceBetweenTitleAndNavigationBar = (navigationBarHeight - safeAreaInsets.top + headerTitleLayout.height) / 2 + headerTitleLayout.y - navigationBarHeight;
|
|
38
|
+
const distanceBetweenTitleAndNavigationBar = Math.max(0, (navigationBarHeight - safeAreaInsets.top + headerTitleLayout.height) / 2 + headerTitleLayout.y - navigationBarHeight);
|
|
39
39
|
const navigationTitleOpacity = useSharedValue(0);
|
|
40
40
|
const stickyHeaderOpacity = useSharedValue(0);
|
|
41
41
|
const stickyComponentOpacity = useSharedValue(0);
|
|
@@ -104,6 +104,14 @@ export const useAnimatedHeaderFlatListAnimatedStyles = ({
|
|
|
104
104
|
navigationTitleOpacity.value = event.contentOffset.y >= distanceBetweenTitleAndNavigationBar ? 1 : 0;
|
|
105
105
|
stickyHeaderOpacity.value = event.contentOffset.y >= headerLayout.height - navigationBarHeight * 2 ? 1 : 0;
|
|
106
106
|
});
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
return () => {
|
|
109
|
+
cancelAnimation(scrollY);
|
|
110
|
+
cancelAnimation(navigationTitleOpacity);
|
|
111
|
+
cancelAnimation(stickyHeaderOpacity);
|
|
112
|
+
cancelAnimation(stickyComponentOpacity);
|
|
113
|
+
};
|
|
114
|
+
}, [scrollY, navigationTitleOpacity, stickyHeaderOpacity, stickyComponentOpacity]);
|
|
107
115
|
return {
|
|
108
116
|
scrollHandler,
|
|
109
117
|
navigationBarHeight,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["useHeaderHeight","useCallback","useState","useWindowDimensions","interpolate","useAnimatedScrollHandler","useAnimatedStyle","useSharedValue","useSafeAreaInsets","useAnimatedHeaderFlatListAnimatedStyles","headerTitleFontSize","navigationTitleFontSize","navigationTitleTranslateX","navigationTitleTranslateY","width","windowWidth","scrollY","navigationBarHeight","safeAreaInsets","headerLayout","setHeaderLayout","x","y","height","headerTitleLayout","setHeaderTitleLayout","stickyComponentLayout","updateStickyComponentLayout","distanceBetweenTitleAndNavigationBar","top","navigationTitleOpacity","stickyHeaderOpacity","stickyComponentOpacity","setStickyComponentLayout","layout","value","navigationBarAnimatedStyle","opacity","marginBottom","
|
|
1
|
+
{"version":3,"names":["useHeaderHeight","useCallback","useState","useEffect","useWindowDimensions","interpolate","useAnimatedScrollHandler","useAnimatedStyle","useSharedValue","cancelAnimation","useSafeAreaInsets","useAnimatedHeaderFlatListAnimatedStyles","headerTitleFontSize","navigationTitleFontSize","navigationTitleTranslateX","navigationTitleTranslateY","width","windowWidth","scrollY","navigationBarHeight","safeAreaInsets","headerLayout","setHeaderLayout","x","y","height","headerTitleLayout","setHeaderTitleLayout","stickyComponentLayout","updateStickyComponentLayout","distanceBetweenTitleAndNavigationBar","Math","max","top","navigationTitleOpacity","stickyHeaderOpacity","stickyComponentOpacity","setStickyComponentLayout","layout","value","navigationBarAnimatedStyle","opacity","marginBottom","navigationTitleAnimatedStyle","transform","translateX","translateY","headerTitleAnimatedStyle","scale","stickyHeaderAnimatedStyle","headerContentAnimatedStyle","headerBackgroundAnimatedStyle","stickyComponentAnimatedStyle","scrollHandler","event","contentOffset"],"sourceRoot":"../../../src","sources":["hooks/useAnimatedHeaderFlatListAnimatedStyles.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
export const getFontSizeFromStyle = textStyle => {
|
|
4
4
|
if (!textStyle) return undefined;
|
|
5
5
|
if (Array.isArray(textStyle)) {
|
|
6
|
-
for (const styleItem of textStyle.
|
|
6
|
+
for (const styleItem of textStyle.toReversed()) {
|
|
7
7
|
if (styleItem && typeof styleItem === 'object' && 'fontSize' in styleItem) {
|
|
8
8
|
return styleItem.fontSize;
|
|
9
9
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["getFontSizeFromStyle","textStyle","undefined","Array","isArray","styleItem","
|
|
1
|
+
{"version":3,"names":["getFontSizeFromStyle","textStyle","undefined","Array","isArray","styleItem","toReversed","fontSize"],"sourceRoot":"../../../src","sources":["utils/styleUtils.ts"],"mappings":";;AAEA,OAAO,MAAMA,oBAAoB,GAAIC,SAA+B,IAAK;EACvE,IAAI,CAACA,SAAS,EAAE,OAAOC,SAAS;EAChC,IAAIC,KAAK,CAACC,OAAO,CAACH,SAAS,CAAC,EAAE;IAC5B,KAAK,MAAMI,SAAS,IAAIJ,SAAS,CAACK,UAAU,CAAC,CAAC,EAAE;MAC9C,IACED,SAAS,IACT,OAAOA,SAAS,KAAK,QAAQ,IAC7B,UAAU,IAAIA,SAAS,EACvB;QACA,OAAOA,SAAS,CAACE,QAAQ;MAC3B;IACF;EACF,CAAC,MAAM,IAAI,OAAON,SAAS,KAAK,QAAQ,IAAI,UAAU,IAAIA,SAAS,EAAE;IACnE,OAAOA,SAAS,CAACM,QAAQ;EAC3B;EACA,OAAOL,SAAS;AAClB,CAAC","ignoreList":[]}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { type ColorValue, type StyleProp, type TextStyle } from 'react-native';
|
|
1
|
+
import { type ReactElement, type RefObject } from 'react';
|
|
2
|
+
import { FlatList, type ColorValue, type StyleProp, type TextStyle } from 'react-native';
|
|
3
3
|
import type { FlatListPropsWithLayout } from 'react-native-reanimated';
|
|
4
4
|
interface Props {
|
|
5
5
|
title: string;
|
|
@@ -14,6 +14,8 @@ interface Props {
|
|
|
14
14
|
navigationTitleTranslateY?: number;
|
|
15
15
|
}
|
|
16
16
|
type AnimatedHeaderFlatListProps<T> = Omit<FlatListPropsWithLayout<T>, keyof Props> & Props;
|
|
17
|
-
export declare
|
|
17
|
+
export declare const AnimatedHeaderFlatList: <T>(props: AnimatedHeaderFlatListProps<T> & {
|
|
18
|
+
ref?: RefObject<FlatList<T> | null>;
|
|
19
|
+
}) => ReactElement;
|
|
18
20
|
export {};
|
|
19
21
|
//# sourceMappingURL=AnimatedHeaderFlatList.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnimatedHeaderFlatList.d.ts","sourceRoot":"","sources":["../../../../src/components/AnimatedHeaderFlatList.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"AnimatedHeaderFlatList.d.ts","sourceRoot":"","sources":["../../../../src/components/AnimatedHeaderFlatList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,YAAY,EAAE,KAAK,SAAS,EAAc,MAAM,OAAO,CAAC;AACtE,OAAO,EACL,QAAQ,EAIR,KAAK,UAAU,EAGf,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AAEtB,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAMvE,UAAU,KAAK;IACb,KAAK,EAAE,MAAM,CAAC;IACd,kBAAkB,CAAC,EAAE,UAAU,CAAC;IAChC,gBAAgB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACxC,oBAAoB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC5C,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC;IACtC,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IACpC,eAAe,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IACtC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC;AAED,KAAK,2BAA2B,CAAC,CAAC,IAAI,IAAI,CACxC,uBAAuB,CAAC,CAAC,CAAC,EAC1B,MAAM,KAAK,CACZ,GACC,KAAK,CAAC;AA2RR,eAAO,MAAM,sBAAsB,EAE9B,CAAC,CAAC,EACL,KAAK,EAAE,2BAA2B,CAAC,CAAC,CAAC,GAAG;IACtC,GAAG,CAAC,EAAE,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;CACrC,KACE,YAAY,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useAnimatedHeaderFlatListAnimatedStyles.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useAnimatedHeaderFlatListAnimatedStyles.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,
|
|
1
|
+
{"version":3,"file":"useAnimatedHeaderFlatListAnimatedStyles.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useAnimatedHeaderFlatListAnimatedStyles.ts"],"names":[],"mappings":"AAEA,OAAO,EAEL,KAAK,eAAe,EACpB,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,EAML,KAAK,aAAa,EAClB,KAAK,sBAAsB,EAC5B,MAAM,yBAAyB,CAAC;AAGjC,KAAK,yCAAyC,GAAG;IAC/C,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAEF,KAAK,oCAAoC,GAAG;IAC1C,aAAa,EAAE,sBAAsB,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IAC/D,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,eAAe,CAAC;IAC9B,eAAe,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IACnD,iBAAiB,EAAE,eAAe,CAAC;IACnC,oBAAoB,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IACxD,qBAAqB,EAAE,eAAe,CAAC;IACvC,wBAAwB,EAAE,CAAC,MAAM,EAAE,eAAe,KAAK,IAAI,CAAC;IAC5D,4BAA4B,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACvD,0BAA0B,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACrD,4BAA4B,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACvD,wBAAwB,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACnD,yBAAyB,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACpD,0BAA0B,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACrD,6BAA6B,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;CACzD,CAAC;AAEF,eAAO,MAAM,uCAAuC,GAAI,yGAKrD,yCAAyC,KAAG,oCAmM9C,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-animated-header-flat-list",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.2",
|
|
4
4
|
"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.",
|
|
5
5
|
"source": "./src/index.tsx",
|
|
6
6
|
"main": "./lib/module/index.js",
|
|
@@ -62,31 +62,32 @@
|
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
64
|
"@commitlint/config-conventional": "^19.8.1",
|
|
65
|
-
"@eslint/compat": "^1.
|
|
65
|
+
"@eslint/compat": "^1.3.1",
|
|
66
66
|
"@eslint/eslintrc": "^3.3.1",
|
|
67
|
-
"@eslint/js": "^9.
|
|
67
|
+
"@eslint/js": "^9.32.0",
|
|
68
68
|
"@evilmartians/lefthook": "^1.5.0",
|
|
69
69
|
"@react-native/eslint-config": "^0.79.2",
|
|
70
70
|
"@react-navigation/elements": "^2.4.3",
|
|
71
71
|
"@react-navigation/native": "^7.1.10",
|
|
72
72
|
"@react-navigation/native-stack": "^7.3.14",
|
|
73
73
|
"@release-it/conventional-changelog": "^9.0.2",
|
|
74
|
-
"@types/jest": "^
|
|
75
|
-
"@types/react": "^19.1.
|
|
74
|
+
"@types/jest": "^30.0.0",
|
|
75
|
+
"@types/react": "^19.1.9",
|
|
76
76
|
"commitlint": "^19.8.1",
|
|
77
77
|
"del-cli": "^5.1.0",
|
|
78
78
|
"eslint": "^9.28.0",
|
|
79
|
-
"eslint-config-prettier": "^10.1.
|
|
80
|
-
"eslint-plugin-
|
|
81
|
-
"
|
|
82
|
-
"
|
|
83
|
-
"
|
|
84
|
-
"react
|
|
79
|
+
"eslint-config-prettier": "^10.1.8",
|
|
80
|
+
"eslint-plugin-ft-flow": "^3.0.11",
|
|
81
|
+
"eslint-plugin-prettier": "^5.5.4",
|
|
82
|
+
"jest": "^30.0.5",
|
|
83
|
+
"prettier": "^3.6.2",
|
|
84
|
+
"react": "18.3.1",
|
|
85
|
+
"react-native": "0.76.9",
|
|
85
86
|
"react-native-builder-bob": "0.37.0",
|
|
86
87
|
"react-native-reanimated": "^3.18.0",
|
|
87
|
-
"react-native-safe-area-context": "^5.
|
|
88
|
+
"react-native-safe-area-context": "^5.6.2",
|
|
88
89
|
"release-it": "^17.10.0",
|
|
89
|
-
"typescript": "^5.
|
|
90
|
+
"typescript": "^5.9.3"
|
|
90
91
|
},
|
|
91
92
|
"peerDependencies": {
|
|
92
93
|
"@react-navigation/elements": ">=2.0.0",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { type ReactElement, type RefObject, forwardRef } from 'react';
|
|
2
2
|
import {
|
|
3
|
+
FlatList,
|
|
3
4
|
StatusBar,
|
|
4
5
|
StyleSheet,
|
|
5
6
|
View,
|
|
@@ -37,19 +38,22 @@ type AnimatedHeaderFlatListProps<T> = Omit<
|
|
|
37
38
|
|
|
38
39
|
const HEADER_ITEM = 'REACT_NATIVE_ANIMATED_HEADER_FLAT_LIST_HEADER';
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
41
|
+
function AnimatedHeaderFlatListInner<T>(
|
|
42
|
+
{
|
|
43
|
+
title,
|
|
44
|
+
navigationBarColor,
|
|
45
|
+
headerTitleStyle,
|
|
46
|
+
navigationTitleStyle,
|
|
47
|
+
HeaderBackground,
|
|
48
|
+
HeaderContent,
|
|
49
|
+
StickyComponent,
|
|
50
|
+
parallax = true,
|
|
51
|
+
navigationTitleTranslateX = 0,
|
|
52
|
+
navigationTitleTranslateY = 0,
|
|
53
|
+
...flatListProps
|
|
54
|
+
}: AnimatedHeaderFlatListProps<T>,
|
|
55
|
+
ref: React.ForwardedRef<FlatList<T>>
|
|
56
|
+
) {
|
|
53
57
|
const navigation = useNavigation();
|
|
54
58
|
const {
|
|
55
59
|
scrollHandler,
|
|
@@ -96,73 +100,77 @@ export function AnimatedHeaderFlatList<T>({
|
|
|
96
100
|
});
|
|
97
101
|
}, [navigationTitle, navigation]);
|
|
98
102
|
|
|
99
|
-
const
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
<View
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
<Animated.View
|
|
112
|
-
style={parallax ? headerBackgroundAnimatedStyle : undefined}
|
|
103
|
+
const createHeaderComponent = useCallback(
|
|
104
|
+
(key: string) => {
|
|
105
|
+
return (
|
|
106
|
+
<View style={styles.headerWrapper} key={key}>
|
|
107
|
+
<View
|
|
108
|
+
style={[styles.headerContainer, { top: -navigationBarHeight }]}
|
|
109
|
+
onLayout={(event: LayoutChangeEvent) => {
|
|
110
|
+
setHeaderLayout({
|
|
111
|
+
...event.nativeEvent.layout,
|
|
112
|
+
height: event.nativeEvent.layout.height + navigationBarHeight,
|
|
113
|
+
});
|
|
114
|
+
}}
|
|
113
115
|
>
|
|
114
|
-
<HeaderBackground />
|
|
115
|
-
</Animated.View>
|
|
116
|
-
{HeaderContent && (
|
|
117
116
|
<Animated.View
|
|
118
|
-
style={
|
|
119
|
-
headerContentAnimatedStyle,
|
|
120
|
-
styles.headerContentContainer,
|
|
121
|
-
]}
|
|
117
|
+
style={parallax ? headerBackgroundAnimatedStyle : undefined}
|
|
122
118
|
>
|
|
123
|
-
<
|
|
119
|
+
<HeaderBackground />
|
|
124
120
|
</Animated.View>
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
121
|
+
{HeaderContent && (
|
|
122
|
+
<Animated.View
|
|
123
|
+
style={[
|
|
124
|
+
headerContentAnimatedStyle,
|
|
125
|
+
styles.headerContentContainer,
|
|
126
|
+
]}
|
|
127
|
+
>
|
|
128
|
+
<HeaderContent />
|
|
129
|
+
</Animated.View>
|
|
130
|
+
)}
|
|
131
|
+
{navigationBarColor && (
|
|
132
|
+
<Animated.View
|
|
133
|
+
style={[
|
|
134
|
+
navigationBarAnimatedStyle,
|
|
135
|
+
styles.animatedNavigationBar,
|
|
136
|
+
{ backgroundColor: navigationBarColor },
|
|
137
|
+
]}
|
|
138
|
+
/>
|
|
139
|
+
)}
|
|
140
|
+
<Animated.Text
|
|
141
|
+
key={`${key}-title`}
|
|
142
|
+
onLayout={(event: LayoutChangeEvent) => {
|
|
143
|
+
setHeaderTitleLayout(event.nativeEvent.layout);
|
|
144
|
+
}}
|
|
145
|
+
numberOfLines={1}
|
|
128
146
|
style={[
|
|
129
|
-
|
|
130
|
-
styles.
|
|
131
|
-
|
|
147
|
+
headerTitleAnimatedStyle,
|
|
148
|
+
styles.headerTitle,
|
|
149
|
+
headerTitleStyle,
|
|
132
150
|
]}
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
setHeaderTitleLayout(event.nativeEvent.layout);
|
|
138
|
-
}}
|
|
139
|
-
numberOfLines={1}
|
|
140
|
-
style={[
|
|
141
|
-
headerTitleAnimatedStyle,
|
|
142
|
-
styles.headerTitle,
|
|
143
|
-
headerTitleStyle,
|
|
144
|
-
]}
|
|
145
|
-
>
|
|
146
|
-
{title}
|
|
147
|
-
</Animated.Text>
|
|
151
|
+
>
|
|
152
|
+
{title}
|
|
153
|
+
</Animated.Text>
|
|
154
|
+
</View>
|
|
148
155
|
</View>
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
156
|
+
);
|
|
157
|
+
},
|
|
158
|
+
[
|
|
159
|
+
navigationBarHeight,
|
|
160
|
+
parallax,
|
|
161
|
+
headerBackgroundAnimatedStyle,
|
|
162
|
+
HeaderBackground,
|
|
163
|
+
HeaderContent,
|
|
164
|
+
headerContentAnimatedStyle,
|
|
165
|
+
headerTitleAnimatedStyle,
|
|
166
|
+
headerTitleStyle,
|
|
167
|
+
title,
|
|
168
|
+
setHeaderLayout,
|
|
169
|
+
setHeaderTitleLayout,
|
|
170
|
+
navigationBarAnimatedStyle,
|
|
171
|
+
navigationBarColor,
|
|
172
|
+
]
|
|
173
|
+
);
|
|
166
174
|
|
|
167
175
|
type CustomItem = typeof HEADER_ITEM | T;
|
|
168
176
|
|
|
@@ -190,7 +198,7 @@ export function AnimatedHeaderFlatList<T>({
|
|
|
190
198
|
},
|
|
191
199
|
]}
|
|
192
200
|
>
|
|
193
|
-
{
|
|
201
|
+
{createHeaderComponent('sticky')}
|
|
194
202
|
</Animated.View>
|
|
195
203
|
{StickyComponent && (
|
|
196
204
|
<Animated.View
|
|
@@ -220,7 +228,7 @@ export function AnimatedHeaderFlatList<T>({
|
|
|
220
228
|
stickyComponentAnimatedStyle,
|
|
221
229
|
stickyHeaderAnimatedStyle,
|
|
222
230
|
headerLayout.height,
|
|
223
|
-
|
|
231
|
+
createHeaderComponent,
|
|
224
232
|
StickyComponent,
|
|
225
233
|
setStickyComponentLayout,
|
|
226
234
|
]
|
|
@@ -238,6 +246,7 @@ export function AnimatedHeaderFlatList<T>({
|
|
|
238
246
|
<StatusBar backgroundColor="transparent" translucent />
|
|
239
247
|
<Animated.FlatList
|
|
240
248
|
{...flatListProps}
|
|
249
|
+
ref={ref}
|
|
241
250
|
stickyHeaderIndices={[1]}
|
|
242
251
|
ListHeaderComponent={
|
|
243
252
|
<Animated.View
|
|
@@ -249,7 +258,7 @@ export function AnimatedHeaderFlatList<T>({
|
|
|
249
258
|
},
|
|
250
259
|
]}
|
|
251
260
|
>
|
|
252
|
-
{
|
|
261
|
+
{createHeaderComponent('main')}
|
|
253
262
|
</Animated.View>
|
|
254
263
|
}
|
|
255
264
|
onScroll={scrollHandler}
|
|
@@ -307,3 +316,11 @@ const styles = StyleSheet.create({
|
|
|
307
316
|
bottom: 0,
|
|
308
317
|
},
|
|
309
318
|
});
|
|
319
|
+
|
|
320
|
+
export const AnimatedHeaderFlatList = forwardRef(
|
|
321
|
+
AnimatedHeaderFlatListInner
|
|
322
|
+
) as <T>(
|
|
323
|
+
props: AnimatedHeaderFlatListProps<T> & {
|
|
324
|
+
ref?: RefObject<FlatList<T> | null>;
|
|
325
|
+
}
|
|
326
|
+
) => ReactElement;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useHeaderHeight } from '@react-navigation/elements';
|
|
2
|
-
import { useCallback, useState } from 'react';
|
|
2
|
+
import { useCallback, useState, useEffect } from 'react';
|
|
3
3
|
import {
|
|
4
4
|
useWindowDimensions,
|
|
5
5
|
type LayoutRectangle,
|
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
useAnimatedScrollHandler,
|
|
11
11
|
useAnimatedStyle,
|
|
12
12
|
useSharedValue,
|
|
13
|
+
cancelAnimation,
|
|
13
14
|
type AnimatedStyle,
|
|
14
15
|
type ScrollHandlerProcessed,
|
|
15
16
|
} from 'react-native-reanimated';
|
|
@@ -69,10 +70,12 @@ export const useAnimatedHeaderFlatListAnimatedStyles = ({
|
|
|
69
70
|
width: 0,
|
|
70
71
|
height: 0,
|
|
71
72
|
});
|
|
72
|
-
const distanceBetweenTitleAndNavigationBar =
|
|
73
|
+
const distanceBetweenTitleAndNavigationBar = Math.max(
|
|
74
|
+
0,
|
|
73
75
|
(navigationBarHeight - safeAreaInsets.top + headerTitleLayout.height) / 2 +
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
headerTitleLayout.y -
|
|
77
|
+
navigationBarHeight
|
|
78
|
+
);
|
|
76
79
|
const navigationTitleOpacity = useSharedValue(0);
|
|
77
80
|
const stickyHeaderOpacity = useSharedValue(0);
|
|
78
81
|
const stickyComponentOpacity = useSharedValue(0);
|
|
@@ -207,6 +210,20 @@ export const useAnimatedHeaderFlatListAnimatedStyles = ({
|
|
|
207
210
|
: 0;
|
|
208
211
|
});
|
|
209
212
|
|
|
213
|
+
useEffect(() => {
|
|
214
|
+
return () => {
|
|
215
|
+
cancelAnimation(scrollY);
|
|
216
|
+
cancelAnimation(navigationTitleOpacity);
|
|
217
|
+
cancelAnimation(stickyHeaderOpacity);
|
|
218
|
+
cancelAnimation(stickyComponentOpacity);
|
|
219
|
+
};
|
|
220
|
+
}, [
|
|
221
|
+
scrollY,
|
|
222
|
+
navigationTitleOpacity,
|
|
223
|
+
stickyHeaderOpacity,
|
|
224
|
+
stickyComponentOpacity,
|
|
225
|
+
]);
|
|
226
|
+
|
|
210
227
|
return {
|
|
211
228
|
scrollHandler,
|
|
212
229
|
navigationBarHeight,
|
package/src/utils/styleUtils.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { type StyleProp, type TextStyle } from 'react-native';
|
|
|
3
3
|
export const getFontSizeFromStyle = (textStyle: StyleProp<TextStyle>) => {
|
|
4
4
|
if (!textStyle) return undefined;
|
|
5
5
|
if (Array.isArray(textStyle)) {
|
|
6
|
-
for (const styleItem of textStyle.
|
|
6
|
+
for (const styleItem of textStyle.toReversed()) {
|
|
7
7
|
if (
|
|
8
8
|
styleItem &&
|
|
9
9
|
typeof styleItem === 'object' &&
|