@applicaster/zapp-react-native-ui-components 14.0.0-alpha.2332850672 → 14.0.0-alpha.2385258459

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 (108) hide show
  1. package/Components/AnimatedInOut/index.tsx +5 -3
  2. package/Components/AudioPlayer/index.tsx +15 -0
  3. package/Components/AudioPlayer/{AudioPlayerMobileLayout.tsx → mobile/Layout.tsx} +10 -5
  4. package/Components/AudioPlayer/{__tests__ → mobile/__tests__}/__snapshots__/audioPlayerMobileLayout.test.js.snap +1 -1
  5. package/Components/AudioPlayer/{__tests__ → mobile/__tests__}/audioPlayerMobileLayout.test.js +2 -2
  6. package/Components/AudioPlayer/mobile/index.tsx +18 -0
  7. package/Components/AudioPlayer/{Artwork.tsx → tv/Artwork.tsx} +3 -2
  8. package/Components/AudioPlayer/{Channel.tsx → tv/Channel.tsx} +7 -7
  9. package/Components/AudioPlayer/tv/Layout.tsx +168 -0
  10. package/Components/AudioPlayer/{Runtime.tsx → tv/Runtime.tsx} +7 -1
  11. package/Components/AudioPlayer/{Summary.tsx → tv/Summary.tsx} +6 -2
  12. package/Components/AudioPlayer/{Title.tsx → tv/Title.tsx} +6 -2
  13. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/Runtime.test.js.snap +2 -2
  14. package/Components/AudioPlayer/tv/__tests__/__snapshots__/audioPlayer.test.js.snap +164 -0
  15. package/Components/AudioPlayer/tv/__tests__/__snapshots__/channel.test.js.snap +19 -0
  16. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/summary.test.js.snap +1 -2
  17. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/title.test.js.snap +1 -2
  18. package/Components/AudioPlayer/{__tests__ → tv/__tests__}/audioPlayer.test.js +7 -3
  19. package/Components/AudioPlayer/{helpers.tsx → tv/helpers.tsx} +11 -5
  20. package/Components/AudioPlayer/{AudioPlayer.tsx → tv/index.tsx} +21 -97
  21. package/Components/AudioPlayer/types.ts +40 -0
  22. package/Components/Cell/index.js +7 -3
  23. package/Components/ComponentResolver/index.ts +1 -1
  24. package/Components/FeedLoader/index.js +1 -1
  25. package/Components/Focusable/Focusable.tsx +5 -3
  26. package/Components/Focusable/FocusableTvOS.tsx +3 -3
  27. package/Components/Focusable/FocusableiOS.tsx +2 -2
  28. package/Components/Focusable/__tests__/index.android.test.tsx +3 -0
  29. package/Components/Focusable/index.android.tsx +12 -8
  30. package/Components/Focusable/index.tsx +1 -1
  31. package/Components/FocusableList/index.tsx +4 -0
  32. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +42 -59
  33. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +12 -8
  34. package/Components/HandlePlayable/HandlePlayable.tsx +25 -9
  35. package/Components/Layout/TV/LayoutBackground.tsx +1 -1
  36. package/Components/MasterCell/DefaultComponents/Button.tsx +1 -1
  37. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -27
  38. package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +1 -1
  39. package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +1 -1
  40. package/Components/MasterCell/elementMapper.tsx +1 -2
  41. package/Components/MasterCell/index.tsx +1 -1
  42. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +13 -18
  43. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +9 -0
  44. package/Components/OfflineHandler/__tests__/index.test.tsx +20 -22
  45. package/Components/PlayerContainer/ErrorDisplay/index.ts +1 -1
  46. package/Components/PlayerContainer/PlayerContainer.tsx +42 -32
  47. package/Components/PlayerContainer/ProgramInfo/index.tsx +1 -1
  48. package/Components/PlayerContainer/index.ts +1 -1
  49. package/Components/PlayerImageBackground/index.tsx +1 -1
  50. package/Components/River/ComponentsMap/ComponentsMap.tsx +0 -1
  51. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +379 -0
  52. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +2 -2
  53. package/Components/River/RefreshControl.tsx +6 -4
  54. package/Components/River/TV/River.tsx +2 -17
  55. package/Components/River/TV/index.tsx +3 -1
  56. package/Components/River/TV/withPipesV1DataLoader.tsx +43 -0
  57. package/Components/River/TV/withRiverDataLoader.tsx +17 -0
  58. package/Components/River/TV/withTVEventHandler.tsx +1 -1
  59. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -0
  60. package/Components/River/index.tsx +1 -1
  61. package/Components/Screen/__tests__/Screen.test.tsx +23 -12
  62. package/Components/ScreenRevealManager/ScreenRevealManager.ts +76 -0
  63. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +107 -0
  64. package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +96 -0
  65. package/Components/ScreenRevealManager/index.ts +1 -0
  66. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +79 -0
  67. package/Components/Tabs/TV/Tabs.android.tsx +0 -2
  68. package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +34 -0
  69. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +15 -9
  70. package/Components/VideoLive/animationUtils.ts +3 -3
  71. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +32 -8
  72. package/Components/VideoModal/PlayerDetails.tsx +24 -2
  73. package/Components/VideoModal/PlayerWrapper.tsx +26 -142
  74. package/Components/VideoModal/VideoModal.tsx +3 -17
  75. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -7
  76. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +44 -240
  77. package/Components/VideoModal/hooks/index.ts +0 -2
  78. package/Components/VideoModal/hooks/useModalSize.ts +18 -2
  79. package/Components/VideoModal/utils.ts +6 -0
  80. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -16
  81. package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +84 -24
  82. package/Components/Viewport/VisibilitySensor/VisibilitySensor.tsx +3 -3
  83. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/index.ts +3 -3
  84. package/Decorators/ConfigurationWrapper/withConfigurationProvider.tsx +2 -2
  85. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +3 -6
  86. package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -0
  87. package/Decorators/ZappPipesDataConnector/__tests__/NullFeedResolver.test.tsx +78 -0
  88. package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +205 -0
  89. package/Decorators/ZappPipesDataConnector/__tests__/StaticFeedResolver.test.tsx +251 -0
  90. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +368 -0
  91. package/Decorators/ZappPipesDataConnector/__tests__/utils.test.ts +39 -0
  92. package/Decorators/ZappPipesDataConnector/index.tsx +26 -293
  93. package/Decorators/ZappPipesDataConnector/resolvers/NullFeedResolver.tsx +25 -0
  94. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +87 -0
  95. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +241 -0
  96. package/Decorators/ZappPipesDataConnector/types.ts +29 -0
  97. package/package.json +5 -10
  98. package/Components/AudioPlayer/AudioPlayerTVLayout.tsx +0 -161
  99. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +0 -66
  100. package/Components/AudioPlayer/__tests__/__snapshots__/channel.test.js.snap +0 -28
  101. package/Components/AudioPlayer/index.ts +0 -1
  102. package/Components/VideoModal/hooks/useBackgroundColor.ts +0 -10
  103. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/Runtime.test.js +0 -0
  104. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/__snapshots__/artWork.test.js.snap +0 -0
  105. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/artWork.test.js +0 -0
  106. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/channel.test.js +0 -0
  107. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/summary.test.js +0 -0
  108. /package/Components/AudioPlayer/{__tests__ → tv/__tests__}/title.test.js +0 -0
