Browse Source

[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 years ago
parent
commit
1afaeb8f22

+ 9
- 7
lib/src/Navigation.ts View File

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

+ 5
- 5
lib/src/adapters/NativeCommandsSender.ts View File

22
     return this.nativeCommandsModule.push(commandId, onComponentId, layout);
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
     return this.nativeCommandsModule.pop(commandId, componentId, options);
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
     return this.nativeCommandsModule.popTo(commandId, componentId, options);
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
     return this.nativeCommandsModule.popToRoot(commandId, componentId, options);
34
     return this.nativeCommandsModule.popToRoot(commandId, componentId, options);
35
   }
35
   }
36
 
36
 
42
     return this.nativeCommandsModule.showModal(commandId, layout);
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
     return this.nativeCommandsModule.dismissModal(commandId, componentId, options);
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
     return this.nativeCommandsModule.dismissAllModals(commandId, options);
50
     return this.nativeCommandsModule.dismissAllModals(commandId, options);
51
   }
51
   }
52
 
52
 

+ 7
- 7
lib/src/commands/Commands.test.ts View File

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

+ 15
- 13
lib/src/commands/Commands.ts View File

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

+ 142
- 0
lib/src/interfaces/Layout.ts View File

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 View File

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