@applicaster/zapp-react-native-ui-components 16.0.0-alpha.2226592390 → 16.0.0-alpha.2295427024

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 (33) hide show
  1. package/Components/CellRendererResolver/index.ts +1 -1
  2. package/Components/Layout/FullWidthRow.tsx +38 -0
  3. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +21 -47
  4. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +6 -34
  5. package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +3 -4
  6. package/Components/MasterCell/DefaultComponents/PressableView.tsx +3 -3
  7. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ActionButton.tsx +2 -40
  8. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/AssetComponent.tsx +4 -15
  9. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +20 -40
  10. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +0 -3
  11. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +17 -24
  12. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +3 -8
  13. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +2 -2
  14. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/insertButtonsBetweenLabels.test.ts +13 -45
  15. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +2 -2
  16. package/Components/MasterCell/dataAdapter.ts +15 -5
  17. package/Components/MasterCell/index.tsx +30 -5
  18. package/Components/MasterCell/utils/__tests__/resolveColor.test.js +169 -132
  19. package/Components/MasterCell/utils/__tests__/resolveColorForProp.test.js +92 -0
  20. package/Components/MasterCell/utils/index.ts +85 -46
  21. package/Components/PlayerContainer/PlayerContainer.tsx +7 -3
  22. package/Components/River/ComponentsMap/ComponentsMap.tsx +2 -2
  23. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +3 -15
  24. package/Components/Screen/index.tsx +8 -4
  25. package/Components/ZappFrameworkComponents/BarView/BarView.tsx +12 -5
  26. package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +2 -2
  27. package/Contexts/CachedDimensionsContext/__tests__/index.test.ts +154 -0
  28. package/Contexts/CachedDimensionsContext/index.ts +17 -2
  29. package/package.json +5 -5
  30. package/Components/Screen/utils.ts +0 -16
  31. /package/Components/BackgroundImage/{BackgroundImage.tv.android.tsx → BackgroundImage.android.tv.tsx} +0 -0
  32. /package/Components/BackgroundImage/{BackgroundImage.tv.ios.tsx → BackgroundImage.ios.tv.tsx} +0 -0
  33. /package/Components/MasterCell/DefaultComponents/ButtonContainerView/{index.tv.android.tsx → index.android.tv.tsx} +0 -0
@@ -92,7 +92,7 @@ export function CellRendererResolver({
92
92
  component,
93
93
  styles,
94
94
  cellStyles,
95
- cellOptions,
95
+ cellOptions: { ...cellOptions, component },
96
96
  ...cellOptions, // fallback for existing plugins
97
97
  });
98
98
  }
