@applicaster/zapp-react-native-ui-components 14.0.0-alpha.4517121861 → 14.0.0-alpha.4520122433

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 (126) 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/Cell.tsx +91 -64
  6. package/Components/Cell/CellWithFocusable.tsx +3 -0
  7. package/Components/Cell/__tests__/CellWIthFocusable.test.js +3 -2
  8. package/Components/Cell/index.js +1 -1
  9. package/Components/ComponentResolver/index.ts +1 -1
  10. package/Components/FeedLoader/FeedLoader.tsx +7 -16
  11. package/Components/FeedLoader/FeedLoaderHOC.tsx +21 -0
  12. package/Components/FeedLoader/index.js +2 -8
  13. package/Components/Focusable/Focusable.tsx +12 -3
  14. package/Components/Focusable/FocusableTvOS.tsx +5 -5
  15. package/Components/Focusable/FocusableiOS.tsx +2 -2
  16. package/Components/Focusable/Touchable.tsx +5 -3
  17. package/Components/Focusable/index.android.tsx +8 -4
  18. package/Components/Focusable/index.tsx +1 -1
  19. package/Components/FocusableGroup/FocusableTvOS.tsx +1 -1
  20. package/Components/FocusableList/FocusableItem.tsx +4 -3
  21. package/Components/FocusableList/FocusableListItemWrapper.tsx +2 -1
  22. package/Components/FocusableList/hooks/useCellState.android.ts +13 -3
  23. package/Components/FocusableList/index.tsx +20 -9
  24. package/Components/FreezeWithCallback/__tests__/index.test.tsx +67 -43
  25. package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +42 -59
  26. package/Components/GeneralContentScreen/utils/useCurationAPI.ts +13 -10
  27. package/Components/HandlePlayable/HandlePlayable.tsx +17 -10
  28. package/Components/Layout/TV/LayoutBackground.tsx +1 -1
  29. package/Components/Layout/TV/__tests__/index.test.tsx +0 -1
  30. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +6 -2
  31. package/Components/MasterCell/DefaultComponents/Button.tsx +1 -1
  32. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +4 -39
  33. package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +1 -1
  34. package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +1 -1
  35. package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +65 -17
  36. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/Image.test.tsx +21 -3
  37. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +6 -3
  38. package/Components/MasterCell/DefaultComponents/Text/index.tsx +26 -6
  39. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +10 -10
  40. package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +18 -18
  41. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/index.test.tsx +10 -10
  42. package/Components/MasterCell/elementMapper.tsx +1 -2
  43. package/Components/MasterCell/utils/behaviorProvider.ts +82 -14
  44. package/Components/MasterCell/utils/index.ts +11 -5
  45. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +13 -18
  46. package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +9 -0
  47. package/Components/OfflineHandler/__tests__/index.test.tsx +26 -35
  48. package/Components/PlayerContainer/ErrorDisplay/index.ts +1 -1
  49. package/Components/PlayerContainer/PlayerContainer.tsx +45 -29
  50. package/Components/PlayerContainer/ProgramInfo/index.tsx +1 -1
  51. package/Components/PlayerContainer/index.ts +1 -1
  52. package/Components/River/ComponentsMap/ComponentsMap.tsx +0 -1
  53. package/Components/River/ComponentsMap/hooks/__tests__/useLoadingState.test.ts +378 -0
  54. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +2 -2
  55. package/Components/River/RefreshControl.tsx +11 -17
  56. package/Components/River/TV/River.tsx +2 -17
  57. package/Components/River/TV/index.tsx +3 -1
  58. package/Components/River/TV/withPipesV1DataLoader.tsx +43 -0
  59. package/Components/River/TV/withRiverDataLoader.tsx +17 -0
  60. package/Components/River/TV/withTVEventHandler.tsx +1 -1
  61. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -0
  62. package/Components/River/__tests__/river.test.js +12 -26
  63. package/Components/River/index.tsx +1 -1
  64. package/Components/Screen/__tests__/Screen.test.tsx +28 -29
  65. package/Components/Screen/__tests__/navigationHandler.test.ts +133 -22
  66. package/Components/Screen/navigationHandler.ts +20 -2
  67. package/Components/ScreenRevealManager/ScreenRevealManager.ts +76 -0
  68. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +107 -0
  69. package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +96 -0
  70. package/Components/ScreenRevealManager/index.ts +1 -0
  71. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +79 -0
  72. package/Components/Tabs/TV/Tabs.android.tsx +1 -3
  73. package/Components/Tabs/Tabs.tsx +2 -3
  74. package/Components/TextInputTv/__tests__/__snapshots__/TextInputTv.test.js.snap +13 -0
  75. package/Components/TextInputTv/index.tsx +11 -0
  76. package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +34 -0
  77. package/Components/Touchable/__tests__/touchable.test.tsx +12 -17
  78. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +15 -9
  79. package/Components/VideoLive/animationUtils.ts +3 -3
  80. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +3 -9
  81. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.web.tsx +294 -0
  82. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.web.tsx +93 -0
  83. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +73 -29
  84. package/Components/VideoModal/PlayerDetails.tsx +24 -2
  85. package/Components/VideoModal/PlayerWrapper.tsx +26 -142
  86. package/Components/VideoModal/VideoModal.tsx +3 -17
  87. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -5
  88. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -7
  89. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +44 -240
  90. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +9 -1
  91. package/Components/VideoModal/hooks/index.ts +0 -2
  92. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +40 -15
  93. package/Components/VideoModal/hooks/useModalSize.ts +18 -2
  94. package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +2 -2
  95. package/Components/VideoModal/hooks/utils/index.ts +4 -0
  96. package/Components/VideoModal/utils.ts +6 -0
  97. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -16
  98. package/Components/Viewport/ViewportTracker/__tests__/viewportTracker.test.js +84 -24
  99. package/Contexts/CellFocusedStateContext/index.tsx +27 -0
  100. package/Contexts/ConfigutaionContext/__tests__/ConfigurationProvider.test.tsx +3 -3
  101. package/Contexts/ScreenContext/index.tsx +46 -6
  102. package/Decorators/ConfigurationWrapper/__tests__/withConfigurationProvider.test.tsx +3 -3
  103. package/Decorators/ConfigurationWrapper/withConfigurationProvider.tsx +2 -2
  104. package/Decorators/RiverFeedLoader/__tests__/__snapshots__/riverFeedLoader.test.tsx.snap +221 -209
  105. package/Decorators/RiverFeedLoader/__tests__/riverFeedLoader.test.tsx +14 -16
  106. package/Decorators/RiverFeedLoader/__tests__/utils.test.ts +0 -20
  107. package/Decorators/RiverFeedLoader/index.tsx +22 -4
  108. package/Decorators/RiverFeedLoader/utils/index.ts +0 -18
  109. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +3 -6
  110. package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -0
  111. package/Decorators/ZappPipesDataConnector/__tests__/NullFeedResolver.test.tsx +78 -0
  112. package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +205 -0
  113. package/Decorators/ZappPipesDataConnector/__tests__/StaticFeedResolver.test.tsx +251 -0
  114. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +368 -0
  115. package/Decorators/ZappPipesDataConnector/__tests__/utils.test.ts +39 -0
  116. package/Decorators/ZappPipesDataConnector/index.tsx +26 -293
  117. package/Decorators/ZappPipesDataConnector/resolvers/NullFeedResolver.tsx +25 -0
  118. package/Decorators/ZappPipesDataConnector/resolvers/StaticFeedResolver.tsx +87 -0
  119. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +266 -0
  120. package/Decorators/ZappPipesDataConnector/types.ts +29 -0
  121. package/Decorators/ZappPipesDataConnector/utils/mongoFilter.ts +738 -0
  122. package/Decorators/ZappPipesDataConnector/utils/useFilter.tsx +157 -0
  123. package/events/index.ts +3 -0
  124. package/package.json +5 -10
  125. package/Components/River/__tests__/__snapshots__/river.test.js.snap +0 -27
  126. package/Components/VideoModal/hooks/useBackgroundColor.ts +0 -10
