@fountain-ui/lab 1.21.1 → 2.0.0-beta.11

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.
Files changed (191) hide show
  1. package/build/commonjs/AnimatedY/AnimatedY.js +10 -14
  2. package/build/commonjs/AnimatedY/AnimatedY.js.map +1 -1
  3. package/build/commonjs/AnimatedY/AnimatedYProps.js.map +1 -1
  4. package/build/commonjs/AnimatedY/index.js.map +1 -1
  5. package/build/commonjs/BottomSheet/BottomSheetNative.js +8 -2
  6. package/build/commonjs/BottomSheet/BottomSheetNative.js.map +1 -1
  7. package/build/commonjs/BottomSheet/BottomSheetProps.js.map +1 -1
  8. package/build/commonjs/BottomSheet/BottomSheetWeb.js +2 -6
  9. package/build/commonjs/BottomSheet/BottomSheetWeb.js.map +1 -1
  10. package/build/commonjs/BottomSheet/TransparentBackdrop.js +1 -1
  11. package/build/commonjs/BottomSheet/TransparentBackdrop.js.map +1 -1
  12. package/build/commonjs/BottomSheet/index.js.map +1 -1
  13. package/build/commonjs/BottomSheet/index.native.js.map +1 -1
  14. package/build/commonjs/Carousel/CarouselNative.js.map +1 -1
  15. package/build/commonjs/Carousel/CarouselProps.js.map +1 -1
  16. package/build/commonjs/Carousel/CarouselWeb.js +1 -1
  17. package/build/commonjs/Carousel/CarouselWeb.js.map +1 -1
  18. package/build/commonjs/Carousel/index.js.map +1 -1
  19. package/build/commonjs/Carousel/index.native.js.map +1 -1
  20. package/build/commonjs/Carousel/utils.js +1 -1
  21. package/build/commonjs/Carousel/utils.js.map +1 -1
  22. package/build/commonjs/ComicViewer/ComicViewer.js +168 -0
  23. package/build/commonjs/ComicViewer/ComicViewer.js.map +1 -0
  24. package/build/commonjs/ComicViewer/ComicViewerItemProps.js +6 -0
  25. package/build/commonjs/ComicViewer/ComicViewerItemProps.js.map +1 -0
  26. package/build/commonjs/ComicViewer/ComicViewerProps.js +2 -0
  27. package/build/commonjs/ComicViewer/ComicViewerProps.js.map +1 -0
  28. package/build/commonjs/ComicViewer/ViewerItem.js +88 -0
  29. package/build/commonjs/ComicViewer/ViewerItem.js.map +1 -0
  30. package/build/commonjs/ComicViewer/index.js +16 -0
  31. package/build/commonjs/ComicViewer/index.js.map +1 -0
  32. package/build/commonjs/DateTimePicker/DateTimePicker.js +7 -1
  33. package/build/commonjs/DateTimePicker/DateTimePicker.js.map +1 -1
  34. package/build/commonjs/DateTimePicker/DateTimePickerProps.js.map +1 -1
  35. package/build/commonjs/DateTimePicker/DateTimePickerProvider.js.map +1 -1
  36. package/build/commonjs/DateTimePicker/YearPicker.js +22 -17
  37. package/build/commonjs/DateTimePicker/YearPicker.js.map +1 -1
  38. package/build/commonjs/DateTimePicker/index.js +4 -4
  39. package/build/commonjs/DateTimePicker/index.js.map +1 -1
  40. package/build/commonjs/DateTimePicker/utils.js +2 -1
  41. package/build/commonjs/DateTimePicker/utils.js.map +1 -1
  42. package/build/commonjs/FlipCard/FlipCard.js +7 -13
  43. package/build/commonjs/FlipCard/FlipCard.js.map +1 -1
  44. package/build/commonjs/FlipCard/FlipCardProps.js.map +1 -1
  45. package/build/commonjs/FlipCard/index.js.map +1 -1
  46. package/build/commonjs/StatusBarProvider/Provider.js +1 -1
  47. package/build/commonjs/StatusBarProvider/Provider.js.map +1 -1
  48. package/build/commonjs/StatusBarProvider/StatusBarProvider.js.map +1 -1
  49. package/build/commonjs/StatusBarProvider/StatusBarProviderProps.js.map +1 -1
  50. package/build/commonjs/StatusBarProvider/index.js.map +1 -1
  51. package/build/commonjs/ViewPager/ChildrenMemoizedPage.js +90 -22
  52. package/build/commonjs/ViewPager/ChildrenMemoizedPage.js.map +1 -1
  53. package/build/commonjs/ViewPager/ViewPagerNative.js +46 -36
  54. package/build/commonjs/ViewPager/ViewPagerNative.js.map +1 -1
  55. package/build/commonjs/ViewPager/ViewPagerProps.js.map +1 -1
  56. package/build/commonjs/ViewPager/ViewPagerWeb.js +32 -25
  57. package/build/commonjs/ViewPager/ViewPagerWeb.js.map +1 -1
  58. package/build/commonjs/ViewPager/index.js.map +1 -1
  59. package/build/commonjs/ViewPager/index.native.js.map +1 -1
  60. package/build/commonjs/ViewPager/utils.js +3 -39
  61. package/build/commonjs/ViewPager/utils.js.map +1 -1
  62. package/build/commonjs/hooks/index.js.map +1 -1
  63. package/build/commonjs/hooks/useAppbarStyles.js.map +1 -1
  64. package/build/commonjs/hooks/useElevationStyle.js.map +1 -1
  65. package/build/commonjs/hooks/useHeight.js +5 -4
  66. package/build/commonjs/hooks/useHeight.js.map +1 -1
  67. package/build/commonjs/hooks/useUnstableCollapsibleAppBar.js +56 -57
  68. package/build/commonjs/hooks/useUnstableCollapsibleAppBar.js.map +1 -1
  69. package/build/commonjs/hooks/useUnstableToggleDisplayStyle.js +9 -11
  70. package/build/commonjs/hooks/useUnstableToggleDisplayStyle.js.map +1 -1
  71. package/build/commonjs/index.js +25 -4
  72. package/build/commonjs/index.js.map +1 -1
  73. package/build/module/AnimatedY/AnimatedY.js +11 -10
  74. package/build/module/AnimatedY/AnimatedY.js.map +1 -1
  75. package/build/module/AnimatedY/AnimatedYProps.js.map +1 -1
  76. package/build/module/AnimatedY/index.js.map +1 -1
  77. package/build/module/BottomSheet/BottomSheetNative.js +8 -2
  78. package/build/module/BottomSheet/BottomSheetNative.js.map +1 -1
  79. package/build/module/BottomSheet/BottomSheetProps.js.map +1 -1
  80. package/build/module/BottomSheet/BottomSheetWeb.js +2 -6
  81. package/build/module/BottomSheet/BottomSheetWeb.js.map +1 -1
  82. package/build/module/BottomSheet/TransparentBackdrop.js +1 -1
  83. package/build/module/BottomSheet/TransparentBackdrop.js.map +1 -1
  84. package/build/module/BottomSheet/index.js.map +1 -1
  85. package/build/module/BottomSheet/index.native.js.map +1 -1
  86. package/build/module/Carousel/CarouselNative.js.map +1 -1
  87. package/build/module/Carousel/CarouselProps.js.map +1 -1
  88. package/build/module/Carousel/CarouselWeb.js +1 -1
  89. package/build/module/Carousel/CarouselWeb.js.map +1 -1
  90. package/build/module/Carousel/index.js.map +1 -1
  91. package/build/module/Carousel/index.native.js.map +1 -1
  92. package/build/module/Carousel/utils.js.map +1 -1
  93. package/build/module/ComicViewer/ComicViewer.js +151 -0
  94. package/build/module/ComicViewer/ComicViewer.js.map +1 -0
  95. package/build/module/ComicViewer/ComicViewerItemProps.js +2 -0
  96. package/build/module/ComicViewer/ComicViewerItemProps.js.map +1 -0
  97. package/build/module/ComicViewer/ComicViewerProps.js +2 -0
  98. package/build/module/ComicViewer/ComicViewerProps.js.map +1 -0
  99. package/build/module/ComicViewer/ViewerItem.js +72 -0
  100. package/build/module/ComicViewer/ViewerItem.js.map +1 -0
  101. package/build/module/ComicViewer/index.js +2 -0
  102. package/build/module/ComicViewer/index.js.map +1 -0
  103. package/build/module/DateTimePicker/DateTimePicker.js +7 -1
  104. package/build/module/DateTimePicker/DateTimePicker.js.map +1 -1
  105. package/build/module/DateTimePicker/DateTimePickerProps.js.map +1 -1
  106. package/build/module/DateTimePicker/DateTimePickerProvider.js.map +1 -1
  107. package/build/module/DateTimePicker/YearPicker.js +22 -17
  108. package/build/module/DateTimePicker/YearPicker.js.map +1 -1
  109. package/build/module/DateTimePicker/index.js.map +1 -1
  110. package/build/module/DateTimePicker/utils.js +2 -1
  111. package/build/module/DateTimePicker/utils.js.map +1 -1
  112. package/build/module/FlipCard/FlipCard.js +7 -7
  113. package/build/module/FlipCard/FlipCard.js.map +1 -1
  114. package/build/module/FlipCard/FlipCardProps.js.map +1 -1
  115. package/build/module/FlipCard/index.js.map +1 -1
  116. package/build/module/StatusBarProvider/Provider.js.map +1 -1
  117. package/build/module/StatusBarProvider/StatusBarProvider.js.map +1 -1
  118. package/build/module/StatusBarProvider/StatusBarProviderProps.js.map +1 -1
  119. package/build/module/StatusBarProvider/index.js.map +1 -1
  120. package/build/module/ViewPager/ChildrenMemoizedPage.js +85 -23
  121. package/build/module/ViewPager/ChildrenMemoizedPage.js.map +1 -1
  122. package/build/module/ViewPager/ViewPagerNative.js +43 -32
  123. package/build/module/ViewPager/ViewPagerNative.js.map +1 -1
  124. package/build/module/ViewPager/ViewPagerProps.js.map +1 -1
  125. package/build/module/ViewPager/ViewPagerWeb.js +26 -23
  126. package/build/module/ViewPager/ViewPagerWeb.js.map +1 -1
  127. package/build/module/ViewPager/index.js.map +1 -1
  128. package/build/module/ViewPager/index.native.js.map +1 -1
  129. package/build/module/ViewPager/utils.js +1 -31
  130. package/build/module/ViewPager/utils.js.map +1 -1
  131. package/build/module/hooks/index.js.map +1 -1
  132. package/build/module/hooks/useAppbarStyles.js.map +1 -1
  133. package/build/module/hooks/useElevationStyle.js.map +1 -1
  134. package/build/module/hooks/useHeight.js +4 -3
  135. package/build/module/hooks/useHeight.js.map +1 -1
  136. package/build/module/hooks/useUnstableCollapsibleAppBar.js +58 -43
  137. package/build/module/hooks/useUnstableCollapsibleAppBar.js.map +1 -1
  138. package/build/module/hooks/useUnstableToggleDisplayStyle.js +9 -7
  139. package/build/module/hooks/useUnstableToggleDisplayStyle.js.map +1 -1
  140. package/build/module/index.js +2 -0
  141. package/build/module/index.js.map +1 -1
  142. package/build/typescript/AnimatedY/AnimatedY.d.ts +0 -1
  143. package/build/typescript/BottomSheet/BottomSheetNative.d.ts +0 -1
  144. package/build/typescript/BottomSheet/BottomSheetWeb.d.ts +0 -1
  145. package/build/typescript/BottomSheet/TransparentBackdrop.d.ts +0 -1
  146. package/build/typescript/Carousel/CarouselNative.d.ts +0 -1
  147. package/build/typescript/ComicViewer/ComicViewer.d.ts +2 -0
  148. package/build/typescript/ComicViewer/ComicViewerItemProps.d.ts +12 -0
  149. package/build/typescript/ComicViewer/ComicViewerProps.d.ts +76 -0
  150. package/build/typescript/ComicViewer/ViewerItem.d.ts +7 -0
  151. package/build/typescript/ComicViewer/index.d.ts +3 -0
  152. package/build/typescript/DateTimePicker/DateTimePicker.d.ts +0 -1
  153. package/build/typescript/DateTimePicker/YearPicker.d.ts +0 -1
  154. package/build/typescript/FlipCard/FlipCard.d.ts +0 -1
  155. package/build/typescript/StatusBarProvider/StatusBarProvider.d.ts +0 -1
  156. package/build/typescript/ViewPager/ChildrenMemoizedPage.d.ts +2 -1
  157. package/build/typescript/ViewPager/ViewPagerNative.d.ts +4 -2
  158. package/build/typescript/ViewPager/ViewPagerProps.d.ts +20 -19
  159. package/build/typescript/ViewPager/ViewPagerWeb.d.ts +4 -2
  160. package/build/typescript/ViewPager/index.d.ts +1 -1
  161. package/build/typescript/ViewPager/utils.d.ts +2 -19
  162. package/build/typescript/hooks/useUnstableCollapsibleAppBar.d.ts +2 -3
  163. package/build/typescript/hooks/useUnstableToggleDisplayStyle.d.ts +2 -2
  164. package/build/typescript/index.d.ts +2 -0
  165. package/package.json +13 -13
  166. package/src/AnimatedY/AnimatedY.tsx +13 -10
  167. package/src/BottomSheet/BottomSheetNative.tsx +6 -0
  168. package/src/ComicViewer/ComicViewer.tsx +162 -0
  169. package/src/ComicViewer/ComicViewerItemProps.ts +15 -0
  170. package/src/ComicViewer/ComicViewerProps.ts +90 -0
  171. package/src/ComicViewer/ViewerItem.tsx +76 -0
  172. package/src/ComicViewer/index.ts +3 -0
  173. package/src/DateTimePicker/DateTimePicker.tsx +6 -0
  174. package/src/DateTimePicker/YearPicker.tsx +2 -1
  175. package/src/FlipCard/FlipCard.tsx +8 -8
  176. package/src/ViewPager/ChildrenMemoizedPage.tsx +91 -22
  177. package/src/ViewPager/ViewPagerNative.tsx +47 -35
  178. package/src/ViewPager/ViewPagerProps.ts +20 -19
  179. package/src/ViewPager/ViewPagerWeb.tsx +34 -29
  180. package/src/ViewPager/index.ts +1 -1
  181. package/src/ViewPager/utils.tsx +2 -55
  182. package/src/hooks/useHeight.ts +2 -2
  183. package/src/hooks/useUnstableCollapsibleAppBar.ts +59 -42
  184. package/src/hooks/useUnstableToggleDisplayStyle.ts +8 -6
  185. package/src/index.ts +3 -0
  186. package/build/commonjs/hooks/useWidth.js +0 -29
  187. package/build/commonjs/hooks/useWidth.js.map +0 -1
  188. package/build/module/hooks/useWidth.js +0 -15
  189. package/build/module/hooks/useWidth.js.map +0 -1
  190. package/build/typescript/hooks/useWidth.d.ts +0 -2
  191. package/src/hooks/useWidth.ts +0 -17
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fountain-ui/lab",
3
- "version": "1.21.1",
3
+ "version": "2.0.0-beta.11",
4
4
  "private": false,
