react-native-navigation 7.45.0 → 7.47.0
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/lib/Mock/Components/ComponentScreen.tsx +2 -1
- package/lib/Mock/Components/LayoutComponent.tsx +9 -0
- package/lib/Mock/Components/SideMenu.tsx +27 -0
- package/lib/Mock/Layouts/BottomTabsNode.ts +4 -2
- package/lib/Mock/Layouts/LayoutNodeFactory.ts +14 -1
- package/lib/Mock/Layouts/ParentNode.ts +4 -0
- package/lib/Mock/Layouts/SideMenu.ts +87 -0
- package/lib/Mock/Stores/LayoutStore.ts +42 -10
- package/lib/Mock/actions/layoutActions.ts +11 -0
- package/lib/Mock/index.js +2 -2
- package/lib/Mock/mocks/NativeCommandsSender.tsx +1 -0
- package/lib/android/app/build.gradle +0 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java +3 -9
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/ReactView.java +3 -3
- package/lib/android/app/src/main/java/com/reactnativenavigation/react/modal/ModalHostLayout.kt +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactTypefaceUtils.java +2 -3
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactViewGroup.kt +2 -4
- package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ViewUtils.java +4 -6
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/LayoutDirectionApplier.kt +4 -8
- package/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/RootPresenter.java +1 -1
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/BackgroundColorAnimator.kt +4 -6
- package/lib/android/app/src/main/java/com/reactnativenavigation/views/element/animators/BackgroundColorEvaluator.kt +2 -4
- package/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt +6 -6
- package/lib/dist/Mock/Application.d.ts +6 -4
- package/lib/dist/Mock/Components/BottomTabs.d.ts +13 -9
- package/lib/dist/Mock/Components/ComponentScreen.d.ts +7 -5
- package/lib/dist/Mock/Components/ComponentScreen.js +2 -1
- package/lib/dist/Mock/Components/LayoutComponent.d.ts +13 -9
- package/lib/dist/Mock/Components/LayoutComponent.js +9 -0
- package/lib/dist/Mock/Components/Modals.d.ts +13 -9
- package/lib/dist/Mock/Components/NavigationButton.d.ts +15 -11
- package/lib/dist/Mock/Components/Overlays.d.ts +13 -9
- package/lib/dist/Mock/Components/SideMenu.d.ts +62 -0
- package/lib/dist/Mock/Components/SideMenu.js +25 -0
- package/lib/dist/Mock/Components/Stack.d.ts +13 -9
- package/lib/dist/Mock/Components/TopBar.d.ts +9 -7
- package/lib/dist/Mock/Layouts/BottomTabsNode.d.ts +1 -1
- package/lib/dist/Mock/Layouts/BottomTabsNode.js +3 -2
- package/lib/dist/Mock/Layouts/LayoutNodeFactory.d.ts +2 -1
- package/lib/dist/Mock/Layouts/LayoutNodeFactory.js +10 -1
- package/lib/dist/Mock/Layouts/ParentNode.d.ts +1 -0
- package/lib/dist/Mock/Layouts/ParentNode.js +3 -0
- package/lib/dist/Mock/Layouts/SideMenu.d.ts +31 -0
- package/lib/dist/Mock/Layouts/SideMenu.js +80 -0
- package/lib/dist/Mock/Stores/LayoutStore.js +38 -9
- package/lib/dist/Mock/actions/layoutActions.d.ts +3 -0
- package/lib/dist/Mock/actions/layoutActions.js +11 -1
- package/lib/dist/Mock/connect.js +1 -2
- package/lib/dist/Mock/index.js +2 -2
- package/lib/dist/Mock/mocks/NativeCommandsSender.js +1 -0
- package/lib/dist/src/adapters/NativeEventsReceiver.js +1 -1
- package/lib/dist/src/adapters/TouchablePreview.d.ts +2 -2
- package/lib/dist/src/commands/LayoutType.js +1 -1
- package/lib/dist/src/components/Modal.d.ts +1 -1
- package/lib/dist/src/interfaces/CommandName.js +1 -1
- package/lib/dist/src/interfaces/Options.js +2 -2
- package/lib/dist/src/types.d.ts +0 -1
- package/lib/ios/BottomTabsBasePresenter.m +2 -3
- package/lib/ios/RNNAppDelegate.mm +3 -2
- package/lib/ios/RNNConvert.h +0 -2
- package/lib/ios/RNNConvert.m +0 -4
- package/lib/ios/RNNStackPresenter.m +2 -2
- package/lib/src/adapters/NativeEventsReceiver.ts +3 -3
- package/lib/src/adapters/TouchablePreview.tsx +3 -3
- package/package.json +31 -37
|
@@ -4,6 +4,7 @@ import { BottomTabs } from './BottomTabs';
|
|
|
4
4
|
import { ComponentProps } from '../ComponentProps';
|
|
5
5
|
import { ComponentScreen } from './ComponentScreen';
|
|
6
6
|
import { Stack } from './Stack';
|
|
7
|
+
import { SideMenuRoot, SideMenuCenter, SideMenuLeft, SideMenuRight } from './SideMenu';
|
|
7
8
|
|
|
8
9
|
export const LayoutComponent = class extends Component<ComponentProps> {
|
|
9
10
|
render() {
|
|
@@ -14,6 +15,14 @@ export const LayoutComponent = class extends Component<ComponentProps> {
|
|
|
14
15
|
return <Stack layoutNode={this.props.layoutNode} />;
|
|
15
16
|
case 'Component':
|
|
16
17
|
return <ComponentScreen layoutNode={this.props.layoutNode} />;
|
|
18
|
+
case 'SideMenuRoot':
|
|
19
|
+
return <SideMenuRoot layoutNode={this.props.layoutNode} />;
|
|
20
|
+
case 'SideMenuLeft':
|
|
21
|
+
return <SideMenuLeft layoutNode={this.props.layoutNode} />;
|
|
22
|
+
case 'SideMenuCenter':
|
|
23
|
+
return <SideMenuCenter layoutNode={this.props.layoutNode} />;
|
|
24
|
+
case 'SideMenuRight':
|
|
25
|
+
return <SideMenuRight layoutNode={this.props.layoutNode} />;
|
|
17
26
|
}
|
|
18
27
|
|
|
19
28
|
return <View />;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React, { Component } from 'react';
|
|
2
|
+
import { connect } from '../connect';
|
|
3
|
+
import { ComponentProps } from '../ComponentProps';
|
|
4
|
+
import { LayoutComponent } from './LayoutComponent';
|
|
5
|
+
import ParentNode from '../Layouts/ParentNode';
|
|
6
|
+
|
|
7
|
+
export const SideMenuRoot = connect(
|
|
8
|
+
class extends Component<ComponentProps> {
|
|
9
|
+
render() {
|
|
10
|
+
const children = this.props.layoutNode.children;
|
|
11
|
+
return children.map((child: ParentNode) => {
|
|
12
|
+
return <LayoutComponent key={child.nodeId} layoutNode={child} />;
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
class SideMenuComponent extends Component<ComponentProps> {
|
|
19
|
+
render() {
|
|
20
|
+
const children = this.props.layoutNode.children;
|
|
21
|
+
const component = children[0];
|
|
22
|
+
return <LayoutComponent key={component.nodeId} layoutNode={component} />;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export const SideMenuLeft = connect(SideMenuComponent);
|
|
26
|
+
export const SideMenuCenter = connect(SideMenuComponent);
|
|
27
|
+
export const SideMenuRight = connect(SideMenuComponent);
|
|
@@ -10,8 +10,10 @@ export default class BottomTabsNode extends ParentNode {
|
|
|
10
10
|
this.selectedIndex = layout.data?.options?.bottomTabs?.currentTabIndex || 0;
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
mergeOptions(
|
|
14
|
-
super.mergeOptions(
|
|
13
|
+
mergeOptions(_options: Options) {
|
|
14
|
+
super.mergeOptions(_options);
|
|
15
|
+
|
|
16
|
+
const { options } = this.data;
|
|
15
17
|
if (options.bottomTabs?.currentTabIndex) {
|
|
16
18
|
this.selectedIndex = options.bottomTabs?.currentTabIndex;
|
|
17
19
|
switchTabByIndex(this, this.selectedIndex);
|
|
@@ -2,6 +2,11 @@ import BottomTabs from './BottomTabsNode';
|
|
|
2
2
|
import ComponentNode from './ComponentNode';
|
|
3
3
|
import Stack from './StackNode';
|
|
4
4
|
import ParentNode from './ParentNode';
|
|
5
|
+
import SideMenuRootNode, {
|
|
6
|
+
SideMenuLeftNode,
|
|
7
|
+
SideMenuRightNode,
|
|
8
|
+
SideMenuCenterNode,
|
|
9
|
+
} from './SideMenu';
|
|
5
10
|
|
|
6
11
|
export default class LayoutNodeFactory {
|
|
7
12
|
static create(layout: any, parentNode?: ParentNode) {
|
|
@@ -10,7 +15,15 @@ export default class LayoutNodeFactory {
|
|
|
10
15
|
return new ComponentNode(layout, parentNode);
|
|
11
16
|
case 'Stack':
|
|
12
17
|
return new Stack(layout, parentNode);
|
|
13
|
-
|
|
18
|
+
case 'SideMenuRoot':
|
|
19
|
+
return new SideMenuRootNode(layout, parentNode);
|
|
20
|
+
case 'SideMenuLeft':
|
|
21
|
+
return new SideMenuLeftNode(layout, parentNode);
|
|
22
|
+
case 'SideMenuCenter':
|
|
23
|
+
return new SideMenuCenterNode(layout, parentNode);
|
|
24
|
+
case 'SideMenuRight':
|
|
25
|
+
return new SideMenuRightNode(layout, parentNode);
|
|
26
|
+
default: // TODO Undo
|
|
14
27
|
case 'BottomTabs':
|
|
15
28
|
return new BottomTabs(layout, parentNode);
|
|
16
29
|
}
|
|
@@ -35,6 +35,10 @@ export default class ParentNode extends Node {
|
|
|
35
35
|
return this;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
applyOptions(_options: Options) {
|
|
39
|
+
this.parentNode?.applyOptions(_options);
|
|
40
|
+
}
|
|
41
|
+
|
|
38
42
|
mergeOptions(options: Options) {
|
|
39
43
|
this.data.options = _.mergeWith(this.data.options, options, (objValue, srcValue, key) => {
|
|
40
44
|
if (_.isArray(objValue)) {
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import ParentNode from './ParentNode';
|
|
2
|
+
import ComponentNode from './ComponentNode';
|
|
3
|
+
import { Options } from '../../src/index';
|
|
4
|
+
import * as layoutActions from '../actions/layoutActions';
|
|
5
|
+
import { NodeType } from './Node';
|
|
6
|
+
|
|
7
|
+
const isCenterChild = (child: ParentNode) => child.type === 'SideMenuCenter';
|
|
8
|
+
const isLeftChild = (child: ParentNode) => child.type === 'SideMenuLeft';
|
|
9
|
+
const isRightChild = (child: ParentNode) => child.type === 'SideMenuRight';
|
|
10
|
+
|
|
11
|
+
export default class SideMenuRootNode extends ParentNode {
|
|
12
|
+
visibleChild: ParentNode;
|
|
13
|
+
|
|
14
|
+
constructor(layout: any, parentNode?: ParentNode) {
|
|
15
|
+
super(layout, 'SideMenuRoot', parentNode);
|
|
16
|
+
|
|
17
|
+
this.visibleChild = this._getCenterChild();
|
|
18
|
+
if (!this.visibleChild) {
|
|
19
|
+
throw new Error('SideMenuRootNode must have a SideMenuCenter child');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
applyOptions(_options: Options) {
|
|
24
|
+
super.applyOptions(_options);
|
|
25
|
+
|
|
26
|
+
this._updateVisibility(_options);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
mergeOptions(options: Options) {
|
|
30
|
+
super.mergeOptions(options);
|
|
31
|
+
|
|
32
|
+
this._updateVisibility(options);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @override
|
|
37
|
+
*/
|
|
38
|
+
getVisibleLayout(): ComponentNode {
|
|
39
|
+
return this.visibleChild.getVisibleLayout();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
_updateVisibility(options: Options) {
|
|
43
|
+
if (options.sideMenu) {
|
|
44
|
+
if (options.sideMenu.left?.visible) {
|
|
45
|
+
this.visibleChild = this._getLeftChild();
|
|
46
|
+
layoutActions.openSideMenu(this.visibleChild);
|
|
47
|
+
} else if (options.sideMenu.right?.visible) {
|
|
48
|
+
this.visibleChild = this._getRightChild();
|
|
49
|
+
layoutActions.openSideMenu(this.visibleChild);
|
|
50
|
+
} else {
|
|
51
|
+
this.visibleChild = this._getCenterChild();
|
|
52
|
+
layoutActions.closeSideMenu(this.visibleChild);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
_getCenterChild = () => this.children.find(isCenterChild) as ParentNode;
|
|
58
|
+
_getLeftChild = () => this.children.find(isLeftChild) as ParentNode;
|
|
59
|
+
_getRightChild = () => this.children.find(isRightChild) as ParentNode;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class SideMenuNode extends ParentNode {
|
|
63
|
+
constructor(layout: any, type: NodeType, parentNode?: ParentNode) {
|
|
64
|
+
super(layout, type, parentNode);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
getVisibleLayout() {
|
|
68
|
+
return this.children[0].getVisibleLayout();
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export class SideMenuLeftNode extends SideMenuNode {
|
|
73
|
+
constructor(layout: any, parentNode?: ParentNode) {
|
|
74
|
+
super(layout, 'SideMenuLeft', parentNode);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
export class SideMenuRightNode extends SideMenuNode {
|
|
78
|
+
constructor(layout: any, parentNode?: ParentNode) {
|
|
79
|
+
super(layout, 'SideMenuRight', parentNode);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export class SideMenuCenterNode extends SideMenuNode {
|
|
84
|
+
constructor(layout: any, parentNode?: ParentNode) {
|
|
85
|
+
super(layout, 'SideMenuCenter', parentNode);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -2,8 +2,9 @@ import _ from 'lodash';
|
|
|
2
2
|
import BottomTabsNode from '../Layouts/BottomTabsNode';
|
|
3
3
|
import ParentNode from '../Layouts/ParentNode';
|
|
4
4
|
import LayoutNodeFactory from '../Layouts/LayoutNodeFactory';
|
|
5
|
-
import {
|
|
5
|
+
import { SideMenuNode } from '../Layouts/SideMenu';
|
|
6
6
|
import StackNode from '../Layouts/StackNode';
|
|
7
|
+
import { Options } from '../../src/interfaces/Options';
|
|
7
8
|
|
|
8
9
|
const remx = require('remx');
|
|
9
10
|
|
|
@@ -11,6 +12,7 @@ const state = remx.state({
|
|
|
11
12
|
root: {},
|
|
12
13
|
modals: [],
|
|
13
14
|
overlays: [],
|
|
15
|
+
sideMenu: undefined,
|
|
14
16
|
});
|
|
15
17
|
|
|
16
18
|
const setters = remx.setters({
|
|
@@ -75,6 +77,23 @@ const setters = remx.setters({
|
|
|
75
77
|
selectTabIndex(layout: BottomTabsNode, index: number) {
|
|
76
78
|
getters.getLayoutById(layout.nodeId).selectedIndex = index;
|
|
77
79
|
},
|
|
80
|
+
openSideMenu(layout: SideMenuNode) {
|
|
81
|
+
if (state.sideMenu) {
|
|
82
|
+
throw new Error(
|
|
83
|
+
'A side-menu is already open; Mocked-testing of multiple side-menu scenarios is not supported yet.' +
|
|
84
|
+
' You can submit a request in https://github.com/wix/react-native-navigation/issues/new/choose.'
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
state.sideMenu = layout;
|
|
88
|
+
},
|
|
89
|
+
closeSideMenu(_layout: SideMenuNode) {
|
|
90
|
+
state.sideMenu = undefined;
|
|
91
|
+
},
|
|
92
|
+
applyOptions(componentId: string, options: Options) {
|
|
93
|
+
const layout = getters.getLayoutById(componentId);
|
|
94
|
+
if (layout) layout.applyOptions(options);
|
|
95
|
+
else console.warn(`[RNN error] Merge options failure: cannot find layout for: ${componentId}`);
|
|
96
|
+
},
|
|
78
97
|
mergeOptions(componentId: string, options: Options) {
|
|
79
98
|
const layout = getters.getLayoutById(componentId);
|
|
80
99
|
if (layout) layout.mergeOptions(options);
|
|
@@ -87,12 +106,26 @@ const getters = remx.getters({
|
|
|
87
106
|
return state.root;
|
|
88
107
|
},
|
|
89
108
|
getVisibleLayout() {
|
|
109
|
+
let layout: ParentNode | undefined;
|
|
90
110
|
if (state.modals.length > 0) {
|
|
91
|
-
|
|
92
|
-
} else if (!_.isEqual(state.root, {}))
|
|
111
|
+
layout = _.last<ParentNode>(state.modals)!;
|
|
112
|
+
} else if (!_.isEqual(state.root, {})) {
|
|
113
|
+
layout = state.root;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Note: While this logic should be fair for all use cases (i.e. even multiple side-menus across tabs),
|
|
117
|
+
// there is no current test case that justifies it. Nevertheless, it's required to pass the tests,
|
|
118
|
+
// because otherwise getVisibleLayout() would not be revisited whenever side-menus are opened/closed.
|
|
119
|
+
if (layout && state.sideMenu && findNode(state.sideMenu.nodeId, layout!)) {
|
|
120
|
+
layout = state.sideMenu.parentNode;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
return layout?.getVisibleLayout();
|
|
93
124
|
},
|
|
94
125
|
isVisibleLayout(layout: ParentNode) {
|
|
95
|
-
|
|
126
|
+
const nodeId = layout.nodeId;
|
|
127
|
+
const visibleLayout = getters.getVisibleLayout();
|
|
128
|
+
return visibleLayout?.nodeId === nodeId;
|
|
96
129
|
},
|
|
97
130
|
getModals() {
|
|
98
131
|
return state.modals;
|
|
@@ -101,13 +134,12 @@ const getters = remx.getters({
|
|
|
101
134
|
return state.overlays;
|
|
102
135
|
},
|
|
103
136
|
getLayoutById(layoutId: string) {
|
|
104
|
-
if (getters.getModalById(layoutId))
|
|
105
|
-
return findParentNode(layoutId, getters.getModalById(layoutId));
|
|
137
|
+
if (getters.getModalById(layoutId)) return findNode(layoutId, getters.getModalById(layoutId));
|
|
106
138
|
|
|
107
|
-
return
|
|
139
|
+
return findNode(layoutId, state.root);
|
|
108
140
|
},
|
|
109
141
|
getModalById(layoutId: string) {
|
|
110
|
-
return _.find(state.modals, (layout) =>
|
|
142
|
+
return _.find(state.modals, (layout) => findNode(layoutId, layout));
|
|
111
143
|
},
|
|
112
144
|
getLayoutChildren(layoutId: string) {
|
|
113
145
|
return getters.getLayoutById(layoutId).children;
|
|
@@ -120,13 +152,13 @@ const getters = remx.getters({
|
|
|
120
152
|
},
|
|
121
153
|
});
|
|
122
154
|
|
|
123
|
-
function
|
|
155
|
+
function findNode(layoutId: string, layout: ParentNode): any | ParentNode {
|
|
124
156
|
if (layoutId === layout.nodeId) {
|
|
125
157
|
return layout;
|
|
126
158
|
} else if (layout.children) {
|
|
127
159
|
for (let i = 0; i < layout.children.length; i += 1) {
|
|
128
160
|
const child = layout.children[i];
|
|
129
|
-
const result =
|
|
161
|
+
const result = findNode(layoutId, child);
|
|
130
162
|
|
|
131
163
|
if (result !== false) {
|
|
132
164
|
return result;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import ParentNode from '../Layouts/ParentNode';
|
|
2
|
+
import { SideMenuNode } from '../Layouts/SideMenu';
|
|
2
3
|
import { LayoutStore } from '../Stores/LayoutStore';
|
|
3
4
|
|
|
4
5
|
export const switchTabByIndex = (bottomTabs: ParentNode | undefined, index: number) => {
|
|
@@ -8,3 +9,13 @@ export const switchTabByIndex = (bottomTabs: ParentNode | undefined, index: numb
|
|
|
8
9
|
LayoutStore.getVisibleLayout().componentDidAppear();
|
|
9
10
|
}
|
|
10
11
|
};
|
|
12
|
+
|
|
13
|
+
export const openSideMenu = (sideMenu: SideMenuNode) => {
|
|
14
|
+
LayoutStore.openSideMenu(sideMenu);
|
|
15
|
+
LayoutStore.getVisibleLayout().componentDidAppear();
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const closeSideMenu = (layout: SideMenuNode) => {
|
|
19
|
+
LayoutStore.getVisibleLayout().componentDidDisappear();
|
|
20
|
+
LayoutStore.closeSideMenu(layout);
|
|
21
|
+
};
|
package/lib/Mock/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.ApplicationMock = void 0;
|
|
4
|
+
exports.mockNativeComponents = mockNativeComponents;
|
|
4
5
|
const tslib_1 = require("tslib");
|
|
5
6
|
exports.ApplicationMock = require('./Application').Application;
|
|
6
7
|
tslib_1.__exportStar(require("./constants"), exports);
|
|
@@ -11,4 +12,3 @@ function mockNativeComponents() {
|
|
|
11
12
|
const { Navigation } = require('react-native-navigation');
|
|
12
13
|
Navigation.mockNativeComponents(new NativeCommandsSender(), new NativeEventsReceiver(), new AppRegistryService());
|
|
13
14
|
}
|
|
14
|
-
exports.mockNativeComponents = mockNativeComponents;
|
|
@@ -39,6 +39,7 @@ export class NativeCommandsSender {
|
|
|
39
39
|
const layoutNode = LayoutNodeFactory.create(layout, stack);
|
|
40
40
|
stack.getVisibleLayout().componentDidDisappear();
|
|
41
41
|
LayoutStore.push(layoutNode, stack);
|
|
42
|
+
LayoutStore.applyOptions(layoutNode.nodeId, layoutNode.data.options);
|
|
42
43
|
stack.getVisibleLayout().componentDidAppear();
|
|
43
44
|
resolve(stack.getVisibleLayout().nodeId);
|
|
44
45
|
this.reportCommandCompletion(CommandName.Push, commandId);
|
|
@@ -20,7 +20,6 @@ def DEFAULT_KOTLIN_STDLIB = 'kotlin-stdlib-jdk8'
|
|
|
20
20
|
def kotlinVersion = safeExtGet("RNNKotlinVersion", DEFAULT_KOTLIN_VERSION)
|
|
21
21
|
def kotlinStdlib = safeExtGet('RNNKotlinStdlib',DEFAULT_KOTLIN_STDLIB )
|
|
22
22
|
def kotlinCoroutinesCore = safeExtGet('RNNKotlinCoroutinesCore', '1.5.2')
|
|
23
|
-
|
|
24
23
|
android {
|
|
25
24
|
namespace 'com.reactnativenavigation'
|
|
26
25
|
compileSdkVersion safeExtGetFallbackLowerBound('compileSdkVersion', DEFAULT_COMPILE_SDK_VERSION)
|
|
@@ -2,20 +2,18 @@ package com.reactnativenavigation;
|
|
|
2
2
|
|
|
3
3
|
import android.app.Application;
|
|
4
4
|
|
|
5
|
+
import androidx.annotation.NonNull;
|
|
6
|
+
|
|
5
7
|
import com.facebook.react.ReactApplication;
|
|
6
8
|
import com.facebook.react.ReactNativeHost;
|
|
7
|
-
import com.facebook.react.soloader.OpenSourceMergedSoMapping;
|
|
8
9
|
import com.facebook.soloader.SoLoader;
|
|
9
10
|
import com.reactnativenavigation.react.ReactGateway;
|
|
10
11
|
import com.reactnativenavigation.viewcontrollers.externalcomponent.ExternalComponentCreator;
|
|
11
12
|
|
|
12
13
|
import java.util.Collections;
|
|
13
|
-
import java.io.IOException;
|
|
14
14
|
import java.util.HashMap;
|
|
15
15
|
import java.util.Map;
|
|
16
16
|
|
|
17
|
-
import androidx.annotation.NonNull;
|
|
18
|
-
|
|
19
17
|
public abstract class NavigationApplication extends Application implements ReactApplication {
|
|
20
18
|
|
|
21
19
|
public static NavigationApplication instance;
|
|
@@ -35,11 +33,7 @@ public abstract class NavigationApplication extends Application implements React
|
|
|
35
33
|
@Override
|
|
36
34
|
public void onCreate() {
|
|
37
35
|
super.onCreate();
|
|
38
|
-
|
|
39
|
-
SoLoader.init(this, OpenSourceMergedSoMapping.INSTANCE);
|
|
40
|
-
} catch (IOException e) {
|
|
41
|
-
throw new RuntimeException(e);
|
|
42
|
-
}
|
|
36
|
+
SoLoader.init(this, false);
|
|
43
37
|
reactGateway = createReactGateway();
|
|
44
38
|
}
|
|
45
39
|
|
|
@@ -5,8 +5,6 @@ import android.content.Context;
|
|
|
5
5
|
import android.os.Bundle;
|
|
6
6
|
import android.view.MotionEvent;
|
|
7
7
|
|
|
8
|
-
import androidx.annotation.RestrictTo;
|
|
9
|
-
|
|
10
8
|
import com.facebook.react.ReactInstanceManager;
|
|
11
9
|
import com.facebook.react.ReactRootView;
|
|
12
10
|
import com.facebook.react.bridge.ReactContext;
|
|
@@ -14,12 +12,14 @@ import com.facebook.react.config.ReactFeatureFlags;
|
|
|
14
12
|
import com.facebook.react.uimanager.JSTouchDispatcher;
|
|
15
13
|
import com.facebook.react.uimanager.UIManagerModule;
|
|
16
14
|
import com.facebook.react.uimanager.events.EventDispatcher;
|
|
15
|
+
import com.reactnativenavigation.viewcontrollers.viewcontroller.ScrollEventListener;
|
|
17
16
|
import com.reactnativenavigation.react.events.ComponentType;
|
|
18
17
|
import com.reactnativenavigation.react.events.EventEmitter;
|
|
19
18
|
import com.reactnativenavigation.viewcontrollers.viewcontroller.IReactView;
|
|
20
|
-
import com.reactnativenavigation.viewcontrollers.viewcontroller.ScrollEventListener;
|
|
21
19
|
import com.reactnativenavigation.views.component.Renderable;
|
|
22
20
|
|
|
21
|
+
import androidx.annotation.RestrictTo;
|
|
22
|
+
|
|
23
23
|
@SuppressLint("ViewConstructor")
|
|
24
24
|
public class ReactView extends ReactRootView implements IReactView, Renderable {
|
|
25
25
|
|
package/lib/android/app/src/main/java/com/reactnativenavigation/react/modal/ModalHostLayout.kt
CHANGED
|
@@ -34,7 +34,7 @@ open class ModalHostLayout(reactContext: ThemedReactContext) : ViewGroup(reactCo
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
@TargetApi(23)
|
|
37
|
-
override fun dispatchProvideStructure(structure: ViewStructure) {
|
|
37
|
+
override fun dispatchProvideStructure(structure: ViewStructure?) {
|
|
38
38
|
mHostView.dispatchProvideStructure(structure)
|
|
39
39
|
}
|
|
40
40
|
|
package/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactTypefaceUtils.java
CHANGED
|
@@ -18,7 +18,6 @@ import android.graphics.Typeface;
|
|
|
18
18
|
import android.text.TextUtils;
|
|
19
19
|
import androidx.annotation.Nullable;
|
|
20
20
|
import com.facebook.react.bridge.ReadableArray;
|
|
21
|
-
import com.facebook.react.common.ReactConstants;
|
|
22
21
|
import com.facebook.react.views.text.ReactFontManager;
|
|
23
22
|
import com.facebook.react.views.text.ReactTextShadowNode;
|
|
24
23
|
import java.util.ArrayList;
|
|
@@ -97,12 +96,12 @@ public class ReactTypefaceUtils {
|
|
|
97
96
|
|
|
98
97
|
int want = 0;
|
|
99
98
|
if ((weight == Typeface.BOLD)
|
|
100
|
-
|| ((oldStyle & Typeface.BOLD) != 0 && weight ==
|
|
99
|
+
|| ((oldStyle & Typeface.BOLD) != 0 && weight == ReactTextShadowNode.UNSET)) {
|
|
101
100
|
want |= Typeface.BOLD;
|
|
102
101
|
}
|
|
103
102
|
|
|
104
103
|
if ((style == Typeface.ITALIC)
|
|
105
|
-
|| ((oldStyle & Typeface.ITALIC) != 0 && style ==
|
|
104
|
+
|| ((oldStyle & Typeface.ITALIC) != 0 && style == ReactTextShadowNode.UNSET)) {
|
|
106
105
|
want |= Typeface.ITALIC;
|
|
107
106
|
}
|
|
108
107
|
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
package com.reactnativenavigation.utils
|
|
2
2
|
|
|
3
|
-
import com.facebook.react.
|
|
4
|
-
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable
|
|
3
|
+
import com.facebook.react.views.view.ReactViewBackgroundDrawable
|
|
5
4
|
import com.facebook.react.views.view.ReactViewGroup
|
|
6
5
|
|
|
7
|
-
@OptIn(UnstableReactNativeAPI::class)
|
|
8
6
|
val ReactViewGroup.borderRadius: Float
|
|
9
|
-
get() = (background as?
|
|
7
|
+
get() = (background as? ReactViewBackgroundDrawable)?.fullBorderRadius ?: 0f
|
|
@@ -5,6 +5,8 @@ import android.view.View;
|
|
|
5
5
|
import android.view.ViewGroup;
|
|
6
6
|
import android.view.ViewParent;
|
|
7
7
|
|
|
8
|
+
import com.facebook.react.views.view.ReactViewBackgroundDrawable;
|
|
9
|
+
|
|
8
10
|
import java.util.ArrayList;
|
|
9
11
|
import java.util.List;
|
|
10
12
|
|
|
@@ -12,9 +14,6 @@ import androidx.annotation.Nullable;
|
|
|
12
14
|
|
|
13
15
|
import static com.reactnativenavigation.utils.ObjectUtils.perform;
|
|
14
16
|
|
|
15
|
-
import com.facebook.react.common.annotations.UnstableReactNativeAPI;
|
|
16
|
-
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable;
|
|
17
|
-
|
|
18
17
|
public class ViewUtils {
|
|
19
18
|
@Nullable
|
|
20
19
|
public static <T extends View> T findChildByClass(ViewGroup root, Class<T> clazz) {
|
|
@@ -108,10 +107,9 @@ public class ViewUtils {
|
|
|
108
107
|
return ((ViewGroup) parent).indexOfChild(view);
|
|
109
108
|
}
|
|
110
109
|
|
|
111
|
-
@UnstableReactNativeAPI
|
|
112
110
|
public static int getBackgroundColor(View view) {
|
|
113
|
-
if (view.getBackground() instanceof
|
|
114
|
-
return ((
|
|
111
|
+
if (view.getBackground() instanceof ReactViewBackgroundDrawable) {
|
|
112
|
+
return ((ReactViewBackgroundDrawable) view.getBackground()).getColor();
|
|
115
113
|
}
|
|
116
114
|
throw new RuntimeException(view.getBackground().getClass().getSimpleName() + " is not ReactViewBackgroundDrawable");
|
|
117
115
|
}
|
|
@@ -1,19 +1,15 @@
|
|
|
1
1
|
package com.reactnativenavigation.viewcontrollers.viewcontroller
|
|
2
2
|
|
|
3
|
-
import android.annotation.SuppressLint
|
|
4
3
|
import com.facebook.react.ReactInstanceManager
|
|
5
4
|
import com.facebook.react.modules.i18nmanager.I18nUtil
|
|
6
5
|
import com.reactnativenavigation.options.Options
|
|
7
6
|
|
|
8
7
|
class LayoutDirectionApplier {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
val currentContext = root.view?.context ?: return
|
|
12
|
-
|
|
13
|
-
if (options.layout.direction.hasValue()) {
|
|
8
|
+
fun apply(root: ViewController<*>, options: Options, instanceManager: ReactInstanceManager) {
|
|
9
|
+
if (options.layout.direction.hasValue() && instanceManager.currentReactContext != null) {
|
|
14
10
|
root.activity.window.decorView.layoutDirection = options.layout.direction.get()
|
|
15
|
-
I18nUtil.
|
|
16
|
-
I18nUtil.
|
|
11
|
+
I18nUtil.getInstance().allowRTL(instanceManager.currentReactContext, options.layout.direction.isRtl)
|
|
12
|
+
I18nUtil.getInstance().forceRTL(instanceManager.currentReactContext, options.layout.direction.isRtl)
|
|
17
13
|
}
|
|
18
14
|
}
|
|
19
15
|
}
|
|
@@ -35,7 +35,7 @@ public class RootPresenter {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
public void setRoot(ViewController appearingRoot, ViewController<?> disappearingRoot, Options defaultOptions, CommandListener listener, ReactInstanceManager reactInstanceManager) {
|
|
38
|
-
layoutDirectionApplier.apply(appearingRoot, defaultOptions);
|
|
38
|
+
layoutDirectionApplier.apply(appearingRoot, defaultOptions, reactInstanceManager);
|
|
39
39
|
rootLayout.addView(appearingRoot.getView(), matchParentWithBehaviour(new BehaviourDelegate(appearingRoot)));
|
|
40
40
|
Options options = appearingRoot.resolveCurrentOptions(defaultOptions);
|
|
41
41
|
AnimationOptions enter = options.animations.setRoot.getEnter();
|
|
@@ -4,23 +4,21 @@ import android.animation.Animator
|
|
|
4
4
|
import android.animation.ObjectAnimator
|
|
5
5
|
import android.view.View
|
|
6
6
|
import android.view.ViewGroup
|
|
7
|
-
import com.facebook.react.common.annotations.UnstableReactNativeAPI
|
|
8
|
-
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable
|
|
9
7
|
import com.facebook.react.views.text.ReactTextView
|
|
8
|
+
import com.facebook.react.views.view.ReactViewBackgroundDrawable
|
|
10
9
|
import com.reactnativenavigation.options.SharedElementTransitionOptions
|
|
11
10
|
import com.reactnativenavigation.utils.*
|
|
12
11
|
|
|
13
|
-
@OptIn(UnstableReactNativeAPI::class)
|
|
14
12
|
class BackgroundColorAnimator(from: View, to: View) : PropertyAnimatorCreator<ViewGroup>(from, to) {
|
|
15
13
|
override fun shouldAnimateProperty(fromChild: ViewGroup, toChild: ViewGroup): Boolean {
|
|
16
|
-
return fromChild.background is
|
|
17
|
-
toChild.background is
|
|
14
|
+
return fromChild.background is ReactViewBackgroundDrawable &&
|
|
15
|
+
toChild.background is ReactViewBackgroundDrawable && (fromChild.background as ReactViewBackgroundDrawable).color != (toChild.background as ReactViewBackgroundDrawable).color
|
|
18
16
|
}
|
|
19
17
|
|
|
20
18
|
override fun excludedViews() = listOf(ReactTextView::class.java)
|
|
21
19
|
|
|
22
20
|
override fun create(options: SharedElementTransitionOptions): Animator {
|
|
23
|
-
val backgroundColorEvaluator = BackgroundColorEvaluator(to.background as
|
|
21
|
+
val backgroundColorEvaluator = BackgroundColorEvaluator(to.background as ReactViewBackgroundDrawable)
|
|
24
22
|
val fromColor = ColorUtils.colorToLAB(ViewUtils.getBackgroundColor(from))
|
|
25
23
|
val toColor = ColorUtils.colorToLAB(ViewUtils.getBackgroundColor(to))
|
|
26
24
|
|
|
@@ -2,13 +2,11 @@ package com.reactnativenavigation.views.element.animators
|
|
|
2
2
|
|
|
3
3
|
import android.animation.TypeEvaluator
|
|
4
4
|
import androidx.core.graphics.ColorUtils
|
|
5
|
-
import com.facebook.react.
|
|
6
|
-
import com.facebook.react.uimanager.drawable.CSSBackgroundDrawable
|
|
5
|
+
import com.facebook.react.views.view.ReactViewBackgroundDrawable
|
|
7
6
|
|
|
8
|
-
class BackgroundColorEvaluator
|
|
7
|
+
class BackgroundColorEvaluator(private val background: ReactViewBackgroundDrawable) : TypeEvaluator<DoubleArray> {
|
|
9
8
|
private val color = DoubleArray(3)
|
|
10
9
|
|
|
11
|
-
@OptIn(UnstableReactNativeAPI::class)
|
|
12
10
|
override fun evaluate(ratio: Float, from: DoubleArray, to: DoubleArray): DoubleArray {
|
|
13
11
|
ColorUtils.blendLAB(from, to, ratio.toDouble(), color)
|
|
14
12
|
background.color = com.reactnativenavigation.utils.ColorUtils.labToColor(color)
|
|
@@ -49,17 +49,17 @@ class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{
|
|
|
49
49
|
updateFirstChildView()
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
override fun onChildStartedNativeGesture(child: View, androidEvent: MotionEvent) {
|
|
52
|
+
override fun onChildStartedNativeGesture(child: View, androidEvent: MotionEvent?) {
|
|
53
53
|
mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher())
|
|
54
54
|
}
|
|
55
|
-
override fun onChildStartedNativeGesture(androidEvent: MotionEvent) {
|
|
55
|
+
override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) {
|
|
56
56
|
mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher())
|
|
57
57
|
}
|
|
58
|
-
override fun onChildEndedNativeGesture(child: View, androidEvent: MotionEvent) {
|
|
58
|
+
override fun onChildEndedNativeGesture(child: View, androidEvent: MotionEvent?) {
|
|
59
59
|
mJSTouchDispatcher.onChildEndedNativeGesture(androidEvent, this.getEventDispatcher())
|
|
60
60
|
}
|
|
61
61
|
override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
|
|
62
|
-
private fun getEventDispatcher(): EventDispatcher {
|
|
62
|
+
private fun getEventDispatcher(): EventDispatcher? {
|
|
63
63
|
val reactContext: ReactContext = this.getReactContext()
|
|
64
64
|
return reactContext.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher
|
|
65
65
|
}
|
|
@@ -73,12 +73,12 @@ class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{
|
|
|
73
73
|
return this.context as ReactContext
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
-
override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
|
|
76
|
+
override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
|
|
77
77
|
mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher())
|
|
78
78
|
return super.onInterceptTouchEvent(event)
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
override fun onTouchEvent(event: MotionEvent): Boolean {
|
|
81
|
+
override fun onTouchEvent(event: MotionEvent?): Boolean {
|
|
82
82
|
mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher())
|
|
83
83
|
super.onTouchEvent(event)
|
|
84
84
|
return true
|
|
@@ -4,11 +4,13 @@ interface ApplicationProps {
|
|
|
4
4
|
}
|
|
5
5
|
export declare const Application: {
|
|
6
6
|
new (props: ApplicationProps): {
|
|
7
|
-
render():
|
|
8
|
-
context:
|
|
7
|
+
render(): JSX.Element;
|
|
8
|
+
context: any;
|
|
9
9
|
setState<K extends never>(state: {} | ((prevState: Readonly<{}>, props: Readonly<ApplicationProps>) => {} | Pick<{}, K> | null) | Pick<{}, K> | null, callback?: (() => void) | undefined): void;
|
|
10
10
|
forceUpdate(callback?: (() => void) | undefined): void;
|
|
11
|
-
readonly props: Readonly<ApplicationProps
|
|
11
|
+
readonly props: Readonly<ApplicationProps> & Readonly<{
|
|
12
|
+
children?: React.ReactNode;
|
|
13
|
+
}>;
|
|
12
14
|
state: Readonly<{}>;
|
|
13
15
|
refs: {
|
|
14
16
|
[key: string]: React.ReactInstance;
|
|
@@ -26,6 +28,6 @@ export declare const Application: {
|
|
|
26
28
|
componentWillUpdate?(nextProps: Readonly<ApplicationProps>, nextState: Readonly<{}>, nextContext: any): void;
|
|
27
29
|
UNSAFE_componentWillUpdate?(nextProps: Readonly<ApplicationProps>, nextState: Readonly<{}>, nextContext: any): void;
|
|
28
30
|
};
|
|
29
|
-
contextType?: React.Context<any
|
|
31
|
+
contextType?: React.Context<any>;
|
|
30
32
|
};
|
|
31
33
|
export {};
|