Просмотр исходного кода

[v2] (restore) Typings for styling options and layouts (#3931)

* Added all styling options and WIP comments

* Completed screen options and layout types

* Added typings to the main entrypoint

* Added buttons too

* Optional fields

* Fixes js unit tests
Birkir Rafn Guðjónsson 6 лет назад
Родитель
Сommit
1afaeb8f22

+ 9
- 7
lib/src/Navigation.ts Просмотреть файл

@@ -13,6 +13,8 @@ import { CommandsObserver } from './events/CommandsObserver';
13 13
 import { Constants } from './adapters/Constants';
14 14
 import { ComponentType } from 'react';
15 15
 import { ComponentEventsObserver } from './events/ComponentEventsObserver';
16
+import { LayoutRoot, Layout } from './interfaces/Layout';
17
+import { Options } from './interfaces/Options';
16 18
 
17 19
 export class Navigation {
18 20
   public readonly Element: React.ComponentType<{ elementId: any; resizeMode?: any; }>;
@@ -64,28 +66,28 @@ export class Navigation {
64 66
   /**
65 67
    * Reset the app to a new layout
66 68
    */
67
-  public setRoot(layout): Promise<any> {
69
+  public setRoot(layout: LayoutRoot): Promise<any> {
68 70
     return this.commands.setRoot(layout);
69 71
   }
70 72
 
71 73
   /**
72 74
    * Set default options to all screens. Useful for declaring a consistent style across the app.
73 75
    */
74
-  public setDefaultOptions(options): void {
76
+  public setDefaultOptions(options: Options): void {
75 77
     this.commands.setDefaultOptions(options);
76 78
   }
77 79
 
78 80
   /**
79 81
    * Change a component's navigation options
80 82
    */
81
-  public mergeOptions(componentId: string, options): void {
83
+  public mergeOptions(componentId: string, options: Options): void {
82 84
     this.commands.mergeOptions(componentId, options);
83 85
   }
84 86
 
85 87
   /**
86 88
    * Show a screen as a modal.
87 89
    */
88
-  public showModal(layout): Promise<any> {
90
+  public showModal(layout: Layout): Promise<any> {
89 91
     return this.commands.showModal(layout);
90 92
   }
91 93
 
@@ -106,7 +108,7 @@ export class Navigation {
106 108
   /**
107 109
    * Push a new layout into this screen's navigation stack.
108 110
    */
109
-  public push(componentId: string, layout): Promise<any> {
111
+  public push(componentId: string, layout: Layout): Promise<any> {
110 112
     return this.commands.push(componentId, layout);
111 113
   }
112 114
 
@@ -134,14 +136,14 @@ export class Navigation {
134 136
   /**
135 137
    * Sets new root component to stack.
136 138
    */
137
-  public setStackRoot(componentId: string, layout): Promise<any> {
139
+  public setStackRoot(componentId: string, layout: Layout): Promise<any> {
138 140
     return this.commands.setStackRoot(componentId, layout);
139 141
   }
140 142
 
141 143
   /**
142 144
    * Show overlay on top of the entire app
143 145
    */
144
-  public showOverlay(layout): Promise<any> {
146
+  public showOverlay(layout: Layout): Promise<any> {
145 147
     return this.commands.showOverlay(layout);
146 148
   }
147 149
 

+ 5
- 5
lib/src/adapters/NativeCommandsSender.ts Просмотреть файл

@@ -22,15 +22,15 @@ export class NativeCommandsSender {
22 22
     return this.nativeCommandsModule.push(commandId, onComponentId, layout);
23 23
   }
24 24
 
25
-  pop(commandId: string, componentId: string, options: object) {
25
+  pop(commandId: string, componentId: string, options?: object) {
26 26
     return this.nativeCommandsModule.pop(commandId, componentId, options);
27 27
   }
28 28
 
29
-  popTo(commandId: string, componentId: string, options: object) {
29
+  popTo(commandId: string, componentId: string, options?: object) {
30 30
     return this.nativeCommandsModule.popTo(commandId, componentId, options);
31 31
   }
32 32
 
33
-  popToRoot(commandId: string, componentId: string, options: object) {
33
+  popToRoot(commandId: string, componentId: string, options?: object) {
34 34
     return this.nativeCommandsModule.popToRoot(commandId, componentId, options);
35 35
   }
36 36
 
@@ -42,11 +42,11 @@ export class NativeCommandsSender {
42 42
     return this.nativeCommandsModule.showModal(commandId, layout);
43 43
   }
44 44
 
45
-  dismissModal(commandId: string, componentId: string, options: object) {
45
+  dismissModal(commandId: string, componentId: string, options?: object) {
46 46
     return this.nativeCommandsModule.dismissModal(commandId, componentId, options);
47 47
   }
48 48
 
49
-  dismissAllModals(commandId: string, options: object) {
49
+  dismissAllModals(commandId: string, options?: object) {
50 50
     return this.nativeCommandsModule.dismissAllModals(commandId, options);
51 51
   }
52 52
 

+ 7
- 7
lib/src/commands/Commands.test.ts Просмотреть файл

@@ -54,7 +54,7 @@ describe('Commands', () => {
54 54
 
55 55
     it('deep clones input to avoid mutation errors', () => {
56 56
       const obj = {};
57
-      uut.setRoot({ root: { component: { name: 'bla', inner: obj } } });
57
+      uut.setRoot({ root: { component: { name: 'bla', inner: obj } as any } });
58 58
       expect(mockCommandsSender.setRoot.mock.calls[0][1].root.data.inner).not.toBe(obj);
59 59
     });
60 60
 
@@ -137,12 +137,12 @@ describe('Commands', () => {
137 137
   describe('mergeOptions', () => {
138 138
     it('deep clones input to avoid mutation errors', () => {
139 139
       const obj = { title: 'test' };
140
-      uut.mergeOptions('theComponentId', obj);
140
+      uut.mergeOptions('theComponentId', obj as any);
141 141
       expect(mockCommandsSender.mergeOptions.mock.calls[0][1]).not.toBe(obj);
142 142
     });
143 143
 
144 144
     it('passes options for component', () => {
145
-      uut.mergeOptions('theComponentId', { title: '1' });
145
+      uut.mergeOptions('theComponentId', { title: '1' } as any);
146 146
       expect(mockCommandsSender.mergeOptions).toHaveBeenCalledTimes(1);
147 147
       expect(mockCommandsSender.mergeOptions).toHaveBeenCalledWith('theComponentId', { title: '1' });
148 148
     });
@@ -151,7 +151,7 @@ describe('Commands', () => {
151 151
   describe('setDefaultOptions', () => {
152 152
     it('deep clones input to avoid mutation errors', () => {
153 153
       const obj = { title: 'test' };
154
-      uut.setDefaultOptions(obj);
154
+      uut.setDefaultOptions(obj as any);
155 155
       expect(mockCommandsSender.setDefaultOptions.mock.calls[0][0]).not.toBe(obj);
156 156
     });
157 157
   });
@@ -177,7 +177,7 @@ describe('Commands', () => {
177 177
 
178 178
     it('deep clones input to avoid mutation errors', () => {
179 179
       const obj = {};
180
-      uut.showModal({ component: { name: 'name', inner: obj } });
180
+      uut.showModal({ component: { name: 'name', inner: obj } as any });
181 181
       expect(mockCommandsSender.showModal.mock.calls[0][1].data.inner).not.toBe(obj);
182 182
     });
183 183
 
@@ -271,7 +271,7 @@ describe('Commands', () => {
271 271
           duration: 0.8
272 272
         }
273 273
       };
274
-      uut.pop('theComponentId', options);
274
+      uut.pop('theComponentId', options as any);
275 275
       expect(mockCommandsSender.pop).toHaveBeenCalledTimes(1);
276 276
       expect(mockCommandsSender.pop).toHaveBeenCalledWith('pop+UNIQUE_ID', 'theComponentId', options);
277 277
     });
@@ -348,7 +348,7 @@ describe('Commands', () => {
348 348
 
349 349
     it('deep clones input to avoid mutation errors', () => {
350 350
       const obj = {};
351
-      uut.showOverlay({ component: { name: 'name', inner: obj } });
351
+      uut.showOverlay({ component: { name: 'name', inner: obj } as any });
352 352
       expect(mockCommandsSender.showOverlay.mock.calls[0][1].data.inner).not.toBe(obj);
353 353
     });
354 354
 

+ 15
- 13
lib/src/commands/Commands.ts Просмотреть файл

@@ -2,6 +2,8 @@ import * as _ from 'lodash';
2 2
 import { CommandsObserver } from '../events/CommandsObserver';
3 3
 import { NativeCommandsSender } from '../adapters/NativeCommandsSender';
4 4
 import { UniqueIdProvider } from '../adapters/UniqueIdProvider';
5
+import { Options } from '../interfaces/Options';
6
+import { Layout, LayoutRoot } from '../interfaces/Layout';
5 7
 
6 8
 export class Commands {
7 9
   constructor(
@@ -12,7 +14,7 @@ export class Commands {
12 14
     private readonly uniqueIdProvider: UniqueIdProvider) {
13 15
   }
14 16
 
15
-  public setRoot(simpleApi) {
17
+  public setRoot(simpleApi: LayoutRoot) {
16 18
     const input = _.cloneDeep(simpleApi);
17 19
     const root = this.layoutTreeParser.parse(input.root);
18 20
     this.layoutTreeCrawler.crawl(root);
@@ -35,7 +37,7 @@ export class Commands {
35 37
     return result;
36 38
   }
37 39
 
38
-  public setDefaultOptions(options) {
40
+  public setDefaultOptions(options: Options) {
39 41
     const input = _.cloneDeep(options);
40 42
     this.layoutTreeCrawler.processOptions(input);
41 43
 
@@ -43,7 +45,7 @@ export class Commands {
43 45
     this.commandsObserver.notify('setDefaultOptions', { options });
44 46
   }
45 47
 
46
-  public mergeOptions(componentId, options) {
48
+  public mergeOptions(componentId: string, options: Options) {
47 49
     const input = _.cloneDeep(options);
48 50
     this.layoutTreeCrawler.processOptions(input);
49 51
 
@@ -51,7 +53,7 @@ export class Commands {
51 53
     this.commandsObserver.notify('mergeOptions', { componentId, options });
52 54
   }
53 55
 
54
-  public showModal(simpleApi) {
56
+  public showModal(simpleApi: Layout) {
55 57
     const input = _.cloneDeep(simpleApi);
56 58
     const layout = this.layoutTreeParser.parse(input);
57 59
     this.layoutTreeCrawler.crawl(layout);
@@ -62,21 +64,21 @@ export class Commands {
62 64
     return result;
63 65
   }
64 66
 
65
-  public dismissModal(componentId, mergeOptions?) {
67
+  public dismissModal(componentId, mergeOptions?: Options) {
66 68
     const commandId = this.uniqueIdProvider.generate('dismissModal');
67 69
     const result = this.nativeCommandsSender.dismissModal(commandId, componentId, mergeOptions);
68 70
     this.commandsObserver.notify('dismissModal', { commandId, componentId, mergeOptions});
69 71
     return result;
70 72
   }
71 73
 
72
-  public dismissAllModals(mergeOptions?) {
74
+  public dismissAllModals(mergeOptions?: Options) {
73 75
     const commandId = this.uniqueIdProvider.generate('dismissAllModals');
74 76
     const result = this.nativeCommandsSender.dismissAllModals(commandId, mergeOptions);
75 77
     this.commandsObserver.notify('dismissAllModals', { commandId, mergeOptions });
76 78
     return result;
77 79
   }
78 80
 
79
-  public push(componentId, simpleApi) {
81
+  public push(componentId: string, simpleApi: Layout) {
80 82
     const input = _.cloneDeep(simpleApi);
81 83
 
82 84
     const layout = this.layoutTreeParser.parse(input);
@@ -88,28 +90,28 @@ export class Commands {
88 90
     return result;
89 91
   }
90 92
 
91
-  public pop(componentId, mergeOptions?) {
93
+  public pop(componentId: string, mergeOptions?: Options) {
92 94
     const commandId = this.uniqueIdProvider.generate('pop');
93 95
     const result = this.nativeCommandsSender.pop(commandId, componentId, mergeOptions);
94 96
     this.commandsObserver.notify('pop', { commandId, componentId, mergeOptions });
95 97
     return result;
96 98
   }
97 99
 
98
-  public popTo(componentId, mergeOptions?) {
100
+  public popTo(componentId: string, mergeOptions?: Options) {
99 101
     const commandId = this.uniqueIdProvider.generate('popTo');
100 102
     const result = this.nativeCommandsSender.popTo(commandId, componentId, mergeOptions);
101 103
     this.commandsObserver.notify('popTo', { commandId, componentId, mergeOptions });
102 104
     return result;
103 105
   }
104 106
 
105
-  public popToRoot(componentId, mergeOptions?) {
107
+  public popToRoot(componentId: string, mergeOptions?: Options) {
106 108
     const commandId = this.uniqueIdProvider.generate('popToRoot');
107 109
     const result = this.nativeCommandsSender.popToRoot(commandId, componentId, mergeOptions);
108 110
     this.commandsObserver.notify('popToRoot', { commandId, componentId, mergeOptions });
109 111
     return result;
110 112
   }
111 113
 
112
-  public setStackRoot(componentId, simpleApi) {
114
+  public setStackRoot(componentId: string, simpleApi: Layout) {
113 115
     const input = _.cloneDeep(simpleApi);
114 116
 
115 117
     const layout = this.layoutTreeParser.parse(input);
@@ -121,7 +123,7 @@ export class Commands {
121 123
     return result;
122 124
   }
123 125
 
124
-  public showOverlay(simpleApi) {
126
+  public showOverlay(simpleApi: Layout) {
125 127
     const input = _.cloneDeep(simpleApi);
126 128
 
127 129
     const layout = this.layoutTreeParser.parse(input);
@@ -133,7 +135,7 @@ export class Commands {
133 135
     return result;
134 136
   }
135 137
 
136
-  public dismissOverlay(componentId) {
138
+  public dismissOverlay(componentId: string) {
137 139
     const commandId = this.uniqueIdProvider.generate('dismissOverlay');
138 140
     const result = this.nativeCommandsSender.dismissOverlay(commandId, componentId);
139 141
     this.commandsObserver.notify('dismissOverlay', { commandId, componentId });

+ 142
- 0
lib/src/interfaces/Layout.ts Просмотреть файл

@@ -0,0 +1,142 @@
1
+import { Options, OptionsSplitView } from './Options';
2
+
3
+export interface LayoutComponent {
4
+  /**
5
+   * Component reference id, Auto generated if empty
6
+   */
7
+  id?: string;
8
+  /**
9
+   * Name of your component
10
+   */
11
+  name: string;
12
+  /**
13
+   * Styling options
14
+   */
15
+  options?: Options;
16
+  /**
17
+   * Properties to pass down to the component
18
+   */
19
+  passProps?: object;
20
+}
21
+
22
+export interface LayoutStackChildren {
23
+  /**
24
+   * Set component
25
+   */
26
+  component?: LayoutComponent;
27
+}
28
+
29
+export interface LayoutStack {
30
+  /**
31
+   * Set ID of the stack so you can use Navigation.mergeOptions to
32
+   * update options
33
+   */
34
+  id?: string;
35
+  /**
36
+   * Set children screens
37
+   */
38
+  children?: LayoutStackChildren[];
39
+  /**
40
+   * Set options
41
+   */
42
+  options?: Options;
43
+}
44
+
45
+export interface LayoutBottomTabsChildren {
46
+  /**
47
+   * Set stack
48
+   */
49
+  stack?: LayoutStack;
50
+  /**
51
+   * Set component
52
+   */
53
+  component?: LayoutComponent;
54
+}
55
+
56
+export interface LayoutBottomTabs {
57
+  /**
58
+   * Set ID of the stack so you can use Navigation.mergeOptions to
59
+   * update options
60
+   */
61
+  id?: string;
62
+  /**
63
+   * Set the children screens
64
+   */
65
+  children?: LayoutBottomTabsChildren[];
66
+  /**
67
+   * Set the bottom tabs options
68
+   */
69
+  options?: Options;
70
+}
71
+
72
+export interface LayoutSideMenu {
73
+  /**
74
+   * Set ID of the stack so you can use Navigation.mergeOptions to
75
+   * update options
76
+   */
77
+  id?: string;
78
+  /**
79
+   * Set the left side bar
80
+   */
81
+  left?: LayoutStackChildren;
82
+  /**
83
+   * Set the center view
84
+   */
85
+  center?: Layout;
86
+  /**
87
+   * Set the right side bar
88
+   */
89
+  right?: LayoutStackChildren;
90
+}
91
+
92
+export interface LayoutSplitView {
93
+  /**
94
+   * Set ID of the stack so you can use Navigation.mergeOptions to
95
+   * update options
96
+   */
97
+  id?: string;
98
+  /**
99
+   * Set master layout (the smaller screen, sidebar)
100
+   */
101
+  master?: Layout;
102
+  /**
103
+   * Set detail layout (the larger screen, flexes)
104
+   */
105
+  detail?: Layout;
106
+  /**
107
+   * Configure split view
108
+   */
109
+  options?: OptionsSplitView;
110
+}
111
+
112
+export interface LayoutRoot {
113
+  /**
114
+   * Set the root
115
+   */
116
+  root?: Layout;
117
+  modals?: any;
118
+  overlays?: any;
119
+}
120
+
121
+export interface Layout {
122
+  /**
123
+   * Set the component
124
+   */
125
+  component?: LayoutComponent;
126
+  /**
127
+   * Set the stack
128
+   */
129
+  stack?: LayoutStack;
130
+  /**
131
+   * Set the bottom tabs
132
+   */
133
+  bottomTabs?: LayoutBottomTabs;
134
+  /**
135
+   * Set the side menu
136
+   */
137
+  sideMenu?: LayoutSideMenu;
138
+  /**
139
+   * Set the split view
140
+   */
141
+  splitView?: LayoutSplitView;
142
+}

+ 8
- 8
lib/src/interfaces/Options.ts Просмотреть файл

@@ -11,20 +11,20 @@ export interface OptionsSplitView {
11 11
    * Master view display mode
12 12
    * @default 'auto'
13 13
    */
14
-  displayMode: 'auto' | 'visible' | 'hidden' | 'overlay';
14
+  displayMode?: 'auto' | 'visible' | 'hidden' | 'overlay';
15 15
   /**
16 16
    * Master view side. Leading is left. Trailing is right.
17 17
    * @default 'leading'
18 18
    */
19
-  primaryEdge: 'leading' | 'trailing';
19
+  primaryEdge?: 'leading' | 'trailing';
20 20
   /**
21 21
    * Set the minimum width of master view
22 22
    */
23
-  minWidth: number;
23
+  minWidth?: number;
24 24
   /**
25 25
    * Set the maximum width of master view
26 26
    */
27
-  maxWidth: number;
27
+  maxWidth?: number;
28 28
 }
29 29
 
30 30
 export interface OptionsStatusBar {
@@ -156,7 +156,7 @@ export interface OptionsTopBarBackButton {
156 156
   /**
157 157
    * Image to show as the back button
158 158
    */
159
-  icon: ImageRequireSource;
159
+  icon?: ImageRequireSource;
160 160
   /**
161 161
    * Weither the back button is visible or not
162 162
    * @default true
@@ -231,7 +231,7 @@ export interface OptionsTopBarButton {
231 231
   /**
232 232
    * Set testID for reference in E2E tests
233 233
    */
234
-  testID: string;
234
+  testID?: string;
235 235
 }
236 236
 
237 237
 export interface OptionsTopBar {
@@ -555,11 +555,11 @@ export interface OptionsAnimationPropertyConfig {
555 555
   /**
556 556
    * Animate from this value, ex. 0
557 557
    */
558
-  from: number;
558
+  from?: number;
559 559
   /**
560 560
    * Animate to this value, ex. 1
561 561
    */
562
-  to: number;
562
+  to?: number;
563 563
   /**
564 564
    * Animation duration
565 565
    * @default 300