@applicaster/zapp-react-native-ui-components 15.0.0-alpha.5485312433 → 15.0.0-alpha.5531846549

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/GeneralContentScreen/GeneralContentScreen.tsx +39 -28
  2. package/Components/GeneralContentScreen/__tests__/GeneralContentScreen.test.tsx +104 -0
  3. package/Components/GeneralContentScreen/utils/__tests__/getScreenDataSource.test.ts +19 -0
  4. package/Components/GeneralContentScreen/utils/getScreenDataSource.ts +9 -0
  5. package/Components/HandlePlayable/HandlePlayable.tsx +16 -29
  6. package/Components/HandlePlayable/utils.ts +31 -0
  7. package/Components/HookRenderer/HookRenderer.tsx +40 -10
  8. package/Components/HookRenderer/__tests__/HookRenderer.test.tsx +60 -0
  9. package/Components/Layout/TV/NavBarContainer.tsx +1 -10
  10. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +7 -12
  11. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +7 -12
  12. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/model.test.ts +80 -0
  13. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +187 -0
  14. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/selectors.test.ts +45 -0
  15. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/style.test.ts +49 -0
  16. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/model.ts +47 -0
  17. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +170 -0
  18. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/selectors.ts +26 -0
  19. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/style.ts +29 -0
  20. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/types.ts +37 -0
  21. package/Components/MasterCell/DefaultComponents/Button.tsx +0 -15
  22. package/Components/MasterCell/DefaultComponents/LiveImage/__tests__/prepareEntry.test.ts +352 -0
  23. package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +136 -0
  24. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +33 -16
  25. package/Components/MasterCell/DefaultComponents/PressableView.tsx +261 -0
  26. package/Components/MasterCell/DefaultComponents/Text/index.tsx +2 -6
  27. package/Components/MasterCell/DefaultComponents/index.ts +2 -0
  28. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Asset.ts +42 -0
  29. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +127 -0
  30. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ButtonContainerView.ts +23 -0
  31. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +16 -0
  32. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabel.ts +67 -0
  33. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +32 -0
  34. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +195 -0
  35. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/builders.test.ts +140 -0
  36. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +222 -0
  37. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/helpers.ts +105 -0
  38. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +104 -0
  39. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +118 -0
  40. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +73 -0
  41. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/index.test.ts +86 -0
  42. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +35 -52
  43. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +35 -171
  44. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +36 -145
  45. package/Components/MasterCell/elementMapper.tsx +1 -0
  46. package/Components/PlayerContainer/PlayerContainer.tsx +1 -18
  47. package/Components/PreloaderWrapper/__tests__/index.test.tsx +26 -0
  48. package/Components/PreloaderWrapper/index.tsx +15 -0
  49. package/Components/River/ComponentsMap/ComponentsMap.tsx +18 -16
  50. package/Components/River/RefreshControl.tsx +19 -83
  51. package/Components/River/River.tsx +9 -82
  52. package/Components/River/RiverItem.tsx +26 -20
  53. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +2 -0
  54. package/Components/River/__tests__/componentsMap.test.js +38 -0
  55. package/Components/River/hooks/__tests__/usePullToRefresh.test.ts +132 -0
  56. package/Components/River/hooks/index.ts +1 -0
  57. package/Components/River/hooks/usePullToRefresh.ts +51 -0
  58. package/Components/Screen/__tests__/Screen.test.tsx +1 -0
  59. package/Components/Screen/hooks.ts +73 -3
  60. package/Components/Screen/index.tsx +7 -1
  61. package/Components/ScreenFeedLoader/ScreenFeedLoader.tsx +46 -0
  62. package/Components/ScreenFeedLoader/__tests__/ScreenFeedLoader.test.tsx +94 -0
  63. package/Components/ScreenFeedLoader/index.ts +1 -0
  64. package/Components/ScreenResolver/__tests__/screenResolver.test.js +24 -0
  65. package/Components/ScreenResolver/hooks/index.ts +3 -0
  66. package/Components/ScreenResolver/hooks/useGetComponent.ts +15 -0
  67. package/Components/ScreenResolver/hooks/useScreenComponentResolver.tsx +90 -0
  68. package/Components/ScreenResolver/index.tsx +15 -117
  69. package/Components/ScreenResolver/utils/__tests__/getScreenTypeProps.test.ts +45 -0
  70. package/Components/ScreenResolver/utils/getScreenTypeProps.ts +43 -0
  71. package/Components/ScreenResolver/utils/index.ts +1 -0
  72. package/Components/ScreenResolver/withDefaultScreenContext.tsx +16 -0
  73. package/Components/ScreenResolverFeedProvider/ScreenResolverFeedProvider.tsx +25 -0
  74. package/Components/ScreenResolverFeedProvider/__tests__/ScreenResolverFeedProvider.test.tsx +44 -0
  75. package/Components/ScreenResolverFeedProvider/index.ts +1 -0
  76. package/Components/Tabs/TabContent.tsx +7 -4
  77. package/Components/TopCutoffOverlay/hooks/__tests__/useMarginTop.test.ts +130 -0
  78. package/Components/TopCutoffOverlay/hooks/index.ts +1 -0
  79. package/Components/TopCutoffOverlay/hooks/useMarginTop.ts +59 -0
  80. package/Components/TopCutoffOverlay/index.tsx +55 -0
  81. package/Components/Transitioner/Scene.tsx +9 -15
  82. package/Components/VideoLive/LiveImageManager.ts +199 -54
  83. package/Components/VideoLive/PlayerLiveImageComponent.tsx +31 -33
  84. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +2 -17
  85. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +0 -2
  86. package/Components/Viewport/ViewportAware/index.tsx +16 -7
  87. package/Components/ZappUIComponent/index.tsx +12 -6
  88. package/Components/default-cell-renderer/viewTrees/mobile/index.ts +0 -3
  89. package/Components/index.js +1 -1
  90. package/Contexts/ScreenContext/__tests__/index.test.tsx +57 -0
  91. package/Contexts/ScreenContext/index.tsx +71 -19
  92. package/Contexts/ZappPipesContext/ZappPipesContextFactory.tsx +18 -7
  93. package/Decorators/ZappPipesDataConnector/ResolverSelector.tsx +25 -7
  94. package/Decorators/ZappPipesDataConnector/__tests__/ResolverSelector.test.tsx +212 -5
  95. package/Decorators/ZappPipesDataConnector/__tests__/UrlFeedResolver.test.tsx +39 -21
  96. package/Decorators/ZappPipesDataConnector/resolvers/UrlFeedResolver.tsx +18 -7
  97. package/events/index.ts +2 -0
  98. package/events/scrollEndReached.ts +15 -0
  99. package/package.json +5 -5
  100. package/Components/MasterCell/DefaultComponents/Text/utils/__tests__/withAdjustedLineHeight.test.ts +0 -46
  101. package/Components/MasterCell/DefaultComponents/Text/utils/index.ts +0 -21
  102. package/Components/PlayerContainer/ErrorDisplay/ErrorDisplay.tsx +0 -57
  103. package/Components/PlayerContainer/ErrorDisplay/index.ts +0 -9
  104. package/Components/PlayerContainer/useRestrictMobilePlayback.tsx +0 -101
  105. /package/Components/HookRenderer/{index.tsx → index.ts} +0 -0
