@applicaster/zapp-react-native-ui-components 13.0.0-rc.52 → 13.0.0-rc.53
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.
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
98
|
-
style,
|
|
44
|
+
isPreferredFocusDisabled,
|
|
45
|
+
style = {},
|
|
99
46
|
groupId,
|
|
100
47
|
...otherProps
|
|
101
48
|
} = this.props;
|
|
102
49
|
|
|
103
|
-
const
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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
|
-
|
|
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;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@applicaster/zapp-react-native-ui-components",
|
|
3
|
-
"version": "13.0.0-rc.
|
|
3
|
+
"version": "13.0.0-rc.53",
|
|
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": "13.0.0-rc.
|
|
38
|
-
"@applicaster/zapp-react-native-bridge": "13.0.0-rc.
|
|
39
|
-
"@applicaster/zapp-react-native-redux": "13.0.0-rc.
|
|
40
|
-
"@applicaster/zapp-react-native-utils": "13.0.0-rc.
|
|
37
|
+
"@applicaster/applicaster-types": "13.0.0-rc.53",
|
|
38
|
+
"@applicaster/zapp-react-native-bridge": "13.0.0-rc.53",
|
|
39
|
+
"@applicaster/zapp-react-native-redux": "13.0.0-rc.53",
|
|
40
|
+
"@applicaster/zapp-react-native-utils": "13.0.0-rc.53",
|
|
41
41
|
"promise": "^8.3.0",
|
|
42
42
|
"react-router-native": "^5.1.2",
|
|
43
43
|
"url": "^0.11.0",
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
/** TODO: Remove this file when tvos FocusableGroup
|
|
2
|
-
* behaviour is aligned to the web one
|
|
3
|
-
* FocusableGroup should only send onFocus and onBlur events when
|
|
4
|
-
* Focus enters and leaves the Focusables inside the branch
|
|
5
|
-
*/
|
|
6
|
-
import * as React from "react";
|
|
7
|
-
|
|
8
|
-
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
|
|
9
|
-
import * as FOCUS_EVENTS from "@applicaster/zapp-react-native-utils/appUtils/focusManager/events";
|
|
10
|
-
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
11
|
-
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
12
|
-
|
|
13
|
-
import { isAppleTV } from "../../Helpers/Platform";
|
|
14
|
-
import { useCellState } from "../MasterCell/utils";
|
|
15
|
-
|
|
16
|
-
const useCellFocusedState = (
|
|
17
|
-
skipFocusManagerRegistration: boolean,
|
|
18
|
-
groupId: string,
|
|
19
|
-
id: string
|
|
20
|
-
) => {
|
|
21
|
-
const [currentCellFocused, setCurrentCellFocused] = React.useState(false);
|
|
22
|
-
|
|
23
|
-
React.useEffect(() => {
|
|
24
|
-
const isGroupItemFocused = () => {
|
|
25
|
-
if (!skipFocusManagerRegistration) {
|
|
26
|
-
const isFocused = focusManager.isGroupItemFocused(groupId, id);
|
|
27
|
-
setCurrentCellFocused(isFocused);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
const handler = () => {
|
|
32
|
-
// tvOS hack for properly checking focus
|
|
33
|
-
if (isAppleTV()) {
|
|
34
|
-
setTimeout(() => {
|
|
35
|
-
isGroupItemFocused();
|
|
36
|
-
}, 0);
|
|
37
|
-
} else {
|
|
38
|
-
isGroupItemFocused();
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
|
|
42
|
-
focusManager.on(FOCUS_EVENTS.FOCUS, handler);
|
|
43
|
-
|
|
44
|
-
return () => {
|
|
45
|
-
focusManager.removeHandler(FOCUS_EVENTS.FOCUS, handler);
|
|
46
|
-
};
|
|
47
|
-
}, [groupId, skipFocusManagerRegistration]);
|
|
48
|
-
|
|
49
|
-
return currentCellFocused;
|
|
50
|
-
};
|
|
51
|
-
|
|
52
|
-
type Props = {
|
|
53
|
-
item: ZappEntry;
|
|
54
|
-
CellRenderer: React.FunctionComponent<any>;
|
|
55
|
-
id: string;
|
|
56
|
-
groupId: string;
|
|
57
|
-
onFocus: Function;
|
|
58
|
-
index: number;
|
|
59
|
-
scrollTo: Function;
|
|
60
|
-
preferredFocus?: boolean;
|
|
61
|
-
skipFocusManagerRegistration?: boolean;
|
|
62
|
-
isFocusable?: boolean;
|
|
63
|
-
behavior: Behavior;
|
|
64
|
-
focused?: boolean;
|
|
65
|
-
};
|
|
66
|
-
|
|
67
|
-
export function CellWithFocusable(props: Props) {
|
|
68
|
-
const {
|
|
69
|
-
index,
|
|
70
|
-
item,
|
|
71
|
-
CellRenderer,
|
|
72
|
-
id,
|
|
73
|
-
groupId,
|
|
74
|
-
onFocus,
|
|
75
|
-
scrollTo = noop,
|
|
76
|
-
preferredFocus,
|
|
77
|
-
skipFocusManagerRegistration,
|
|
78
|
-
isFocusable,
|
|
79
|
-
behavior,
|
|
80
|
-
focused,
|
|
81
|
-
} = props;
|
|
82
|
-
|
|
83
|
-
const isFocused = useCellFocusedState(
|
|
84
|
-
skipFocusManagerRegistration,
|
|
85
|
-
groupId,
|
|
86
|
-
id
|
|
87
|
-
);
|
|
88
|
-
|
|
89
|
-
const state = useCellState({
|
|
90
|
-
id: item.id,
|
|
91
|
-
behavior,
|
|
92
|
-
focused: isFocused || toBooleanWithDefaultFalse(focused),
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
const [focusedButtonId, setFocusedButtonId] = React.useState(undefined);
|
|
96
|
-
|
|
97
|
-
// for horizontal scrolling
|
|
98
|
-
React.useEffect(() => {
|
|
99
|
-
if (focusedButtonId) {
|
|
100
|
-
scrollTo(index);
|
|
101
|
-
}
|
|
102
|
-
}, [focusedButtonId]);
|
|
103
|
-
|
|
104
|
-
const handleToggleFocus = (value) => {
|
|
105
|
-
setFocusedButtonId(value.focusedButtonId);
|
|
106
|
-
|
|
107
|
-
if (value.focusable) {
|
|
108
|
-
onFocus(value.focusable, value.mouse);
|
|
109
|
-
}
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
return (
|
|
113
|
-
<CellRenderer
|
|
114
|
-
item={item}
|
|
115
|
-
groupId={groupId}
|
|
116
|
-
onToggleFocus={handleToggleFocus}
|
|
117
|
-
state={state}
|
|
118
|
-
prefixId={id}
|
|
119
|
-
focusedButtonId={focusedButtonId}
|
|
120
|
-
preferredFocus={preferredFocus}
|
|
121
|
-
skipFocusManagerRegistration={skipFocusManagerRegistration}
|
|
122
|
-
isFocusable={isFocusable}
|
|
123
|
-
focused={focused}
|
|
124
|
-
/>
|
|
125
|
-
);
|
|
126
|
-
}
|