5
5
  "author": "Fountain-UI Team",
6
6
  "description": "Incubator for Fountain-UI React components.",
@@ -15,20 +15,21 @@
15
15
  "prepare": "bob build"
16
16
  },
17
17
  "dependencies": {
18
- "@emotion/react": "^11.4.1",
19
- "@emotion/styled": "^11.0.0",
20
- "@fountain-ui/icons": "^1.20.1",
21
- "@fountain-ui/utils": "^1.1.0",
18
+ "@emotion/react": "^11.10.0",
19
+ "@emotion/styled": "^11.10.0",
20
+ "@fountain-ui/icons": "^2.0.0-beta.6",
21
+ "@fountain-ui/utils": "^2.0.0-beta.3",
22
22
  "react-native-calendars": "1.1267.0"
23
23
  },
24
24
  "peerDependencies": {
25
- "@fountain-ui/core": "^1.0.0-alpha.4",
25
+ "@fountain-ui/core": "^2.0.0-beta.3",
26
26
  "@gorhom/bottom-sheet": "^4.1.3",
27
- "@react-native-community/viewpager": "> 4.2.x",
28
27
  "date-fns": "^2.0.0",
29
28
  "react": "^16.8.0 || ^17.0.0",
30
29
  "react-dom": "^16.8.0 || ^17.0.0",
31
30
  "react-native": "^0.63.0",
31
+ "react-native-gesture-handler": "^2.0.0",
32
+ "react-native-pager-view": "^4.0.0",
32
33
  "react-native-snap-carousel": "^3.9.0",
33
34
  "react-slick": "^0.25.0"
34
35
  },
