瀏覽代碼

V2 side menu visibility ios (toggleDrawer) (#2324)

* side menu visibility options

* e2e fix

* Rename ContainerView related classes (#2328)

* Rename ContainerView related classes

* fix test

* rename ContainerViewCreator

* splitted showSideMenu into two methods
yogevbd 7 年之前
父節點
當前提交
68dd47ac81

+ 1
- 1
README.md 查看文件

@@ -197,7 +197,7 @@ Note:  v1 properties with names beginning with 'navBar' are replaced in v2 with
197 197
 | rootBackgroundImageName            |  ✅   |    [Contribute](/docs/docs/CONTRIBUTING.md)     |    [Contribute](/docs/docs/CONTRIBUTING.md)       |
198 198
 | setButtons          |   ✅     |    ✅    | [Contribute](/docs/docs/CONTRIBUTING.md) | @Johan-dutoit|
199 199
 | title            |   ✅     |        	✅    | 	✅| Wix|
200
-| toggleDrawer        |   ✅     |        [Contribute](/docs/docs/CONTRIBUTING.md)   | [Contribute](/docs/docs/CONTRIBUTING.md) |
200
+| toggleDrawer        |   ✅     |           | [Contribute](/docs/docs/CONTRIBUTING.md) |
201 201
 | setTabBadge         |    ✅    |       ✅    | [Contribute](/docs/docs/CONTRIBUTING.md)| Wix|
202 202
 | switchToTab         |    ✅    |       ✅   |[Contribute](/docs/docs/CONTRIBUTING.md) |
203 203
 | topBarCustomView        |   ✅     |     WIP @gran33     | [Contribute](/docs/docs/CONTRIBUTING.md)|

+ 16
- 0
e2e/ScreenStyle.test.js 查看文件

@@ -75,6 +75,22 @@ describe('screen style', () => {
75 75
     await expect(element(by.type('UITabBar'))).toBeVisible();
76 76
   });
77 77
 
78
+  it('side menu visibility - left', async () => {
79
+    await elementById(testIDs.TAB_BASED_APP_SIDE_BUTTON).tap();
80
+    await elementById(testIDs.SHOW_LEFT_SIDE_MENU_BUTTON).tap();
81
+    await expect(elementById(testIDs.HIDE_LEFT_SIDE_MENU_BUTTON)).toBeVisible();
82
+    await elementById(testIDs.HIDE_LEFT_SIDE_MENU_BUTTON).tap();
83
+    await expect(elementById(testIDs.CENTERED_TEXT_HEADER)).toBeVisible();
84
+  });
85
+
86
+  it('side menu visibility - right', async () => {
87
+    await elementById(testIDs.TAB_BASED_APP_SIDE_BUTTON).tap();
88
+    await elementById(testIDs.SHOW_RIGHT_SIDE_MENU_BUTTON).tap();
89
+    await expect(elementById(testIDs.HIDE_RIGHT_SIDE_MENU_BUTTON)).toBeVisible();
90
+    await elementById(testIDs.HIDE_RIGHT_SIDE_MENU_BUTTON).tap();
91
+    await expect(elementById(testIDs.CENTERED_TEXT_HEADER)).toBeVisible();
92
+  });
93
+
78 94
   it('set right buttons', async () => {
79 95
     await elementById(testIDs.PUSH_OPTIONS_BUTTON).tap();
80 96
     await expect(elementById('buttonOne')).toBeVisible();

+ 2
- 2
e2e/TopLevelApi.test.js 查看文件

@@ -20,8 +20,8 @@ describe('top level api', () => {
20 20
 
21 21
   it('switch to tabs with side menus', async () => {
22 22
     await elementById(testIDs.TAB_BASED_APP_SIDE_BUTTON).tap();
23
-    await elementByLabel('This is a side menu center screen tab 1').swipe('right');
24
-    await expect(elementByLabel('This is a left side menu screen')).toBeVisible();
23
+    await elementById(testIDs.CENTERED_TEXT_HEADER).swipe('right');
24
+    await expect(elementById(testIDs.HIDE_LEFT_SIDE_MENU_BUTTON)).toBeVisible();
25 25
   });
26 26
 
27 27
   it('screen lifecycle', async () => {

+ 2
- 0
lib/ios/RNNNavigationOptions.h 查看文件

@@ -2,6 +2,7 @@
2 2
 #import <UIKit/UIKit.h>
3 3
 #import "RNNTopBarOptions.h"
4 4
 #import "RNNTabBarOptions.h"
5
+#import "RNNSideMenuOptions.h"
5 6
 
6 7
 extern const NSInteger BLUR_STATUS_TAG;
7 8
 extern const NSInteger BLUR_TOPBAR_TAG;
@@ -21,6 +22,7 @@ extern const NSInteger TOP_BAR_TRANSPARENT_TAG;
21 22
 @property (nonatomic, strong) NSNumber* popGesture;
22 23
 @property (nonatomic, strong) RNNTopBarOptions* topBar;
23 24
 @property (nonatomic, strong) RNNTabBarOptions* bottomTabs;
25
+@property (nonatomic, strong) RNNSideMenuOptions* sideMenu;
24 26
 
25 27
 
26 28
 - (UIInterfaceOrientationMask)supportedOrientations;

+ 25
- 0
lib/ios/RNNNavigationOptions.m 查看文件

@@ -3,6 +3,7 @@
3 3
 #import "RNNNavigationController.h"
4 4
 #import "RNNTabBarController.h"
5 5
 #import "RNNTopBarOptions.h"
6
+#import "RNNSideMenuController.h"
6 7
 
7 8
 const NSInteger BLUR_STATUS_TAG = 78264801;
8 9
 const NSInteger BLUR_TOPBAR_TAG = 78264802;
@@ -26,6 +27,7 @@ const NSInteger TOP_BAR_TRANSPARENT_TAG = 78264803;
26 27
 	self.rightButtons = [navigationOptions objectForKey:@"rightButtons"];
27 28
 	self.topBar = [[RNNTopBarOptions alloc] initWithDict:[navigationOptions objectForKey:@"topBar"]];
28 29
 	self.bottomTabs = [[RNNTabBarOptions alloc] initWithDict:[navigationOptions objectForKey:@"bottomTabs"]];
30
+	self.sideMenu = [[RNNSideMenuOptions alloc] initWithDict:[navigationOptions objectForKey:@"sideMenu"]];
29 31
 	
30 32
 	return self;
31 33
 }
@@ -36,6 +38,8 @@ const NSInteger TOP_BAR_TRANSPARENT_TAG = 78264803;
36 38
 			[self.topBar mergeWith:[otherOptions objectForKey:key]];
37 39
 		} else if ([key isEqualToString:@"bottomTabs"]) {
38 40
 			[self.bottomTabs mergeWith:[otherOptions objectForKey:key]];
41
+		} else if ([key isEqualToString:@"sideMenu"]) {
42
+			[self.sideMenu mergeWith:[otherOptions objectForKey:@"sideMenu"]];
39 43
 		} else {
40 44
 			[self setValue:[otherOptions objectForKey:key] forKey:key];
41 45
 		}
@@ -208,6 +212,27 @@ const NSInteger TOP_BAR_TRANSPARENT_TAG = 78264803;
208 212
 			}
209 213
 		}
210 214
 	}
215
+	
216
+	RNNSideMenuController* sideMenuController = (RNNSideMenuController*)UIApplication.sharedApplication.delegate.window.rootViewController;
217
+	if ([sideMenuController isKindOfClass:[RNNSideMenuController class]]) {
218
+		if (self.sideMenu.leftSideVisible) {
219
+			if (self.sideMenu.leftSideVisible.boolValue) {
220
+				[sideMenuController showSideMenu:MMDrawerSideLeft animated:YES];
221
+			} else {
222
+				[sideMenuController hideSideMenu:MMDrawerSideLeft animated:YES];
223
+			}
224
+		}
225
+		
226
+		if (self.sideMenu.rightSideVisible) {
227
+			if (self.sideMenu.rightSideVisible.boolValue) {
228
+				[sideMenuController showSideMenu:MMDrawerSideRight animated:YES];
229
+			} else {
230
+				[sideMenuController hideSideMenu:MMDrawerSideRight animated:YES];
231
+			}
232
+		}
233
+		
234
+		[self.sideMenu resetOptions];
235
+	}
211 236
 }
212 237
 
213 238
 - (UIInterfaceOrientationMask)supportedOrientations {

+ 3
- 0
lib/ios/RNNSideMenuController.h 查看文件

@@ -19,4 +19,7 @@
19 19
 
20 20
 -(instancetype)initWithControllers:(NSArray*)controllers;
21 21
 
22
+-(void)showSideMenu:(MMDrawerSide)side animated:(BOOL)animated;
23
+-(void)hideSideMenu:(MMDrawerSide)side animated:(BOOL)animated;
24
+
22 25
 @end

+ 8
- 0
lib/ios/RNNSideMenuController.m 查看文件

@@ -41,6 +41,14 @@
41 41
 	return self;
42 42
 }
43 43
 
44
+-(void)showSideMenu:(MMDrawerSide)side animated:(BOOL)animated {
45
+	[self.sideMenu openDrawerSide:side animated:animated completion:nil];
46
+}
47
+
48
+-(void)hideSideMenu:(MMDrawerSide)side animated:(BOOL)animated {
49
+	[self.sideMenu closeDrawerAnimated:animated completion:nil];
50
+}
51
+
44 52
 -(void)setControllers:(NSArray*)controllers {
45 53
 	for (id controller in controllers) {
46 54
 		

+ 14
- 0
lib/ios/RNNSideMenuOptions.h 查看文件

@@ -0,0 +1,14 @@
1
+#import <Foundation/Foundation.h>
2
+
3
+@interface RNNSideMenuOptions : NSObject
4
+
5
+@property (nonatomic, strong) NSNumber* leftSideVisible;
6
+@property (nonatomic, strong) NSNumber* rightSideVisible;
7
+
8
+-(instancetype)init;
9
+-(instancetype)initWithDict:(NSDictionary *)sideMenuOptions;
10
+-(void)mergeWith:(NSDictionary*)otherOptions;
11
+
12
+-(void)resetOptions;
13
+
14
+@end

+ 27
- 0
lib/ios/RNNSideMenuOptions.m 查看文件

@@ -0,0 +1,27 @@
1
+#import "RNNSideMenuOptions.h"
2
+
3
+@implementation RNNSideMenuOptions
4
+
5
+-(instancetype)init {
6
+	return [self initWithDict:@{}];
7
+}
8
+
9
+-(instancetype)initWithDict:(NSDictionary *)sideMenuOptions {
10
+	self = [super init];
11
+	
12
+	[self mergeWith:sideMenuOptions];
13
+	
14
+	return self;
15
+}
16
+
17
+-(void)mergeWith:(NSDictionary *)otherOptions {
18
+	self.leftSideVisible = [[otherOptions valueForKey:@"left"] valueForKey:@"visible"];
19
+	self.rightSideVisible = [[otherOptions valueForKey:@"right"] valueForKey:@"visible"];
20
+}
21
+
22
+-(void)resetOptions {
23
+	self.leftSideVisible = nil;
24
+	self.rightSideVisible = nil;
25
+}
26
+
27
+@end

+ 10
- 2
lib/ios/ReactNativeNavigation.xcodeproj/project.pbxproj 查看文件

@@ -57,6 +57,8 @@
57 57
 		268692831E5054F800E2C612 /* RNNStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 268692811E5054F800E2C612 /* RNNStore.m */; };
58 58
 		26916C981E4B9E7700D13680 /* RNNReactRootViewCreator.h in Headers */ = {isa = PBXBuildFile; fileRef = 26916C961E4B9E7700D13680 /* RNNReactRootViewCreator.h */; };
59 59
 		26916C991E4B9E7700D13680 /* RNNReactRootViewCreator.m in Sources */ = {isa = PBXBuildFile; fileRef = 26916C971E4B9E7700D13680 /* RNNReactRootViewCreator.m */; };
60
+		50CB3B691FDE911400AA153B /* RNNSideMenuOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 50CB3B671FDE911400AA153B /* RNNSideMenuOptions.h */; };
61
+		50CB3B6A1FDE911400AA153B /* RNNSideMenuOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 50CB3B681FDE911400AA153B /* RNNSideMenuOptions.m */; };
60 62
 		50F5DFC11F407A8C001A00BC /* RNNTabBarController.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F5DFBF1F407A8C001A00BC /* RNNTabBarController.h */; };