@@ -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
  };
@@ -48,7 +49,9 @@ function getAssetValue(asset, flavour, fallbackAsset = null) {
48
49
  return asset.src || fallbackAsset;
49
50
  }
50
51
 
51
- export function ActionButton(props: Props) {
52
+ export const ActionButton = React.memo(function ActionButtonComponent(
53
+ props: Props
54
+ ) {
52
55
  const { item, action, asset, flavour = "flavour_1", cellUUID } = props;
53
56
  const actionContext = useActions(action?.identifier);
54
57
 
@@ -98,6 +101,7 @@ export function ActionButton(props: Props) {
98
101
  onPress={onPress}
99
102
  testID={props?.testID || `${item?.id}`}
100
103
  accessibilityLabel={props?.accessibilityLabel || `${item?.id}`}
104
+ accessibilityHint={props?.accessibilityHint}
101
105
  accessible={!!(props?.testID || props?.accessibilityLabel)}
102
106
  style={props?.style}
103
107
  >
@@ -118,4 +122,4 @@ export function ActionButton(props: Props) {
118
122
  )}
119
123
  </TouchableOpacity>
120
124
  );
121
- }
125
+ });
@@ -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,10 +2,8 @@ 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
- import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
9
7
 
10
8
  const { Logger } = getXray();
11
9
 
@@ -45,11 +43,6 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
45
43
 
46
44
  const actionContext = useActions(pluginIdentifier);
47
45
 
