@applicaster/zapp-react-native-ui-components 16.0.0-alpha.1042942411 → 16.0.0-alpha.1054344748

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 (112) hide show
  1. package/Components/AudioPlayer/tv/__tests__/audioPlayer.test.js +19 -0
  2. package/Components/AudioPlayer/tv/__tests__/index.test.tsx +120 -0
  3. package/Components/AudioPlayer/tv/index.tsx +5 -1
  4. package/Components/Cell/Cell.tsx +3 -6
  5. package/Components/Cell/TvOSCellComponent.tsx +0 -1
  6. package/Components/GeneralContentScreen/GeneralContentScreenHookAdapter.tsx +15 -0
  7. package/Components/GeneralContentScreen/hookAdapter/__tests__/skipExpression.test.ts +294 -0
  8. package/Components/GeneralContentScreen/hookAdapter/__tests__/validationHelper.test.ts +64 -0
  9. package/Components/GeneralContentScreen/hookAdapter/skipExpression.ts +252 -0
  10. package/Components/GeneralContentScreen/hookAdapter/validationHelper.ts +18 -0
  11. package/Components/LinkHandler/LinkHandler.tsx +2 -7
  12. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +64 -28
  13. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/ActionButtonController.tsx +19 -4
  14. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/__tests__/ActionButtonController.test.tsx +43 -1
  15. package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +46 -217
  16. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +109 -46
  17. package/Components/MasterCell/DefaultComponents/Button.tsx +44 -50
  18. package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +14 -13
  19. package/Components/MasterCell/DefaultComponents/Image/hoc/utils/__tests__/withDimensions.test.ts +420 -125
  20. package/Components/MasterCell/DefaultComponents/Image/hoc/utils/index.ts +114 -19
  21. package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +19 -8
  22. package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +2 -4
  23. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -3
  24. package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +50 -46
  25. package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +39 -47
  26. package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +6 -19
  27. package/Components/MasterCell/DefaultComponents/Text/index.tsx +15 -45
  28. package/Components/MasterCell/DefaultComponents/Toggle.tsx +36 -14
  29. package/Components/MasterCell/DefaultComponents/__tests__/Toggle.test.tsx +167 -0
  30. package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +67 -196
  31. package/Components/MasterCell/DefaultComponents/index.ts +0 -4
  32. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +6 -4
  33. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/factory.test.ts +32 -0
  34. package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +1 -2
  35. package/Components/MasterCell/elementMapper.tsx +0 -2
  36. package/Components/ModalComponent/ActionsBottomSheet/ActionButton.tsx +56 -0
  37. package/Components/ModalComponent/ActionsBottomSheet/__tests__/openActionsBottomSheet.test.ts +38 -0
  38. package/Components/ModalComponent/ActionsBottomSheet/boundActionButton.tsx +24 -0
  39. package/Components/ModalComponent/ActionsBottomSheet/index.ts +9 -0
  40. package/Components/ModalComponent/ActionsBottomSheet/openActionsBottomSheet.ts +61 -0
  41. package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +87 -97
  42. package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +87 -126
  43. package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +140 -83
  44. package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +252 -123
  45. package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +205 -0
  46. package/Components/ModalComponent/AudioPlayer/Components/__tests__/Item.test.tsx +113 -0
  47. package/Components/ModalComponent/AudioPlayer/Components/__tests__/NowPlayingHeaderSection.test.tsx +36 -0
  48. package/Components/ModalComponent/AudioPlayer/Components/index.ts +3 -3
  49. package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +356 -0
  50. package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +521 -0
  51. package/Components/ModalComponent/BottomSheetModalContent.tsx +498 -66
  52. package/Components/ModalComponent/Button/index.tsx +5 -3
  53. package/Components/ModalComponent/Header/CloseButton.tsx +12 -0
  54. package/Components/ModalComponent/Header/__tests__/CloseButton.test.tsx +72 -0
  55. package/Components/ModalComponent/Header/index.tsx +20 -7
  56. package/Components/ModalComponent/Header/utils.ts +1 -1
  57. package/Components/ModalComponent/ModalBlocksStyleContext.tsx +10 -0
  58. package/Components/ModalComponent/SortableList.tsx +156 -0
  59. package/Components/ModalComponent/SortableList.web.tsx +34 -0
  60. package/Components/ModalComponent/TextInputContent.tsx +135 -0
  61. package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +343 -0
  62. package/Components/ModalComponent/__tests__/SortableList.web.test.tsx +16 -0
  63. package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +169 -0
  64. package/Components/ModalComponent/__tests__/showTextInput.test.ts +95 -0
  65. package/Components/ModalComponent/index.tsx +18 -9
  66. package/Components/ModalComponent/presets/__tests__/getCell.test.ts +90 -0
  67. package/Components/ModalComponent/presets/dynamicCollectionCell.tsx +78 -0
  68. package/Components/ModalComponent/presets/index.ts +27 -0
  69. package/Components/ModalComponent/presets/selectableCell.tsx +28 -0
  70. package/Components/ModalComponent/presets/standardCell.tsx +41 -0
  71. package/Components/ModalComponent/presets/types.ts +35 -0
  72. package/Components/ModalComponent/showTextInput.ts +52 -0
  73. package/Components/ModalComponent/utils.ts +82 -21
  74. package/Components/OfflineHandler/__tests__/index.test.tsx +109 -0
  75. package/Components/OfflineHandler/hooks.ts +0 -12
  76. package/Components/OfflineHandler/index.tsx +42 -4
  77. package/Components/PlayerContainer/PlayerContainer.tsx +19 -8
  78. package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -4
  79. package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +66 -13
  80. package/Components/River/ComponentsMap/ComponentsMap.tsx +85 -59
  81. package/Components/River/River.tsx +4 -0
  82. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +138 -75
  83. package/Components/River/__tests__/componentsMap.test.js +8 -3
  84. package/Components/River/__tests__/resultCallback.test.tsx +47 -0
  85. package/Components/Screen/__tests__/Screen.test.tsx +24 -0
  86. package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -0
  87. package/Components/Screen/index.tsx +5 -0
  88. package/Components/Screen/navigationHandler.ts +8 -8
  89. package/Components/ScreenRevealManager/ScreenRevealManager.ts +18 -2
  90. package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +36 -0
  91. package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +56 -0
  92. package/Components/ScreenRevealManager/withScreenRevealManager.tsx +21 -4
  93. package/Components/Transitioner/AnimationManager.js +1 -1
  94. package/Components/Transitioner/Scene.tsx +4 -3
  95. package/Components/Transitioner/Transitioner.tsx +71 -33
  96. package/Components/Transitioner/__tests__/transitioner.test.js +372 -3
  97. package/Components/VideoLive/LiveImageManager.ts +9 -3
  98. package/Components/VideoLive/__tests__/LiveImageManager.test.ts +59 -0
  99. package/Contexts/ModalNavigationContext/__tests__/index.test.tsx +15 -0
  100. package/Contexts/ModalNavigationContext/index.tsx +2 -2
  101. package/Hooks/useEntryActionsExpander.ts +63 -0
  102. package/assets/empty-Info.png +0 -0
  103. package/package.json +6 -5
  104. package/Components/MasterCell/DefaultComponents/CellBadge/__tests__/__snapshots__/index.test.tsx.snap +0 -18
  105. package/Components/MasterCell/DefaultComponents/CellBadge/__tests__/index.test.tsx +0 -90
  106. package/Components/MasterCell/DefaultComponents/UIKitAdapters/Badge.tsx +0 -49
  107. package/Components/MasterCell/DefaultComponents/__tests__/ActionButton.test.tsx +0 -122
  108. package/Components/MasterCell/DefaultComponents/__tests__/Button.test.tsx +0 -186
  109. package/Components/MasterCell/DefaultComponents/__tests__/DynamicBadge.test.tsx +0 -156
  110. package/Components/MasterCell/DefaultComponents/__tests__/__snapshots__/ActionButton.test.tsx.snap +0 -60
  111. package/Components/ModalComponent/AudioPlayer/Components/Action.tsx +0 -332
  112. /package/Decorators/ZappPipesDataConnector/__tests__/{Hero.js → Hero.tsx} +0 -0
