@applicaster/zapp-react-native-ui-components 14.0.0-alpha.8419134002 → 14.0.0-alpha.8557119261

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 (105) hide show
  1. package/Components/AnimatedInOut/index.tsx +5 -3
  2. package/Components/AudioPlayer/mobile/Layout.tsx +1 -1
  3. package/Components/AudioPlayer/tv/helpers.tsx +10 -3
  4. package/Components/BaseFocusable/index.tsx +23 -12
  5. package/Components/Cell/__tests__/CellWIthFocusable.test.js +3 -2
  6. package/Components/Cell/index.js +1 -1
  7. package/Components/ComponentResolver/index.ts +1 -1
  8. package/Components/FeedLoader/FeedLoader.tsx +6 -15
  9. package/Components/FeedLoader/FeedLoaderHOC.tsx +21 -0
  10. package/Components/FeedLoader/index.js +2 -8
  11. package/Components/Focusable/Focusable.tsx +5 -3
  12. package/Components/Focusable/FocusableTvOS.tsx +3 -3
  13. package/Components/Focusable/FocusableiOS.tsx +2 -2
  14. package/Components/Focusable/__tests__/index.android.test.tsx +3 -0
  15. package/Components/Focusable/index.android.tsx +12 -8
  16. package/Components/Focusable/index.tsx +1 -1
  17. package/Components/FocusableList/index.tsx +4 -0
  18. package/Components/FreezeWithCallback/__tests__/index.test.tsx +67 -43
  19. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +42 -59
  20. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +13 -10
  21. package/Components/HandlePlayable/HandlePlayable.tsx +25 -9
  22. package/Components/Layout/TV/LayoutBackground.tsx +1 -1
  23. package/Components/Layout/TV/__tests__/index.test.tsx +0 -1
  24. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -0
  25. package/Components/MasterCell/DefaultComponents/Button.tsx +1 -1
  26. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -27
  27. package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +1 -1
  28. package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +1 -1
  29. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +10 -10
  30. package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +18 -18
  31. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/index.test.tsx +10 -10
  32. package/Components/MasterCell/elementMapper.tsx +1 -2
  33. package/Components/MasterCell/utils/behaviorProvider.ts +82 -14
  34. package/Components/MasterCell/utils/index.ts +11 -5
  35. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +13 -18
  36. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +9 -0
  37. package/Components/OfflineHandler/__tests__/index.test.tsx +26 -35
  38. package/Components/PlayerContainer/ErrorDisplay/index.ts +1 -1
  39. package/Components/PlayerContainer/PlayerContainer.tsx +41 -28
  40. package/Components/PlayerContainer/ProgramInfo/index.tsx +1 -1
  41. package/Components/PlayerContainer/index.ts +1 -1
  42. package/Components/River/ComponentsMap/ComponentsMap.tsx +0 -1
  43. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +378 -0
  44. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +2 -2
  45. package/Components/River/RefreshControl.tsx +11 -17
  46. package/Components/River/TV/River.tsx +2 -17
  47. package/Components/River/TV/index.tsx +3 -1
  48. package/Components/River/TV/withPipesV1DataLoader.tsx +43 -0
  49. package/Components/River/TV/withRiverDataLoader.tsx +17 -0
  50. package/Components/River/TV/withTVEventHandler.tsx +1 -1
  51. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -0
  52. package/Components/River/__tests__/river.test.js +12 -26
  53. package/Components/River/index.tsx +1 -1
  54. package/Components/Screen/__tests__/Screen.test.tsx +28 -29
  55. package/Components/ScreenRevealManager/ScreenRevealManager.ts +76 -0
  56. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +107 -0
  57. package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +96 -0
  58. package/Components/ScreenRevealManager/index.ts +1 -0
  59. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +79 -0
  60. package/Components/Tabs/TV/Tabs.android.tsx +0 -2
  61. package/Components/Tabs/Tabs.tsx +2 -3
  62. package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +34 -0
  63. package/Components/Touchable/__tests__/touchable.test.tsx +12 -17
  64. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +15 -9
  65. package/Components/VideoLive/animationUtils.ts +3 -3
  66. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +3 -9
  67. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +32 -8
  68. package/Components/VideoModal/PlayerDetails.tsx +24 -2
  69. package/Components/VideoModal/PlayerWrapper.tsx +26 -142
  70. package/Components/VideoModal/VideoModal.tsx +3 -17
  71. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -5
  72. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -7
  73. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +44 -240
  74. package/Components/VideoModal/hooks/index.ts +0 -2
  75. package/Components/VideoModal/hooks/useModalSize.ts +18 -2
  76. package/Components/VideoModal/utils.ts +6 -0
  77. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -16
  78. package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +84 -24
  79. package/Contexts/ConfigutaionContext/__tests__/ConfigurationProvider.test.tsx +3 -3
  80. package/Contexts/ScreenContext/index.tsx +46 -6
  81. package/Decorators/ConfigurationWrapper/__tests__/withConfigurationProvider.test.tsx +3 -3
  82. package/Decorators/ConfigurationWrapper/withConfigurationProvider.tsx +2 -2
  83. package/Decorators/RiverFeedLoader/__tests__/__snapshots__/riverFeedLoader.test.tsx.snap +221 -209
  84. package/Decorators/RiverFeedLoader/__tests__/riverFeedLoader.test.tsx +14 -16
  85. package/Decorators/RiverFeedLoader/__tests__/utils.test.ts +0 -20
  86. package/Decorators/RiverFeedLoader/index.tsx +22 -4
  87. package/Decorators/RiverFeedLoader/utils/index.ts +0 -18
  88. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +3 -6
  89. package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -0
  90. package/Decorators/ZappPipesDataConnector/__tests__/NullFeedResolver.test.tsx +78 -0
  91. package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +205 -0
  92. package/Decorators/ZappPipesDataConnector/__tests__/StaticFeedResolver.test.tsx +251 -0
  93. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +368 -0
  94. package/Decorators/ZappPipesDataConnector/__tests__/utils.test.ts +39 -0
  95. package/Decorators/ZappPipesDataConnector/index.tsx +26 -293
  96. package/Decorators/ZappPipesDataConnector/resolvers/NullFeedResolver.tsx +25 -0
  97. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +87 -0
  98. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +266 -0
  99. package/Decorators/ZappPipesDataConnector/types.ts +29 -0
  100. package/Decorators/ZappPipesDataConnector/utils/mongoFilter.ts +738 -0
  101. package/Decorators/ZappPipesDataConnector/utils/useFilter.tsx +157 -0
  102. package/events/index.ts +1 -0
  103. package/package.json +5 -10
  104. package/Components/River/__tests__/__snapshots__/river.test.js.snap +0 -27
  105. package/Components/VideoModal/hooks/useBackgroundColor.ts +0 -10