61 63
 		50F5DFC21F407A8C001A00BC /* RNNTabBarController.m in Sources */ = {isa = PBXBuildFile; fileRef = 50F5DFC01F407A8C001A00BC /* RNNTabBarController.m */; };
62 64
 		50F5DFC51F407AA0001A00BC /* RNNNavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = 50F5DFC31F407AA0001A00BC /* RNNNavigationController.h */; };
@@ -203,6 +205,8 @@
203 205
 		26916C941E4B9CCC00D13680 /* RNNRootViewCreator.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNRootViewCreator.h; sourceTree = "<group>"; };
204 206
 		26916C961E4B9E7700D13680 /* RNNReactRootViewCreator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RNNReactRootViewCreator.h; sourceTree = "<group>"; };
205 207
 		26916C971E4B9E7700D13680 /* RNNReactRootViewCreator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RNNReactRootViewCreator.m; sourceTree = "<group>"; };
208
+		50CB3B671FDE911400AA153B /* RNNSideMenuOptions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNSideMenuOptions.h; sourceTree = "<group>"; };
209
+		50CB3B681FDE911400AA153B /* RNNSideMenuOptions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNSideMenuOptions.m; sourceTree = "<group>"; };
206 210
 		50F5DFBF1F407A8C001A00BC /* RNNTabBarController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNTabBarController.h; sourceTree = "<group>"; };
207 211
 		50F5DFC01F407A8C001A00BC /* RNNTabBarController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNNTabBarController.m; sourceTree = "<group>"; };
208 212
 		50F5DFC31F407AA0001A00BC /* RNNNavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RNNNavigationController.h; sourceTree = "<group>"; };
@@ -411,9 +415,9 @@
411 415
 				50F5DFC31F407AA0001A00BC /* RNNNavigationController.h */,