@@ -0,0 +1,261 @@
1
+ import React, { useCallback, useEffect, useMemo, useState } from "react";
2
+ import { TouchableOpacity } from "react-native";
3
+
4
+ import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
5
+
6
+ import { masterCellLogger } from "../logger";
7
+ import {
8
+ buildLegacySelection,
9
+ resolveIsActive,
10
+ resolveLabelText,
11
+ } from "./mobile/MobileActionButtons/helpers";
12
+
13
+ type ChildElementProps = {
14
+ children?: React.ReactNode;
15
+ mobileActionRole?: string;
16
+ uri?: string;
17
+ state?: "default" | "focused";
18
+ };
19
+
20
+ type Props = {
21
+ children?: React.ReactNode;
22
+ item: ZappEntry | ZappFeed;
23
+ action?: {
24
+ identifier?: string;
25
+ flavour?: "flavour_1" | "flavour_2";
26
+ };
27
+ style?: Record<string, unknown>;
28
+ focusedStyles?: Record<string, unknown>;
29
+ testID?: string;
30
+ accessibilityLabel?: string;
31
+ accessibilityHint?: string;
32
+ };
33
+
34
+ const isValidElement = (
35
+ child: React.ReactNode
36
+ ): child is React.ReactElement<ChildElementProps> =>
37
+ React.isValidElement(child);
38
+
39
+ /** retrieves asset uri for a given flavour,
40
+ * if flavour is not provided, returns the default asset from `asset` or selected state asset (if available)
41
+ * asset can be:
42
+ * provided as asset path,
43
+ * provided as [default || flavour_1, alternative || flavour_2] array.
44
+ * mobileButtonAssets asset can be:
45
+ * provided as asset path,
46
+ * provided as [default || flavour_1, alternative || flavour_2] array,
47
+ * provided as [[] as flavour_1, [] as flavour_2] array for multiple flavours, where each flavour can be either a path or [default, alternative] array.
48
+ *
49
+ * isActive reflect the state of the action and can be used to render different asset for active/inactive state if asset is provided as array
50
+ *
51
+ * */
52
+ const selectByAssetFlavour = (
53
+ actionState: {
54
+ asset?: string | [string, string];
55
+ mobileButtonAssets?: [string, string] | [string, string][];
56
+ },
57
+ flavour?: "flavour_1" | "flavour_2",
58
+ isActive?: boolean
59
+ ) => {
60
+ if (actionState.mobileButtonAssets) {
61
+ if (flavour) {
62
+ if (flavour === "flavour_1") {
63
+ if (typeof actionState.mobileButtonAssets[0] === "string") {
64
+ return actionState.mobileButtonAssets[0];
65
+ }
66
+
67
+ if (Array.isArray(actionState.mobileButtonAssets[0])) {
68
+ return actionState.mobileButtonAssets[0][isActive ? 1 : 0];
69
+ }
70
+
71
+ return actionState.mobileButtonAssets[0];
72
+ } else if (flavour === "flavour_2") {
73
+ if (typeof actionState.mobileButtonAssets[1] === "string") {
74
+ return actionState.mobileButtonAssets[1];
75
+ }
76
+
77
+ if (Array.isArray(actionState.mobileButtonAssets[1])) {
78
+ return actionState.mobileButtonAssets[1][isActive ? 1 : 0];
79
+ }
80
+
81
+ return actionState.mobileButtonAssets[1];
82
+ }
83
+ }
84
+
85
+ return Array.isArray(actionState.mobileButtonAssets[0])
86
+ ? actionState.mobileButtonAssets[0][isActive ? 1 : 0]
87
+ : actionState.mobileButtonAssets[0];
88
+ } else {
89
+ return typeof actionState?.asset === "string"
90
+ ? actionState.asset
91
+ : actionState.asset[isActive ? 1 : 0];
92
+ }
93
+ };
94
+
95
+ export function PressableView({
96
+ children,
97
+ item,
98
+ action,
99
+ style = {},
100
+ focusedStyles = {},
101
+ testID,
102
+ accessibilityLabel,
103
+ accessibilityHint,
104
+ }: Props) {
105
+ const actionContext = useActions(action?.identifier);
106
+
107
+ const actionDisabled =
108
+ typeof actionContext?.isActionAvailable === "function" &&
109
+ !actionContext.isActionAvailable(item);
110
+
111
+ const supportsEntryState =
112
+ typeof actionContext?.initialEntryState === "function" && !actionDisabled;
113
+
114
+ const [actionState, setActionState] = useState(() =>
115
+ supportsEntryState ? actionContext.initialEntryState(item) : null
116
+ );
117
+
118
+ useEffect(() => {
119
+ if (supportsEntryState) {
120
+ setActionState(actionContext.initialEntryState(item));
121
+ }
122
+ }, [supportsEntryState, item, actionContext]);
123
+
124
+ useEffect(() => {
125
+ if (typeof actionContext?.addListener === "function") {
126
+ return actionContext.addListener(String(item?.id), (nextState) => {
127
+ setActionState(nextState);
128
+ });
129
+ }
130
+
131
+ if (typeof actionContext?.addListeners === "function") {
132
+ return actionContext.addListeners(({ entryState, entry }) => {
133
+ if (entry?.id === item?.id) {
134
+ setActionState(entryState);
135
+ }
136
+ });
137
+ }
138
+
139
+ return undefined;
140
+ }, [actionContext, item?.id]);
141
+
142
+ const legacySelected = useMemo(() => {
143
+ if (!actionContext || supportsEntryState) {
144
+ return false;
145
+ }
146
+
147
+ return buildLegacySelection(item, actionContext);
148
+ }, [actionContext, supportsEntryState, item]);
149
+
150
+ const isActive = resolveIsActive(actionState, legacySelected);
151
+
152
+ const labelText = supportsEntryState
153
+ ? resolveLabelText(actionState?.label)
154
+ : "";
155
+
156
+ const shouldRenderAsset = Boolean(
157
+ supportsEntryState
158
+ ? actionState?.asset && actionState?.mobileButtonAssets
159
+ : false
160
+ );
161
+
162
+ const shouldRenderLabel = Boolean(labelText);
163
+
164
+ const cloneChildrenWithState = (nodes?: React.ReactNode): React.ReactNode => {
165
+ return React.Children.map(nodes, (child) => {
166
+ if (!isValidElement(child)) {
167
+ return child;
168
+ }
169
+
170
+ const role = child.props.mobileActionRole;
171
+ const nextChildren = cloneChildrenWithState(child.props.children);
172
+
173
+ if (role === "asset" && !shouldRenderAsset) {
174
+ return null;
175
+ }
176
+
177
+ if (role === "label" && !shouldRenderLabel) {
178
+ return null;
179
+ }
180
+
181
+ if (
182
+ role === "label_container" &&
183
+ React.Children.count(nextChildren) === 0
184
+ ) {
185
+ return null;
186
+ }
187
+
188
+ const nextProps: Partial<ChildElementProps> = {};
189
+
190
+ if (role === "asset") {
191
+ if (action.flavour) {
192
+ nextProps.uri = selectByAssetFlavour(
193
+ actionState,
194
+ action.flavour,
195
+ isActive
196
+ );
197
+ }
198
+ }
199
+
200
+ if (role === "label") {
201
+ nextProps.state = isActive ? "focused" : "default";
202
+ }
203
+
204
+ if (nextChildren !== child.props.children) {
205
+ nextProps.children = nextChildren;
206
+ }
207
+
208
+ return React.cloneElement(child, nextProps);
209
+ });
210
+ };
211
+
212
+ const onPress = useCallback(async () => {
213
+ if (!actionContext) {
214
+ return;
215
+ }
216
+
217
+ if (supportsEntryState) {
218
+ return actionContext.invokeAction(item, {
219
+ updateState: setActionState,
220
+ });
221
+ }
222
+
223
+ const favouritesAction = legacySelected
224
+ ? actionContext.removeFavourite
225
+ : actionContext.addFavourite;
226
+
227
+ const toggleAction = actionContext?.invokeAction ?? favouritesAction;
228
+
229
+ return toggleAction?.(item);
230
+ }, [actionContext, supportsEntryState, item, legacySelected]);
231
+
232
+ if (!actionContext) {
233
+ masterCellLogger.warning(
234
+ `You're missing an action plugin(${action?.identifier}) required by your mobile action button.`
235
+ );
236
+
237
+ return null;
238
+ }
239
+
240
+ if (actionDisabled) {
241
+ return null;
242
+ }
243
+
244
+ if (!shouldRenderAsset && !shouldRenderLabel) {
245
+ return null;
246
+ }
247
+
248
+ return (
249
+ <TouchableOpacity
250
+ activeOpacity={1}
251
+ onPress={onPress}
252
+ testID={testID || `${item?.id}`}
253
+ accessibilityLabel={accessibilityLabel || `${item?.id}`}
254
+ accessibilityHint={accessibilityHint}
255
+ accessible={!!(testID || accessibilityLabel)}
256
+ style={isActive ? { ...style, ...focusedStyles } : style}
257
+ >
258
+ {cloneChildrenWithState(children)}
259
+ </TouchableOpacity>
260
+ );
261
+ }
@@ -7,7 +7,6 @@ import {
7
7
  } from "@applicaster/zapp-react-native-utils/cellUtils";
