@applicaster/zapp-react-native-ui-components 15.0.0-rc.129 → 15.0.0-rc.131

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 (30) hide show
  1. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/model.test.ts +80 -0
  2. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/placement.test.ts +187 -0
  3. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/selectors.test.ts +45 -0
  4. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/__tests__/style.test.ts +49 -0
  5. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/model.ts +47 -0
  6. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/placement.ts +170 -0
  7. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/selectors.ts +26 -0
  8. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/style.ts +29 -0
  9. package/Components/MasterCell/DefaultComponents/ActionButtonsCore/types.ts +37 -0
  10. package/Components/MasterCell/DefaultComponents/PressableView.tsx +196 -0
  11. package/Components/MasterCell/DefaultComponents/index.ts +2 -0
  12. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Asset.ts +46 -0
  13. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Button.ts +126 -0
  14. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/ButtonContainerView.ts +23 -0
  15. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/Spacer.ts +16 -0
  16. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabel.ts +67 -0
  17. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/TextLabelsContainer.ts +32 -0
  18. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +191 -0
  19. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/builders.test.ts +140 -0
  20. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/index.test.ts +222 -0
  21. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/helpers.ts +105 -0
  22. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/index.ts +104 -0
  23. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/__tests__/insertButtons.test.ts +118 -0
  24. package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/utils/index.ts +73 -0
  25. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/__tests__/index.test.ts +86 -0
  26. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/index.ts +35 -52
  27. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/__tests__/getPluginIdentifier.test.ts +35 -171
  28. package/Components/MasterCell/DefaultComponents/tv/TvActionButtons/utils/index.ts +36 -145
  29. package/Components/MasterCell/elementMapper.tsx +1 -0
  30. package/package.json +5 -5
@@ -7,159 +7,71 @@ describe("getPluginIdentifier", () => {
7
7
  memoizedGetPluginIdentifier.clear();
8
8
  });
9
9
 
