@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.
- package/Components/CellRendererResolver/index.ts +1 -1
- package/Components/Layout/FullWidthRow.tsx +38 -0
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +21 -47
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +6 -34
- package/Components/MasterCell/DefaultComponents/ImageContainer/index.tsx +3 -4
- package/Components/MasterCell/DefaultComponents/PressableView.tsx +3 -3
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ActionButton.tsx +2 -40
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/AssetComponent.tsx +4 -15
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +20 -40
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +0 -3
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +17 -24
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +3 -8
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +2 -2
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/insertButtonsBetweenLabels.test.ts +13 -45
- package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +2 -2
- package/Components/MasterCell/dataAdapter.ts +15 -5
- package/Components/MasterCell/index.tsx +30 -5
- package/Components/MasterCell/utils/__tests__/resolveColor.test.js +169 -132
- package/Components/MasterCell/utils/__tests__/resolveColorForProp.test.js +92 -0
- package/Components/MasterCell/utils/index.ts +85 -46
- package/Components/PlayerContainer/PlayerContainer.tsx +7 -3
- package/Components/River/ComponentsMap/ComponentsMap.tsx +2 -2
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +3 -15
- package/Components/Screen/index.tsx +8 -4
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +12 -5
- package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +2 -2
- package/Contexts/CachedDimensionsContext/__tests__/index.test.ts +154 -0
- package/Contexts/CachedDimensionsContext/index.ts +17 -2
- package/package.json +5 -5
- package/Components/Screen/utils.ts +0 -16
- /package/Components/BackgroundImage/{BackgroundImage.tv.android.tsx → BackgroundImage.android.tv.tsx} +0 -0
- /package/Components/BackgroundImage/{BackgroundImage.tv.ios.tsx → BackgroundImage.ios.tv.tsx} +0 -0
- /package/Components/MasterCell/DefaultComponents/ButtonContainerView/{index.tv.android.tsx → index.android.tv.tsx} +0 -0
|
@@ -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
|
+
}
|
package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts
CHANGED
|
@@ -6,54 +6,28 @@ import {
|
|
|
6
6
|
describe("ActionButtonsCore placement", () => {
|
|
7
7
|
const buttons = { type: "View", name: "buttons" };
|
|
8
8
|
|
|
9
|
-
const
|
|
10
|
-
{ name: "
|
|
11
|
-
{ name: "
|
|
12
|
-
{ name: "
|
|
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
|
|
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: "
|
|
20
|
-
).toEqual([
|
|
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: "
|
|
26
|
-
).toEqual([
|
|
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
|
-
|
|
38
|
+
below_labels
|
|
65
39
|
)
|
|
66
|
-
).toEqual([buttons, ...
|
|
40
|
+
).toEqual([buttons, ...below_labels]);
|
|
67
41
|
|
|
68
42
|
expect(
|
|
69
43
|
insertBetweenLabels(
|
|
70
44
|
{ position: "on_top", allowOnTop: false },
|
|
71
45
|
buttons,
|
|
72
|
-
|
|
46
|
+
below_labels
|
|
73
47
|
)
|
|
74
|
-
).toEqual(
|
|
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
|
-
|
|
56
|
+
below_labels
|
|
83
57
|
)
|
|
84
|
-
).toEqual([...
|
|
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
|
-
|
|
66
|
+
below_labels
|
|
93
67
|
)
|
|
94
|
-
).toEqual(
|
|
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
|
-
|
|
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
|
-
|
|
125
|
-
const
|
|
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
|
|
116
|
+
if (!inserted && appendWhenMissing) {
|
|
117
|
+
return [...labels, buttons];
|
|
146
118
|
}
|
|
147
119
|
|
|
148
|
-
return
|
|
120
|
+
return inserted ? labelsWithButtons : [...labels];
|
|
149
121
|
};
|
|
150
122
|
|
|
151
123
|
export const insertBetweenLabelContainers = (
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import 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 =
|
|
7
|
+
type Props = {
|
|
8
8
|
enable_video_preview: boolean;
|
|
9
9
|
player_screen_id: string;
|
|
10
|
-
|
|
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
|
|
2
|
+
import { TouchableOpacity } from "react-native";
|
|
3
3
|
|
|
4
4
|
type Props = {
|
|
5
5
|
children?: React.ReactNode;
|
|
6
|
-
style?:
|
|
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
|
-
|
|
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
|
}}
|
package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/AssetComponent.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import {
|
|
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={
|
|
15
|
+
<View style={props.style} testID={props.testID}>
|
|
24
16
|
{React.cloneElement(props.asset, { cellUUID: props.cellUUID })}
|
|
25
17
|
</View>
|
|
26
18
|
) : (
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
14
|
+
const displayModeStyle = (value) => {
|
|
16
15
|
const mode = value("display_mode") || "dynamic";
|
|
17
16
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
17
|
+
if (mode === "fixed") {
|
|
18
|
+
return {
|
|
19
|
+
width: toNumberWithDefault(140, value("width")),
|
|
20
|
+
};
|
|
21
|
+
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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:
|
|
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
|
-
//
|
|
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
|
-
|
|
77
|
+
flexDirection: getContentDirection(assetAlignment),
|
|
78
|
+
alignContent: "center",
|
|
79
|
+
alignItems: getContentsAlignment(contentsAlignment, assetAlignment),
|
|
80
|
+
justifyContent: getContentsAlignment(contentsAlignment, assetAlignment),
|
|
93
81
|
...getPressableStyles(getValue),
|
|
94
|
-
...displayModeStyle(getValue
|
|
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")
|
|
137
|
-
ellipseMode: "tail",
|
|
117
|
+
numberOfLines: getValue("number_of_lines"),
|
|
138
118
|
},
|
|
139
119
|
actionIdentifier,
|
|
140
120
|
testID,
|
|
@@ -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
|
-
...(
|
|
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
|
-
:
|
|
59
|
+
: {}),
|
|
76
60
|
};
|
|
77
61
|
|
|
78
62
|
const contentStyle = {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
22
|
+
labels // "text_label_1", "text_label_2", "text_label_3", "text_label_4"
|
|
23
23
|
);
|
|
24
24
|
|
|
25
25
|
export const insertButtonsBetweenLabelContainers = (
|