@@ -36,9 +37,6 @@
36
37
  "@gorhom/bottom-sheet": {
37
38
  "optional": true
38
39
  },
39
- "@react-native-community/viewpager": {
40
- "optional": true
41
- },
42
40
  "react-dom": {
43
41
  "optional": true
44
42
  },
@@ -48,17 +46,19 @@
48
46
  "react-slick": {
49
47
  "optional": true
50
48
  },
49
+ "react-native-pager-view": {
50
+ "optional": true
51
+ },
51
52
  "react-native-snap-carousel": {
52
53
  "optional": true
53
54
  }
54
55
  },
55
56
  "devDependencies": {
56
- "@fountain-ui/core": "^1.19.1",
57
57
  "@gorhom/bottom-sheet": "4.1.3",
58
- "@react-native-community/viewpager": "^4.2.2",
59
58
  "@types/react-native-snap-carousel": "^3.8.4",
60
59
  "@types/react-slick": "^0.23.5",
61
60
  "date-fns": "^2.23.0",
61
+ "react-native-pager-view": "^4.2.4",
62
62
  "react-native-safe-area-context": "^3.3.2",
63
63
  "react-native-snap-carousel": "^3.9.1",
64
64
  "react-slick": "^0.28.1"
@@ -85,5 +85,5 @@
85
85
  "publishConfig": {
86
86
  "access": "public"
87
87
  },
88
- "gitHead": "1624478e1427948c29a61931e3af6658db41505f"
88
+ "gitHead": "80988af3fdfd671fcb655d4b36a017ce13baf29e"
89
89
  }