412 416
 				50F5DFC41F407AA0001A00BC /* RNNNavigationController.m */,
413 417
 				263905D41E4C94970023D7D3 /* RNNSideMenuController.h */,
418
+				263905D51E4C94970023D7D3 /* RNNSideMenuController.m */,
414 419
 				7BC9346C1E26886E00EFA125 /* RNNControllerFactory.h */,
415 420
 				7BC9346D1E26886E00EFA125 /* RNNControllerFactory.m */,
416
-				263905D51E4C94970023D7D3 /* RNNSideMenuController.m */,
417 421
 				263905E41E4CAC950023D7D3 /* RNNSideMenuChildVC.h */,
418 422
 				263905E51E4CAC950023D7D3 /* RNNSideMenuChildVC.m */,
419 423
 				E83BAD691F27362500A9F3DD /* RNNNavigationOptions.h */,
@@ -422,10 +426,12 @@
422 426
 				21B85E5C1F44480200B314B5 /* RNNNavigationButtons.m */,
423 427
 				214545261F4DC164006E8DA1 /* RNNUIBarButtonItem.h */,
424 428
 				214545241F4DC125006E8DA1 /* RNNUIBarButtonItem.m */,
425
-				A7626BFC1FC2FB2C00492FB8 /* RNNTopBarOptions.m */,
426 429
 				A7626BFE1FC2FB6700492FB8 /* RNNTopBarOptions.h */,
