@applicaster/zapp-react-native-ui-components 12.0.0-rc.99 → 13.0.0-alpha.2322412833

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 (67) hide show
  1. package/Components/Cell/Cell.tsx +33 -18
  2. package/Components/Cell/CellWithFocusable.tsx +1 -1
  3. package/Components/Cell/TvOSCellComponent.tsx +3 -4
  4. package/Components/Focusable/__tests__/index.android.test.tsx +72 -0
  5. package/Components/Focusable/index.android.tsx +15 -9
  6. package/Components/FocusableList/FocusableChild.ts +2 -2
  7. package/Components/FocusableList/index.tsx +11 -12
  8. package/Components/FocusableScrollView/index.tsx +1 -1
  9. package/Components/FreezeWithCallback/Freeze.tsx +31 -0
  10. package/Components/FreezeWithCallback/LICENSE +21 -0
  11. package/Components/FreezeWithCallback/Suspender.tsx +17 -0
  12. package/Components/FreezeWithCallback/__tests__/index.test.tsx +170 -0
  13. package/Components/FreezeWithCallback/index.tsx +3 -0
  14. package/Components/Image/Image.android.tsx +1 -1
  15. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +11 -7
  16. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +1 -7
  17. package/Components/MasterCell/DefaultComponents/CellBadge/index.tsx +6 -1
  18. package/Components/MasterCell/DefaultComponents/FocusableView/index.tsx +12 -0
  19. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +6 -5
  20. package/Components/MasterCell/DefaultComponents/Image/Image.web.tsx +2 -2
  21. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/index.ts +71 -0
  22. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  23. package/Components/MasterCell/DefaultComponents/index.ts +2 -0
  24. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +7 -1
  25. package/Components/MasterCell/dataAdapter.ts +21 -7
  26. package/Components/MasterCell/index.tsx +5 -3
  27. package/Components/MasterCell/utils/index.ts +3 -4
  28. package/Components/NativeFocusables/{index.js → index.ts} +4 -2
  29. package/Components/PlayerContainer/PlayerContainer.tsx +14 -8
  30. package/Components/Screen/TV/hooks/index.ts +0 -2
  31. package/Components/Screen/TV/index.web.tsx +32 -19
  32. package/Components/Screen/__tests__/Screen.test.tsx +0 -49
  33. package/Components/Screen/index.tsx +2 -20
  34. package/Components/Screen/navigationHandler.ts +1 -3
  35. package/Components/Screen/orientationHandler.ts +18 -7
  36. package/Components/Screen/utils.ts +16 -0
  37. package/Components/ScreenResolver/index.tsx +6 -11
  38. package/Components/Transitioner/Scene.tsx +9 -2
  39. package/Components/Transitioner/Transitioner.tsx +38 -23
  40. package/Components/Transitioner/__tests__/Scene.test.js +7 -0
  41. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +1 -0
  42. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +5 -0
  43. package/Components/VideoModal/ModalAnimation/AnimatedPlayerModalWrapper.tsx +3 -9
  44. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +87 -41
  45. package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +20 -9
  46. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +41 -22
  47. package/Components/VideoModal/PlayerDetails.tsx +16 -2
  48. package/Components/VideoModal/PlayerWrapper.tsx +101 -67
  49. package/Components/VideoModal/VideoModal.tsx +33 -27
  50. package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +7 -0
  51. package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +2 -0
  52. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +78 -16
  53. package/Components/ZappFrameworkComponents/BarView/BarView.tsx +7 -3
  54. package/Components/ZappFrameworkComponents/BarView/Buttons/BackButton.tsx +7 -2
  55. package/Components/ZappFrameworkComponents/BarView/Buttons/CloseButton.tsx +7 -2
  56. package/Components/ZappFrameworkComponents/BarView/__tests__/BarView.test.tsx +87 -0
  57. package/Components/ZappFrameworkComponents/Buttons/ActionButton.tsx +9 -4
  58. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +4 -4
  59. package/Contexts/CachedDimensionsContext/index.ts +13 -9
  60. package/Contexts/ConfirmDialogState/index.ts +1 -1
  61. package/Contexts/ScreenContext/index.tsx +6 -1
  62. package/Decorators/Analytics/{index.js → index.tsx} +11 -11
  63. package/README.md +1 -13
  64. package/const.ts +6 -0
  65. package/index.js +3 -0
  66. package/package.json +5 -5
  67. package/Components/Screen/TV/hooks/useRestoreFocus.ts +0 -22
