@applicaster/zapp-react-native-ui-components 13.0.0-alpha.1436249127 → 13.0.0-alpha.1486614302

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 (199) hide show
  1. package/Components/AppContainer/__tests__/AppContainer.test.js +4 -6
  2. package/Components/AppContainer/__tests__/__snapshots__/AppContainer.test.js.snap +1 -1
  3. package/Components/AudioPlayer/AudioPlayer.tsx +7 -0
  4. package/Components/AudioPlayer/__tests__/Runtime.test.js +5 -8
  5. package/Components/AudioPlayer/__tests__/__snapshots__/Runtime.test.js.snap +4 -4
  6. package/Components/AudioPlayer/__tests__/__snapshots__/artWork.test.js.snap +3 -3
  7. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +56 -113
  8. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +39 -23
  9. package/Components/AudioPlayer/__tests__/__snapshots__/channel.test.js.snap +3 -3
  10. package/Components/AudioPlayer/__tests__/__snapshots__/summary.test.js.snap +2 -2
  11. package/Components/AudioPlayer/__tests__/__snapshots__/title.test.js.snap +2 -2
  12. package/Components/AudioPlayer/__tests__/artWork.test.js +3 -5
  13. package/Components/AudioPlayer/__tests__/audioPlayer.test.js +3 -5
  14. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +7 -8
  15. package/Components/AudioPlayer/__tests__/channel.test.js +3 -5
  16. package/Components/AudioPlayer/__tests__/summary.test.js +3 -5
  17. package/Components/AudioPlayer/__tests__/title.test.js +3 -5
  18. package/Components/AudioPlayer/helpers.tsx +1 -0
  19. package/Components/BaseFocusable/index.ios.ts +1 -1
  20. package/Components/BaseFocusable/index.tsx +2 -3
  21. package/Components/Cell/Cell.tsx +11 -16
  22. package/Components/Cell/CellWithFocusable.tsx +50 -59
  23. package/Components/Cell/CellWrapper.tsx +18 -0
  24. package/Components/Cell/TvOSCellComponent.tsx +20 -26
  25. package/Components/Cell/__tests__/CellWIthFocusable.test.js +13 -6
  26. package/Components/Cell/index.js +3 -1
  27. package/Components/Cell/styles.ts +17 -0
  28. package/Components/CellRendererResolver/__tests__/cellRendererResolver.test.js +50 -50
  29. package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +1 -42
  30. package/Components/ComponentResolver/__tests__/componentResolver.test.js +26 -30
  31. package/Components/ContentScreen/__tests__/contentScreen.test.js +3 -3
  32. package/Components/DisplayState/__tests__/__snapshots__/displayState.test.js.snap +2 -2
  33. package/Components/ErrorScreen/index.tsx +14 -6
  34. package/Components/Focusable/Focusable.tsx +1 -0
  35. package/Components/Focusable/FocusableTvOS.tsx +6 -2
  36. package/Components/Focusable/Touchable.tsx +19 -20
  37. package/Components/Focusable/index.android.tsx +10 -3
  38. package/Components/FocusableCell/index.tsx +1 -1
  39. package/Components/FocusableGroup/FocusableTvOS.tsx +34 -86
  40. package/Components/FocusableGroup/index.tsx +0 -3
  41. package/Components/FocusableList/index.tsx +26 -10
  42. package/Components/FocusableScrollView/index.tsx +43 -13
  43. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +9 -0
  44. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +1 -1
  45. package/Components/HandlePlayable/HandlePlayable.tsx +21 -27
  46. package/Components/Layout/TV/NavBarContainer.tsx +19 -23
  47. package/Components/Layout/TV/ScreenContainer.tsx +8 -1
  48. package/Components/Layout/TV/ScreenLayoutContextProvider.tsx +5 -0
  49. package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +3 -1
  50. package/Components/Layout/TV/__tests__/__snapshots__/LayoutContainer.test.tsx.snap +1 -1
  51. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +6 -5
  52. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +12 -11
  53. package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +1 -1
  54. package/Components/Layout/TV/__tests__/index.test.tsx +7 -3
  55. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
  56. package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +66 -0
  57. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -1
  58. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +10 -15
  59. package/Components/MasterCell/DefaultComponents/Image/hooks/useImage.ts +11 -7
  60. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +93 -0
  61. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -2
  62. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +3 -3
  63. package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
  64. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  65. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/const.ts +3 -0
  66. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +6 -6
  67. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/__snapshots__/index.test.tsx.snap +1 -1
  68. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
  69. package/Components/MasterCell/__tests__/__snapshots__/dataAdapter.test.js.snap +180 -180
  70. package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +11 -19
  71. package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +6 -235
  72. package/Components/MasterCell/__tests__/elementMapper.test.js +18 -5
  73. package/Components/MasterCell/__tests__/masterCell.test.js +26 -26
  74. package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
  75. package/Components/MasterCell/hooks/useAsyncRendering/index.ts +2 -2
  76. package/Components/MasterCell/utils/behaviorProvider.ts +136 -0
  77. package/Components/MasterCell/utils/index.ts +9 -135
  78. package/Components/ModalComponent/Button/assets.ts +1 -1
  79. package/Components/ModalComponent/Button/index.tsx +6 -6
  80. package/Components/ModalComponent/Header/index.tsx +3 -3
  81. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +2 -2
  82. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +2 -2
  83. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -5
  84. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +7 -7
  85. package/Components/OfflineHandler/__tests__/index.test.tsx +28 -25
  86. package/Components/OfflineHandler/utils/index.ts +1 -1
  87. package/Components/PlayerContainer/PlayerContainer.tsx +45 -25
  88. package/Components/PlayerContainer/PlayerContainerContext.tsx +9 -0
  89. package/Components/PlayerContainer/ProgramInfo/index.tsx +2 -2
  90. package/Components/PlayerImageBackground/index.tsx +1 -1
  91. package/Components/River/ComponentsMap/ComponentsMap.tsx +42 -65
  92. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
  93. package/Components/River/RefreshControl.tsx +1 -1
  94. package/Components/River/RiverFooter.tsx +39 -9
  95. package/Components/River/RiverItem.tsx +37 -2
  96. package/Components/River/TV/index.tsx +6 -1
  97. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +114 -45
  98. package/Components/River/__tests__/__snapshots__/river.test.js.snap +21 -83
  99. package/Components/River/__tests__/componentsMap.test.js +64 -17
  100. package/Components/River/__tests__/river.test.js +75 -40
  101. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +12 -5
  102. package/Components/RouteManager/__tests__/routeManager.test.js +29 -14
  103. package/Components/RouteManager/__tests__/testId.test.js +8 -6
  104. package/Components/Screen/TV/index.web.tsx +5 -6
  105. package/Components/Screen/__tests__/Screen.test.tsx +41 -27
  106. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +4 -4
  107. package/Components/Screen/hooks.ts +53 -0
  108. package/Components/Screen/index.tsx +16 -42
  109. package/Components/ScreenResolver/__tests__/screenResolver.test.js +95 -70
  110. package/Components/Tabs/Tab.tsx +12 -9
  111. package/Components/TextInputTv/__tests__/TextInputTv.test.js +42 -42
  112. package/Components/TextInputTv/__tests__/__snapshots__/TextInputTv.test.js.snap +7 -0
  113. package/Components/TextInputTv/index.tsx +6 -5
  114. package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +2 -2
  115. package/Components/TrackedView/index.tsx +1 -0
  116. package/Components/Transitioner/AnimationManager.js +15 -15
  117. package/Components/Transitioner/Scene.tsx +53 -24
  118. package/Components/Transitioner/Transitioner.tsx +3 -3
  119. package/Components/Transitioner/__tests__/Scene.test.js +25 -14
  120. package/Components/Transitioner/__tests__/__snapshots__/AnimationManager.test.js.snap +26 -26
  121. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +10 -50
  122. package/Components/Transitioner/__tests__/__snapshots__/config.test.js.snap +20 -20
  123. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +4 -4
  124. package/Components/Transitioner/__tests__/transitioner.test.js +13 -4
  125. package/Components/Transitioner/index.js +8 -4
  126. package/Components/VideoLive/LiveImageManager.ts +27 -1
  127. package/Components/VideoLive/PlayerLiveImageComponent.tsx +36 -24
  128. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +63 -8
  129. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +6 -10
  130. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +1 -1
  131. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +52 -32
  132. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +8 -4
  133. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +48 -22
  134. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +8 -15
  135. package/Components/VideoModal/ModalAnimation/__tests__/getMoveUpValue.test.ts +108 -0
  136. package/Components/VideoModal/ModalAnimation/const.ts +5 -0
  137. package/Components/VideoModal/ModalAnimation/index.ts +4 -1
  138. package/Components/VideoModal/ModalAnimation/useModalAnimationContext.ts +6 -0
  139. package/Components/VideoModal/ModalAnimation/utils.ts +38 -2
  140. package/Components/VideoModal/OpaqueLayer.tsx +33 -0
  141. package/Components/VideoModal/PlayerDetails.tsx +9 -6
  142. package/Components/VideoModal/PlayerWrapper.tsx +43 -39
  143. package/Components/VideoModal/VideoModal.tsx +17 -11
  144. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -2
  145. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +13 -10
  146. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +4 -4
  147. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +66 -156
  148. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +89 -0
  149. package/Components/VideoModal/hooks/index.ts +7 -0
  150. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +49 -0
  151. package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +91 -0
  152. package/Components/VideoModal/hooks/utils/index.ts +33 -0
  153. package/Components/VideoModal/utils.ts +6 -9
  154. package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +24 -36
  155. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -18
  156. package/Components/Viewport/ViewportTracker/__tests__/__snapshots__/viewportTracker.test.js.snap +1 -1
  157. package/Components/Viewport/__tests__/utils.test.js +5 -4
  158. package/Components/ZappUIComponent/Placeholder.tsx +3 -1
  159. package/Components/ZappUIComponent/__tests__/{ZappUIComponent.test.js → ZappUIComponent.test.tsx} +26 -10
  160. package/Components/ZappUIComponent/index.tsx +4 -17
  161. package/Components/default-cell-renderer/__tests__/defaultCellRenderer.test.tsx +20 -17
  162. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/__tests__/DefaultCell.test.tsx +15 -11
  163. package/Contexts/ComponentsMapOffsetContext/index.tsx +49 -0
  164. package/Contexts/ConfigutaionContext/__tests__/__snapshots__/ConfigurationProvider.test.tsx.snap +1 -1
  165. package/Contexts/FocusableGroupContext/withFocusableContext.tsx +4 -10
  166. package/Contexts/HeaderOffsetContext/index.tsx +4 -6
  167. package/Contexts/ScreenContext/index.tsx +6 -12
  168. package/Contexts/ScreenLayoutContext/index.tsx +5 -3
  169. package/Decorators/Navigator/__tests__/navigator.test.js +16 -16
  170. package/Decorators/Navigator/index.tsx +1 -1
  171. package/Decorators/RiverFeedLoader/__tests__/__snapshots__/riverFeedLoader.test.tsx.snap +77 -77
  172. package/Decorators/RiverFeedLoader/__tests__/riverFeedLoader.test.tsx +34 -39
  173. package/Decorators/RiverFeedLoader/__tests__/utils.test.ts +0 -9
  174. package/Decorators/RiverFeedLoader/index.tsx +1 -1
  175. package/Decorators/RiverFeedLoader/utils/getDatasourceUrl.ts +39 -0
  176. package/Decorators/RiverFeedLoader/utils/index.ts +29 -0
  177. package/Decorators/RiverFeedLoader/utils/usePipesContexts.ts +40 -0
  178. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +27 -27
  179. package/Decorators/RiverResolver/index.tsx +6 -8
  180. package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
  181. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +29 -22
  182. package/Decorators/ZappPipesDataConnector/index.tsx +7 -3
  183. package/package.json +13 -11
  184. package/tsconfig.json +2 -3
  185. package/.babelrc +0 -8
  186. package/Components/Cell/CellStyles/FallbackCellStyle/index.js +0 -157
  187. package/Components/Cell/CellStyles/Hero/index.js +0 -111
  188. package/Components/Cell/CellStyles/ScreenSelector/index.js +0 -68
  189. package/Components/Cell/CellStyles/cellStylesResolver.ts +0 -19
  190. package/Components/Cell/CellStyles/colors.js +0 -40
  191. package/Components/Cell/CellStyles/index.js +0 -15
  192. package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +0 -53
  193. package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +0 -17
  194. package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +0 -17
  195. package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +0 -91
  196. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +0 -338
  197. package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +0 -18
  198. package/Decorators/RiverFeedLoader/utils.ts +0 -100
  199. package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +0 -28
