@applicaster/zapp-react-native-ui-components 15.0.0-alpha.3564837831 → 15.0.0-alpha.4043532513

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.
@@ -2,6 +2,7 @@ import * as React from "react";
2
2
 
3
3
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
4
4
  import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
5
+ import { platformSelect } from "@applicaster/zapp-react-native-utils/reactUtils";
5
6
 
6
7
  import { useCellState } from "../MasterCell/utils";
7
8
  import { FocusableGroup } from "../FocusableGroup";
@@ -26,6 +27,13 @@ type Props = {
26
27
 
27
28
  const addPrefix = (id: string) => `focusable-cell-wrapper-${id}`;
28
29
 
30
+ const wrapperStyles = {
31
+ flex: platformSelect({
32
+ tvos: 1,
33
+ default: undefined,
34
+ }),
35
+ };
36
+
29
37
  export function CellWithFocusable(props: Props) {
30
38
  const {
31
39
  index,
@@ -94,6 +102,7 @@ export function CellWithFocusable(props: Props) {
94
102
  onFocus={onGroupFocus}
95
103
  onBlur={onGroupBlur}
96
104
  skipFocusManagerRegistration={skipFocusManagerRegistration}
105
+ style={wrapperStyles}
97
106
  >
98
107
  <CellWrapper style={styles.cellWrapper}>
99
108
  <CellRenderer
@@ -13,7 +13,7 @@ import { findNodeHandle, ViewStyle } from "react-native";
13
13
  import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
14
14
 
15
15
  import {
16
- emitDidFocused,
16
+ emitFocused,
17
17
  emitNativeRegistered,
18
18
  } from "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux/utils/utils.ios";
19
19
 
@@ -91,7 +91,7 @@ export class Focusable extends BaseFocusable<Props> {
91
91
  }
92
92
 
93
93
  const id: string = nativeEvent.itemID;
94
- emitDidFocused(id);
94
+ emitFocused(id);
95
95
 
96
96
  onFocus(nativeEvent);
97
97
  }
@@ -1,5 +1,4 @@
1
1
  import * as React from "react";
2
- import { compose } from "@applicaster/zapp-react-native-utils/utils";
3
2
  import { FocusableGroupNative } from "@applicaster/zapp-react-native-ui-components/Components/NativeFocusables";
4
3
  import { BaseFocusable } from "@applicaster/zapp-react-native-ui-components/Components/BaseFocusable";
5
4
  import { createLogger } from "@applicaster/zapp-react-native-utils/logger";
@@ -7,9 +6,6 @@ import { LayoutContext } from "@applicaster/zapp-react-native-tvos-app/Context/L
7
6
  import { useRoute } from "@applicaster/zapp-react-native-utils/reactHooks/navigation/useRoute";
8
7
  import { isScreenPlayable } from "@applicaster/zapp-react-native-utils/navigationUtils/itemTypes";
9
8
  import { emitNativeRegistered } from "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux/utils/utils.ios";
10
- import { withAboveTabsScreenContextConsumer } from "@applicaster/zapp-react-native-ui-components/Contexts/AboveTabsScreenContext";
11
-
12
- import { useIsFocusEnabled } from "./hooks";
13
9
 
14
10
  const { log_verbose } = createLogger({
15
11
  subsystem: "General",
@@ -91,8 +87,8 @@ class FocusableGroupComponent extends BaseFocusable<Props> {
91
87
  }
92
88
  }
93
89
 
94
- export const withFocusDisabledHOC = (Component) => {
95
- return function WithFocusDisabledHOC(props) {
90
+ export const withFocusDisabled = (Component) => {
91
+ return function WithFocusDisabled(props) {
96
92
  // @ts-ignore
97
93
  const { screenFocusBlocked } = React.useContext(LayoutContext.ReactContext);
98
94
 
@@ -102,27 +98,8 @@ export const withFocusDisabledHOC = (Component) => {
102
98
 
103
99
  const blockScreenFocus = isPlayerPresented === false && screenFocusBlocked;
104
100
 
105
- return (
106
- <Component
107
- {...props}
108
- isFocusDisabled={blockScreenFocus || props.isFocusDisabled}
109
- />
110
- );
111
- };
112
- };
113
-
114
- const withAboveTabsScreenHOC = (Component) => {
115
- return function WithAboveTabsScreenHOC(props) {
116
- const { aboveTabsScreen } = props;
117
-
118
- const isFocusEnabled = useIsFocusEnabled(aboveTabsScreen);
119
-
120
- return <Component {...props} isFocusDisabled={!isFocusEnabled} />;
101
+ return <Component {...props} isFocusDisabled={blockScreenFocus} />;
121
102
  };
122
103
  };
123
104
 
124
- export const FocusableGroup = compose(
125
- withAboveTabsScreenContextConsumer,
126
- withAboveTabsScreenHOC,
127
- withFocusDisabledHOC
128
- )(FocusableGroupComponent);
105
+ export const FocusableGroup = withFocusDisabled(FocusableGroupComponent);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@applicaster/zapp-react-native-ui-components",
3
- "version": "15.0.0-alpha.3564837831",
3
+ "version": "15.0.0-alpha.4043532513",
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-alpha.3564837831",
32
- "@applicaster/zapp-react-native-bridge": "15.0.0-alpha.3564837831",
33
- "@applicaster/zapp-react-native-redux": "15.0.0-alpha.3564837831",
34
- "@applicaster/zapp-react-native-utils": "15.0.0-alpha.3564837831",
31
+ "@applicaster/applicaster-types": "15.0.0-alpha.4043532513",
32
+ "@applicaster/zapp-react-native-bridge": "15.0.0-alpha.4043532513",
33
+ "@applicaster/zapp-react-native-redux": "15.0.0-alpha.4043532513",
34
+ "@applicaster/zapp-react-native-utils": "15.0.0-alpha.4043532513",
35
35
  "fast-json-stable-stringify": "^2.1.0",
36
36
  "promise": "^8.3.0",
37
37
  "url": "^0.11.0",
@@ -1,113 +0,0 @@
1
- import { act, renderHook } from "@testing-library/react-native";
2
-
3
- import { useIsFocusEnabled } from "../useIsFocusEnabled";
4
-
5
- // ----------------- MOCKS -----------------
6
- jest.mock(
7
- "@applicaster/zapp-react-native-utils/appUtils/focusManager/index.ios",
8
- () => ({
9
- focusManager: {
10
- isFocusOnMenu: jest.fn(),
11
- isFocusOnTabsScreen: jest.fn(),
12
- },
13
- })
14
- );
15
-
16
- jest.mock(
17
- "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux/utils/utils.ios",
18
- () => {
19
- const { Subject } = require("rxjs");
20
-
21
- return {
22
- willFocused$: new Subject<void>(),
23
- didFocused$: new Subject<void>(),
24
- TabsScreenScreenSelectorContainerRegistry: {
25
- observable$: new Subject<string>(),
26
- },
27
- };
28
- }
29
- );
30
-
31
- import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager/index.ios";
32
- import {
33
- willFocused$,
34
- didFocused$,
35
- TabsScreenScreenSelectorContainerRegistry,
36
- } from "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux/utils/utils.ios";
37
-
38
- // ----------------- TESTS -----------------
39
- describe("useIsFocusEnabled", () => {
40
- beforeEach(() => {
41
- jest.clearAllMocks();
42
- });
43
-
44
- it("returns true by default", () => {
45
- const { result } = renderHook(() => useIsFocusEnabled(true));
46
-
47
- expect(result.current).toBe(true);
48
- });
49
-
50
- it("disables focus when focus moves to menu", () => {
51
- (focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(true);
52
-
53
- const { result } = renderHook(() => useIsFocusEnabled(true));
54
-
55
- act(() => {
56
- willFocused$.next();
57
- didFocused$.next();
58
- });
59
-
60
- expect(result.current).toBe(false);
61
- });
62
-
63
- it("re-enables focus when focus lands on tabs screen", () => {
64
- (focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(true);
65
- (focusManager.isFocusOnTabsScreen as jest.Mock).mockReturnValue(true);
66
-
67
- const { result } = renderHook(() => useIsFocusEnabled(true));
68
-
69
- // Disable focus first
70
- act(() => {
71
- willFocused$.next();
72
- didFocused$.next();
73
- });
74
-
75
- expect(result.current).toBe(false);
76
-
77
- // Enable focus again
78
- act(() => {
79
- didFocused$.next();
80
- TabsScreenScreenSelectorContainerRegistry.observable$.next("tabs-id");
81
- });
82
-
83
- expect(result.current).toBe(true);
84
- });
85
-
86
- it("does nothing when not above tabs screen", () => {
87
- const { result } = renderHook(() => useIsFocusEnabled(false));
88
-
89
- act(() => {
90
- willFocused$.next();
91
- didFocused$.next();
92
- TabsScreenScreenSelectorContainerRegistry.observable$.next("id");
93
- });
94
-
95
- expect(result.current).toBe(true);
96
- });
97
-
98
- it("cleans up subscriptions on unmount", () => {
99
- (focusManager.isFocusOnMenu as jest.Mock).mockReturnValue(true);
100
-
101
- const { unmount, result } = renderHook(() => useIsFocusEnabled(true));
102
-
103
- unmount();
104
-
105
- act(() => {
106
- willFocused$.next();
107
- didFocused$.next();
108
- });
109
-
110
- // State should not change after unmount
111
- expect(result.current).toBe(true);
112
- });
113
- });
@@ -1 +0,0 @@
1
- export { useIsFocusEnabled } from "./useIsFocusEnabled";
@@ -1,68 +0,0 @@
1
- import * as React from "react";
2
- import { switchMap, first, filter, repeat } from "rxjs/operators";
3
- import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager/index.ios";
4
-
5
- import {
6
- willFocused$,
7
- didFocused$,
8
- TabsScreenScreenSelectorContainerRegistry,
9
- } from "@applicaster/zapp-react-native-utils/appUtils/focusManagerAux/utils/utils.ios";
10
-
11
- export const useIsFocusEnabled = (isAboveTabsScreen: boolean): boolean => {
12
- const [isFocusEnabled, setIsFocusedEnabled] = React.useState(true);
13
-
14
- const enableFocus = React.useCallback(() => {
15
- setIsFocusedEnabled(true);
16
- }, []);
17
-
18
- const disableFocus = React.useCallback(() => {
19
- setIsFocusedEnabled(false);
20
- }, []);
21
-
22
- React.useEffect(() => {
23
- const subscription = didFocused$
24
- .pipe(
25
- filter(() => isAboveTabsScreen && !isFocusEnabled),
26
-
27
- switchMap(() => TabsScreenScreenSelectorContainerRegistry.observable$),
28
- filter((id) => id && focusManager.isFocusOnTabsScreen(id)),
29
-
30
- // run only once, then re-subscribe on didFocused$ again
31
- first(),
32
- repeat()
33
- )
34
- .subscribe(() => {
35
- enableFocus();
36
- });
37
-
38
- return () => {
39
- subscription.unsubscribe();
40
- };
41
- }, [enableFocus, isFocusEnabled, isAboveTabsScreen]);
42
-
43
- React.useEffect(() => {
44
- const subscription = willFocused$
45
- .pipe(
46
- filter(() => isAboveTabsScreen && isFocusEnabled),
47
-
48
- // start waiting onFocus event
49
- switchMap(() => didFocused$),
50
-
51
- // focus is landed on top-menu
52
- filter(() => focusManager.isFocusOnMenu()),
53
-
54
- // run only once, then re-subscribe on willFocused$ again
55
- first(),
56
- repeat()
57
- )
58
- .subscribe(() => {
59
- disableFocus();
60
- });
61
-
62
- return () => {
63
- subscription.unsubscribe();
64
- };
65
- }, [disableFocus, isFocusEnabled, isAboveTabsScreen]);
66
-
67
- return isFocusEnabled;
68
- };
@@ -1,33 +0,0 @@
1
- import React, { useMemo } from "react";
2
- import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
3
-
4
- export const AboveTabsScreenContext = React.createContext({
5
- aboveTabsScreen: false,
6
- });
7
-
8
- export const withAboveTabsScreenContext = (Component) =>
9
- function AbovetabsScreenContextProviderWrapper(props) {
10
- const aboveTabsScreen = toBooleanWithDefaultFalse(
11
- props?.item?.above_tabs_screen
12
- );
13
-
14
- const contextValue = useMemo(
15
- () => ({
16
- aboveTabsScreen,
17
- }),
18
- [aboveTabsScreen]
19
- );
20
-
21
- return (
22
- <AboveTabsScreenContext.Provider value={contextValue}>
23
- <Component {...props} />
24
- </AboveTabsScreenContext.Provider>
25
- );
26
- };
27
-
28
- export const withAboveTabsScreenContextConsumer = (Component) =>
29
- function AboveTabsScreenContextConsumerWrapper(props) {
30
- const { aboveTabsScreen } = React.useContext(AboveTabsScreenContext);
31
-
32
- return <Component {...props} aboveTabsScreen={aboveTabsScreen} />;
33
- };