430
+				A7626BFC1FC2FB2C00492FB8 /* RNNTopBarOptions.m */,
427 431
 				A7626BFF1FC578AB00492FB8 /* RNNTabBarOptions.h */,
428 432
 				A7626C001FC5796200492FB8 /* RNNTabBarOptions.m */,
433
+				50CB3B671FDE911400AA153B /* RNNSideMenuOptions.h */,
434
+				50CB3B681FDE911400AA153B /* RNNSideMenuOptions.m */,
429 435
 			);
430 436
 			name = Controllers;
431 437
 			sourceTree = "<group>";
@@ -570,6 +576,7 @@
570 576
 				7B4928081E70415400555040 /* RNNCommandsHandler.h in Headers */,
571 577
 				263905AE1E4C6F440023D7D3 /* MMDrawerBarButtonItem.h in Headers */,
572 578
 				50F5DFC11F407A8C001A00BC /* RNNTabBarController.h in Headers */,
579
+				50CB3B691FDE911400AA153B /* RNNSideMenuOptions.h in Headers */,
573 580
 				263905BD1E4C6F440023D7D3 /* RCCDrawerProtocol.h in Headers */,
574 581
 				263905C21E4C6F440023D7D3 /* SidebarAnimation.h in Headers */,
575 582
 				E8E518361F83B94A000467AC /* RNNViewLocation.h in Headers */,
