@applicaster/zapp-react-native-ui-components 16.0.0-alpha.1042942411 → 16.0.0-alpha.1054344748
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Components/AudioPlayer/tv/__tests__/audioPlayer.test.js +19 -0
- package/Components/AudioPlayer/tv/__tests__/index.test.tsx +120 -0
- package/Components/AudioPlayer/tv/index.tsx +5 -1
- package/Components/Cell/Cell.tsx +3 -6
- package/Components/Cell/TvOSCellComponent.tsx +0 -1
- package/Components/GeneralContentScreen/GeneralContentScreenHookAdapter.tsx +15 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/skipExpression.test.ts +294 -0
- package/Components/GeneralContentScreen/hookAdapter/__tests__/validationHelper.test.ts +64 -0
- package/Components/GeneralContentScreen/hookAdapter/skipExpression.ts +252 -0
- package/Components/GeneralContentScreen/hookAdapter/validationHelper.ts +18 -0
- package/Components/LinkHandler/LinkHandler.tsx +2 -7
- package/Components/MasterCell/DefaultComponents/ActionButton.tsx +64 -28
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/ActionButtonController.tsx +19 -4
- package/Components/MasterCell/DefaultComponents/ActionButtonsCore/components/__tests__/ActionButtonController.test.tsx +43 -1
- package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +46 -217
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +109 -46
- package/Components/MasterCell/DefaultComponents/Button.tsx +44 -50
- package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +14 -13
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/__tests__/withDimensions.test.ts +420 -125
- package/Components/MasterCell/DefaultComponents/Image/hoc/utils/index.ts +114 -19
- package/Components/MasterCell/DefaultComponents/Image/hoc/withDimensions.tsx +19 -8
- package/Components/MasterCell/DefaultComponents/LiveImage/executePreloadHooks.ts +2 -4
- package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -3
- package/Components/MasterCell/DefaultComponents/SecondaryImage/Image.tsx +50 -46
- package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +39 -47
- package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +6 -19
- package/Components/MasterCell/DefaultComponents/Text/index.tsx +15 -45
- package/Components/MasterCell/DefaultComponents/Toggle.tsx +36 -14
- package/Components/MasterCell/DefaultComponents/__tests__/Toggle.test.tsx +167 -0
- package/Components/MasterCell/DefaultComponents/__tests__/text.test.tsx +67 -196
- package/Components/MasterCell/DefaultComponents/index.ts +0 -4
- package/Components/MasterCell/DefaultComponents/mobile/MobileActionButtons/__tests__/PressableView.test.tsx +6 -4
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/factory.test.ts +32 -0
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/index.ts +1 -2
- package/Components/MasterCell/elementMapper.tsx +0 -2
- package/Components/ModalComponent/ActionsBottomSheet/ActionButton.tsx +56 -0
- package/Components/ModalComponent/ActionsBottomSheet/__tests__/openActionsBottomSheet.test.ts +38 -0
- package/Components/ModalComponent/ActionsBottomSheet/boundActionButton.tsx +24 -0
- package/Components/ModalComponent/ActionsBottomSheet/index.ts +9 -0
- package/Components/ModalComponent/ActionsBottomSheet/openActionsBottomSheet.ts +61 -0
- package/Components/ModalComponent/AudioPlayer/Components/Button.tsx +87 -97
- package/Components/ModalComponent/AudioPlayer/Components/Header.tsx +87 -126
- package/Components/ModalComponent/AudioPlayer/Components/Input.tsx +140 -83
- package/Components/ModalComponent/AudioPlayer/Components/Item.tsx +252 -123
- package/Components/ModalComponent/AudioPlayer/Components/NowPlayingHeaderSection.tsx +205 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/Item.test.tsx +113 -0
- package/Components/ModalComponent/AudioPlayer/Components/__tests__/NowPlayingHeaderSection.test.tsx +36 -0
- package/Components/ModalComponent/AudioPlayer/Components/index.ts +3 -3
- package/Components/ModalComponent/AudioPlayer/utils/__tests__/mergeStyles.test.ts +356 -0
- package/Components/ModalComponent/AudioPlayer/utils/mergeStyles.ts +521 -0
- package/Components/ModalComponent/BottomSheetModalContent.tsx +498 -66
- package/Components/ModalComponent/Button/index.tsx +5 -3
- package/Components/ModalComponent/Header/CloseButton.tsx +12 -0
- package/Components/ModalComponent/Header/__tests__/CloseButton.test.tsx +72 -0
- package/Components/ModalComponent/Header/index.tsx +20 -7
- package/Components/ModalComponent/Header/utils.ts +1 -1
- package/Components/ModalComponent/ModalBlocksStyleContext.tsx +10 -0
- package/Components/ModalComponent/SortableList.tsx +156 -0
- package/Components/ModalComponent/SortableList.web.tsx +34 -0
- package/Components/ModalComponent/TextInputContent.tsx +135 -0
- package/Components/ModalComponent/__tests__/BottomSheetModalContent.test.tsx +343 -0
- package/Components/ModalComponent/__tests__/SortableList.web.test.tsx +16 -0
- package/Components/ModalComponent/__tests__/TextInputContent.test.tsx +169 -0
- package/Components/ModalComponent/__tests__/showTextInput.test.ts +95 -0
- package/Components/ModalComponent/index.tsx +18 -9
- package/Components/ModalComponent/presets/__tests__/getCell.test.ts +90 -0
- package/Components/ModalComponent/presets/dynamicCollectionCell.tsx +78 -0
- package/Components/ModalComponent/presets/index.ts +27 -0
- package/Components/ModalComponent/presets/selectableCell.tsx +28 -0
- package/Components/ModalComponent/presets/standardCell.tsx +41 -0
- package/Components/ModalComponent/presets/types.ts +35 -0
- package/Components/ModalComponent/showTextInput.ts +52 -0
- package/Components/ModalComponent/utils.ts +82 -21
- package/Components/OfflineHandler/__tests__/index.test.tsx +109 -0
- package/Components/OfflineHandler/hooks.ts +0 -12
- package/Components/OfflineHandler/index.tsx +42 -4
- package/Components/PlayerContainer/PlayerContainer.tsx +19 -8
- package/Components/PlayerContainer/ProgramInfo/index.tsx +3 -4
- package/Components/PlayerContainer/__tests__/PlayerContainer.test.tsx +66 -13
- package/Components/River/ComponentsMap/ComponentsMap.tsx +85 -59
- package/Components/River/River.tsx +4 -0
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +138 -75
- package/Components/River/__tests__/componentsMap.test.js +8 -3
- package/Components/River/__tests__/resultCallback.test.tsx +47 -0
- package/Components/Screen/__tests__/Screen.test.tsx +24 -0
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +2 -0
- package/Components/Screen/index.tsx +5 -0
- package/Components/Screen/navigationHandler.ts +8 -8
- package/Components/ScreenRevealManager/ScreenRevealManager.ts +18 -2
- package/Components/ScreenRevealManager/__tests__/ScreenRevealManager.test.ts +36 -0
- package/Components/ScreenRevealManager/__tests__/withScreenRevealManager.test.tsx +56 -0
- package/Components/ScreenRevealManager/withScreenRevealManager.tsx +21 -4
- package/Components/Transitioner/AnimationManager.js +1 -1
- package/Components/Transitioner/Scene.tsx +4 -3
- package/Components/Transitioner/Transitioner.tsx +71 -33
- package/Components/Transitioner/__tests__/transitioner.test.js +372 -3
- package/Components/VideoLive/LiveImageManager.ts +9 -3
- package/Components/VideoLive/__tests__/LiveImageManager.test.ts +59 -0
- package/Contexts/ModalNavigationContext/__tests__/index.test.tsx +15 -0
- package/Contexts/ModalNavigationContext/index.tsx +2 -2
- package/Hooks/useEntryActionsExpander.ts +63 -0
- package/assets/empty-Info.png +0 -0
- package/package.json +6 -5
- package/Components/MasterCell/DefaultComponents/CellBadge/__tests__/__snapshots__/index.test.tsx.snap +0 -18
- package/Components/MasterCell/DefaultComponents/CellBadge/__tests__/index.test.tsx +0 -90
- package/Components/MasterCell/DefaultComponents/UIKitAdapters/Badge.tsx +0 -49
- package/Components/MasterCell/DefaultComponents/__tests__/ActionButton.test.tsx +0 -122
- package/Components/MasterCell/DefaultComponents/__tests__/Button.test.tsx +0 -186
- package/Components/MasterCell/DefaultComponents/__tests__/DynamicBadge.test.tsx +0 -156
- package/Components/MasterCell/DefaultComponents/__tests__/__snapshots__/ActionButton.test.tsx.snap +0 -60
- package/Components/ModalComponent/AudioPlayer/Components/Action.tsx +0 -332
- /package/Decorators/ZappPipesDataConnector/__tests__/{Hero.js → Hero.tsx} +0 -0
package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx
CHANGED
|
@@ -1,85 +1,26 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
import {
|
|
3
|
+
BorderContainerView,
|
|
4
|
+
getBorderPadding, // Export for testing (using a double underscore prefix is a common convention)
|
|
5
|
+
} from "../index";
|
|
6
|
+
import { render } from "@testing-library/react-native";
|
|
7
|
+
import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
8
|
+
import { View } from "react-native";
|
|
9
|
+
|
|
10
|
+
jest.mock("@applicaster/zapp-react-native-utils/numberUtils", () => ({
|
|
11
|
+
toNumberWithDefaultZero: jest.fn((value) => Number(value) || 0),
|
|
12
|
+
}));
|
|
10
13
|
|
|
11
14
|
jest.mock(
|
|
12
15
|
"@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks",
|
|
13
16
|
() => ({
|
|
14
17
|
useAccessibilityManager: jest.fn(() => ({
|
|
15
|
-
addHeading:
|
|
18
|
+
addHeading: jest.fn(),
|
|
16
19
|
})),
|
|
17
20
|
})
|
|
18
21
|
);
|
|
19
22
|
|
|
20
|
-
const createMockValue = () => {
|
|
21
|
-
const values = {
|
|
22
|
-
cell_padding_top: 1,
|
|
23
|
-
cell_padding_left: 2,
|
|
24
|
-
cell_padding_right: 3,
|
|
25
|
-
cell_padding_bottom: 4,
|
|
26
|
-
image_border_size: 5,
|
|
27
|
-
image_focused_border_color: "red",
|
|
28
|
-
image_selected_border_color: "blue",
|
|
29
|
-
image_focused_selected_border_color: "green",
|
|
30
|
-
image_border_color: "black",
|
|
31
|
-
image_corner_radius: 10,
|
|
32
|
-
image_border_position: "outside",
|
|
33
|
-
image_border_padding_top: 6,
|
|
34
|
-
image_border_padding_right: 7,
|
|
35
|
-
image_border_padding_bottom: 8,
|
|
36
|
-
image_border_padding_left: 9,
|
|
37
|
-
image_margin_top: 11,
|
|
38
|
-
image_margin_left: 12,
|
|
39
|
-
image_margin_right: 13,
|
|
40
|
-
image_margin_bottom: 14,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
return (key) => values[key] || 0;
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
const renderBorderContainer = (
|
|
47
|
-
overrideProps: Partial<any> = {},
|
|
48
|
-
measurementValue: React.ContextType<typeof MeasurementPortalContext> = null
|
|
49
|
-
) => {
|
|
50
|
-
const props = {
|
|
51
|
-
style: {
|
|
52
|
-
borderWidth: 4,
|
|
53
|
-
borderColor: "red",
|
|
54
|
-
borderRadius: 8,
|
|
55
|
-
backgroundColor: "navy",
|
|
56
|
-
},
|
|
57
|
-
testID: "border-container",
|
|
58
|
-
borderPosition: "outside" as const,
|
|
59
|
-
borderPaddingTop: 1,
|
|
60
|
-
borderPaddingRight: 2,
|
|
61
|
-
borderPaddingBottom: 3,
|
|
62
|
-
borderPaddingLeft: 4,
|
|
63
|
-
hasFocusableInside: jest.fn(() => false),
|
|
64
|
-
entry: { id: "test-entry", title: "Test title" } as ZappEntry,
|
|
65
|
-
state: "focused" as CellState,
|
|
66
|
-
hasTextLabels: false,
|
|
67
|
-
children: <View testID="child" />,
|
|
68
|
-
...overrideProps,
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
return render(
|
|
72
|
-
<MeasurementPortalContext.Provider value={measurementValue}>
|
|
73
|
-
<BorderContainerView {...props} />
|
|
74
|
-
</MeasurementPortalContext.Provider>
|
|
75
|
-
);
|
|
76
|
-
};
|
|
77
|
-
|
|
78
23
|
describe("BorderContainerView", () => {
|
|
79
|
-
beforeEach(() => {
|
|
80
|
-
jest.clearAllMocks();
|
|
81
|
-
});
|
|
82
|
-
|
|
83
24
|
describe("getBorderPadding", () => {
|
|
84
25
|
it("returns 0 for inside", () => {
|
|
85
26
|
expect(getBorderPadding("inside", 10)).toBe(0);
|
|
@@ -94,159 +35,47 @@ describe("BorderContainerView", () => {
|
|
|
94
35
|
});
|
|
95
36
|
|
|
96
37
|
it("returns borderWidth for invalid position", () => {
|
|
97
|
-
// @ts-ignore
|
|
38
|
+
// @ts-ignore
|
|
98
39
|
expect(getBorderPadding("other_value", 10)).toBe(10);
|
|
99
40
|
});
|
|
100
41
|
});
|
|
101
42
|
|
|
102
|
-
it("
|
|
103
|
-
const style =
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
const
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
const flattenedOverlayStyle = StyleSheet.flatten(overlayHost.props.style);
|
|
133
|
-
expect(flattenedOverlayStyle.borderWidth).toBe(6);
|
|
134
|
-
expect(flattenedOverlayStyle.borderColor).toBe("orange");
|
|
135
|
-
expect(flattenedOverlayStyle.top).toBe(-7);
|
|
136
|
-
expect(flattenedOverlayStyle.right).toBe(-8);
|
|
137
|
-
expect(flattenedOverlayStyle.bottom).toBe(-9);
|
|
138
|
-
expect(flattenedOverlayStyle.left).toBe(-10);
|
|
139
|
-
expect(flattenedOverlayStyle.borderTopLeftRadius).toBe(19);
|
|
140
|
-
expect(flattenedOverlayStyle.borderTopRightRadius).toBe(19);
|
|
141
|
-
expect(flattenedOverlayStyle.borderBottomLeftRadius).toBe(21);
|
|
142
|
-
expect(flattenedOverlayStyle.borderBottomRightRadius).toBe(20);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
it("renders no overlay when borderPosition is missing", () => {
|
|
146
|
-
const { getByTestId } = renderBorderContainer({
|
|
147
|
-
borderPosition: null,
|
|
148
|
-
});
|
|
149
|
-
|
|
150
|
-
const root = getByTestId("border-container");
|
|
151
|
-
|
|
152
|
-
expect(root.children).toHaveLength(2);
|
|
153
|
-
expect((root.children[0] as any).children).toHaveLength(0);
|
|
154
|
-
expect((root.children[1] as any).props.testID).toBe("child");
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it("preserves root pointerEvents defaults and caller overrides", () => {
|
|
158
|
-
const defaultRender = renderBorderContainer();
|
|
159
|
-
|
|
160
|
-
expect(
|
|
161
|
-
defaultRender.getByTestId("border-container").props.pointerEvents
|
|
162
|
-
).toBe("box-none");
|
|
163
|
-
|
|
164
|
-
const overrideRender = renderBorderContainer({
|
|
165
|
-
pointerEvents: "none",
|
|
166
|
-
testID: "override-border-container",
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
expect(
|
|
170
|
-
overrideRender.getByTestId("override-border-container").props
|
|
171
|
-
.pointerEvents
|
|
172
|
-
).toBe("none");
|
|
173
|
-
});
|
|
174
|
-
|
|
175
|
-
it("keeps the heading announcement logic in the QuickBrick wrapper", async () => {
|
|
176
|
-
renderBorderContainer({
|
|
177
|
-
entry: { id: "entry-1", title: "Hero title" } as ZappEntry,
|
|
178
|
-
state: "focused",
|
|
179
|
-
hasTextLabels: false,
|
|
180
|
-
hasFocusableInside: jest.fn(() => false),
|
|
181
|
-
});
|
|
182
|
-
|
|
183
|
-
await waitFor(() => {
|
|
184
|
-
expect(mockAddHeading).toHaveBeenCalledWith("Hero title");
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
it("suppresses the heading announcement while measurement is in progress", async () => {
|
|
189
|
-
renderBorderContainer(
|
|
190
|
-
{
|
|
191
|
-
entry: { id: "entry-1", title: "Hero title" } as ZappEntry,
|
|
192
|
-
},
|
|
193
|
-
{ measuringInProgress: true }
|
|
43
|
+
it("Border component renders null if no borderPosition", () => {
|
|
44
|
+
const style = { borderWidth: 5, borderRadius: 10, borderColor: "red" };
|
|
45
|
+
|
|
46
|
+
const padding = {
|
|
47
|
+
paddingTop: 2,
|
|
48
|
+
paddingRight: 3,
|
|
49
|
+
paddingBottom: 4,
|
|
50
|
+
paddingLeft: 5,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const borderPosition = null;
|
|
54
|
+
const mockEntry = { id: "test-entry" } as ZappEntry;
|
|
55
|
+
const mockHasFocusableInside = jest.fn(() => false);
|
|
56
|
+
|
|
57
|
+
const { queryByTestId } = render(
|
|
58
|
+
<BorderContainerView
|
|
59
|
+
style={style}
|
|
60
|
+
testID="border-container"
|
|
61
|
+
borderPosition={borderPosition}
|
|
62
|
+
borderPaddingTop={toNumberWithDefaultZero(padding.paddingTop)}
|
|
63
|
+
borderPaddingRight={toNumberWithDefaultZero(padding.paddingRight)}
|
|
64
|
+
borderPaddingBottom={toNumberWithDefaultZero(padding.paddingBottom)}
|
|
65
|
+
borderPaddingLeft={toNumberWithDefaultZero(padding.paddingLeft)}
|
|
66
|
+
hasFocusableInside={mockHasFocusableInside}
|
|
67
|
+
entry={mockEntry}
|
|
68
|
+
state="focused"
|
|
69
|
+
hasTextLabels={false}
|
|
70
|
+
>
|
|
71
|
+
<View testID="child" />
|
|
72
|
+
</BorderContainerView>
|
|
194
73
|
);
|
|
195
74
|
|
|
196
|
-
|
|
197
|
-
expect(mockAddHeading).not.toHaveBeenCalled();
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
it("stays compatible with the ImageBorderContainer caller path", () => {
|
|
202
|
-
const imageBorderConfig = ImageBorderContainer({
|
|
203
|
-
value: createMockValue(),
|
|
204
|
-
state: "default",
|
|
205
|
-
imageStyles: {
|
|
206
|
-
width: 100,
|
|
207
|
-
height: 60,
|
|
208
|
-
},
|
|
209
|
-
});
|
|
210
|
-
|
|
211
|
-
const { getByTestId } = renderBorderContainer({
|
|
212
|
-
style: imageBorderConfig.style,
|
|
213
|
-
pointerEvents: imageBorderConfig.additionalProps.pointerEvents,
|
|
214
|
-
borderPosition: imageBorderConfig.additionalProps.borderPosition,
|
|
215
|
-
borderPaddingTop: imageBorderConfig.additionalProps.borderPaddingTop,
|
|
216
|
-
borderPaddingRight: imageBorderConfig.additionalProps.borderPaddingRight,
|
|
217
|
-
borderPaddingBottom:
|
|
218
|
-
imageBorderConfig.additionalProps.borderPaddingBottom,
|
|
219
|
-
borderPaddingLeft: imageBorderConfig.additionalProps.borderPaddingLeft,
|
|
220
|
-
children: <View testID="image-border-child" />,
|
|
221
|
-
state: null,
|
|
222
|
-
hasTextLabels: true,
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
const root = getByTestId("border-container");
|
|
226
|
-
const overlay = root.children[0] as any;
|
|
227
|
-
const overlayHost = overlay.children[0] as any;
|
|
228
|
-
const child = root.children[1] as any;
|
|
229
|
-
|
|
230
|
-
expect(root.props.pointerEvents).toBe("none");
|
|
231
|
-
expect(child.props.testID).toBe("image-border-child");
|
|
232
|
-
|
|
233
|
-
const flattenedRootStyle = StyleSheet.flatten(root.props.style);
|
|
234
|
-
expect(flattenedRootStyle.borderRadius).toBe(10);
|
|
235
|
-
expect(flattenedRootStyle.marginTop).toBe(12);
|
|
236
|
-
expect(flattenedRootStyle.marginLeft).toBe(14);
|
|
237
|
-
expect(flattenedRootStyle.marginRight).toBe(16);
|
|
238
|
-
expect(flattenedRootStyle.marginBottom).toBe(18);
|
|
75
|
+
const children = queryByTestId("border-container").children;
|
|
239
76
|
|
|
240
|
-
expect(
|
|
241
|
-
expect(overlay.props.borderColor).toBe("black");
|
|
242
|
-
expect(overlay.props.borderRadius).toBe(10);
|
|
77
|
+
expect(children[1].props.testID).toBe("child");
|
|
243
78
|
|
|
244
|
-
|
|
245
|
-
expect(flattenedOverlayStyle.borderWidth).toBe(5);
|
|
246
|
-
expect(flattenedOverlayStyle.borderColor).toBe("black");
|
|
247
|
-
expect(flattenedOverlayStyle.borderTopLeftRadius).toBe(21);
|
|
248
|
-
expect(flattenedOverlayStyle.borderTopRightRadius).toBe(21);
|
|
249
|
-
expect(flattenedOverlayStyle.borderBottomLeftRadius).toBe(23);
|
|
250
|
-
expect(flattenedOverlayStyle.borderBottomRightRadius).toBe(22);
|
|
79
|
+
expect(children[0].children.length).toBe(0);
|
|
251
80
|
});
|
|
252
81
|
});
|
|
@@ -1,27 +1,18 @@
|
|
|
1
1
|
import React, { useMemo, useContext, useEffect } from "react";
|
|
2
|
-
import {
|
|
3
|
-
ImageStyle,
|
|
4
|
-
StyleProp,
|
|
5
|
-
StyleSheet,
|
|
6
|
-
ViewProps,
|
|
7
|
-
ViewStyle,
|
|
8
|
-
} from "react-native";
|
|
9
|
-
import {
|
|
10
|
-
BorderContainer as UIKitBorderContainer,
|
|
11
|
-
getBorderPadding,
|
|
12
|
-
type BorderPosition,
|
|
13
|
-
type UIKitBorderContainerProps,
|
|
14
|
-
} from "@applicaster/uikit/lib/components/uikit/border-container";
|
|
2
|
+
import { ImageStyle, StyleSheet, View, ViewStyle } from "react-native";
|
|
15
3
|
import { useAccessibilityManager } from "@applicaster/zapp-react-native-utils/appUtils/accessibilityManager/hooks";
|
|
4
|
+
import { toNumberWithDefaultZero } from "@applicaster/zapp-react-native-utils/numberUtils";
|
|
16
5
|
import { MeasurementPortalContext } from "../../../MeasurmentsPortal/MeasurementsPortal";
|
|
17
6
|
|
|
18
|
-
|
|
7
|
+
type BorderPosition = "inside" | "outside" | "center";
|
|
8
|
+
|
|
9
|
+
interface Props {
|
|
19
10
|
hasFocusableInside: (entry: ZappEntry) => boolean;
|
|
20
11
|
entry: ZappEntry;
|
|
21
12
|
state: CellState;
|
|
22
13
|
hasTextLabels: boolean;
|
|
23
|
-
style:
|
|
24
|
-
borderPosition
|
|
14
|
+
style: ImageStyle | ViewStyle;
|
|
15
|
+
borderPosition: BorderPosition;
|
|
25
16
|
borderPaddingTop: number;
|
|
26
17
|
borderPaddingRight: number;
|
|
27
18
|
borderPaddingBottom: number;
|
|
@@ -29,23 +20,100 @@ interface Props extends ViewProps {
|
|
|
29
20
|
children: React.ReactNode;
|
|
30
21
|
}
|
|
31
22
|
|
|
32
|
-
const
|
|
33
|
-
|
|
23
|
+
const COLOR_TRANSPARENT = "transparent";
|
|
24
|
+
|
|
25
|
+
const styles = StyleSheet.create({
|
|
26
|
+
container: {
|
|
27
|
+
overflow: "visible",
|
|
28
|
+
borderWidth: 0,
|
|
29
|
+
borderColor: COLOR_TRANSPARENT,
|
|
30
|
+
},
|
|
31
|
+
border: {
|
|
32
|
+
...StyleSheet.absoluteFillObject,
|
|
33
|
+
zIndex: 1,
|
|
34
|
+
},
|
|
35
|
+
});
|
|
34
36
|
|
|
35
|
-
|
|
37
|
+
export const getBorderPadding = (
|
|
38
|
+
borderPosition: BorderPosition,
|
|
39
|
+
borderWidth: number
|
|
40
|
+
) => {
|
|
41
|
+
switch (borderPosition) {
|
|
42
|
+
case "inside":
|
|
43
|
+
return 0;
|
|
44
|
+
case "center":
|
|
45
|
+
return borderWidth / 2;
|
|
46
|
+
case "outside":
|
|
47
|
+
return borderWidth;
|
|
48
|
+
default:
|
|
49
|
+
return borderWidth;
|
|
50
|
+
}
|
|
36
51
|
};
|
|
37
52
|
|
|
38
|
-
const
|
|
39
|
-
|
|
53
|
+
const Border = ({
|
|
54
|
+
style,
|
|
55
|
+
padding,
|
|
56
|
+
borderPosition,
|
|
57
|
+
}: {
|
|
58
|
+
style: ViewStyle;
|
|
59
|
+
padding: ViewStyle;
|
|
60
|
+
borderPosition: BorderPosition;
|
|
61
|
+
}) => {
|
|
62
|
+
if (!borderPosition) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
40
65
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
66
|
+
const borderWidth = toNumberWithDefaultZero(style.borderWidth);
|
|
67
|
+
const containerPadding = getBorderPadding(borderPosition, borderWidth);
|
|
68
|
+
|
|
69
|
+
const initialBorderRadius = toNumberWithDefaultZero(style.borderRadius);
|
|
70
|
+
const paddingTop = toNumberWithDefaultZero(padding.paddingTop);
|
|
71
|
+
const paddingRight = toNumberWithDefaultZero(padding.paddingRight);
|
|
72
|
+
const paddingBottom = toNumberWithDefaultZero(padding.paddingBottom);
|
|
73
|
+
const paddingLeft = toNumberWithDefaultZero(padding.paddingLeft);
|
|
74
|
+
|
|
75
|
+
const borderRadiusStyle = initialBorderRadius
|
|
76
|
+
? {
|
|
77
|
+
borderTopLeftRadius:
|
|
78
|
+
initialBorderRadius +
|
|
79
|
+
containerPadding +
|
|
80
|
+
Math.min(paddingTop, paddingLeft),
|
|
81
|
+
borderTopRightRadius:
|
|
82
|
+
initialBorderRadius +
|
|
83
|
+
containerPadding +
|
|
84
|
+
Math.min(paddingTop, paddingRight),
|
|
85
|
+
borderBottomLeftRadius:
|
|
86
|
+
initialBorderRadius +
|
|
87
|
+
containerPadding +
|
|
88
|
+
Math.min(paddingBottom, paddingLeft),
|
|
89
|
+
borderBottomRightRadius:
|
|
90
|
+
initialBorderRadius +
|
|
91
|
+
containerPadding +
|
|
92
|
+
Math.min(paddingBottom, paddingRight),
|
|
93
|
+
}
|
|
94
|
+
: {
|
|
95
|
+
borderTopLeftRadius: 0,
|
|
96
|
+
borderTopRightRadius: 0,
|
|
97
|
+
borderBottomLeftRadius: 0,
|
|
98
|
+
borderBottomRightRadius: 0,
|
|
99
|
+
};
|
|
47
100
|
|
|
48
|
-
|
|
101
|
+
return (
|
|
102
|
+
<View
|
|
103
|
+
pointerEvents="none"
|
|
104
|
+
style={{
|
|
105
|
+
...styles.border,
|
|
106
|
+
right: -containerPadding - paddingRight,
|
|
107
|
+
bottom: -containerPadding - paddingBottom,
|
|
108
|
+
left: -containerPadding - paddingLeft,
|
|
109
|
+
top: -containerPadding - paddingTop,
|
|
110
|
+
borderWidth,
|
|
111
|
+
borderColor: style.borderColor,
|
|
112
|
+
...borderRadiusStyle,
|
|
113
|
+
}}
|
|
114
|
+
/>
|
|
115
|
+
);
|
|
116
|
+
};
|
|
49
117
|
|
|
50
118
|
export const BorderContainerView = (props: Props) => {
|
|
51
119
|
const {
|
|
@@ -60,15 +128,11 @@ export const BorderContainerView = (props: Props) => {
|
|
|
60
128
|
entry,
|
|
61
129
|
state,
|
|
62
130
|
hasTextLabels,
|
|
63
|
-
...viewProps
|
|
64
131
|
} = props;
|
|
65
132
|
|
|
66
133
|
const accessibilityManager = useAccessibilityManager();
|
|
67
134
|
const isMeasurement = useContext(MeasurementPortalContext);
|
|
68
135
|
|
|
69
|
-
const { borderWidth, borderColor, borderRadius } =
|
|
70
|
-
getBorderPropsFromStyle(style);
|
|
71
|
-
|
|
72
136
|
const isImageOnlyCell = useMemo(
|
|
73
137
|
() =>
|
|
74
138
|
state === "focused" &&
|
|
@@ -84,21 +148,20 @@ export const BorderContainerView = (props: Props) => {
|
|
|
84
148
|
}
|
|
85
149
|
}, [isImageOnlyCell, entry?.title]);
|
|
86
150
|
|
|
151
|
+
const padding =
|
|
152
|
+
borderPosition === "outside"
|
|
153
|
+
? {
|
|
154
|
+
paddingTop: borderPaddingTop,
|
|
155
|
+
paddingRight: borderPaddingRight,
|
|
156
|
+
paddingBottom: borderPaddingBottom,
|
|
157
|
+
paddingLeft: borderPaddingLeft,
|
|
158
|
+
}
|
|
159
|
+
: {};
|
|
160
|
+
|
|
87
161
|
return (
|
|
88
|
-
<
|
|
89
|
-
|
|
90
|
-
{...viewProps}
|
|
91
|
-
style={style as UIKitBorderContainerProps["style"]}
|
|
92
|
-
borderPosition={borderPosition}
|
|
93
|
-
borderWidth={borderWidth}
|
|
94
|
-
borderColor={borderColor}
|
|
95
|
-
borderRadius={borderRadius}
|
|
96
|
-
borderPaddingTop={borderPaddingTop}
|
|
97
|
-
borderPaddingRight={borderPaddingRight}
|
|
98
|
-
borderPaddingBottom={borderPaddingBottom}
|
|
99
|
-
borderPaddingLeft={borderPaddingLeft}
|
|
100
|
-
>
|
|
162
|
+
<View pointerEvents="box-none" {...props} style={[style, styles.container]}>
|
|
163
|
+
<Border style={style} padding={padding} borderPosition={borderPosition} />
|
|
101
164
|
{children}
|
|
102
|
-
</
|
|
165
|
+
</View>
|
|
103
166
|
);
|
|
104
167
|
};
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import * as R from "ramda";
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { TouchableOpacity } from "react-native";
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { connectToStore } from "@applicaster/zapp-react-native-redux/utils/connectToStore";
|
|
7
|
+
import { useActions } from "@applicaster/zapp-react-native-utils/reactHooks/actions";
|
|
7
8
|
|
|
8
9
|
import Image from "./Image";
|
|
9
10
|
import { masterCellLogger } from "../logger";
|
|
@@ -21,43 +22,50 @@ type Props = {
|
|
|
21
22
|
style: {};
|
|
22
23
|
type: "Image" | "Svg" | "Lottie";
|
|
23
24
|
};
|
|
25
|
+
initiallyActive: boolean;
|
|
24
26
|
action: {
|
|
25
|
-
src?: Record<string, string | undefined>;
|
|
26
27
|
identifier: string;
|
|
27
28
|
type: string;
|
|
28
29
|
};
|
|
29
30
|
style: {};
|
|
31
|
+
plugins: [];
|
|
30
32
|
testID?: string;
|
|
31
33
|
accessibilityLabel?: string;
|
|
34
|
+
cellUUID?: string;
|
|
32
35
|
};
|
|
33
36
|
|
|
34
37
|
const components = {
|
|
35
38
|
Image,
|
|
36
39
|
};
|
|
37
40
|
|
|
38
|
-
|
|
39
|
-
const
|
|
41
|
+
function ButtonComponent(props: Props) {
|
|
42
|
+
const asset = props?.asset;
|
|
43
|
+
const item = props?.item;
|
|
44
|
+
const action = props?.action;
|
|
40
45
|
|
|
41
46
|
const assetType = asset?.type || "Image";
|
|
42
47
|
|
|
43
48
|
const ButtonAsset = components[assetType];
|
|
44
49
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
invokeAction?: (item: ZappEntry) => Promise<void>;
|
|
54
|
-
initialEntryState?: (...args: unknown[]) => unknown;
|
|
55
|
-
}
|
|
56
|
-
| undefined;
|
|
50
|
+
const actionContext = useActions(action?.identifier);
|
|
51
|
+
|
|
52
|
+
// TODO: better handling of missing plugin
|
|
53
|
+
if (!actionContext) {
|
|
54
|
+
// eslint-disable-next-line no-console
|
|
55
|
+
masterCellLogger.warning(
|
|
56
|
+
`You're missing an action plugin(${action?.identifier}) required by your button. \n Button can't be displayed`
|
|
57
|
+
);
|
|
57
58
|
|
|
58
|
-
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// if the action context implements the initialEntryState function, it
|
|
63
|
+
// means it uses the new Action Button API.
|
|
64
|
+
if (typeof actionContext?.initialEntryState === "function") {
|
|
65
|
+
return <ActionButton {...props} />;
|
|
66
|
+
}
|
|
59
67
|
|
|
60
|
-
const defaultIsSelected = R.includes(item, actionContext
|
|
68
|
+
const defaultIsSelected = R.includes(item, actionContext.state || []);
|
|
61
69
|
|
|
62
70
|
const isSelected = actionContext?.masterCell?.isSelected
|
|
63
71
|
? actionContext?.masterCell?.isSelected(item)
|
|
@@ -67,45 +75,31 @@ export function Button(props: Props) {
|
|
|
67
75
|
const assetSrc = isSelected ? asset?.src?.active : asset?.src?.inactive;
|
|
68
76
|
|
|
69
77
|
const favouritesAction = isSelected
|
|
70
|
-
? actionContext
|
|
71
|
-
: actionContext
|
|
78
|
+
? actionContext.removeFavourite
|
|
79
|
+
: actionContext.addFavourite;
|
|
72
80
|
|
|
73
81
|
const toggleAction = actionContext?.invokeAction ?? favouritesAction;
|
|
74
82
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
} catch (error) {
|
|
79
|
-
masterCellLogger.error(
|
|
80
|
-
`Error invoking action for button with item ${item?.id}`,
|
|
81
|
-
error
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
}, [item, toggleAction]);
|
|
85
|
-
|
|
86
|
-
if (!actionContext) {
|
|
87
|
-
masterCellLogger.warning(
|
|
88
|
-
`You're missing an action plugin(${action?.identifier}) required by your button. \n Button can't be displayed`
|
|
89
|
-
);
|
|
90
|
-
|
|
91
|
-
return null;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Action context is the preferred API when the plugin exposes initialEntryState (new Action Button API).
|
|
95
|
-
if (typeof actionContext?.initialEntryState === "function") {
|
|
96
|
-
return <ActionButton {...props} />;
|
|
83
|
+
async function onPress() {
|
|
84
|
+
// TODO: loading state
|
|
85
|
+
await toggleAction(item);
|
|
97
86
|
}
|
|
98
87
|
|
|
99
|
-
// Legacy button rendering with image inside is the default path for action contexts without initialEntryState.
|
|
100
88
|
return (
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
style={style}
|
|
104
|
-
testID={testID}
|
|
105
|
-
accessibilityLabel={accessibilityLabel}
|
|
89
|
+
<TouchableOpacity
|
|
90
|
+
activeOpacity={1}
|
|
106
91
|
onPress={onPress}
|
|
92
|
+
testID={props?.testID || `${item?.id}`}
|
|
93
|
+
accessibilityLabel={props?.accessibilityLabel || `${item?.id}`}
|
|
94
|
+
accessibilityRole="button"
|
|
95
|
+
accessible={!!(props?.testID || props?.accessibilityLabel)}
|
|
96
|
+
style={props?.style}
|
|
107
97
|
>
|
|
108
98
|
<ButtonAsset style={asset?.style} uri={assetSrc} {...asset?.props} />
|
|
109
|
-
</
|
|
99
|
+
</TouchableOpacity>
|
|
110
100
|
);
|
|
111
101
|
}
|
|
102
|
+
|
|
103
|
+
export const Button = R.compose(connectToStore(R.pick(["plugins"])))(
|
|
104
|
+
ButtonComponent
|
|
105
|
+
);
|
|
@@ -4,7 +4,10 @@ import {
|
|
|
4
4
|
ifElseSelected,
|
|
5
5
|
} from "@applicaster/zapp-react-native-utils/cellUtils";
|
|
6
6
|
import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
7
|
-
|
|
7
|
+
|
|
8
|
+
import { getPositionStyles } from "./utils";
|
|
9
|
+
|
|
10
|
+
const View = "View";
|
|
8
11
|
const Image = "Image";
|
|
9
12
|
|
|
10
13
|
type Props = {
|
|
@@ -27,24 +30,22 @@ export const CellBadge = ({
|
|
|
27
30
|
const position = value("cell_badge_position");
|
|
28
31
|
|
|
29
32
|
return {
|
|
30
|
-
type:
|
|
33
|
+
type: View, // Cell badge view
|
|
31
34
|
style: {
|
|
32
35
|
flex: platformSelect({
|
|
33
36
|
tvos: 0,
|
|
34
37
|
android_tv: 0,
|
|
35
38
|
default: 1,
|
|
36
39
|
}),
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
marginLeft: value("cell_badge_margin_left"),
|
|
47
|
-
},
|
|
40
|
+
position: "absolute",
|
|
41
|
+
...getPositionStyles(position, {
|
|
42
|
+
width: value("cell_badge_width"),
|
|
43
|
+
height: value("cell_badge_height"),
|
|
44
|
+
}),
|
|
45
|
+
marginTop: value("cell_badge_margin_top"),
|
|
46
|
+
marginRight: value("cell_badge_margin_right"),
|
|
47
|
+
marginBottom: value("cell_badge_margin_bottom"),
|
|
48
|
+
marginLeft: value("cell_badge_margin_left"),
|
|
48
49
|
},
|
|
49
50
|
elements: compact([
|
|
50
51
|
{
|