@applicaster/zapp-react-native-ui-components 13.0.0-alpha.9946926334 → 13.0.0-rc.100

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 (172) hide show
  1. package/Components/AppContainer/__tests__/AppContainer.test.js +4 -6
  2. package/Components/AudioPlayer/AudioPlayer.tsx +7 -0
  3. package/Components/AudioPlayer/__tests__/Runtime.test.js +5 -8
  4. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +54 -111
  5. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +36 -20
  6. package/Components/AudioPlayer/__tests__/artWork.test.js +3 -5
  7. package/Components/AudioPlayer/__tests__/audioPlayer.test.js +3 -5
  8. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +7 -8
  9. package/Components/AudioPlayer/__tests__/channel.test.js +3 -5
  10. package/Components/AudioPlayer/__tests__/summary.test.js +3 -5
  11. package/Components/AudioPlayer/__tests__/title.test.js +3 -5
  12. package/Components/AudioPlayer/helpers.tsx +1 -0
  13. package/Components/BaseFocusable/index.ios.ts +1 -1
  14. package/Components/BaseFocusable/index.tsx +2 -3
  15. package/Components/Cell/Cell.tsx +11 -16
  16. package/Components/Cell/CellWithFocusable.tsx +50 -59
  17. package/Components/Cell/CellWrapper.tsx +18 -0
  18. package/Components/Cell/TvOSCellComponent.tsx +20 -26
  19. package/Components/Cell/__tests__/CellWIthFocusable.test.js +13 -6
  20. package/Components/Cell/index.js +3 -1
  21. package/Components/Cell/styles.ts +17 -0
  22. package/Components/CellRendererResolver/__tests__/cellRendererResolver.test.js +46 -48
  23. package/Components/CellRendererResolver/index.ts +2 -1
  24. package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +1 -42
  25. package/Components/ComponentResolver/__tests__/componentResolver.test.js +16 -22
  26. package/Components/ContentScreen/__tests__/contentScreen.test.js +3 -3
  27. package/Components/ErrorScreen/index.tsx +14 -6
  28. package/Components/Focusable/Focusable.tsx +1 -0
  29. package/Components/Focusable/FocusableTvOS.tsx +6 -2
  30. package/Components/Focusable/Touchable.tsx +19 -20
  31. package/Components/Focusable/index.android.tsx +10 -3
  32. package/Components/FocusableCell/index.tsx +1 -1
  33. package/Components/FocusableGroup/FocusableTvOS.tsx +34 -86
  34. package/Components/FocusableGroup/index.tsx +0 -3
  35. package/Components/FocusableList/index.tsx +26 -10
  36. package/Components/FocusableScrollView/index.tsx +43 -13
  37. package/Components/HandlePlayable/HandlePlayable.tsx +21 -27
  38. package/Components/Layout/TV/LayoutBackground.tsx +28 -0
  39. package/Components/Layout/TV/NavBarContainer.tsx +19 -23
  40. package/Components/Layout/TV/ScreenContainer.tsx +8 -2
  41. package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
  42. package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +2 -1
  43. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +3 -2
  44. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +3 -2
  45. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +15 -10
  46. package/Components/Layout/TV/__tests__/index.test.tsx +8 -2
  47. package/Components/Layout/TV/index.tsx +6 -20
  48. package/Components/Layout/TV/index.web.tsx +4 -1
  49. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
  50. package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +66 -0
  51. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -1
  52. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +10 -15
  53. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
  54. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +93 -0
  55. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -2
  56. package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
  57. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  58. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
  59. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
  60. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
  61. package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +4 -12
  62. package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +0 -229
  63. package/Components/MasterCell/__tests__/elementMapper.test.js +18 -5
  64. package/Components/MasterCell/__tests__/masterCell.test.js +26 -26
  65. package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
  66. package/Components/MasterCell/hooks/useAsyncRendering/index.ts +2 -2
  67. package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
  68. package/Components/MasterCell/utils/index.ts +9 -135
  69. package/Components/ModalComponent/BottomSheetModalContent.tsx +45 -19
  70. package/Components/ModalComponent/Button/Item.tsx +6 -5
  71. package/Components/ModalComponent/Button/assets.ts +1 -1
  72. package/Components/ModalComponent/Button/index.tsx +30 -43
  73. package/Components/ModalComponent/Header/index.tsx +3 -3
  74. package/Components/ModalComponent/utils.ts +55 -7
  75. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +2 -2
  76. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +2 -2
  77. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -5
  78. package/Components/OfflineHandler/utils/index.ts +1 -1
  79. package/Components/PlayerContainer/PlayerContainer.tsx +43 -21
  80. package/Components/PlayerContainer/PlayerContainerContext.tsx +9 -0
  81. package/Components/PlayerContainer/ProgramInfo/index.tsx +2 -2
  82. package/Components/PlayerImageBackground/index.tsx +1 -1
  83. package/Components/River/ComponentsMap/ComponentsMap.tsx +42 -65
  84. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
  85. package/Components/River/RiverFooter.tsx +39 -9
  86. package/Components/River/RiverItem.tsx +39 -3
  87. package/Components/River/TV/index.tsx +6 -1
  88. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +100 -31
  89. package/Components/River/__tests__/__snapshots__/river.test.js.snap +20 -82
  90. package/Components/River/__tests__/componentsMap.test.js +17 -5
  91. package/Components/River/__tests__/river.test.js +75 -40
  92. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +11 -4
  93. package/Components/RouteManager/__tests__/routeManager.test.js +29 -14
  94. package/Components/RouteManager/__tests__/testId.test.js +8 -6
  95. package/Components/Screen/TV/index.web.tsx +5 -6
  96. package/Components/Screen/hooks.ts +53 -0
  97. package/Components/Screen/index.tsx +16 -42
  98. package/Components/ScreenResolver/__tests__/screenResolver.test.js +91 -70
  99. package/Components/Tabs/Tab.tsx +11 -9
  100. package/Components/TextInputTv/index.tsx +4 -3
  101. package/Components/TopMarginApplicator/TopMarginApplicator.tsx +2 -3
  102. package/Components/TrackedView/index.tsx +1 -0
  103. package/Components/Transitioner/AnimationManager.js +15 -15
  104. package/Components/Transitioner/Scene.tsx +53 -24
  105. package/Components/Transitioner/Transitioner.tsx +3 -3
  106. package/Components/Transitioner/__tests__/Scene.test.js +25 -14
  107. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +9 -49
  108. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
  109. package/Components/Transitioner/__tests__/transitioner.test.js +13 -4
  110. package/Components/Transitioner/index.js +8 -4
  111. package/Components/VideoLive/LiveImageManager.ts +27 -1
  112. package/Components/VideoLive/PlayerLiveImageComponent.tsx +36 -24
  113. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +51 -1
  114. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +1 -5
  115. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
  116. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +51 -31
  117. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +8 -4
  118. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +48 -22
  119. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +12 -6
  120. package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
  121. package/Components/VideoModal/ModalAnimation/const.ts +5 -0
  122. package/Components/VideoModal/ModalAnimation/index.ts +2 -0
  123. package/Components/VideoModal/ModalAnimation/utils.ts +38 -2
  124. package/Components/VideoModal/OpaqueLayer.tsx +33 -0
  125. package/Components/VideoModal/PlayerDetails.tsx +18 -10
  126. package/Components/VideoModal/PlayerWrapper.tsx +43 -39
  127. package/Components/VideoModal/VideoModal.tsx +17 -11
  128. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -1
  129. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -40
  130. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +0 -90
  131. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +89 -0
  132. package/Components/VideoModal/hooks/index.ts +7 -0
  133. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +49 -0
  134. package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +91 -0
  135. package/Components/VideoModal/hooks/utils/index.ts +33 -0
  136. package/Components/VideoModal/utils.ts +4 -5
  137. package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +24 -36
  138. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -18
  139. package/Components/Viewport/__tests__/utils.test.js +5 -4
  140. package/Components/ZappUIComponent/Placeholder.tsx +3 -1
  141. package/Components/ZappUIComponent/__tests__/{ZappUIComponent.test.js → ZappUIComponent.test.tsx} +26 -10
  142. package/Components/ZappUIComponent/index.tsx +4 -17
  143. package/Components/default-cell-renderer/__tests__/defaultCellRenderer.test.tsx +20 -17
  144. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/__tests__/DefaultCell.test.tsx +15 -11
  145. package/Contexts/ComponentsMapOffsetContext/index.tsx +49 -0
  146. package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
  147. package/Contexts/HeaderOffsetContext/index.tsx +4 -6
  148. package/Contexts/ScreenContext/index.tsx +6 -12
  149. package/Contexts/ScreenLayoutContext/index.tsx +5 -3
  150. package/Decorators/Navigator/__tests__/navigator.test.js +16 -16
  151. package/Decorators/Navigator/index.tsx +1 -1
  152. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +18 -24
  153. package/Decorators/RiverResolver/index.tsx +6 -8
  154. package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
  155. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +29 -22
  156. package/Decorators/ZappPipesDataConnector/index.tsx +6 -2
  157. package/package.json +7 -11
  158. package/tsconfig.json +2 -3
  159. package/.babelrc +0 -8
  160. package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
  161. package/Components/Cell/CellStyles/Hero/index.js +0 -111
  162. package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
  163. package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
  164. package/Components/Cell/CellStyles/colors.js +0 -40
  165. package/Components/Cell/CellStyles/index.js +0 -15
  166. package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +0 -53
  167. package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +0 -17
  168. package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +0 -17
  169. package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +0 -91
  170. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +0 -338
  171. package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +0 -18
  172. package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +0 -28
