@legendapp/list 1.0.12 → 1.0.14
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/CHANGELOG.md +4 -0
- package/index.js +116 -97
- package/index.mjs +68 -49
- package/keyboard-controller.d.mts +133 -133
- package/keyboard-controller.d.ts +133 -133
- package/package.json +1 -1
package/index.mjs
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import
|
|
1
|
+
import * as React2 from 'react';
|
|
2
|
+
import React2__default, { useReducer, useEffect, createContext, useMemo, useRef, useCallback, useImperativeHandle, useContext, useState, forwardRef, memo, useLayoutEffect } from 'react';
|
|
3
3
|
import { View, Text, Platform, Animated, ScrollView, StyleSheet, Dimensions, RefreshControl } from 'react-native';
|
|
4
4
|
import { useSyncExternalStore } from 'use-sync-external-store/shim';
|
|
5
5
|
|
|
6
6
|
// src/LegendList.tsx
|
|
7
|
-
var ContextState =
|
|
7
|
+
var ContextState = React2.createContext(null);
|
|
8
8
|
function StateProvider({ children }) {
|
|
9
|
-
const [value] =
|
|
9
|
+
const [value] = React2.useState(() => ({
|
|
10
10
|
listeners: /* @__PURE__ */ new Map(),
|
|
11
11
|
values: /* @__PURE__ */ new Map([
|
|
12
12
|
["paddingTop", 0],
|
|
@@ -21,10 +21,10 @@ function StateProvider({ children }) {
|
|
|
21
21
|
columnWrapperStyle: void 0,
|
|
22
22
|
viewRefs: /* @__PURE__ */ new Map()
|
|
23
23
|
}));
|
|
24
|
-
return /* @__PURE__ */
|
|
24
|
+
return /* @__PURE__ */ React2.createElement(ContextState.Provider, { value }, children);
|
|
25
25
|
}
|
|
26
26
|
function useStateContext() {
|
|
27
|
-
return
|
|
27
|
+
return React2.useContext(ContextState);
|
|
28
28
|
}
|
|
29
29
|
function createSelectorFunctionsArr(ctx, signalNames) {
|
|
30
30
|
let lastValues = [];
|
|
@@ -94,17 +94,17 @@ function getContentSize(ctx) {
|
|
|
94
94
|
return headerSize + footerSize + totalSize + stylePaddingTop;
|
|
95
95
|
}
|
|
96
96
|
function useArr$(signalNames) {
|
|
97
|
-
const ctx =
|
|
98
|
-
const { subscribe, get } =
|
|
97
|
+
const ctx = React2.useContext(ContextState);
|
|
98
|
+
const { subscribe, get } = React2.useMemo(() => createSelectorFunctionsArr(ctx, signalNames), [ctx, signalNames]);
|
|
99
99
|
const value = useSyncExternalStore(subscribe, get);
|
|
100
100
|
return value;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
103
|
// src/DebugView.tsx
|
|
104
104
|
var DebugRow = ({ children }) => {
|
|
105
|
-
return /* @__PURE__ */
|
|
105
|
+
return /* @__PURE__ */ React2.createElement(View, { style: { flexDirection: "row", alignItems: "center", justifyContent: "space-between" } }, children);
|
|
106
106
|
};
|
|
107
|
-
var DebugView =
|
|
107
|
+
var DebugView = React2.memo(function DebugView2({ state }) {
|
|
108
108
|
const ctx = useStateContext();
|
|
109
109
|
const [
|
|
110
110
|
totalSize = 0,
|
|
@@ -128,7 +128,7 @@ var DebugView = React3.memo(function DebugView2({ state }) {
|
|
|
128
128
|
useInterval(() => {
|
|
129
129
|
forceUpdate();
|
|
130
130
|
}, 100);
|
|
131
|
-
return /* @__PURE__ */
|
|
131
|
+
return /* @__PURE__ */ React2.createElement(
|
|
132
132
|
View,
|
|
133
133
|
{
|
|
134
134
|
style: {
|
|
@@ -144,15 +144,15 @@ var DebugView = React3.memo(function DebugView2({ state }) {
|
|
|
144
144
|
},
|
|
145
145
|
pointerEvents: "none"
|
|
146
146
|
},
|
|
147
|
-
/* @__PURE__ */
|
|
148
|
-
/* @__PURE__ */
|
|
149
|
-
/* @__PURE__ */
|
|
150
|
-
/* @__PURE__ */
|
|
151
|
-
/* @__PURE__ */
|
|
152
|
-
/* @__PURE__ */
|
|
153
|
-
/* @__PURE__ */
|
|
154
|
-
/* @__PURE__ */
|
|
155
|
-
/* @__PURE__ */
|
|
147
|
+
/* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "TotalSize:"), /* @__PURE__ */ React2.createElement(Text, null, totalSize.toFixed(2))),
|
|
148
|
+
/* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "ContentSize:"), /* @__PURE__ */ React2.createElement(Text, null, contentSize.toFixed(2))),
|
|
149
|
+
/* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "At end:"), /* @__PURE__ */ React2.createElement(Text, null, String(state.isAtBottom))),
|
|
150
|
+
/* @__PURE__ */ React2.createElement(Text, null),
|
|
151
|
+
/* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "ScrollAdjust:"), /* @__PURE__ */ React2.createElement(Text, null, scrollAdjust.toFixed(2))),
|
|
152
|
+
/* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "TotalSizeReal: "), /* @__PURE__ */ React2.createElement(Text, null, totalSizeWithScrollAdjust.toFixed(2))),
|
|
153
|
+
/* @__PURE__ */ React2.createElement(Text, null),
|
|
154
|
+
/* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "RawScroll: "), /* @__PURE__ */ React2.createElement(Text, null, rawScroll.toFixed(2))),
|
|
155
|
+
/* @__PURE__ */ React2.createElement(DebugRow, null, /* @__PURE__ */ React2.createElement(Text, null, "ComputedScroll: "), /* @__PURE__ */ React2.createElement(Text, null, scroll.toFixed(2)))
|
|
156
156
|
);
|
|
157
157
|
});
|
|
158
158
|
function useInterval(callback, delay) {
|
|
@@ -185,6 +185,13 @@ function comparatorByDistance(a, b) {
|
|
|
185
185
|
function comparatorDefault(a, b) {
|
|
186
186
|
return a - b;
|
|
187
187
|
}
|
|
188
|
+
function getPadding(s) {
|
|
189
|
+
var _a, _b, _c;
|
|
190
|
+
return (_c = (_b = (_a = s.paddingTop) != null ? _a : s.paddingVertical) != null ? _b : s.padding) != null ? _c : 0;
|
|
191
|
+
}
|
|
192
|
+
function extractPaddingTop(style, contentContainerStyle) {
|
|
193
|
+
return getPadding(style) + getPadding(contentContainerStyle);
|
|
194
|
+
}
|
|
188
195
|
var symbolFirst = Symbol();
|
|
189
196
|
function useInit(cb) {
|
|
190
197
|
const refValue = useRef(symbolFirst);
|
|
@@ -280,8 +287,8 @@ function useRecyclingState(valueOrFun) {
|
|
|
280
287
|
);
|
|
281
288
|
return [refState.current.value, setState];
|
|
282
289
|
}
|
|
283
|
-
var LeanViewComponent =
|
|
284
|
-
return
|
|
290
|
+
var LeanViewComponent = React2.forwardRef((props, ref) => {
|
|
291
|
+
return React2.createElement("RCTView", { ...props, ref });
|
|
285
292
|
});
|
|
286
293
|
LeanViewComponent.displayName = "RCTView";
|
|
287
294
|
var LeanView = Platform.OS === "android" || Platform.OS === "ios" ? LeanViewComponent : View;
|
|
@@ -421,16 +428,16 @@ var Container = ({
|
|
|
421
428
|
ctx.viewRefs.set(id, ref);
|
|
422
429
|
return { containerId: id, itemKey, index, value: data, triggerLayout };
|
|
423
430
|
}, [id, itemKey, index, data]);
|
|
424
|
-
const contentFragment = /* @__PURE__ */
|
|
431
|
+
const contentFragment = /* @__PURE__ */ React2__default.createElement(React2__default.Fragment, { key: recycleItems ? void 0 : itemKey }, /* @__PURE__ */ React2__default.createElement(ContextContainer.Provider, { value: contextValue }, renderedItem, renderedItemInfo && ItemSeparatorComponent && !lastItemKeys.includes(itemKey) && /* @__PURE__ */ React2__default.createElement(ItemSeparatorComponent, { leadingItem: renderedItemInfo.item })));
|
|
425
432
|
if (maintainVisibleContentPosition) {
|
|
426
433
|
const anchorStyle = position.type === "top" ? { position: "absolute", top: 0, left: 0, right: 0 } : { position: "absolute", bottom: 0, left: 0, right: 0 };
|
|
427
434
|
if (__DEV__ && ENABLE_DEVMODE) {
|
|
428
435
|
anchorStyle.borderColor = position.type === "top" ? "red" : "blue";
|
|
429
436
|
anchorStyle.borderWidth = 1;
|
|
430
437
|
}
|
|
431
|
-
return /* @__PURE__ */
|
|
438
|
+
return /* @__PURE__ */ React2__default.createElement(LeanView, { style }, /* @__PURE__ */ React2__default.createElement(LeanView, { style: [anchorStyle, paddingStyles], onLayout, ref }, contentFragment, __DEV__ && ENABLE_DEVMODE && /* @__PURE__ */ React2__default.createElement(Text, { style: { position: "absolute", top: 0, left: 0, zIndex: 1e3 } }, position.top)));
|
|
432
439
|
}
|
|
433
|
-
return /* @__PURE__ */
|
|
440
|
+
return /* @__PURE__ */ React2__default.createElement(LeanView, { style, onLayout, ref }, contentFragment);
|
|
434
441
|
};
|
|
435
442
|
var typedForwardRef = forwardRef;
|
|
436
443
|
var typedMemo = memo;
|
|
@@ -483,7 +490,7 @@ var Containers = typedMemo(function Containers2({
|
|
|
483
490
|
const containers = [];
|
|
484
491
|
for (let i = 0; i < numContainers; i++) {
|
|
485
492
|
containers.push(
|
|
486
|
-
/* @__PURE__ */
|
|
493
|
+
/* @__PURE__ */ React2.createElement(
|
|
487
494
|
Container,
|
|
488
495
|
{
|
|
489
496
|
id: i,
|
|
@@ -512,7 +519,7 @@ var Containers = typedMemo(function Containers2({
|
|
|
512
519
|
}
|
|
513
520
|
}
|
|
514
521
|
}
|
|
515
|
-
return /* @__PURE__ */
|
|
522
|
+
return /* @__PURE__ */ React2.createElement(Animated.View, { style }, containers);
|
|
516
523
|
});
|
|
517
524
|
function ListHeaderComponentContainer({
|
|
518
525
|
children,
|
|
@@ -527,7 +534,7 @@ function ListHeaderComponentContainer({
|
|
|
527
534
|
transform: [{ translateY: Animated.multiply(scrollAdjust, -1) }],
|
|
528
535
|
opacity: animOpacity
|
|
529
536
|
};
|
|
530
|
-
return /* @__PURE__ */
|
|
537
|
+
return /* @__PURE__ */ React2.createElement(
|
|
531
538
|
Animated.View,
|
|
532
539
|
{
|
|
533
540
|
style: [style, additionalSize],
|
|
@@ -542,11 +549,11 @@ function ListHeaderComponentContainer({
|
|
|
542
549
|
|
|
543
550
|
// src/ListComponent.tsx
|
|
544
551
|
var getComponent = (Component) => {
|
|
545
|
-
if (
|
|
552
|
+
if (React2.isValidElement(Component)) {
|
|
546
553
|
return Component;
|
|
547
554
|
}
|
|
548
555
|
if (Component) {
|
|
549
|
-
return /* @__PURE__ */
|
|
556
|
+
return /* @__PURE__ */ React2.createElement(Component, null);
|
|
550
557
|
}
|
|
551
558
|
return null;
|
|
552
559
|
};
|
|
@@ -554,12 +561,12 @@ var PaddingAndAdjust = () => {
|
|
|
554
561
|
const animPaddingTop = useValue$("paddingTop", (v) => v, true);
|
|
555
562
|
const animScrollAdjust = useValue$("scrollAdjust", (v) => v, true);
|
|
556
563
|
const additionalSize = { marginTop: animScrollAdjust, paddingTop: animPaddingTop };
|
|
557
|
-
return /* @__PURE__ */
|
|
564
|
+
return /* @__PURE__ */ React2.createElement(Animated.View, { style: additionalSize });
|
|
558
565
|
};
|
|
559
566
|
var PaddingAndAdjustDevMode = () => {
|
|
560
567
|
const animPaddingTop = useValue$("paddingTop", (v) => v, true);
|
|
561
568
|
const animScrollAdjust = useValue$("scrollAdjust", (v) => v, true);
|
|
562
|
-
return /* @__PURE__ */
|
|
569
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(Animated.View, { style: { marginTop: animScrollAdjust } }), /* @__PURE__ */ React2.createElement(Animated.View, { style: { paddingTop: animPaddingTop } }), /* @__PURE__ */ React2.createElement(
|
|
563
570
|
Animated.View,
|
|
564
571
|
{
|
|
565
572
|
style: {
|
|
@@ -571,7 +578,7 @@ var PaddingAndAdjustDevMode = () => {
|
|
|
571
578
|
backgroundColor: "green"
|
|
572
579
|
}
|
|
573
580
|
}
|
|
574
|
-
), /* @__PURE__ */
|
|
581
|
+
), /* @__PURE__ */ React2.createElement(
|
|
575
582
|
Animated.View,
|
|
576
583
|
{
|
|
577
584
|
style: {
|
|
@@ -583,7 +590,7 @@ var PaddingAndAdjustDevMode = () => {
|
|
|
583
590
|
backgroundColor: "lightblue"
|
|
584
591
|
}
|
|
585
592
|
}
|
|
586
|
-
), /* @__PURE__ */
|
|
593
|
+
), /* @__PURE__ */ React2.createElement(
|
|
587
594
|
Animated.View,
|
|
588
595
|
{
|
|
589
596
|
style: {
|
|
@@ -629,10 +636,10 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
629
636
|
}) {
|
|
630
637
|
const ctx = useStateContext();
|
|
631
638
|
const ScrollComponent = renderScrollComponent ? useMemo(
|
|
632
|
-
() =>
|
|
639
|
+
() => React2.forwardRef((props, ref) => renderScrollComponent({ ...props, ref })),
|
|
633
640
|
[renderScrollComponent]
|
|
634
641
|
) : ScrollView;
|
|
635
|
-
return /* @__PURE__ */
|
|
642
|
+
return /* @__PURE__ */ React2.createElement(
|
|
636
643
|
ScrollComponent,
|
|
637
644
|
{
|
|
638
645
|
...rest,
|
|
@@ -650,8 +657,8 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
650
657
|
contentOffset: initialContentOffset ? horizontal ? { x: initialContentOffset, y: 0 } : { x: 0, y: initialContentOffset } : void 0,
|
|
651
658
|
ref: refScrollView
|
|
652
659
|
},
|
|
653
|
-
!ListEmptyComponent && (ENABLE_DEVMODE ? /* @__PURE__ */
|
|
654
|
-
ListHeaderComponent && /* @__PURE__ */
|
|
660
|
+
!ListEmptyComponent && (ENABLE_DEVMODE ? /* @__PURE__ */ React2.createElement(PaddingAndAdjustDevMode, null) : /* @__PURE__ */ React2.createElement(PaddingAndAdjust, null)),
|
|
661
|
+
ListHeaderComponent && /* @__PURE__ */ React2.createElement(
|
|
655
662
|
ListHeaderComponentContainer,
|
|
656
663
|
{
|
|
657
664
|
style: ListHeaderComponentStyle,
|
|
@@ -662,7 +669,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
662
669
|
getComponent(ListHeaderComponent)
|
|
663
670
|
),
|
|
664
671
|
ListEmptyComponent && getComponent(ListEmptyComponent),
|
|
665
|
-
/* @__PURE__ */
|
|
672
|
+
/* @__PURE__ */ React2.createElement(
|
|
666
673
|
Containers,
|
|
667
674
|
{
|
|
668
675
|
horizontal,
|
|
@@ -673,7 +680,7 @@ var ListComponent = typedMemo(function ListComponent2({
|
|
|
673
680
|
updateItemSize
|
|
674
681
|
}
|
|
675
682
|
),
|
|
676
|
-
ListFooterComponent && /* @__PURE__ */
|
|
683
|
+
ListFooterComponent && /* @__PURE__ */ React2.createElement(
|
|
677
684
|
View,
|
|
678
685
|
{
|
|
679
686
|
style: ListFooterComponentStyle,
|
|
@@ -955,7 +962,7 @@ function createColumnWrapperStyle(contentContainerStyle) {
|
|
|
955
962
|
}
|
|
956
963
|
}
|
|
957
964
|
var LegendList = typedForwardRef(function LegendList2(props, forwardedRef) {
|
|
958
|
-
return /* @__PURE__ */
|
|
965
|
+
return /* @__PURE__ */ React2.createElement(StateProvider, null, /* @__PURE__ */ React2.createElement(LegendListInner, { ...props, ref: forwardedRef }));
|
|
959
966
|
});
|
|
960
967
|
var LegendListInner = typedForwardRef(function LegendListInner2(props, forwardedRef) {
|
|
961
968
|
const {
|
|
@@ -1006,7 +1013,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1006
1013
|
callbacks.current.onEndReached = rest.onEndReached;
|
|
1007
1014
|
const contentContainerStyle = { ...StyleSheet.flatten(contentContainerStyleProp) };
|
|
1008
1015
|
const style = { ...StyleSheet.flatten(styleProp) };
|
|
1009
|
-
const stylePaddingTopState = (
|
|
1016
|
+
const stylePaddingTopState = extractPaddingTop(style, contentContainerStyle);
|
|
1010
1017
|
if (style == null ? void 0 : style.paddingTop) {
|
|
1011
1018
|
style.paddingTop = void 0;
|
|
1012
1019
|
}
|
|
@@ -1055,8 +1062,10 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1055
1062
|
state.sizes.set(key, size);
|
|
1056
1063
|
return size;
|
|
1057
1064
|
};
|
|
1058
|
-
const calculateOffsetForIndex = (
|
|
1065
|
+
const calculateOffsetForIndex = (indexParam) => {
|
|
1059
1066
|
var _a;
|
|
1067
|
+
const isFromInit = indexParam === void 0;
|
|
1068
|
+
const index = isFromInit ? initialScrollIndex : indexParam;
|
|
1060
1069
|
const data = dataProp;
|
|
1061
1070
|
if (index !== void 0) {
|
|
1062
1071
|
let offset = 0;
|
|
@@ -1075,12 +1084,13 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
1075
1084
|
offset = index * estimatedItemSize;
|
|
1076
1085
|
}
|
|
1077
1086
|
const adjust = peek$(ctx, "containersDidLayout") ? ((_a = refState.current) == null ? void 0 : _a.scrollAdjustHandler.getAppliedAdjust()) || 0 : 0;
|
|
1078
|
-
const
|
|
1087
|
+
const stylePaddingTop = isFromInit ? stylePaddingTopState : peek$(ctx, "stylePaddingTop");
|
|
1088
|
+
const topPad = (stylePaddingTop != null ? stylePaddingTop : 0) + peek$(ctx, "headerSize");
|
|
1079
1089
|
return offset / numColumnsProp - adjust + topPad;
|
|
1080
1090
|
}
|
|
1081
1091
|
return 0;
|
|
1082
1092
|
};
|
|
1083
|
-
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : useMemo(calculateOffsetForIndex, []);
|
|
1093
|
+
const initialContentOffset = initialScrollOffset != null ? initialScrollOffset : useMemo(() => calculateOffsetForIndex(void 0), []);
|
|
1084
1094
|
if (!refState.current) {
|
|
1085
1095
|
const initialScrollLength = Dimensions.get("window")[horizontal ? "width" : "height"];
|
|
1086
1096
|
refState.current = {
|
|
@@ -2191,7 +2201,16 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2191
2201
|
if (!queuedInitialLayout && checkAllSizesKnown()) {
|
|
2192
2202
|
needsUpdateContainersDidLayout = true;
|
|
2193
2203
|
}
|
|
2194
|
-
|
|
2204
|
+
let isInView = index >= startBuffered && index <= endBuffered;
|
|
2205
|
+
if (!isInView) {
|
|
2206
|
+
const numContainers = ctx.values.get("numContainers");
|
|
2207
|
+
for (let i = 0; i < numContainers; i++) {
|
|
2208
|
+
if (peek$(ctx, `containerItemKey${i}`) === itemKey) {
|
|
2209
|
+
isInView = true;
|
|
2210
|
+
break;
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2195
2214
|
if (needsUpdateContainersDidLayout || !fromFixGaps && needsCalculate && (isInView || !queuedInitialLayout)) {
|
|
2196
2215
|
const scrollVelocity = state.scrollVelocity;
|
|
2197
2216
|
let didCalculate = false;
|
|
@@ -2386,7 +2405,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2386
2405
|
}
|
|
2387
2406
|
}, []);
|
|
2388
2407
|
}
|
|
2389
|
-
return /* @__PURE__ */
|
|
2408
|
+
return /* @__PURE__ */ React2.createElement(React2.Fragment, null, /* @__PURE__ */ React2.createElement(
|
|
2390
2409
|
ListComponent,
|
|
2391
2410
|
{
|
|
2392
2411
|
...rest,
|
|
@@ -2425,7 +2444,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2425
2444
|
maintainVisibleContentPosition,
|
|
2426
2445
|
scrollEventThrottle: Platform.OS === "web" ? 16 : void 0,
|
|
2427
2446
|
waitForInitialLayout,
|
|
2428
|
-
refreshControl: refreshControl != null ? refreshControl : onRefresh && /* @__PURE__ */
|
|
2447
|
+
refreshControl: refreshControl != null ? refreshControl : onRefresh && /* @__PURE__ */ React2.createElement(
|
|
2429
2448
|
RefreshControl,
|
|
2430
2449
|
{
|
|
2431
2450
|
refreshing: !!refreshing,
|
|
@@ -2436,7 +2455,7 @@ var LegendListInner = typedForwardRef(function LegendListInner2(props, forwarded
|
|
|
2436
2455
|
style,
|
|
2437
2456
|
contentContainerStyle
|
|
2438
2457
|
}
|
|
2439
|
-
), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */
|
|
2458
|
+
), __DEV__ && ENABLE_DEBUG_VIEW && /* @__PURE__ */ React2.createElement(DebugView, { state: refState.current }));
|
|
2440
2459
|
});
|
|
2441
2460
|
|
|
2442
2461
|
export { LegendList, useRecyclingEffect, useRecyclingState, useViewability, useViewabilityAmount };
|