48
- const accessibilityManager = useAccessibilityManager({});
49
-
50
- const { ttsLabel = "" } =
51
- actionContext?.initialEntryState(item)?.getAccessibility?.(item) || {};
52
-
53
46
  const onPress = (event) => {
54
47
  event?.preventDefault?.();
55
48
 
@@ -67,39 +60,11 @@ export function FocusableView({ style, children, item, ...otherProps }: Props) {
67
60
  const handleFocus = (focusable) => {
68
61
  const focusedButtonId = getFocusedButtonId(focusable);
69
62
 
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
- });
63
+ otherProps?.onToggleFocus?.({
64
+ focusable: wrapperRef.current,
65
+ focusedButtonId,
66
+ mouse: focusable.mouse,
96
67
  });
97
-
98
- if (ttsLabel) {
99
- accessibilityManager.readText({
100
- text: ttsLabel,
101
- });
102
- }
103
68
  };
104
69
 
105
70
  const handleBlur = (_focusable, _direction) => {
@@ -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
  };
@@ -28,17 +28,10 @@ interface Props {
28
28
  onAsyncRender: () => void;
29
29
  }
30
30
 
31
- const SecondaryImageComponent = (props: Props) => {
32
- const {
33
- uri,
34
- style,
35
- displayMode,
36
- imageSizing,
37
- fitPosition,
38
- fixedHeight,
39
- fixedWidth,
40
- onAsyncRender,
41
- } = props;
31
+ /** Secondary Image Dynamic does not render until the image is loaded */
32
+ const SecondaryImageDynamic = (props: Props) => {
33
+ const { uri, style, displayMode, imageSizing, fitPosition, onAsyncRender } =
34
+ props;
42
35
 
43
36
  const imageDimension = useGetImageDimensions(
44
37
  uri,
@@ -46,13 +39,9 @@ const SecondaryImageComponent = (props: Props) => {
46
39
  isImageSizingFit(imageSizing) ? undefined : (style.height as number)
47
40
  );
48
41
 
49
- const containerHeight = isDisplayModeFixed(displayMode)
50
- ? fixedHeight
51
- : imageDimension?.height;
42
+ const containerHeight = imageDimension?.height;
52
43
 
53
- const containerWidth = isDisplayModeFixed(displayMode)
54
- ? fixedWidth
55
- : style?.width;
44
+ const containerWidth = style?.width;
56
45
 
57
46
  if (isNil(imageDimension?.aspectRatio)) {
58
47
  return null;
@@ -80,4 +69,63 @@ const SecondaryImageComponent = (props: Props) => {
80
69
  );
81
70
  };
82
71
 
72
+ /** Secondary Image Fixed does not render the image until the image is loaded, but keep container rendered */
73
+ const SecondaryImageFixed = (props: Props) => {
74
+ const {
75
+ uri,
76
+ style,
77
+ displayMode,
78
+ imageSizing,
79
+ fitPosition,
80
+ fixedHeight,
81
+ fixedWidth,
82
+ onAsyncRender,
83
+ } = props;
84
+
85
+ const imageDimension = useGetImageDimensions(
86
+ uri,
87
+ style.width as number,
88
+ isImageSizingFit(imageSizing) ? undefined : (style.height as number)
89
+ );
90
+
91
+ return (
92
+ <View style={style} onLayout={onAsyncRender}>
93
+ {isNil(imageDimension?.aspectRatio) ? null : (
94
+ <Image
95
+ {...props}
96
+ source={{ uri }}
97
+ style={{
98
+ ...getStyle({
99
+ imageSizing,
100
+ fitPosition,
101
+ displayMode,
102
+ imageDimension,
103
+ containerHeight: fixedHeight,
104
+ containerWidth: fixedWidth,
105
+ }),
106
+ borderRadius: style.borderRadius,
107
+ aspectRatio: imageDimension.aspectRatio,
108
+ }}
109
+ />
110
+ )}
111
+ </View>
112
+ );
113
+ };
114
+
115
+ const SecondaryImageComponent = (props: Props) => {
116
+ const { uri, displayMode } = props;
117
+
118
+ if (!uri) {
119
+ return null;
120
+ }
121
+
122
+ const isFixed = isDisplayModeFixed(displayMode);
123
+
124
+ return isFixed ? (
125
+ <SecondaryImageFixed {...props} />
126
+ ) : (
127
+ <SecondaryImageDynamic {...props} />
128
+ );
129
+ };
130
+
83
131
  export const SecondaryImage = withAsyncRenderHOC(SecondaryImageComponent);
@@ -4,9 +4,26 @@ import { render } from "@testing-library/react-native";
4
4
  import { SecondaryImage } from "../Image";
5
5
 
6
6
  describe("SecondaryImage - Image", () => {
7
- it("SecondaryImage should not render if no aspect ratio", async () => {
7
+ it("SecondaryImage should not render if no uri", async () => {
8
8
  const wrapper = await render(
9
- <SecondaryImage uri="" style={{ width: 100 }} />
9
+ <SecondaryImage
10
+ displayMode="dynamic"
11
+ uri={undefined}
12
+ style={{ width: 100 }}
13
+ />
14
+ );
15
+
16
+ expect(wrapper.toJSON()).toEqual(null);
17
+ expect(wrapper.toJSON()).toMatchSnapshot();
18
+ });
19
+
20
+ it("SecondaryImage should not render if no aspect ratio (dynamic)", async () => {
21
+ const wrapper = await render(
22
+ <SecondaryImage
23
+ displayMode="dynamic"
24
+ uri="someurl"
25
+ style={{ width: 100 }}
26
+ />
10
27
  );
11
28
 
12
29
  expect(wrapper.toJSON()).toEqual(null);
@@ -16,7 +33,8 @@ describe("SecondaryImage - Image", () => {
16
33
  it("SecondaryImage should render if known dimensions", async () => {
17
34
  const wrapper = await render(
18
35
  <SecondaryImage
19
- uri=""
36
+ uri="someUrl"
37
+ displayMode="dynamic"
20
38
  style={{ width: 100, height: 100, borderRadius: 10 }}
21
39
  />
22
40
  );
@@ -1,6 +1,8 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`SecondaryImage - Image SecondaryImage should not render if no aspect ratio 1`] = `null`;
3
+ exports[`SecondaryImage - Image SecondaryImage should not render if no aspect ratio (dynamic) 1`] = `null`;
4
+
5
+ exports[`SecondaryImage - Image SecondaryImage should not render if no uri 1`] = `null`;
4
6
 
5
7
  exports[`SecondaryImage - Image SecondaryImage should render if known dimensions 1`] = `
6
8
  <View
@@ -14,10 +16,11 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
14
16
  }
15
17
  >
16
18
  <Image
19
+ displayMode="dynamic"
17
20
  onAsyncRender={[Function]}
18
21
  source={
19
22
  {
20
- "uri": "",
23
+ "uri": "someUrl",
21
24
  }
22
25
  }
23
26
  style={
@@ -28,7 +31,7 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
28
31
  "width": 100,
29
32
  }
30
33
  }
31
- uri=""
34
+ uri="someUrl"
32
35
  />
33
36
  </View>
34
37
  `;
@@ -11,6 +11,8 @@ import { withScaledLineHeight } from "./utils";
11
11
  import { toNumber } from "@applicaster/zapp-react-native-utils/numberUtils";
12
12
  import { MeasurementPortalContext } from "../../../MeasurmentsPortal";
13
13
  import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
14
+ import { CellFocusedStateContext } from "@applicaster/zapp-react-native-ui-components/Contexts/CellFocusedStateContext";
15
+ import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
14
16
 
15
17
  type Props = {
16
18
  style: any;
@@ -35,10 +37,9 @@ const _Text = ({
35
37
  }: Props) => {
36
38
  const _label = useTextLabel({ label, entry });
37
39
  const isMeasurement = React.useContext(MeasurementPortalContext);
40
+ const cellFocused = React.useContext(CellFocusedStateContext);
38
41
 
39
- if (isNilOrEmpty(_label)) {
40
- return null;
41
- }
42
+ const accessibilityManager = useAccessibilityManager({});
42
43
 
43
44
  // set maximum possible height for the text in case of measurement
44
45
  const height =
@@ -46,6 +47,27 @@ const _Text = ({
46
47
  ? toNumber(otherProps.numberOfLines) * toNumber(style.lineHeight)
47
48
  : undefined;
48
49
 
50
+ const textLabel = dateTransformEnabled
51
+ ? dateFormat(dateTransform, label)
52
+ : textTransform(transformText, _label);
53
+
54
+ React.useLayoutEffect(() => {
55
+ // For FocusableCells with action buttons
56
+ if (otherProps.state) {
57
+ if (otherProps.state === "focused" && cellFocused === true) {
58
+ accessibilityManager.addHeading(textLabel);
59
+ }
60
+ } else {
61
+ if (cellFocused === true) {
62
+ accessibilityManager.addHeading(textLabel);
63
+ }
64
+ }
65
+ }, [cellFocused, otherProps.state, textLabel]);
66
+
67
+ if (isNilOrEmpty(_label)) {
68
+ return null;
69
+ }
70
+
49
71
  return (
50
72
  <Text
51
73
  style={[
@@ -55,9 +77,7 @@ const _Text = ({
55
77
  allowFontScaling={false}
56
78
  {...withoutLabel(otherProps)}
57
79
  >
58
- {dateTransformEnabled
59
- ? dateFormat(dateTransform, label)
60
- : textTransform(transformText, _label)}
80
+ {textLabel}
61
81
  </Text>
62
82
  );
63
83
  };
@@ -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}