@applicaster/zapp-react-native-ui-components 13.0.0-alpha.9433330286 → 13.0.0-alpha.9814200105
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/AppContainer/__tests__/__snapshots__/AppContainer.test.js.snap +1 -1
- package/Components/AudioPlayer/__tests__/__snapshots__/Runtime.test.js.snap +4 -4
- package/Components/AudioPlayer/__tests__/__snapshots__/artWork.test.js.snap +3 -3
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayer.test.js.snap +6 -6
- package/Components/AudioPlayer/__tests__/__snapshots__/audioPlayerLayout.test.js.snap +7 -7
- package/Components/AudioPlayer/__tests__/__snapshots__/channel.test.js.snap +3 -3
- package/Components/AudioPlayer/__tests__/__snapshots__/summary.test.js.snap +2 -2
- package/Components/AudioPlayer/__tests__/__snapshots__/title.test.js.snap +2 -2
- package/Components/BaseFocusable/index.ios.ts +1 -1
- package/Components/BaseFocusable/index.tsx +66 -29
- package/Components/Cell/Cell.tsx +10 -1
- package/Components/Cell/CellWithFocusable.ios.tsx +126 -0
- package/Components/Cell/CellWithFocusable.tsx +43 -59
- package/Components/Cell/TvOSCellComponent.tsx +0 -4
- package/Components/Cell/__tests__/CellWIthFocusable.test.js +13 -6
- package/Components/CellRendererResolver/__tests__/__snapshots__/cellRendererResolver.test.js.snap +20 -20
- package/Components/CellRendererResolver/__tests__/cellRendererResolver.test.js +5 -3
- package/Components/ComponentResolver/__tests__/__snapshots__/componentResolver.test.js.snap +5 -5
- package/Components/ComponentResolver/__tests__/componentResolver.test.js +11 -9
- package/Components/DisplayState/__tests__/__snapshots__/displayState.test.js.snap +2 -2
- package/Components/Focusable/Focusable.tsx +0 -54
- package/Components/Focusable/FocusableTvOS.tsx +1 -1
- package/Components/Focusable/Touchable.tsx +19 -20
- package/Components/FocusableList/index.tsx +0 -1
- package/Components/GeneralContentScreen/utils/__tests__/useCurationAPI.test.js +76 -7
- package/Components/GeneralContentScreen/utils/useCurationAPI.ts +53 -9
- package/Components/Layout/TV/__tests__/ScreenContainer.test.tsx +1 -0
- package/Components/Layout/TV/__tests__/__snapshots__/LayoutContainer.test.tsx.snap +1 -1
- package/Components/Layout/TV/__tests__/__snapshots__/NavBarContainer.test.tsx.snap +3 -3
- package/Components/Layout/TV/__tests__/__snapshots__/ScreenContainer.test.tsx.snap +9 -9
- package/Components/Layout/TV/__tests__/__snapshots__/index.test.tsx.snap +1 -1
- package/Components/Layout/TV/__tests__/index.test.tsx +7 -3
- package/Components/MasterCell/DefaultComponents/BorderContainerView/__tests__/index.test.tsx +66 -0
- package/Components/MasterCell/DefaultComponents/BorderContainerView/index.tsx +4 -1
- package/Components/MasterCell/DefaultComponents/Image/Image.ios.tsx +6 -12
- package/Components/MasterCell/DefaultComponents/ImageBorderContainer/__tests__/index.test.ts +93 -0
- package/Components/MasterCell/DefaultComponents/SecondaryImage/__tests__/__snapshots__/Image.test.tsx.snap +3 -3
- package/Components/MasterCell/DefaultComponents/SecondaryImage/utils.ts +1 -1
- package/Components/MasterCell/DefaultComponents/__tests__/image.test.js +1 -1
- package/Components/MasterCell/SharedUI/CollapsibleTextContainer/__tests__/__snapshots__/index.test.tsx.snap +1 -1
- package/Components/MasterCell/__tests__/__snapshots__/dataAdapter.test.js.snap +180 -180
- package/Components/MasterCell/__tests__/__snapshots__/elementMapper.test.js.snap +7 -7
- package/Components/MasterCell/__tests__/__snapshots__/masterCell.test.js.snap +34 -34
- package/Components/MasterCell/hooks/useAsyncRendering/MasterCellAsyncRenderManager.ts +2 -2
- package/Components/MasterCell/hooks/useAsyncRendering/index.ts +2 -2
- package/Components/MasterCell/utils/index.ts +1 -1
- package/Components/ModalComponent/Header/index.tsx +3 -3
- package/Components/OfflineHandler/__tests__/__snapshots__/index.test.tsx.snap +7 -7
- package/Components/OfflineHandler/__tests__/index.test.tsx +28 -25
- package/Components/PlayerContainer/PlayerContainer.tsx +5 -11
- package/Components/PlayerContainer/PlayerContainerContext.tsx +9 -0
- package/Components/River/ComponentsMap/ComponentsMap.tsx +39 -65
- package/Components/River/ComponentsMap/hooks/useLoadingState.ts +78 -51
- package/Components/River/RefreshControl.tsx +1 -1
- package/Components/River/RiverFooter.tsx +39 -9
- package/Components/River/RiverItem.tsx +37 -2
- package/Components/River/__tests__/__snapshots__/componentsMap.test.js.snap +114 -45
- package/Components/River/__tests__/__snapshots__/river.test.js.snap +12 -12
- package/Components/River/__tests__/componentsMap.test.js +64 -17
- package/Components/RouteManager/__tests__/__snapshots__/routeManager.test.js.snap +1 -1
- package/Components/RouteManager/__tests__/__snapshots__/testId.test.js.snap +1 -1
- package/Components/Screen/__tests__/Screen.test.tsx +41 -27
- package/Components/Screen/__tests__/__snapshots__/Screen.test.tsx.snap +4 -4
- package/Components/Screen/hooks.ts +56 -0
- package/Components/Screen/index.tsx +13 -39
- package/Components/ScreenResolver/__tests__/__snapshots__/screenResolver.test.js.snap +2 -2
- package/Components/ScreenResolver/__tests__/screenResolver.test.js +31 -27
- package/Components/Tabs/Tab.tsx +7 -6
- package/Components/TextInputTv/__tests__/TextInputTv.test.js +42 -42
- package/Components/TextInputTv/__tests__/__snapshots__/TextInputTv.test.js.snap +7 -0
- package/Components/TextInputTv/index.tsx +4 -4
- package/Components/Touchable/__tests__/__snapshots__/touchable.test.tsx.snap +2 -2
- package/Components/Transitioner/AnimationManager.js +8 -8
- package/Components/Transitioner/Scene.tsx +52 -23
- package/Components/Transitioner/__tests__/__snapshots__/AnimationManager.test.js.snap +26 -26
- package/Components/Transitioner/__tests__/__snapshots__/Scene.test.js.snap +62 -46
- package/Components/Transitioner/__tests__/__snapshots__/config.test.js.snap +20 -20
- package/Components/Transitioner/__tests__/__snapshots__/transitioner.test.js.snap +4 -4
- package/Components/Transitioner/index.js +8 -4
- package/Components/VideoLive/LiveImageManager.ts +27 -1
- package/Components/VideoLive/PlayerLiveImageComponent.tsx +29 -21
- package/Components/VideoLive/__tests__/PlayerLiveImageComponent.test.tsx +63 -8
- package/Components/VideoLive/__tests__/__snapshots__/PlayerLiveImageComponent.test.tsx.snap +5 -10
- package/Components/VideoModal/ModalAnimation/AnimatedScrollModal.tsx +5 -1
- package/Components/VideoModal/ModalAnimation/AnimatedVideoPlayerComponent.tsx +5 -1
- package/Components/VideoModal/ModalAnimation/AnimationComponent.tsx +8 -7
- package/Components/VideoModal/ModalAnimation/ModalAnimationContext.tsx +6 -13
- package/Components/VideoModal/ModalAnimation/index.ts +2 -1
- package/Components/VideoModal/ModalAnimation/useModalAnimationContext.ts +6 -0
- package/Components/VideoModal/ModalAnimation/utils.ts +2 -2
- package/Components/VideoModal/OpaqueLayer.tsx +33 -0
- package/Components/VideoModal/PlayerWrapper.tsx +17 -52
- package/Components/VideoModal/VideoModal.tsx +14 -23
- package/Components/VideoModal/__tests__/PlayerDetails.test.tsx +5 -2
- package/Components/VideoModal/__tests__/PlayerWrapper.test.tsx +13 -10
- package/Components/VideoModal/__tests__/__snapshots__/PlayerDetails.test.tsx.snap +4 -4
- package/Components/VideoModal/__tests__/__snapshots__/PlayerWrapper.test.tsx.snap +72 -162
- package/Components/VideoModal/hooks/__tests__/useDelayedPlayerDetails.test.ts +89 -0
- package/Components/VideoModal/hooks/index.ts +7 -0
- package/Components/VideoModal/hooks/useDelayedPlayerDetails.ts +49 -0
- package/Components/VideoModal/hooks/utils/__tests__/showDetails.test.ts +91 -0
- package/Components/VideoModal/hooks/utils/index.ts +33 -0
- package/Components/VideoModal/utils.ts +3 -5
- package/Components/Viewport/ViewportAware/__tests__/__snapshots__/viewportAware.test.js.snap +2 -2
- package/Components/Viewport/ViewportTracker/__tests__/__snapshots__/viewportTracker.test.js.snap +1 -1
- package/Components/ZappFrameworkComponents/BarView/BarView.tsx +1 -0
- package/Components/ZappUIComponent/__tests__/__snapshots__/ZappUIComponent.test.js.snap +11 -11
- package/Components/default-cell-renderer/__tests__/__snapshots__/defaultCellRenderer.test.tsx.snap +30 -30
- package/Contexts/ConfigutaionContext/__tests__/__snapshots__/ConfigurationProvider.test.tsx.snap +1 -1
- package/Contexts/FocusableGroupContext/withFocusableContext.tsx +18 -11
- package/Contexts/ScreenContext/index.tsx +3 -2
- package/Decorators/Navigator/__tests__/__snapshots__/navigator.test.js.snap +2 -2
- package/Decorators/RiverFeedLoader/__tests__/__snapshots__/riverFeedLoader.test.tsx.snap +77 -77
- package/Decorators/RiverFeedLoader/__tests__/riverFeedLoader.test.tsx +34 -39
- package/Decorators/RiverFeedLoader/__tests__/utils.test.ts +0 -9
- package/Decorators/RiverFeedLoader/index.tsx +1 -1
- package/Decorators/RiverFeedLoader/utils/getDatasourceUrl.ts +39 -0
- package/Decorators/RiverFeedLoader/utils/index.ts +29 -0
- package/Decorators/RiverFeedLoader/utils/usePipesContexts.ts +40 -0
- package/Decorators/RiverResolver/__tests__/__snapshots__/riverResolver.test.tsx.snap +5 -5
- package/Decorators/RiverResolver/__tests__/riverResolver.test.tsx +16 -10
- package/Decorators/ZappPipesDataConnector/__tests__/Hero.js +1 -1
- package/Decorators/ZappPipesDataConnector/index.tsx +32 -2
- package/package.json +12 -6
- package/Decorators/RiverFeedLoader/utils.ts +0 -100
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
exports[`<Runtime /> LTR renders correctly 1`] = `
|
|
4
4
|
<View
|
|
5
5
|
style={
|
|
6
|
-
|
|
6
|
+
{
|
|
7
7
|
"height": 40,
|
|
8
8
|
"justifyContent": "flex-start",
|
|
9
9
|
"width": 600,
|
|
@@ -12,7 +12,7 @@ exports[`<Runtime /> LTR renders correctly 1`] = `
|
|
|
12
12
|
>
|
|
13
13
|
<Text
|
|
14
14
|
style={
|
|
15
|
-
|
|
15
|
+
{
|
|
16
16
|
"alignItems": "flex-end",
|
|
17
17
|
"color": "white",
|
|
18
18
|
"flexDirection": "row",
|
|
@@ -32,7 +32,7 @@ exports[`<Runtime /> LTR renders correctly 1`] = `
|
|
|
32
32
|
exports[`<Runtime /> RTL renders correctly 1`] = `
|
|
33
33
|
<View
|
|
34
34
|
style={
|
|
35
|
-
|
|
35
|
+
{
|
|
36
36
|
"height": 40,
|
|
37
37
|
"justifyContent": "flex-end",
|
|
38
38
|
"width": 600,
|
|
@@ -41,7 +41,7 @@ exports[`<Runtime /> RTL renders correctly 1`] = `
|
|
|
41
41
|
>
|
|
42
42
|
<Text
|
|
43
43
|
style={
|
|
44
|
-
|
|
44
|
+
{
|
|
45
45
|
"alignItems": "flex-start",
|
|
46
46
|
"color": "white",
|
|
47
47
|
"flexDirection": "row-reverse",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
exports[`<Artwork /> renders correctly 1`] = `
|
|
4
4
|
<View
|
|
5
5
|
style={
|
|
6
|
-
|
|
6
|
+
{
|
|
7
7
|
"marginHorizontal": 24,
|
|
8
8
|
}
|
|
9
9
|
}
|
|
@@ -12,12 +12,12 @@ exports[`<Artwork /> renders correctly 1`] = `
|
|
|
12
12
|
fadeDuration={0}
|
|
13
13
|
resizeMode="cover"
|
|
14
14
|
source={
|
|
15
|
-
|
|
15
|
+
{
|
|
16
16
|
"uri": "https://example.com",
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
style={
|
|
20
|
-
|
|
20
|
+
{
|
|
21
21
|
"height": 400,
|
|
22
22
|
"width": 400,
|
|
23
23
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
exports[`<AudioPlayer /> renders correctly 1`] = `
|
|
4
4
|
<AudioPlayerLayout
|
|
5
5
|
config={
|
|
6
|
-
|
|
6
|
+
{
|
|
7
7
|
"artworkAspectRatio": "1:1",
|
|
8
8
|
"audioPlayerBackgroundImageQuery": "",
|
|
9
9
|
"backgroundColor": "black",
|
|
@@ -21,11 +21,11 @@ exports[`<AudioPlayer /> renders correctly 1`] = `
|
|
|
21
21
|
"titleFontSize": undefined,
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
|
-
style={
|
|
24
|
+
style={{}}
|
|
25
25
|
>
|
|
26
26
|
<Channel
|
|
27
27
|
config={
|
|
28
|
-
|
|
28
|
+
{
|
|
29
29
|
"artworkAspectRatio": "1:1",
|
|
30
30
|
"audioPlayerBackgroundImageQuery": "",
|
|
31
31
|
"backgroundColor": "black",
|
|
@@ -47,7 +47,7 @@ exports[`<AudioPlayer /> renders correctly 1`] = `
|
|
|
47
47
|
/>
|
|
48
48
|
<Title
|
|
49
49
|
config={
|
|
50
|
-
|
|
50
|
+
{
|
|
51
51
|
"artworkAspectRatio": "1:1",
|
|
52
52
|
"audioPlayerBackgroundImageQuery": "",
|
|
53
53
|
"backgroundColor": "black",
|
|
@@ -69,7 +69,7 @@ exports[`<AudioPlayer /> renders correctly 1`] = `
|
|
|
69
69
|
/>
|
|
70
70
|
<Summary
|
|
71
71
|
config={
|
|
72
|
-
|
|
72
|
+
{
|
|
73
73
|
"artworkAspectRatio": "1:1",
|
|
74
74
|
"audioPlayerBackgroundImageQuery": "",
|
|
75
75
|
"backgroundColor": "black",
|
|
@@ -98,7 +98,7 @@ exports[`<AudioPlayer /> renders correctly 1`] = `
|
|
|
98
98
|
audio_player_summary_color="white"
|
|
99
99
|
audio_player_title_color="white"
|
|
100
100
|
config={
|
|
101
|
-
|
|
101
|
+
{
|
|
102
102
|
"artworkAspectRatio": "1:1",
|
|
103
103
|
"audioPlayerBackgroundImageQuery": "",
|
|
104
104
|
"backgroundColor": "black",
|
|
@@ -4,7 +4,7 @@ exports[`<AudioPlayerLayout /> renders correctly 1`] = `
|
|
|
4
4
|
<View
|
|
5
5
|
pointerEvents="none"
|
|
6
6
|
style={
|
|
7
|
-
|
|
7
|
+
{
|
|
8
8
|
"backgroundColor": "transparent",
|
|
9
9
|
"overflow": "hidden",
|
|
10
10
|
}
|
|
@@ -12,12 +12,12 @@ exports[`<AudioPlayerLayout /> renders correctly 1`] = `
|
|
|
12
12
|
>
|
|
13
13
|
<ForwardRef(AnimatedComponentWrapper)
|
|
14
14
|
style={
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
[
|
|
16
|
+
{
|
|
17
17
|
"backgroundColor": "transparent",
|
|
18
18
|
"overflow": "hidden",
|
|
19
19
|
},
|
|
20
|
-
|
|
20
|
+
{
|
|
21
21
|
"opacity": 0,
|
|
22
22
|
},
|
|
23
23
|
]
|
|
@@ -26,19 +26,19 @@ exports[`<AudioPlayerLayout /> renders correctly 1`] = `
|
|
|
26
26
|
<ImageBackground
|
|
27
27
|
resizeMode="cover"
|
|
28
28
|
source={
|
|
29
|
-
|
|
29
|
+
{
|
|
30
30
|
"uri": "https://example.com",
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
33
|
style={
|
|
34
|
-
|
|
34
|
+
{
|
|
35
35
|
"flex": 1,
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
>
|
|
39
39
|
<View
|
|
40
40
|
style={
|
|
41
|
-
|
|
41
|
+
{
|
|
42
42
|
"backgroundColor": "transparent",
|
|
43
43
|
"overflow": "hidden",
|
|
44
44
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
exports[`<Channel /> renders correctly 1`] = `
|
|
4
4
|
<View
|
|
5
5
|
style={
|
|
6
|
-
|
|
6
|
+
{
|
|
7
7
|
"height": 72,
|
|
8
8
|
"marginBottom": 30,
|
|
9
9
|
"width": 128,
|
|
@@ -13,12 +13,12 @@ exports[`<Channel /> renders correctly 1`] = `
|
|
|
13
13
|
<Image
|
|
14
14
|
fadeDuration={0}
|
|
15
15
|
source={
|
|
16
|
-
|
|
16
|
+
{
|
|
17
17
|
"uri": "https://example.com",
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
20
|
style={
|
|
21
|
-
|
|
21
|
+
{
|
|
22
22
|
"height": 72,
|
|
23
23
|
"width": 128,
|
|
24
24
|
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
exports[`<Summary /> renders correctly 1`] = `
|
|
4
4
|
<View
|
|
5
5
|
style={
|
|
6
|
-
|
|
6
|
+
{
|
|
7
7
|
"height": 80,
|
|
8
8
|
"marginBottom": 30,
|
|
9
9
|
"width": 600,
|
|
@@ -13,7 +13,7 @@ exports[`<Summary /> renders correctly 1`] = `
|
|
|
13
13
|
<Text
|
|
14
14
|
numberOfLines={2}
|
|
15
15
|
style={
|
|
16
|
-
|
|
16
|
+
{
|
|
17
17
|
"color": "white",
|
|
18
18
|
"fontFamily": null,
|
|
19
19
|
"fontSize": 20,
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
exports[`<Title /> renders correctly 1`] = `
|
|
4
4
|
<View
|
|
5
5
|
style={
|
|
6
|
-
|
|
6
|
+
{
|
|
7
7
|
"height": 100,
|
|
8
8
|
"marginBottom": 12,
|
|
9
9
|
"width": 600,
|
|
@@ -13,7 +13,7 @@ exports[`<Title /> renders correctly 1`] = `
|
|
|
13
13
|
<Text
|
|
14
14
|
numberOfLines={2}
|
|
15
15
|
style={
|
|
16
|
-
|
|
16
|
+
{
|
|
17
17
|
"color": "white",
|
|
18
18
|
"fontFamily": null,
|
|
19
19
|
"fontSize": 38,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
+
import * as R from "ramda";
|
|
2
3
|
|
|
3
4
|
import {
|
|
4
5
|
BaseFocusable as BaseFocusableInterface,
|
|
@@ -7,7 +8,6 @@ import {
|
|
|
7
8
|
|
|
8
9
|
import { createReactRef } from "@applicaster/zapp-react-native-utils/reactUtils";
|
|
9
10
|
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
|
|
10
|
-
import * as FOCUS_EVENTS from "@applicaster/zapp-react-native-utils/appUtils/focusManager/events";
|
|
11
11
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
12
12
|
|
|
13
13
|
type ScrollDirection = FocusManager.IOS.Direction | FocusManager.Web.Direction;
|
|
@@ -35,7 +35,7 @@ type Props = {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
export class BaseFocusable<
|
|
38
|
-
T extends Props = Props
|
|
38
|
+
T extends Props = Props,
|
|
39
39
|
> extends BaseFocusableInterface<T> {
|
|
40
40
|
constructor(props) {
|
|
41
41
|
super(props);
|
|
@@ -131,12 +131,6 @@ export class BaseFocusable<
|
|
|
131
131
|
willLoseFocus: FocusManager.FocusEventCB = (focusable, scrollDirection) => {
|
|
132
132
|
const { willLoseFocus = noop } = this.props;
|
|
133
133
|
willLoseFocus(focusable, scrollDirection);
|
|
134
|
-
|
|
135
|
-
focusManager.invokeHandler?.(
|
|
136
|
-
FOCUS_EVENTS.WILL_LOSE_FOCUS,
|
|
137
|
-
this,
|
|
138
|
-
scrollDirection
|
|
139
|
-
);
|
|
140
134
|
};
|
|
141
135
|
|
|
142
136
|
willReceiveFocus: FocusManager.FocusEventCB = (
|
|
@@ -145,12 +139,6 @@ export class BaseFocusable<
|
|
|
145
139
|
) => {
|
|
146
140
|
const { willReceiveFocus = noop } = this.props;
|
|
147
141
|
willReceiveFocus(focusable, scrollDirection);
|
|
148
|
-
|
|
149
|
-
focusManager.invokeHandler?.(
|
|
150
|
-
FOCUS_EVENTS.WILL_RECEIVE_FOCUS,
|
|
151
|
-
this,
|
|
152
|
-
scrollDirection
|
|
153
|
-
);
|
|
154
142
|
};
|
|
155
143
|
|
|
156
144
|
/**
|
|
@@ -163,8 +151,6 @@ export class BaseFocusable<
|
|
|
163
151
|
const { onFocus = noop } = this.props;
|
|
164
152
|
this.setFocusedState(true);
|
|
165
153
|
onFocus(focusable, scrollDirection);
|
|
166
|
-
|
|
167
|
-
focusManager.invokeHandler?.(FOCUS_EVENTS.FOCUS, this, scrollDirection);
|
|
168
154
|
};
|
|
169
155
|
|
|
170
156
|
/**
|
|
@@ -179,12 +165,6 @@ export class BaseFocusable<
|
|
|
179
165
|
) => {
|
|
180
166
|
const { hasReceivedFocus = noop } = this.props;
|
|
181
167
|
hasReceivedFocus(focusable, scrollDirection);
|
|
182
|
-
|
|
183
|
-
focusManager.invokeHandler?.(
|
|
184
|
-
FOCUS_EVENTS.HAS_RECEIVED_FOCUS,
|
|
185
|
-
this,
|
|
186
|
-
scrollDirection
|
|
187
|
-
);
|
|
188
168
|
};
|
|
189
169
|
|
|
190
170
|
/**
|
|
@@ -196,12 +176,6 @@ export class BaseFocusable<
|
|
|
196
176
|
hasLostFocus: FocusManager.FocusEventCB = (focusable, scrollDirection) => {
|
|
197
177
|
const { hasLostFocus = noop } = this.props;
|
|
198
178
|
hasLostFocus(focusable, scrollDirection);
|
|
199
|
-
|
|
200
|
-
focusManager.invokeHandler?.(
|
|
201
|
-
FOCUS_EVENTS.HAS_LOST_FOCUS,
|
|
202
|
-
this,
|
|
203
|
-
scrollDirection
|
|
204
|
-
);
|
|
205
179
|
};
|
|
206
180
|
|
|
207
181
|
/**
|
|
@@ -228,7 +202,6 @@ export class BaseFocusable<
|
|
|
228
202
|
const { onBlur = noop } = this.props;
|
|
229
203
|
this.setFocusedState(false);
|
|
230
204
|
onBlur(focusable, scrollDirection);
|
|
231
|
-
focusManager.invokeHandler?.(FOCUS_EVENTS.BLUR, this, scrollDirection);
|
|
232
205
|
};
|
|
233
206
|
|
|
234
207
|
onPress = (keyEvent?: Nullable<React.MouseEvent>) => {
|
|
@@ -269,4 +242,68 @@ export class BaseFocusable<
|
|
|
269
242
|
this.setState({ focused });
|
|
270
243
|
}
|
|
271
244
|
};
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* will invoke the underlying component's focus method
|
|
248
|
+
* @param {Object} scrollDirection
|
|
249
|
+
* @returns {Promise}
|
|
250
|
+
*/
|
|
251
|
+
focus(_, scrollDirection) {
|
|
252
|
+
return this.onFocus(this, scrollDirection); // invokeComponentMethod(this, "onFocus", scrollDirection);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* will invoke the underlying component's blur method
|
|
257
|
+
* @param {Object} scrollDirection
|
|
258
|
+
* @returns {Promise}
|
|
259
|
+
*/
|
|
260
|
+
blur(
|
|
261
|
+
_,
|
|
262
|
+
scrollDirection?: FocusManager.Web.Direction | FocusManager.IOS.Direction
|
|
263
|
+
) {
|
|
264
|
+
return this.onBlur(this, scrollDirection);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/**
|
|
268
|
+
* Sets the focus on this item. Will trigger sequentially a sequence of
|
|
269
|
+
* functions (willReceiveFocus, focus, hasReceivedFocus). If these functions (defined in the Focusable
|
|
270
|
+
* Item underlying component) return promises, execution will wait before it proceeds to the next. This
|
|
271
|
+
* is useful for triggering sequential operations that specifically require to fully run before or after
|
|
272
|
+
* focus is actually set on that item.
|
|
273
|
+
* @param {string} scrollDirection string representation of the direction of the navigation which landed
|
|
274
|
+
* to this item being focused
|
|
275
|
+
*/
|
|
276
|
+
_executeFocusSequence(methodNames, scrollDirection) {
|
|
277
|
+
return R.reduce(
|
|
278
|
+
(sequence, methodName) => {
|
|
279
|
+
const method = this[methodName]; // Access the method by name
|
|
280
|
+
|
|
281
|
+
if (typeof method !== "function") {
|
|
282
|
+
throw new Error(
|
|
283
|
+
`Method '${methodName}' not found or not a function.`
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
return sequence
|
|
288
|
+
.then(() => method.call(this, scrollDirection))
|
|
289
|
+
.catch((e) => {
|
|
290
|
+
throw e; // Re-throw for consistent error handling
|
|
291
|
+
});
|
|
292
|
+
},
|
|
293
|
+
Promise.resolve(),
|
|
294
|
+
methodNames
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
setFocus(scrollDirection) {
|
|
299
|
+
const focusMethods = ["willReceiveFocus", "focus", "hasReceivedFocus"];
|
|
300
|
+
|
|
301
|
+
return this._executeFocusSequence(focusMethods, scrollDirection);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
setBlur(scrollDirection) {
|
|
305
|
+
const blurMethods = ["willLoseFocus", "blur", "hasLostFocus"];
|
|
306
|
+
|
|
307
|
+
return this._executeFocusSequence(blurMethods, scrollDirection);
|
|
308
|
+
}
|
|
272
309
|
}
|
package/Components/Cell/Cell.tsx
CHANGED
|
@@ -272,7 +272,16 @@ export class CellComponent extends React.Component<Props, State> {
|
|
|
272
272
|
|
|
273
273
|
if (isFocused) {
|
|
274
274
|
const accessibilityManager = AccessibilityManager.getInstance();
|
|
275
|
-
|
|
275
|
+
|
|
276
|
+
const accessibilityTitle =
|
|
277
|
+
item?.extensions?.accessibility?.label || item?.title || "";
|
|
278
|
+
|
|
279
|
+
const accessibilityHint =
|
|
280
|
+
item?.extensions?.accessibility?.hint || "";
|
|
281
|
+
|
|
282
|
+
accessibilityManager.readText({
|
|
283
|
+
text: `${accessibilityTitle} ${accessibilityHint}`,
|
|
284
|
+
});
|
|
276
285
|
}
|
|
277
286
|
|
|
278
287
|
return (
|
|
@@ -0,0 +1,126 @@
|
|
|
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
|
+
}
|
|
@@ -1,48 +1,10 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
|
|
3
|
-
import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focusManager";
|
|
4
|
-
import * as FOCUS_EVENTS from "@applicaster/zapp-react-native-utils/appUtils/focusManager/events";
|
|
5
3
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
6
4
|
import { toBooleanWithDefaultFalse } from "@applicaster/zapp-react-native-utils/booleanUtils";
|
|
7
5
|
|
|
8
|
-
import { isAppleTV } from "../../Helpers/Platform";
|
|
9
6
|
import { useCellState } from "../MasterCell/utils";
|
|
10
|
-
|
|
11
|
-
const useCellFocusedState = (
|
|
12
|
-
skipFocusManagerRegistration: boolean,
|
|
13
|
-
groupId: string,
|
|
14
|
-
id: string
|
|
15
|
-
) => {
|
|
16
|
-
const [currentCellFocused, setCurrentCellFocused] = React.useState(false);
|
|
17
|
-
|
|
18
|
-
React.useEffect(() => {
|
|
19
|
-
const isGroupItemFocused = () => {
|
|
20
|
-
if (!skipFocusManagerRegistration) {
|
|
21
|
-
const isFocused = focusManager.isGroupItemFocused(groupId, id);
|
|
22
|
-
setCurrentCellFocused(isFocused);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
const handler = () => {
|
|
27
|
-
// tvOS hack for properly checking focus
|
|
28
|
-
if (isAppleTV()) {
|
|
29
|
-
setTimeout(() => {
|
|
30
|
-
isGroupItemFocused();
|
|
31
|
-
}, 0);
|
|
32
|
-
} else {
|
|
33
|
-
isGroupItemFocused();
|
|
34
|
-
}
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
focusManager.on(FOCUS_EVENTS.FOCUS, handler);
|
|
38
|
-
|
|
39
|
-
return () => {
|
|
40
|
-
focusManager.removeHandler(FOCUS_EVENTS.FOCUS, handler);
|
|
41
|
-
};
|
|
42
|
-
}, [groupId, skipFocusManagerRegistration]);
|
|
43
|
-
|
|
44
|
-
return currentCellFocused;
|
|
45
|
-
};
|
|
7
|
+
import { FocusableGroup } from "../FocusableGroup";
|
|
46
8
|
|
|
47
9
|
type Props = {
|
|
48
10
|
item: ZappEntry;
|
|
@@ -75,11 +37,7 @@ export function CellWithFocusable(props: Props) {
|
|
|
75
37
|
focused,
|
|
76
38
|
} = props;
|
|
77
39
|
|
|
78
|
-
const isFocused =
|
|
79
|
-
skipFocusManagerRegistration,
|
|
80
|
-
groupId,
|
|
81
|
-
id
|
|
82
|
-
);
|
|
40
|
+
const [isFocused, setIsFocused] = React.useState(false);
|
|
83
41
|
|
|
84
42
|
const state = useCellState({
|
|
85
43
|
id: item.id,
|
|
@@ -96,26 +54,52 @@ export function CellWithFocusable(props: Props) {
|
|
|
96
54
|
}
|
|
97
55
|
}, [focusedButtonId]);
|
|
98
56
|
|
|
99
|
-
const handleToggleFocus = (
|
|
100
|
-
|
|
57
|
+
const handleToggleFocus = React.useCallback(
|
|
58
|
+
(value) => {
|
|
59
|
+
setFocusedButtonId(value.focusedButtonId);
|
|
60
|
+
|
|
61
|
+
if (value.focusable) {
|
|
62
|
+
onFocus(value.focusable, value.mouse);
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
[onFocus]
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const onGroupFocus = React.useCallback(() => {
|
|
69
|
+
if (!skipFocusManagerRegistration) {
|
|
70
|
+
setIsFocused(true);
|
|
71
|
+
}
|
|
72
|
+
}, [skipFocusManagerRegistration]);
|
|
101
73
|
|
|
102
|
-
|
|
103
|
-
|
|
74
|
+
const onGroupBlur = React.useCallback(() => {
|
|
75
|
+
if (!skipFocusManagerRegistration) {
|
|
76
|
+
setIsFocused(false);
|
|
104
77
|
}
|
|
105
|
-
};
|
|
78
|
+
}, [skipFocusManagerRegistration]);
|
|
106
79
|
|
|
107
80
|
return (
|
|
108
|
-
<
|
|
109
|
-
|
|
81
|
+
<FocusableGroup
|
|
82
|
+
id={`focusable-cell-wrapper-${id}`}
|
|
83
|
+
testID={"cell-with-focusable-cell-renderer-focusable-group"}
|
|
110
84
|
groupId={groupId}
|
|
111
|
-
onToggleFocus={handleToggleFocus}
|
|
112
|
-
state={state}
|
|
113
|
-
prefixId={id}
|
|
114
|
-
focusedButtonId={focusedButtonId}
|
|
115
85
|
preferredFocus={preferredFocus}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
86
|
+
shouldUsePreferredFocus
|
|
87
|
+
onFocus={onGroupFocus}
|
|
88
|
+
onBlur={onGroupBlur}
|
|
89
|
+
>
|
|
90
|
+
<CellRenderer
|
|
91
|
+
testID={"cell-with-focusable-cell-renderer"}
|
|
92
|
+
item={item}
|
|
93
|
+
groupId={`focusable-cell-wrapper-${id}`}
|
|
94
|
+
onToggleFocus={handleToggleFocus}
|
|
95
|
+
state={state}
|
|
96
|
+
prefixId={id}
|
|
97
|
+
focusedButtonId={focusedButtonId}
|
|
98
|
+
preferredFocus={true}
|
|
99
|
+
skipFocusManagerRegistration={skipFocusManagerRegistration}
|
|
100
|
+
isFocusable={isFocusable}
|
|
101
|
+
focused={focused}
|
|
102
|
+
/>
|
|
103
|
+
</FocusableGroup>
|
|
120
104
|
);
|
|
121
105
|
}
|
|
@@ -10,10 +10,6 @@ import { focusManager } from "@applicaster/zapp-react-native-utils/appUtils/focu
|
|
|
10
10
|
import { sendSelectCellEvent } from "@applicaster/zapp-react-native-utils/analyticsUtils";
|
|
11
11
|
import { noop } from "@applicaster/zapp-react-native-utils/functionUtils";
|
|
12
12
|
import { CellWithFocusable } from "./CellWithFocusable";
|
|
13
|
-
import { getCellState } from "./utils";
|
|
14
|
-
|
|
15
|
-
const _getCellState = (focused, selected) =>
|
|
16
|
-
getCellState({ focused, selected });
|
|
17
13
|
|
|
18
14
|
type Props = {
|
|
19
15
|
item: ZappEntry;
|