@@ -0,0 +1,38 @@
1
+ import * as React from "react";
2
+ import { StyleSheet, View } from "react-native";
3
+
4
+ const styles = StyleSheet.create({
5
+ row: { flexDirection: "row" },
6
+ basis: {
7
+ maxWidth: "100%",
8
+ flexBasis: "100%",
9
+ },
10
+ });
11
+
12
+ type Props = {
13
+ children: React.ReactNode;
14
+ };
15
+
16
+ /**
17
+ * Constrains its child to exactly the available parent width.
18
+ *
19
+ * UI components such as Hero and List render their items inside a parent
20
+ * `ScrollView` (e.g. when wrapped by tabs). A child placed directly in a
21
+ * scroll container can size itself to its own content rather than to the
22
+ * viewport, which causes items to be measured at a stale width and resize
23
+ * unexpectedly after layout changes such as device rotation.
24
+ *
25
+ * Wrapping the content in a `flexDirection: "row"` parent with a
26
+ * `flexBasis: "100%"` / `maxWidth: "100%"` child forces the child to
27
+ * re-derive its width from the parent on every layout pass instead of
28
+ * caching a measured pixel width, keeping it full-width and stable.
29
+ *
30
+ * @param children - The content to render at full parent width.
31
+ */
32
+ export function FullWidthRow({ children }: Props) {
33
+ return (
34
+ <View style={styles.row}>
35
+ <View style={styles.basis}>{children}</View>
36
+ </View>
37
+ );
38
+ }
@@ -6,54 +6,28 @@ import {
6
6
  describe("ActionButtonsCore placement", () => {
7
7
  const buttons = { type: "View", name: "buttons" };
8
8
 
9
- const slots = [
10
- { name: "text_label_1", element: { type: "View", id: "label_1" } },
11
- { name: "text_label_2", element: { type: "View", id: "label_2" } },
12
- { name: "text_label_3", element: { type: "View", id: "label_3" } },
9
+ const above_labels = [
10
+ { name: "above_label_1" },
11
+ { name: "above_label_2" },
12
+ { name: "above_label_3" },
13
13
  ];
14
14
 
15
- const labels = slots.map((slot) => slot.element);
15
+ const below_labels = [
16
+ { name: "below_label_1" },
17
+ { name: "below_label_2" },
18
+ { name: "below_label_3" },
19
+ ];
16
20
 
17
21
  it("inserts buttons after the matching label", () => {
18
22
  expect(
19
- insertBetweenLabels({ position: "below_text_label_2" }, buttons, slots)
20
- ).toEqual([labels[0], labels[1], buttons, labels[2]]);
23
+ insertBetweenLabels({ position: "below_label_2" }, buttons, below_labels)
24
+ ).toEqual([below_labels[0], below_labels[1], buttons, below_labels[2]]);
21
25
  });
22
26
 
23
27
  it("inserts buttons before the matching label", () => {
24
28
  expect(
25
- insertBetweenLabels({ position: "above_text_label_2" }, buttons, slots)
26
- ).toEqual([labels[0], buttons, labels[1], labels[2]]);
27
- });
28
-
29
- it("inserts buttons after the matching label on a plain name match", () => {
30
- expect(
31
- insertBetweenLabels({ position: "text_label_2" }, buttons, slots)
32
- ).toEqual([labels[0], labels[1], buttons, labels[2]]);
33
- });
34
-
35
- it("keeps the slot when its label is empty (null element)", () => {
36
- const slotsWithEmpty = [
37
- { name: "text_label_1", element: { id: "label_1" } },
38
- { name: "text_label_2", element: null },
39
- { name: "text_label_3", element: { id: "label_3" } },
40
- ];
41
-
42
- expect(
43
- insertBetweenLabels(
44
- { position: "above_text_label_2" },
45
- buttons,
46
- slotsWithEmpty
47
- )
48
- ).toEqual([{ id: "label_1" }, buttons, { id: "label_3" }]);
49
-
50
- expect(
51
- insertBetweenLabels(
52
- { position: "below_text_label_2" },
53
- buttons,
54
- slotsWithEmpty
55
- )
56
- ).toEqual([{ id: "label_1" }, buttons, { id: "label_3" }]);
29
+ insertBetweenLabels({ position: "above_label_2" }, buttons, above_labels)
30
+ ).toEqual([above_labels[0], buttons, above_labels[1], above_labels[2]]);
57
31
  });
58
32
 
59
33
  it("prepends buttons only when on_top is allowed", () => {
@@ -61,17 +35,17 @@ describe("ActionButtonsCore placement", () => {
61
35
  insertBetweenLabels(
62
36
  { position: "on_top", allowOnTop: true },
63
37
  buttons,
64
- slots
38
+ below_labels
65
39
  )
66
- ).toEqual([buttons, ...labels]);
40
+ ).toEqual([buttons, ...below_labels]);
67
41
 
68
42
  expect(
69
43
  insertBetweenLabels(
70
44
  { position: "on_top", allowOnTop: false },
71
45
  buttons,
72
- slots
46
+ below_labels
73
47
  )
74
- ).toEqual(labels);
48
+ ).toEqual(below_labels);
75
49
  });
76
50
 
77
51
  it("appends buttons when appendWhenMissing is enabled", () => {
@@ -79,9 +53,9 @@ describe("ActionButtonsCore placement", () => {
79
53
  insertBetweenLabels(
80
54
  { position: "unknown", appendWhenMissing: true },
81
55
  buttons,
82
- slots
56
+ below_labels
83
57
  )
84
- ).toEqual([...labels, buttons]);
58
+ ).toEqual([...below_labels, buttons]);
85
59
  });
86
60
 
87
61
  it("returns labels unchanged when appendWhenMissing is disabled", () => {
@@ -89,9 +63,9 @@ describe("ActionButtonsCore placement", () => {
89
63
  insertBetweenLabels(
90
64
  { position: "unknown", appendWhenMissing: false },
91
65
  buttons,
92
- slots
66
+ below_labels
93
67
  )
94
- ).toEqual(labels);
68
+ ).toEqual(below_labels);
95
69
  });
96
70
 
97
71
  const labelContainers = [
@@ -17,11 +17,6 @@ type InsertOptions = {
17
17
  appendWhenMissing?: boolean;
18
18
  };
19
19
 
20
- type Slot = {
21
- name: string;
22
- element?: unknown;
23
- };
24
-
25
20
  const hasLabelName = (value: unknown): value is Label =>
26
21
  !!value &&
27
22
  typeof value === "object" &&
@@ -105,14 +100,8 @@ const containsNestedLabel = (
105
100
  export const insertBetweenLabels = (
106
101
  { position, allowOnTop = false, appendWhenMissing = false }: InsertOptions,
107
102
  buttons: unknown,
108
- slots: Slot[] = []
103
+ labels: Label[] = []
109
104
  ) => {
110
- // Slots are defined by the canonical label list, so an empty (null) label
111
- // still keeps its position — buttons placed above/below it survive.
112
- const labels = slots
113
- .map((slot) => slot.element)
114
- .filter((element) => element != null);
115
-
116
105
  if (buttons == null) {
117
106
  return labels;
118
107
  }
@@ -121,31 +110,14 @@ export const insertBetweenLabels = (
121
110
  return [buttons, ...labels];
122
111
  }
123
112
 
124
- let inserted = false;
125
- const result: unknown[] = [];
126
-
127
- for (const { name, element } of slots) {
128
- if (position === `above_${name}`) {
129
- result.push(buttons);
130
- inserted = true;
131
- }
132
-
133
- if (element != null) {
134
- result.push(element);
135
- }
136
-
137
- // Insert after on `below_*` or a plain label-name match.
138
- if (position === `below_${name}` || position === name) {
139
- result.push(buttons);
140
- inserted = true;
141
- }
142
- }
113
+ const labelsWithButtons = withButtons(position, buttons, labels);
114
+ const inserted = labelsWithButtons.length !== labels.length;
143
115
 
144
- if (!inserted) {
145
- return appendWhenMissing ? [...labels, buttons] : labels;
116
+ if (!inserted && appendWhenMissing) {
117
+ return [...labels, buttons];
146
118
  }
147
119
 
148
- return result;
120
+ return inserted ? labelsWithButtons : [...labels];
149
121
  };
150
122
 
151
123
  export const insertBetweenLabelContainers = (
@@ -1,14 +1,13 @@
1
- import React, { PropsWithChildren } from "react";
1
+ import React from "react";
2
2
  import { isVideoPreviewEnabled } from "@applicaster/zapp-react-native-ui-components/Components/MasterCell/utils";
3
3
  import { LiveImage } from "../LiveImage";
4
4
  import PureImage from "../Image";
5
5
  import { useIsScreenActive } from "@applicaster/zapp-react-native-utils/reactHooks";
6
6
 
7
- type Props = PropsWithChildren<{
7
+ type Props = {
8
8
  enable_video_preview: boolean;
9
9
  player_screen_id: string;
10
- uri?: string;
11
- }>;
10
+ };
12
11
 
13
12
  export const ImageContainer = (props: Props) => {
14
13
  const isActive = useIsScreenActive();
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
- import { TouchableOpacity, ViewStyle } from "react-native";
2
+ import { TouchableOpacity } from "react-native";
3
3
 
4
4
  type Props = {
5
5
  children?: React.ReactNode;
6
- style?: ViewStyle | ViewStyle[];
6
+ style?: Record<string, unknown>;
7
7
  testID?: string;
8
8
  accessibilityLabel?: string;
9
9
  accessibilityHint?: string;
@@ -12,7 +12,7 @@ type Props = {
12
12
 
13
13
  export function PressableView({
14
14
  children,
15
- style,
15
+ style = {},
16
16
  testID,
17
17
  accessibilityLabel,
18
18
  accessibilityHint,
@@ -1,5 +1,4 @@
1
1
  import React from "react";
2
- import { StyleSheet, View, ViewStyle } from "react-native";
3
2
  import { PressableView } from "../../PressableView";
4
3
 
5
4
  import { ActionButtonController } from "../../ActionButtonsCore/components";
@@ -16,22 +15,6 @@ type ChildElementProps = {
16
15
  entry?: any;
17
16
  };
18
17
 
19
- const styles = StyleSheet.create({
20
- pressableView: {
21
- flexDirection: "row",
22
- overflow: "hidden",
23
- },
24
- maxWidthFull: {
25
- width: "100%",
26
- },
27
- innerWrapper: {
28
- flexDirection: "row",
29
- flexGrow: 0,
30
- flexShrink: 1,
31
- overflow: "hidden",
32
- },
33
- });
34
-
35
18
  const isValidElement = (
36
19
  child: React.ReactNode
37
20
  ): child is React.ReactElement<ChildElementProps> =>
@@ -138,33 +121,12 @@ export const ActionButton = ({ style, children, action, entry, ...props }) => {
138
121
  return (
139
122
  <PressableView
140
123
  testID={props.testID || `${entry?.id}`}
141
- style={[
142
- isActive
143
- ? {
144
- ...(style as ViewStyle),
145
- ...(props.focusedStyles as ViewStyle),
146
- }
147
- : (style as ViewStyle),
148
- styles.pressableView,
149
- ]}
124
+ style={isActive ? { ...style, ...props.focusedStyles } : style}
150
125
  onPress={onPress}
151
126
  accessibilityLabel={props.accessibilityLabel || `${entry?.id}`}
152
127
  accessibilityHint={props.accessibilityHint}
153
128
  >
154
- <View
155
- // eslint-disable-next-line react-native/no-inline-styles
156
- style={{
157
- width: props.displayMode === "fill" ? "100%" : undefined,
158
- maxWidth: (style as ViewStyle).maxWidth,
159
- ...((style as ViewStyle).maxWidth
160
- ? styles.maxWidthFull
161
- : undefined),
162
- }}
163
- >
164
- <View style={[styles.innerWrapper, props.alignment]}>
165
- {_cloneChildrenWithState(children)}
166
- </View>
167
- </View>
129
+ {_cloneChildrenWithState(children)}
168
130
  </PressableView>
169
131
  );
170
132
  }}
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { StyleSheet, View } from "react-native";
2
+ import { View } from "react-native";
3
3
  import { ImageContainer } from "../../ImageContainer";
4
4
 
5
5
  type Props = {
@@ -10,24 +10,13 @@ type Props = {
10
10
  cellUUID?: string;
11
11
  };
12
12
 
13
- const styles = StyleSheet.create({
14
- assetContainer: {
15
- flexShrink: 0,
16
- justifyContent: "center",
17
- alignItems: "center",
18
- },
19
- });
20
-
21
13
  export const AssetComponent = (props: Props & Record<string, unknown>) => {
22
14
  return props.asset && React.isValidElement(props.asset) ? (
23
- <View style={[styles.assetContainer, props.style]} testID={props.testID}>
15
+ <View style={props.style} testID={props.testID}>
24
16
  {React.cloneElement(props.asset, { cellUUID: props.cellUUID })}
25
17
  </View>
26
18
  ) : (
27
- <ImageContainer
28
- style={[styles.assetContainer, props.style]}
29
- {...(props as any)}
30
- uri={props.uri}
31
- />
19
+ // @ts-ignore
20
+ <ImageContainer {...props} uri={props.uri} />
32
21
  );
33
22
  };
@@ -10,34 +10,23 @@ import {
10
10
  getPressableStyles,
11
11
  getTextLabelStyles,
12
12
  } from "./utils";
13
- import { ViewStyle } from "react-native";
14
13
 
15
- const displayModeStyle = (value, isVertical: boolean) => {
14
+ const displayModeStyle = (value) => {
16
15
  const mode = value("display_mode") || "dynamic";
17
16
 
18
- const defaultStyle = {
19
- flexShrink: 1,
20
- };
17
+ if (mode === "fixed") {
18
+ return {
19
+ width: toNumberWithDefault(140, value("width")),
20
+ };
21
+ }
21
22
 
22
- switch (mode) {
23
- case "fixed":
24
- return {
25
- ...defaultStyle,
26
- width: toNumberWithDefault(140, value("width")),
27
- maxWidth: toNumberWithDefault(140, value("width")),
28
- };
29
- case "fill":
30
- return {
31
- ...defaultStyle,
32
- width: isVertical ? "100%" : undefined,
33
- flex: !isVertical ? 1 : undefined,
34
- };
35
- case "dynamic":
36
- default:
37
- return {
38
- ...defaultStyle,
39
- };
23
+ if (mode === "fill") {
24
+ return {
25
+ flex: 1,
26
+ };
40
27
  }
28
+
29
+ return {};
41
30
  };
42
31
 
43
32
  type Props = {
@@ -45,8 +34,7 @@ type Props = {
45
34
  value: Function;
46
35
  stylePrefix: string;
47
36
  specificPrefix: string;
48
- spacingStyle: ViewStyle;
49
- isVertical: boolean;
37
+ spacingStyle: Record<string, unknown>;
50
38
  };
51
39
 
52
40
  export const Button = ({
@@ -55,9 +43,8 @@ export const Button = ({
55
43
  stylePrefix,
56
44
  specificPrefix,
57
45
  spacingStyle,
58
- isVertical,
59
46
  }: Props) => {
60
- // Retrieves values depending to the slot
47
+ // Retrives values depending to the slot
61
48
  const getSlotBasedValue = (property: string) =>
62
49
  value(`${specificPrefix}_${property}`);
63
50
 
@@ -81,27 +68,21 @@ export const Button = ({
81
68
  const testID = `mobile_action_button_${index + 1}`;
82
69
  const actionIdentifier = getSlotBasedValue("assign_action");
83
70
  const assetAlignment = getValue("asset_alignment") || "left";
84
-
85
71
  const actionAssetFlavour = getValue("action_asset_flavour");
86
72
  const contentsAlignment = getValue("contents_alignment") || "center";
87
- const displayMode = getValue("display_mode") || "dynamic";
88
73
 
89
74
  return {
90
75
  type: "MobileActionButton",
91
76
  style: {
92
- // alignContent: "center", Why do we need this?
77
+ flexDirection: getContentDirection(assetAlignment),
78
+ alignContent: "center",
79
+ alignItems: getContentsAlignment(contentsAlignment, assetAlignment),
80
+ justifyContent: getContentsAlignment(contentsAlignment, assetAlignment),
93
81
  ...getPressableStyles(getValue),
94
- ...displayModeStyle(getValue, isVertical),
82
+ ...displayModeStyle(getValue),
95
83
  ...spacingStyle,
96
84
  },
97
85
  additionalProps: {
98
- displayMode,
99
- alignment: {
100
- alignContent: "center",
101
- flexDirection: getContentDirection(assetAlignment),
102
- alignItems: getContentsAlignment(contentsAlignment, assetAlignment),
103
- justifyContent: getContentsAlignment(contentsAlignment, assetAlignment),
104
- },
105
86
  action: {
106
87
  identifier: actionIdentifier,
107
88
  flavour: actionAssetFlavour,
@@ -133,8 +114,7 @@ export const Button = ({
133
114
  color: getValue("focused_font_color"),
134
115
  },
135
116
  transformText: getValue("text_transform") || "default",
136
- numberOfLines: getValue("number_of_lines") || 1,
137
- ellipseMode: "tail",
117
+ numberOfLines: getValue("number_of_lines"),
138
118
  },
139
119
  actionIdentifier,
140
120
  testID,
@@ -14,9 +14,6 @@ export const TextLabelsContainer = ({
14
14
  }: Props) => {
15
15
  return {
16
16
  type: "View",
17
- style: {
18
- flexShrink: 1,
19
- },
20
17
  additionalProps: {
21
18
  mobileActionRole: "label_container",
22
19
  },
@@ -6,7 +6,6 @@ import {
6
6
  } from "./utils";
7
7
  import { Button } from "./Button";
8
8
  import { buildActionButtonsModel } from "../../ActionButtonsCore/model";
9
- import { ViewStyle } from "react-native";
10
9
 
11
10
  const CONTAINER_PREFIX = "mobile_buttons_container";
12
11
  const BUTTON_PREFIX = "mobile_button";
@@ -43,24 +42,9 @@ export const MobileActionButtons = ({
43
42
  return null;
44
43
  }
45
44
 
46
- const {
47
- container: { stacking, verticalGutter, horizontalGutter },
48
- } = model;
49
-
50
- const isVertical = stacking === "vertical";
51
- const isOverImage = position === "over_image";
52
- const gutter = isVertical ? verticalGutter : horizontalGutter;
53
-
54
- const containerPaddings = {
55
- paddingTop: model.container.margins.top,
56
- paddingRight: model.container.margins.right,
57
- paddingBottom: model.container.margins.bottom,
58
- paddingLeft: model.container.margins.left,
59
- };
60
-
61
45
  const style = {
62
46
  alignItems: "center",
63
- ...(isOverImage
47
+ ...(placement === "over_image"
64
48
  ? {
65
49
  position: "absolute",
66
50
  zIndex: 10,
@@ -72,22 +56,32 @@ export const MobileActionButtons = ({
72
56
  value(`${CONTAINER_PREFIX}_over_image_position`) as string
73
57
  ),
74
58
  }
75
- : containerPaddings),
59
+ : {}),
76
60
  };
77
61
 
78
62
  const contentStyle = {
79
- ...(isOverImage ? containerPaddings : {}),
80
- flexDirection: isVertical ? "column" : "row",
81
- width: isVertical ? "100%" : undefined,
82
- alignSelf: !isOverImage ? model.container.horizontalAlign : undefined,
63
+ flexDirection: model.container.stacking === "vertical" ? "column" : "row",
64
+ alignSelf:
65
+ placement !== "over_image" ? model.container.horizontalAlign : undefined,
83
66
  alignItems: model.container.horizontalAlign,
67
+ marginTop: model.container.margins.top,
68
+ marginRight: model.container.margins.right,
69
+ marginBottom: model.container.margins.bottom,
70
+ marginLeft: model.container.margins.left,
84
71
  };
85
72
 
86
73
  const elements = compact(
87
74
  model.buttons.map(({ renderIndex, specificPrefix, stylePrefix }) => {
88
75
  const isNotLast = renderIndex < model.buttons.length - 1;
89
76
 
90
- const spacingStyle: ViewStyle = {
77
+ const {
78
+ container: { stacking, verticalGutter, horizontalGutter },
79
+ } = model;
80
+
81
+ const isVertical = stacking === "vertical";
82
+ const gutter = isVertical ? verticalGutter : horizontalGutter;
83
+
84
+ const spacingStyle = {
91
85
  [isVertical ? "marginBottom" : "marginRight"]: isNotLast ? gutter : 0,
92
86
  };
93
87
 
@@ -97,7 +91,6 @@ export const MobileActionButtons = ({
97
91
  stylePrefix,
98
92
  specificPrefix,
99
93
  spacingStyle,
100
- isVertical,
101
94
  });
102
95
 
103
96
  if (!button) return null;
@@ -5,19 +5,14 @@ import {
5
5
  } from "..";
6
6
 
7
7
  describe("mobile action insertion helpers", () => {
8
- const slots = [
9
- { name: "text_label_1", element: { type: "View", id: "text_label_1" } },
10
- { name: "text_label_2", element: { type: "View", id: "text_label_2" } },
11
- ];
12
-
13
- const labels = slots.map((slot) => slot.element);
8
+ const labels = [{ name: "text_label_1" }, { name: "text_label_2" }];
14
9
  const buttons = { type: "View", name: "buttons" };
15
10
 
16
11
  it("inserts label buttons below target label", () => {
17
12
  const result = insertButtonsBetweenLabels(
18
13
  { mobile_buttons_container_position: "below_text_label_1" },
19
14
  buttons,
20
- slots
15
+ labels
21
16
  );
22
17
 
23
18
  expect(result).toEqual([labels[0], buttons, labels[1]]);
@@ -27,7 +22,7 @@ describe("mobile action insertion helpers", () => {
27
22
  const result = insertButtonsBetweenLabels(
28
23
  { mobile_buttons_container_position: "unknown" },
29
24
  buttons,
30
- slots
25
+ labels
31
26
  );
32
27
 
33
28
  expect(result).toEqual([labels[0], labels[1]]);
@@ -8,7 +8,7 @@ import { Platform } from "react-native";
8
8
  export const insertButtonsBetweenLabels = (
9
9
  configuration: Record<string, unknown>,
10
10
  buttons,
11
- slots = [] // { name, element } per canonical text label slot
11
+ labels = []
12
12
  ) =>
13
13
  insertBetweenLabels(
14
14
  {
@@ -19,7 +19,7 @@ export const insertButtonsBetweenLabels = (
19
19
  appendWhenMissing: false,
20
20
  },
21
21
  buttons,
22
- slots
22
+ labels // "text_label_1", "text_label_2", "text_label_3", "text_label_4"
23
23
  );
24
24
 
25
25
  export const insertButtonsBetweenLabelContainers = (