@@ -11,12 +11,16 @@ const renderEmptyView = () => {
11
11
  return <View style={emptyViewStyle} />;
12
12
  };
13
13
 
14
- type FloatingButtonProps = {
14
+ type FloatingButtonProps = Testable & {
15
15
  onPress: () => void;
16
16
  screenStyles: any;
17
17
  };
18
18
 
19
- const BackButton = ({ onPress, screenStyles }: FloatingButtonProps) => {
19
+ const BackButton = ({
20
+ onPress,
21
+ screenStyles,
22
+ testID = "backButton",
23
+ }: FloatingButtonProps) => {
20
24
  const containerStyle: any = {};
21
25
 
22
26
  if (!onPress) {
@@ -25,6 +29,7 @@ const BackButton = ({ onPress, screenStyles }: FloatingButtonProps) => {
25
29
 
26
30
  return (
27
31
  <ActionButton
32
+ testID={`${testID}-actionButton`}
28
33
  onPress={onPress}
29
34
  buttonStyles={containerStyle}
30
35
  imageUrl={screenStyles.back_button_image}
@@ -11,12 +11,16 @@ const renderEmptyView = () => {
11
11
  return <View style={emptyViewStyle} />;
12
12
  };
13
13
 
14
- type CloseButtonProps = {
14
+ type CloseButtonProps = Testable & {
15
15
  onPress: () => void;
16
16
  screenStyles?: any;
17
17
  };
18
18
 
19
- const CloseButton = ({ onPress, screenStyles }: CloseButtonProps) => {
19
+ const CloseButton = ({
20
+ onPress,
21
+ screenStyles,
22
+ testID = "closeButton",
23
+ }: CloseButtonProps) => {
20
24
  const containerStyle: any = {};
21
25
 
22
26
  if (!onPress) {
@@ -25,6 +29,7 @@ const CloseButton = ({ onPress, screenStyles }: CloseButtonProps) => {
25
29
 
26
30
  return (
27
31
  <ActionButton
32
+ testID={`${testID}-actionButton`}
28
33
  onPress={onPress}
29
34
  buttonStyles={containerStyle}
30
35
  imageUrl={screenStyles.close_button_image}
@@ -0,0 +1,87 @@
1
+ import React from "react";
2
+ import { renderWithProviders } from "@applicaster/zapp-react-native-utils/testUtils";
3
+ import { fireEvent } from "@testing-library/react-native";
4
+
5
+ const mockUseIsRTL = jest.fn(() => true);
6
+
7
+ jest.mock("@applicaster/zapp-react-native-utils/localizationUtils", () => ({
8
+ useIsRTL: mockUseIsRTL,
9
+ }));
10
+
11
+ const BarView = require("../BarView").default;
12
+
13
+ describe("BarView", () => {
14
+ const screenStyles = {
15
+ title_font_color: "#000",
16
+ title_font_android: "Roboto",
17
+ title_font_ios: "San Francisco",
18
+ title_font_size: "16",
19
+ background_color: "#fff",
20
+ };
21
+
22
+ const barState = {
23
+ backHandler: jest.fn(),
24
+ closeHandler: jest.fn(),
25
+ title: "Test Title",
26
+ };
27
+
28
+ beforeEach(() => {
29
+ jest.clearAllMocks();
30
+ });
31
+
32
+ it("renders without crashing", () => {
33
+ mockUseIsRTL.mockReturnValue(false);
34
+
35
+ const { getByText } = renderWithProviders(
36
+ <BarView screenStyles={screenStyles} barState={barState} />
37
+ );
38
+
39
+ expect(getByText("Test Title")).toBeTruthy();
40
+ });
41
+
42
+ it("applies RTL styles when isRTL is true", () => {
43
+ mockUseIsRTL.mockReturnValue(true);
44
+
45
+ const { getByTestId } = renderWithProviders(
46
+ <BarView screenStyles={screenStyles} barState={barState} />
47
+ );
48
+
49
+ expect(getByTestId("BarView-safeAreaView").props.style).toContainEqual({
50
+ transform: [{ scaleX: -1 }],
51
+ });
52
+ });
53
+
54
+ it("does not apply RTL styles when isRTL is false", () => {
55
+ mockUseIsRTL.mockReturnValue(false);
56
+
57
+ const { getByTestId } = renderWithProviders(
58
+ <BarView screenStyles={screenStyles} barState={barState} />
59
+ );
60
+
61
+ expect(getByTestId("BarView-safeAreaView").props.style).not.toContainEqual({
62
+ transform: [{ scaleX: -1 }],
63
+ });
64
+ });
65
+
66
+ it("calls closeHandler when CloseButton is pressed", () => {
67
+ mockUseIsRTL.mockReturnValue(false);
68
+
69
+ const { getByTestId } = renderWithProviders(
70
+ <BarView screenStyles={screenStyles} barState={barState} />
71
+ );
72
+
73
+ fireEvent.press(getByTestId("closeButton-actionButton-touchable"));
74
+ expect(barState.closeHandler).toHaveBeenCalled();
75
+ });
76
+
77
+ it("calls backHandler when BackButton is pressed", () => {
78
+ mockUseIsRTL.mockReturnValue(false);
79
+
80
+ const { getByTestId } = renderWithProviders(
81
+ <BarView screenStyles={screenStyles} barState={barState} />
82
+ );
83
+
84
+ fireEvent.press(getByTestId("backButton-actionButton-touchable"));
85
+ expect(barState.backHandler).toHaveBeenCalled();
86
+ });
87
+ });
@@ -28,7 +28,7 @@ styles: {
28
28
  }
29
29
  */
30
30
 
31
- type ActionButtonProps = {
31
+ type ActionButtonProps = Testable & {
32
32
  onPress: () => void;
33
33
  buttonStyles: any;
34
34
  imageUrl: string;
@@ -46,11 +46,16 @@ const ActionButton = ({
46
46
  buttonStyles,
47
47
  imageUrl,
48
48
  imageStyle = closeButtonStyle,
49
+ testID,
49
50
  }: ActionButtonProps) => {
50
51
  return (
51
- <View style={buttonStyles}>
52
- <TouchableOpacity onPress={onPress}>
53
- <Image source={{ uri: imageUrl }} style={imageStyle} />
52
+ <View style={buttonStyles} testID={testID}>
53
+ <TouchableOpacity onPress={onPress} testID={`${testID}-touchable`}>
54
+ <Image
55
+ source={{ uri: imageUrl }}
56
+ style={imageStyle}
57
+ testID={`${testID}-image`}
58
+ />
54
59
  </TouchableOpacity>
55
60
  </View>
56
61
  );
@@ -16,9 +16,9 @@ exports[`DefaultCellRenderer returns a react component and it renders correctly
16
16
  store={null}
17
17
  style={
18
18
  Object {
19
- "backgroundColor": "#CCC",
19
+ "backgroundColor": "transparent",
20
20
  "margin": 12,
21
- "opacity": 0.6,
21
+ "opacity": 1,
22
22
  "width": 169,
23
23
  }
24
24
  }
@@ -105,7 +105,7 @@ exports[`DefaultCellRenderer returns a react component for LG TVs 1`] = `
105
105
  store={null}
106
106
  style={
107
107
  Object {
108
- "backgroundColor": "rgba(252,70,27,1.0)",
108
+ "backgroundColor": "rgba(47,47,47,1.0)",
109
109
  "borderRadius": 4,
110
110
  "flex": 1,
111
111
  "overflow": "hidden",
@@ -238,7 +238,7 @@ exports[`DefaultCellRenderer returns a react component for Samsung TVs 1`] = `
238
238
  store={null}
239
239
  style={
240
240
  Object {
241
- "backgroundColor": "rgba(252,70,27,1.0)",
241
+ "backgroundColor": "rgba(47,47,47,1.0)",
242
242
  "borderRadius": 4,
243
243
  "flex": 1,
244
244
  "overflow": "hidden",
@@ -1,5 +1,6 @@
1
1
  import { create, useStore } from "zustand";
2
2
  import { produce } from "immer";
3
+ import { useCallback, useMemo } from "react";
3
4
 
4
5
  type Dimensions = {
5
6
  width: Option<number>;
@@ -31,16 +32,19 @@ export const useCachedDimensions = (id: string) => {
31
32
  dimensionsStore
32
33
  ) as DimensionsState;
33
34
 
34
- const getCachedDimensions = () => {
35
+ const getCachedDimensions = useCallback(() => {
35
36
  return dimensions[id] || initialDimensions();
36
- };
37
+ }, [dimensions?.[id], id]);
37
38
 
38
- const handleSetCachedDimensions = (newDimensions) => {
39
+ const handleSetCachedDimensions = useCallback((newDimensions) => {
39
40
  setCachedDimensions(id, newDimensions);
40
- };
41
-
42
- return {
43
- getCachedDimensions,
44
- setCachedDimensions: handleSetCachedDimensions,
45
- };
41
+ }, []);
42
+
43
+ return useMemo(
44
+ () => ({
45
+ getCachedDimensions,
46
+ setCachedDimensions: handleSetCachedDimensions,
47
+ }),
48
+ [getCachedDimensions, handleSetCachedDimensions]
49
+ );
46
50
  };
@@ -2,7 +2,7 @@ import { createStore } from "zustand/vanilla";
2
2
  import { useStore } from "zustand";
3
3
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
4
4
 
5
- interface ConfirmationDialogState {
5
+ export interface ConfirmationDialogState {
6
6
  isDialogVisible: boolean;
7
7
  messages: string;
8
8
  confirmAction: () => void;
@@ -177,7 +177,12 @@ export function withScreenContext(Component: React.ComponentType<any>) {
177
177
  return function WithScreenContextWrapper(props) {
178
178
  return (
179
179
  <ScreenContext.Consumer>
180
- {(value) => <Component {...props} screenContext={value} />}
180
+ {useCallback(
181
+ (value) => (
182
+ <Component {...props} screenContext={value} />
183
+ ),
184
+ [Component, props]
185
+ )}
181
186
  </ScreenContext.Consumer>
182
187
  );
183
188
  };
@@ -5,18 +5,18 @@ import { usePickFromState } from "@applicaster/zapp-react-native-redux/hooks";
5
5
 
6
6
  type ComponentProps = {
7
7
  component: {
8
- id: string,
9
- rules: { item_limit: number, component_cells_selectable: boolean },
10
- component_type: string,
8
+ id: string;
9
+ rules: { item_limit: number; component_cells_selectable: boolean };
10
+ component_type: string;
11
11
  styles: {
12
- cell_style: string,
13
- header: { visible: boolean },
14
- component_cells_selectable: boolean,
15
- },
16
- },
17
- zappPipesData: { url: string, data: { title: string } },
18
- selected: boolean,
19
- assets: { menu_button: string },
12
+ cell_style: string;
13
+ header: { visible: boolean };
14
+ component_cells_selectable: boolean;
15
+ };
16
+ };
17
+ zappPipesData: { url: string; data: { title: string } };
18
+ selected: boolean;
19
+ assets: { menu_button: string };
20
20
  };
21
21
 
22
22
  function withAnalytics(Component) {
package/README.md CHANGED
@@ -78,17 +78,6 @@ export default MyAwesomeComponent;
78
78
  export { MyAwesomeComponent } from "./MyAwesomeComponent";
79
79
  ```
80
80
 
81
- We provide flow types for component props - please use it to make sure your component will be compliant
82
-
83
- ```javascript
84
- import * as React from "react";
85
- import type { ZappComponentProps } from "../../flow-types"; // in the root of the project
86
-
87
- export class MyComponent extends React.Component<ZappComponentProps> {
88
- /* ... */
89
- }
90
- ```
91
-
92
81
  ## Connecting my component to Zapp Pipes
93
82
 
94
83
  Zapp App components rely on [Zapp-Pipes](https://github.com/applicaster/zapp-pipes) to load data.
@@ -100,10 +89,9 @@ In order to connect your component to ZappPipes, you simply need to use the `Zap
100
89
  import * as React from "react";
101
90
  import { View, Text } from "react-native";
102
91
  import { zappPipesDataConnector } from "../ZappPipesDataConnector";
103
- import type { ZappComponentProps } from "../../flow-types";
104
92
 
105
93
  @zappPipesDataConnector
106
- export class MyComponent extends React.Component<ZappComponentProps> {
94
+ export class MyComponent extends React.Component {
107
95
  renderComponent = (data) => {
108
96
  return (
109
97
  <View>
package/const.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { ViewStyle } from "react-native";
2
+
1
3
  export const tvPluginsWithCellRenderer = [
2
4
  "group-qb",
3
5
  "gallery-qb",
@@ -5,3 +7,7 @@ export const tvPluginsWithCellRenderer = [
5
7
  "hero-qb",
6
8
  "list-qb",
7
9
  ];
10
+
11
+ // Can't be used in StyleSheet.create, need to be inline/defined as a constant
12
+ // https://github.com/necolas/react-native-web/issues/1427
13
+ export const flatListOverflowStyle: ViewStyle = { overflow: "visible" };
package/index.js CHANGED
@@ -1,3 +1,6 @@
1
1
  import * as QuickBrickComponents from "./Components";
2
+ import { flatListOverflowStyle } from "./const";
3
+
4
+ export { flatListOverflowStyle };
2
5
 
3
6
  export default QuickBrickComponents;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "12.0.0-rc.99",
3
+ "version": "13.0.0-alpha.2322412833",
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",
@@ -34,10 +34,10 @@
34
34
  "redux-mock-store": "^1.5.3"
35
35
  },
36
36
  "dependencies": {
37
- "@applicaster/applicaster-types": "12.0.0-rc.99",
38
- "@applicaster/zapp-react-native-bridge": "12.0.0-rc.99",
39
- "@applicaster/zapp-react-native-redux": "12.0.0-rc.99",
40
- "@applicaster/zapp-react-native-utils": "12.0.0-rc.99",
37
+ "@applicaster/applicaster-types": "13.0.0-alpha.2322412833",
38
+ "@applicaster/zapp-react-native-bridge": "13.0.0-alpha.2322412833",
39
+ "@applicaster/zapp-react-native-redux": "13.0.0-alpha.2322412833",
40
+ "@applicaster/zapp-react-native-utils": "13.0.0-alpha.2322412833",
41
41
  "promise": "^8.3.0",
42
42
  "react-router-native": "^5.1.2",
43
43
  "url": "^0.11.0",
@@ -1,22 +0,0 @@
1
- import * as React from "react";
2
- import { isNil } from "ramda";
3
- import { useIsScreenActive } from "@applicaster/zapp-react-native-utils/reactHooks/navigation";
4
- import { usePrevious } from "@applicaster/zapp-react-native-utils/reactHooks/utils";
5
- import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
6
-
7
- export const useRestoreFocus = (): void => {
8
- const isScreenActive = useIsScreenActive();
9
- const previousIsScreenActive = usePrevious(isScreenActive);
10
-
11
- React.useEffect(() => {
12
- if (isNil(previousIsScreenActive)) {
13
- // it's initial mounting of the screen, do nothing here
14
- return;
15
- }
16
-
17
- if (!previousIsScreenActive && isScreenActive) {
18
- // restore focus when we go back from next screen
19
- focusManager.setInitialFocus();
20
- }
21
- }, [previousIsScreenActive, isScreenActive]);
22
- };