@orionarm/react-native-collapse-tabs 1.0.8 → 1.0.10
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 +68 -0
- package/lib/TabBar.js +2 -3
- package/package.json +23 -2
- package/src/TabBar.tsx +2 -3
package/README.md
CHANGED
|
@@ -30,6 +30,32 @@
|
|
|
30
30
|
|
|
31
31
|
---
|
|
32
32
|
|
|
33
|
+
## When to use
|
|
34
|
+
|
|
35
|
+
Use `@orionarm/react-native-collapse-tabs` when you need a **Twitter / Instagram / YouTube profile style screen** in React Native — a large header that collapses as you scroll, sticky tabs underneath, swipeable pages, and per-tab scroll memory.
|
|
36
|
+
|
|
37
|
+
Typical use cases:
|
|
38
|
+
|
|
39
|
+
- **User / profile screens** with a hero header and `Posts / Likes / Media` tabs
|
|
40
|
+
- **Product detail pages** with tabbed sections (Description / Reviews / Q&A)
|
|
41
|
+
- **Restaurant / store pages** with collapsing cover image and category tabs
|
|
42
|
+
- **Music / video apps** with an artist header and `Songs / Albums / Playlists` tabs
|
|
43
|
+
- Any screen that needs a **collapsing header + sticky tab bar + horizontal swipe**
|
|
44
|
+
|
|
45
|
+
## Comparison with similar libraries
|
|
46
|
+
|
|
47
|
+
| Library | Collapsible header | Swipeable tabs | Per-tab scroll | Reanimated v3 worklets | Bundle size |
|
|
48
|
+
| --------------------------------------------- | ------------------ | -------------- | -------------- | ---------------------- | ----------- |
|
|
49
|
+
| **@orionarm/react-native-collapse-tabs** | ✅ | ✅ | ✅ | ✅ | ~30 KB |
|
|
50
|
+
| `react-native-collapsible-tab-view` | ✅ | ✅ | ✅ | ✅ | larger |
|
|
51
|
+
| `react-native-scrollable-tab-view` _(legacy)_ | partial | ✅ | ❌ | ❌ | small |
|
|
52
|
+
| `react-native-tab-view` | ❌ | ✅ | ❌ | partial | medium |
|
|
53
|
+
| `react-native-sticky-parallax-header` | ✅ | ❌ | ❌ | partial | medium |
|
|
54
|
+
|
|
55
|
+
Compared to `react-native-collapsible-tab-view`, this library aims for a **smaller API surface** and uses `react-native-pager-view` directly for native paging — fewer abstractions, easier to drop in, and easier to customize.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
33
59
|
## Requirements
|
|
34
60
|
|
|
35
61
|
| Peer dependency | Version |
|
|
@@ -266,6 +292,48 @@ import type {
|
|
|
266
292
|
|
|
267
293
|
---
|
|
268
294
|
|
|
295
|
+
## FAQ
|
|
296
|
+
|
|
297
|
+
### How is this different from `react-native-collapsible-tab-view`?
|
|
298
|
+
|
|
299
|
+
Both solve the same problem. `@orionarm/react-native-collapse-tabs` has a smaller surface area, uses `react-native-pager-view` directly (instead of `react-native-tab-view`), and exposes the underlying Reanimated `SharedValue`s through `useTabsContext()` so you can build fully custom headers/tab bars without forking.
|
|
300
|
+
|
|
301
|
+
### Does it work with Expo?
|
|
302
|
+
|
|
303
|
+
Yes. It works with **Expo SDK 49+** (any version that supports `react-native-reanimated` v3 and `react-native-pager-view` 6+). Run `npx expo install react-native-reanimated react-native-pager-view react-native-gesture-handler` and you're set.
|
|
304
|
+
|
|
305
|
+
### Does it support iOS and Android?
|
|
306
|
+
|
|
307
|
+
Yes — both platforms are first-class. All animations run on the UI thread via Reanimated worklets, so performance is identical on both.
|
|
308
|
+
|
|
309
|
+
### Does it support pull-to-refresh?
|
|
310
|
+
|
|
311
|
+
Yes. Pass `refreshControl` to the wrapped `<FlatList>` just like a normal RN list. The library handles overscroll so the header won't fly off-screen during the pull gesture.
|
|
312
|
+
|
|
313
|
+
### Can I use a custom tab bar / animated header?
|
|
314
|
+
|
|
315
|
+
Absolutely. Pass `renderTabBar` and `renderHeader` props, or read the shared scroll state via `useTabsContext()` to drive your own animations.
|
|
316
|
+
|
|
317
|
+
### Does it support dynamic header height?
|
|
318
|
+
|
|
319
|
+
Not yet — `headerHeight` is currently fixed. Dynamic height is on the [roadmap](#roadmap).
|
|
320
|
+
|
|
321
|
+
### How do I keep each tab's scroll position independent?
|
|
322
|
+
|
|
323
|
+
It's automatic. Just make sure the `name` prop on `<Tab>` matches the `name` prop on the inner `<FlatList>` / `<ScrollView>`.
|
|
324
|
+
|
|
325
|
+
### Why Reanimated v3?
|
|
326
|
+
|
|
327
|
+
Reanimated v3 worklets let scroll-driven animations run entirely on the UI thread, which is required for jank-free 60fps header collapse on lower-end Android devices.
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## Keywords
|
|
332
|
+
|
|
333
|
+
`react-native collapsible tabs` · `react-native sticky header tabs` · `react-native parallax header` · `react-native tab view with collapsing header` · `react-native scrollable tab bar` · `react-native pager view tabs` · `react-native animated tabs` · `react-native profile screen` · `instagram profile tabs react-native` · `twitter profile header react-native`
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
269
337
|
## Roadmap
|
|
270
338
|
|
|
271
339
|
- [ ] Dynamic header height
|
package/lib/TabBar.js
CHANGED
|
@@ -17,15 +17,14 @@ const TabBarItem = ({ name, index, indexDecimal, onPress }) => {
|
|
|
17
17
|
};
|
|
18
18
|
const Indicator = ({ count, indexDecimal }) => {
|
|
19
19
|
const style = useAnimatedStyle(() => ({
|
|
20
|
-
transform: [
|
|
21
|
-
{ translateX: (indexDecimal.value * 100) / count + "%" },
|
|
22
|
-
],
|
|
20
|
+
transform: [{ translateX: indexDecimal.value * 100 + "%" }],
|
|
23
21
|
width: `${100 / count}%`,
|
|
24
22
|
}));
|
|
25
23
|
return <Animated.View style={[styles.indicator, style]}/>;
|
|
26
24
|
};
|
|
27
25
|
const styles = StyleSheet.create({
|
|
28
26
|
container: {
|
|
27
|
+
flex: 1,
|
|
29
28
|
flexDirection: "row",
|
|
30
29
|
backgroundColor: "#fff",
|
|
31
30
|
},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orionarm/react-native-collapse-tabs",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.10",
|
|
4
4
|
"description": "A high-performance React Native collapsible tabs component with sticky/animated header, swipeable pages, and per-tab scroll. Built on react-native-pager-view and react-native-reanimated v3.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -13,33 +13,54 @@
|
|
|
13
13
|
"keywords": [
|
|
14
14
|
"react-native",
|
|
15
15
|
"react-native-tabs",
|
|
16
|
+
"react-native-collapse-tabs",
|
|
16
17
|
"react-native-collapsible-tabs",
|
|
18
|
+
"react-native-collapsible-tab-view",
|
|
17
19
|
"react-native-sticky-header",
|
|
20
|
+
"react-native-sticky-tabs",
|
|
21
|
+
"react-native-parallax-header",
|
|
22
|
+
"react-native-animated-header",
|
|
18
23
|
"react-native-pager-view",
|
|
19
24
|
"react-native-reanimated",
|
|
25
|
+
"react-native-flatlist",
|
|
26
|
+
"react-native-scrollview",
|
|
27
|
+
"react-native-tab-view",
|
|
28
|
+
"react-native-profile-screen",
|
|
20
29
|
"collapse",
|
|
30
|
+
"collapse-tabs",
|
|
31
|
+
"collapsing-header",
|
|
21
32
|
"collapsible",
|
|
33
|
+
"collapsible-header",
|
|
22
34
|
"tabs",
|
|
23
35
|
"tab",
|
|
24
36
|
"tab-view",
|
|
25
37
|
"tabbar",
|
|
26
38
|
"tab-bar",
|
|
27
39
|
"sticky-header",
|
|
40
|
+
"sticky-tabs",
|
|
28
41
|
"sticky",
|
|
29
42
|
"animated-header",
|
|
43
|
+
"parallax",
|
|
30
44
|
"parallax-header",
|
|
31
45
|
"scroll",
|
|
32
46
|
"scrollable",
|
|
47
|
+
"nested-scroll",
|
|
33
48
|
"swipe",
|
|
34
49
|
"swipeable",
|
|
35
50
|
"pager",
|
|
36
51
|
"pager-view",
|
|
37
52
|
"reanimated",
|
|
53
|
+
"reanimated-v3",
|
|
54
|
+
"worklet",
|
|
38
55
|
"ios",
|
|
39
56
|
"android",
|
|
40
57
|
"expo",
|
|
58
|
+
"expo-tabs",
|
|
41
59
|
"flatlist",
|
|
42
|
-
"scrollview"
|
|
60
|
+
"scrollview",
|
|
61
|
+
"header",
|
|
62
|
+
"instagram-profile",
|
|
63
|
+
"twitter-profile"
|
|
43
64
|
],
|
|
44
65
|
"author": "yanan_orionarm",
|
|
45
66
|
"license": "ISC",
|
package/src/TabBar.tsx
CHANGED
|
@@ -53,9 +53,7 @@ const Indicator: React.FC<{
|
|
|
53
53
|
indexDecimal: Animated.SharedValue<number>;
|
|
54
54
|
}> = ({ count, indexDecimal }) => {
|
|
55
55
|
const style = useAnimatedStyle(() => ({
|
|
56
|
-
transform: [
|
|
57
|
-
{ translateX: (indexDecimal.value * 100) / count + "%" } as any,
|
|
58
|
-
],
|
|
56
|
+
transform: [{ translateX: indexDecimal.value * 100 + "%" } as any],
|
|
59
57
|
width: `${100 / count}%`,
|
|
60
58
|
}));
|
|
61
59
|
return <Animated.View style={[styles.indicator, style]} />;
|
|
@@ -63,6 +61,7 @@ const Indicator: React.FC<{
|
|
|
63
61
|
|
|
64
62
|
const styles = StyleSheet.create({
|
|
65
63
|
container: {
|
|
64
|
+
flex: 1,
|
|
66
65
|
flexDirection: "row",
|
|
67
66
|
backgroundColor: "#fff",
|
|
68
67
|
},
|