@@ -1,48 +1,12 @@
1
1
  import * as React from "react";
2
2
 
3
- import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
4
- import * as FOCUS_EVENTS from "@applicaster/zapp-react-native-utils/appUtils/focusManager/events";
5
3
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
6
4
  import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
7
5
 
8
- import { isAppleTV } from "../../Helpers/Platform";
9
6
  import { useCellState } from "../MasterCell/utils";
10
-
11
- const useCellFocusedState = (
12
- skipFocusManagerRegistration: boolean,
13
- groupId: string,
14
- id: string
15
- ) => {
16
- const [currentCellFocused, setCurrentCellFocused] = React.useState(false);
17
-
18
- React.useEffect(() => {
19
- const isGroupItemFocused = () => {
20
- if (!skipFocusManagerRegistration) {
21
- const isFocused = focusManager.isGroupItemFocused(groupId, id);
22
- setCurrentCellFocused(isFocused);
23
- }
24
- };
25
-
26
- const handler = () => {
27
- // tvOS hack for properly checking focus
28
- if (isAppleTV()) {
29
- setTimeout(() => {
30
- isGroupItemFocused();
31
- }, 0);
32
- } else {
33
- isGroupItemFocused();
34
- }
35
- };
36
-
37
- focusManager.on(FOCUS_EVENTS.FOCUS, handler);
38
-
39
- return () => {
40
- focusManager.removeHandler(FOCUS_EVENTS.FOCUS, handler);
41
- };
42
- }, [groupId, skipFocusManagerRegistration]);
43
-
44
- return currentCellFocused;
45
- };
7
+ import { FocusableGroup } from "../FocusableGroup";
8
+ import { CellWrapper } from "./CellWrapper";
9
+ import { styles } from "./styles";
46
10
 
