@r0b0t3d/react-native-collapsible 1.3.5-beta.3 → 1.3.5-beta.5
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/commonjs/components/CollapsibleContainer.js +3 -2
- package/lib/commonjs/components/CollapsibleContainer.js.map +1 -1
- package/lib/commonjs/components/header/CollapsibleHeaderConsumer.js +65 -0
- package/lib/commonjs/components/header/CollapsibleHeaderConsumer.js.map +1 -0
- package/lib/commonjs/components/header/CollapsibleHeaderContainer.js +24 -86
- package/lib/commonjs/components/header/CollapsibleHeaderContainer.js.map +1 -1
- package/lib/commonjs/components/header/CollapsibleHeaderContainerProvider.js +105 -0
- package/lib/commonjs/components/header/CollapsibleHeaderContainerProvider.js.map +1 -0
- package/lib/commonjs/components/header/StickyView.js +0 -6
- package/lib/commonjs/components/header/StickyView.js.map +1 -1
- package/lib/commonjs/hooks/useCollapsibleHeaderConsumerContext.js +21 -0
- package/lib/commonjs/hooks/useCollapsibleHeaderConsumerContext.js.map +1 -0
- package/lib/commonjs/withCollapsibleContext.js +0 -2
- package/lib/commonjs/withCollapsibleContext.js.map +1 -1
- package/lib/module/components/CollapsibleContainer.js +3 -2
- package/lib/module/components/CollapsibleContainer.js.map +1 -1
- package/lib/module/components/header/CollapsibleHeaderConsumer.js +57 -0
- package/lib/module/components/header/CollapsibleHeaderConsumer.js.map +1 -0
- package/lib/module/components/header/CollapsibleHeaderContainer.js +25 -87
- package/lib/module/components/header/CollapsibleHeaderContainer.js.map +1 -1
- package/lib/module/components/header/CollapsibleHeaderContainerProvider.js +96 -0
- package/lib/module/components/header/CollapsibleHeaderContainerProvider.js.map +1 -0
- package/lib/module/components/header/StickyView.js +0 -6
- package/lib/module/components/header/StickyView.js.map +1 -1
- package/lib/module/hooks/useCollapsibleHeaderConsumerContext.js +13 -0
- package/lib/module/hooks/useCollapsibleHeaderConsumerContext.js.map +1 -0
- package/lib/module/withCollapsibleContext.js +0 -2
- package/lib/module/withCollapsibleContext.js.map +1 -1
- package/lib/typescript/components/CollapsibleContainer.d.ts.map +1 -1
- package/lib/typescript/components/header/CollapsibleHeaderConsumer.d.ts +9 -0
- package/lib/typescript/components/header/CollapsibleHeaderConsumer.d.ts.map +1 -0
- package/lib/typescript/components/header/CollapsibleHeaderContainer.d.ts +2 -2
- package/lib/typescript/components/header/CollapsibleHeaderContainer.d.ts.map +1 -1
- package/lib/typescript/components/header/CollapsibleHeaderContainerProvider.d.ts +10 -0
- package/lib/typescript/components/header/CollapsibleHeaderContainerProvider.d.ts.map +1 -0
- package/lib/typescript/components/header/StickyView.d.ts.map +1 -1
- package/lib/typescript/hooks/useCollapsibleHeaderConsumerContext.d.ts +15 -0
- package/lib/typescript/hooks/useCollapsibleHeaderConsumerContext.d.ts.map +1 -0
- package/lib/typescript/types.d.ts +1 -2
- package/lib/typescript/types.d.ts.map +1 -1
- package/lib/typescript/withCollapsibleContext.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/components/CollapsibleContainer.tsx +4 -3
- package/src/components/header/CollapsibleHeaderConsumer.tsx +78 -0
- package/src/components/header/CollapsibleHeaderContainer.tsx +27 -145
- package/src/components/header/CollapsibleHeaderContainerProvider.tsx +162 -0
- package/src/components/header/StickyView.tsx +0 -2
- package/src/hooks/useCollapsibleHeaderConsumerContext.ts +22 -0
- package/src/types.ts +1 -2
- package/src/withCollapsibleContext.tsx +0 -2
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import React, {
|
|
2
|
+
ReactNode,
|
|
3
|
+
useCallback,
|
|
4
|
+
useEffect,
|
|
5
|
+
useMemo,
|
|
6
|
+
useRef,
|
|
7
|
+
useState,
|
|
8
|
+
} from 'react';
|
|
9
|
+
import { StyleSheet, View } from 'react-native';
|
|
10
|
+
import { CollapsibleHeaderConsumerContext } from '../../hooks/useCollapsibleHeaderConsumerContext';
|
|
11
|
+
|
|
12
|
+
export type HeaderItem = { key: string; children: ReactNode };
|
|
13
|
+
|
|
14
|
+
export default function CollapsibleHeaderConsumer({
|
|
15
|
+
children,
|
|
16
|
+
}: {
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}) {
|
|
19
|
+
const [headers, setHeaders] = useState<HeaderItem[]>([]);
|
|
20
|
+
const mounted = useRef(false);
|
|
21
|
+
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
mounted.current = true;
|
|
24
|
+
return () => {
|
|
25
|
+
mounted.current = false;
|
|
26
|
+
};
|
|
27
|
+
}, []);
|
|
28
|
+
|
|
29
|
+
const mount = useCallback((key: string, children: ReactNode) => {
|
|
30
|
+
setHeaders((prev) => [...prev, { key, children }]);
|
|
31
|
+
}, []);
|
|
32
|
+
|
|
33
|
+
const unmount = useCallback((key: string) => {
|
|
34
|
+
setHeaders((prev) => prev.filter((h) => h.key !== key));
|
|
35
|
+
}, []);
|
|
36
|
+
|
|
37
|
+
const update = useCallback((key: string, children: ReactNode) => {
|
|
38
|
+
if (!mounted.current) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
setHeaders((prev) =>
|
|
42
|
+
prev.map((item) => {
|
|
43
|
+
if (item.key === key) {
|
|
44
|
+
return {
|
|
45
|
+
...item,
|
|
46
|
+
children,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return item;
|
|
50
|
+
})
|
|
51
|
+
);
|
|
52
|
+
}, []);
|
|
53
|
+
|
|
54
|
+
const context = useMemo(
|
|
55
|
+
() => ({
|
|
56
|
+
headers,
|
|
57
|
+
mount,
|
|
58
|
+
unmount,
|
|
59
|
+
update,
|
|
60
|
+
}),
|
|
61
|
+
[headers, mount, unmount, update]
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<CollapsibleHeaderConsumerContext.Provider value={context}>
|
|
66
|
+
{children}
|
|
67
|
+
<View style={styles.container} pointerEvents="box-none">
|
|
68
|
+
{headers.map((item) => item.children)}
|
|
69
|
+
</View>
|
|
70
|
+
</CollapsibleHeaderConsumerContext.Provider>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const styles = StyleSheet.create({
|
|
75
|
+
container: {
|
|
76
|
+
zIndex: 10,
|
|
77
|
+
},
|
|
78
|
+
});
|
|
@@ -1,27 +1,7 @@
|
|
|
1
|
-
import React, { ReactNode,
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
LayoutChangeEvent,
|
|
6
|
-
LayoutRectangle,
|
|
7
|
-
StyleSheet,
|
|
8
|
-
} from 'react-native';
|
|
9
|
-
import useInternalCollapsibleContext from '../../hooks/useInternalCollapsibleContext';
|
|
10
|
-
import useCollapsibleContext from '../../hooks/useCollapsibleContext';
|
|
11
|
-
import Animated, {
|
|
12
|
-
Extrapolate,
|
|
13
|
-
interpolate,
|
|
14
|
-
runOnJS,
|
|
15
|
-
useAnimatedReaction,
|
|
16
|
-
useAnimatedStyle,
|
|
17
|
-
useDerivedValue,
|
|
18
|
-
useSharedValue,
|
|
19
|
-
} from 'react-native-reanimated';
|
|
20
|
-
import {
|
|
21
|
-
CollapsibleContextHeaderType,
|
|
22
|
-
CollapsibleHeaderContext,
|
|
23
|
-
} from '../../hooks/useCollapsibleHeaderContext';
|
|
24
|
-
import useSharedValueRef from '../../utils/useSharedValueRef';
|
|
1
|
+
import React, { ReactNode, useEffect, useMemo } from 'react';
|
|
2
|
+
import { StyleProp, ViewStyle } from 'react-native';
|
|
3
|
+
import useCollapsibleHeaderConsumerContext from '../../hooks/useCollapsibleHeaderConsumerContext';
|
|
4
|
+
import CollapsibleHeaderContainerProvider from './CollapsibleHeaderContainerProvider';
|
|
25
5
|
|
|
26
6
|
type Props = {
|
|
27
7
|
children: ReactNode;
|
|
@@ -35,65 +15,7 @@ export default function CollapsibleHeaderContainer({
|
|
|
35
15
|
containerStyle,
|
|
36
16
|
}: Props) {
|
|
37
17
|
const contentKey = useMemo(() => `collapsible-header-${key++}`, []);
|
|
38
|
-
const {
|
|
39
|
-
useInternalCollapsibleContext();
|
|
40
|
-
const { scrollY } = useCollapsibleContext();
|
|
41
|
-
const currentLayout = useSharedValue<LayoutRectangle | undefined>(undefined);
|
|
42
|
-
const [stickyLayouts, setStickyLayouts] = useSharedValueRef<
|
|
43
|
-
Record<string, LayoutRectangle | undefined>
|
|
44
|
-
>({});
|
|
45
|
-
|
|
46
|
-
useEffect(() => {
|
|
47
|
-
return () => {
|
|
48
|
-
handleHeaderContainerLayout(contentKey);
|
|
49
|
-
};
|
|
50
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
51
|
-
}, [contentKey]);
|
|
52
|
-
|
|
53
|
-
const stickyHeight = useDerivedValue(
|
|
54
|
-
() =>
|
|
55
|
-
Object.values(stickyLayouts.value).reduce(
|
|
56
|
-
(acc, value) => acc + (value?.height ?? 0),
|
|
57
|
-
0
|
|
58
|
-
),
|
|
59
|
-
[]
|
|
60
|
-
);
|
|
61
|
-
|
|
62
|
-
useAnimatedReaction(
|
|
63
|
-
() => {
|
|
64
|
-
if (!currentLayout.value) {
|
|
65
|
-
return -1;
|
|
66
|
-
}
|
|
67
|
-
return currentLayout.value.height - stickyHeight.value;
|
|
68
|
-
},
|
|
69
|
-
(result, previous) => {
|
|
70
|
-
if (result !== -1 && result !== previous) {
|
|
71
|
-
runOnJS(handleHeaderContainerLayout)(
|
|
72
|
-
contentKey,
|
|
73
|
-
currentLayout.value,
|
|
74
|
-
stickyHeight.value
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
);
|
|
79
|
-
|
|
80
|
-
const handleLayout = useCallback(
|
|
81
|
-
({ nativeEvent: { layout } }: LayoutChangeEvent) => {
|
|
82
|
-
currentLayout.value = layout;
|
|
83
|
-
},
|
|
84
|
-
[currentLayout]
|
|
85
|
-
);
|
|
86
|
-
|
|
87
|
-
const handleStickyViewLayout = useCallback(
|
|
88
|
-
(stickyKey: string, layout?: LayoutRectangle) => {
|
|
89
|
-
console.log('handleStickyViewLayout', stickyKey, layout);
|
|
90
|
-
|
|
91
|
-
setStickyLayouts({
|
|
92
|
-
[stickyKey]: layout,
|
|
93
|
-
});
|
|
94
|
-
},
|
|
95
|
-
[setStickyLayouts]
|
|
96
|
-
);
|
|
18
|
+
const { mount, unmount, update } = useCollapsibleHeaderConsumerContext();
|
|
97
19
|
|
|
98
20
|
const internalStyle = useMemo(() => {
|
|
99
21
|
return {
|
|
@@ -101,71 +23,31 @@ export default function CollapsibleHeaderContainer({
|
|
|
101
23
|
};
|
|
102
24
|
}, []);
|
|
103
25
|
|
|
104
|
-
const
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
position.stickyHeight;
|
|
114
|
-
|
|
115
|
-
return interpolate(
|
|
116
|
-
scrollY.value,
|
|
117
|
-
[0, topPosition, 10000],
|
|
118
|
-
[0, -topPosition, -topPosition],
|
|
119
|
-
Extrapolate.CLAMP
|
|
26
|
+
const content = useMemo(() => {
|
|
27
|
+
return (
|
|
28
|
+
<CollapsibleHeaderContainerProvider
|
|
29
|
+
containerStyle={[containerStyle, internalStyle]}
|
|
30
|
+
contentKey={contentKey}
|
|
31
|
+
key={contentKey}
|
|
32
|
+
>
|
|
33
|
+
{children}
|
|
34
|
+
</CollapsibleHeaderContainerProvider>
|
|
120
35
|
);
|
|
121
|
-
});
|
|
36
|
+
}, [children, containerStyle, contentKey, internalStyle]);
|
|
122
37
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
transform: [
|
|
126
|
-
{
|
|
127
|
-
translateY: translateY.value,
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
|
-
};
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
const animatedY = useDerivedValue(() => {
|
|
134
|
-
const position = headerViewPositions.value[contentKey];
|
|
135
|
-
if (!currentLayout.value || !position) {
|
|
136
|
-
return 0;
|
|
137
|
-
}
|
|
138
|
-
const value = scrollY.value - currentLayout.value.y + position.top;
|
|
139
|
-
const maxV = currentLayout.value.height - stickyHeight.value;
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
mount(contentKey, content);
|
|
140
40
|
|
|
141
|
-
return
|
|
142
|
-
|
|
41
|
+
return () => {
|
|
42
|
+
unmount(contentKey);
|
|
43
|
+
};
|
|
44
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
45
|
+
}, [contentKey]);
|
|
143
46
|
|
|
144
|
-
|
|
145
|
-
()
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
}),
|
|
149
|
-
[handleStickyViewLayout, animatedY]
|
|
150
|
-
);
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
update(contentKey, content);
|
|
49
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
50
|
+
}, [content]);
|
|
151
51
|
|
|
152
|
-
return
|
|
153
|
-
<CollapsibleHeaderContext.Provider value={value}>
|
|
154
|
-
<Animated.View
|
|
155
|
-
key={contentKey}
|
|
156
|
-
style={[styles.container, containerStyle, internalStyle, animatedStyle]}
|
|
157
|
-
pointerEvents="box-none"
|
|
158
|
-
onLayout={handleLayout}
|
|
159
|
-
>
|
|
160
|
-
{children}
|
|
161
|
-
</Animated.View>
|
|
162
|
-
</CollapsibleHeaderContext.Provider>
|
|
163
|
-
);
|
|
52
|
+
return null;
|
|
164
53
|
}
|
|
165
|
-
|
|
166
|
-
const styles = StyleSheet.create({
|
|
167
|
-
container: {
|
|
168
|
-
overflow: 'hidden',
|
|
169
|
-
backgroundColor: 'white',
|
|
170
|
-
},
|
|
171
|
-
});
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import React, { ReactNode, useCallback, useEffect, useMemo } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
StyleProp,
|
|
4
|
+
ViewStyle,
|
|
5
|
+
LayoutChangeEvent,
|
|
6
|
+
LayoutRectangle,
|
|
7
|
+
StyleSheet,
|
|
8
|
+
} from 'react-native';
|
|
9
|
+
import useInternalCollapsibleContext from '../../hooks/useInternalCollapsibleContext';
|
|
10
|
+
import useCollapsibleContext from '../../hooks/useCollapsibleContext';
|
|
11
|
+
import Animated, {
|
|
12
|
+
Extrapolate,
|
|
13
|
+
interpolate,
|
|
14
|
+
runOnJS,
|
|
15
|
+
useAnimatedReaction,
|
|
16
|
+
useAnimatedStyle,
|
|
17
|
+
useDerivedValue,
|
|
18
|
+
useSharedValue,
|
|
19
|
+
} from 'react-native-reanimated';
|
|
20
|
+
import {
|
|
21
|
+
CollapsibleContextHeaderType,
|
|
22
|
+
CollapsibleHeaderContext,
|
|
23
|
+
} from '../../hooks/useCollapsibleHeaderContext';
|
|
24
|
+
import useSharedValueRef from '../../utils/useSharedValueRef';
|
|
25
|
+
|
|
26
|
+
type Props = {
|
|
27
|
+
children: ReactNode;
|
|
28
|
+
containerStyle?: StyleProp<ViewStyle>;
|
|
29
|
+
contentKey: string;
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export default function CollapsibleHeaderContainerProvider({
|
|
33
|
+
children,
|
|
34
|
+
containerStyle,
|
|
35
|
+
contentKey,
|
|
36
|
+
}: Props) {
|
|
37
|
+
const { handleHeaderContainerLayout, headerViewPositions } =
|
|
38
|
+
useInternalCollapsibleContext();
|
|
39
|
+
const { scrollY } = useCollapsibleContext();
|
|
40
|
+
const currentLayout = useSharedValue<LayoutRectangle | undefined>(undefined);
|
|
41
|
+
const [stickyLayouts, setStickyLayouts] = useSharedValueRef<
|
|
42
|
+
Record<string, LayoutRectangle | undefined>
|
|
43
|
+
>({});
|
|
44
|
+
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
return () => {
|
|
47
|
+
handleHeaderContainerLayout(contentKey);
|
|
48
|
+
};
|
|
49
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
50
|
+
}, [contentKey]);
|
|
51
|
+
|
|
52
|
+
const stickyHeight = useDerivedValue(
|
|
53
|
+
() =>
|
|
54
|
+
Object.values(stickyLayouts.value).reduce(
|
|
55
|
+
(acc, value) => acc + (value?.height ?? 0),
|
|
56
|
+
0
|
|
57
|
+
),
|
|
58
|
+
[]
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
useAnimatedReaction(
|
|
62
|
+
() => {
|
|
63
|
+
if (!currentLayout.value) {
|
|
64
|
+
return -1;
|
|
65
|
+
}
|
|
66
|
+
return currentLayout.value.height - stickyHeight.value;
|
|
67
|
+
},
|
|
68
|
+
(result, previous) => {
|
|
69
|
+
if (result !== -1 && result !== previous) {
|
|
70
|
+
runOnJS(handleHeaderContainerLayout)(
|
|
71
|
+
contentKey,
|
|
72
|
+
currentLayout.value,
|
|
73
|
+
stickyHeight.value
|
|
74
|
+
);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const handleLayout = useCallback(
|
|
80
|
+
({ nativeEvent: { layout } }: LayoutChangeEvent) => {
|
|
81
|
+
currentLayout.value = layout;
|
|
82
|
+
},
|
|
83
|
+
[currentLayout]
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
const handleStickyViewLayout = useCallback(
|
|
87
|
+
(stickyKey: string, layout?: LayoutRectangle) => {
|
|
88
|
+
setStickyLayouts({
|
|
89
|
+
[stickyKey]: layout,
|
|
90
|
+
});
|
|
91
|
+
},
|
|
92
|
+
[setStickyLayouts]
|
|
93
|
+
);
|
|
94
|
+
|
|
95
|
+
const translateY = useDerivedValue(() => {
|
|
96
|
+
const position = headerViewPositions.value[contentKey];
|
|
97
|
+
if (!currentLayout.value || !position) {
|
|
98
|
+
return scrollY.value;
|
|
99
|
+
}
|
|
100
|
+
const topPosition =
|
|
101
|
+
currentLayout.value.height +
|
|
102
|
+
currentLayout.value.y -
|
|
103
|
+
position.top -
|
|
104
|
+
position.stickyHeight;
|
|
105
|
+
|
|
106
|
+
return interpolate(
|
|
107
|
+
scrollY.value,
|
|
108
|
+
[0, topPosition, 10000],
|
|
109
|
+
[0, -topPosition, -topPosition],
|
|
110
|
+
Extrapolate.CLAMP
|
|
111
|
+
);
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const animatedStyle = useAnimatedStyle(() => {
|
|
115
|
+
return {
|
|
116
|
+
transform: [
|
|
117
|
+
{
|
|
118
|
+
translateY: translateY.value,
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
};
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
const animatedY = useDerivedValue(() => {
|
|
125
|
+
const position = headerViewPositions.value[contentKey];
|
|
126
|
+
if (!currentLayout.value || !position) {
|
|
127
|
+
return 0;
|
|
128
|
+
}
|
|
129
|
+
const value = scrollY.value - currentLayout.value.y + position.top;
|
|
130
|
+
const maxV = currentLayout.value.height - stickyHeight.value;
|
|
131
|
+
|
|
132
|
+
return Math.max(0, Math.min(value, maxV));
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
const value: CollapsibleContextHeaderType = useMemo(
|
|
136
|
+
() => ({
|
|
137
|
+
handleStickyViewLayout,
|
|
138
|
+
animatedY,
|
|
139
|
+
}),
|
|
140
|
+
[handleStickyViewLayout, animatedY]
|
|
141
|
+
);
|
|
142
|
+
|
|
143
|
+
return (
|
|
144
|
+
<CollapsibleHeaderContext.Provider value={value}>
|
|
145
|
+
<Animated.View
|
|
146
|
+
key={contentKey}
|
|
147
|
+
style={[styles.container, containerStyle, animatedStyle]}
|
|
148
|
+
pointerEvents="box-none"
|
|
149
|
+
onLayout={handleLayout}
|
|
150
|
+
>
|
|
151
|
+
{children}
|
|
152
|
+
</Animated.View>
|
|
153
|
+
</CollapsibleHeaderContext.Provider>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
const styles = StyleSheet.create({
|
|
158
|
+
container: {
|
|
159
|
+
overflow: 'hidden',
|
|
160
|
+
backgroundColor: 'white',
|
|
161
|
+
},
|
|
162
|
+
});
|
|
@@ -49,8 +49,6 @@ export default function StickyView({ children, style }: Props) {
|
|
|
49
49
|
const { height: stickyHeight, y: top } = currentLayout.value;
|
|
50
50
|
const topValue = top;
|
|
51
51
|
|
|
52
|
-
console.log({ key, animatedY: animatedY.value, top, stickyHeight });
|
|
53
|
-
|
|
54
52
|
return interpolate(
|
|
55
53
|
animatedY.value,
|
|
56
54
|
[0, topValue, topValue + stickyHeight + 100],
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createContext, ReactNode, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
export type HeaderItem = { key: string; children: ReactNode };
|
|
4
|
+
|
|
5
|
+
type CollapsibleContextHeaderConsumerType = {
|
|
6
|
+
headers: HeaderItem[];
|
|
7
|
+
mount: (key: string, header: ReactNode) => void;
|
|
8
|
+
update: (key: string, header: ReactNode) => void;
|
|
9
|
+
unmount: (key: string) => void;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const CollapsibleHeaderConsumerContext =
|
|
13
|
+
// @ts-ignore
|
|
14
|
+
createContext<CollapsibleContextHeaderConsumerType>({});
|
|
15
|
+
|
|
16
|
+
export default function useCollapsibleHeaderConsumerContext() {
|
|
17
|
+
const ctx = useContext(CollapsibleHeaderConsumerContext);
|
|
18
|
+
if (!ctx) {
|
|
19
|
+
throw new Error('Component should be wrapped CollapsibleHeaderProvider');
|
|
20
|
+
}
|
|
21
|
+
return ctx;
|
|
22
|
+
}
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
|
-
import type { LayoutRectangle
|
|
2
|
+
import type { LayoutRectangle } from 'react-native';
|
|
3
3
|
import type Animated from 'react-native-reanimated';
|
|
4
4
|
|
|
5
5
|
export type ScrollToIndexParams = {
|
|
@@ -31,7 +31,6 @@ export type LayoutParams = {
|
|
|
31
31
|
|
|
32
32
|
export type CollapsibleContextInternalType = {
|
|
33
33
|
scrollViewRef: React.RefObject<any>;
|
|
34
|
-
containerRef: React.RefObject<View>;
|
|
35
34
|
contentMinHeight: Animated.SharedValue<number>;
|
|
36
35
|
headerViewPositions: Animated.SharedValue<
|
|
37
36
|
Record<string, { top: number; stickyHeight: number }>
|
|
@@ -17,7 +17,6 @@ export default function withCollapsibleContext<T>(Component: FC<T>) {
|
|
|
17
17
|
const scrollY = useSharedValue(0);
|
|
18
18
|
const fixedHeaderHeight = useSharedValue(0);
|
|
19
19
|
const containerHeight = useSharedValue(0);
|
|
20
|
-
const containerRef = useRef<View>(null);
|
|
21
20
|
const scrollViewRef = useRef<View>(null);
|
|
22
21
|
const headerContainerLayouts = useRef<
|
|
23
22
|
Record<string, (LayoutRectangle & { stickyHeight?: number }) | undefined>
|
|
@@ -104,7 +103,6 @@ export default function withCollapsibleContext<T>(Component: FC<T>) {
|
|
|
104
103
|
const internalContext = useMemo(
|
|
105
104
|
() => ({
|
|
106
105
|
scrollViewRef,
|
|
107
|
-
containerRef,
|
|
108
106
|
handleHeaderContainerLayout,
|
|
109
107
|
setCollapsibleHandlers,
|
|
110
108
|
handleContainerHeight,
|