@@ -1,7 +1,13 @@
1
- import React from 'react';
2
- import Animated, { Easing } from 'react-native-reanimated';
1
+ import React, { useEffect } from 'react';
2
+ import type { WithTimingConfig } from 'react-native-reanimated';
3
+ import Animated, { Easing, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
3
4
  import type AnimatedYProps from './AnimatedYProps';
4
5
 
6
+ const ANIMATION_CONFIG: Readonly<WithTimingConfig> = {
7
+ duration: 150,
8
+ easing: Easing.out(Easing.exp),
9
+ };
10
+
5
11
  export default function AnimatedY(props: AnimatedYProps) {
6
12
  const {
7
13
  children,
@@ -9,17 +15,14 @@ export default function AnimatedY(props: AnimatedYProps) {
9
15
  style,
10
16
  } = props;
11
17
 
12
- const animatedY = Animated.useSharedValue(translateY);
13
- const animatedStyle = Animated.useAnimatedStyle(() => ({
18
+ const animatedY = useSharedValue(translateY);
19
+ const animatedStyle = useAnimatedStyle(() => ({
14
20
  transform: [{ translateY: animatedY.value }],
15
- }));
21
+ }), []);
16
22
 
17
- React.useEffect(() => {
23
+ useEffect(() => {
18
24
  if (translateY >= 0) {
19
- animatedY.value = Animated.withTiming(translateY, {
20
- duration: 150,
21
- easing: Easing.out(Easing.exp),
22
- });
25
+ animatedY.value = withTiming(translateY, ANIMATION_CONFIG);
23
26
  }
24
27
  }, [translateY]);
25
28
 
@@ -46,6 +46,7 @@ export default function BottomSheet(props: BottomSheetProps) {
46
46
  } else if (indexRef.current >= 0 && index < 0) {
47
47
  bottomSheetRef.current?.dismiss();
48
48
  } else {
49
+ // @ts-ignore
49
50
  bottomSheetRef.current?.snapToIndex(index);
50
51
  }
51
52
  }, [index]);
@@ -60,6 +61,9 @@ export default function BottomSheet(props: BottomSheetProps) {
60
61
  web: shadow?.boxShadow,
61
62
  }),
62
63
  };
64
+ const backgroundStyle = {
65
+ backgroundColor: theme.palette.paper.default,
66
+ };
63
67
 
64
68
  const isBackdropTransparent = backdropOpacity <= 0;
65
69
 
@@ -76,6 +80,8 @@ export default function BottomSheet(props: BottomSheetProps) {
76
80
  <BottomSheetModalProvider>
77
81
  <BottomSheetModal
78
82
  backdropComponent={isBackdropTransparent ? TransparentBackdrop : OpacityAwareBackdrop}
83
+ // @ts-ignore
84
+ backgroundStyle={backgroundStyle}
79
85
  index={index}
80
86
  handleComponent={NoHandle}
81
87
  onChange={handleChange}
@@ -0,0 +1,162 @@
1
+ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
+ import { FlatList, ListRenderItem, ViewToken } from 'react-native';
3
+ import * as R from 'ramda';
4
+ import { ComicViewerItemData, default as ComicViewerProps, ErrorInfo } from './ComicViewerProps';
5
+ import type ComicViewerItemProps from './ComicViewerItemProps';
6
+ import ViewerItem from './ViewerItem';
7
+
8
+ const getItemHeights = <T, >(items: ComicViewerItemProps<T>[]): number[] => R.map((content: ComicViewerItemProps<T>) => content.height)(items);
9
+ const appender = (left: number, right: number): [number, number] => [left + right, left + right];
10
+ const getHeightAccum = (itemHeights: number[]): [number, number[]] => R.mapAccum(appender, 0, itemHeights);
11
+
12
+ const keyExtractor = <T, >(item: ComicViewerItemProps<T>) => item.id;
13
+
14
+ export default function ComicViewer<T>(props: ComicViewerProps<T>) {
15
+ const {
16
+ data,
17
+ errorDebounceMillis = 500,
18
+ errorRetryCount = 3,
19
+ initialNumToRender = 1,
20
+ initialScrollPercentage = 0,
21
+ itemVisiblePercentThreshold = 0,
22
+ onError,
23
+ viewerWidth,
24
+ windowSize = 3,
25
+ ...otherProps
26
+ } = props;
27
+
28
+ const flatListRef = useRef<FlatList>(null);
29
+
30
+ const errors = useRef<Map<string, number>>(new Map());
31
+ const debounceTimeOut = useRef<NodeJS.Timeout | null>(null);
32
+
33
+ const resourceString = R.toString(R.map((itemData: ComicViewerItemData) => itemData.sourceUrl)(data));
34
+
35
+ const initialItems = R.map((itemData: ComicViewerItemData<T>) => ({
36
+ ...itemData,
37
+ isViewable: false,
38
+ width: viewerWidth,
39
+ height: (itemData.height * viewerWidth) / itemData.width,
40
+ }))(data);
41
+
42
+ const [items, setItems] = useState<ComicViewerItemProps<T>[]>(initialItems);
43
+
44
+ const itemHeights = getItemHeights(items);
45
+ const itemHeightAccum = getHeightAccum(itemHeights);
46
+
47
+ const viewabilityConfig = useMemo(() => ({
48
+ itemVisiblePercentThreshold,
49
+ }), [itemVisiblePercentThreshold]);
50
+
51
+ const getItemLayout = useCallback((data: any, index: number) => {
52
+ const offsets = R.prepend(0, itemHeightAccum[1]);
53
+
54
+ return {
55
+ length: itemHeights[index],
56
+ offset: offsets[index],
57
+ index,
58
+ };
59
+ }, [itemHeights]);
60
+
61
+ const onViewableItemsChanged = useRef(({ viewableItems }: {
62
+ viewableItems: Array<ViewToken>,
63
+ }) => {
64
+ setItems((prev: ComicViewerItemProps<T>[]) => {
65
+ const viewableItemIds = R.map((viewableItem: ViewToken) => viewableItem.item.id)(viewableItems);
66
+
67
+ return R.map((prevItem: ComicViewerItemProps<T>) => ({
68
+ ...prevItem,
69
+ isViewable: R.includes(prevItem.id, viewableItemIds),
70
+ }))([...prev]);
71
+ });
72
+ });
73
+
74
+ const onErrorHandler = (errors: ErrorInfo[]) => {
75
+ const isRetryLimited = R.any((error: ErrorInfo) => error.count >= errorRetryCount)(errors);
76
+
77
+ if (isRetryLimited) {
78
+ return;
79
+ }
80
+
81
+ onError && onError(errors);
82
+ };
83
+
84
+ const itemErrorHandler = useCallback((errorInfo: ErrorInfo) => {
85
+ errors.current.set(errorInfo.id, errorInfo.count);
86
+
87
+ if (debounceTimeOut.current) {
88
+ clearTimeout(debounceTimeOut.current);
89
+ }
90
+
91
+ debounceTimeOut.current = setTimeout(function () {
92
+ const errorsArray = Array.from(errors.current.entries());
93
+ const errorsInfo = R.map(([key, value]: [string, number]) => ({
94
+ id: key,
95
+ count: value,
96
+ }))(errorsArray);
97
+
98
+ onErrorHandler([...errorsInfo]);
99
+ errors.current.clear();
100
+ }, errorDebounceMillis);
101
+ }, [errorDebounceMillis, errors.current]);
102
+
103
+ const renderItem: ListRenderItem<ComicViewerItemProps<T>> = useCallback(({ item }) => {
104
+ const props = {
105
+ ...item,
106
+ onError: itemErrorHandler,
107
+ };
108
+
109
+ return <ViewerItem props={props}/>;
110
+ }, []);
111
+
112
+ useEffect(() => {
113
+ setItems((prev: ComicViewerItemProps<T>[]) => {
114
+ return R.map((prevItem: ComicViewerItemProps<T>) => {
115
+ const currentData = R.find((currentItemData: ComicViewerItemData<T>) => prevItem.id === currentItemData.id)(data);
116
+
117
+ if (currentData && (currentData.sourceUrl !== prevItem.sourceUrl)) {
118
+ return {
119
+ ...prevItem,
120
+ sourceUrl: currentData.sourceUrl,
121
+ };
122
+ }
123
+
124
+ return prevItem;
125
+ })([...prev]);
126
+ });
127
+ }, [resourceString]);
128
+
129
+ useEffect(() => {
130
+ const newItems = R.map((item: ComicViewerItemProps<T>) => ({
131
+ ...item,
132
+ width: viewerWidth,
133
+ height: (item.height * viewerWidth) / item.width,
134
+ }))(items);
135
+
136
+ setItems(newItems);
137
+ }, [viewerWidth]);
138
+
139
+ useEffect(() => {
140
+ const totalHeight = itemHeightAccum[0];
141
+ const offset = Math.floor((initialScrollPercentage / 100) * totalHeight);
142
+
143
+ if (flatListRef.current) {
144
+ flatListRef.current.scrollToOffset({ offset, animated: false });
145
+ }
146
+ }, [flatListRef.current]);
147
+
148
+ return (
149
+ <FlatList
150
+ data={items}
151
+ getItemLayout={getItemLayout}
152
+ initialNumToRender={initialNumToRender}
153
+ keyExtractor={keyExtractor}
154
+ onViewableItemsChanged={onViewableItemsChanged.current}
155
+ ref={flatListRef}
156
+ renderItem={renderItem}
157
+ viewabilityConfig={viewabilityConfig}
158
+ windowSize={windowSize}
159
+ {...otherProps}
160
+ />
161
+ );
162
+ };
@@ -0,0 +1,15 @@
1
+ import { ComicViewerItemData, ErrorInfo } from './ComicViewerProps';
2
+
3
+ type ComicViewerItemProps<T> = ComicViewerItemData<T> & {
4
+ /**
5
+ * FlatListItem is viewable in screen.
6
+ */
7
+ isViewable: boolean;
8
+
9
+ /**
10
+ * Error handler
11
+ */
12
+ onError?: (errorInfo: ErrorInfo) => void;
13
+ }
14
+
15
+ export default ComicViewerItemProps;
@@ -0,0 +1,90 @@
1
+ import { ComponentProps } from '@fountain-ui/core';
2
+
3
+ export interface ErrorInfo {
4
+ /**
5
+ * ComicViewerItemData.id.
6
+ */
7
+ id: string;
8
+
9
+ /**
10
+ * Number of times an error occurred.
11
+ */
12
+ count: number;
13
+ }
14
+
15
+ export type ComicViewerItemData<T = {}> = T & {
16
+ /**
17
+ * Image height.
18
+ */
19
+ height: number;
20
+
21
+ /**
22
+ * Unique value for identifying.
23
+ */
24
+ id: string;
25
+
26
+ /**
27
+ * Image sourceUrl for displaying.
28
+ */
29
+ sourceUrl: string;
30
+
31
+ /**
32
+ * Image width.
33
+ */
34
+ width: number;
35
+ }
36
+
37
+ export default interface ComicViewerProps<T> extends ComponentProps <{
38
+ /**
39
+ * Data for render.
40
+ */
41
+ data: ComicViewerItemData<T>[];
42
+
43
+ /**
44
+ * Delay Time to call the error handler.
45
+ * @default 500
46
+ */
47
+ errorDebounceMillis?: number;
48
+
49
+ /**
50
+ * How many times retry onError when same item error occur
51
+ * @default 3
52
+ */
53
+ errorRetryCount?: number;
54
+
55
+ /**
56
+ * How many items to render in the initial batch.
57
+ * @default 1
58
+ */
59
+ initialNumToRender?: number;
60
+
61
+ /**
62
+ * Start at initialScrollPercentage.
63
+ * If over 100, scroll to end.
64
+ * @default 0
65
+ */
66
+ initialScrollPercentage?: number;
67
+
68
+ /**
69
+ * The value for FlatList viewabilityConfig.itemVisiblePercentThreshold.
70
+ * @default 0
71
+ */
72
+ itemVisiblePercentThreshold?: number;
73
+
74
+ /**
75
+ * Handling all viewerItem errors at once.
76
+ * @param errors Array of ViewerItems errorInfo.
77
+ */
78
+ onError?: (errors: ErrorInfo[]) => void;
79
+
80
+ /**
81
+ * Comic viewer width.
82
+ */
83
+ viewerWidth: number;
84
+
85
+ /**
86
+ * The value for FlatList windowSize.
87
+ * @default 3
88
+ */
89
+ windowSize?: number;
90
+ }> {}
@@ -0,0 +1,76 @@
1
+ import React, { useCallback, useRef, useState } from 'react';
2
+ import { View } from 'react-native';
3
+ import { Image, StyleSheet } from '@fountain-ui/core';
4
+ import ComicViewerItemProps from './ComicViewerItemProps';
5
+
6
+ const styles = StyleSheet.create({
7
+ placeholder: {
8
+ backgroundColor: '#abcabc',
9
+ },
10
+ });
11
+
12
+ function ViewerItem<T>({ props }: { props: ComicViewerItemProps<T> }) {
13
+ const {
14
+ height,
15
+ id,
16
+ isViewable,
17
+ onError,
18
+ sourceUrl,
19
+ width,
20
+ } = props;
21
+
22
+ const [isLoaded, setIsLoaded] = useState(false);
23
+
24
+ const errorCount = useRef<number>(0);
25
+
26
+ const onLoad = useCallback(() => {
27
+ errorCount.current = 0;
28
+ setIsLoaded(true);
29
+ }, []);
30
+
31
+ const handleError = useCallback(() => {
32
+ errorCount.current = errorCount.current + 1;
33
+
34
+ onError && onError({
35
+ id,
36
+ count: errorCount.current
37
+ });
38
+ }, [id]);
39
+
40
+ const viewStyle = { width, height };
41
+
42
+ const Placeholder = () => (
43
+ <View style={[
44
+ viewStyle,
45
+ styles.placeholder,
46
+ ]}/>
47
+ );
48
+
49
+ if (!isViewable && !isLoaded) {
50
+ return <Placeholder/>;
51
+ }
52
+
53
+ return (
54
+ <Image
55
+ disableOutline={true}
56
+ key={sourceUrl}
57
+ onLoad={onLoad}
58
+ onError={handleError}
59
+ source={{ uri: sourceUrl }}
60
+ style={viewStyle}
61
+ square={true}
62
+ />
63
+ );
64
+ }
65
+
66
+ export default React.memo(ViewerItem, (prevProps, nextProps) => {
67
+ if (prevProps.props.isViewable !== nextProps.props.isViewable) {
68
+ return false;
69
+ }
70
+
71
+ if (prevProps.props.sourceUrl !== nextProps.props.sourceUrl) {
72
+ return false;
73
+ }
74
+
75
+ return true;
76
+ });
@@ -0,0 +1,3 @@
1
+ export { default } from './ComicViewer';
2
+ export type { ComicViewerItemData, default as ComicViewerProps, ErrorInfo } from './ComicViewerProps';
3
+ export type { default as ComicViewerItemProps } from './ComicViewerItemProps';
@@ -81,6 +81,12 @@ export default function DateTimePicker(props: DateTimePickerProps) {
81
81
  onPress={() => setYearPickerVisible(true)}
82
82
  />
83
83
  )}
84
+ theme={{
85
+ backgroundColor: theme.palette.paper.default,
86
+ calendarBackground: theme.palette.paper.default,
87
+ dayTextColor: theme.palette.text.primary,
88
+ textDisabledColor: theme.palette.text.hint,
89
+ }}
84
90
  />
85
91
  );