47
11
  type Props = {
48
12
  item: ZappEntry;
@@ -59,6 +23,8 @@ type Props = {
59
23
  focused?: boolean;
60
24
  };
61
25
 
26
+ const addPrefix = (id: string) => `focusable-cell-wrapper-${id}`;
27
+
62
28
  export function CellWithFocusable(props: Props) {
63
29
  const {
64
30
  index,
@@ -75,14 +41,10 @@ export function CellWithFocusable(props: Props) {
75
41
  focused,
76
42
  } = props;
77
43
 
78
- const isFocused = useCellFocusedState(
79
- skipFocusManagerRegistration,
80
- groupId,
81
- id
82
- );
44
+ const [isFocused, setIsFocused] = React.useState(false);
83
45
 
84
46
  const state = useCellState({
85
- id: item.id,
47
+ item,
86
48
  behavior,
87
49
  focused: isFocused || toBooleanWithDefaultFalse(focused),
88
50
  });
@@ -96,26 +58,55 @@ export function CellWithFocusable(props: Props) {
96
58
  }
97
59
  }, [focusedButtonId]);
98
60
 
99
- const handleToggleFocus = (value) => {
100
- setFocusedButtonId(value.focusedButtonId);
61
+ const handleToggleFocus = React.useCallback(
62
+ (value) => {
63
+ setFocusedButtonId(value.focusedButtonId);
64
+
65
+ if (value.focusable) {
66
+ onFocus(value.focusable, value.mouse);
67
+ }
68
+ },
69
+ [onFocus]
70
+ );
71
+
72
+ const onGroupFocus = React.useCallback(() => {
73
+ if (!skipFocusManagerRegistration) {
74
+ setIsFocused(true);
75
+ }
76
+ }, [skipFocusManagerRegistration]);
101
77
 
102
- if (value.focusable) {
103
- onFocus(value.focusable, value.mouse);
78
+ const onGroupBlur = React.useCallback(() => {
79
+ if (!skipFocusManagerRegistration) {
80
+ setIsFocused(false);
104
81
  }
105
- };
82
+ }, [skipFocusManagerRegistration]);
106
83
 
107
84
  return (
108
- <CellRenderer
109
- item={item}
85
+ <FocusableGroup
86
+ id={addPrefix(id)}
87
+ testID={"cell-with-focusable-cell-renderer-focusable-group"}
110
88
  groupId={groupId}
111
- onToggleFocus={handleToggleFocus}
112
- state={state}
113
- prefixId={id}
114
- focusedButtonId={focusedButtonId}
115
89
  preferredFocus={preferredFocus}
90
+ shouldUsePreferredFocus
91
+ onFocus={onGroupFocus}
92
+ onBlur={onGroupBlur}
116
93
  skipFocusManagerRegistration={skipFocusManagerRegistration}
117
- isFocusable={isFocusable}
118
- focused={focused}
119
- />
94
+ >
95
+ <CellWrapper style={styles.cellWrapper}>
96
+ <CellRenderer
97
+ testID={"cell-with-focusable-cell-renderer"}
98
+ item={item}
99
+ groupId={addPrefix(id)}
100
+ onToggleFocus={handleToggleFocus}
101
+ state={state}
102
+ prefixId={id}
103
+ focusedButtonId={focusedButtonId}
104
+ preferredFocus={true}
105
+ skipFocusManagerRegistration={skipFocusManagerRegistration}
106
+ isFocusable={isFocusable}
107
+ focused={focused}
108
+ />
109
+ </CellWrapper>
110
+ </FocusableGroup>
120
111
  );
121
112
  }
@@ -0,0 +1,18 @@
1
+ import * as React from "react";
2
+ import { View, ViewStyle } from "react-native";
3
+ import { isTvOSPlatform } from "@applicaster/zapp-react-native-utils/reactUtils";
4
+
5
+ const isTvOS = isTvOSPlatform();
6
+
7
+ type Props = {
8
+ style: ViewStyle;
9
+ children: React.ReactNode;
10
+ };
11
+
12
+ export const CellWrapper = ({ style, children }: Props) => {
13
+ if (isTvOS) {
14
+ return <View style={style}>{children}</View>;
15
+ }
16
+
17
+ return <>{children}</>;
18
+ };
@@ -2,7 +2,7 @@ import * as React from "react";
2
2
  import * as R from "ramda";
3
3
  import { View, StyleSheet } from "react-native";
4
4
 
5
- import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable";
5
+ import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable/FocusableTvOS";
6
6
  import { FocusableCell } from "@applicaster/zapp-react-native-ui-components/Components/FocusableCell";
7
7
  import { getItemType } from "@applicaster/zapp-react-native-utils/navigationUtils";
8
8
  import { SCREEN_TYPES } from "@applicaster/zapp-react-native-utils/navigationUtils/itemTypes";
@@ -10,10 +10,6 @@ import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focu
10
10
  import { sendSelectCellEvent } from "@applicaster/zapp-react-native-utils/analyticsUtils";
11
11
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
12
12
  import { CellWithFocusable } from "./CellWithFocusable";
13
- import { getCellState } from "./utils";
14
-
15
- const _getCellState = (focused, selected) =>
16
- getCellState({ focused, selected });
17
13
 
18
14
  type Props = {
19
15
  item: ZappEntry;
@@ -69,6 +65,7 @@ type Props = {
69
65
  isFocusable: boolean;
70
66
  shouldUpdate: boolean;
71
67
  behavior: Behavior;
68
+ componentsMapOffset: number;
72
69
  };
73
70
 
74
71
  type State = {
@@ -183,6 +180,7 @@ export class TvOSCellComponent extends React.Component<Props, State> {
183
180
  groupId,
184
181
  component,
185
182
  index,
183
+ componentsMapOffset,
186
184
  } = this.props;
187
185
 
188
186
  this.setScreenLayout(componentAnchorPointY, screenLayout);
@@ -197,13 +195,11 @@ export class TvOSCellComponent extends React.Component<Props, State> {
197
195
  const extraAnchorPointYOffset =
198
196
  screenLayout?.extraAnchorPointYOffset || 0;
199
197
 
200
- const marginTop = screenLayout?.screenMarginTop || 0;
201
-
202
198
  const totalOffset =
203
199
  headerOffset +
204
- (componentAnchorPointY || 0) +
205
- extraAnchorPointYOffset -
206
- marginTop;
200
+ (componentAnchorPointY || 0) +
201
+ extraAnchorPointYOffset -
202
+ componentsMapOffset || 0;
207
203
 
208
204
  mainOffsetUpdater?.(
209
205
  { tag: this.target },
@@ -251,7 +247,7 @@ export class TvOSCellComponent extends React.Component<Props, State> {
251
247
 
252
248
  const focusableId = R.join("-", [component?.id, id, index]);
253
249
 
254
- const handleFocus = (arg1: any, index: number) => {
250
+ const handleFocus = (arg1: any, index?: number) => {
255
251
  const focusFn = onFocus || noop;
256
252
  focusFn(arg1, index);
257
253
 
@@ -284,7 +280,7 @@ export class TvOSCellComponent extends React.Component<Props, State> {
284
280
  <View onLayout={this.onLayout} style={styles.container}>
285
281
  <Focusable
286
282
  id={focusableId}
287
- groupId={groupId || component?.id}
283
+ groupId={String(groupId || component?.id)}
288
284
  onFocus={handleFocus}
289
285
  onBlur={onBlur || this.onBlur}
290
286
  isParallaxDisabled={this.layout?.width > 1740}
@@ -296,20 +292,18 @@ export class TvOSCellComponent extends React.Component<Props, State> {
296
292
  style={baseCellStyles}
297
293
  isFocusable={isFocusable}
298
294
  >
299
- {(focused) => {
300
- return (
301
- <FocusableCell
302
- {...{
303
- index,
304
- CellRenderer,
305
- item,
306
- focused: this.props.focused || selectedCell || focused,
307
- scrollTo: this.scrollTo,
308
- behavior,
309
- }}
310
- />
311
- );
312
- }}
295
+ {(focused) => (
296
+ <FocusableCell
297
+ {...{
298
+ index,
299
+ CellRenderer,
300
+ item,
301
+ focused: !!(this.props.focused || selectedCell || focused),
302
+ scrollTo: this.scrollTo,
303
+ behavior,
304
+ }}
305
+ />
306
+ )}
313
307
  </Focusable>
314
308
  </View>
315
309
  );
@@ -1,7 +1,7 @@
1
1
  import { View } from "react-native";
2
2
  import React from "react";
3
3
  import { act, render } from "@testing-library/react-native";
4
- import { CellWithFocusable } from "../CellWithFocusable";
4
+ import { CellWithFocusable } from "../CellWithFocusable.tsx";
5
5
 
6
6
  import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
7
7
 
@@ -23,7 +23,9 @@ describe("CellWithFocusable", () => {
23
23
 
24
24
  const wrapper = renderWith(props);
25
25
 
26
- expect(wrapper.UNSAFE_getByType("View").props.state).toBe("default");
26
+ const element = wrapper.getByTestId("cell-with-focusable-cell-renderer");
27
+
28
+ expect(element.props.state).toBe("default");
27
29
  });
28
30
 
29
31
  it("should render in default state", () => {
@@ -40,8 +42,9 @@ describe("CellWithFocusable", () => {
40
42
  focusManager.isGroupItemFocused = jest.fn(() => true);
41
43
 
42
44
  const wrapper = renderWith(props);
45
+ const element = wrapper.getByTestId("cell-with-focusable-cell-renderer");
43
46
 
44
- expect(wrapper.UNSAFE_getByType("View").props.state).toBe("default");
47
+ expect(element.props.state).toBe("default");
45
48
  });
46
49
 
47
50
  it("should render in focused state", () => {
@@ -55,13 +58,17 @@ describe("CellWithFocusable", () => {
55
58
  scrollTo: jest.fn(),
56
59
  };
57
60
 
58
- focusManager.isGroupItemFocused = jest.fn(() => true);
59
61
  const wrapper = renderWith(props);
60
62
 
63
+ const focusableGroupComponent = wrapper.getByTestId(
64
+ "cell-with-focusable-cell-renderer-focusable-group"
65
+ );
66
+
61
67
  act(() => {
62
- focusManager.on.mock.calls[focusManager.on.mock.calls.length - 1][1]();
68
+ focusableGroupComponent.props.onFocus();
63
69
  });
64
70
 
65
- expect(wrapper.UNSAFE_getByType("View").props.state).toBe("focused");
71
+ const element = wrapper.getByTestId("cell-with-focusable-cell-renderer");
72
+ expect(element.props.state).toBe("focused");
66
73
  });
67
74
  });
@@ -11,6 +11,7 @@ import { ScreenScrollingContext } from "../../Contexts/ScreenScrollingContext";
11
11
 
12
12
  import { ScreenLayoutContextConsumer } from "../../Contexts/ScreenLayoutContext";
13
13
  import { createContext } from "@applicaster/zapp-react-native-utils/reactUtils/createContext";
14
+ import { withComponentsMapOffsetContextConsumer } from "../../Contexts/ComponentsMapOffsetContext";
14
15
 
15
16
  // TODO | Gallery QB | Extract this
16
17
  export const ScrollInterceptorContext = createContext(
@@ -30,5 +31,6 @@ export const Cell = R.compose(
30
31
  RiverOffsetContext.withConsumer,
31
32
  HorizontalScrollContext.withConsumer,
32
33
  withConsumer,
33
- ScreenLayoutContextConsumer
34
+ ScreenLayoutContextConsumer,
35
+ withComponentsMapOffsetContextConsumer
34
36
  )(Component);
@@ -0,0 +1,17 @@
1
+ import { StyleSheet } from "react-native";
2
+
3
+ export const styles = StyleSheet.create({
4
+ cellWrapper: {
5
+ flex: 0,
6
+ height: "100%",
7
+ },
8
+ baseCell: {
9
+ height: "100%",
10
+ display: "flex",
11
+ flex: 1,
12
+ },
13
+ touchableCell: {
14
+ flex: 1,
15
+ height: "100%",
16
+ },
17
+ });
@@ -1,6 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
- import { shallow } from "enzyme";
3
+ import { render } from "@testing-library/react-native";
4
+ import { CellRendererResolver } from "../";
4
5
 
5
6
  jest.mock("../../default-cell-renderer", () => {
6
7
  const View = jest.requireActual("react-native").View;
@@ -8,8 +9,6 @@ jest.mock("../../default-cell-renderer", () => {
8
9
  return jest.fn((prop) => <View whoAmI="default renderer" someProp={prop} />);
9
10
  });
10
11
 
11
- const { CellRendererResolver } = require("../index");
12
-
13
12
  const component = {
14
13
  styles: {
15
14
  cell_plugin_configuration_id: "ABCDE-123456",
@@ -45,17 +44,9 @@ describe("CellRendererResolver", () => {
45
44
  cellStyles,
46
45
  });
47
46
 
48
- it("renders correctly", () => {
49
- const result = shallow(
50
- getResult({ component, plugins, styles, cellStyles })
51
- );
52
-
53
- expect(result).toMatchSnapshot();
54
- });
55
-
56
47
  describe("with a default renderer plugin", () => {
57
48
  it("renders correctly", () => {
58
- const result = shallow(
49
+ const { UNSAFE_root } = render(
59
50
  getResult({
60
51
  component,
61
52
  plugins,
@@ -64,56 +55,63 @@ describe("CellRendererResolver", () => {
64
55
  })
65
56
  );
66
57
 
67
- expect(result).toMatchSnapshot();
58
+ expect(UNSAFE_root).toBeDefined();
68
59
  });
69
60
 
70
61
  it("returns default plugin if component has no cell_plugin_configuration_id", () => {
71
- const result = getResult({
72
- component: {},
73
- plugins,
74
- styles,
75
- cellStyles,
76
- });
77
-
78
- expect(result).toBeDefined();
79
- expect(result.props.whoAmI).toEqual("default renderer");
62
+ const { UNSAFE_getByProps } = render(
63
+ getResult({
64
+ component: {},
65
+ plugins,
66
+ styles,
67
+ cellStyles,
68
+ })
69
+ );
70
+
71
+ expect(UNSAFE_getByProps({ whoAmI: "default renderer" })).toBeTruthy();
80
72
  });
81
73
 
82
74
  it("returns default plugin if requested cell plugin configuration does not exist", () => {
83
- const result = getResult({
84
- component: { styles: { cell_plugin_configuration_id: "wrong-id" } },
85
- plugins,
86
- styles,
87
- cellStyles,
88
- });
89
-
90
- expect(result.props.whoAmI).toEqual("default renderer");
75
+ const { UNSAFE_getByProps } = render(
76
+ getResult({
77
+ component: { styles: { cell_plugin_configuration_id: "wrong-id" } },
78
+ plugins,
79
+ styles,
80
+ cellStyles,
81
+ })
82
+ );
83
+
84
+ expect(UNSAFE_getByProps({ whoAmI: "default renderer" })).toBeTruthy();
91
85
  });
92
86
 
93
87
  it("returns default plugin if cellStyles store is empty", () => {
94
- const result = getResult({
95
- component,
96
- plugins,
97
- styles,
98
- cellStyles: {},
99
- });
100
-
101
- expect(result.props.whoAmI).toEqual("default renderer");
88
+ const { UNSAFE_getByProps } = render(
89
+ getResult({
90
+ component,
91
+ plugins,
92
+ styles,
93
+ cellStyles: {},
94
+ })
95
+ );
96
+
97
+ expect(UNSAFE_getByProps({ whoAmI: "default renderer" })).toBeTruthy();
102
98
  });
103
99
 
104
100
  it("returns null if requested renderer plugin does not exist", () => {
105
- const result = getResult({
106
- component: {
107
- styles: {
108
- cell_plugin_configuration_id: "FGHIJ-123456",
101
+ const { UNSAFE_getByProps } = render(
102
+ getResult({
103
+ component: {
104
+ styles: {
105
+ cell_plugin_configuration_id: "FGHIJ-123456",
106
+ },
109
107
  },
110
- },
111
- plugins,
112
- styles,
113
- cellStyles,
114
- });
108
+ plugins,
109
+ styles,
110
+ cellStyles,
111
+ })
112
+ );
115
113
 
116
- expect(result.props.whoAmI).toEqual("default renderer");
114
+ expect(UNSAFE_getByProps({ whoAmI: "default renderer" })).toBeTruthy();
117
115
  });
118
116
  });
119
117
  });
@@ -1,4 +1,5 @@
1
1
  import { findPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
2
+ import { isGroup } from "@applicaster/zapp-react-native-utils/componentsUtils";
2
3
 
3
4
  import { componentsLogger } from "../../Helpers/logger";
4
5
  import defaultCellRenderer from "../default-cell-renderer";
@@ -80,7 +81,7 @@ export function CellRendererResolver({
80
81
  }: Props) {
81
82
  const cellRendererPlugin = getRendererPlugin(component, plugins, cellStyles);
82
83
 
83
- if (!cellRendererPlugin && component.component_type !== "group-qb") {
84
+ if (!cellRendererPlugin && !isGroup(component)) {
84
85
  logger.warning({
85
86
  message: "Could not resolve cell builder plugin",
86
87
  data: { component },
@@ -1,48 +1,7 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`ComponentResolver renders correctly 1`] = `
4
- <ContextProvider
5
- value={null}
6
- >
7
- <Memo(ComponentResolver)
8
- cellStyles={{}}
9
- component={
10
- {
11
- "component_type": "some_component",
12
- }
13
- }
14
- components={
15
- {
16
- "SomeComponent": [MockFunction],
17
- }
18
- }
19
- decorators={[MockFunction]}
20
- dispatch={[Function]}
21
- plugins={[]}
22
- store={
23
- {
24
- "clearActions": [Function],
25
- "dispatch": [Function],
26
- "getActions": [Function],
27
- "getState": [Function],
28
- "replaceReducer": [Function],
29
- "subscribe": [Function],
30
- }
31
- }
32
- />
33
- </ContextProvider>
34
- `;
35
-
36
3
  exports[`ComponentResolverComponent initializes the cell renderer plugin module if matching plugin exists 1`] = `
37
- <mockConstructor
4
+ <View
38
5
  rendered={true}
39
6
  />
40
7
  `;
41
-
42
- exports[`ComponentResolverComponent renders the Component if it exists 1`] = `
43
- <mockConstructor
44
- rendered={true}
45
- />
46
- `;
47
-
48
- exports[`ComponentResolverComponent returns null if the component doesn't exist 1`] = `""`;
@@ -1,7 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
- import { shallow } from "enzyme";
4
- import { shallowToJson } from "enzyme-to-json";
3
+ import { render } from "@testing-library/react-native";
5
4
  import configureStore from "redux-mock-store";
6
5
 
7
6
  const mockLogger = {
@@ -43,37 +42,36 @@ const store = configureStore()({
43
42
  });
44
43
 
45
44
  const component = { component_type: "some_component" };
46
- const decorators = jest.fn((x) => x);
45
+ const decorators = (x) => x;
47
46
  const renderFunction = jest.fn((Comp) => <Comp rendered />);
48
47
 
49
48
  function clearAllMocks() {
50
- SomeComponent.mockClear();
51
- decorators.mockClear();
52
- renderFunction.mockClear();
53
- mockLogger.warning.mockClear();
49
+ jest.clearAllMocks();
54
50
  }
55
51
 
56
52
  describe("ComponentResolver", () => {
57
53
  beforeEach(clearAllMocks);
58
54
 
59
55
  it("renders correctly", () => {
60
- const wrapper = shallow(
56
+ const { toJSON } = render(
61
57
  <ComponentResolver
62
58
  component={component}
63
59
  decorators={decorators}
64
60
  store={store}
65
- />
61
+ >
62
+ {() => null}
63
+ </ComponentResolver>
66
64
  );
67
65
 
68
- expect(shallowToJson(wrapper)).toMatchSnapshot();
66
+ expect(toJSON()).toBeNull();
69
67
  });
70
68
  });
71
69
 
72
70
  describe("ComponentResolverComponent", () => {
73
71
  beforeEach(clearAllMocks);
74
72
 
75
- const getWrapper = (component, plugins) =>
76
- shallow(
73
+ const renderComponent = (component, plugins) =>
74
+ render(
77
75
  <ComponentResolverComponent
78
76
  components={components}
79
77
  component={component}
@@ -87,9 +85,9 @@ describe("ComponentResolverComponent", () => {
87
85
  );
88
86
 
89
87
  it("renders the Component if it exists", () => {
90
- const wrapper = getWrapper(component, plugins);
88
+ const { toJSON } = renderComponent(component, plugins);
91
89
 
92
- expect(shallowToJson(wrapper)).toMatchSnapshot();
90
+ expect(toJSON()).not.toBeNull();
93
91
 
94
92
  expect(renderFunction).toHaveBeenCalledWith(
95
93
  SomeComponent,
@@ -98,14 +96,12 @@ describe("ComponentResolverComponent", () => {
98
96
  });
99
97
 
100
98
  it("returns null if the component doesn't exist", () => {
101
- const wrapper = getWrapper({ component_type: "foo" }, plugins);
99
+ const { UNSAFE_root } = renderComponent({ component_type: "foo" }, plugins);
102
100
 
103
101
  const warningMessage =
104
102
  "Component foo cannot be found - it is skipped from rendering";
105
103
 
106
- expect(shallowToJson(wrapper)).toMatchSnapshot();
107
- expect(wrapper.isEmptyRender()).toBe(true);
108
-
104
+ expect(UNSAFE_root.children.length).toBe(0);
109
105
  expect(mockLogger.warning).toHaveBeenCalledTimes(2);
110
106
 
111
107
  expect(mockLogger.warning).toHaveBeenNthCalledWith(
@@ -124,11 +120,9 @@ describe("ComponentResolverComponent", () => {
124
120
  });
125
121
 
126
122
  it("initializes the cell renderer plugin module if matching plugin exists", () => {
127
- const plugins = [];
128
-
129
- const wrapper = getWrapper(component, plugins);
123
+ const { toJSON } = renderComponent(component, plugins);
130
124
 
131
- expect(shallowToJson(wrapper)).toMatchSnapshot();
125
+ expect(toJSON()).toMatchSnapshot();
132
126
 
133
127
  expect(renderFunction).toHaveBeenCalledWith(
134
128
  SomeComponent,
@@ -1,10 +1,10 @@
1
1
  import React from "react";
2
- import { shallow } from "enzyme";
2
+ import { render } from "@testing-library/react-native";
3
3
 
4
- import { ContentScreen } from "../index";
4
+ import { ContentScreen } from "../";
5
5
 
6
6
  describe("<ContentScreen />", () => {
7
7
  it("renders correctly", () => {
8
- expect(() => shallow(<ContentScreen />)).toThrowErrorMatchingSnapshot();
8
+ expect(() => render(<ContentScreen />)).toThrowErrorMatchingSnapshot();
9
9
  });
10
10
  });