@@ -721,6 +728,7 @@
721 728
 				7BEF0D191E437684003E96B0 /* RNNRootViewController.m in Sources */,
722 729
 				263905C31E4C6F440023D7D3 /* SidebarAnimation.m in Sources */,
723 730
 				E8A5CD531F464F0400E89D0D /* RNNAnimator.m in Sources */,
731
+				50CB3B6A1FDE911400AA153B /* RNNSideMenuOptions.m in Sources */,
724 732
 				261F0E6B1E6F028A00989DE2 /* RNNNavigationStackManager.m in Sources */,
725 733
 				E8DA24411F97459B00CD552B /* RNNElementFinder.m in Sources */,
726 734
 				263905BF1E4C6F440023D7D3 /* RCCTheSideBarManagerViewController.m in Sources */,

+ 1
- 0
lib/src/params/NavigationOptions.js 查看文件

@@ -26,6 +26,7 @@ class NavigationOptions {
26 26
     this.orientation = options.orientation;
27 27
     this.rightButtons = options.rightButtons && options.rightButtons.map((button) => new Button(button));
28 28
     this.leftButtons = options.leftButtons && options.leftButtons.map((button) => new Button(button));
29
+    this.sideMenu = options.sideMenu;
29 30
   }
30 31
 }
31 32
 

+ 42
- 0
playground/src/containers/SideMenuScreen.js 查看文件

@@ -0,0 +1,42 @@
1
+const React = require('react');
2
+const { Component } = require('react');
3
+
4
+const { View, Text, Button } = require('react-native');
5
+
6
+const Navigation = require('react-native-navigation');
7
+const testIDs = require('../testIDs');
8
+
9
+class SideMenuScreen extends Component {
10
+
11
+  render() {
12
+    const testID = this.props.side === 'left' ? testIDs.HIDE_LEFT_SIDE_MENU_BUTTON : testIDs.HIDE_RIGHT_SIDE_MENU_BUTTON;
13
+    return (
14
+      <View style={styles.root} testID={this.props.testID}>
15
+        <Text testID={testIDs.SIDE_BAR}>Side Bar</Text>
16
+        <Text style={styles.h1}>{`This is a ${this.props.side} side menu screen`}</Text>
17
+        <Button title="Hide Side Menu" testID={testID} onPress={() => this.hideSideMenu()} />
18
+      </View>
19
+    );
20
+  }
21
+
22
+  hideSideMenu() {
23
+    Navigation.setOptions(this.props.containerId, {
24
+      sideMenu: {
25
+        [this.props.side]: {
26
+          visible: false
27
+        }
28
+      }
29
+    });
30
+  }
31
+}
32
+module.exports = SideMenuScreen;
33
+
34
+const styles = {
35
+  root: {
36
+    flexGrow: 1,
37
+    justifyContent: 'center',
38
+    alignItems: 'center',
39
+    backgroundColor: '#f5fcff'
40
+  }
41
+};
42
+

+ 14
- 1
playground/src/containers/TextScreen.js 查看文件

@@ -11,13 +11,15 @@ class TextScreen extends Component {
11 11
   render() {
12 12
     return (
13 13
       <View style={styles.root}>
14
-        <Text style={styles.h1}>{this.props.text || 'Text Screen'}</Text>
14
+        <Text style={styles.h1} testID={testIDs.CENTERED_TEXT_HEADER}>{this.props.text || 'Text Screen'}</Text>
15 15
         {this.renderTextFromFunctionInProps()}
16 16
         <Text style={styles.footer}>{`this.props.containerId = ${this.props.containerId}`}</Text>
17 17
         <Button title={'Set Tab Badge'} testID={testIDs.SET_TAB_BADGE_BUTTON} onPress={() => this.onButtonPress()} />
18 18
         <Button title={'Switch To Tab 2'} testID={testIDs.SWITCH_SECOND_TAB_BUTTON} onPress={() => this.onClickSwitchToTab()} />
19 19
         <Button title="Hide Tab Bar" onPress={() => this.hideTabBar(true)} />
20 20
         <Button title="Show Tab Bar" onPress={() => this.hideTabBar(false)} />
21
+        <Button title="Show Left Side Menu" testID={testIDs.SHOW_LEFT_SIDE_MENU_BUTTON} onPress={() => this.showSideMenu('left')} />
22
+        <Button title="Show Right Side Menu" testID={testIDs.SHOW_RIGHT_SIDE_MENU_BUTTON} onPress={() => this.showSideMenu('right')} />
21 23
       </View>
22 24
     );
23 25
   }
@@ -56,7 +58,18 @@ class TextScreen extends Component {
56 58
       }
57 59
     });
