@orionarm/react-native-collapse-tabs 1.0.3 → 1.0.4
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/lib/CollapseTabs.d.ts.map +1 -1
- package/lib/CollapseTabs.js +3 -5
- package/lib/FlatList.d.ts +1 -1
- package/lib/FlatList.d.ts.map +1 -1
- package/lib/FlatList.js +16 -8
- package/lib/ScrollView.d.ts +1 -1
- package/lib/ScrollView.d.ts.map +1 -1
- package/lib/ScrollView.js +16 -8
- package/package.json +1 -1
- package/src/CollapseTabs.tsx +25 -28
- package/src/FlatList.tsx +25 -8
- package/src/ScrollView.tsx +20 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CollapseTabs.d.ts","sourceRoot":"","sources":["../src/CollapseTabs.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"CollapseTabs.d.ts","sourceRoot":"","sources":["../src/CollapseTabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAiD,MAAM,OAAO,CAAC;AAkBtE,OAAO,EACL,iBAAiB,EAOlB,MAAM,eAAe,CAAC;AAIvB,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC,iBAAiB,CAkLpD,CAAC"}
|
package/lib/CollapseTabs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useCallback, useMemo, useRef, useState
|
|
1
|
+
import React, { useCallback, useMemo, useRef, useState } from "react";
|
|
2
2
|
import { StyleSheet, View } from "react-native";
|
|
3
3
|
import PagerView from "react-native-pager-view";
|
|
4
4
|
import Animated, { useAnimatedReaction, useAnimatedStyle, useEvent, useHandler, useSharedValue, withTiming, } from "react-native-reanimated";
|
|
@@ -25,7 +25,7 @@ export const CollapseTabs = ({ children, initialTabName, headerHeight, tabBarHei
|
|
|
25
25
|
const y = scrollY.value[tab] ?? 0;
|
|
26
26
|
return {
|
|
27
27
|
tab,
|
|
28
|
-
translateY: -Math.min(y, headerScrollDistance),
|
|
28
|
+
translateY: -Math.min(Math.max(y, 0), headerScrollDistance),
|
|
29
29
|
};
|
|
30
30
|
}, (next, prev) => {
|
|
31
31
|
if (prev && prev.tab !== next.tab) {
|
|
@@ -103,9 +103,7 @@ export const CollapseTabs = ({ children, initialTabName, headerHeight, tabBarHei
|
|
|
103
103
|
{renderHeader?.(headerProps)}
|
|
104
104
|
</View>
|
|
105
105
|
<View style={{ height: tabBarHeight }}>
|
|
106
|
-
{renderTabBar
|
|
107
|
-
? renderTabBar(headerProps)
|
|
108
|
-
: <DefaultTabBar {...headerProps}/>}
|
|
106
|
+
{renderTabBar ? (renderTabBar(headerProps)) : (<DefaultTabBar {...headerProps}/>)}
|
|
109
107
|
</View>
|
|
110
108
|
</Animated.View>
|
|
111
109
|
</View>
|
package/lib/FlatList.d.ts
CHANGED
|
@@ -3,6 +3,6 @@ import { FlatListProps } from "react-native";
|
|
|
3
3
|
type Props<T> = FlatListProps<T> & {
|
|
4
4
|
name: string;
|
|
5
5
|
};
|
|
6
|
-
export declare function FlatList<T>({ name, contentContainerStyle, ...rest }: Props<T>): React.JSX.Element;
|
|
6
|
+
export declare function FlatList<T>({ name, contentContainerStyle, onScroll: userOnScroll, ...rest }: Props<T>): React.JSX.Element;
|
|
7
7
|
export {};
|
|
8
8
|
//# sourceMappingURL=FlatList.d.ts.map
|
package/lib/FlatList.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlatList.d.ts","sourceRoot":"","sources":["../src/FlatList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,EAA0B,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"FlatList.d.ts","sourceRoot":"","sources":["../src/FlatList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,EAA0B,aAAa,EAAE,MAAM,cAAc,CAAC;AAQrE,KAAK,KAAK,CAAC,CAAC,IAAI,aAAa,CAAC,CAAC,CAAC,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,EAC1B,IAAI,EACJ,qBAAqB,EACrB,QAAQ,EAAE,YAAY,EACtB,GAAG,IAAI,EACR,EAAE,KAAK,CAAC,CAAC,CAAC,qBA+CV"}
|
package/lib/FlatList.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
|
-
import Animated, { useAnimatedRef, useAnimatedScrollHandler, } from "react-native-reanimated";
|
|
2
|
+
import Animated, { runOnJS, useAnimatedRef, useAnimatedScrollHandler, } from "react-native-reanimated";
|
|
3
3
|
import { useTabsContext } from "./hooks";
|
|
4
|
-
export function FlatList({ name, contentContainerStyle, ...rest }) {
|
|
4
|
+
export function FlatList({ name, contentContainerStyle, onScroll: userOnScroll, ...rest }) {
|
|
5
5
|
const { headerHeight, tabBarHeight, scrollY, focusedTab, setRef, } = useTabsContext();
|
|
6
6
|
const ref = useAnimatedRef();
|
|
7
7
|
useEffect(() => {
|
|
@@ -9,13 +9,21 @@ export function FlatList({ name, contentContainerStyle, ...rest }) {
|
|
|
9
9
|
}, [name, ref, setRef]);
|
|
10
10
|
const handler = useAnimatedScrollHandler({
|
|
11
11
|
onScroll: (event) => {
|
|
12
|
-
if (focusedTab.value
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
if (focusedTab.value === name) {
|
|
13
|
+
const map = { ...scrollY.value };
|
|
14
|
+
map[name] = event.contentOffset.y;
|
|
15
|
+
scrollY.value = map;
|
|
16
|
+
}
|
|
17
|
+
if (userOnScroll) {
|
|
18
|
+
if (userOnScroll.worklet === true) {
|
|
19
|
+
userOnScroll(event);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
runOnJS(userOnScroll)(event);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
17
25
|
},
|
|
18
|
-
});
|
|
26
|
+
}, [name, userOnScroll]);
|
|
19
27
|
return (<Animated.FlatList {...rest} ref={ref} onScroll={handler} scrollEventThrottle={16} contentContainerStyle={[
|
|
20
28
|
{ paddingTop: headerHeight + tabBarHeight },
|
|
21
29
|
contentContainerStyle,
|
package/lib/ScrollView.d.ts
CHANGED
|
@@ -4,6 +4,6 @@ type Props = ScrollViewProps & {
|
|
|
4
4
|
name: string;
|
|
5
5
|
children?: React.ReactNode;
|
|
6
6
|
};
|
|
7
|
-
export declare function ScrollView({ name, contentContainerStyle, children, ...rest }: Props): React.JSX.Element;
|
|
7
|
+
export declare function ScrollView({ name, contentContainerStyle, children, onScroll: userOnScroll, ...rest }: Props): React.JSX.Element;
|
|
8
8
|
export {};
|
|
9
9
|
//# sourceMappingURL=ScrollView.d.ts.map
|
package/lib/ScrollView.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ScrollView.d.ts","sourceRoot":"","sources":["../src/ScrollView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,eAAe,EAA8B,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"ScrollView.d.ts","sourceRoot":"","sources":["../src/ScrollView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAoB,MAAM,OAAO,CAAC;AACzC,OAAO,EAAE,eAAe,EAA8B,MAAM,cAAc,CAAC;AAQ3E,KAAK,KAAK,GAAG,eAAe,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAAE,CAAC;AAE5E,wBAAgB,UAAU,CAAC,EACzB,IAAI,EACJ,qBAAqB,EACrB,QAAQ,EACR,QAAQ,EAAE,YAAY,EACtB,GAAG,IAAI,EACR,EAAE,KAAK,qBAiDP"}
|
package/lib/ScrollView.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
|
-
import Animated, { useAnimatedRef, useAnimatedScrollHandler, } from "react-native-reanimated";
|
|
2
|
+
import Animated, { runOnJS, useAnimatedRef, useAnimatedScrollHandler, } from "react-native-reanimated";
|
|
3
3
|
import { useTabsContext } from "./hooks";
|
|
4
|
-
export function ScrollView({ name, contentContainerStyle, children, ...rest }) {
|
|
4
|
+
export function ScrollView({ name, contentContainerStyle, children, onScroll: userOnScroll, ...rest }) {
|
|
5
5
|
const { headerHeight, tabBarHeight, scrollY, focusedTab, setRef, } = useTabsContext();
|
|
6
6
|
const ref = useAnimatedRef();
|
|
7
7
|
useEffect(() => {
|
|
@@ -9,13 +9,21 @@ export function ScrollView({ name, contentContainerStyle, children, ...rest }) {
|
|
|
9
9
|
}, [name, ref, setRef]);
|
|
10
10
|
const handler = useAnimatedScrollHandler({
|
|
11
11
|
onScroll: (event) => {
|
|
12
|
-
if (focusedTab.value
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
if (focusedTab.value === name) {
|
|
13
|
+
const map = { ...scrollY.value };
|
|
14
|
+
map[name] = event.contentOffset.y;
|
|
15
|
+
scrollY.value = map;
|
|
16
|
+
}
|
|
17
|
+
if (userOnScroll) {
|
|
18
|
+
if (userOnScroll.worklet === true) {
|
|
19
|
+
userOnScroll(event);
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
runOnJS(userOnScroll)(event);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
17
25
|
},
|
|
18
|
-
});
|
|
26
|
+
}, [name, userOnScroll]);
|
|
19
27
|
return (<Animated.ScrollView {...rest} ref={ref} onScroll={handler} scrollEventThrottle={16} contentContainerStyle={[
|
|
20
28
|
{ paddingTop: headerHeight + tabBarHeight },
|
|
21
29
|
contentContainerStyle,
|
package/package.json
CHANGED
package/src/CollapseTabs.tsx
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
2
|
-
useCallback,
|
|
3
|
-
useMemo,
|
|
4
|
-
useRef,
|
|
5
|
-
useState,
|
|
6
|
-
} from "react";
|
|
1
|
+
import React, { useCallback, useMemo, useRef, useState } from "react";
|
|
7
2
|
import { StyleSheet, View } from "react-native";
|
|
8
3
|
import PagerView, {
|
|
9
4
|
PagerViewOnPageScrollEventData,
|
|
@@ -48,20 +43,20 @@ export const CollapseTabs: React.FC<CollapseTabsProps> = ({
|
|
|
48
43
|
}) => {
|
|
49
44
|
const tabs = useMemo(
|
|
50
45
|
() =>
|
|
51
|
-
React.Children.toArray(children).filter(
|
|
52
|
-
|
|
46
|
+
React.Children.toArray(children).filter((c): c is TabReactElement =>
|
|
47
|
+
React.isValidElement(c),
|
|
53
48
|
),
|
|
54
|
-
[children]
|
|
49
|
+
[children],
|
|
55
50
|
);
|
|
56
51
|
|
|
57
52
|
const tabNames = useMemo(
|
|
58
53
|
() => tabs.map((t) => (t.props as TabProps).name),
|
|
59
|
-
[tabs]
|
|
54
|
+
[tabs],
|
|
60
55
|
);
|
|
61
56
|
|
|
62
57
|
const initialIndex = Math.max(
|
|
63
58
|
0,
|
|
64
|
-
initialTabName ? tabNames.indexOf(initialTabName) : 0
|
|
59
|
+
initialTabName ? tabNames.indexOf(initialTabName) : 0,
|
|
65
60
|
);
|
|
66
61
|
|
|
67
62
|
const headerScrollDistance = headerHeight - minHeaderHeight;
|
|
@@ -85,7 +80,7 @@ export const CollapseTabs: React.FC<CollapseTabsProps> = ({
|
|
|
85
80
|
const y = scrollY.value[tab] ?? 0;
|
|
86
81
|
return {
|
|
87
82
|
tab,
|
|
88
|
-
translateY: -Math.min(y, headerScrollDistance),
|
|
83
|
+
translateY: -Math.min(Math.max(y, 0), headerScrollDistance),
|
|
89
84
|
};
|
|
90
85
|
},
|
|
91
86
|
(next, prev) => {
|
|
@@ -95,7 +90,7 @@ export const CollapseTabs: React.FC<CollapseTabsProps> = ({
|
|
|
95
90
|
headerTranslateY.value = next.translateY;
|
|
96
91
|
}
|
|
97
92
|
},
|
|
98
|
-
[headerScrollDistance]
|
|
93
|
+
[headerScrollDistance],
|
|
99
94
|
);
|
|
100
95
|
|
|
101
96
|
const refMap = useRef<Record<TabName, AnimatedRef<RefComponent>>>({}).current;
|
|
@@ -105,16 +100,19 @@ export const CollapseTabs: React.FC<CollapseTabsProps> = ({
|
|
|
105
100
|
refMap[key] = ref as unknown as AnimatedRef<RefComponent>;
|
|
106
101
|
return ref;
|
|
107
102
|
},
|
|
108
|
-
[refMap]
|
|
103
|
+
[refMap],
|
|
109
104
|
);
|
|
110
105
|
|
|
111
106
|
const containerRef = useRef<ContainerRef>(null);
|
|
112
107
|
|
|
113
|
-
const onTabPress = useCallback(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
108
|
+
const onTabPress = useCallback(
|
|
109
|
+
(name: TabName) => {
|
|
110
|
+
const i = tabNames.indexOf(name);
|
|
111
|
+
if (i < 0) return;
|
|
112
|
+
containerRef.current?.setPage(i);
|
|
113
|
+
},
|
|
114
|
+
[tabNames],
|
|
115
|
+
);
|
|
118
116
|
|
|
119
117
|
const [renderIndex, setRenderIndex] = useState(initialIndex);
|
|
120
118
|
|
|
@@ -125,7 +123,7 @@ export const CollapseTabs: React.FC<CollapseTabsProps> = ({
|
|
|
125
123
|
indexDecimal.value = e.position + e.offset;
|
|
126
124
|
},
|
|
127
125
|
["onPageScroll"],
|
|
128
|
-
doDependenciesDiffer
|
|
126
|
+
doDependenciesDiffer,
|
|
129
127
|
);
|
|
130
128
|
|
|
131
129
|
const onPageSelected = useCallback(
|
|
@@ -136,7 +134,7 @@ export const CollapseTabs: React.FC<CollapseTabsProps> = ({
|
|
|
136
134
|
setRenderIndex(i);
|
|
137
135
|
onIndexChange?.(i);
|
|
138
136
|
},
|
|
139
|
-
[tabNames, index, focusedTab, onIndexChange]
|
|
137
|
+
[tabNames, index, focusedTab, onIndexChange],
|
|
140
138
|
);
|
|
141
139
|
|
|
142
140
|
const headerAnimStyle = useAnimatedStyle(() => ({
|
|
@@ -194,16 +192,15 @@ export const CollapseTabs: React.FC<CollapseTabsProps> = ({
|
|
|
194
192
|
headerAnimStyle,
|
|
195
193
|
]}
|
|
196
194
|
>
|
|
197
|
-
<View
|
|
198
|
-
pointerEvents="box-none"
|
|
199
|
-
style={{ height: headerHeight }}
|
|
200
|
-
>
|
|
195
|
+
<View pointerEvents="box-none" style={{ height: headerHeight }}>
|
|
201
196
|
{renderHeader?.(headerProps)}
|
|
202
197
|
</View>
|
|
203
198
|
<View style={{ height: tabBarHeight }}>
|
|
204
|
-
{renderTabBar
|
|
205
|
-
|
|
206
|
-
|
|
199
|
+
{renderTabBar ? (
|
|
200
|
+
renderTabBar(headerProps)
|
|
201
|
+
) : (
|
|
202
|
+
<DefaultTabBar {...headerProps} />
|
|
203
|
+
)}
|
|
207
204
|
</View>
|
|
208
205
|
</Animated.View>
|
|
209
206
|
</View>
|
package/src/FlatList.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
2
|
import { FlatList as RNFlatList, FlatListProps } from "react-native";
|
|
3
3
|
import Animated, {
|
|
4
|
+
runOnJS,
|
|
4
5
|
useAnimatedRef,
|
|
5
6
|
useAnimatedScrollHandler,
|
|
6
7
|
} from "react-native-reanimated";
|
|
@@ -8,7 +9,12 @@ import { useTabsContext } from "./hooks";
|
|
|
8
9
|
|
|
9
10
|
type Props<T> = FlatListProps<T> & { name: string };
|
|
10
11
|
|
|
11
|
-
export function FlatList<T>({
|
|
12
|
+
export function FlatList<T>({
|
|
13
|
+
name,
|
|
14
|
+
contentContainerStyle,
|
|
15
|
+
onScroll: userOnScroll,
|
|
16
|
+
...rest
|
|
17
|
+
}: Props<T>) {
|
|
12
18
|
const {
|
|
13
19
|
headerHeight,
|
|
14
20
|
tabBarHeight,
|
|
@@ -23,14 +29,25 @@ export function FlatList<T>({ name, contentContainerStyle, ...rest }: Props<T>)
|
|
|
23
29
|
setRef(name, ref);
|
|
24
30
|
}, [name, ref, setRef]);
|
|
25
31
|
|
|
26
|
-
const handler = useAnimatedScrollHandler(
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
+
const handler = useAnimatedScrollHandler(
|
|
33
|
+
{
|
|
34
|
+
onScroll: (event) => {
|
|
35
|
+
if (focusedTab.value === name) {
|
|
36
|
+
const map = { ...scrollY.value };
|
|
37
|
+
map[name] = event.contentOffset.y;
|
|
38
|
+
scrollY.value = map;
|
|
39
|
+
}
|
|
40
|
+
if (userOnScroll) {
|
|
41
|
+
if ((userOnScroll as any).worklet === true) {
|
|
42
|
+
(userOnScroll as any)(event);
|
|
43
|
+
} else {
|
|
44
|
+
runOnJS(userOnScroll as any)(event);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
},
|
|
32
48
|
},
|
|
33
|
-
|
|
49
|
+
[name, userOnScroll],
|
|
50
|
+
);
|
|
34
51
|
|
|
35
52
|
return (
|
|
36
53
|
<Animated.FlatList
|
package/src/ScrollView.tsx
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
2
|
import { ScrollViewProps, ScrollView as RNScrollView } from "react-native";
|
|
3
3
|
import Animated, {
|
|
4
|
+
runOnJS,
|
|
4
5
|
useAnimatedRef,
|
|
5
6
|
useAnimatedScrollHandler,
|
|
6
7
|
} from "react-native-reanimated";
|
|
@@ -12,6 +13,7 @@ export function ScrollView({
|
|
|
12
13
|
name,
|
|
13
14
|
contentContainerStyle,
|
|
14
15
|
children,
|
|
16
|
+
onScroll: userOnScroll,
|
|
15
17
|
...rest
|
|
16
18
|
}: Props) {
|
|
17
19
|
const {
|
|
@@ -28,14 +30,25 @@ export function ScrollView({
|
|
|
28
30
|
setRef(name, ref);
|
|
29
31
|
}, [name, ref, setRef]);
|
|
30
32
|
|
|
31
|
-
const handler = useAnimatedScrollHandler(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
const handler = useAnimatedScrollHandler(
|
|
34
|
+
{
|
|
35
|
+
onScroll: (event) => {
|
|
36
|
+
if (focusedTab.value === name) {
|
|
37
|
+
const map = { ...scrollY.value };
|
|
38
|
+
map[name] = event.contentOffset.y;
|
|
39
|
+
scrollY.value = map;
|
|
40
|
+
}
|
|
41
|
+
if (userOnScroll) {
|
|
42
|
+
if ((userOnScroll as any).worklet === true) {
|
|
43
|
+
(userOnScroll as any)(event);
|
|
44
|
+
} else {
|
|
45
|
+
runOnJS(userOnScroll as any)(event);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
},
|
|
37
49
|
},
|
|
38
|
-
|
|
50
|
+
[name, userOnScroll],
|
|
51
|
+
);
|
|
39
52
|
|
|
40
53
|
return (
|
|
41
54
|
<Animated.ScrollView
|