@@ -1,7 +1,11 @@
1
1
  import React from "react";
2
2
  import { render } from "@testing-library/react-native";
3
3
 
4
- import { AudioPlayer } from "../AudioPlayer";
4
+ import { AudioPlayerTV } from "..";
5
+
6
+ jest.mock("@applicaster/zapp-react-native-utils/audioPlayerUtils", () => ({
7
+ useArtworkImage: jest.fn(() => "artwork_url"),
8
+ }));
5
9
 
6
10
  const audioPlayerProps = {
7
11
  audio_item: {
@@ -45,9 +49,9 @@ const audioPlayerProps = {
45
49
  styles: {},
46
50
  };
47
51
 
48
- describe("<AudioPlayer />", () => {
52
+ describe("<AudioPlayerTV />", () => {
49
53
  it("renders correctly", () => {
50
- const { toJSON } = render(<AudioPlayer {...audioPlayerProps} />);
54
+ const { toJSON } = render(<AudioPlayerTV {...audioPlayerProps} />);
51
55
  expect(toJSON()).toMatchSnapshot();
52
56
  });
53
57
  });
@@ -2,9 +2,8 @@ const defaults = {
2
2
  audio_player_title_color: "white",
3
3
  audio_player_summary_color: "white",
4
4
  audio_player_background_color: "black",
5
- audio_player_artwork_aspect_ratio: "1:1",
5
+ audio_player_background_image: undefined,
6
6
  audio_player_rtl: false,
7
- audio_player_background_image_default_color: "",
8
7
  };
9
8
 
10
9
  export function getPropertyFromEntryOrConfig({ entry, plugin_configuration }) {
@@ -28,13 +27,20 @@ const LTR = {
28
27
  justifyContent: "flex-start",
29
28
  textAlign: "left",
30
29
  alignItems: "flex-end",
31
- };
30
+ } as const;
32
31
 
33
32
  const RTL = {
34
33
  flexDirection: "row-reverse",
35
34
  justifyContent: "flex-end",
36
35
  textAlign: "right",
37
36
  alignItems: "flex-start",
38
- };
37
+ } as const;
39
38
 
40
- export const directionStyles = (isRTL) => (isRTL ? RTL : LTR);
39
+ export const directionStyles = (
40
+ isRTL: boolean
41
+ ): {
42
+ flexDirection: "row" | "row-reverse";
43
+ justifyContent: "flex-start" | "flex-end";
44
+ textAlign: "left" | "right";
45
+ alignItems: "flex-end" | "flex-start";
46
+ } => (isRTL ? RTL : LTR);
@@ -1,76 +1,23 @@
1
1
  import React, { useCallback, useMemo } from "react";
2
2
 
3
- import {
4
- platformSelect,
5
- isTV,
6
- } from "@applicaster/zapp-react-native-utils/reactUtils";
3
+ import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
4
+ import { useArtworkImage } from "@applicaster/zapp-react-native-utils/audioPlayerUtils";
7
5
 
8
- import { imageSrcFromMediaItem } from "@applicaster/zapp-react-native-utils/configurationUtils";
9
- import { getBackgroundImage } from "@applicaster/zapp-react-native-utils/audioPlayerUtils";
10
-
11
- import { AudioPlayerMobileLayout } from "./AudioPlayerMobileLayout";
12
- import { AudioPlayerTVLayout } from "./AudioPlayerTVLayout";
6
+ import { AudioPlayerTVLayout } from "./Layout";
13
7
 
14
8
  import { Channel } from "./Channel";
15
9
  import { Title } from "./Title";
16
10
  import { Summary } from "./Summary";
17
11
  import { Runtime } from "./Runtime";
18
12
  import { getPropertyFromEntryOrConfig } from "./helpers";
19
- import { ViewStyle } from "react-native";
20
-
21
- type Props = {
22
- audio_item: ZappEntry & {
23
- extensions?: {
24
- audio_player_artwork_aspect_ratio?: string;
25
- audio_player_background_image?: string;
26
- audio_player_background_color?: string;
27
- audio_player_channel_icon?: string;
28
- audio_player_title_color?: string;
29
- audio_player_summary_color?: string;
30
- audio_player_rtl?: boolean;
31
- audio_player_background_image_default_color?: string;
32
- start_time?: string;
33
- end_time?: string;
34
- };
35
- };
36
- plugin_configuration: {
37
- audio_player_background_color?: string;
38
- audio_player_title_color?: string;
39
- audio_player_summary_color?: string;
40
- audio_player_rtl?: string;
41
- audio_player_background_image_default_color?: string;
42
- audio_player_background_image?: string;
43
- audio_player_artwork_aspect_ratio?: string;
44
- lg_tv_audio_player_title_font_family?: string;
45
- lg_tv_audio_player_title_font_size?: number;
46
- lg_tv_audio_player_summary_font_family?: string;
47
- lg_tv_audio_player_summary_font_size?: number;
48
- samsung_tv_audio_player_title_font_family?: string;
49
- samsung_tv_audio_player_title_font_size?: number;
50
- samsung_tv_audio_player_summary_font_family?: string;
51
- samsung_tv_audio_player_summary_font_size?: number;
52
- tv_os_audio_player_title_font_family?: string;
53
- tv_os_audio_player_title_font_size?: number;
54
- tv_os_audio_player_summary_font_family?: string;
55
- tv_os_audio_player_summary_font_size?: number;
56
- };
57
- style?: ViewStyle;
58
- };
59
-
60
- export function AudioPlayer(props: Props) {
13
+
14
+ import { Props } from "../types";
15
+
16
+ export function AudioPlayerTV(props: Props) {
61
17
  const { audio_item, plugin_configuration, style = {} } = props;
62
18
  const { extensions, title, summary } = audio_item;
63
19
 
64
- const mobileConfig = useMemo(() => {
65
- const backgroundImage = getBackgroundImage({
66
- entry: audio_item,
67
- plugin_configuration,
68
- });
69
-
70
- return {
71
- backgroundImage,
72
- };
73
- }, [audio_item, plugin_configuration]);
20
+ const artwork = useArtworkImage(audio_item);
74
21
 
75
22
  const getProp = useCallback(
76
23
  getPropertyFromEntryOrConfig({
@@ -80,22 +27,21 @@ export function AudioPlayer(props: Props) {
80
27
  [audio_item, plugin_configuration]
81
28
  );
82
29
 
83
- const tvConfig = useMemo(() => {
84
- // Checking if we are recieving items from the DSP
30
+ const config = useMemo(() => {
31
+ // Checking if we are receiving items from the DSP
85
32
  const titleColor = getProp("audio_player_title_color");
86
33
  const summaryColor = getProp("audio_player_summary_color");
87
34
  const backgroundColor = getProp("audio_player_background_color");
88
35
  const backgroundImage = getProp("audio_player_background_image");
89
- const backgroundImageKey = getProp("audio_player_background_image_key");
90
- const artworkAspectRatio = getProp("audio_player_artwork_aspect_ratio");
91
36
  const channelIcon = getProp("audio_player_channel_icon");
92
37
  const rtlFlag = getProp("audio_player_rtl");
93
- const artworkBorderRadius = getProp("audio_player_artwork_border_radius");
94
38
 
95
- const audioPlayerBackgroundImageDefaultColor = getProp(
96
- "audio_player_background_image_default_color"
39
+ const backgroundImageOverlay = getProp(
40
+ "audio_player_background_image_overlay"
97
41
  );
98
42
 
43
+ const artworkBorderRadius = getProp("audio_player_artwork_border_radius");
44
+
99
45
  const isRTL = rtlFlag === "1" || rtlFlag === "true" || rtlFlag === true;
100
46
 
101
47
  const titleFontFamily = getProp(
@@ -163,7 +109,6 @@ export function AudioPlayer(props: Props) {
163
109
  summaryColor,
164
110
  backgroundColor,
165
111
  backgroundImage,
166
- backgroundImageKey,
167
112
  isRTL,
168
113
  titleFontFamily,
169
114
  titleFontSize,
@@ -171,39 +116,18 @@ export function AudioPlayer(props: Props) {
171
116
  summaryFontSize,
172
117
  runTimeFontFamily,
173
118
  runTimeFontSize,
174
- artworkAspectRatio,
175
119
  channelIcon,
176
- audioPlayerBackgroundImageDefaultColor,
177
120
  artworkBorderRadius,
121
+ backgroundImageOverlay,
178
122
  };
179
123
  }, [getProp]);
180
124
 
181
- const artwork = imageSrcFromMediaItem(audio_item, [
182
- tvConfig?.artworkAspectRatio,
183
- ]);
184
-
185
- console.log("debug_2", "AudioPlayer", {
186
- tvConfig,
187
- mobileConfig,
188
- audio_item,
189
- plugin_configuration,
190
- });
191
-
192
- if (isTV()) {
193
- return (
194
- <AudioPlayerTVLayout artwork={artwork} config={tvConfig} style={style}>
195
- <Channel srcImage={tvConfig?.channelIcon} config={tvConfig} />
196
- <Title title={title} config={tvConfig} />
197
- <Summary summary={summary} config={tvConfig} />
198
- <Runtime {...extensions} config={tvConfig} />
199
- </AudioPlayerTVLayout>
200
- );
201
- }
202
-
203
125
  return (
204
- <AudioPlayerMobileLayout
205
- backgroundImage={mobileConfig.backgroundImage}
206
- style={style}
207
- />
126
+ <AudioPlayerTVLayout artwork={artwork} config={config} style={style}>
127
+ <Channel srcImage={config?.channelIcon} config={config} />
128
+ <Title title={title} config={config} />
129
+ <Summary summary={summary} config={config} />
130
+ <Runtime {...extensions} config={config} />
131
+ </AudioPlayerTVLayout>
208
132
  );
209
133
  }
@@ -0,0 +1,40 @@
1
+ import { ViewStyle } from "react-native";
2
+
3
+ export type Props = {
4
+ audio_item: ZappEntry & {
5
+ extensions?: {
6
+ audio_player_artwork_aspect_ratio?: string;
7
+ audio_player_background_image?: string;
8
+ audio_player_background_color?: string;
9
+ audio_player_channel_icon?: string;
10
+ audio_player_title_color?: string;
11
+ audio_player_summary_color?: string;
12
+ audio_player_rtl?: boolean;
13
+ audio_player_background_image_default_color?: string;
14
+ start_time?: string;
15
+ end_time?: string;
16
+ };
17
+ };
18
+ plugin_configuration: {
19
+ audio_player_background_color?: string;
20
+ audio_player_title_color?: string;
21
+ audio_player_summary_color?: string;
22
+ audio_player_rtl?: string;
23
+ audio_player_background_image_default_color?: string;
24
+ audio_player_background_image?: string;
25
+ audio_player_artwork_aspect_ratio?: string;
26
+ lg_tv_audio_player_title_font_family?: string;
27
+ lg_tv_audio_player_title_font_size?: number;
28
+ lg_tv_audio_player_summary_font_family?: string;
29
+ lg_tv_audio_player_summary_font_size?: number;
30
+ samsung_tv_audio_player_title_font_family?: string;
31
+ samsung_tv_audio_player_title_font_size?: number;
32
+ samsung_tv_audio_player_summary_font_family?: string;
33
+ samsung_tv_audio_player_summary_font_size?: number;
34
+ tv_os_audio_player_title_font_family?: string;
35
+ tv_os_audio_player_title_font_size?: number;
36
+ tv_os_audio_player_summary_font_family?: string;
37
+ tv_os_audio_player_summary_font_size?: number;
38
+ };
39
+ style?: ViewStyle;
40
+ };
@@ -1,13 +1,17 @@
1
1
  import * as R from "ramda";
2
2
 
3
- import { connectToStore } from "@applicaster/zapp-react-native-redux";
3
+ import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
4
4
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
5
5
 
6
- import { HorizontalScrollContext, RiverOffsetContext } from "../../Contexts";
6
+ import {
7
+ HorizontalScrollContext,
8
+ RiverOffsetContext,
9
+ ScreenScrollingContext,
10
+ } from "../../Contexts";
11
+
7
12
  import { CellComponent } from "./Cell";
8
13
  import { TvOSCellComponent } from "./TvOSCellComponent";
9
14
  import { withConsumer } from "../../Contexts/HeaderOffsetContext";
10
- import { ScreenScrollingContext } from "../../Contexts/ScreenScrollingContext";
11
15
 
12
16
  import { ScreenLayoutContextConsumer } from "../../Contexts/ScreenLayoutContext";
13
17
  import { createContext } from "@applicaster/zapp-react-native-utils/reactUtils/createContext";
@@ -1,6 +1,6 @@
1
1
  import * as R from "ramda";
2
2
 
3
- import { connectToStore } from "@applicaster/zapp-react-native-redux";
3
+ import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
4
4
 
5
5
  import { ComponentResolverComponent } from "./ComponentResolver";
6
6
 
@@ -1,6 +1,6 @@
1
1
  import * as R from "ramda";
2
2
 
3
- import { connectToStore } from "@applicaster/zapp-react-native-redux";
3
+ import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
4
4
  import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
5
5
 
6
6
  import { FeedLoaderComponent } from "./FeedLoader";
@@ -5,6 +5,7 @@ import { BaseFocusable } from "../BaseFocusable";
5
5
  import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
6
6
  import { LONG_KEY_PRESS_TIMEOUT } from "@applicaster/quick-brick-core/const";
7
7
  import { withFocusableContext } from "../../Contexts/FocusableGroupContext/withFocusableContext";
8
+ import { StyleSheet, ViewStyle } from "react-native";
8
9
 
9
10
  type Props = {
10
11
  initialFocus?: boolean;
@@ -21,7 +22,7 @@ type Props = {
21
22
  handleFocus?: ({ mouse }: { mouse: boolean }) => void;
22
23
  children: (boolean, string) => React.ComponentType<any>;
23
24
  selected?: boolean;
24
- style?: React.CSSProperties;
25
+ style?: ViewStyle[] | ViewStyle;
25
26
  };
26
27
 
27
28
  class Focusable extends BaseFocusable<Props> {
@@ -122,7 +123,7 @@ class Focusable extends BaseFocusable<Props> {
122
123
  }
123
124
 
124
125
  render() {
125
- const { children, style } = this.props;
126
+ const { children, style, ...otherProps } = this.props;
126
127
  const { focused } = this.state;
127
128
 
128
129
  const id = this.getId();
@@ -139,7 +140,8 @@ class Focusable extends BaseFocusable<Props> {
139
140
  onMouseUp={this.pressOut}
140
141
  data-testid={focusableId}
141
142
  focused-teststate={focused ? "focused" : "default"}
142
- style={style}
143
+ style={StyleSheet.flatten(style) as any as React.CSSProperties}
144
+ {...otherProps}
143
145
  >
144
146
  {children(focused, { mouse: this.mouse })}
145
147
  </div>
@@ -16,9 +16,9 @@ function noop() {}
16
16
  type Props = {
17
17
  id: string;
18
18
  groupId: string;
19
- onPress?: (nativeEvent: React.SyntheticEvent) => void;
20
- onFocus?: (nativeEvent: React.SyntheticEvent) => void;
21
- onBlur?: (nativeEvent: React.SyntheticEvent) => void;
19
+ onPress?: (nativeEvent: any) => void;
20
+ onFocus?: (nativeEvent: any) => void;
21
+ onBlur?: (nativeEvent: any) => void;
22
22
  children: (focused?: boolean) => React.ReactNode;
23
23
  isParallaxDisabled: boolean;
24
24
  preferredFocus?: boolean;
@@ -2,7 +2,7 @@ import React from "react";
2
2
 
3
3
  type Props = {
4
4
  children: () => React.ReactNode;
5
- };
5
+ } & Record<string, any>;
6
6
 
7
7
  function FocusableiOSComponent({ children }: Props) {
8
8
  if (typeof children === "function") {
@@ -12,4 +12,4 @@ function FocusableiOSComponent({ children }: Props) {
12
12
  return children;
13
13
  }
14
14
 
15
- export const FocusableiOS = React.forwardRef(FocusableiOSComponent);
15
+ export const FocusableiOS = FocusableiOSComponent;
@@ -38,6 +38,9 @@ describe("Focusable", () => {
38
38
  });
39
39
 
40
40
  it("updates disableFocus state when disableFocus prop changes", () => {
41
+ const unregister = jest.fn();
42
+ mockFocusManager.registerFocusable.mockReturnValue(unregister);
43
+
41
44
  const { rerender } = render(
42
45
  <Focusable id="test-id" disableFocus={false}>
43
46
  <Touchable testID="touchable" />
@@ -43,11 +43,13 @@ export const FocusableContext = React.createContext<
43
43
  // eslint-disable-next-line
44
44
  setIsFocusable: (enableFocus: boolean) => void;
45
45
  ref: FocusManager.FocusableRef;
46
+ parentFocusableId: Option<string>;
46
47
  } & ParentFocus
47
48
  >({
48
49
  focused: false,
49
50
  setIsFocusable: () => {},
50
51
  ref: { current: null },
52
+ parentFocusableId: undefined,
51
53
  });
52
54
 
53
55
  export const useFocusable = () => React.useContext(FocusableContext);
@@ -74,7 +76,7 @@ function FocusableComponent(props: Props, forwardedRef) {
74
76
 
75
77
  const isRTL = useIsRTL();
76
78
  const focusManager = useFocusManager();
77
- const { ref: parentFocusable } = useFocusable();
79
+ const { ref: parentFocusableRef, parentFocusableId } = useFocusable();
78
80
  const touchableRef = React.useRef(null);
79
81
 
80
82
  const [focused, setFocused] = React.useState(() =>
@@ -98,13 +100,14 @@ function FocusableComponent(props: Props, forwardedRef) {
98
100
  }
99
101
  }, [disableFocus]);
100
102
 
101
- React.useEffect(() => {
103
+ React.useLayoutEffect(() => {
102
104
  if (id) {
103
- const unregister = focusManager.registerFocusable(
105
+ const unregister = focusManager.registerFocusable({
104
106
  touchableRef,
105
- parentFocusable,
106
- isFocusableCell
107
- );
107
+ parentFocusableRef,
108
+ isFocusableCell,
109
+ parentFocusableId,
110
+ });
108
111
 
109
112
  onRegister();
110
113
 
@@ -112,7 +115,7 @@ function FocusableComponent(props: Props, forwardedRef) {
112
115
  unregister();
113
116
  };
114
117
  }
115
- }, [id, onRegister, isFocusableCell]);
118
+ }, [id, onRegister, isFocusableCell, parentFocusableId]);
116
119
 
117
120
  if (R.isNil(id)) {
118
121
  // eslint-disable-next-line no-console
@@ -164,8 +167,9 @@ function FocusableComponent(props: Props, forwardedRef) {
164
167
  ...parentFocus,
165
168
  ref: touchableRef,
166
169
  setIsFocusable,
170
+ parentFocusableId: id,
167
171
  };
168
- }, [parentFocus, focused]);
172
+ }, [parentFocus, focused, id]);
169
173
 
170
174
  return (
171
175
  <Touchable
@@ -4,7 +4,7 @@ import { FocusableiOS } from "./FocusableiOS";
4
4
 
5
5
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
6
6
 
7
- export const Focusable = platformSelect({
7
+ export const Focusable: React.ComponentType<any> = platformSelect({
8
8
  tvos: FocusableTvOS,
9
9
  ios: FocusableiOS,
10
10
  default: FocusableDefault,
@@ -91,6 +91,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
91
91
  // eslint-disable-next-line unused-imports/no-unused-vars
92
92
  omitPropsPropagation = [],
93
93
  useScrollView = false,
94
+ onScrollToIndexFailed = noop,
94
95
  } = props;
95
96
 
96
97
  useCheckItemIdsForUnique({ componentId: props.id, items: data });
@@ -277,6 +278,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
277
278
  "withStateMemory",
278
279
  "useSequentialLoading",
279
280
  "useScrollView",
281
+ "onScrollToIndexFailed",
280
282
  ...omitPropsPropagation,
281
283
  ],
282
284
  R.__
@@ -305,6 +307,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
305
307
  {...getFlatListProps(props)}
306
308
  onEndReached={onEndReached}
307
309
  initialNumToRender={initialNumToRender}
310
+ onScrollToIndexFailed={onScrollToIndexFailed}
308
311
  renderItem={renderItem}
309
312
  focused={focused}
310
313
  data={data}
@@ -319,6 +322,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
319
322
  renderItem={renderItem}
320
323
  onEndReached={onEndReached}
321
324
  initialNumToRender={initialNumToRender}
325
+ onScrollToIndexFailed={onScrollToIndexFailed}
322
326
  />
323
327
  )}
324
328
  </ChildrenFocusDeactivatorView>
@@ -8,13 +8,10 @@ import {
8
8
  useCurationAPI,
9
9
  } from "../useCurationAPI";
10
10
  import * as redux from "react-redux";
11
- import * as layoutPresets from "@applicaster/zapp-react-native-redux/hooks/useLayoutPresets";
12
- import * as pipesFeeds from "@applicaster/zapp-react-native-redux/hooks/useZappPipesFeeds";
13
11
  import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/Contexts/NavigationContext";
14
12
  import { PathnameContext } from "@applicaster/zapp-react-native-ui-components/Contexts/PathnameContext";
15
13
 
16
- import { Provider } from "react-redux";
17
- import configureStore from "redux-mock-store";
14
+ import { WrappedWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
18
15
 
19
16
  jest.mock(
20
17
  "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute",
@@ -42,19 +39,20 @@ const mainStackNavigator = {
42
39
  },
43
40
  };
44
41
 
45
- const store = configureStore()({});
46
-
47
- const wrapper = ({ children }) => (
48
- <Provider store={store}>
49
- <NavigationContext.Provider
50
- value={{ ...mainStackNavigator, currentRoute: homeStack.route }}
51
- >
52
- <PathnameContext.Provider value={homeStack.route}>
53
- {children}
54
- </PathnameContext.Provider>
55
- </NavigationContext.Provider>
56
- </Provider>
57
- );
42
+ const getWrapper =
43
+ (store) =>
44
+ // eslint-disable-next-line react/display-name, react/prop-types
45
+ ({ children }) => (
46
+ <WrappedWithProviders store={store}>
47
+ <NavigationContext.Provider
48
+ value={{ ...mainStackNavigator, currentRoute: homeStack.route }}
49
+ >
50
+ <PathnameContext.Provider value={homeStack.route}>
51
+ {children}
52
+ </PathnameContext.Provider>
53
+ </NavigationContext.Provider>
54
+ </WrappedWithProviders>
55
+ );
58
56
 
59
57
  describe("getTransformedPreset should return the passed components if smartComponents is empty", () => {
60
58
  describe("getTransformedPreset function", () => {
@@ -312,19 +310,10 @@ describe("getTransformedPreset should return the passed components if smartCompo
312
310
  { id: "02", component_type: "not_smart_another" },
313
311
  ];
314
312
 
315
- // mock the hooks
316
- const mockUseZappPipesFeeds = jest.spyOn(pipesFeeds, "useZappPipesFeeds");
317
- mockUseZappPipesFeeds.mockReturnValue({});
318
-
319
- const mockUseLayoutPresets = jest.spyOn(
320
- layoutPresets,
321
- "useLayoutPresets"
322
- );
323
-
324
- mockUseLayoutPresets.mockReturnValue({});
325
-
326
313
  const { result } = renderHook(() => useCurationAPI(mockComponents), {
327
- wrapper,
314
+ wrapper: getWrapper({
315
+ zappPipes: {},
316
+ }),
328
317
  });
329
318
 
330
319
  // if there are no smart components, it should return the original array
@@ -366,18 +355,15 @@ describe("getTransformedPreset should return the passed components if smartCompo
366
355
  "http://curation": { loading: false, data: { entry: mockPresetEntry } },
367
356
  };
368
357
 
369
- const mockUseZappPipesFeeds = jest.spyOn(pipesFeeds, "useZappPipesFeeds");
370
- mockUseZappPipesFeeds.mockReturnValue(mockFeeds);
371
-
372
- const mockUseLayoutPresets = jest.spyOn(
373
- layoutPresets,
374
- "useLayoutPresets"
375
- );
376
-
377
- mockUseLayoutPresets.mockReturnValue(mockLayoutPresets);
378
-
379
358
  const { result } = renderHook(() => useCurationAPI(mockComponents), {
380
- wrapper,
359
+ wrapper: getWrapper({
360
+ zappPipes: mockFeeds,
361
+ presetsMapping: {
362
+ presets_mappings: {
363
+ ...mockLayoutPresets,
364
+ },
365
+ },
366
+ }),
381
367
  });
382
368
 
383
369
  expect(result.current).toEqual(mockTransformedComponents);
@@ -437,19 +423,15 @@ describe("getTransformedPreset should return the passed components if smartCompo
437
423
  },
438
424
  };
439
425
 
440
- // mock the hooks
441
- const mockUseZappPipesFeeds = jest.spyOn(pipesFeeds, "useZappPipesFeeds");
442
- mockUseZappPipesFeeds.mockReturnValue(mockFeeds);
443
-
444
- const mockUseLayoutPresets = jest.spyOn(
445
- layoutPresets,
446
- "useLayoutPresets"
447
- );
448
-
449
- mockUseLayoutPresets.mockReturnValue(mockLayoutPresets);
450
-
451
426
  const { result } = renderHook(() => useCurationAPI(mockComponents), {
452
- wrapper,
427
+ wrapper: getWrapper({
428
+ zappPipes: mockFeeds,
429
+ presetsMapping: {
430
+ presets_mappings: {
431
+ ...mockLayoutPresets,
432
+ },
433
+ },
434
+ }),
453
435
  });
454
436
 
455
437
  expect(result.current).toEqual(mockTransformedComponents);
@@ -495,14 +477,15 @@ describe("getTransformedPreset should return the passed components if smartCompo
495
477
  "http://curation": { loading: false, data: { entry: mockPresetEntry } },
496
478
  };
497
479
 
498
- // mock the hooks
499
- const mockUseZappPipesFeeds = jest.spyOn(pipesFeeds, "useZappPipesFeeds");
500
- mockUseZappPipesFeeds.mockReturnValue(mockFeeds);
501
- const mockUseLayoutPresets = jest.spyOn(layoutPresets, "useLayoutPresets");
502
- mockUseLayoutPresets.mockReturnValue(mockLayoutPresets);
503
-
504
480
  const { result } = renderHook(() => useCurationAPI(mockComponents), {
505
- wrapper,
481
+ wrapper: getWrapper({
482
+ zappPipes: mockFeeds,
483
+ presetsMapping: {
484
+ presets_mappings: {
485
+ ...mockLayoutPresets,
486
+ },
487
+ },
488
+ }),
506
489
  });
507
490
 
508
491
  expect(result.current).toEqual(mockTransformedComponents);