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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "uilib-native",
3
- "version": "5.0.0-snapshot.7356",
3
+ "version": "5.0.0-snapshot.7360",
4
4
  "homepage": "https://github.com/wix/react-native-ui-lib",
5
5
  "description": "uilib native components (separated from js components)",
6
6
  "main": "components/index",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-ui-lib",
3
- "version": "7.46.3-snapshot.7356",
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.7266",
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 { useDidUpdate, useScrollToItem } from "../../hooks";
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 'hooks';
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 as share animated value
50
- */
51
- itemsWidthsAnimated: any;
52
- /**
53
- * The items' offsets as share animated value
43
+ * The items' width
54
44
  */
55
- itemsOffsetsAnimated: any;
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 { useSharedValue } from 'react-native-reanimated';
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(widths => {
58
- if (_isEmpty(widths)) {
52
+ const setSnapBreakpoints = useCallback(itemsWidths => {
53
+ if (_isEmpty(itemsWidths)) {
59
54
  return;
60
55
  }
61
- const screenCenter = containerWidth / 2;
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(-containerWidth + widths[0] + outerSpacing + innerSpacing);
63
+ rightOffsets.push(-Constants.screenWidth + itemsWidths[0] + outerSpacing + innerSpacing);
69
64
  while (index < itemsCount) {
70
- /* calc center, left and right offsets */
71
- centeredOffsets[index] = currentCenterOffset - screenCenter + widths[index] / 2;
65
+ centeredOffsets[index] = currentCenterOffset - screenCenter + itemsWidths[index] / 2;
72
66
  ++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;
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] -= widths[index - 1];
81
- rightOffsets[index] += widths[index + 1] + innerSpacing;
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][rtlIndex], animated);
97
+ scrollTo(offsets[offsetType][index], animated);
123
98
  } else {
124
99
  const movingLeft = index < currentIndex.current;
125
- currentIndex.current = rtlIndex;
126
- scrollTo(movingLeft ? offsets[OffsetType.RIGHT][rtlIndex] : offsets[OffsetType.LEFT][rtlIndex], animated);
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, false);
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
- itemsWidthsAnimated,
151
- itemsOffsetsAnimated,
113
+ itemsWidths: offsets.CENTER.length > 0 ? itemsWidths.current : [],
152
114
  focusIndex,
153
- reset,
154
115
  onContentSizeChange,
155
116
  onLayout
156
117
  };