react-native-ui-lib 7.36.0-snapshot.6091 → 7.36.0-snapshot.6094

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 CHANGED
@@ -15,6 +15,13 @@
15
15
  [![NPM Downloads](https://img.shields.io/npm/dm/react-native-ui-lib.svg?style=flat)](https://www.npmjs.com/package/react-native-ui-lib)
16
16
  <a href="https://twitter.com/rnuilib"><img src="https://img.shields.io/twitter/follow/rnuilib.svg?style=flat&colorA=1DA1F2&colorB=20303C&label=Follow%20us%20on%20Twitter" alt="Follow on Twitter"></a>
17
17
 
18
+ ## Notes
19
+
20
+ #### React Native New Arc
21
+
22
+ We are working on upgrading our UI Library to support the new React Native Architecture.
23
+ Currently, we support React Native 0.73, and we plan to support React Native 0.77 next.
24
+ While we don’t have a timeline yet, this is part of our roadmap.
18
25
 
19
26
  ## Links
20
27
  - [Docs](https://wix.github.io/react-native-ui-lib/)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-native-ui-lib",
3
- "version": "7.36.0-snapshot.6091",
3
+ "version": "7.36.0-snapshot.6094",
4
4
  "main": "src/index.js",
5
5
  "types": "src/index.d.ts",
6
6
  "author": "Ethan Sharabi <ethan.shar@gmail.com>",
@@ -70,7 +70,7 @@
70
70
  "@formatjs/intl-locale": "^3.0.3",
71
71
  "@formatjs/intl-numberformat": "^8.0.4",
72
72
  "@formatjs/intl-pluralrules": "^5.0.3",
73
- "@react-native-community/blur": "4.4.1",
73
+ "@react-native-community/blur": "4.3.0",
74
74
  "@react-native-community/datetimepicker": "^3.4.6",
75
75
  "@react-native-community/netinfo": "^5.6.2",
76
76
  "@react-native/babel-preset": "0.73.21",
@@ -138,6 +138,7 @@ class FloatingButton extends PureComponent {
138
138
  }
139
139
  const styles = StyleSheet.create({
140
140
  container: {
141
+ ...StyleSheet.absoluteFillObject,
141
142
  top: undefined,
142
143
  zIndex: Constants.isAndroid ? 99 : undefined
143
144
  },
@@ -3,7 +3,6 @@ import { PickerProps, PickerValue, PickerSingleValue, PickerMultiValue } from '.
3
3
  interface UsePickerSelectionProps extends Pick<PickerProps, 'migrate' | 'value' | 'onChange' | 'getItemValue' | 'topBarProps' | 'mode'> {
4
4
  pickerExpandableRef: RefObject<any>;
5
5
  setSearchValue: (searchValue: string) => void;
6
- pickerRef: React.RefObject<any>;
7
6
  }
8
7
  declare const usePickerSelection: (props: UsePickerSelectionProps) => {
9
8
  multiDraftValue: PickerMultiValue;
@@ -2,7 +2,6 @@ import _xor from "lodash/xor";
2
2
  import _xorBy from "lodash/xorBy";
3
3
  import { useCallback, useState, useEffect } from 'react';
4
4
  import { PickerModes } from "../types";
5
- import { AccessibilityInfo } from 'react-native';
6
5
  const usePickerSelection = props => {
7
6
  const {
8
7
  migrate,
@@ -12,8 +11,7 @@ const usePickerSelection = props => {
12
11
  pickerExpandableRef,
13
12
  getItemValue,
14
13
  setSearchValue,
15
- mode,
16
- pickerRef
14
+ mode
17
15
  } = props;
18
16
  const [multiDraftValue, setMultiDraftValue] = useState(value);
19
17
  const [multiFinalValue, setMultiFinalValue] = useState(value);
@@ -28,10 +26,6 @@ const usePickerSelection = props => {
28
26
  setMultiFinalValue(item);
29
27
  pickerExpandableRef.current?.closeExpandable?.();
30
28
  onChange?.(item);
31
- const reactTag = pickerRef.current.getNodeHandle();
32
- if (reactTag) {
33
- AccessibilityInfo.setAccessibilityFocus(reactTag);
34
- }
35
29
  }, [onChange]);
36
30
  const toggleItemSelection = useCallback(item => {
37
31
  let newValue;
@@ -110,8 +110,7 @@ const Picker = React.forwardRef((props, ref) => {
110
110
  getItemValue,
111
111
  topBarProps,
112
112
  setSearchValue,
113
- mode,
114
- pickerRef
113
+ mode
115
114
  });
116
115
  const {
117
116
  label,
@@ -1,5 +1,4 @@
1
1
  import { useContext, useImperativeHandle, useRef } from 'react';
2
- import { findNodeHandle } from 'react-native';
3
2
  import FieldContext from "./FieldContext";
4
3
  const useImperativeInputHandle = (ref, props) => {
5
4
  const inputRef = useRef();
@@ -20,11 +19,6 @@ const useImperativeInputHandle = (ref, props) => {
20
19
  // Note: This returns field validity without actually validating it
21
20
  isValid: () => {
22
21
  return context.checkValidity();
23
- },
24
- getNodeHandle: () => {
25
- if (inputRef.current) {
26
- return findNodeHandle(inputRef.current);
27
- }
28
22
  }
29
23
  };
30
24
  });
@@ -1,21 +1,21 @@
1
- import React, { useContext, useCallback, useRef } from 'react';
1
+ import React, { useContext, useCallback, useRef, useState } from 'react';
2
2
  import { ActivityIndicator, StyleSheet } from 'react-native';
3
3
  import { runOnJS, useAnimatedReaction, useSharedValue } from 'react-native-reanimated';
4
4
  import { FlashListPackage } from "../../optionalDependencies";
5
5
  import { BorderRadiuses, Colors } from "../../style";
6
+ import { useDidUpdate } from "../../hooks";
6
7
  import View from "../../components/view";
7
8
  import Text from "../../components/text";
8
9
  import { isSameDay, isSameMonth } from "./helpers/DateUtils";
9
10
  import { UpdateSource } from "./types";
10
11
  import CalendarContext from "./CalendarContext";
11
12
  const FlashList = FlashListPackage?.FlashList;
12
-
13
- // TODO: Fix initial scrolling
14
13
  function Agenda(props) {
14
+ // TODO: Consider removing itemHeight if it's not needed
15
15
  const {
16
16
  renderEvent,
17
17
  renderHeader,
18
- itemHeight = 50,
18
+ itemHeight,
19
19
  onEndReached,
20
20
  showLoader
21
21
  } = props;
@@ -28,11 +28,22 @@ function Agenda(props) {
28
28
  const flashList = useRef(null);
29
29
  const closestSectionHeader = useSharedValue(null);
30
30
  const scrolledByUser = useSharedValue(false);
31
+ const [stickyHeaderIndices, setStickyHeaderIndices] = useState([]);
32
+ const lastDateBeforeLoadingNewEvents = useSharedValue(selectedDate.value);
31
33
 
32
34
  /* const keyExtractor = useCallback((item: InternalEvent) => {
33
35
  return item.type === 'Event' ? item.id : item.header;
34
36
  }, []); */
35
37
 
38
+ useDidUpdate(() => {
39
+ const result = findClosestDateAfter(lastDateBeforeLoadingNewEvents.value);
40
+ if (result?.index) {
41
+ setTimeout(() => scrollToIndex(result?.index, false), 200);
42
+ }
43
+ const headerIndices = data.map((e, index) => e.type === 'Header' ? index : undefined).filter(i => i !== undefined);
44
+ // @ts-expect-error
45
+ setStickyHeaderIndices(headerIndices);
46
+ }, [data]);
36
47
  const _renderEvent = useCallback(eventItem => {
37
48
  if (renderEvent) {
38
49
  return <View height={itemHeight} style={styles.eventContainer}>
@@ -61,7 +72,7 @@ function Agenda(props) {
61
72
  if (renderHeader) {
62
73
  return <View height={itemHeight}>{renderHeader(headerItem)}</View>;
63
74
  }
64
- return <View bottom marginB-5 marginH-20 height={itemHeight}>
75
+ return <View bg-$backgroundDefault bottom marginB-5 marginH-20 height={itemHeight}>
65
76
  <Text>{headerItem.header}</Text>
66
77
  </View>;
67
78
  }, [renderHeader, itemHeight]);
@@ -116,6 +127,10 @@ function Agenda(props) {
116
127
  const _isSameMonth = isSameMonth(selected, previous);
117
128
  runOnJS(scrollToIndex)(index, _isSameMonth);
118
129
  }
130
+ } else {
131
+ // Note: We got here because we are missing future agenda events to scroll to.
132
+ // therefor we should expect and new events data load
133
+ lastDateBeforeLoadingNewEvents.value = selectedDate.value;
119
134
  }
120
135
  }
121
136
  }
@@ -148,6 +163,7 @@ function Agenda(props) {
148
163
  // eslint-disable-next-line react-hooks/exhaustive-deps
149
164
  }, []);
150
165
  const _onEndReached = useCallback(() => {
166
+ lastDateBeforeLoadingNewEvents.value = selectedDate.value;
151
167
  onEndReached?.(selectedDate.value);
152
168
  // eslint-disable-next-line react-hooks/exhaustive-deps
153
169
  }, [onEndReached]);
@@ -155,7 +171,7 @@ function Agenda(props) {
155
171
  <FlashList ref={flashList} estimatedItemSize={52} data={data}
156
172
  // TODO: Not sure we need key extractor in flash list
157
173
  // keyExtractor={keyExtractor}
158
- renderItem={renderItem} getItemType={getItemType} onViewableItemsChanged={onViewableItemsChanged} onMomentumScrollBegin={onMomentumScrollBegin} onScrollBeginDrag={onScrollBeginDrag} initialScrollIndex={findClosestDateAfter(selectedDate.value)?.index ?? 0} onEndReached={_onEndReached} />
174
+ renderItem={renderItem} getItemType={getItemType} stickyHeaderIndices={stickyHeaderIndices} onViewableItemsChanged={onViewableItemsChanged} onMomentumScrollBegin={onMomentumScrollBegin} onScrollBeginDrag={onScrollBeginDrag} initialScrollIndex={findClosestDateAfter(selectedDate.value)?.index ?? 0} onEndReached={_onEndReached} />
159
175
  {showLoader && <View absF center style={{
160
176
  backgroundColor: Colors.rgba(Colors.grey10, 0.2)
161
177
  }}>
@@ -9,6 +9,12 @@ import { getDateObject, getMonthForIndex, addMonths } from "./helpers/DateUtils"
9
9
  import { DayNamesFormat, UpdateSource } from "./types";
10
10
  import CalendarContext from "./CalendarContext";
11
11
  import WeekDaysNames from "./WeekDaysNames";
12
+
13
+ // Note: this fixes the updates on the header month title
14
+ Reanimated.addWhitelistedNativeProps({
15
+ text: true
16
+ });
17
+ const ARROWS_THROTTLE_TIME = 300;
12
18
  const WEEK_NUMBER_WIDTH = 32;
13
19
  const ARROW_NEXT = require("./assets/arrowNext.png");
14
20
  const ARROW_BACK = require("./assets/arrowBack.png");
@@ -31,10 +37,16 @@ const Header = props => {
31
37
  }, []);
32
38
  const onLeftArrowPress = useCallback(throttle(() => {
33
39
  setDate(getNewDate(-1), UpdateSource.MONTH_ARROW);
34
- }, 300), [setDate, getNewDate]);
40
+ }, ARROWS_THROTTLE_TIME, {
41
+ leading: true,
42
+ trailing: false
43
+ }), [setDate, getNewDate]);
35
44
  const onRightArrowPress = useCallback(throttle(() => {
36
45
  setDate(getNewDate(1), UpdateSource.MONTH_ARROW);
37
- }, 300), [setDate, getNewDate]);
46
+ }, ARROWS_THROTTLE_TIME, {
47
+ leading: true,
48
+ trailing: false
49
+ }), [setDate, getNewDate]);
38
50
  const getTitle = useCallback(date => {
39
51
  'worklet';
40
52
 
@@ -15,12 +15,11 @@ import { useDidUpdate } from "../../hooks";
15
15
  const FlashList = FlashListPackage?.FlashList;
16
16
  const VIEWABILITY_CONFIG = {
17
17
  itemVisiblePercentThreshold: 95,
18
- minimumViewTime: 200
18
+ minimumViewTime: 1000
19
19
  };
20
- const YEARS_RANGE = 1;
20
+ const YEARS_RANGE = 5;
21
21
  const PAGE_RELOAD_THRESHOLD = 3;
22
- const NOW = Date.now(); // so the 'initialDate' effect won't get called since the now different on every rerender
23
-
22
+ const NOW = new Date().setHours(0, 0, 0, 0);
24
23
  function Calendar(props) {
25
24
  const {
26
25
  data,
@@ -31,20 +30,20 @@ function Calendar(props) {
31
30
  staticHeader = false,
32
31
  showExtraDays = true
33
32
  } = props;
34
- const [items] = useState(() => generateMonthItems(initialDate, YEARS_RANGE, YEARS_RANGE));
33
+ const [monthItems] = useState(() => generateMonthItems(initialDate, YEARS_RANGE, YEARS_RANGE));
35
34
  const getItemIndex = useCallback(date => {
36
35
  'worklet';
37
36
 
38
37
  const dateObject = getDateObject(date);
39
- for (let i = 0; i < items.length; i++) {
40
- if (items[i].month === dateObject.month && items[i].year === dateObject.year) {
38
+ for (let i = 0; i < monthItems.length; i++) {
39
+ if (monthItems[i].month === dateObject.month && monthItems[i].year === dateObject.year) {
41
40
  return i;
42
41
  }
43
42
  }
44
43
  return -1;
45
- }, [items]);
44
+ }, [monthItems]);
46
45
  const flashListRef = useRef();
47
- const current = useSharedValue(initialDate);
46
+ const current = useSharedValue(new Date(initialDate).setHours(0, 0, 0, 0));
48
47
  const initialMonthIndex = useRef(getItemIndex(current.value));
49
48
  const lastUpdateSource = useSharedValue(UpdateSource.INIT);
50
49
  const processedData = useMemo(() => addHeaders(data), [data]);
@@ -74,7 +73,7 @@ function Calendar(props) {
74
73
  console.log('Update items');
75
74
  const index = getItemIndex(current.value);
76
75
  scrollToIndex(index);
77
- }, [items, getItemIndex]);
76
+ }, [monthItems, getItemIndex]);
78
77
  const setHeaderHeight = useCallback(height => {
79
78
  headerHeight.value = height;
80
79
  // eslint-disable-next-line react-hooks/exhaustive-deps
@@ -116,21 +115,21 @@ function Calendar(props) {
116
115
  // const newDate = addYears(current.value, prepend ? -1 : 1);
117
116
  // const newItems = generateMonthItems(newDate, pastRange, futureRange);
118
117
  // const newArray = mergeArrays(prepend, items, newItems);
119
- // setItems(newArray);
118
+ // setMonthItems(newArray);
120
119
  // // eslint-disable-next-line react-hooks/exhaustive-deps
121
- }, [items]);
120
+ }, [monthItems]);
122
121
  const shouldAddPages = useCallback(index => {
123
122
  'worklet';
124
123
 
125
- return index !== -1 && (index < PAGE_RELOAD_THRESHOLD || index > items.length - PAGE_RELOAD_THRESHOLD);
124
+ return index !== -1 && (index < PAGE_RELOAD_THRESHOLD || index > monthItems.length - PAGE_RELOAD_THRESHOLD);
126
125
  // eslint-disable-next-line react-hooks/exhaustive-deps
127
- }, [items]);
126
+ }, [monthItems]);
128
127
  useAnimatedReaction(() => {
129
128
  return current.value;
130
129
  }, (selected, previous) => {
131
130
  const index = getItemIndex(selected);
132
131
  if (shouldAddPages(index)) {
133
- console.log('Add new pages: ', index, items.length);
132
+ console.log('Add new pages: ', index, monthItems.length);
134
133
  runOnJS(addPages)(/* index */);
135
134
  } else if (lastUpdateSource.value !== UpdateSource.MONTH_SCROLL) {
136
135
  if (previous && !isSameMonth(selected, previous)) {
@@ -176,7 +175,7 @@ function Calendar(props) {
176
175
  }, []);
177
176
  return <CalendarContext.Provider value={contextValue}>
178
177
  {staticHeader && <Header />}
179
- <FlashList ref={flashListRef} estimatedItemSize={Constants.screenWidth} data={items} initialScrollIndex={initialMonthIndex.current} estimatedFirstItemOffset={0} renderItem={renderCalendarItem} horizontal pagingEnabled showsHorizontalScrollIndicator={false}
178
+ <FlashList ref={flashListRef} estimatedItemSize={Constants.screenWidth} data={monthItems} initialScrollIndex={initialMonthIndex.current} estimatedFirstItemOffset={0} renderItem={renderCalendarItem} horizontal pagingEnabled showsHorizontalScrollIndicator={false}
180
179
  // TODO: Consider moving this shared logic with Agenda to a hook
181
180
  onViewableItemsChanged={onViewableItemsChanged} viewabilityConfig={VIEWABILITY_CONFIG} onMomentumScrollBegin={onMomentumScrollBegin} onScrollBeginDrag={onScrollBeginDrag} />
182
181
  {children}
@@ -113,7 +113,7 @@ export interface CalendarProps {
113
113
  export interface AgendaProps {
114
114
  renderEvent?: (event: Event) => React.ReactElement | null;
115
115
  renderHeader?: (header: DateSectionHeader) => React.ReactElement | null;
116
- itemHeight?: number;
116
+ itemHeight?: number | null;
117
117
  showLoader?: boolean;
118
118
  onEndReached?: (date: number) => void;
119
119
  }