8
8
 
9
9
  import { useTextLabel, withFocusedStyles } from "./hooks";
10
- import { withScaledLineHeight } from "./utils";
11
10
  import { toNumber } from "@applicaster/zapp-react-native-utils/numberUtils";
12
11
  import { MeasurementPortalContext } from "../../../MeasurmentsPortal";
13
12
  import { isNilOrEmpty } from "@applicaster/zapp-react-native-utils/reactUtils/helpers";
@@ -70,12 +69,9 @@ const _Text = ({
70
69
 
71
70
  return (
72
71
  <Text
73
- style={[
74
- withScaledLineHeight(withFocusedStyles({ style, otherProps })),
75
- { height },
76
- ]}
77
- allowFontScaling={false}
72
+ style={[withFocusedStyles({ style, otherProps }), { height }]}
78
73
  {...withoutLabel(otherProps)}
74
+ allowFontScaling={false}
79
75
  >
80
76
  {textLabel}
81
77
  </Text>
@@ -16,12 +16,14 @@ import { CellBadge } from "./CellBadge";
16
16
  import { TvActionButtons } from "./tv/TvActionButtons";
17
17
  import { ButtonContainerView } from "./tv/ButtonContainerView";
18
18
  import { ImageBorderContainer } from "./ImageBorderContainer";
19
+ import { PressableView } from "./PressableView";
19
20
 
20
21
  export const defaultComponents = {
21
22
  View,
22
23
  CollapsibleTextContainer,
23
24
  Text,
24
25
  Button,
26
+ PressableView,
25
27
  Image,
26
28
  PureImage,
27
29
  ButtonContainerView,
@@ -0,0 +1,42 @@
1
+ import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
2
+
3
+ type Props = {
4
+ prefix: string;
5
+ value: Function;
6
+ testID?: string;
7
+ };
8
+
9
+ /** Asset used in conjunction with PressableView inside mobile action buttons, uri is provided by PressableView */
10
+ export const Asset = ({ prefix, value, testID }: Props) => {
11
+ if (!value(`${prefix}_asset_enabled`)) {
12
+ return null;
13
+ }
14
+
15
+ return {
16
+ type: "Image",
17
+ style: {
18
+ width: toNumberWithDefaultZero(value(`${prefix}_asset_width`)),
19
+ height: toNumberWithDefaultZero(value(`${prefix}_asset_height`)),
20
+ marginTop: toNumberWithDefaultZero(value(`${prefix}_asset_margin_top`)),
21
+ marginRight: toNumberWithDefaultZero(
22
+ value(`${prefix}_asset_margin_right`)
23
+ ),
24
+ marginBottom: toNumberWithDefaultZero(
25
+ value(`${prefix}_asset_margin_bottom`)
26
+ ),
27
+ marginLeft: toNumberWithDefaultZero(value(`${prefix}_asset_margin_left`)),
28
+ backgroundColor: "transparent",
29
+ },
30
+ data: [
31
+ {
32
+ func: (entry) => entry,
33
+ args: [],
34
+ propName: "entry",
35
+ },
36
+ ],
37
+ additionalProps: {
38
+ mobileActionRole: "asset",
39
+ testID: testID ? `${testID}-asset` : undefined,
40
+ },
41
+ };
42
+ };
@@ -0,0 +1,127 @@
1
+ import {
2
+ toNumberWithDefault,
3
+ toNumberWithDefaultZero,
4
+ } from "@applicaster/zapp-react-native-utils/numberUtils";
5
+ import { compact } from "@applicaster/zapp-react-native-utils/cellUtils";
6
+
7
+ import { Asset } from "./Asset";
8
+ import { Spacer } from "./Spacer";
9
+ import { TextLabelsContainer } from "./TextLabelsContainer";
10
+ import { getContentDirection, getContentsAlignment } from "./helpers";
11
+
12
+ const displayModeStyle = ({ value, prefix }) => {
13
+ const mode = value(`${prefix}_display_mode`) || "dynamic";
14
+
15
+ if (mode === "fixed") {
16
+ return {
17
+ width: toNumberWithDefault(140, value(`${prefix}_width`)),
18
+ };
19
+ }
20
+
21
+ if (mode === "fill") {
22
+ return {
23
+ flex: 1,
24
+ };
25
+ }
26
+
27
+ return {};
28
+ };
29
+
30
+ type Props = {
31
+ index: number;
32
+ value: Function;
33
+ stylePrefix: string;
34
+ specificPrefix: string;
35
+ spacingStyle: Record<string, unknown>;
36
+ };
37
+
38
+ export const Button = ({
39
+ index,
40
+ value,
41
+ stylePrefix,
42
+ specificPrefix,
43
+ spacingStyle,
44
+ }: Props) => {
45
+ if (!value(`${specificPrefix}_button_enabled`)) {
46
+ return null;
47
+ }
48
+
49
+ const testID = `mobile_action_button_${index + 1}`;
50
+ const actionIdentifier = value(`${specificPrefix}_assign_action`);
51
+ const assetAlignment = value(`${stylePrefix}_asset_alignment`) || "left";
52
+ const actionAssetFlavour = value(`${stylePrefix}_action_asset_flavour`);
53
+
54
+ const contentsAlignment =
55
+ value(`${stylePrefix}_contents_alignment`) || "center";
56
+
57
+ return {
58
+ type: "PressableView",
59
+ style: {
60
+ flexDirection: getContentDirection(assetAlignment),
61
+ alignItems: "center",
62
+ justifyContent: getContentsAlignment(contentsAlignment),
63
+
64
+ marginTop: toNumberWithDefaultZero(value(`${stylePrefix}_margin_top`)),
65
+ marginRight: toNumberWithDefaultZero(
66
+ value(`${stylePrefix}_margin_right`)
67
+ ),
68
+ marginBottom: toNumberWithDefaultZero(
69
+ value(`${stylePrefix}_margin_bottom`)
70
+ ),
71
+ marginLeft: toNumberWithDefaultZero(value(`${stylePrefix}_margin_left`)),
72
+
73
+ paddingTop: toNumberWithDefaultZero(value(`${stylePrefix}_padding_top`)),
74
+ paddingRight: toNumberWithDefaultZero(
75
+ value(`${stylePrefix}_padding_right`)
76
+ ),
77
+ paddingBottom: toNumberWithDefaultZero(
78
+ value(`${stylePrefix}_padding_bottom`)
79
+ ),
80
+ paddingLeft: toNumberWithDefaultZero(
81
+ value(`${stylePrefix}_padding_left`)
82
+ ),
83
+
84
+ borderWidth: toNumberWithDefaultZero(value(`${stylePrefix}_border_size`)),
85
+ borderRadius: toNumberWithDefaultZero(
86
+ value(`${stylePrefix}_corner_radius`)
87
+ ),
88
+ borderColor: value(`${stylePrefix}_border_color`),
89
+ backgroundColor: value(`${stylePrefix}_background_color`),
90
+
91
+ ...displayModeStyle({ value, prefix: stylePrefix }),
92
+ ...spacingStyle,
93
+ },
94
+ additionalProps: {
95
+ action: {
96
+ identifier: actionIdentifier,
97
+ flavour: actionAssetFlavour,
98
+ },
99
+ focusedStyles: {
100
+ backgroundColor: value(`${stylePrefix}_focused_background_color`),
101
+ borderColor: value(`${stylePrefix}_focused_border_color`),
102
+ },
103
+ testID,
104
+ },
105
+ elements: compact([
106
+ Asset({
107
+ prefix: stylePrefix,
108
+ value,
109
+ testID,
110
+ }),
111
+ Spacer(),
112
+ TextLabelsContainer({
113
+ prefix: stylePrefix,
114
+ value,
115
+ actionIdentifier,
116
+ testID,
117
+ }),
118
+ ]),
119
+ data: [
120
+ {
121
+ func: (x) => x,
122
+ args: [],
123
+ propName: "item",
124
+ },
125
+ ],
126
+ };
127
+ };
@@ -0,0 +1,23 @@
1
+ type Props = {
2
+ style: Record<string, unknown>;
3
+ contentStyle: Record<string, unknown>;
4
+ elements: Array<Record<string, unknown>>;
5
+ };
6
+
7
+ export const ButtonContainerView = ({
8
+ style,
9
+ contentStyle,
10
+ elements,
11
+ }: Props) => {
12
+ return {
13
+ type: "View",
14
+ style,
15
+ elements: [
16
+ {
17
+ type: "View",
18
+ style: contentStyle,
19
+ elements,
20
+ },
21
+ ],
22
+ };
23
+ };
@@ -0,0 +1,16 @@
1
+ type Props = {
2
+ enabled?: boolean;
3
+ };
4
+
5
+ export const Spacer = ({ enabled = false }: Props = {}) => {
6
+ if (!enabled) {
7
+ return null;
8
+ }
9
+
10
+ return {
11
+ type: "View",
12
+ style: {
13
+ flex: 1,
14
+ },
15
+ };
16
+ };
@@ -0,0 +1,67 @@
1
+ import { Platform } from "react-native";
2
+
3
+ import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
4
+
5
+ type Props = {
6
+ prefix: string;
7
+ value: Function;
8
+ actionIdentifier: string;
9
+ testID?: string;
10
+ };
11
+
12
+ export const TextLabel = ({
13
+ prefix,
14
+ value,
15
+ actionIdentifier,
16
+ testID,
17
+ }: Props) => {
18
+ if (!value(`${prefix}_label_enabled`)) {
19
+ return null;
20
+ }
21
+
22
+ return {
23
+ type: "Text",
24
+ style: {
25
+ color: value(`${prefix}_font_color`),
26
+ fontSize: toNumberWithDefaultZero(value(`${prefix}_font_size`)),
27
+ lineHeight: toNumberWithDefaultZero(value(`${prefix}_line_height`)),
28
+ marginTop: toNumberWithDefaultZero(value(`${prefix}_margin_top`)),
29
+ marginRight: toNumberWithDefaultZero(value(`${prefix}_margin_right`)),
30
+ marginBottom: toNumberWithDefaultZero(value(`${prefix}_margin_bottom`)),
31
+ marginLeft: toNumberWithDefaultZero(value(`${prefix}_margin_left`)),
32
+ fontFamily:
33
+ Platform.OS === "ios"
34
+ ? value(`${prefix}_ios_font_family`)
35
+ : value(`${prefix}_android_font_family`),
36
+ letterSpacing: toNumberWithDefaultZero(
37
+ Platform.OS === "ios"
38
+ ? value(`${prefix}_ios_letter_spacing`)
39
+ : value(`${prefix}_android_letter_spacing`)
40
+ ),
41
+ },
42
+ data: [
43
+ {
44
+ func: (entry) => entry,
45
+ args: [],
46
+ propName: "entry",
47
+ },
48
+ ],
49
+ additionalProps: {
50
+ label: {
51
+ context: actionIdentifier,
52
+ name: "label_1",
53
+ },
54
+ normalStyles: {
55
+ color: value(`${prefix}_font_color`),
56
+ },
57
+ focusedStyles: {
58
+ color: value(`${prefix}_focused_font_color`),
59
+ },
60
+ state: "default",
61
+ mobileActionRole: "label",
62
+ transformText: value(`${prefix}_text_transform`) || "default",
63
+ numberOfLines: value(`${prefix}_number_of_lines`),
64
+ testID: testID ? `${testID}-label` : undefined,
65
+ },
66
+ };
67
+ };
@@ -0,0 +1,32 @@
1
+ import { compact } from "@applicaster/zapp-react-native-utils/cellUtils";
2
+
3
+ import { TextLabel } from "./TextLabel";
4
+
5
+ type Props = {
6
+ prefix: string;
7
+ value: Function;
8
+ actionIdentifier: string;
9
+ testID?: string;
10
+ };
11
+
12
+ export const TextLabelsContainer = ({
13
+ prefix,
14
+ value,
15
+ actionIdentifier,
16
+ testID,
17
+ }: Props) => {
18
+ return {
19
+ type: "View",
20
+ additionalProps: {
21
+ mobileActionRole: "label_container",
22
+ },
23
+ elements: compact([
24
+ TextLabel({
25
+ prefix,
26
+ value,
27
+ actionIdentifier,
28
+ testID,
29
+ }),
30
+ ]),
31
+ };
32
+ };