@@ -1,15 +1,85 @@
1
- import {
2
- toFiniteNumberWithDefault,
3
- toNumber,
4
- } from "@applicaster/zapp-react-native-utils/numberUtils";
1
+ import { toFiniteNumberWithDefault } from "@applicaster/zapp-react-native-utils/numberUtils";
5
2
  import { isNil } from "ramda";
3
+ import { coreLogger } from "@applicaster/zapp-react-native-utils/logger";
6
4
 
7
- const dimensionRegex = /\b(width|height)=(\d+)\b/gi;
5
+ const imageResizingLogger = coreLogger
6
+ ?.addSubsystem("components")
7
+ ?.addSubsystem("ImageResizing");
8
8
 
9
+ const TEMPLATE_REGEX = /{{(width|height)}}/gi;
10
+ const UNRESOLVED_PLACEHOLDER_REGEX = /{{[^}]*}}?/;
11
+ const INVALID_PLACEHOLDER_EXTRACT_REGEX = /{{([^}]*)}}?/g;
12
+ const ALLOWED_PLACEHOLDERS = ["width", "height"];
13
+
14
+ /**
15
+ * Merges query-param string `paramsString` into `baseUrl`.
16
+ * Params from `paramsString` override any existing params with the same key.
17
+ */
18
+ export const mergeQueryParams = (
19
+ baseUrl: string,
20
+ paramsString: string
21
+ ): string => {
22
+ try {
23
+ const urlObj = new URL(baseUrl);
24
+ const newParams = new URLSearchParams(paramsString);
25
+
26
+ newParams.forEach((value, key) => {
27
+ urlObj.searchParams.set(key, value);
28
+ });
29
+
30
+ return urlObj.toString();
31
+ } catch {
32
+ // If URL parsing fails, return original
33
+ return baseUrl;
34
+ }
35
+ };
36
+
37
+ /**
38
+ * Extracts unresolved placeholder names from a param pair and logs a warning.
39
+ */
40
+ const logInvalidPlaceholders = (pair: string): void => {
41
+ const invalidNames: string[] = [];
42
+ let match: RegExpExecArray | null;
43
+
44
+ // Reset lastIndex before using the global regex
45
+ INVALID_PLACEHOLDER_EXTRACT_REGEX.lastIndex = 0;
46
+
47
+ while ((match = INVALID_PLACEHOLDER_EXTRACT_REGEX.exec(pair)) !== null) {
48
+ const name = match[1];
49
+
50
+ if (!ALLOWED_PLACEHOLDERS.includes(name?.toLowerCase())) {
51
+ invalidNames.push(name);
52
+ }
53
+ }
54
+
55
+ if (invalidNames.length > 0) {
56
+ imageResizingLogger?.warning({
57
+ message: `Image resizing: invalid placeholder(s) found: ${invalidNames.map((n) => `{{${n}}}`).join(", ")}. Allowed placeholders are: {{width}}, {{height}}. The param "${pair}" was ignored.`,
58
+ data: { pair, invalidNames, allowedPlaceholders: ALLOWED_PLACEHOLDERS },
59
+ });
60
+ }
61
+ };
62
+
63
+ /**
64
+ * Parses a dimension mapping template string (query param format) and injects
65
+ * the resolved width/height values into the given URL.
66
+ *
67
+ * The template uses `{{width}}` and `{{height}}` placeholders.
68
+ * It is treated as query-param key=value pairs (e.g. "w={{width}}&h={{height}}"
69
+ * or "size={{width}}x{{height}}").
70
+ *
71
+ * Resolved params are **merged** into the original URL – existing params with
72
+ * the same key are replaced; new ones are appended.
73
+ *
74
+ * Invalid mappings (containing unresolved placeholders like `{{heit}}` or
75
+ * malformed `{{heit}`) are silently dropped and logged as warnings.
76
+ * A leading `?` in the template is stripped.
77
+ */
9
78
  export const withDimensions = (
10
79
  url: Option<string>,
11
80
  width: Option<number | string>,
12
- height: Option<number | string>
81
+ height: Option<number | string>,
82
+ dimensionMappingTemplate?: Option<string>
13
83
  ) => {
14
84
  if (isNil(url)) {
15
85
  return url;
@@ -22,23 +92,48 @@ export const withDimensions = (
22
92
  const newWidth = Math.trunc(toFiniteNumberWithDefault(0, width));
23
93
  const newHeight = Math.trunc(toFiniteNumberWithDefault(0, height));
24
94
 
25
- return url.replace(dimensionRegex, (match, name, originalValue) => {
26
- if (name.toLocaleLowerCase() === "width" && newWidth > 0) {
27
- const originalWidth = toNumber(originalValue);
95
+ if (newWidth <= 0 && newHeight <= 0) {
96
+ return url;
97
+ }
98
+
99
+ // Strip leading `?` and whitespace from the template
100
+ const template = dimensionMappingTemplate?.trim()?.replace(/^\?/, "");
28
101
 
29
- if (originalWidth > 0 && originalWidth > newWidth) {
30
- return `${name}=${newWidth}`;
31
- }
32
- }
102
+ if (!template) {
103
+ return url;
104
+ }
33
105
 
34
- if (name.toLocaleLowerCase() === "height" && newHeight > 0) {
35
- const originalHeight = toNumber(originalValue);
106
+ // Replace {{width}} / {{height}} placeholders in the template
107
+ const resolvedTemplate = template.replace(TEMPLATE_REGEX, (_match, name) => {
108
+ if (name.toLowerCase() === "width") {
109
+ return newWidth > 0 ? String(newWidth) : _match;
110
+ }
36
111
 
37
- if (originalHeight > 0 && originalHeight > newHeight) {
38
- return `${name}=${newHeight}`;
39
- }
112
+ if (name.toLowerCase() === "height") {
113
+ return newHeight > 0 ? String(newHeight) : _match;
40
114
  }
41
115
 
42
- return match;
116
+ return _match;
43
117
  });
118
+
119
+ // Filter out param pairs that still contain unresolved / malformed placeholders
120
+ const cleanedParams = resolvedTemplate
121
+ .split("&")
122
+ .filter((pair) => {
123
+ if (UNRESOLVED_PLACEHOLDER_REGEX.test(pair)) {
124
+ logInvalidPlaceholders(pair);
125
+
126
+ return false;
127
+ }
128
+
129
+ return true;
130
+ })
131
+ .join("&");
132
+
133
+ if (!cleanedParams) {
134
+ return url;
135
+ }
136
+
137
+ // Parse the resolved template as query params and merge into URL
138
+ return mergeQueryParams(url, cleanedParams);
44
139
  };
@@ -14,25 +14,36 @@ type Style = {
14
14
  height: Option<number | string>;
15
15
  };
16
16
 
17
- const withAppliedDimensions = (style: Style) => (source: Source) => ({
18
- ...source,
19
- uri: withDimensions(source?.uri, style?.width, style?.height),
20
- });
17
+ const withAppliedDimensions =
18
+ (style: Style, dimensionMappingTemplate: string) => (source: Source) => ({
19
+ ...source,
20
+ uri: withDimensions(
21
+ source?.uri,
22
+ style?.width,
23
+ style?.height,
24
+ dimensionMappingTemplate
25
+ ),
26
+ });
21
27
 
22
28
  export const withDimensionsHOC = (Component) => {
23
29
  return function WithDimensions(props: Record<string, unknown>) {
24
30
  const theme = useTheme<BaseThemePropertiesMobile>();
25
31
 
26
- const useDownScalingImages = toBooleanWithDefaultFalse(
27
- theme.use_downscaling_images
32
+ const useImageResizing = toBooleanWithDefaultFalse(
33
+ theme.use_image_resizing ?? theme.use_downscaling_images
28
34
  );
29
35
 
36
+ const dimensionMappingTemplate = theme.image_resizing_template;
37
+
30
38
  return (
31
39
  <Component
32
40
  {...props}
33
41
  withDimensions={
34
- useDownScalingImages
35
- ? withAppliedDimensions((props?.style || {}) as Style)
42
+ useImageResizing
43
+ ? withAppliedDimensions(
44
+ (props?.style || {}) as Style,
45
+ dimensionMappingTemplate
46
+ )
36
47
  : identity
37
48
  }
38
49
  />
@@ -1,5 +1,4 @@
1
- import { findPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
2
- import { appStore } from "@applicaster/zapp-react-native-redux/AppStore";
1
+ import { getPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
3
2
  import { loggerLiveImageManager } from "../../../VideoLive/loggerHelper";
4
3
 
5
4
  const { log_debug, log_error } = loggerLiveImageManager;
@@ -74,10 +73,9 @@ export async function executePreloadHooks({
74
73
  let payload: any = entry;
75
74
 
76
75
  let needsAbort = false;
77
- const plugins = appStore.get("plugins");
78
76
 
79
77
  for (const hookConfig of sortedHooks) {
80
- const plugin = findPluginByIdentifier(hookConfig.identifier, plugins, true);
78
+ const plugin = getPluginByIdentifier(hookConfig.identifier, true);
81
79
 
82
80
  if (!plugin?.module) {
83
81
  log_debug(
@@ -8,7 +8,7 @@ import Image from "../Image";
8
8
  import { useTrackCurrentAutoScrollingElement } from "@applicaster/zapp-react-native-utils/reactHooks/autoscrolling/useTrackCurrentAutoScrollingElement";
9
9
  import { useUIComponentContext } from "@applicaster/zapp-react-native-ui-components/Contexts/UIComponentContext";
10
10
  import { getPropComponentType } from "@applicaster/zapp-react-native-utils/cellUtils";
11
- import { findPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
11
+ import { getPluginByIdentifier } from "@applicaster/zapp-react-native-utils/pluginUtils";
12
12
  import { useAccessibilityState } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
13
13
 
14
14
  type LiveImageProps = {
@@ -249,9 +249,8 @@ const LiveImageComponent = (props: LiveImageProps) => {
249
249
  getPlayerConfig(player_screen_id, actionIdentifier) ?? {};
250
250
 
251
251
  const playableEntry = playerPluginId ? getPlayableEntry(item) : null;
252
- const plugins = appStore.get("plugins");
253
252
 
254
- const playerPlugin = findPluginByIdentifier(playerPluginId, plugins);
253
+ const playerPlugin = getPluginByIdentifier(playerPluginId);
255
254
 
256
255
  const isShouldRender =
257
256
  playerPlugin &&
@@ -1,16 +1,17 @@
1
1
  import * as React from "react";
2
2
  import { isNil } from "ramda";
3
- import { ViewStyle } from "react-native";
3
+ import { ImageStyle, View } from "react-native";
4
4
  import {
5
- SecondaryImage as UIKitSecondaryImage,
6
- UIKitSecondaryImageProps,
7
- } from "@applicaster/uikit";
5
+ FIT_POSITION,
6
+ IMAGE_SIZING_FILL,
7
+ IMAGE_SIZING_FIT,
8
+ } from "@applicaster/zapp-react-native-utils/manifestUtils/secondaryImage";
9
+ import { QBImage as Image } from "@applicaster/zapp-react-native-ui-components/Components/Image";
8
10
 
9
11
  import { useGetImageDimensions } from "./hooks";
10
12
  import {
11
13
  DisplayMode,
12
- FitPosition,
13
- ImageSizing,
14
+ getStyle,
14
15
  isDisplayModeFixed,
15
16
  isImageSizingFit,
16
17
  } from "./utils";
@@ -19,9 +20,9 @@ import { withAsyncRenderHOC } from "../../hoc/withAsyncRender";
19
20
  interface Props {
20
21
  displayMode: DisplayMode;
21
22
  uri: Nullable<string>;
22
- style: ViewStyle;
23
- imageSizing: ImageSizing;
24
- fitPosition: FitPosition;
23
+ style: ImageStyle;
24
+ imageSizing: typeof IMAGE_SIZING_FIT | typeof IMAGE_SIZING_FILL;
25
+ fitPosition: typeof FIT_POSITION;
25
26
  fixedWidth: number;
26
27
  fixedHeight: number;
27
28
  onAsyncRender?: () => void;
@@ -30,17 +31,8 @@ interface Props {
30
31
  /** Secondary Image Dynamic does not render until the image is loaded */
31
32
  const SecondaryImageDynamic = withAsyncRenderHOC(
32
33
  (props: Props & { onAsyncRender: () => void }) => {
33
- const {
34
- uri,
35
- style,
36
- displayMode,
37
- imageSizing,
38
- fitPosition,
39
- onAsyncRender,
40
- fixedHeight: _fixedHeight,
41
- fixedWidth: _fixedWidth,
42
- ...imageProps
43
- } = props;
34
+ const { uri, style, displayMode, imageSizing, fitPosition, onAsyncRender } =
35
+ props;
44
36
 
45
37
  const imageDimension = useGetImageDimensions(
46
38
  uri,
@@ -57,18 +49,24 @@ const SecondaryImageDynamic = withAsyncRenderHOC(
57
49
  }
58
50
 
59
51
  return (
60
- <UIKitSecondaryImage
61
- {...imageProps}
62
- uri={uri}
63
- style={style as UIKitSecondaryImageProps["style"]}
64
- displayMode={displayMode}
65
- imageSizing={imageSizing}
66
- fitPosition={fitPosition}
67
- width={containerWidth as number}
68
- height={containerHeight}
69
- imageDimension={imageDimension}
70
- onAsyncRender={onAsyncRender}
71
- />
52
+ <View style={style} onLayout={onAsyncRender}>
53
+ <Image
54
+ {...props}
55
+ source={{ uri }}
56
+ style={{
57
+ ...getStyle({
58
+ imageSizing,
59
+ fitPosition,
60
+ displayMode,
61
+ imageDimension,
62
+ containerHeight,
63
+ containerWidth,
64
+ }),
65
+ borderRadius: style.borderRadius,
66
+ aspectRatio: imageDimension.aspectRatio,
67
+ }}
68
+ />
69
+ </View>
72
70
  );
73
71
  }
74
72
  );
@@ -83,8 +81,6 @@ const SecondaryImageFixed = (props: Props) => {
83
81
  fitPosition,
84
82
  fixedHeight,
85
83
  fixedWidth,
86
- onAsyncRender: _onAsyncRender,
87
- ...imageProps
88
84
  } = props;
89
85
 
90
86
  const imageDimension = useGetImageDimensions(
@@ -94,18 +90,26 @@ const SecondaryImageFixed = (props: Props) => {
94
90
  );
95
91
 
96
92
  return (
97
- <UIKitSecondaryImage
98
- {...imageProps}
99
- uri={uri}
100
- style={style as UIKitSecondaryImageProps["style"]}
101
- displayMode={displayMode}
102
- imageSizing={imageSizing}
103
- fitPosition={fitPosition}
104
- width={fixedWidth}
105
- height={fixedHeight}
106
- imageDimension={imageDimension}
107
- testID="secondary-image-fixed"
108
- />
93
+ <View style={style}>
94
+ {isNil(imageDimension?.aspectRatio) ? null : (
95
+ <Image
96
+ {...props}
97
+ source={{ uri }}
98
+ style={{
99
+ ...getStyle({
100
+ imageSizing,
101
+ fitPosition,
102
+ displayMode,
103
+ imageDimension,
104
+ containerHeight: fixedHeight,
105
+ containerWidth: fixedWidth,
106
+ }),
107
+ borderRadius: style.borderRadius,
108
+ aspectRatio: imageDimension.aspectRatio,
109
+ }}
110
+ />
111
+ )}
112
+ </View>
109
113
  );
110
114
  };
111
115
 
@@ -3,21 +3,19 @@
3
3
  exports[`SecondaryImage - Image SecondaryImage fixed mode should not use async render props 1`] = `
4
4
  <View
5
5
  style={
6
- [
7
- {
8
- "borderRadius": 10,
9
- "height": 100,
10
- "width": 100,
11
- },
12
- {
13
- "height": 100,
14
- "width": 100,
15
- },
16
- ]
6
+ {
7
+ "borderRadius": 10,
8
+ "height": 100,
9
+ "width": 100,
10
+ }
17
11
  }
18
- testID="secondary-image-fixed"
19
12
  >
20
13
  <Image
14
+ displayMode="fixed"
15
+ fitPosition="center"
16
+ fixedHeight={100}
17
+ fixedWidth={100}
18
+ imageSizing="fill"
21
19
  source={
22
20
  {
23
21
  "uri": "someUrl",
@@ -31,6 +29,7 @@ exports[`SecondaryImage - Image SecondaryImage fixed mode should not use async r
31
29
  "width": 100,
32
30
  }
33
31
  }
32
+ uri="someUrl"
34
33
  />
35
34
  </View>
36
35
  `;
@@ -45,20 +44,20 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
45
44
  <View
46
45
  onLayout={[Function]}
47
46
  style={
48
- [
49
- {
50
- "borderRadius": 10,
51
- "height": 100,
52
- "width": 100,
53
- },
54
- {
55
- "height": 100,
56
- "width": 100,
57
- },
58
- ]
47
+ {
48
+ "borderRadius": 10,
49
+ "height": 100,
50
+ "width": 100,
51
+ }
59
52
  }
60
53
  >
61
54
  <Image
55
+ displayMode="dynamic"
56
+ fitPosition="center"
57
+ fixedHeight={0}
58
+ fixedWidth={0}
59
+ imageSizing="fill"
60
+ onAsyncRender={[Function]}
62
61
  source={
63
62
  {
64
63
  "uri": "someUrl",
@@ -72,6 +71,7 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
72
71
  "width": 100,
73
72
  }
74
73
  }
74
+ uri="someUrl"
75
75
  />
76
76
  </View>
77
77
  `;
@@ -79,21 +79,19 @@ exports[`SecondaryImage - Image SecondaryImage should render if known dimensions
79
79
  exports[`SecondaryImage - Image SecondaryImage should render in fixed mode with known dimensions 1`] = `
80
80
  <View
81
81
  style={
82
- [
83
- {
84
- "borderRadius": 10,
85
- "height": 100,
86
- "width": 100,
87
- },
88
- {
89
- "height": 100,
90
- "width": 100,
91
- },
92
- ]
82
+ {
83
+ "borderRadius": 10,
84
+ "height": 100,
85
+ "width": 100,
86
+ }
93
87
  }
94
- testID="secondary-image-fixed"
95
88
  >
96
89
  <Image
90
+ displayMode="fixed"
91
+ fitPosition="center"
92
+ fixedHeight={100}
93
+ fixedWidth={100}
94
+ imageSizing="fill"
97
95
  source={
98
96
  {
99
97
  "uri": "someUrl",
@@ -107,6 +105,7 @@ exports[`SecondaryImage - Image SecondaryImage should render in fixed mode with
107
105
  "width": 100,
108
106
  }
109
107
  }
108
+ uri="someUrl"
110
109
  />
111
110
  </View>
112
111
  `;
@@ -114,18 +113,11 @@ exports[`SecondaryImage - Image SecondaryImage should render in fixed mode with
114
113
  exports[`SecondaryImage - Image SecondaryImage should render in fixed mode without image until loaded 1`] = `
115
114
  <View
116
115
  style={
117
- [
118
- {
119
- "borderRadius": 5,
120
- "height": 100,
121
- "width": 100,
122
- },
123
- {
124
- "height": 100,
125
- "width": 100,
126
- },
127
- ]
116
+ {
117
+ "borderRadius": 5,
118
+ "height": 100,
119
+ "width": 100,
120
+ }
128
121
  }
129
- testID="secondary-image-fixed"
130
122
  />
131
123
  `;
@@ -1,30 +1,27 @@
1
1
  import { identity, isNil } from "ramda";
2
2
  import {
3
3
  POSITION_OVER_IMAGE,
4
+ DISPLAY_MODE_DYNAMIC,
4
5
  DISPLAY_MODE_FIXED,
5
6
  VISIBILITY_ALWAYS,
6
7
  VISIBILITY_DEFAULT,
7
8
  VISIBILITY_FOCUSED,
8
9
  IMAGE_POSITION,
9
10
  IMAGE_SIZING_FIT,
11
+ IMAGE_SIZING_FILL,
10
12
  FIT_POSITION,
11
13
  } from "@applicaster/zapp-react-native-utils/manifestUtils/secondaryImage";
12
14
  import { ImageStyle } from "react-native";
13
- import type {
14
- SecondaryImageDisplayMode,
15
- SecondaryImageFitPosition,
16
- SecondaryImageImageSizing,
17
- } from "@applicaster/uikit/lib/components/uikit/secondary-image/types";
18
15
 
19
16
  const SECONDARY_IMAGE_PREFIX = "secondary_image";
20
17
 
21
- export type ImageSizing = SecondaryImageImageSizing;
22
-
23
- export type FitPosition = SecondaryImageFitPosition;
18
+ type ImageSizing = typeof IMAGE_SIZING_FIT | typeof IMAGE_SIZING_FILL;
24
19
 
25
20
  type ImagePosition = (typeof IMAGE_POSITION)[keyof typeof IMAGE_POSITION];
26
21
 
27
- export type DisplayMode = SecondaryImageDisplayMode;
22
+ export type DisplayMode =
23
+ | typeof DISPLAY_MODE_FIXED
24
+ | typeof DISPLAY_MODE_DYNAMIC;
28
25
 
29
26
  export enum SecondaryImageStyleKeys {
30
27
  ENABLE = "switch",
@@ -177,16 +174,6 @@ export const getStyle = ({
177
174
  imageDimension,
178
175
  containerWidth,
179
176
  containerHeight,
180
- }: {
181
- imageSizing: ImageSizing;
182
- fitPosition: FitPosition;
183
- displayMode: DisplayMode;
184
- imageDimension: {
185
- width: number;
186
- height: number;
187
- };
188
- containerWidth: number;
189
- containerHeight: number;
190
177
  }): ImageStyle => {
191
178
  if (!isImageSizingFit(imageSizing)) {
192
179
  return {
@@ -1,9 +1,10 @@
1
1
  import * as React from "react";
2
+ import { Text } from "react-native";
3
+ import { omit } from "ramda";
2
4
  import {
3
5
  textTransform,
4
6
  dateFormat,
5
7
  } from "@applicaster/zapp-react-native-utils/cellUtils";
6
- import { Text as UIKitText } from "@applicaster/uikit/lib/components/uikit/text";
7
8
 
8
9
  import { useTextLabel, withFocusedStyles } from "./hooks";
9
10
  import { toNumber } from "@applicaster/zapp-react-native-utils/numberUtils";
@@ -19,18 +20,11 @@ type Props = {
19
20
  entry?: any;
20
21
  dateTransformEnabled: boolean;
21
22
  dateTransform: string;
22
- state?: string;
23
- focusedStyles?: any;
24
- normalStyles?: any;
25
- numberOfLines?: number;
26
- ellipsizeMode?: "head" | "middle" | "tail" | "clip";
27
- testID?: string;
28
- accessibilityLabel?: string;
29
- accessibilityHint?: string;
30
- nativeID?: string;
31
- selectable?: boolean;
23
+ [key: string]: any;
32
24
  };
33
25
 
26
+ const withoutLabel = omit(["label"]);
27
+
34
28
  const _Text = ({
35
29
  style,
36
30
  label,
@@ -38,16 +32,7 @@ const _Text = ({
38
32
  transformText = "default",
39
33
  dateTransformEnabled = false,
40
34
  dateTransform,
41
- state,
42
- focusedStyles,
43
- normalStyles,
44
- numberOfLines,
45
- ellipsizeMode,
46
- testID,
47
- accessibilityLabel,
48
- accessibilityHint,
49
- nativeID,
50
- selectable,
35
+ ...otherProps
51
36
  }: Props) => {
52
37
  const _label = useTextLabel({ label, entry });
53
38
  const isMeasurement = React.useContext(MeasurementPortalContext);
@@ -57,8 +42,8 @@ const _Text = ({
57
42
 
58
43
  // set maximum possible height for the text in case of measurement
59
44
  const height =
60
- isMeasurement && numberOfLines && style.lineHeight
61
- ? toNumber(numberOfLines) * toNumber(style.lineHeight)
45
+ isMeasurement && otherProps.numberOfLines && style.lineHeight
46
+ ? toNumber(otherProps.numberOfLines) * toNumber(style.lineHeight)
62
47
  : undefined;
63
48
 
64
49
  const textLabel = dateTransformEnabled
@@ -67,7 +52,7 @@ const _Text = ({
67
52
 
68
53
  React.useLayoutEffect(() => {
69
54
  if (cellFocused) {
70
- switch (state) {
55
+ switch (otherProps.state) {
71
56
  case "focused":
72
57
  accessibilityManager.addHeading(textLabel);
73
58
  break;
@@ -76,35 +61,20 @@ const _Text = ({
76
61
  break;
77
62
  }
78
63
  }
79
- }, [accessibilityManager, cellFocused, state, textLabel]);
64
+ }, [cellFocused, otherProps.state, textLabel]);
80
65
 
81
66
  if (isNilOrEmpty(_label)) {
82
67
  return null;
83
68
  }
84
69
 
85
70
  return (
86
- <UIKitText
87
- style={[
88
- withFocusedStyles({
89
- style,
90
- otherProps: {
91
- state,
92
- focusedStyles,
93
- normalStyles,
94
- },
95
- }),
96
- { height },
97
- ]}
98
- numberOfLines={numberOfLines}
99
- ellipsizeMode={ellipsizeMode}
100
- testID={testID}
101
- accessibilityLabel={accessibilityLabel}
102
- accessibilityHint={accessibilityHint}
103
- nativeID={nativeID}
104
- selectable={selectable}
71
+ <Text
72
+ style={[withFocusedStyles({ style, otherProps }), { height }]}
73
+ {...withoutLabel(otherProps)}
74
+ allowFontScaling={false}
105
75
  >
106
76
  {textLabel}
107
- </UIKitText>
77
+ </Text>
108
78
  );
109
79
  };
110
80