10
- it("returns the first valid plugin identifier", () => {
10
+ it("returns the requested slot action identifier", () => {
11
11
  expect.assertions(2);
12
12
 
13
13
  const configuration = {
14
- tv_buttons_button_1_other: "value",
15
14
  tv_buttons_button_1_assign_action:
16
15
  "tv_buttons_button_1_assign_action_value",
17
- tv_buttons_button_2_assign_action:
18
- "tv_buttons_button_2_assign_action_value",
16
+ tv_buttons_button_3_assign_action:
17
+ "tv_buttons_button_3_assign_action_value",
19
18
  };
20
19
 
21
- const index = 0;
22
- const result = getPluginIdentifier(configuration, prefix, index);
20
+ const slot = 3;
21
+ const result = getPluginIdentifier(configuration, prefix, slot);
23
22
 
24
23
  const memoizedResult = memoizedGetPluginIdentifier(
25
24
  configuration,
26
25
  prefix,
27
- index
28
- );
29
-
30
- expect(result).toEqual(configuration.tv_buttons_button_1_assign_action);
31
- expect(memoizedResult).toEqual(result);
32
- });
33
-
34
- it("returns the second valid plugin identifier", () => {
35
- expect.assertions(2);
36
-
37
- const configuration = {
38
- tv_buttons_button_1_other: "value_1",
39
- tv_buttons_button_1_assign_action:
40
- "tv_buttons_button_1_assign_action_value",
41
- tv_buttons_button_2_other: "value_2",
42
- tv_buttons_button_2_assign_action:
43
- "tv_buttons_button_2_assign_action_value",
44
- };
45
-
46
- const index = 1;
47
- const result = getPluginIdentifier(configuration, prefix, index);
48
-
49
- const memoizedResult = memoizedGetPluginIdentifier(
50
- configuration,
51
- prefix,
52
- index
53
- );
54
-
55
- expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
56
- expect(memoizedResult).toEqual(result);
57
- });
58
-
59
- it("returns undefined when there are no assign_action keys", () => {
60
- expect.assertions(2);
61
-
62
- const configuration = {};
63
- const index = 0;
64
-
65
- const result = getPluginIdentifier(configuration, prefix, index);
66
-
67
- const memoizedResult = memoizedGetPluginIdentifier(
68
- configuration,
69
- prefix,
70
- index
71
- );
72
-
73
- expect(result).toBeUndefined();
74
- expect(memoizedResult).toBeUndefined();
75
- });
76
-
77
- it("skips undefined values and returns the correct plugin identifier", () => {
78
- expect.assertions(2);
79
-
80
- const configuration = {
81
- tv_buttons_button_1_assign_action: "tv_buttons_button_1_assign_action",
82
- tv_buttons_button_2_assign_action: undefined,
83
- tv_buttons_button_3_assign_action: "tv_buttons_button_3_assign_action",
84
- };
85
-
86
- const index = 1;
87
- const result = getPluginIdentifier(configuration, prefix, index);
88
-
89
- const memoizedResult = memoizedGetPluginIdentifier(
90
- configuration,
91
- prefix,
92
- index
26
+ slot
93
27
  );
94
28
 
95
29
  expect(result).toEqual(configuration.tv_buttons_button_3_assign_action);
96
30
  expect(memoizedResult).toEqual(result);
97
31
  });
98
32
 
99
- it("handles missing intermediate keys and returns the correct plugin identifier", () => {
33
+ it("returns undefined for a disabled or missing slot", () => {
100
34
  expect.assertions(2);
101
35
 
102
36
  const configuration = {
103
37
  tv_buttons_button_1_assign_action: "tv_buttons_button_1_assign_action",
104
- tv_buttons_button_3_assign_action: "tv_buttons_button_3_assign_action",
105
38
  };
106
39
 
107
- const index = 1;
108
- const result = getPluginIdentifier(configuration, prefix, index);
40
+ const slot = 2;
41
+ const result = getPluginIdentifier(configuration, prefix, slot);
109
42
 
110
43
  const memoizedResult = memoizedGetPluginIdentifier(
111
44
  configuration,
112
45
  prefix,
113
- index
46
+ slot
114
47
  );
115
48
 
116
- expect(result).toEqual(configuration.tv_buttons_button_3_assign_action);
49
+ expect(result).toBeUndefined();
117
50
  expect(memoizedResult).toEqual(result);
118
51
  });
119
52
 
120
- it("skips empty string values and returns the first non-empty assign_action", () => {
53
+ it("returns undefined for empty string values", () => {
121
54
  expect.assertions(2);
122
55
 
123
56
  const configuration = {
124
- tv_buttons_button_1_assign_action: "",
125
- tv_buttons_button_2_assign_action: "tv_buttons_button_2_assign_action",
57
+ tv_buttons_button_2_assign_action: "",
126
58
  };
127
59
 
128
- const index = 0;
129
- const result = getPluginIdentifier(configuration, prefix, index);
130
-
131
- const memoizedResult = memoizedGetPluginIdentifier(
132
- configuration,
133
- prefix,
134
- index
135
- );
136
-
137
- expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
138
- expect(memoizedResult).toEqual(result);
139
- });
60
+ const slot = 2;
140
61
 
141
- it("returns undefined for negative index", () => {
142
- expect.assertions(2);
143
-
144
- const configuration = {
145
- tv_buttons_button_1_assign_action: "a",
146
- tv_buttons_button_2_assign_action: "b",
147
- };
148
-
149
- const index = -1;
150
- const result = getPluginIdentifier(configuration, prefix, index);
62
+ const result = getPluginIdentifier(configuration, prefix, slot);
151
63
 
152
64
  const memoizedResult = memoizedGetPluginIdentifier(
153
65
  configuration,
154
66
  prefix,
155
- index
67
+ slot
156
68
  );
157
69
 
158
70
  expect(result).toBeUndefined();
159
71
  expect(memoizedResult).toBeUndefined();
160
72
  });
161
73
 
162
- it("returns undefined for out-of-bounds index", () => {
74
+ it("returns undefined for negative slots", () => {
163
75
  expect.assertions(2);
164
76
 
165
77
  const configuration = {
@@ -167,85 +79,37 @@ describe("getPluginIdentifier", () => {
167
79
  tv_buttons_button_2_assign_action: "b",
168
80
  };
169
81
 
170
- const index = 5;
171
- const result = getPluginIdentifier(configuration, prefix, index);
172
-
173
- const memoizedResult = memoizedGetPluginIdentifier(
174
- configuration,
175
- prefix,
176
- index
177
- );
178
-
179
- expect(result).toBeUndefined();
180
- expect(memoizedResult).toBeUndefined();
181
- });
182
-
183
- it("ignores keys with wrong prefix or format", () => {
184
- expect.assertions(2);
185
-
186
- const configuration = {
187
- tv_buttons_button_1_assign_action: "a",
188
- tv_buttons_wrongprefix_2_assign_action: "b",
189
- tv_buttons_button_x_assign_action: "c",
190
- };
191
-
192
- const index = 1;
193
- const result = getPluginIdentifier(configuration, prefix, index);
82
+ const slot = -1;
83
+ const result = getPluginIdentifier(configuration, prefix, slot);
194
84
 
195
85
  const memoizedResult = memoizedGetPluginIdentifier(
196
86
  configuration,
197
87
  prefix,
198
- index
88
+ slot
199
89
  );
200
90
 
201
91
  expect(result).toBeUndefined();
202
92
  expect(memoizedResult).toBeUndefined();
203
93
  });
204
94
 
205
- it("returns undefined if all assign_actions are null or empty", () => {
95
+ it("handles non-string values by returning the configured slot value", () => {
206
96
  expect.assertions(2);
207
97
 
208
98
  const configuration = {
209
- tv_buttons_button_1_assign_action: null,
210
- tv_buttons_button_2_assign_action: undefined,
211
- tv_buttons_button_3_assign_action: "",
99
+ tv_buttons_button_2_assign_action: true,
212
100
  };
213
101
 
214
- const index = 0;
215
- const result = getPluginIdentifier(configuration, prefix, index);
102
+ const slot = 2;
103
+ const result = getPluginIdentifier(configuration, prefix, slot);
216
104
 
217
105
  const memoizedResult = memoizedGetPluginIdentifier(
218
106
  configuration,
219
107
  prefix,
220
- index
108
+ slot
221
109
  );
222
110
 
223
- expect(result).toBeUndefined();
224
- expect(memoizedResult).toBeUndefined();
225
- });
226
-
227
- it("handles non-string values correctly", () => {
228
- expect.assertions(6);
229
-
230
- const configuration = {
231
- tv_buttons_button_1_assign_action: 123,
232
- tv_buttons_button_2_assign_action: true,
233
- tv_buttons_button_3_assign_action: { nested: "value" },
234
- };
235
-
236
- expect(getPluginIdentifier(configuration, prefix, 0)).toEqual(123);
237
- expect(getPluginIdentifier(configuration, prefix, 1)).toEqual(true);
238
-
239
- expect(getPluginIdentifier(configuration, prefix, 2)).toEqual({
240
- nested: "value",
241
- });
242
-
243
- expect(memoizedGetPluginIdentifier(configuration, prefix, 0)).toEqual(123);
244
- expect(memoizedGetPluginIdentifier(configuration, prefix, 1)).toEqual(true);
245
-
246
- expect(memoizedGetPluginIdentifier(configuration, prefix, 2)).toEqual({
247
- nested: "value",
248
- });
111
+ expect(result).toBe(true);
112
+ expect(memoizedResult).toBe(true);
249
113
  });
250
114
  });
251
115
 
@@ -261,32 +125,32 @@ describe("getPluginIdentifier - when configuration has duplicate values", () =>
261
125
  tv_buttons_button_2_assign_action: "navigation_action",
262
126
  };
263
127
 
264
- it("returns the first plugin identifier when values are identical", () => {
128
+ it("returns the requested slot even when values are identical", () => {
265
129
  expect.assertions(2);
266
130
 
267
- const index = 0;
268
- const result = getPluginIdentifier(configuration, prefix, index);
131
+ const slot = 1;
132
+ const result = getPluginIdentifier(configuration, prefix, slot);
269
133
 
270
134
  const memoizedResult = memoizedGetPluginIdentifier(
271
135
  configuration,
272
136
  prefix,
273
- index
137
+ slot
274
138
  );
275
139
 
276
140
  expect(result).toEqual(configuration.tv_buttons_button_1_assign_action);
277
141
  expect(memoizedResult).toEqual(result);
278
142
  });
279
143
 
280
- it("returns the second plugin identifier when values are identical", () => {
144
+ it("returns the second slot when values are identical", () => {
281
145
  expect.assertions(2);
282
146
 
283
- const index = 1;
284
- const result = getPluginIdentifier(configuration, prefix, index);
147
+ const slot = 2;
148
+ const result = getPluginIdentifier(configuration, prefix, slot);
285
149
 
286
150
  const memoizedResult = memoizedGetPluginIdentifier(
287
151
  configuration,
288
152
  prefix,
289
- index
153
+ slot
290
154
  );
291
155
 
292
156
  expect(result).toEqual(configuration.tv_buttons_button_2_assign_action);
@@ -1,177 +1,68 @@
1
- import * as R from "ramda";
2
1
  import memoizee from "memoizee";
3
-
4
2
  import { isWeb } from "@applicaster/zapp-react-native-utils/reactUtils";
3
+ import { getEnabledButtonSlots } from "../../../ActionButtonsCore/selectors";
4
+ import {
5
+ insertBetweenLabelContainers,
6
+ insertBetweenLabels,
7
+ } from "../../../ActionButtonsCore/placement";
5
8
 
6
9
  export const getButtonsCount = (
7
10
  configuration: Record<string, unknown>,
8
11
  prefix: string
9
12
  ): number => {
10
- const button1Key = `${prefix}_button_1_button_enabled`;
11
- const button2Key = `${prefix}_button_2_button_enabled`;
12
- const button3Key = `${prefix}_button_3_button_enabled`;
13
-
14
- return R.toPairs(configuration).filter(
15
- ([key, value]) =>
16
- [button1Key, button2Key, button3Key].includes(key) && value
17
- ).length;
13
+ return getEnabledButtonSlots(configuration, `${prefix}_button`).length;
18
14
  };
19
15
 
20
16
  export const getPluginIdentifier = (
21
17
  configuration: Record<string, unknown>,
22
18
  prefix: string,
23
- index: number
19
+ slot: number
24
20
  ): string | undefined => {
25
- const re = new RegExp(`${prefix}_button_\\d_assign_action`);
26
- let count = 0;
27
-
28
- for (const [key, value] of Object.entries(configuration)) {
29
- if (
30
- key.startsWith(`${prefix}_button`) &&
31
- re.test(key) &&
32
- value != null &&
33
- value !== ""
34
- ) {
35
- if (count === index) return value as string;
36
- count++;
37
- }
38
- }
21
+ const value = configuration[
22
+ `${prefix}_button_${slot}_assign_action`
23
+ ] as string;
39
24
 
40
- return undefined;
25
+ return value == null || value === "" ? undefined : value;
41
26
  };
42
27
 
43
28
  export const memoizedGetPluginIdentifier = memoizee(getPluginIdentifier);
44
29
 
45
- type Label = {
46
- name: string;
47
- };
48
-
49
- type LabelContainer = {
50
- elements: Array<Label>;
51
- };
52
-
53
- type LabelExtraContainer = {
54
- elements: Array<LabelContainer>;
55
- };
56
-
57
- const withButtons = (labelName, buttons, labels) => {
58
- return labels.reduce((acc, label) => {
59
- if (label.name === labelName) {
60
- return [...acc, label, buttons];
61
- }
62
-
63
- return [...acc, label];
64
- }, []);
65
- };
66
-
67
- const withButtonsInContainer = (labelName, buttons, views) => {
68
- return views.map((view) => {
69
- return {
70
- ...view,
71
- elements: view.elements.reduce((acc, label) => {
72
- if (label.name === labelName) {
73
- return [...acc, label, buttons];
74
- }
75
-
76
- return [...acc, label];
77
- }, []),
78
- };
79
- });
80
- };
81
-
82
30
  export const insertButtonsBetweenLabels = (
83
31
  configuration: Record<string, unknown>,
84
32
  buttons,
85
- labels: Label[] = []
86
- ) => {
87
- if (R.isNil(buttons)) {
88
- return labels;
89
- }
90
-
91
- const position = R.pathOr(
92
- undefined,
93
- ["tv_buttons_container_position"],
94
- configuration
33
+ labels = []
34
+ ) =>
35
+ insertBetweenLabels(
36
+ {
37
+ position: configuration.tv_buttons_container_position as
38
+ | string
39
+ | undefined,
40
+ allowOnTop: true,
41
+ appendWhenMissing: true,
42
+ },
43
+ buttons,
44
+ labels
95
45
  );
96
46
 
97
- if (position === "on_top") {
98
- return [buttons, ...labels];
99
- }
100
-
101
- const labelsWithButtons = withButtons(position, buttons, labels);
102
-
103
- if (R.equals(labelsWithButtons, labels)) {
104
- // put buttons after all labels by default
105
- return [...labels, buttons];
106
- }
107
-
108
- return labelsWithButtons;
109
- };
110
-
111
47
  export const insertButtonsBetweenLabelContainers = (
112
48
  configuration: Record<string, unknown>,
113
49
  buttons,
114
- labelContainers: Array<LabelExtraContainer> = []
115
- ) => {
116
- if (R.isNil(buttons)) {
117
- return labelContainers;
118
- }
119
-
120
- if (R.isEmpty(labelContainers)) {
121
- return [buttons];
122
- }
123
-
124
- const position = R.pathOr(
125
- undefined,
126
- ["tv_buttons_container_position"],
127
- configuration
50
+ labelContainers = []
51
+ ) =>
52
+ insertBetweenLabelContainers(
53
+ {
54
+ position: configuration.tv_buttons_container_position as
55
+ | string
56
+ | undefined,
57
+ allowOnTop: true,
58
+ appendWhenMissing: true,
59
+ },
60
+ buttons,
61
+ labelContainers
128
62
  );
129
63
 
130
- if (position === "on_top") {
131
- const firstContainerLabels = R.lensPath([0, "elements"]);
132
-
133
- return R.over(firstContainerLabels, R.prepend(buttons), labelContainers);
134
- }
135
-
136
- const labelContainersWithButtons = labelContainers.map((labelContainer) => {
137
- return {
138
- ...labelContainer,
139
- elements: withButtonsInContainer(
140
- position,
141
- buttons,
142
- labelContainer.elements
143
- ),
144
- };
145
- });
146
-
147
- if (R.equals(labelContainersWithButtons, labelContainers)) {
148
- // put buttons in last container
149
- const lastContainerLabels = R.lensPath([
150
- labelContainers.length - 1,
151
- "elements",
152
- ]);
153
-
154
- return R.over(lastContainerLabels, R.append(buttons), labelContainers);
155
- }
156
-
157
- return labelContainersWithButtons;
158
- };
159
-
160
- export const mapSelfAlignment = (horizontalPosition) => {
161
- switch (horizontalPosition) {
162
- case "left":
163
- return "flex-start";
164
- case "right":
165
- return "flex-end";
166
- case "center":
167
- return "center";
168
- default:
169
- return "flex-start";
170
- }
171
- };
172
-
173
64
  export const getTextTransform = (textTransform: string) => {
174
- if (R.isNil(textTransform) || R.isEmpty(textTransform)) {
65
+ if (textTransform == null || textTransform === "") {
175
66
  return "none";
176
67
  }
177
68
 
@@ -19,6 +19,7 @@ const focusableTypes = new Set([
19
19
  "View",
20
20
  "ButtonContainerView",
21
21
  "FocusableView",
22
+ "PressableView",
22
23
  "CollapsibleTextContainer",
23
24
  "BorderContainerView",
24
25
  ]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "15.0.0-rc.129",
3
+ "version": "15.0.0-rc.131",
4
4
  "description": "Applicaster Zapp React Native ui components for the Quick Brick App",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -28,10 +28,10 @@
28
28
  },
29
29
  "homepage": "https://github.com/applicaster/quickbrick#readme",
30
30
  "dependencies": {
31
- "@applicaster/applicaster-types": "15.0.0-rc.129",
32
- "@applicaster/zapp-react-native-bridge": "15.0.0-rc.129",
33
- "@applicaster/zapp-react-native-redux": "15.0.0-rc.129",
34
- "@applicaster/zapp-react-native-utils": "15.0.0-rc.129",
31
+ "@applicaster/applicaster-types": "15.0.0-rc.131",
32
+ "@applicaster/zapp-react-native-bridge": "15.0.0-rc.131",
33
+ "@applicaster/zapp-react-native-redux": "15.0.0-rc.131",
34
+ "@applicaster/zapp-react-native-utils": "15.0.0-rc.131",
35
35
  "fast-json-stable-stringify": "^2.1.0",
36
36
  "promise": "^8.3.0",
37
37
  "url": "^0.11.0",