86
92
  };
@@ -61,6 +61,7 @@ const YearPicker = ({
61
61
  <Column>
62
62
  <Typography
63
63
  children={formatDate(date, locale)}
64
+ color={'textPrimary'}
64
65
  variant={'subtitle2'}
65
66
  />
66
67
  <FlatList
@@ -84,4 +85,4 @@ const YearPicker = ({
84
85
  );
85
86
  };
86
87
 
87
- export default YearPicker;
88
+ export default YearPicker;
@@ -1,6 +1,6 @@
1
1
  import React, { useEffect } from 'react';
2
2
  import { StyleSheet, View } from 'react-native';
3
- import Animated from 'react-native-reanimated';
3
+ import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
4
4
  import type FlipCardProps from './FlipCardProps';
5
5
 
6
6
  const styles = StyleSheet.create({
@@ -27,9 +27,9 @@ export default function FlipCard(props: FlipCardProps) {
27
27
  style,
28
28
  } = props;
29
29
 
30
- const sharedAngle = Animated.useSharedValue(0);
30
+ const sharedAngle = useSharedValue(0);
31
31
 
32
- const animatedFrontCardStyle = Animated.useAnimatedStyle(() => {
32
+ const animatedFrontCardStyle = useAnimatedStyle(() => {
33
33
  return {
34
34
  zIndex: sharedAngle.value < Z_INDEX_CHANGE_ANGLE ? 2 : 1,
35
35
  transform: [
@@ -37,9 +37,9 @@ export default function FlipCard(props: FlipCardProps) {
37
37
  { rotateX: `${sharedAngle.value}deg` },
38
38
  ],
39
39
  };
40
- });
40
+ }, []);
41
41
 
42
- const animatedBackCardStyle = Animated.useAnimatedStyle(() => {
42
+ const animatedBackCardStyle = useAnimatedStyle(() => {
43
43
  return {
44
44
  zIndex: sharedAngle.value <= Z_INDEX_CHANGE_ANGLE ? 1 : 2,
45
45
  transform: [
@@ -47,11 +47,11 @@ export default function FlipCard(props: FlipCardProps) {
47
47
  { rotateX: `${(sharedAngle.value + 180)}deg` },
48
48
  ],
49
49
  };
50
- });
50
+ }, []);
51
51
 
52
52
  useEffect(() => {
53
53
  sharedAngle.value = 0;
54
- sharedAngle.value = Animated.withTiming(180, { duration: 500 });
54
+ sharedAngle.value = withTiming(180, { duration: 500 });
55
55
  }, [reanimationKey]);
56
56
 
57
57
  return (
@@ -65,4 +65,4 @@ export default function FlipCard(props: FlipCardProps) {
65
65
  </Animated.View>
66
66
  </View>
67
67
  );
68
- };
68
+ };
@@ -1,36 +1,105 @@
1
- import React from 'react';
2
- import { View } from 'react-native';
1
+ import React, { memo, useState } from 'react';
2
+ import { Platform, View } from 'react-native';
3
+ import { runOnJS, useAnimatedReaction } from 'react-native-reanimated';
4
+ import { StyleSheet } from '@fountain-ui/core';
3
5
  import type { PageProps } from './ViewPagerProps';
4
6
 
5
- const Page = function Page(props: PageProps) {
6
- const { isVisible, ...otherProps } = props;
7
+ const OFFSCREEN_RERENDER_LIMIT = 1;
8
+
9
+ const styles = StyleSheet.create({
10
+ none: { display: 'none' },
11
+ });
12
+
13
+ interface PageState {
14
+ active: boolean;
15
+ visited: boolean;
16
+ }
17
+
18
+ function Page(props: PageProps) {
19
+ const {
20
+ index,
21
+ children,
22
+ loading,
23
+ sharedIndex,
24
+ } = props;
25
+
26
+ const assumeInitialPageState = (): PageState => {
27
+ const activeIndex = sharedIndex.value;
28
+
29
+ const active = index === activeIndex;
30
+
31
+ if (Platform.OS === 'web') {
32
+ return { active, visited: active };
33
+ }
34
+
35
+ if (loading === 'eager') {
36
+ return { active, visited: true };
37
+ }
38
+
39
+ const visited = index >= activeIndex - OFFSCREEN_RERENDER_LIMIT
40
+ && index <= activeIndex + OFFSCREEN_RERENDER_LIMIT;
41
+
42
+ return { active, visited };
43
+ };
44
+
45
+ const [pageState, setPageState] = useState<PageState>(assumeInitialPageState);
46
+
47
+ const content = pageState.visited ? children : null;
48
+
49
+ const updatePageState = (active: boolean, neighbor: boolean) => {
50
+ setPageState(prevState => {
51
+ if (prevState.active !== active) {
52
+ return { active, visited: active || prevState.visited };
53
+ }
54
+
55
+ if (neighbor && !prevState.visited) {
56
+ return { ...prevState, visited: true };
57
+ }
58
+
59
+ return prevState;
60
+ });
61
+ };
62
+
63
+ useAnimatedReaction(
64
+ () => {
65
+ const activeIndex = sharedIndex.value;
66
+
67
+ const willVisible = index >= activeIndex - OFFSCREEN_RERENDER_LIMIT
68
+ && index <= activeIndex + OFFSCREEN_RERENDER_LIMIT;
69
+
70
+ const willActive = index === activeIndex;
71
+ const willNeighbor = Platform.OS === 'web' ? false : (willVisible && !willActive);
72
+
73
+ return { willActive, willNeighbor };
74
+ },
75
+ (nextState, prevState) => {
76
+ const activeStateChanged = nextState.willActive !== prevState?.willActive;
77
+ const willNewNeighbor = nextState.willNeighbor && !prevState?.willNeighbor;
78
+
79
+ if (activeStateChanged || willNewNeighbor) {
80
+ runOnJS(updatePageState)(nextState.willActive, nextState.willNeighbor);
81
+ }
82
+ },
83
+ [index],
84
+ );
85
+
86
+ const style = Platform.OS === 'web'
87
+ ? (pageState.active ? StyleSheet.absoluteFill : styles.none)
88
+ : undefined;
7
89
 
8
90
  return (
9
91
  <View
92
+ children={content}
10
93
  collapsable={false}
11
- {...otherProps}
94
+ style={style}
12
95
  />
13
96
  );
14
- };
15
-
16
- export default React.memo(Page, (prevProps, nextProps) => {
17
- if (prevProps.children === null && nextProps.children === null) {
18
- return true;
19
- }
20
-
21
- // isVisible is an important condition for determining memos on the web.
22
- // Reference ViewPagerWeb's return.
23
- if (prevProps.isVisible !== nextProps.isVisible) {
24
- return false;
25
- }
26
-
27
- if (nextProps.isVisible || nextProps.isNeighbor) {
28
- return false;
29
- }
97
+ }
30
98
 
99
+ export default memo(Page, (prevProps, nextProps) => {
31
100
  if (prevProps.rerenderKey !== nextProps.rerenderKey) {
32
101
  return false;
33
102
  }
34
103
 
35
- return prevProps.children !== null && nextProps.children !== null;
104
+ return prevProps.index !== nextProps.index;
36
105
  });