@@ -12,6 +12,7 @@ import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
12
12
  import { CellWithFocusable } from "./CellWithFocusable";
13
13
  import { BaseFocusable } from "../BaseFocusable";
14
14
  import { AccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager";
15
+ import { styles } from "./styles";
15
16
 
16
17
  type Props = {
17
18
  item: ZappEntry;
@@ -61,23 +62,13 @@ type Props = {
61
62
  skipFocusManagerRegistration?: boolean;
62
63
  shouldUpdate: boolean;
63
64
  behavior: Behavior;
65
+ componentsMapOffset: number;
64
66
  };
65
67
 
66
68
  type State = {
67
69
  hasFocusableInside: boolean;
68
70
  };
69
71
 
70
- const baseCellStyles = {
71
- height: "100%",
72
- display: "flex",
73
- flex: 1,
74
- } as const;
75
-
76
- const touchableStyles = {
77
- flex: 1,
78
- height: "100%",
79
- } as const;
80
-
81
72
  export class CellComponent extends React.Component<Props, State> {
82
73
  constructor(props) {
83
74
  super(props);
@@ -251,7 +242,7 @@ export class CellComponent extends React.Component<Props, State> {
251
242
  <View
252
243
  testID={`${component?.id}-${id}`}
253
244
  accessible={false}
254
- style={touchableStyles}
245
+ style={styles.touchableCell}
255
246
  >
256
247
  <Focusable
257
248
  id={focusableId}
@@ -263,7 +254,7 @@ export class CellComponent extends React.Component<Props, State> {
263
254
  hasReceivedFocus={hasReceivedFocus || this.hasReceivedFocus}
264
255
  preferredFocus={preferredFocus}
265
256
  offsetUpdater={offsetUpdater}
266
- style={baseCellStyles}
257
+ style={styles.baseCell}
267
258
  isFocusable={isFocusable}
268
259
  skipFocusManagerRegistration={skipFocusManagerRegistration}
269
260
  >
@@ -273,10 +264,14 @@ export class CellComponent extends React.Component<Props, State> {
273
264
  if (isFocused) {
274
265
  const accessibilityManager = AccessibilityManager.getInstance();
275
266
 
267
+ const accessibilityTitle =
268
+ item?.extensions?.accessibility?.label || item?.title || "";
269
+
270
+ const accessibilityHint =
271
+ item?.extensions?.accessibility?.hint || "";
272
+
276
273
  accessibilityManager.readText({
277
- text: String(
278
- item.extensions?.accessibility?.label || item.title
279
- ),
274
+ text: `${accessibilityTitle} ${accessibilityHint}`,
280
275
  });
281
276
  }
282
277
 
@@ -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,12 +1,13 @@
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
- jest.mock("../../default-cell-renderer", () =>
6
- jest.fn((prop) => <View whoAmI="default renderer" someProp={prop} />)
7
- );
6
+ jest.mock("../../default-cell-renderer", () => {
7
+ const View = jest.requireActual("react-native").View;
8
8
 
9
- const { CellRendererResolver } = require("../index");
9
+ return jest.fn((prop) => <View whoAmI="default renderer" someProp={prop} />);
10
+ });
10
11
 
11
12
  const component = {
12
13
  styles: {
@@ -43,17 +44,9 @@ describe("CellRendererResolver", () => {
43
44
  cellStyles,
44
45
  });
45
46
 
46
- it("renders correctly", () => {
47
- const result = shallow(
48
- getResult({ component, plugins, styles, cellStyles })
49
- );
50
-
51
- expect(result).toMatchSnapshot();
52
- });
53
-
54
47
  describe("with a default renderer plugin", () => {
55
48
  it("renders correctly", () => {
56
- const result = shallow(
49
+ const { UNSAFE_root } = render(
57
50
  getResult({
58
51
  component,
59
52
  plugins,
@@ -62,56 +55,63 @@ describe("CellRendererResolver", () => {
62
55
  })
63
56
  );
64
57
 
65
- expect(result).toMatchSnapshot();
58
+ expect(UNSAFE_root).toBeDefined();
66
59
  });
67
60
 
68
61
  it("returns default plugin if component has no cell_plugin_configuration_id", () => {
69
- const result = getResult({
70
- component: {},
71
- plugins,
72
- styles,
73
- cellStyles,
74
- });
75
-
76
- expect(result).toBeDefined();
77
- 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();
78
72
  });
79
73
 
80
74
  it("returns default plugin if requested cell plugin configuration does not exist", () => {
81
- const result = getResult({
82
- component: { styles: { cell_plugin_configuration_id: "wrong-id" } },
83
- plugins,
84
- styles,
85
- cellStyles,
86
- });
87
-
88
- 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();
89
85
  });
90
86
 
91
87
  it("returns default plugin if cellStyles store is empty", () => {
92
- const result = getResult({
93
- component,
94
- plugins,
95
- styles,
96
- cellStyles: {},
97
- });
98
-
99
- 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();
100
98
  });
101
99
 
102
100
  it("returns null if requested renderer plugin does not exist", () => {
103
- const result = getResult({
104
- component: {
105
- styles: {
106
- 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
+ },
107
107
  },
108
- },
109
- plugins,
110
- styles,
111
- cellStyles,
112
- });
108
+ plugins,
109
+ styles,
110
+ cellStyles,
111
+ })
112
+ );
113
113
 
114
- expect(result.props.whoAmI).toEqual("default renderer");
114
+ expect(UNSAFE_getByProps({ whoAmI: "default renderer" })).toBeTruthy();
115
115
  });
116
116
  });
117
117
  });
@@ -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={Object {}}
9
- component={
10
- Object {
11
- "component_type": "some_component",
12
- }
13
- }
14
- components={
15
- Object {
16
- "SomeComponent": [MockFunction],
17
- }
18
- }
19
- decorators={[MockFunction]}
20
- dispatch={[Function]}
21
- plugins={Array []}
22
- store={
23
- Object {
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`] = `""`;