@applicaster/zapp-react-native-ui-components 13.0.0-alpha.7222542422 → 13.0.0-alpha.7223526501

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 (124) hide show
  1. package/Components/AnimatedInOut/index.tsx +5 -3
  2. package/Components/AppContainer/__tests__/AppContainer.test.js +4 -6
  3. package/Components/AudioPlayer/__tests__/Runtime.test.js +5 -8
  4. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +54 -111
  5. package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +36 -20
  6. package/Components/AudioPlayer/__tests__/artWork.test.js +3 -5
  7. package/Components/AudioPlayer/__tests__/audioPlayer.test.js +3 -5
  8. package/Components/AudioPlayer/__tests__/audioPlayerLayout.test.js +7 -8
  9. package/Components/AudioPlayer/__tests__/channel.test.js +3 -5
  10. package/Components/AudioPlayer/__tests__/summary.test.js +3 -5
  11. package/Components/AudioPlayer/__tests__/title.test.js +3 -5
  12. package/Components/BaseFocusable/index.ios.ts +1 -1
  13. package/Components/BaseFocusable/index.tsx +2 -3
  14. package/Components/Cell/Cell.tsx +7 -3
  15. package/Components/Cell/CellWithFocusable.tsx +43 -58
  16. package/Components/Cell/__tests__/CellWIthFocusable.test.js +13 -6
  17. package/Components/CellRendererResolver/__tests__/cellRendererResolver.test.js +46 -48
  18. package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +1 -42
  19. package/Components/ComponentResolver/__tests__/componentResolver.test.js +16 -22
  20. package/Components/ContentScreen/__tests__/contentScreen.test.js +3 -3
  21. package/Components/ErrorScreen/index.tsx +6 -6
  22. package/Components/Focusable/Focusable.tsx +1 -0
  23. package/Components/Focusable/Touchable.tsx +19 -20
  24. package/Components/Focusable/index.android.tsx +10 -3
  25. package/Components/FocusableGroup/FocusableTvOS.tsx +34 -83
  26. package/Components/FocusableGroup/index.tsx +1 -3
  27. package/Components/FocusableList/index.tsx +1 -0
  28. package/Components/FocusableScrollView/index.tsx +6 -3
  29. package/Components/Layout/TV/NavBarContainer.tsx +14 -19
  30. package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +3 -2
  31. package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +3 -2
  32. package/Components/MasterCell/DefaultComponents/ActionButton.tsx +2 -3
  33. package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +66 -0
  34. package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -1
  35. package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +5 -11
  36. package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +93 -0
  37. package/Components/MasterCell/DefaultComponents/LiveImage/index.tsx +2 -2
  38. package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
  39. package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
  40. package/Components/MasterCell/SharedUI/ProgressBar/hooks/useFillInPercent.ts +2 -8
  41. package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +4 -12
  42. package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +0 -229
  43. package/Components/MasterCell/__tests__/elementMapper.test.js +18 -5
  44. package/Components/MasterCell/__tests__/masterCell.test.js +26 -26
  45. package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
  46. package/Components/MasterCell/utils/index.ts +1 -1
  47. package/Components/ModalComponent/Button/index.tsx +6 -6
  48. package/Components/ModalComponent/Header/index.tsx +3 -3
  49. package/Components/OfflineHandler/NotificationView/NotificationView.lg.tsx +2 -2
  50. package/Components/OfflineHandler/NotificationView/NotificationView.samsung.tsx +2 -2
  51. package/Components/OfflineHandler/NotificationView/__tests__/index.test.tsx +0 -5
  52. package/Components/PlayerContainer/PlayerContainer.tsx +8 -8
  53. package/Components/PlayerContainer/ProgramInfo/index.tsx +2 -2
  54. package/Components/PlayerImageBackground/index.tsx +23 -3
  55. package/Components/River/ComponentsMap/ComponentsMap.tsx +39 -66
  56. package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
  57. package/Components/River/RiverFooter.tsx +39 -9
  58. package/Components/River/RiverItem.tsx +37 -2
  59. package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +100 -31
  60. package/Components/River/__tests__/__snapshots__/river.test.js.snap +20 -82
  61. package/Components/River/__tests__/componentsMap.test.js +17 -5
  62. package/Components/River/__tests__/river.test.js +75 -40
  63. package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +11 -4
  64. package/Components/RouteManager/__tests__/routeManager.test.js +29 -14
  65. package/Components/RouteManager/__tests__/testId.test.js +8 -6
  66. package/Components/Screen/hooks.ts +56 -0
  67. package/Components/Screen/index.tsx +16 -42
  68. package/Components/ScreenResolver/__tests__/screenResolver.test.js +91 -70
  69. package/Components/Tabs/Tab.tsx +11 -9
  70. package/Components/TextInputTv/index.tsx +4 -3
  71. package/Components/Transitioner/AnimationManager.js +8 -8
  72. package/Components/Transitioner/Scene.tsx +53 -24
  73. package/Components/Transitioner/Transitioner.tsx +3 -3
  74. package/Components/Transitioner/__tests__/Scene.test.js +25 -14
  75. package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +9 -49
  76. package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +2 -2
  77. package/Components/Transitioner/__tests__/transitioner.test.js +13 -4
  78. package/Components/Transitioner/index.js +8 -4
  79. package/Components/VideoLive/LiveImageManager.ts +27 -1
  80. package/Components/VideoLive/PlayerLiveImageComponent.tsx +32 -24
  81. package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +51 -1
  82. package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +0 -5
  83. package/Components/VideoLive/animationUtils.ts +7 -4
  84. package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +11 -11
  85. package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +14 -13
  86. package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +2 -3
  87. package/Components/VideoModal/ModalAnimation/utils.ts +2 -2
  88. package/Components/VideoModal/OpaqueLayer.tsx +33 -0
  89. package/Components/VideoModal/PlayerDetails.tsx +9 -6
  90. package/Components/VideoModal/PlayerWrapper.tsx +17 -36
  91. package/Components/VideoModal/VideoModal.tsx +14 -23
  92. package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +1 -1
  93. package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +0 -90
  94. package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +89 -0
  95. package/Components/VideoModal/hooks/index.ts +7 -0
  96. package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +49 -0
  97. package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +91 -0
  98. package/Components/VideoModal/hooks/utils/index.ts +33 -0
  99. package/Components/VideoModal/utils.ts +1 -1
  100. package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +24 -36
  101. package/Components/Viewport/ViewportAware/__tests__/viewportAware.test.js +12 -18
  102. package/Components/Viewport/__tests__/utils.test.js +5 -4
  103. package/Components/ZappUIComponent/Placeholder.tsx +3 -1
  104. package/Components/ZappUIComponent/__tests__/{ZappUIComponent.test.js → ZappUIComponent.test.tsx} +26 -10
  105. package/Components/ZappUIComponent/index.tsx +3 -16
  106. package/Components/default-cell-renderer/__tests__/defaultCellRenderer.test.tsx +20 -17
  107. package/Components/default-cell-renderer/viewTrees/tv/DefaultCell/__tests__/DefaultCell.test.tsx +15 -11
  108. package/Contexts/ComponentsMapOffsetContext/index.tsx +14 -6
  109. package/Contexts/ScreenContext/index.tsx +3 -2
  110. package/Decorators/Navigator/__tests__/navigator.test.js +16 -16
  111. package/Decorators/Navigator/index.tsx +1 -1
  112. package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +18 -24
  113. package/Decorators/RiverResolver/index.tsx +1 -1
  114. package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
  115. package/Decorators/ZappPipesDataConnector/__tests__/zappPipesDataConnector.test.js +29 -22
  116. package/Decorators/ZappPipesDataConnector/index.tsx +31 -1
  117. package/package.json +7 -7
  118. package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +0 -53
  119. package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +0 -17
  120. package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +0 -17
  121. package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +0 -91
  122. package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +0 -338
  123. package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +0 -18
  124. package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +0 -28