@@ -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);
@@ -1,17 +1,16 @@
1
1
  import { all, equals, path, prop, isEmpty, pluck, values } from "ramda";
2
2
 
3
3
  import { useEffect, useMemo } from "react";
4
- import { useDispatch } from "react-redux";
5
4
 
6
5
  import {
7
6
  useLayoutPresets,
8
- useZappPipesFeeds,
9
- } from "@applicaster/zapp-react-native-redux/hooks";
10
- import { loadPipesData } from "@applicaster/zapp-react-native-redux/ZappPipes";
7
+ useZappPipesFeed,
8
+ } from "@applicaster/zapp-react-native-redux";
11
9
  import { isEmptyOrNil } from "@applicaster/zapp-react-native-utils/cellUtils";
12
10
  import { Categories } from "./logger";
13
11
  import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
14
12
  import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute";
13
+
15
14
  import {
16
15
  ZappPipesEntryContext,
17
16
  ZappPipesScreenContext,
@@ -24,9 +23,13 @@ import {
24
23
  } from "@applicaster/zapp-react-native-utils/reactHooks/feed/useInflatedUrl";
25
24
 
26
25
  import { produce } from "immer";
26
+ import { useLoadPipesDataDispatch } from "@applicaster/zapp-react-native-utils/reactHooks";
27
27
  // types reference
28
28
 
29
- declare type CurationEntry = { preset_name: string; feed_url: string };
29
+ declare interface CurationEntry {
30
+ preset_name: string;
31
+ feed_url: string;
32
+ }
30
33
 
31
34
  type Feeds = Record<string, ZappPipesData>;
32
35
 
@@ -122,8 +125,6 @@ export const getFinalComponents = (
122
125
  export const useCurationAPI = (
123
126
  components: Array<ZappUIComponent>
124
127
  ): ZappUIComponent[] => {
125
- const dispatch = useDispatch();
126
-
127
128
  const smartComponents = useMemo(
128
129
  () => components?.filter?.(isSmartComponent) ?? [],
129
130
  [components]
@@ -159,19 +160,21 @@ export const useCurationAPI = (
159
160
 
160
161
  const urls = useMemo<string[]>(() => Object.values(urlsMap), [urlsMap]);
161
162
 
163
+ const loadPipesDataDispatcher = useLoadPipesDataDispatch();
164
+
162
165
  useEffect(() => {
163
166
  urls.forEach((url, index) => {
164
167
  if (url) {
165
- dispatch(loadPipesData(url, { clearCache: false }));
168
+ loadPipesDataDispatcher(url, { clearCache: false });
166
169
  } else {
167
170
  logger.log_error("Curation url is empty", {
168
171
  componentId: smartComponents?.[index]?.id,
169
172
  });
170
173
  }
171
174
  });
172
- }, [urls]);
175
+ }, [urls, loadPipesDataDispatcher]);
173
176
 
174
- const feeds = useZappPipesFeeds(urls);
177
+ const feeds = useZappPipesFeed(urls);
175
178
  const layoutPresets = useLayoutPresets();
176
179
 
177
180
  const enrichedComponents = useMemo(() => {
@@ -7,12 +7,15 @@ import {
7
7
  import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
8
8
  import {
9
9
  useDimensions,
10
+ useIsTablet as isTablet,
10
11
  useNavigation,
11
12
  } from "@applicaster/zapp-react-native-utils/reactHooks";
12
13
 
13
14
  import { BufferAnimation } from "../PlayerContainer/BufferAnimation";
14
15
  import { PlayerContainer } from "../PlayerContainer";
15
16
  import { useModalSize } from "../VideoModal/hooks";
17
+ import { ViewStyle } from "react-native";
18
+ import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
16
19
 
17
20
  type Props = {
18
21
  item: ZappEntry;
@@ -83,6 +86,13 @@ type PlayableComponent = {
83
86
  Component: React.ComponentType<any>;
84
87
  };
85
88
 
89
+ const dimensionsContext: "window" | "screen" = platformSelect({
90
+ android_tv: "window",
91
+ amazon: "window",
92
+ // eslint-disable-next-line react-hooks/rules-of-hooks
93
+ default: isTablet() ? "window" : "screen", // on tablet, window represents correct values, on phone it's not as the screen could be rotated
94
+ });
95
+
86
96
  export function HandlePlayable({
87
97
  item,
88
98
  isModal,
@@ -135,19 +145,25 @@ export function HandlePlayable({
135
145
  });
136
146
  }, [casting]);
137
147
 
138
- const { width: screenWidth, height: screenHeight } = useDimensions("window");
148
+ const { width: screenWidth, height: screenHeight } =
149
+ useDimensions(dimensionsContext);
139
150
 
140
151
  const modalSize = useModalSize();
141
152
 
142
153
  const style = React.useMemo(
143
- () => ({
144
- width: isModal ? modalSize.width : mode === "PIP" ? "100%" : screenWidth,
145
- height: isModal
146
- ? modalSize.height
147
- : mode === "PIP"
148
- ? "100%"
149
- : screenHeight,
150
- }),
154
+ () =>
155
+ ({
156
+ width: isModal
157
+ ? modalSize.width
158
+ : mode === "PIP"
159
+ ? "100%"
160
+ : screenWidth,
161
+ height: isModal
162
+ ? modalSize.height
163
+ : mode === "PIP"
164
+ ? "100%"
165
+ : screenHeight,
166
+ }) as ViewStyle,
151
167
  [screenWidth, screenHeight, modalSize, isModal, mode]
152
168
  );
153
169
 
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks/usePickFromState";
2
+ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
3
3
  import { getBackgroundImageUrl } from "../utils";
4
4
  import { useTheme } from "@applicaster/zapp-react-native-utils/theme";
5
5
 
@@ -7,7 +7,6 @@ import { NavigationContext } from "@applicaster/zapp-react-native-ui-components/
7
7
  import configureStore from "redux-mock-store";
8
8
  import Layout from "../index.web";
9
9
 
10
- // mock useTheme to provide app_background_color
11
10
  jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
12
11
  useTheme: () => ({
13
12
  app_background_color: "#000000",
@@ -23,6 +23,7 @@ type Props = {
23
23
  style: ViewStyle;
24
24
  testID?: string;
25
25
  accessibilityLabel?: string;
26
+ accessibilityHint?: string;
26
27
  cellUUID?: string;
27
28
  extraProps?: Record<string, any>;
28
29
  };
@@ -98,6 +99,7 @@ export function ActionButton(props: Props) {
98
99
  onPress={onPress}
99
100
  testID={props?.testID || `${item?.id}`}
100
101
  accessibilityLabel={props?.accessibilityLabel || `${item?.id}`}
102
+ accessibilityHint={props?.accessibilityHint}
101
103
  accessible={!!(props?.testID || props?.accessibilityLabel)}
102
104
  style={props?.style}
103
105
  >
@@ -4,7 +4,7 @@ import * as R from "ramda";
4
4
  import { TouchableOpacity } from "react-native";
5
5
  // import { SvgUri } from "react-native-svg";
6
6
 
7
- import { connectToStore } from "@applicaster/zapp-react-native-redux";
7
+ import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
8
8
  import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
9
9
 
10
10
  import Image from "./Image";
@@ -2,7 +2,6 @@ import React, { useMemo } from "react";
2
2
  import { ImageStyle } from "react-native";
3
3
  import { Focusable } from "@applicaster/zapp-react-native-ui-components/Components/Focusable";
4
4
  import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
5
- import * as R from "ramda";
6
5
  import { getXray } from "@applicaster/zapp-react-native-utils/logger";
7
6
  import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
8
7
  import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
@@ -67,32 +66,10 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
67
66
  const handleFocus = (focusable) => {
68
67
  const focusedButtonId = getFocusedButtonId(focusable);
69
68
 
70
- wrapperRef?.current?.measure((x, y, width, height, pageX, pageY) => {
71
- const top = pageY;
72
- const bottom = top + height;
73
- const left = pageX;
74
- const right = left + width;
75
-
76
- const boundingRect = {
77
- x,
78
- y,
79
- pageX,
80
- pageY,
81
- width,
82
- height,
83
- top,
84
- bottom,
85
- left,
86
- right,
87
- };
88
-
89
- otherProps?.onToggleFocus?.({
90
- focusable: {
91
- getRect: R.always(boundingRect),
92
- },
93
- focusedButtonId,
94
- mouse: focusable.mouse,
95
- });
69
+ otherProps?.onToggleFocus?.({
70
+ focusable: wrapperRef.current,
71
+ focusedButtonId,
72
+ mouse: focusable.mouse,
96
73
  });
97
74
 
98
75
  if (ttsLabel) {
@@ -20,7 +20,7 @@ const withAppliedDimensions = (style: Style) => (source: Source) => ({
20
20
  });
21
21
 
22
22
  export const withDimensionsHOC = (Component) => {
23
- return function WithDimensions(props: { style: any }) {
23
+ return function WithDimensions(props: Record<string, unknown>) {
24
24
  const theme = useTheme<BaseThemePropertiesMobile>();
25
25
 
26
26
  const useDownScalingImages = toBooleanWithDefaultFalse(
@@ -13,7 +13,7 @@ export const ImageContainer = (props: Props) => {
13
13
  const isActive = useIsScreenActive();
14
14
 
15
15
  const Component =
16
- isVideoPreviewEnabled(props) && isActive ? LiveImage : PureImage;
16
+ isVideoPreviewEnabled(props as Props) && isActive ? LiveImage : PureImage;
17
17
 
18
18
  return <Component {...props} />;
19
19
  };
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import TestRenderer from "react-test-renderer";
2
+ import { render } from "@testing-library/react-native";
3
3
  import { Image } from "react-native";
4
4
 
5
5
  jest.mock("@applicaster/zapp-react-native-utils/theme", () => ({
@@ -10,35 +10,35 @@ const CustomImage = require("../Image").default;
10
10
 
11
11
  describe("image with no source", () => {
12
12
  it("Uses provided placeholder image string", () => {
13
- const testRenderer = TestRenderer.create(
13
+ const { UNSAFE_getByType } = render(
14
14
  <CustomImage placeholderImage={"foo"} />
15
15
  );
16
16
 
17
- const testInstance = testRenderer.root;
17
+ const imageComponent = UNSAFE_getByType(Image);
18
18
 
19
- expect(testInstance.findByType(Image).props.source).toEqual({
19
+ expect(imageComponent.props.source).toEqual({
20
20
  uri: "foo",
21
21
  });
22
22
  });
23
23
 
24
24
  it("Uses provided placeholder image object", () => {
25
- const testRenderer = TestRenderer.create(
25
+ const { UNSAFE_getByType } = render(
26
26
  <CustomImage placeholderImage={"foo"} />
27
27
  );
28
28
 
29
- const testInstance = testRenderer.root;
29
+ const imageComponent = UNSAFE_getByType(Image);
30
30
 
31
- expect(testInstance.findByType(Image).props.source).toEqual({
31
+ expect(imageComponent.props.source).toEqual({
32
32
  uri: "foo",
33
33
  });
34
34
  });
35
35
 
36
36
  it("Returns empty string if no image or placeholder defined", () => {
37
- const testRenderer = TestRenderer.create(
37
+ const { UNSAFE_getByType } = render(
38
38
  <CustomImage placeholderImage={null} />
39
39
  );
40
40
 
41
- const testInstance = testRenderer.root;
42
- expect(testInstance.findByType(Image).props.source).toBeUndefined();
41
+ const imageComponent = UNSAFE_getByType(Image);
42
+ expect(imageComponent.props.source).toBeUndefined();
43
43
  });
44
44
  });
@@ -1,8 +1,6 @@
1
1
  import React from "react";
2
2
  import RN from "react-native";
3
- import { Provider } from "react-redux";
4
- import TestRenderer from "react-test-renderer";
5
- import configureStoreFn from "redux-mock-store";
3
+ import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
6
4
 
7
5
  const mockUseIsRTL = jest.fn(() => true);
8
6
  const mockGetIsRTL = jest.fn(() => true);
@@ -17,7 +15,6 @@ jest.mock("@applicaster/zapp-react-native-utils/localizationUtils", () => ({
17
15
  }));
18
16
 
19
17
  const CustomText = require("../Text").default;
20
- const mockStore = configureStoreFn();
21
18
 
22
19
  const defaultProps = {
23
20
  entry: {},
@@ -25,16 +22,15 @@ const defaultProps = {
25
22
  transformText: "default",
26
23
  };
27
24
 
28
- const getRenderedText = (label: string, store: any) => {
25
+ const getRenderedText = (label: string, storeConfig: any) => {
29
26
  const props = { ...{ ...defaultProps, label } };
30
27
 
31
- const testRenderer = TestRenderer.create(
32
- <Provider store={store}>
33
- <CustomText {...props} />
34
- </Provider>
28
+ const { UNSAFE_getByType } = renderWithProviders(
29
+ <CustomText {...props} />,
30
+ storeConfig
35
31
  );
36
32
 
37
- return testRenderer.root.findByType(RN.Text).props.children;
33
+ return UNSAFE_getByType(RN.Text).props.children;
38
34
  };
39
35
 
40
36
  describe("RTL app: Hebrew text contains english word", () => {
@@ -42,28 +38,32 @@ describe("RTL app: Hebrew text contains english word", () => {
42
38
  const textWithNotFirstEnglishWord = "השיר של נועה נועה קירל באירוויזיון Word";
43
39
  const textWithoutEnglishWord = "השיר של נועה נועה קירל באירוויזיון";
44
40
 
45
- const store = mockStore({
41
+ const storeConfig = {
46
42
  remoteConfigurations: { localizations: { he: {} } },
47
43
  appData: {
48
44
  languageCode: "he",
49
45
  countryCode: "IL",
50
46
  },
51
- });
47
+ };
52
48
 
53
49
  it("Hebrew text contains first english word", () => {
54
- const renderedText = getRenderedText(textWithFirstEnglishWord, store);
50
+ const renderedText = getRenderedText(textWithFirstEnglishWord, storeConfig);
55
51
  const desiredText = "\u200fWord\u202c השיר של נועה נועה קירל באירוויזיון";
56
52
 
57
53
  expect(renderedText).toEqual(desiredText);
58
54
  });
59
55
 
60
56
  it("Hebrew text contains not first english word", () => {
61
- const renderedText = getRenderedText(textWithNotFirstEnglishWord, store);
57
+ const renderedText = getRenderedText(
58
+ textWithNotFirstEnglishWord,
59
+ storeConfig
60
+ );
61
+
62
62
  expect(renderedText).toEqual(textWithNotFirstEnglishWord);
63
63
  });
64
64
 
65
65
  it("Hebrew text doesn't contain english word", () => {
66
- const renderedText = getRenderedText(textWithoutEnglishWord, store);
66
+ const renderedText = getRenderedText(textWithoutEnglishWord, storeConfig);
67
67
  expect(renderedText).toEqual(textWithoutEnglishWord);
68
68
  });
69
69
  });
@@ -77,16 +77,16 @@ describe("LTR app: English text", () => {
77
77
 
78
78
  const englishText = "Test sentence";
79
79
 
80
- const store = mockStore({
80
+ const storeConfig = {
81
81
  remoteConfigurations: { localizations: { en: {} } },
82
82
  appData: {
83
83
  languageCode: "en",
84
84
  countryCode: "US",
85
85
  },
86
- });
86
+ };
87
87
 
88
88
  it("English text", () => {
89
- const renderedText = getRenderedText(englishText, store);
89
+ const renderedText = getRenderedText(englishText, storeConfig);
90
90
  expect(renderedText).toEqual(englishText);
91
91
  });
92
92
  });
@@ -1,12 +1,12 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
- import ReactTestRenderer from "react-test-renderer";
3
+ import { render } from "@testing-library/react-native";
4
4
 
5
5
  import { CollapsibleTextContainer } from "../CollapsibleTextContainer";
6
6
 
7
7
  describe("CollapsibleTextContainer", () => {
8
8
  it("render container+children when label is presented", () => {
9
- const renderer = ReactTestRenderer.create(
9
+ const { toJSON } = render(
10
10
  <CollapsibleTextContainer
11
11
  backgroundColor="#000000"
12
12
  label={"label"}
@@ -16,36 +16,36 @@ describe("CollapsibleTextContainer", () => {
16
16
  </CollapsibleTextContainer>
17
17
  );
18
18
 
19
- const result = renderer.toJSON();
19
+ const result = toJSON();
20
20
 
21
21
  expect(result).not.toBeNull();
22
- expect(renderer.toJSON()).toMatchSnapshot();
22
+ expect(toJSON()).toMatchSnapshot();
23
23
  });
24
24
 
25
25
  it("render nothing when label is empty", () => {
26
- const renderer = ReactTestRenderer.create(
26
+ const { toJSON } = render(
27
27
  <CollapsibleTextContainer backgroundColor="#000000" label={""} style={{}}>
28
28
  <View />
29
29
  </CollapsibleTextContainer>
30
30
  );
31
31
 
32
- const result = renderer.toJSON();
32
+ const result = toJSON();
33
33
  expect(result).toBeNull();
34
34
  });
35
35
 
36
36
  it("render nothing when label is not passed", () => {
37
- const renderer = ReactTestRenderer.create(
37
+ const { toJSON } = render(
38
38
  <CollapsibleTextContainer backgroundColor="#000000" label={""} style={{}}>
39
39
  <View />
40
40
  </CollapsibleTextContainer>
41
41
  );
42
42
 
43
- const result = renderer.toJSON();
43
+ const result = toJSON();
44
44
  expect(result).toBeNull();
45
45
  });
46
46
 
47
47
  it("render nothing when label is undefined", () => {
48
- const renderer = ReactTestRenderer.create(
48
+ const { toJSON } = render(
49
49
  <CollapsibleTextContainer
50
50
  backgroundColor="#000000"
51
51
  label={undefined}
@@ -55,7 +55,7 @@ describe("CollapsibleTextContainer", () => {
55
55
  </CollapsibleTextContainer>
56
56
  );
57
57
 
58
- const result = renderer.toJSON();
58
+ const result = toJSON();
59
59
  expect(result).toBeNull();
60
60
  });
61
61
  });
@@ -73,7 +73,6 @@ export function elementMapper(
73
73
  : {};
74
74
 
75
75
  const componentProps = {
76
- key,
77
76
  style,
78
77
  skipButtons: otherProps?.skipButtons,
79
78
  emitAsyncElementRegistrate: otherProps?.emitAsyncElementRegistrate,
@@ -91,7 +90,7 @@ export function elementMapper(
91
90
  const fn = mapElementWithKey(elementMapper(components, otherProps));
92
91
 
93
92
  return (
94
- <Component {...componentProps}>
93
+ <Component key={key} {...componentProps}>
95
94
  {focusableTypes.has(type) && elements.length > 0
96
95
  ? elements.map(fn)
97
96
  : null}