58 60
   }
61
+
62
+  showSideMenu(side) {
63
+    Navigation.setOptions(this.props.containerId, {
64
+      sideMenu: {
65
+        [side]: {
66
+          visible: true
67
+        }
68
+      }
69
+    });
70
+  }
59 71
 }
72
+
60 73
 module.exports = TextScreen;
61 74
 
62 75
 const styles = {

+ 4
- 4
playground/src/containers/WelcomeScreen.js 查看文件

@@ -99,17 +99,17 @@ class WelcomeScreen extends Component {
99 99
       sideMenu: {
100 100
         left: {
101 101
           container: {
102
-            name: 'navigation.playground.TextScreen',
102
+            name: 'navigation.playground.SideMenuScreen',
103 103
             passProps: {
104
-              text: 'This is a left side menu screen'
104
+              side: 'left'
105 105
             }
106 106
           }
107 107
         },
108 108
         right: {
109 109
           container: {
110
-            name: 'navigation.playground.TextScreen',
110
+            name: 'navigation.playground.SideMenuScreen',
111 111
             passProps: {
112
-              text: 'This is a right side menu screen'
112
+              side: 'right'
113 113
             }
114 114
           }
115 115
         }

+ 2
- 0
playground/src/containers/index.js 查看文件

@@ -12,6 +12,7 @@ const CustomTransitionOrigin = require('./CustomTransitionOrigin');
12 12
 const CustomTransitionDestination = require('./CustomTransitionDestination');
13 13
 const CustomDialog = require('./CustomDialog');
14 14
 const BandHandlerScreen = require('./BackHandlerScreen');
15
+const SideMenuScreen = require('./SideMenuScreen');
15 16
 
16 17
 function registerContainers() {
17 18
   Navigation.registerContainer(`navigation.playground.CustomTransitionDestination`, () => CustomTransitionDestination);
@@ -27,6 +28,7 @@ function registerContainers() {
27 28
   Navigation.registerContainer(`navigation.playground.OrientationDetectScreen`, () => OrientationDetectScreen);
28 29
   Navigation.registerContainer('navigation.playground.CustomDialog', () => CustomDialog);
29 30
   Navigation.registerContainer('navigation.playground.BackHandlerScreen', () => BandHandlerScreen);
31
+  Navigation.registerContainer('navigation.playground.SideMenuScreen', () => SideMenuScreen);
30 32
 }
31 33
 
32 34
 module.exports = {

+ 5
- 0
playground/src/testIDs.js 查看文件

@@ -36,9 +36,14 @@ module.exports = {
36 36
   TOGGLE_TOP_BAR_HIDE_ON_SCROLL: `TOGGLE_TOP_BAR_HIDE_ON_SCROLL`,
37 37
   SET_TAB_BADGE_BUTTON: `SET_TAB_BADGE_BUTTON`,
38 38
   PUSH_TO_TEST_DID_DISAPPEAR_BUTTON: `PUSH_TO_TEST_DID_DISAPPEAR_BUTTON`,
39
+  SHOW_LEFT_SIDE_MENU_BUTTON: `SHOW_LEFT_SIDE_MENU_BUTTON`,
40
+  SHOW_RIGHT_SIDE_MENU_BUTTON: `SHOW_RIGHT_SIDE_MENU_BUTTON`,
41
+  HIDE_LEFT_SIDE_MENU_BUTTON: `HIDE_LEFT_SIDE_MENU_BUTTON`,
42
+  HIDE_RIGHT_SIDE_MENU_BUTTON: `HIDE_RIGHT_SIDE_MENU_BUTTON`,
39 43
 
40 44
   // Elements
41 45
   SCROLLVIEW_ELEMENT: `SCROLLVIEW_ELEMENT`,
46
+  CENTERED_TEXT_HEADER: `CENTERED_TEXT_HEADER`,
42 47
 
43 48
   // Headers
44 49
   WELCOME_SCREEN_HEADER: `WELCOME_SCREEN_HEADER`,