@@ -1,7 +1,7 @@
1
1
  import { View } from "react-native";
2
2
  import React from "react";
3
3
  import { act, render } from "@testing-library/react-native";
4
- import { CellWithFocusable } from "../CellWithFocusable";
4
+ import { CellWithFocusable } from "../CellWithFocusable.tsx";
5
5
 
6
6
  import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
7
7
 
@@ -23,7 +23,9 @@ describe("CellWithFocusable", () => {
23
23
 
24
24
  const wrapper = renderWith(props);
25
25
 
26
- expect(wrapper.UNSAFE_getByType("View").props.state).toBe("default");
26
+ const element = wrapper.getByTestId("cell-with-focusable-cell-renderer");
27
+
28
+ expect(element.props.state).toBe("default");
27
29
  });
28
30
 
29
31
  it("should render in default state", () => {
@@ -40,8 +42,9 @@ describe("CellWithFocusable", () => {
40
42
  focusManager.isGroupItemFocused = jest.fn(() => true);
41
43
 
42
44
  const wrapper = renderWith(props);
45
+ const element = wrapper.getByTestId("cell-with-focusable-cell-renderer");
43
46
 
44
- expect(wrapper.UNSAFE_getByType("View").props.state).toBe("default");
47
+ expect(element.props.state).toBe("default");
45
48
  });
46
49
 
47
50
  it("should render in focused state", () => {
@@ -55,13 +58,17 @@ describe("CellWithFocusable", () => {
55
58
  scrollTo: jest.fn(),
56
59
  };
57
60
 
58
- focusManager.isGroupItemFocused = jest.fn(() => true);
59
61
  const wrapper = renderWith(props);
60
62
 
63
+ const focusableGroupComponent = wrapper.getByTestId(
64
+ "cell-with-focusable-cell-renderer-focusable-group"
65
+ );
66
+
61
67
  act(() => {
62
- focusManager.on.mock.calls[focusManager.on.mock.calls.length - 1][1]();
68
+ focusableGroupComponent.props.onFocus();
63
69
  });
64
70
 
65
- expect(wrapper.UNSAFE_getByType("View").props.state).toBe("focused");
71
+ const element = wrapper.getByTestId("cell-with-focusable-cell-renderer");
72
+ expect(element.props.state).toBe("focused");
66
73
  });
67
74
  });
@@ -1,6 +1,7 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
- import { shallow } from "enzyme";
3
+ import { render } from "@testing-library/react-native";
4
+ import { CellRendererResolver } from "../";
4
5
 
5
6
  jest.mock("../../default-cell-renderer", () => {
6
7
  const View = jest.requireActual("react-native").View;
@@ -8,8 +9,6 @@ jest.mock("../../default-cell-renderer", () => {
8
9
  return jest.fn((prop) => <View whoAmI="default renderer" someProp={prop} />);
9
10
  });
10
11
 
11
- const { CellRendererResolver } = require("../index");
12
-
13
12
  const component = {
14
13
  styles: {
15
14
  cell_plugin_configuration_id: "ABCDE-123456",
@@ -45,17 +44,9 @@ describe("CellRendererResolver", () => {
45
44
  cellStyles,
46
45
  });
47
46
 
48
- it("renders correctly", () => {
49
- const result = shallow(
50
- getResult({ component, plugins, styles, cellStyles })
51
- );
52
-
53
- expect(result).toMatchSnapshot();
54
- });
55
-
56
47
  describe("with a default renderer plugin", () => {
57
48
  it("renders correctly", () => {
58
- const result = shallow(
49
+ const { UNSAFE_root } = render(
59
50
  getResult({
60
51
  component,
61
52
  plugins,
@@ -64,56 +55,63 @@ describe("CellRendererResolver", () => {
64
55
  })
65
56
  );
66
57
 
67
- expect(result).toMatchSnapshot();
58
+ expect(UNSAFE_root).toBeDefined();
68
59
  });
69
60
 
70
61
  it("returns default plugin if component has no cell_plugin_configuration_id", () => {
71
- const result = getResult({
72
- component: {},
73
- plugins,
74
- styles,
75
- cellStyles,
76
- });
77
-
78
- expect(result).toBeDefined();
79
- expect(result.props.whoAmI).toEqual("default renderer");
62
+ const { UNSAFE_getByProps } = render(
63
+ getResult({
64
+ component: {},
65
+ plugins,
66
+ styles,
67
+ cellStyles,
68
+ })
69
+ );
70
+
71
+ expect(UNSAFE_getByProps({ whoAmI: "default renderer" })).toBeTruthy();
80
72
  });
81
73
 
82
74
  it("returns default plugin if requested cell plugin configuration does not exist", () => {
83
- const result = getResult({
84
- component: { styles: { cell_plugin_configuration_id: "wrong-id" } },
85
- plugins,
86
- styles,
87
- cellStyles,
88
- });
89
-
90
- expect(result.props.whoAmI).toEqual("default renderer");
75
+ const { UNSAFE_getByProps } = render(
76
+ getResult({
77
+ component: { styles: { cell_plugin_configuration_id: "wrong-id" } },
78
+ plugins,
79
+ styles,
80
+ cellStyles,
81
+ })
82
+ );
83
+
84
+ expect(UNSAFE_getByProps({ whoAmI: "default renderer" })).toBeTruthy();
91
85
  });
92
86
 
93
87
  it("returns default plugin if cellStyles store is empty", () => {
94
- const result = getResult({
95
- component,
96
- plugins,
97
- styles,
98
- cellStyles: {},
99
- });
100
-
101
- expect(result.props.whoAmI).toEqual("default renderer");
88
+ const { UNSAFE_getByProps } = render(
89
+ getResult({
90
+ component,
91
+ plugins,
92
+ styles,
93
+ cellStyles: {},
94
+ })
95
+ );
96
+
97
+ expect(UNSAFE_getByProps({ whoAmI: "default renderer" })).toBeTruthy();
102
98
  });
103
99
 
104
100
  it("returns null if requested renderer plugin does not exist", () => {
105
- const result = getResult({
106
- component: {
107
- styles: {
108
- cell_plugin_configuration_id: "FGHIJ-123456",
101
+ const { UNSAFE_getByProps } = render(
102
+ getResult({
103
+ component: {
104
+ styles: {
105
+ cell_plugin_configuration_id: "FGHIJ-123456",
106
+ },
109
107
  },
110
- },
111
- plugins,
112
- styles,
113
- cellStyles,
114
- });
108
+ plugins,
109
+ styles,
110
+ cellStyles,
111
+ })
112
+ );
115
113
 
116
- expect(result.props.whoAmI).toEqual("default renderer");
114
+ expect(UNSAFE_getByProps({ whoAmI: "default renderer" })).toBeTruthy();
117
115
  });
118
116
  });
119
117
  });
@@ -1,48 +1,7 @@
1
1
  // Jest Snapshot v1, https://goo.gl/fbAQLP
2
2
 
3
- exports[`ComponentResolver renders correctly 1`] = `
4
- <ContextProvider
5
- value={null}
6
- >
7
- <Memo(ComponentResolver)
8
- cellStyles={{}}
9
- component={
10
- {
11
- "component_type": "some_component",
12
- }
13
- }
14
- components={
15
- {
16
- "SomeComponent": [MockFunction],
17
- }
18
- }
19
- decorators={[MockFunction]}
20
- dispatch={[Function]}
21
- plugins={[]}
22
- store={
23
- {
24
- "clearActions": [Function],
25
- "dispatch": [Function],
26
- "getActions": [Function],
27
- "getState": [Function],
28
- "replaceReducer": [Function],
29
- "subscribe": [Function],
30
- }
31
- }
32
- />
33
- </ContextProvider>
34
- `;
35
-
36
3
  exports[`ComponentResolverComponent initializes the cell renderer plugin module if matching plugin exists 1`] = `
37
- <mockConstructor
4
+ <View
38
5
  rendered={true}
39
6
  />
40
7
  `;
41
-
42
- exports[`ComponentResolverComponent renders the Component if it exists 1`] = `
43
- <mockConstructor
44
- rendered={true}
45
- />
46
- `;
47
-
48
- exports[`ComponentResolverComponent returns null if the component doesn't exist 1`] = `""`;
@@ -1,7 +1,6 @@
1
1
  import * as React from "react";
2
2
  import { View } from "react-native";
3
- import { shallow } from "enzyme";
4
- import { shallowToJson } from "enzyme-to-json";
3
+ import { render } from "@testing-library/react-native";
5
4
  import configureStore from "redux-mock-store";
6
5
 
7
6
  const mockLogger = {
@@ -43,37 +42,36 @@ const store = configureStore()({
43
42
  });
44
43
 
45
44
  const component = { component_type: "some_component" };
46
- const decorators = jest.fn((x) => x);
45
+ const decorators = (x) => x;
47
46
  const renderFunction = jest.fn((Comp) => <Comp rendered />);
48
47
 
49
48
  function clearAllMocks() {
50
- SomeComponent.mockClear();
51
- decorators.mockClear();
52
- renderFunction.mockClear();
53
- mockLogger.warning.mockClear();
49
+ jest.clearAllMocks();
54
50
  }
55
51
 
56
52
  describe("ComponentResolver", () => {
57
53
  beforeEach(clearAllMocks);
58
54
 
59
55
  it("renders correctly", () => {
60
- const wrapper = shallow(
56
+ const { toJSON } = render(
61
57
  <ComponentResolver
62
58
  component={component}
63
59
  decorators={decorators}
64
60
  store={store}
65
- />
61
+ >
62
+ {() => null}
63
+ </ComponentResolver>
66
64
  );
67
65
 
68
- expect(shallowToJson(wrapper)).toMatchSnapshot();
66
+ expect(toJSON()).toBeNull();
69
67
  });
70
68
  });
71
69
 
72
70
  describe("ComponentResolverComponent", () => {
73
71
  beforeEach(clearAllMocks);
74
72
 
75
- const getWrapper = (component, plugins) =>
76
- shallow(
73
+ const renderComponent = (component, plugins) =>
74
+ render(
77
75
  <ComponentResolverComponent
78
76
  components={components}
79
77
  component={component}
@@ -87,9 +85,9 @@ describe("ComponentResolverComponent", () => {
87
85
  );
88
86
 
89
87
  it("renders the Component if it exists", () => {
90
- const wrapper = getWrapper(component, plugins);
88
+ const { toJSON } = renderComponent(component, plugins);
91
89
 
92
- expect(shallowToJson(wrapper)).toMatchSnapshot();
90
+ expect(toJSON()).not.toBeNull();
93
91
 
94
92
  expect(renderFunction).toHaveBeenCalledWith(
95
93
  SomeComponent,
@@ -98,14 +96,12 @@ describe("ComponentResolverComponent", () => {
98
96
  });
99
97
 
100
98
  it("returns null if the component doesn't exist", () => {
101
- const wrapper = getWrapper({ component_type: "foo" }, plugins);
99
+ const { UNSAFE_root } = renderComponent({ component_type: "foo" }, plugins);
102
100
 
103
101
  const warningMessage =
104
102
  "Component foo cannot be found - it is skipped from rendering";
105
103
 
106
- expect(shallowToJson(wrapper)).toMatchSnapshot();
107
- expect(wrapper.isEmptyRender()).toBe(true);
108
-
104
+ expect(UNSAFE_root.children.length).toBe(0);
109
105
  expect(mockLogger.warning).toHaveBeenCalledTimes(2);
110
106
 
111
107
  expect(mockLogger.warning).toHaveBeenNthCalledWith(
@@ -124,11 +120,9 @@ describe("ComponentResolverComponent", () => {
124
120
  });
125
121
 
126
122
  it("initializes the cell renderer plugin module if matching plugin exists", () => {
127
- const plugins = [];
128
-
129
- const wrapper = getWrapper(component, plugins);
123
+ const { toJSON } = renderComponent(component, plugins);
130
124
 
131
- expect(shallowToJson(wrapper)).toMatchSnapshot();
125
+ expect(toJSON()).toMatchSnapshot();
132
126
 
133
127
  expect(renderFunction).toHaveBeenCalledWith(
134
128
  SomeComponent,
@@ -1,10 +1,10 @@
1
1
  import React from "react";
2
- import { shallow } from "enzyme";
2
+ import { render } from "@testing-library/react-native";
3
3
 
4
- import { ContentScreen } from "../index";
4
+ import { ContentScreen } from "../";
5
5
 
6
6
  describe("<ContentScreen />", () => {
7
7
  it("renders correctly", () => {
8
- expect(() => shallow(<ContentScreen />)).toThrowErrorMatchingSnapshot();
8
+ expect(() => render(<ContentScreen />)).toThrowErrorMatchingSnapshot();
9
9
  });
10
10
  });
@@ -1,13 +1,13 @@
1
1
  import React, { useMemo } from "react";
2
2
  import * as R from "ramda";
3
3
  import {
4
- View,
4
+ ImageStyle,
5
5
  StyleSheet,
6
6
  Text,
7
- ViewStyle,
8
- TextStyle,
9
- ImageStyle,
10
7
  TextProps,
8
+ TextStyle,
9
+ View,
10
+ ViewStyle,
11
11
  } from "react-native";
12
12
  import { defaultAsset } from "./defaultAsset";
13
13
  import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
@@ -150,13 +150,13 @@ export function ErrorScreen(props: Props) {
150
150
  return (
151
151
  <View style={[baseStyles.container, styles.screen]}>
152
152
  <View style={[baseStyles.container, styles.component]}>
153
- {assetEnabled && (
153
+ {assetEnabled ? (
154
154
  <Image
155
155
  fadeDuration={0}
156
156
  source={{ uri: asset }}
157
157
  style={styles.asset}
158
158
  />
159
- )}
159
+ ) : null}
160
160
  <Text style={styles.title} {...titleProps}>
161
161
  {title}
162
162
  </Text>
@@ -1,3 +1,4 @@
1
+ /* eslint-disable react/no-unknown-property */
1
2
  import * as React from "react";
2
3
 
3
4
  import { BaseFocusable } from "../BaseFocusable";
@@ -1,25 +1,24 @@
1
1
  import * as React from "react";
2
2
 
3
- type Props =
4
- | {
5
- id: string;
6
- children: React.ReactNode;
7
- onPress?: (ref: FocusManager.TouchableRef) => void;
8
- onPressIn?: (ref: FocusManager.TouchableRef) => void;
9
- onPressOut?: (ref: FocusManager.TouchableRef) => void;
10
- onLongPress?: (ref: FocusManager.TouchableRef) => void;
11
- onFocus?: (
12
- ref: FocusManager.TouchableRef,
13
- options: FocusManager.Android.CallbackOptions
14
- ) => void;
15
- onBlur?: (
16
- ref: FocusManager.TouchableRef,
17
- options: FocusManager.Android.CallbackOptions
18
- ) => void;
19
-
20
- disableFocus?: boolean;
21
- blockFocus?: boolean;
22
- } & Partial<ParentFocus>;
3
+ type Props = {
4
+ id: string;
5
+ children: React.ReactNode;
6
+ onPress?: (ref: FocusManager.TouchableRef) => void;
7
+ onPressIn?: (ref: FocusManager.TouchableRef) => void;
8
+ onPressOut?: (ref: FocusManager.TouchableRef) => void;
9
+ onLongPress?: (ref: FocusManager.TouchableRef) => void;
10
+ onFocus?: (
11
+ ref: FocusManager.TouchableRef,
12
+ options: FocusManager.Android.CallbackOptions
13
+ ) => void;
14
+ onBlur?: (
15
+ ref: FocusManager.TouchableRef,
16
+ options: FocusManager.Android.CallbackOptions
17
+ ) => void;
18
+
19
+ disableFocus?: boolean;
20
+ blockFocus?: boolean;
21
+ } & Partial<ParentFocus>;
23
22
 
24
23
  export class Touchable extends React.Component<Props> {
25
24
  onPress(focusableRef: FocusManager.TouchableRef): void {
@@ -33,6 +33,8 @@ type Props = {
33
33
  onLongPress?: (ref: FocusManager.FocusableRef) => void;
34
34
  onRegister?: () => void;
35
35
  isFocusableCell?: boolean;
36
+ /** only for FocusableScrollView */
37
+ onSetIsFocusable?: (isFocusable: boolean) => void;
36
38
  } & ParentFocus;
37
39
 
38
40
  export const FocusableContext = React.createContext<
@@ -67,6 +69,7 @@ function FocusableComponent(props: Props, forwardedRef) {
67
69
  onLongPress,
68
70
  onRegister = noop,
69
71
  isFocusableCell = true,
72
+ onSetIsFocusable,
70
73
  } = props;
71
74
 
72
75
  const isRTL = useIsRTL();
@@ -137,9 +140,13 @@ function FocusableComponent(props: Props, forwardedRef) {
137
140
  [onBlur]
138
141
  );
139
142
 
140
- const setIsFocusable = React.useCallback((blockFocus) => {
141
- setDisableFocus(!blockFocus);
142
- }, []);
143
+ const setIsFocusable = React.useCallback(
144
+ (blockFocus) => {
145
+ onSetIsFocusable?.(blockFocus);
146
+ setDisableFocus(!blockFocus);
147
+ },
148
+ [onSetIsFocusable]
149
+ );
143
150
 
144
151
  const parentFocus = React.useMemo(
145
152
  () => ({
@@ -1,17 +1,31 @@
1
1
  import * as React from "react";
2
2
  import { FocusableGroupNative } from "@applicaster/zapp-react-native-ui-components/Components/NativeFocusables";
3
3
  import { BaseFocusable } from "@applicaster/zapp-react-native-ui-components/Components/BaseFocusable";
4
-
5
- function noop() {}
4
+ import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
5
+
6
+ const { log_verbose } = createLogger({
7
+ subsystem: "General",
8
+ category: "FocusableGroup",
9
+ });
10
+
11
+ type FocusableGroupNativeEvent = {
12
+ nativeEvent: {
13
+ focusHeading: FocusManager.Direction;
14
+ groupId: string;
15
+ isActive: boolean;
16
+ isFocusDisabled: boolean;
17
+ isFocusingByUser: boolean;
18
+ itemId: string;
19
+ target: number;
20
+ };
21
+ };
6
22
 
7
23
  type Props = {
8
24
  id: string;
9
25
  children: (arg1: boolean) => React.ComponentType<any>;
10
- onWillUpdateFocus: (nativeEvent: any) => void;
11
- onDidUpdateFocus: (nativeEvent: any) => void;
12
26
  isFocusDisabled: boolean;
13
27
  initialItemId: string;
14
- resetFocusToInitialValue: boolean;
28
+ isPreferredFocusDisabled: boolean;
15
29
  focusGroupRef: React.Component;
16
30
  shouldUsePreferredFocus: boolean;
17
31
  groupId: string;
@@ -21,86 +35,27 @@ type Props = {
21
35
  };
22
36
 
23
37
  export class FocusableGroup extends BaseFocusable<Props> {
24
- focusableGroupNativeRef: React.Component | null;
25
- constructor(props) {
26
- super(props);
27
- this.focusableGroupNativeRef = null;
28
-
29
- this.state = {
30
- isActive: false,
31
- };
32
-
33
- this.onWillUpdateFocus = this.onWillUpdateFocus.bind(this);
34
- this.onDidUpdateFocus = this.onDidUpdateFocus.bind(this);
35
- this.isGroup = true;
36
-
37
- this.shouldUsePreferredFocus = this.shouldUsePreferredFocus.bind(this);
38
- this.measureView = this.measureView.bind(this);
39
- }
40
-
41
- connectedScreenId() {
42
- const {
43
- screenData: { screenId, parentScreenId },
44
- } = this.props;
45
-
46
- if (screenId) {
47
- return null;
48
- }
49
-
50
- return parentScreenId ? `${parentScreenId}-${screenId}` : screenId;
51
- }
52
-
53
- /**
54
- * tells whether the group should give focus to a preferred item when it gains focus from another
55
- * group
56
- * @returns {boolean}
57
- */
58
- shouldUsePreferredFocus() {
59
- return this.props.shouldUsePreferredFocus || false;
60
- }
61
-
62
- /**
63
- * indicates whether the underlying component should claim preferred focus
64
- * when navigating into the group of this item
65
- * @returns {boolean}
66
- */
67
- isPreferredFocus() {
68
- return this.props.preferredFocus || false;
69
- }
70
-
71
- onWillUpdateFocus({ nativeEvent }) {
72
- const { isActive } = nativeEvent;
73
- this.setState({ isActive });
74
- const { onWillUpdateFocus = noop } = this.props;
75
- onWillUpdateFocus(nativeEvent);
76
- }
77
-
78
- onDidUpdateFocus({ nativeEvent }) {
79
- const { onDidUpdateFocus = noop } = this.props;
80
- onDidUpdateFocus(nativeEvent);
81
- }
82
-
83
- setFocusDisabled(isFocusDisabled) {
84
- if (this.ref) {
85
- this.ref.current.setNativeProps({
86
- isFocusDisabled,
87
- });
88
- }
89
- }
90
-
91
38
  render() {
92
39
  const {
93
40
  children,
94
41
  id,
95
42
  isFocusDisabled,
96
43
  initialItemId,
97
- resetFocusToInitialValue,
98
- style,
44
+ isPreferredFocusDisabled,
45
+ style = {},
99
46
  groupId,
100
47
  ...otherProps
101
48
  } = this.props;
102
49
 
103
- const focusableStyles = style || {};
50
+ const onGroupFocus = ({ nativeEvent }: FocusableGroupNativeEvent) => {
51
+ log_verbose("FOCUSABLE_GROUP: onGroupFocus", { nativeEvent });
52
+ this.onFocus(this.ref, nativeEvent.focusHeading);
53
+ };
54
+
55
+ const onGroupBlur = ({ nativeEvent }: FocusableGroupNativeEvent) => {
56
+ log_verbose("FOCUSABLE_GROUP: onGroupBlur", { nativeEvent });
57
+ this.onBlur(this.ref, nativeEvent.focusHeading);
58
+ };
104
59
 
105
60
  return (
106
61
  <FocusableGroupNative
@@ -109,15 +64,11 @@ export class FocusableGroup extends BaseFocusable<Props> {
109
64
  ref={this.ref}
110
65
  isFocusDisabled={isFocusDisabled}
111
66
  initialItemId={initialItemId}
112
- resetFocusToInitialValue={resetFocusToInitialValue}
113
- onLayout={this.measureView}
114
- onViewFocus={this.onFocus}
115
- onViewPress={this.onPress}
116
- onViewBlur={this.onBlur}
117
- style={focusableStyles}
67
+ isPreferredFocusDisabled={isPreferredFocusDisabled}
68
+ onGroupFocus={onGroupFocus}
69
+ onGroupBlur={onGroupBlur}
70
+ style={style}
118
71
  {...otherProps}
119
- onWillUpdateFocus={this.onWillUpdateFocus}
120
- onDidUpdateFocus={this.onDidUpdateFocus}
121
72
  >
122
73
  {children}
123
74
  </FocusableGroupNative>
@@ -16,12 +16,10 @@ type Props = {
16
16
  prioritiseFocusOn?: number;
17
17
  groupId?: string;
18
18
  hasTVPreferredFocus?: boolean;
19
- resetFocusToInitialValue?: boolean;
19
+ isPreferredFocusDisabled?: boolean;
20
20
  onFocus?: () => void;
21
21
  onBlur?: () => void;
22
- onWillUpdateFocus?: (event?: any) => void;
23
22
  willReceiveFocus?: (event?: any) => void;
24
- onDidUpdateFocus?: (event?: any) => void;
25
23
  hasLostFocus?: any;
26
24
  nextFocusUp?: any;
27
25
  nextFocusDown?: any;
@@ -311,6 +311,7 @@ function FocusableListComponent<ItemT>(props: Props<ItemT>, ref) {
311
311
  />
312
312
  ) : (
313
313
  <FlatList
314
+ testID="focusable-list-flat-list"
314
315
  focusable={false}
315
316
  scrollEnabled={false}
316
317
  ref={ref}