forked from wix/react-native-navigation
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLayoutTreeCrawler.ts
63 lines (55 loc) · 1.82 KB
/
LayoutTreeCrawler.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import * as _ from 'lodash';
import { OptionsProcessor } from './OptionsProcessor';
import { LayoutType } from './LayoutType';
export interface Data {
name?: string;
options?: any;
passProps?: any;
}
export interface LayoutNode {
id?: string;
type: LayoutType;
data: Data;
children: LayoutNode[];
}
export class LayoutTreeCrawler {
private optionsProcessor: OptionsProcessor;
constructor(
private readonly uniqueIdProvider: any,
public readonly store: any) {
this.crawl = this.crawl.bind(this);
this.processOptions = this.processOptions.bind(this);
this.optionsProcessor = new OptionsProcessor(store, uniqueIdProvider);
}
crawl(node: LayoutNode): void {
node.id = node.id || this.uniqueIdProvider.generate(node.type);
if (node.type === LayoutType.Component) {
this._handleComponent(node);
}
this.processOptions(node.data.options);
_.forEach(node.children, this.crawl);
}
processOptions(options) {
this.optionsProcessor.processOptions(options);
}
_handleComponent(node) {
this._assertComponentDataName(node);
this._savePropsToStore(node);
this._applyStaticOptions(node);
node.data.passProps = undefined;
}
_savePropsToStore(node) {
this.store.setPropsForId(node.id, node.data.passProps);
}
_applyStaticOptions(node) {
const clazz = this.store.getComponentClassForName(node.data.name) ? this.store.getComponentClassForName(node.data.name)() : {};
const staticOptions = _.isFunction(clazz.options) ? clazz.options(node.data.passProps || {}) : (_.cloneDeep(clazz.options) || {});
const passedOptions = node.data.options || {};
node.data.options = _.merge({}, staticOptions, passedOptions);
}
_assertComponentDataName(component) {
if (!component.data.name) {
throw new Error('Missing component data.name');
}
}
}