react-native-ui-lib 7.46.3-snapshot.7356 → 7.46.3-snapshot.7360
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/package.json +1 -1
- package/package.json +2 -2
- package/src/components/tabController/TabBar.js +2 -1
- package/src/components/tabController/useScrollToItem.d.ts +79 -0
- package/src/components/tabController/useScrollToItem.js +159 -0
- package/src/hooks/useScrollToItem/index.d.ts +4 -18
- package/src/hooks/useScrollToItem/index.js +17 -56
package/lib/package.json
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-native-ui-lib",
|
|
3
|
-
"version": "7.46.3-snapshot.
|
|
3
|
+
"version": "7.46.3-snapshot.7360",
|
|
4
4
|
"main": "src/index.js",
|
|
5
5
|
"types": "src/index.d.ts",
|
|
6
6
|
"author": "Ethan Sharabi <ethan.shar@gmail.com>",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"react-native-redash": "^12.0.3",
|
|
57
57
|
"semver": "^5.5.0",
|
|
58
58
|
"tinycolor2": "^1.4.2",
|
|
59
|
-
"uilib-native": "5.0.0-snapshot.
|
|
59
|
+
"uilib-native": "5.0.0-snapshot.7358",
|
|
60
60
|
"url-parse": "^1.2.0",
|
|
61
61
|
"wix-react-native-text-size": "1.0.9"
|
|
62
62
|
},
|
|
@@ -9,7 +9,8 @@ import { Constants, asBaseComponent, forwardRef } from "../../commons/new";
|
|
|
9
9
|
import View from "../view";
|
|
10
10
|
import { Colors, Spacings, Typography } from "../../style";
|
|
11
11
|
import FadedScrollView from "../fadedScrollView";
|
|
12
|
-
import
|
|
12
|
+
import useScrollToItem from "./useScrollToItem";
|
|
13
|
+
import { useDidUpdate } from "../../hooks";
|
|
13
14
|
const DEFAULT_HEIGHT = 48;
|
|
14
15
|
const DEFAULT_LABEL_STYLE = {
|
|
15
16
|
...Typography.text80M,
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
import { LayoutChangeEvent } from 'react-native';
|
|
3
|
+
import { ScrollToSupportedViews, ScrollToResultProps } from 'hooks';
|
|
4
|
+
export declare enum OffsetType {
|
|
5
|
+
CENTER = "CENTER",
|
|
6
|
+
DYNAMIC = "DYNAMIC",
|
|
7
|
+
LEFT = "LEFT",
|
|
8
|
+
RIGHT = "RIGHT"
|
|
9
|
+
}
|
|
10
|
+
export type ScrollToItemProps<T extends ScrollToSupportedViews> = {
|
|
11
|
+
scrollViewRef?: RefObject<T>;
|
|
12
|
+
/**
|
|
13
|
+
* The number of items
|
|
14
|
+
*/
|
|
15
|
+
itemsCount: number;
|
|
16
|
+
/**
|
|
17
|
+
* The selected item's index
|
|
18
|
+
*/
|
|
19
|
+
selectedIndex?: number;
|
|
20
|
+
/**
|
|
21
|
+
* The container width, should update on orientation change
|
|
22
|
+
*/
|
|
23
|
+
containerWidth: number;
|
|
24
|
+
/**
|
|
25
|
+
* Where would the item be located (default to CENTER)
|
|
26
|
+
*/
|
|
27
|
+
offsetType?: OffsetType | `${OffsetType}`;
|
|
28
|
+
/**
|
|
29
|
+
* Add a margin to the offset (default to true)
|
|
30
|
+
* This gives a better UX
|
|
31
|
+
* Not relevant to OffsetType.CENTER
|
|
32
|
+
*/
|
|
33
|
+
addOffsetMargin?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* How much space (padding \ margin) is there on the left\right of the items
|
|
36
|
+
*/
|
|
37
|
+
outerSpacing?: number;
|
|
38
|
+
/**
|
|
39
|
+
* How much space (padding \ margin) is there between each item
|
|
40
|
+
*/
|
|
41
|
+
innerSpacing?: number;
|
|
42
|
+
};
|
|
43
|
+
export type ScrollToItemResultProps<T extends ScrollToSupportedViews> = Pick<ScrollToResultProps<T>, 'scrollViewRef'> & {
|
|
44
|
+
/**
|
|
45
|
+
* This should be called by each ot the items' onLayout
|
|
46
|
+
*/
|
|
47
|
+
onItemLayout: (event: LayoutChangeEvent, index: number) => void;
|
|
48
|
+
/**
|
|
49
|
+
* The items' width as share animated value
|
|
50
|
+
*/
|
|
51
|
+
itemsWidthsAnimated: any;
|
|
52
|
+
/**
|
|
53
|
+
* The items' offsets as share animated value
|
|
54
|
+
*/
|
|
55
|
+
itemsOffsetsAnimated: any;
|
|
56
|
+
/**
|
|
57
|
+
* Use in order to focus the item with the specified index (use when the selectedIndex is not changed)
|
|
58
|
+
*/
|
|
59
|
+
focusIndex: (index: number, animated?: boolean) => void;
|
|
60
|
+
/**
|
|
61
|
+
* Use in order to reset the data.
|
|
62
|
+
*/
|
|
63
|
+
reset: () => void;
|
|
64
|
+
/**
|
|
65
|
+
* onContentSizeChange callback (should be set to your onContentSizeChange).
|
|
66
|
+
* Needed for RTL support on Android.
|
|
67
|
+
*/
|
|
68
|
+
onContentSizeChange: (contentWidth: number, contentHeight: number) => void;
|
|
69
|
+
/**
|
|
70
|
+
* onLayout callback (should be set to your onLayout).
|
|
71
|
+
* Needed for RTL support on Android.
|
|
72
|
+
*/
|
|
73
|
+
onLayout: (event: LayoutChangeEvent) => void;
|
|
74
|
+
};
|
|
75
|
+
declare const useScrollToItem: {
|
|
76
|
+
<T extends ScrollToSupportedViews>(props: ScrollToItemProps<T>): ScrollToItemResultProps<T>;
|
|
77
|
+
offsetType: typeof OffsetType;
|
|
78
|
+
};
|
|
79
|
+
export default useScrollToItem;
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import _isUndefined from "lodash/isUndefined";
|
|
2
|
+
import _includes from "lodash/includes";
|
|
3
|
+
import _isEmpty from "lodash/isEmpty";
|
|
4
|
+
import _times from "lodash/times";
|
|
5
|
+
import { useState, useCallback, useEffect, useRef } from 'react';
|
|
6
|
+
import { useSharedValue } from 'react-native-reanimated';
|
|
7
|
+
import { useScrollTo } from "../../hooks";
|
|
8
|
+
import { Constants } from "../../commons/new";
|
|
9
|
+
const FIX_RTL = Constants.isRTL;
|
|
10
|
+
export let OffsetType = /*#__PURE__*/function (OffsetType) {
|
|
11
|
+
OffsetType["CENTER"] = "CENTER";
|
|
12
|
+
OffsetType["DYNAMIC"] = "DYNAMIC";
|
|
13
|
+
OffsetType["LEFT"] = "LEFT";
|
|
14
|
+
OffsetType["RIGHT"] = "RIGHT";
|
|
15
|
+
return OffsetType;
|
|
16
|
+
}({});
|
|
17
|
+
|
|
18
|
+
// TODO: this is what I want, is there a better way to do it?
|
|
19
|
+
|
|
20
|
+
const useScrollToItem = props => {
|
|
21
|
+
const {
|
|
22
|
+
scrollViewRef: propsScrollViewRef,
|
|
23
|
+
itemsCount,
|
|
24
|
+
selectedIndex,
|
|
25
|
+
containerWidth,
|
|
26
|
+
offsetType = OffsetType.CENTER,
|
|
27
|
+
addOffsetMargin = true,
|
|
28
|
+
outerSpacing = 0,
|
|
29
|
+
innerSpacing = 0
|
|
30
|
+
} = props;
|
|
31
|
+
const itemsWidths = useRef(_times(itemsCount, () => null));
|
|
32
|
+
const itemsWidthsAnimated = useSharedValue(_times(itemsCount, () => 0));
|
|
33
|
+
const itemsOffsetsAnimated = useSharedValue(_times(itemsCount, () => 0));
|
|
34
|
+
const currentIndex = useRef(selectedIndex || 0);
|
|
35
|
+
const [offsets, setOffsets] = useState({
|
|
36
|
+
CENTER: [],
|
|
37
|
+
LEFT: [],
|
|
38
|
+
RIGHT: []
|
|
39
|
+
});
|
|
40
|
+
const {
|
|
41
|
+
scrollViewRef,
|
|
42
|
+
scrollTo,
|
|
43
|
+
onContentSizeChange,
|
|
44
|
+
onLayout
|
|
45
|
+
} = useScrollTo({
|
|
46
|
+
scrollViewRef: propsScrollViewRef
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
// TODO: reset?
|
|
50
|
+
// useEffect(() => {
|
|
51
|
+
// itemsWidths.current = _.times(itemsCount, () => null);
|
|
52
|
+
// }, [itemsCount]);
|
|
53
|
+
|
|
54
|
+
// const contentWidth = _.sum(itemsWidths);
|
|
55
|
+
// TODO: const scrollEnabled = contentWidth.current > containerWidth;
|
|
56
|
+
|
|
57
|
+
const setSnapBreakpoints = useCallback(widths => {
|
|
58
|
+
if (_isEmpty(widths)) {
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
const screenCenter = containerWidth / 2;
|
|
62
|
+
let index = 0;
|
|
63
|
+
const centeredOffsets = [];
|
|
64
|
+
let currentCenterOffset = outerSpacing;
|
|
65
|
+
const leftOffsets = [];
|
|
66
|
+
leftOffsets.push(outerSpacing - innerSpacing);
|
|
67
|
+
const rightOffsets = [];
|
|
68
|
+
rightOffsets.push(-containerWidth + widths[0] + outerSpacing + innerSpacing);
|
|
69
|
+
while (index < itemsCount) {
|
|
70
|
+
/* calc center, left and right offsets */
|
|
71
|
+
centeredOffsets[index] = currentCenterOffset - screenCenter + widths[index] / 2;
|
|
72
|
+
++index;
|
|
73
|
+
currentCenterOffset += widths[index - 1] + innerSpacing;
|
|
74
|
+
leftOffsets[index] = leftOffsets[index - 1] + widths[index - 1] + innerSpacing;
|
|
75
|
+
rightOffsets[index] = rightOffsets[index - 1] + widths[index] + innerSpacing;
|
|
76
|
+
}
|
|
77
|
+
if (addOffsetMargin) {
|
|
78
|
+
index = 1;
|
|
79
|
+
while (index < itemsCount - 1) {
|
|
80
|
+
leftOffsets[index] -= widths[index - 1];
|
|
81
|
+
rightOffsets[index] += widths[index + 1] + innerSpacing;
|
|
82
|
+
++index;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
setOffsets({
|
|
86
|
+
CENTER: centeredOffsets,
|
|
87
|
+
LEFT: leftOffsets,
|
|
88
|
+
RIGHT: rightOffsets
|
|
89
|
+
}); // default for DYNAMIC is CENTER
|
|
90
|
+
|
|
91
|
+
// Update shared values
|
|
92
|
+
// @ts-expect-error pretty sure this is a bug in reanimated since itemsWidthsAnimated is defined as SharedValue<number[]>
|
|
93
|
+
itemsWidthsAnimated.modify(value => {
|
|
94
|
+
'worklet';
|
|
95
|
+
|
|
96
|
+
return value.map((_, index) => widths[index]);
|
|
97
|
+
});
|
|
98
|
+
itemsOffsetsAnimated.modify(value => {
|
|
99
|
+
'worklet';
|
|
100
|
+
|
|
101
|
+
value.forEach((_, index) => {
|
|
102
|
+
if (index > 0) {
|
|
103
|
+
value[index] = value[index - 1] + widths[index - 1];
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
return value;
|
|
107
|
+
});
|
|
108
|
+
}, [itemsCount, outerSpacing, innerSpacing, addOffsetMargin, containerWidth]);
|
|
109
|
+
const onItemLayout = useCallback((event, index) => {
|
|
110
|
+
const {
|
|
111
|
+
width
|
|
112
|
+
} = event.nativeEvent.layout;
|
|
113
|
+
itemsWidths.current[index] = width;
|
|
114
|
+
if (!_includes(itemsWidths.current, null)) {
|
|
115
|
+
setSnapBreakpoints(itemsWidths.current);
|
|
116
|
+
}
|
|
117
|
+
}, [setSnapBreakpoints]);
|
|
118
|
+
const focusIndex = useCallback((index, animated = true) => {
|
|
119
|
+
if (index >= 0 && offsets.CENTER.length > index) {
|
|
120
|
+
const rtlIndex = FIX_RTL ? itemsCount - index - 1 : index;
|
|
121
|
+
if (offsetType !== OffsetType.DYNAMIC) {
|
|
122
|
+
scrollTo(offsets[offsetType][rtlIndex], animated);
|
|
123
|
+
} else {
|
|
124
|
+
const movingLeft = index < currentIndex.current;
|
|
125
|
+
currentIndex.current = rtlIndex;
|
|
126
|
+
scrollTo(movingLeft ? offsets[OffsetType.RIGHT][rtlIndex] : offsets[OffsetType.LEFT][rtlIndex], animated);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}, [offsets, offsetType, scrollTo]);
|
|
130
|
+
useEffect(() => {
|
|
131
|
+
if (!_isUndefined(selectedIndex)) {
|
|
132
|
+
focusIndex(selectedIndex, false);
|
|
133
|
+
}
|
|
134
|
+
}, [selectedIndex, focusIndex]);
|
|
135
|
+
const reset = useCallback(() => {
|
|
136
|
+
for (let i = 0; i < itemsCount; ++i) {
|
|
137
|
+
itemsWidths.current[i] = null;
|
|
138
|
+
itemsWidthsAnimated.value[i] = 0;
|
|
139
|
+
itemsOffsetsAnimated.value[i] = 0;
|
|
140
|
+
}
|
|
141
|
+
setOffsets({
|
|
142
|
+
CENTER: [],
|
|
143
|
+
LEFT: [],
|
|
144
|
+
RIGHT: []
|
|
145
|
+
});
|
|
146
|
+
}, [itemsCount]);
|
|
147
|
+
return {
|
|
148
|
+
scrollViewRef,
|
|
149
|
+
onItemLayout,
|
|
150
|
+
itemsWidthsAnimated,
|
|
151
|
+
itemsOffsetsAnimated,
|
|
152
|
+
focusIndex,
|
|
153
|
+
reset,
|
|
154
|
+
onContentSizeChange,
|
|
155
|
+
onLayout
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
useScrollToItem.offsetType = OffsetType;
|
|
159
|
+
export default useScrollToItem;
|
|
@@ -1,14 +1,12 @@
|
|
|
1
|
-
import { RefObject } from 'react';
|
|
2
1
|
import { LayoutChangeEvent } from 'react-native';
|
|
3
|
-
import { ScrollToSupportedViews, ScrollToResultProps } from '
|
|
2
|
+
import { ScrollToProps, ScrollToSupportedViews, ScrollToResultProps } from '../useScrollTo';
|
|
4
3
|
export declare enum OffsetType {
|
|
5
4
|
CENTER = "CENTER",
|
|
6
5
|
DYNAMIC = "DYNAMIC",
|
|
7
6
|
LEFT = "LEFT",
|
|
8
7
|
RIGHT = "RIGHT"
|
|
9
8
|
}
|
|
10
|
-
export type ScrollToItemProps<T extends ScrollToSupportedViews> = {
|
|
11
|
-
scrollViewRef?: RefObject<T>;
|
|
9
|
+
export type ScrollToItemProps<T extends ScrollToSupportedViews> = Pick<ScrollToProps<T>, 'scrollViewRef'> & {
|
|
12
10
|
/**
|
|
13
11
|
* The number of items
|
|
14
12
|
*/
|
|
@@ -17,10 +15,6 @@ export type ScrollToItemProps<T extends ScrollToSupportedViews> = {
|
|
|
17
15
|
* The selected item's index
|
|
18
16
|
*/
|
|
19
17
|
selectedIndex?: number;
|
|
20
|
-
/**
|
|
21
|
-
* The container width, should update on orientation change
|
|
22
|
-
*/
|
|
23
|
-
containerWidth: number;
|
|
24
18
|
/**
|
|
25
19
|
* Where would the item be located (default to CENTER)
|
|
26
20
|
*/
|
|
@@ -46,21 +40,13 @@ export type ScrollToItemResultProps<T extends ScrollToSupportedViews> = Pick<Scr
|
|
|
46
40
|
*/
|
|
47
41
|
onItemLayout: (event: LayoutChangeEvent, index: number) => void;
|
|
48
42
|
/**
|
|
49
|
-
* The items' width
|
|
50
|
-
*/
|
|
51
|
-
itemsWidthsAnimated: any;
|
|
52
|
-
/**
|
|
53
|
-
* The items' offsets as share animated value
|
|
43
|
+
* The items' width
|
|
54
44
|
*/
|
|
55
|
-
|
|
45
|
+
itemsWidths: number[];
|
|
56
46
|
/**
|
|
57
47
|
* Use in order to focus the item with the specified index (use when the selectedIndex is not changed)
|
|
58
48
|
*/
|
|
59
49
|
focusIndex: (index: number, animated?: boolean) => void;
|
|
60
|
-
/**
|
|
61
|
-
* Use in order to reset the data.
|
|
62
|
-
*/
|
|
63
|
-
reset: () => void;
|
|
64
50
|
/**
|
|
65
51
|
* onContentSizeChange callback (should be set to your onContentSizeChange).
|
|
66
52
|
* Needed for RTL support on Android.
|
|
@@ -3,10 +3,8 @@ import _includes from "lodash/includes";
|
|
|
3
3
|
import _isEmpty from "lodash/isEmpty";
|
|
4
4
|
import _times from "lodash/times";
|
|
5
5
|
import { useState, useCallback, useEffect, useRef } from 'react';
|
|
6
|
-
import
|
|
7
|
-
import { useScrollTo } from "./..";
|
|
6
|
+
import useScrollTo from "../useScrollTo";
|
|
8
7
|
import { Constants } from "../../commons/new";
|
|
9
|
-
const FIX_RTL = Constants.isRTL;
|
|
10
8
|
export let OffsetType = /*#__PURE__*/function (OffsetType) {
|
|
11
9
|
OffsetType["CENTER"] = "CENTER";
|
|
12
10
|
OffsetType["DYNAMIC"] = "DYNAMIC";
|
|
@@ -22,15 +20,12 @@ const useScrollToItem = props => {
|
|
|
22
20
|
scrollViewRef: propsScrollViewRef,
|
|
23
21
|
itemsCount,
|
|
24
22
|
selectedIndex,
|
|
25
|
-
containerWidth,
|
|
26
23
|
offsetType = OffsetType.CENTER,
|
|
27
24
|
addOffsetMargin = true,
|
|
28
25
|
outerSpacing = 0,
|
|
29
26
|
innerSpacing = 0
|
|
30
27
|
} = props;
|
|
31
28
|
const itemsWidths = useRef(_times(itemsCount, () => null));
|
|
32
|
-
const itemsWidthsAnimated = useSharedValue(_times(itemsCount, () => 0));
|
|
33
|
-
const itemsOffsetsAnimated = useSharedValue(_times(itemsCount, () => 0));
|
|
34
29
|
const currentIndex = useRef(selectedIndex || 0);
|
|
35
30
|
const [offsets, setOffsets] = useState({
|
|
36
31
|
CENTER: [],
|
|
@@ -54,31 +49,30 @@ const useScrollToItem = props => {
|
|
|
54
49
|
// const contentWidth = _.sum(itemsWidths);
|
|
55
50
|
// TODO: const scrollEnabled = contentWidth.current > containerWidth;
|
|
56
51
|
|
|
57
|
-
const setSnapBreakpoints = useCallback(
|
|
58
|
-
if (_isEmpty(
|
|
52
|
+
const setSnapBreakpoints = useCallback(itemsWidths => {
|
|
53
|
+
if (_isEmpty(itemsWidths)) {
|
|
59
54
|
return;
|
|
60
55
|
}
|
|
61
|
-
const screenCenter =
|
|
56
|
+
const screenCenter = Constants.screenWidth / 2; // TODO: change to something more dynamic?
|
|
62
57
|
let index = 0;
|
|
63
58
|
const centeredOffsets = [];
|
|
64
59
|
let currentCenterOffset = outerSpacing;
|
|
65
60
|
const leftOffsets = [];
|
|
66
61
|
leftOffsets.push(outerSpacing - innerSpacing);
|
|
67
62
|
const rightOffsets = [];
|
|
68
|
-
rightOffsets.push(-
|
|
63
|
+
rightOffsets.push(-Constants.screenWidth + itemsWidths[0] + outerSpacing + innerSpacing);
|
|
69
64
|
while (index < itemsCount) {
|
|
70
|
-
|
|
71
|
-
centeredOffsets[index] = currentCenterOffset - screenCenter + widths[index] / 2;
|
|
65
|
+
centeredOffsets[index] = currentCenterOffset - screenCenter + itemsWidths[index] / 2;
|
|
72
66
|
++index;
|
|
73
|
-
currentCenterOffset +=
|
|
74
|
-
leftOffsets[index] = leftOffsets[index - 1] +
|
|
75
|
-
rightOffsets[index] = rightOffsets[index - 1] +
|
|
67
|
+
currentCenterOffset += itemsWidths[index - 1] + innerSpacing;
|
|
68
|
+
leftOffsets[index] = leftOffsets[index - 1] + itemsWidths[index - 1] + innerSpacing;
|
|
69
|
+
rightOffsets[index] = rightOffsets[index - 1] + itemsWidths[index] + innerSpacing;
|
|
76
70
|
}
|
|
77
71
|
if (addOffsetMargin) {
|
|
78
72
|
index = 1;
|
|
79
73
|
while (index < itemsCount - 1) {
|
|
80
|
-
leftOffsets[index] -=
|
|
81
|
-
rightOffsets[index] +=
|
|
74
|
+
leftOffsets[index] -= itemsWidths[index - 1];
|
|
75
|
+
rightOffsets[index] += itemsWidths[index + 1] + innerSpacing;
|
|
82
76
|
++index;
|
|
83
77
|
}
|
|
84
78
|
}
|
|
@@ -87,25 +81,7 @@ const useScrollToItem = props => {
|
|
|
87
81
|
LEFT: leftOffsets,
|
|
88
82
|
RIGHT: rightOffsets
|
|
89
83
|
}); // default for DYNAMIC is CENTER
|
|
90
|
-
|
|
91
|
-
// Update shared values
|
|
92
|
-
// @ts-expect-error pretty sure this is a bug in reanimated since itemsWidthsAnimated is defined as SharedValue<number[]>
|
|
93
|
-
itemsWidthsAnimated.modify(value => {
|
|
94
|
-
'worklet';
|
|
95
|
-
|
|
96
|
-
return value.map((_, index) => widths[index]);
|
|
97
|
-
});
|
|
98
|
-
itemsOffsetsAnimated.modify(value => {
|
|
99
|
-
'worklet';
|
|
100
|
-
|
|
101
|
-
value.forEach((_, index) => {
|
|
102
|
-
if (index > 0) {
|
|
103
|
-
value[index] = value[index - 1] + widths[index - 1];
|
|
104
|
-
}
|
|
105
|
-
});
|
|
106
|
-
return value;
|
|
107
|
-
});
|
|
108
|
-
}, [itemsCount, outerSpacing, innerSpacing, addOffsetMargin, containerWidth]);
|
|
84
|
+
}, [itemsCount, outerSpacing, innerSpacing, addOffsetMargin]);
|
|
109
85
|
const onItemLayout = useCallback((event, index) => {
|
|
110
86
|
const {
|
|
111
87
|
width
|
|
@@ -117,40 +93,25 @@ const useScrollToItem = props => {
|
|
|
117
93
|
}, [setSnapBreakpoints]);
|
|
118
94
|
const focusIndex = useCallback((index, animated = true) => {
|
|
119
95
|
if (index >= 0 && offsets.CENTER.length > index) {
|
|
120
|
-
const rtlIndex = FIX_RTL ? itemsCount - index - 1 : index;
|
|
121
96
|
if (offsetType !== OffsetType.DYNAMIC) {
|
|
122
|
-
scrollTo(offsets[offsetType][
|
|
97
|
+
scrollTo(offsets[offsetType][index], animated);
|
|
123
98
|
} else {
|
|
124
99
|
const movingLeft = index < currentIndex.current;
|
|
125
|
-
currentIndex.current =
|
|
126
|
-
scrollTo(movingLeft ? offsets[OffsetType.RIGHT][
|
|
100
|
+
currentIndex.current = index;
|
|
101
|
+
scrollTo(movingLeft ? offsets[OffsetType.RIGHT][index] : offsets[OffsetType.LEFT][index], animated);
|
|
127
102
|
}
|
|
128
103
|
}
|
|
129
104
|
}, [offsets, offsetType, scrollTo]);
|
|
130
105
|
useEffect(() => {
|
|
131
106
|
if (!_isUndefined(selectedIndex)) {
|
|
132
|
-
focusIndex(selectedIndex
|
|
107
|
+
focusIndex(selectedIndex);
|
|
133
108
|
}
|
|
134
109
|
}, [selectedIndex, focusIndex]);
|
|
135
|
-
const reset = useCallback(() => {
|
|
136
|
-
for (let i = 0; i < itemsCount; ++i) {
|
|
137
|
-
itemsWidths.current[i] = null;
|
|
138
|
-
itemsWidthsAnimated.value[i] = 0;
|
|
139
|
-
itemsOffsetsAnimated.value[i] = 0;
|
|
140
|
-
}
|
|
141
|
-
setOffsets({
|
|
142
|
-
CENTER: [],
|
|
143
|
-
LEFT: [],
|
|
144
|
-
RIGHT: []
|
|
145
|
-
});
|
|
146
|
-
}, [itemsCount]);
|
|
147
110
|
return {
|
|
148
111
|
scrollViewRef,
|
|
149
112
|
onItemLayout,
|
|
150
|
-
|
|
151
|
-
itemsOffsetsAnimated,
|
|
113
|
+
itemsWidths: offsets.CENTER.length > 0 ? itemsWidths.current : [],
|
|
152
114
|
focusIndex,
|
|
153
|
-
reset,
|
|
154
115
|
onContentSizeChange,
|
|
155
116
|
onLayout
|
|
156
117
|
};
|