react-native-collapsible-header-tab-view 1.0.4 → 1.0.6
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 +33 -8
- package/dist/index.js +141 -57
- package/dist/index.mjs +160 -63
- package/dist/src/TabScrollView.d.ts.map +1 -1
- package/dist/src/TabSectionList.d.ts +9 -0
- package/dist/src/TabSectionList.d.ts.map +1 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/types.d.ts +2 -2
- package/dist/src/types.d.ts.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
✨ **轻量级** - 不依赖 react-native-reanimated
|
|
10
10
|
🎯 **高性能** - 优化的滚动性能
|
|
11
11
|
📱 **吸顶效果** - 完整的粘性头部和标签栏支持
|
|
12
|
-
🔄 **灵活** - 支持 FlatList 和 ScrollView
|
|
12
|
+
🔄 **灵活** - 支持 FlatList、SectionList 和 ScrollView
|
|
13
13
|
⚡ **TypeScript** - 完整的类型支持
|
|
14
14
|
|
|
15
15
|
## 安装
|
|
@@ -31,8 +31,18 @@ npm install react-native-pager-view
|
|
|
31
31
|
|
|
32
32
|
### 基础示例
|
|
33
33
|
|
|
34
|
+
`TabFlatList`、`TabSectionList`、`TabScrollView` 可以在同一个 `CollapsibleTabView` 中混合使用,每个子组件对应一个 Tab 页。
|
|
35
|
+
|
|
34
36
|
```jsx
|
|
35
|
-
import CollapsibleTabView
|
|
37
|
+
import CollapsibleTabView, {
|
|
38
|
+
TabFlatList,
|
|
39
|
+
TabSectionList,
|
|
40
|
+
} from 'react-native-collapsible-header-tab-view';
|
|
41
|
+
|
|
42
|
+
const sections = [
|
|
43
|
+
{ title: 'A', data: ['Alice', 'Amy'] },
|
|
44
|
+
{ title: 'B', data: ['Bob', 'Ben'] },
|
|
45
|
+
];
|
|
36
46
|
|
|
37
47
|
export function App() {
|
|
38
48
|
return (
|
|
@@ -40,15 +50,18 @@ export function App() {
|
|
|
40
50
|
renderHeader={() => <HeaderComponent />}
|
|
41
51
|
renderTabBar={(props) => <TabBarComponent {...props} />}
|
|
42
52
|
>
|
|
53
|
+
{/* Tab 1: FlatList */}
|
|
43
54
|
<TabFlatList
|
|
44
|
-
data={
|
|
55
|
+
data={data}
|
|
45
56
|
renderItem={({ item }) => <ItemComponent item={item} />}
|
|
46
57
|
keyExtractor={(item) => item.id}
|
|
47
58
|
/>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
59
|
+
{/* Tab 2: SectionList */}
|
|
60
|
+
<TabSectionList
|
|
61
|
+
sections={sections}
|
|
62
|
+
renderItem={({ item }) => <Text>{item}</Text>}
|
|
63
|
+
renderSectionHeader={({ section }) => <Text>{section.title}</Text>}
|
|
64
|
+
keyExtractor={(item, index) => item + index}
|
|
52
65
|
/>
|
|
53
66
|
</CollapsibleTabView>
|
|
54
67
|
);
|
|
@@ -75,13 +88,25 @@ export function App() {
|
|
|
75
88
|
|
|
76
89
|
### TabFlatList
|
|
77
90
|
|
|
91
|
+
继承所有 `FlatList` 的 Props。
|
|
92
|
+
|
|
78
93
|
| 属性 | 类型 | 说明 |
|
|
79
94
|
|------|------|------|
|
|
80
|
-
| index | `number` | 必需,标签页索引 |
|
|
81
95
|
| data | `T[]` | 列表数据 |
|
|
82
96
|
| renderItem | `(info: { item: T, index: number }) => ReactNode` | 列表项渲染函数 |
|
|
83
97
|
| keyExtractor | `(item: T, index: number) => string` | 列表项 key |
|
|
84
98
|
|
|
99
|
+
### TabSectionList
|
|
100
|
+
|
|
101
|
+
继承所有 `SectionList` 的 Props。
|
|
102
|
+
|
|
103
|
+
| 属性 | 类型 | 说明 |
|
|
104
|
+
|------|------|------|
|
|
105
|
+
| sections | `SectionListData[]` | 分组数据 |
|
|
106
|
+
| renderItem | `(info: { item: T, index: number, section: S }) => ReactNode` | 列表项渲染函数 |
|
|
107
|
+
| renderSectionHeader | `(info: { section: S }) => ReactNode` | 分组头部渲染函数 |
|
|
108
|
+
| keyExtractor | `(item: T, index: number) => string` | 列表项 key |
|
|
109
|
+
|
|
85
110
|
## Ref Methods
|
|
86
111
|
|
|
87
112
|
```typescript
|
package/dist/index.js
CHANGED
|
@@ -32,11 +32,12 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
TabFlatList: () => TabFlatList,
|
|
34
34
|
TabScrollView: () => TabScrollView,
|
|
35
|
+
TabSectionList: () => TabSectionList,
|
|
35
36
|
default: () => index_default
|
|
36
37
|
});
|
|
37
38
|
module.exports = __toCommonJS(index_exports);
|
|
38
|
-
var
|
|
39
|
-
var
|
|
39
|
+
var import_react5 = __toESM(require("react"));
|
|
40
|
+
var import_react_native4 = require("react-native");
|
|
40
41
|
var import_react_native_pager_view = __toESM(require("react-native-pager-view"));
|
|
41
42
|
|
|
42
43
|
// src/context.ts
|
|
@@ -134,7 +135,17 @@ var import_react_native2 = require("react-native");
|
|
|
134
135
|
var TabScrollView = (0, import_react3.forwardRef)(
|
|
135
136
|
({ contentContainerStyle, onScroll, children, ...props }, ref) => {
|
|
136
137
|
const index = useTabIndex();
|
|
137
|
-
const {
|
|
138
|
+
const {
|
|
139
|
+
scrollY,
|
|
140
|
+
activeIndex,
|
|
141
|
+
stickyEnabled,
|
|
142
|
+
headerHeight,
|
|
143
|
+
tabBarHeight,
|
|
144
|
+
renderHeader,
|
|
145
|
+
renderTabBar,
|
|
146
|
+
registerRef,
|
|
147
|
+
syncScrollY
|
|
148
|
+
} = useCollapsible();
|
|
138
149
|
const innerRef = (0, import_react3.useRef)(null);
|
|
139
150
|
const isActive = activeIndex === index;
|
|
140
151
|
(0, import_react3.useEffect)(() => {
|
|
@@ -150,8 +161,12 @@ var TabScrollView = (0, import_react3.forwardRef)(
|
|
|
150
161
|
},
|
|
151
162
|
[index, onScroll, syncScrollY]
|
|
152
163
|
);
|
|
153
|
-
const
|
|
154
|
-
|
|
164
|
+
const mergedChildren = (0, import_react3.useMemo)(() => {
|
|
165
|
+
if (stickyEnabled) return children;
|
|
166
|
+
return /* @__PURE__ */ import_react3.default.createElement(import_react_native2.View, null, renderHeader?.(), renderTabBar?.(), children);
|
|
167
|
+
}, [stickyEnabled, children, renderHeader, renderTabBar]);
|
|
168
|
+
const paddingTop = stickyEnabled ? headerHeight + tabBarHeight : 0;
|
|
169
|
+
const collapseRange = stickyEnabled ? headerHeight : 0;
|
|
155
170
|
const [containerHeight, setContainerHeight] = (0, import_react3.useState)(0);
|
|
156
171
|
const handleLayout = (0, import_react3.useCallback)((e) => {
|
|
157
172
|
setContainerHeight(e.nativeEvent.layout.height);
|
|
@@ -164,24 +179,95 @@ var TabScrollView = (0, import_react3.forwardRef)(
|
|
|
164
179
|
...props,
|
|
165
180
|
onLayout: handleLayout,
|
|
166
181
|
contentContainerStyle: [
|
|
167
|
-
{ paddingTop },
|
|
182
|
+
paddingTop > 0 && { paddingTop },
|
|
168
183
|
minHeight > 0 && { minHeight },
|
|
169
184
|
contentContainerStyle
|
|
170
185
|
],
|
|
171
|
-
onScroll: isActive ? import_react_native2.Animated.event(
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
186
|
+
onScroll: isActive && stickyEnabled ? import_react_native2.Animated.event(
|
|
187
|
+
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
|
|
188
|
+
{
|
|
189
|
+
useNativeDriver: true,
|
|
190
|
+
listener: handleScroll
|
|
191
|
+
}
|
|
192
|
+
) : handleScroll,
|
|
175
193
|
scrollEventThrottle: 16,
|
|
176
194
|
showsVerticalScrollIndicator: false
|
|
177
195
|
},
|
|
178
|
-
|
|
196
|
+
mergedChildren
|
|
179
197
|
);
|
|
180
198
|
}
|
|
181
199
|
);
|
|
182
200
|
|
|
201
|
+
// src/TabSectionList.tsx
|
|
202
|
+
var import_react4 = __toESM(require("react"));
|
|
203
|
+
var import_react_native3 = require("react-native");
|
|
204
|
+
var AnimatedSectionListComponent = import_react_native3.Animated.createAnimatedComponent(import_react_native3.SectionList);
|
|
205
|
+
var AnimatedSectionList = AnimatedSectionListComponent;
|
|
206
|
+
var TabSectionListInner = ({ contentContainerStyle, onScroll, ListHeaderComponent, ...props }, ref) => {
|
|
207
|
+
const index = useTabIndex();
|
|
208
|
+
const {
|
|
209
|
+
scrollY,
|
|
210
|
+
activeIndex,
|
|
211
|
+
stickyEnabled,
|
|
212
|
+
headerHeight,
|
|
213
|
+
tabBarHeight,
|
|
214
|
+
renderHeader,
|
|
215
|
+
renderTabBar,
|
|
216
|
+
registerRef,
|
|
217
|
+
syncScrollY
|
|
218
|
+
} = useCollapsible();
|
|
219
|
+
const innerRef = (0, import_react4.useRef)(null);
|
|
220
|
+
const isActive = activeIndex === index;
|
|
221
|
+
(0, import_react4.useEffect)(() => {
|
|
222
|
+
registerRef(index, innerRef.current);
|
|
223
|
+
return () => registerRef(index, null);
|
|
224
|
+
}, [index]);
|
|
225
|
+
(0, import_react4.useImperativeHandle)(ref, () => innerRef.current, []);
|
|
226
|
+
const handleScroll = (0, import_react4.useCallback)(
|
|
227
|
+
(e) => {
|
|
228
|
+
const y = e.nativeEvent.contentOffset.y;
|
|
229
|
+
syncScrollY(index, y);
|
|
230
|
+
onScroll?.(e);
|
|
231
|
+
},
|
|
232
|
+
[index, onScroll, syncScrollY]
|
|
233
|
+
);
|
|
234
|
+
const mergedHeader = (0, import_react4.useMemo)(() => {
|
|
235
|
+
if (stickyEnabled) return ListHeaderComponent;
|
|
236
|
+
const OriginalHeader = typeof ListHeaderComponent === "function" ? /* @__PURE__ */ import_react4.default.createElement(ListHeaderComponent, null) : ListHeaderComponent ?? null;
|
|
237
|
+
return /* @__PURE__ */ import_react4.default.createElement(import_react_native3.View, null, renderHeader?.(), renderTabBar?.(), OriginalHeader);
|
|
238
|
+
}, [stickyEnabled, ListHeaderComponent, renderHeader, renderTabBar]);
|
|
239
|
+
const paddingTop = stickyEnabled ? headerHeight + tabBarHeight : 0;
|
|
240
|
+
const collapseRange = stickyEnabled ? headerHeight : 0;
|
|
241
|
+
const [containerHeight, setContainerHeight] = (0, import_react4.useState)(0);
|
|
242
|
+
const handleLayout = (0, import_react4.useCallback)((e) => {
|
|
243
|
+
setContainerHeight(e.nativeEvent.layout.height);
|
|
244
|
+
}, []);
|
|
245
|
+
const minHeight = containerHeight > 0 ? containerHeight + collapseRange : 0;
|
|
246
|
+
return /* @__PURE__ */ import_react4.default.createElement(
|
|
247
|
+
AnimatedSectionList,
|
|
248
|
+
{
|
|
249
|
+
...props,
|
|
250
|
+
ref: innerRef,
|
|
251
|
+
onLayout: handleLayout,
|
|
252
|
+
ListHeaderComponent: mergedHeader,
|
|
253
|
+
contentContainerStyle: [
|
|
254
|
+
paddingTop > 0 && { paddingTop },
|
|
255
|
+
minHeight > 0 && { minHeight },
|
|
256
|
+
contentContainerStyle
|
|
257
|
+
],
|
|
258
|
+
onScroll: isActive && stickyEnabled ? import_react_native3.Animated.event([{ nativeEvent: { contentOffset: { y: scrollY } } }], {
|
|
259
|
+
useNativeDriver: true,
|
|
260
|
+
listener: handleScroll
|
|
261
|
+
}) : handleScroll,
|
|
262
|
+
scrollEventThrottle: 16,
|
|
263
|
+
showsVerticalScrollIndicator: false
|
|
264
|
+
}
|
|
265
|
+
);
|
|
266
|
+
};
|
|
267
|
+
var TabSectionList = (0, import_react4.forwardRef)(TabSectionListInner);
|
|
268
|
+
|
|
183
269
|
// src/index.tsx
|
|
184
|
-
var CollapsibleTabView = (0,
|
|
270
|
+
var CollapsibleTabView = (0, import_react5.forwardRef)(
|
|
185
271
|
({
|
|
186
272
|
children,
|
|
187
273
|
renderHeader,
|
|
@@ -196,13 +282,13 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
196
282
|
swipeEnabled = true,
|
|
197
283
|
style
|
|
198
284
|
}, ref) => {
|
|
199
|
-
const [activeIndex, setActiveIndex] = (0,
|
|
200
|
-
const pagerRef = (0,
|
|
201
|
-
const pages = (0,
|
|
202
|
-
() =>
|
|
285
|
+
const [activeIndex, setActiveIndex] = (0, import_react5.useState)(initialTabIndex);
|
|
286
|
+
const pagerRef = (0, import_react5.useRef)(null);
|
|
287
|
+
const pages = (0, import_react5.useMemo)(
|
|
288
|
+
() => import_react5.default.Children.toArray(children).filter(import_react5.default.isValidElement),
|
|
203
289
|
[children]
|
|
204
290
|
);
|
|
205
|
-
(0,
|
|
291
|
+
(0, import_react5.useImperativeHandle)(ref, () => ({
|
|
206
292
|
scrollToTab: (index, animated = true) => {
|
|
207
293
|
if (index === activeIndex || index < 0 || index >= pages.length) return;
|
|
208
294
|
syncTabOnSwitch(index);
|
|
@@ -217,17 +303,17 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
217
303
|
getActiveIndex: () => activeIndex
|
|
218
304
|
}));
|
|
219
305
|
const hasEstimate = estimatedHeaderHeight > 0;
|
|
220
|
-
const headerHeightRef = (0,
|
|
221
|
-
const tabBarHeightRef = (0,
|
|
222
|
-
const [layout, setLayout] = (0,
|
|
306
|
+
const headerHeightRef = (0, import_react5.useRef)(0);
|
|
307
|
+
const tabBarHeightRef = (0, import_react5.useRef)(0);
|
|
308
|
+
const [layout, setLayout] = (0, import_react5.useState)({
|
|
223
309
|
headerHeight: estimatedHeaderHeight,
|
|
224
310
|
tabBarHeight: estimatedTabBarHeight,
|
|
225
311
|
ready: hasEstimate
|
|
226
312
|
});
|
|
227
313
|
const { headerHeight, tabBarHeight } = layout;
|
|
228
314
|
const visible = layout.ready;
|
|
229
|
-
const adjustY = (0,
|
|
230
|
-
const tryCommitLayout = (0,
|
|
315
|
+
const adjustY = (0, import_react5.useRef)(new import_react_native4.Animated.Value(0)).current;
|
|
316
|
+
const tryCommitLayout = (0, import_react5.useCallback)(() => {
|
|
231
317
|
const h = headerHeightRef.current;
|
|
232
318
|
const t = tabBarHeightRef.current;
|
|
233
319
|
if (h > 0 && t > 0) {
|
|
@@ -238,7 +324,7 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
238
324
|
const diff = h + t - (prev.headerHeight + prev.tabBarHeight);
|
|
239
325
|
if (prev.ready && Math.abs(diff) > 1) {
|
|
240
326
|
adjustY.setValue(-diff);
|
|
241
|
-
|
|
327
|
+
import_react_native4.Animated.timing(adjustY, {
|
|
242
328
|
toValue: 0,
|
|
243
329
|
duration: 200,
|
|
244
330
|
useNativeDriver: true
|
|
@@ -248,35 +334,32 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
248
334
|
});
|
|
249
335
|
}
|
|
250
336
|
}, [adjustY]);
|
|
251
|
-
const handleHeaderLayout = (0,
|
|
337
|
+
const handleHeaderLayout = (0, import_react5.useCallback)(
|
|
252
338
|
(e) => {
|
|
253
339
|
headerHeightRef.current = e.nativeEvent.layout.height;
|
|
254
340
|
tryCommitLayout();
|
|
255
341
|
},
|
|
256
342
|
[tryCommitLayout]
|
|
257
343
|
);
|
|
258
|
-
const handleTabBarLayout = (0,
|
|
344
|
+
const handleTabBarLayout = (0, import_react5.useCallback)(
|
|
259
345
|
(e) => {
|
|
260
346
|
tabBarHeightRef.current = e.nativeEvent.layout.height;
|
|
261
347
|
tryCommitLayout();
|
|
262
348
|
},
|
|
263
349
|
[tryCommitLayout]
|
|
264
350
|
);
|
|
265
|
-
const scrollY = (0,
|
|
266
|
-
const tabScrollYMap = (0,
|
|
267
|
-
const tabRefs = (0,
|
|
351
|
+
const scrollY = (0, import_react5.useRef)(new import_react_native4.Animated.Value(0)).current;
|
|
352
|
+
const tabScrollYMap = (0, import_react5.useRef)(/* @__PURE__ */ new Map());
|
|
353
|
+
const tabRefs = (0, import_react5.useRef)(
|
|
268
354
|
/* @__PURE__ */ new Map()
|
|
269
355
|
);
|
|
270
356
|
const collapseRange = stickyEnabled ? Math.max(headerHeight - stickyTop, 0) : 0;
|
|
271
|
-
const headerTranslateY =
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
[scrollY, collapseRange]
|
|
278
|
-
);
|
|
279
|
-
const registerRef = (0, import_react4.useCallback)(
|
|
357
|
+
const headerTranslateY = scrollY.interpolate({
|
|
358
|
+
inputRange: [0, Math.max(collapseRange, 1)],
|
|
359
|
+
outputRange: [0, -collapseRange],
|
|
360
|
+
extrapolate: "clamp"
|
|
361
|
+
});
|
|
362
|
+
const registerRef = (0, import_react5.useCallback)(
|
|
280
363
|
(index, ref2) => {
|
|
281
364
|
if (ref2) {
|
|
282
365
|
tabRefs.current.set(index, ref2);
|
|
@@ -286,14 +369,14 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
286
369
|
},
|
|
287
370
|
[]
|
|
288
371
|
);
|
|
289
|
-
const syncScrollY = (0,
|
|
372
|
+
const syncScrollY = (0, import_react5.useCallback)(
|
|
290
373
|
(index, y) => {
|
|
291
374
|
tabScrollYMap.current.set(index, y);
|
|
292
375
|
onScrollProp?.(y);
|
|
293
376
|
},
|
|
294
377
|
[onScrollProp]
|
|
295
378
|
);
|
|
296
|
-
const scrollTabTo = (0,
|
|
379
|
+
const scrollTabTo = (0, import_react5.useCallback)((index, offset) => {
|
|
297
380
|
const ref2 = tabRefs.current.get(index);
|
|
298
381
|
if (!ref2) return;
|
|
299
382
|
if (ref2.scrollToOffset) {
|
|
@@ -309,7 +392,7 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
309
392
|
}
|
|
310
393
|
}
|
|
311
394
|
}, []);
|
|
312
|
-
const syncTabOnSwitch = (0,
|
|
395
|
+
const syncTabOnSwitch = (0, import_react5.useCallback)((newIndex) => {
|
|
313
396
|
const currentY = tabScrollYMap.current.get(activeIndex) ?? 0;
|
|
314
397
|
const newTabSavedY = tabScrollYMap.current.get(newIndex) ?? 0;
|
|
315
398
|
const isCollapsed = currentY >= collapseRange - 1;
|
|
@@ -318,7 +401,7 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
318
401
|
tabScrollYMap.current.set(newIndex, targetY);
|
|
319
402
|
scrollY.setValue(Math.min(targetY, collapseRange));
|
|
320
403
|
}, []);
|
|
321
|
-
const preSyncAdjacentTabs = (0,
|
|
404
|
+
const preSyncAdjacentTabs = (0, import_react5.useCallback)(() => {
|
|
322
405
|
const currentY = tabScrollYMap.current.get(activeIndex) ?? 0;
|
|
323
406
|
const isCollapsed = currentY >= collapseRange - 1;
|
|
324
407
|
for (const i of [activeIndex - 1, activeIndex + 1]) {
|
|
@@ -329,7 +412,7 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
329
412
|
tabScrollYMap.current.set(i, targetY);
|
|
330
413
|
}
|
|
331
414
|
}, [activeIndex, collapseRange, pages.length, scrollTabTo]);
|
|
332
|
-
const handlePageScrollStateChanged = (0,
|
|
415
|
+
const handlePageScrollStateChanged = (0, import_react5.useCallback)(
|
|
333
416
|
(e) => {
|
|
334
417
|
if (e.nativeEvent.pageScrollState === "dragging") {
|
|
335
418
|
preSyncAdjacentTabs();
|
|
@@ -337,7 +420,7 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
337
420
|
},
|
|
338
421
|
[preSyncAdjacentTabs]
|
|
339
422
|
);
|
|
340
|
-
const handleTabPress = (0,
|
|
423
|
+
const handleTabPress = (0, import_react5.useCallback)(
|
|
341
424
|
(index) => {
|
|
342
425
|
if (index === activeIndex) return;
|
|
343
426
|
syncTabOnSwitch(index);
|
|
@@ -347,7 +430,7 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
347
430
|
},
|
|
348
431
|
[activeIndex, syncTabOnSwitch, onTabChange]
|
|
349
432
|
);
|
|
350
|
-
const handlePageSelected = (0,
|
|
433
|
+
const handlePageSelected = (0, import_react5.useCallback)(
|
|
351
434
|
(e) => {
|
|
352
435
|
const newIndex = e.nativeEvent.position;
|
|
353
436
|
if (newIndex === activeIndex) return;
|
|
@@ -358,18 +441,18 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
358
441
|
},
|
|
359
442
|
[activeIndex, collapseRange, scrollY, onTabChange]
|
|
360
443
|
);
|
|
361
|
-
const tabBarProps = (0,
|
|
444
|
+
const tabBarProps = (0, import_react5.useMemo)(
|
|
362
445
|
() => ({
|
|
363
446
|
activeIndex,
|
|
364
447
|
onTabPress: handleTabPress
|
|
365
448
|
}),
|
|
366
449
|
[activeIndex, handleTabPress]
|
|
367
450
|
);
|
|
368
|
-
const renderTabBarNode = (0,
|
|
451
|
+
const renderTabBarNode = (0, import_react5.useCallback)(
|
|
369
452
|
() => renderTabBar(tabBarProps),
|
|
370
453
|
[renderTabBar, tabBarProps]
|
|
371
454
|
);
|
|
372
|
-
const contextValue = (0,
|
|
455
|
+
const contextValue = (0, import_react5.useMemo)(
|
|
373
456
|
() => ({
|
|
374
457
|
scrollY,
|
|
375
458
|
activeIndex,
|
|
@@ -393,8 +476,8 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
393
476
|
syncScrollY
|
|
394
477
|
]
|
|
395
478
|
);
|
|
396
|
-
return /* @__PURE__ */
|
|
397
|
-
|
|
479
|
+
return /* @__PURE__ */ import_react5.default.createElement(CollapsibleContext.Provider, { value: contextValue }, /* @__PURE__ */ import_react5.default.createElement(import_react_native4.View, { style: [styles.container, style] }, /* @__PURE__ */ import_react5.default.createElement(
|
|
480
|
+
import_react_native4.Animated.View,
|
|
398
481
|
{
|
|
399
482
|
style: [
|
|
400
483
|
styles.pager,
|
|
@@ -402,7 +485,7 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
402
485
|
{ transform: [{ translateY: adjustY }] }
|
|
403
486
|
]
|
|
404
487
|
},
|
|
405
|
-
/* @__PURE__ */
|
|
488
|
+
/* @__PURE__ */ import_react5.default.createElement(
|
|
406
489
|
import_react_native_pager_view.default,
|
|
407
490
|
{
|
|
408
491
|
ref: pagerRef,
|
|
@@ -412,10 +495,10 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
412
495
|
onPageScrollStateChanged: handlePageScrollStateChanged,
|
|
413
496
|
scrollEnabled: swipeEnabled
|
|
414
497
|
},
|
|
415
|
-
pages.map((page, i) => /* @__PURE__ */
|
|
498
|
+
pages.map((page, i) => /* @__PURE__ */ import_react5.default.createElement(import_react_native4.View, { key: page?.key ?? i, style: styles.page }, /* @__PURE__ */ import_react5.default.createElement(TabIndexContext.Provider, { value: i }, page)))
|
|
416
499
|
)
|
|
417
|
-
), stickyEnabled && /* @__PURE__ */
|
|
418
|
-
|
|
500
|
+
), stickyEnabled && /* @__PURE__ */ import_react5.default.createElement(
|
|
501
|
+
import_react_native4.Animated.View,
|
|
419
502
|
{
|
|
420
503
|
style: [
|
|
421
504
|
styles.overlay,
|
|
@@ -423,12 +506,12 @@ var CollapsibleTabView = (0, import_react4.forwardRef)(
|
|
|
423
506
|
],
|
|
424
507
|
pointerEvents: "box-none"
|
|
425
508
|
},
|
|
426
|
-
/* @__PURE__ */
|
|
427
|
-
/* @__PURE__ */
|
|
509
|
+
/* @__PURE__ */ import_react5.default.createElement(import_react_native4.View, { pointerEvents: "box-none", onLayout: handleHeaderLayout }, renderHeader()),
|
|
510
|
+
/* @__PURE__ */ import_react5.default.createElement(import_react_native4.View, { onLayout: handleTabBarLayout }, renderTabBarNode())
|
|
428
511
|
)));
|
|
429
512
|
}
|
|
430
513
|
);
|
|
431
|
-
var styles =
|
|
514
|
+
var styles = import_react_native4.StyleSheet.create({
|
|
432
515
|
container: {
|
|
433
516
|
flex: 1
|
|
434
517
|
},
|
|
@@ -453,5 +536,6 @@ var index_default = CollapsibleTabView;
|
|
|
453
536
|
// Annotate the CommonJS export names for ESM import in node:
|
|
454
537
|
0 && (module.exports = {
|
|
455
538
|
TabFlatList,
|
|
456
|
-
TabScrollView
|
|
539
|
+
TabScrollView,
|
|
540
|
+
TabSectionList
|
|
457
541
|
});
|
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
// src/index.tsx
|
|
2
|
-
import
|
|
3
|
-
forwardRef as
|
|
4
|
-
useCallback as
|
|
5
|
-
useImperativeHandle as
|
|
6
|
-
useMemo as
|
|
7
|
-
useRef as
|
|
8
|
-
useState as
|
|
2
|
+
import React4, {
|
|
3
|
+
forwardRef as forwardRef4,
|
|
4
|
+
useCallback as useCallback4,
|
|
5
|
+
useImperativeHandle as useImperativeHandle4,
|
|
6
|
+
useMemo as useMemo4,
|
|
7
|
+
useRef as useRef4,
|
|
8
|
+
useState as useState4
|
|
9
9
|
} from "react";
|
|
10
10
|
import {
|
|
11
|
-
Animated as
|
|
11
|
+
Animated as Animated4,
|
|
12
12
|
StyleSheet,
|
|
13
|
-
View as
|
|
13
|
+
View as View4
|
|
14
14
|
} from "react-native";
|
|
15
15
|
import PagerView from "react-native-pager-view";
|
|
16
16
|
|
|
@@ -121,16 +121,28 @@ import React2, {
|
|
|
121
121
|
useCallback as useCallback2,
|
|
122
122
|
useEffect as useEffect2,
|
|
123
123
|
useImperativeHandle as useImperativeHandle2,
|
|
124
|
+
useMemo as useMemo2,
|
|
124
125
|
useRef as useRef2,
|
|
125
126
|
useState as useState2
|
|
126
127
|
} from "react";
|
|
127
128
|
import {
|
|
128
|
-
Animated as Animated2
|
|
129
|
+
Animated as Animated2,
|
|
130
|
+
View as View2
|
|
129
131
|
} from "react-native";
|
|
130
132
|
var TabScrollView = forwardRef2(
|
|
131
133
|
({ contentContainerStyle, onScroll, children, ...props }, ref) => {
|
|
132
134
|
const index = useTabIndex();
|
|
133
|
-
const {
|
|
135
|
+
const {
|
|
136
|
+
scrollY,
|
|
137
|
+
activeIndex,
|
|
138
|
+
stickyEnabled,
|
|
139
|
+
headerHeight,
|
|
140
|
+
tabBarHeight,
|
|
141
|
+
renderHeader,
|
|
142
|
+
renderTabBar,
|
|
143
|
+
registerRef,
|
|
144
|
+
syncScrollY
|
|
145
|
+
} = useCollapsible();
|
|
134
146
|
const innerRef = useRef2(null);
|
|
135
147
|
const isActive = activeIndex === index;
|
|
136
148
|
useEffect2(() => {
|
|
@@ -146,8 +158,12 @@ var TabScrollView = forwardRef2(
|
|
|
146
158
|
},
|
|
147
159
|
[index, onScroll, syncScrollY]
|
|
148
160
|
);
|
|
149
|
-
const
|
|
150
|
-
|
|
161
|
+
const mergedChildren = useMemo2(() => {
|
|
162
|
+
if (stickyEnabled) return children;
|
|
163
|
+
return /* @__PURE__ */ React2.createElement(View2, null, renderHeader?.(), renderTabBar?.(), children);
|
|
164
|
+
}, [stickyEnabled, children, renderHeader, renderTabBar]);
|
|
165
|
+
const paddingTop = stickyEnabled ? headerHeight + tabBarHeight : 0;
|
|
166
|
+
const collapseRange = stickyEnabled ? headerHeight : 0;
|
|
151
167
|
const [containerHeight, setContainerHeight] = useState2(0);
|
|
152
168
|
const handleLayout = useCallback2((e) => {
|
|
153
169
|
setContainerHeight(e.nativeEvent.layout.height);
|
|
@@ -160,24 +176,107 @@ var TabScrollView = forwardRef2(
|
|
|
160
176
|
...props,
|
|
161
177
|
onLayout: handleLayout,
|
|
162
178
|
contentContainerStyle: [
|
|
163
|
-
{ paddingTop },
|
|
179
|
+
paddingTop > 0 && { paddingTop },
|
|
164
180
|
minHeight > 0 && { minHeight },
|
|
165
181
|
contentContainerStyle
|
|
166
182
|
],
|
|
167
|
-
onScroll: isActive ? Animated2.event(
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
183
|
+
onScroll: isActive && stickyEnabled ? Animated2.event(
|
|
184
|
+
[{ nativeEvent: { contentOffset: { y: scrollY } } }],
|
|
185
|
+
{
|
|
186
|
+
useNativeDriver: true,
|
|
187
|
+
listener: handleScroll
|
|
188
|
+
}
|
|
189
|
+
) : handleScroll,
|
|
171
190
|
scrollEventThrottle: 16,
|
|
172
191
|
showsVerticalScrollIndicator: false
|
|
173
192
|
},
|
|
174
|
-
|
|
193
|
+
mergedChildren
|
|
175
194
|
);
|
|
176
195
|
}
|
|
177
196
|
);
|
|
178
197
|
|
|
198
|
+
// src/TabSectionList.tsx
|
|
199
|
+
import React3, {
|
|
200
|
+
forwardRef as forwardRef3,
|
|
201
|
+
useCallback as useCallback3,
|
|
202
|
+
useEffect as useEffect3,
|
|
203
|
+
useImperativeHandle as useImperativeHandle3,
|
|
204
|
+
useMemo as useMemo3,
|
|
205
|
+
useRef as useRef3,
|
|
206
|
+
useState as useState3
|
|
207
|
+
} from "react";
|
|
208
|
+
import {
|
|
209
|
+
Animated as Animated3,
|
|
210
|
+
SectionList,
|
|
211
|
+
View as View3
|
|
212
|
+
} from "react-native";
|
|
213
|
+
var AnimatedSectionListComponent = Animated3.createAnimatedComponent(SectionList);
|
|
214
|
+
var AnimatedSectionList = AnimatedSectionListComponent;
|
|
215
|
+
var TabSectionListInner = ({ contentContainerStyle, onScroll, ListHeaderComponent, ...props }, ref) => {
|
|
216
|
+
const index = useTabIndex();
|
|
217
|
+
const {
|
|
218
|
+
scrollY,
|
|
219
|
+
activeIndex,
|
|
220
|
+
stickyEnabled,
|
|
221
|
+
headerHeight,
|
|
222
|
+
tabBarHeight,
|
|
223
|
+
renderHeader,
|
|
224
|
+
renderTabBar,
|
|
225
|
+
registerRef,
|
|
226
|
+
syncScrollY
|
|
227
|
+
} = useCollapsible();
|
|
228
|
+
const innerRef = useRef3(null);
|
|
229
|
+
const isActive = activeIndex === index;
|
|
230
|
+
useEffect3(() => {
|
|
231
|
+
registerRef(index, innerRef.current);
|
|
232
|
+
return () => registerRef(index, null);
|
|
233
|
+
}, [index]);
|
|
234
|
+
useImperativeHandle3(ref, () => innerRef.current, []);
|
|
235
|
+
const handleScroll = useCallback3(
|
|
236
|
+
(e) => {
|
|
237
|
+
const y = e.nativeEvent.contentOffset.y;
|
|
238
|
+
syncScrollY(index, y);
|
|
239
|
+
onScroll?.(e);
|
|
240
|
+
},
|
|
241
|
+
[index, onScroll, syncScrollY]
|
|
242
|
+
);
|
|
243
|
+
const mergedHeader = useMemo3(() => {
|
|
244
|
+
if (stickyEnabled) return ListHeaderComponent;
|
|
245
|
+
const OriginalHeader = typeof ListHeaderComponent === "function" ? /* @__PURE__ */ React3.createElement(ListHeaderComponent, null) : ListHeaderComponent ?? null;
|
|
246
|
+
return /* @__PURE__ */ React3.createElement(View3, null, renderHeader?.(), renderTabBar?.(), OriginalHeader);
|
|
247
|
+
}, [stickyEnabled, ListHeaderComponent, renderHeader, renderTabBar]);
|
|
248
|
+
const paddingTop = stickyEnabled ? headerHeight + tabBarHeight : 0;
|
|
249
|
+
const collapseRange = stickyEnabled ? headerHeight : 0;
|
|
250
|
+
const [containerHeight, setContainerHeight] = useState3(0);
|
|
251
|
+
const handleLayout = useCallback3((e) => {
|
|
252
|
+
setContainerHeight(e.nativeEvent.layout.height);
|
|
253
|
+
}, []);
|
|
254
|
+
const minHeight = containerHeight > 0 ? containerHeight + collapseRange : 0;
|
|
255
|
+
return /* @__PURE__ */ React3.createElement(
|
|
256
|
+
AnimatedSectionList,
|
|
257
|
+
{
|
|
258
|
+
...props,
|
|
259
|
+
ref: innerRef,
|
|
260
|
+
onLayout: handleLayout,
|
|
261
|
+
ListHeaderComponent: mergedHeader,
|
|
262
|
+
contentContainerStyle: [
|
|
263
|
+
paddingTop > 0 && { paddingTop },
|
|
264
|
+
minHeight > 0 && { minHeight },
|
|
265
|
+
contentContainerStyle
|
|
266
|
+
],
|
|
267
|
+
onScroll: isActive && stickyEnabled ? Animated3.event([{ nativeEvent: { contentOffset: { y: scrollY } } }], {
|
|
268
|
+
useNativeDriver: true,
|
|
269
|
+
listener: handleScroll
|
|
270
|
+
}) : handleScroll,
|
|
271
|
+
scrollEventThrottle: 16,
|
|
272
|
+
showsVerticalScrollIndicator: false
|
|
273
|
+
}
|
|
274
|
+
);
|
|
275
|
+
};
|
|
276
|
+
var TabSectionList = forwardRef3(TabSectionListInner);
|
|
277
|
+
|
|
179
278
|
// src/index.tsx
|
|
180
|
-
var CollapsibleTabView =
|
|
279
|
+
var CollapsibleTabView = forwardRef4(
|
|
181
280
|
({
|
|
182
281
|
children,
|
|
183
282
|
renderHeader,
|
|
@@ -192,13 +291,13 @@ var CollapsibleTabView = forwardRef3(
|
|
|
192
291
|
swipeEnabled = true,
|
|
193
292
|
style
|
|
194
293
|
}, ref) => {
|
|
195
|
-
const [activeIndex, setActiveIndex] =
|
|
196
|
-
const pagerRef =
|
|
197
|
-
const pages =
|
|
198
|
-
() =>
|
|
294
|
+
const [activeIndex, setActiveIndex] = useState4(initialTabIndex);
|
|
295
|
+
const pagerRef = useRef4(null);
|
|
296
|
+
const pages = useMemo4(
|
|
297
|
+
() => React4.Children.toArray(children).filter(React4.isValidElement),
|
|
199
298
|
[children]
|
|
200
299
|
);
|
|
201
|
-
|
|
300
|
+
useImperativeHandle4(ref, () => ({
|
|
202
301
|
scrollToTab: (index, animated = true) => {
|
|
203
302
|
if (index === activeIndex || index < 0 || index >= pages.length) return;
|
|
204
303
|
syncTabOnSwitch(index);
|
|
@@ -213,17 +312,17 @@ var CollapsibleTabView = forwardRef3(
|
|
|
213
312
|
getActiveIndex: () => activeIndex
|
|
214
313
|
}));
|
|
215
314
|
const hasEstimate = estimatedHeaderHeight > 0;
|
|
216
|
-
const headerHeightRef =
|
|
217
|
-
const tabBarHeightRef =
|
|
218
|
-
const [layout, setLayout] =
|
|
315
|
+
const headerHeightRef = useRef4(0);
|
|
316
|
+
const tabBarHeightRef = useRef4(0);
|
|
317
|
+
const [layout, setLayout] = useState4({
|
|
219
318
|
headerHeight: estimatedHeaderHeight,
|
|
220
319
|
tabBarHeight: estimatedTabBarHeight,
|
|
221
320
|
ready: hasEstimate
|
|
222
321
|
});
|
|
223
322
|
const { headerHeight, tabBarHeight } = layout;
|
|
224
323
|
const visible = layout.ready;
|
|
225
|
-
const adjustY =
|
|
226
|
-
const tryCommitLayout =
|
|
324
|
+
const adjustY = useRef4(new Animated4.Value(0)).current;
|
|
325
|
+
const tryCommitLayout = useCallback4(() => {
|
|
227
326
|
const h = headerHeightRef.current;
|
|
228
327
|
const t = tabBarHeightRef.current;
|
|
229
328
|
if (h > 0 && t > 0) {
|
|
@@ -234,7 +333,7 @@ var CollapsibleTabView = forwardRef3(
|
|
|
234
333
|
const diff = h + t - (prev.headerHeight + prev.tabBarHeight);
|
|
235
334
|
if (prev.ready && Math.abs(diff) > 1) {
|
|
236
335
|
adjustY.setValue(-diff);
|
|
237
|
-
|
|
336
|
+
Animated4.timing(adjustY, {
|
|
238
337
|
toValue: 0,
|
|
239
338
|
duration: 200,
|
|
240
339
|
useNativeDriver: true
|
|
@@ -244,35 +343,32 @@ var CollapsibleTabView = forwardRef3(
|
|
|
244
343
|
});
|
|
245
344
|
}
|
|
246
345
|
}, [adjustY]);
|
|
247
|
-
const handleHeaderLayout =
|
|
346
|
+
const handleHeaderLayout = useCallback4(
|
|
248
347
|
(e) => {
|
|
249
348
|
headerHeightRef.current = e.nativeEvent.layout.height;
|
|
250
349
|
tryCommitLayout();
|
|
251
350
|
},
|
|
252
351
|
[tryCommitLayout]
|
|
253
352
|
);
|
|
254
|
-
const handleTabBarLayout =
|
|
353
|
+
const handleTabBarLayout = useCallback4(
|
|
255
354
|
(e) => {
|
|
256
355
|
tabBarHeightRef.current = e.nativeEvent.layout.height;
|
|
257
356
|
tryCommitLayout();
|
|
258
357
|
},
|
|
259
358
|
[tryCommitLayout]
|
|
260
359
|
);
|
|
261
|
-
const scrollY =
|
|
262
|
-
const tabScrollYMap =
|
|
263
|
-
const tabRefs =
|
|
360
|
+
const scrollY = useRef4(new Animated4.Value(0)).current;
|
|
361
|
+
const tabScrollYMap = useRef4(/* @__PURE__ */ new Map());
|
|
362
|
+
const tabRefs = useRef4(
|
|
264
363
|
/* @__PURE__ */ new Map()
|
|
265
364
|
);
|
|
266
365
|
const collapseRange = stickyEnabled ? Math.max(headerHeight - stickyTop, 0) : 0;
|
|
267
|
-
const headerTranslateY =
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
[scrollY, collapseRange]
|
|
274
|
-
);
|
|
275
|
-
const registerRef = useCallback3(
|
|
366
|
+
const headerTranslateY = scrollY.interpolate({
|
|
367
|
+
inputRange: [0, Math.max(collapseRange, 1)],
|
|
368
|
+
outputRange: [0, -collapseRange],
|
|
369
|
+
extrapolate: "clamp"
|
|
370
|
+
});
|
|
371
|
+
const registerRef = useCallback4(
|
|
276
372
|
(index, ref2) => {
|
|
277
373
|
if (ref2) {
|
|
278
374
|
tabRefs.current.set(index, ref2);
|
|
@@ -282,14 +378,14 @@ var CollapsibleTabView = forwardRef3(
|
|
|
282
378
|
},
|
|
283
379
|
[]
|
|
284
380
|
);
|
|
285
|
-
const syncScrollY =
|
|
381
|
+
const syncScrollY = useCallback4(
|
|
286
382
|
(index, y) => {
|
|
287
383
|
tabScrollYMap.current.set(index, y);
|
|
288
384
|
onScrollProp?.(y);
|
|
289
385
|
},
|
|
290
386
|
[onScrollProp]
|
|
291
387
|
);
|
|
292
|
-
const scrollTabTo =
|
|
388
|
+
const scrollTabTo = useCallback4((index, offset) => {
|
|
293
389
|
const ref2 = tabRefs.current.get(index);
|
|
294
390
|
if (!ref2) return;
|
|
295
391
|
if (ref2.scrollToOffset) {
|
|
@@ -305,7 +401,7 @@ var CollapsibleTabView = forwardRef3(
|
|
|
305
401
|
}
|
|
306
402
|
}
|
|
307
403
|
}, []);
|
|
308
|
-
const syncTabOnSwitch =
|
|
404
|
+
const syncTabOnSwitch = useCallback4((newIndex) => {
|
|
309
405
|
const currentY = tabScrollYMap.current.get(activeIndex) ?? 0;
|
|
310
406
|
const newTabSavedY = tabScrollYMap.current.get(newIndex) ?? 0;
|
|
311
407
|
const isCollapsed = currentY >= collapseRange - 1;
|
|
@@ -314,7 +410,7 @@ var CollapsibleTabView = forwardRef3(
|
|
|
314
410
|
tabScrollYMap.current.set(newIndex, targetY);
|
|
315
411
|
scrollY.setValue(Math.min(targetY, collapseRange));
|
|
316
412
|
}, []);
|
|
317
|
-
const preSyncAdjacentTabs =
|
|
413
|
+
const preSyncAdjacentTabs = useCallback4(() => {
|
|
318
414
|
const currentY = tabScrollYMap.current.get(activeIndex) ?? 0;
|
|
319
415
|
const isCollapsed = currentY >= collapseRange - 1;
|
|
320
416
|
for (const i of [activeIndex - 1, activeIndex + 1]) {
|
|
@@ -325,7 +421,7 @@ var CollapsibleTabView = forwardRef3(
|
|
|
325
421
|
tabScrollYMap.current.set(i, targetY);
|
|
326
422
|
}
|
|
327
423
|
}, [activeIndex, collapseRange, pages.length, scrollTabTo]);
|
|
328
|
-
const handlePageScrollStateChanged =
|
|
424
|
+
const handlePageScrollStateChanged = useCallback4(
|
|
329
425
|
(e) => {
|
|
330
426
|
if (e.nativeEvent.pageScrollState === "dragging") {
|
|
331
427
|
preSyncAdjacentTabs();
|
|
@@ -333,7 +429,7 @@ var CollapsibleTabView = forwardRef3(
|
|
|
333
429
|
},
|
|
334
430
|
[preSyncAdjacentTabs]
|
|
335
431
|
);
|
|
336
|
-
const handleTabPress =
|
|
432
|
+
const handleTabPress = useCallback4(
|
|
337
433
|
(index) => {
|
|
338
434
|
if (index === activeIndex) return;
|
|
339
435
|
syncTabOnSwitch(index);
|
|
@@ -343,7 +439,7 @@ var CollapsibleTabView = forwardRef3(
|
|
|
343
439
|
},
|
|
344
440
|
[activeIndex, syncTabOnSwitch, onTabChange]
|
|
345
441
|
);
|
|
346
|
-
const handlePageSelected =
|
|
442
|
+
const handlePageSelected = useCallback4(
|
|
347
443
|
(e) => {
|
|
348
444
|
const newIndex = e.nativeEvent.position;
|
|
349
445
|
if (newIndex === activeIndex) return;
|
|
@@ -354,18 +450,18 @@ var CollapsibleTabView = forwardRef3(
|
|
|
354
450
|
},
|
|
355
451
|
[activeIndex, collapseRange, scrollY, onTabChange]
|
|
356
452
|
);
|
|
357
|
-
const tabBarProps =
|
|
453
|
+
const tabBarProps = useMemo4(
|
|
358
454
|
() => ({
|
|
359
455
|
activeIndex,
|
|
360
456
|
onTabPress: handleTabPress
|
|
361
457
|
}),
|
|
362
458
|
[activeIndex, handleTabPress]
|
|
363
459
|
);
|
|
364
|
-
const renderTabBarNode =
|
|
460
|
+
const renderTabBarNode = useCallback4(
|
|
365
461
|
() => renderTabBar(tabBarProps),
|
|
366
462
|
[renderTabBar, tabBarProps]
|
|
367
463
|
);
|
|
368
|
-
const contextValue =
|
|
464
|
+
const contextValue = useMemo4(
|
|
369
465
|
() => ({
|
|
370
466
|
scrollY,
|
|
371
467
|
activeIndex,
|
|
@@ -389,8 +485,8 @@ var CollapsibleTabView = forwardRef3(
|
|
|
389
485
|
syncScrollY
|
|
390
486
|
]
|
|
391
487
|
);
|
|
392
|
-
return /* @__PURE__ */
|
|
393
|
-
|
|
488
|
+
return /* @__PURE__ */ React4.createElement(CollapsibleContext.Provider, { value: contextValue }, /* @__PURE__ */ React4.createElement(View4, { style: [styles.container, style] }, /* @__PURE__ */ React4.createElement(
|
|
489
|
+
Animated4.View,
|
|
394
490
|
{
|
|
395
491
|
style: [
|
|
396
492
|
styles.pager,
|
|
@@ -398,7 +494,7 @@ var CollapsibleTabView = forwardRef3(
|
|
|
398
494
|
{ transform: [{ translateY: adjustY }] }
|
|
399
495
|
]
|
|
400
496
|
},
|
|
401
|
-
/* @__PURE__ */
|
|
497
|
+
/* @__PURE__ */ React4.createElement(
|
|
402
498
|
PagerView,
|
|
403
499
|
{
|
|
404
500
|
ref: pagerRef,
|
|
@@ -408,10 +504,10 @@ var CollapsibleTabView = forwardRef3(
|
|
|
408
504
|
onPageScrollStateChanged: handlePageScrollStateChanged,
|
|
409
505
|
scrollEnabled: swipeEnabled
|
|
410
506
|
},
|
|
411
|
-
pages.map((page, i) => /* @__PURE__ */
|
|
507
|
+
pages.map((page, i) => /* @__PURE__ */ React4.createElement(View4, { key: page?.key ?? i, style: styles.page }, /* @__PURE__ */ React4.createElement(TabIndexContext.Provider, { value: i }, page)))
|
|
412
508
|
)
|
|
413
|
-
), stickyEnabled && /* @__PURE__ */
|
|
414
|
-
|
|
509
|
+
), stickyEnabled && /* @__PURE__ */ React4.createElement(
|
|
510
|
+
Animated4.View,
|
|
415
511
|
{
|
|
416
512
|
style: [
|
|
417
513
|
styles.overlay,
|
|
@@ -419,8 +515,8 @@ var CollapsibleTabView = forwardRef3(
|
|
|
419
515
|
],
|
|
420
516
|
pointerEvents: "box-none"
|
|
421
517
|
},
|
|
422
|
-
/* @__PURE__ */
|
|
423
|
-
/* @__PURE__ */
|
|
518
|
+
/* @__PURE__ */ React4.createElement(View4, { pointerEvents: "box-none", onLayout: handleHeaderLayout }, renderHeader()),
|
|
519
|
+
/* @__PURE__ */ React4.createElement(View4, { onLayout: handleTabBarLayout }, renderTabBarNode())
|
|
424
520
|
)));
|
|
425
521
|
}
|
|
426
522
|
);
|
|
@@ -449,5 +545,6 @@ var index_default = CollapsibleTabView;
|
|
|
449
545
|
export {
|
|
450
546
|
TabFlatList,
|
|
451
547
|
TabScrollView,
|
|
548
|
+
TabSectionList,
|
|
452
549
|
index_default as default
|
|
453
550
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TabScrollView.d.ts","sourceRoot":"","sources":["../../src/TabScrollView.tsx"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"TabScrollView.d.ts","sourceRoot":"","sources":["../../src/TabScrollView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAC;AACf,OAAO,EAGL,iBAAiB,EACjB,oBAAoB,EACpB,UAAU,EACV,eAAe,EAEhB,MAAM,cAAc,CAAC;AAItB,MAAM,MAAM,kBAAkB,GAAG,IAAI,CAAC,eAAe,EAAE,UAAU,CAAC,GAAG;IACnE,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAC;CACjE,CAAC;AAEF,QAAA,MAAM,aAAa;eAHN,CAAC,CAAC,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,KAAK,IAAI;oCAsFhE,CAAC;AAEF,OAAO,EAAE,aAAa,EAAE,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { NativeScrollEvent, NativeSyntheticEvent, SectionList, SectionListProps } from "react-native";
|
|
3
|
+
export type TabSectionListProps<T = any> = Omit<SectionListProps<T>, "onScroll"> & {
|
|
4
|
+
onScroll?: (e: NativeSyntheticEvent<NativeScrollEvent>) => void;
|
|
5
|
+
};
|
|
6
|
+
export declare const TabSectionList: <T>(props: TabSectionListProps<T> & {
|
|
7
|
+
ref?: React.Ref<SectionList<T>>;
|
|
8
|
+
}) => React.ReactElement;
|
|
9
|
+
//# sourceMappingURL=TabSectionList.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabSectionList.d.ts","sourceRoot":"","sources":["../../src/TabSectionList.tsx"],"names":[],"mappings":"AAAA,OAAO,KAQN,MAAM,OAAO,CAAA;AACd,OAAO,EAGL,iBAAiB,EACjB,oBAAoB,EACpB,WAAW,EACX,gBAAgB,EAEjB,MAAM,cAAc,CAAA;AAUrB,MAAM,MAAM,mBAAmB,CAAC,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,UAAU,CAAC,GAAG;IACjF,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,oBAAoB,CAAC,iBAAiB,CAAC,KAAK,IAAI,CAAA;CAChE,CAAA;AA0FD,eAAO,MAAM,cAAc,EAAsC,CAAC,CAAC,EACjE,KAAK,EAAE,mBAAmB,CAAC,CAAC,CAAC,GAAG;IAAE,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAA;CAAE,KAChE,KAAK,CAAC,YAAY,CAAA"}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import React from "react";
|
|
|
2
2
|
import { CollapsibleTabViewProps, CollapsibleTabViewRef } from "./types";
|
|
3
3
|
export { TabFlatList } from "./TabFlatList";
|
|
4
4
|
export { TabScrollView } from "./TabScrollView";
|
|
5
|
+
export { TabSectionList } from "./TabSectionList";
|
|
5
6
|
export type { CollapsibleTabViewProps, CollapsibleTabViewRef, TabBarProps, } from "./types";
|
|
6
7
|
declare const CollapsibleTabView: React.ForwardRefExoticComponent<CollapsibleTabViewProps & React.RefAttributes<CollapsibleTabViewRef>>;
|
|
7
8
|
export default CollapsibleTabView;
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAaf,OAAO,EAEL,uBAAuB,EACvB,qBAAqB,EAEtB,MAAM,SAAS,CAAC;AAEjB,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,YAAY,EACV,uBAAuB,EACvB,qBAAqB,EACrB,WAAW,GACZ,MAAM,SAAS,CAAC;AAEjB,QAAA,MAAM,kBAAkB,uGAuTvB,CAAC;AAwBF,eAAe,kBAAkB,CAAC"}
|
package/dist/src/types.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { Animated, FlatList, ScrollView, StyleProp, ViewStyle } from "react-native";
|
|
2
|
+
import { Animated, FlatList, ScrollView, SectionList, StyleProp, ViewStyle } from "react-native";
|
|
3
3
|
export interface TabBarProps {
|
|
4
4
|
activeIndex: number;
|
|
5
5
|
onTabPress: (index: number) => void;
|
|
@@ -30,7 +30,7 @@ export interface CollapsibleContextValue {
|
|
|
30
30
|
tabBarHeight: number;
|
|
31
31
|
renderHeader?: () => React.ReactNode;
|
|
32
32
|
renderTabBar?: () => React.ReactNode;
|
|
33
|
-
registerRef: (index: number, ref: FlatList<any> | ScrollView | null) => void;
|
|
33
|
+
registerRef: (index: number, ref: FlatList<any> | SectionList<any> | ScrollView | null) => void;
|
|
34
34
|
syncScrollY: (index: number, y: number) => void;
|
|
35
35
|
}
|
|
36
36
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/src/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AAEhG,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACpC;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;IACzB,YAAY,EAAE,MAAM,KAAK,CAAC,SAAS,CAAA;IACnC,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,KAAK,CAAC,SAAS,CAAA;IACrD,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;IACrC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACpC,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAA;CAC7B;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACxD,cAAc,EAAE,MAAM,MAAM,CAAA;CAC7B;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAA;IACvB,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,OAAO,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAA;IACpC,YAAY,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAA;IACpC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,UAAU,GAAG,IAAI,KAAK,IAAI,CAAA;IAC/F,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,KAAK,IAAI,CAAA;CAChD"}
|