-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbabel-plugin-transform-react-optional.js
More file actions
63 lines (51 loc) · 1.61 KB
/
Copy pathbabel-plugin-transform-react-optional.js
File metadata and controls
63 lines (51 loc) · 1.61 KB
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
'use strict';
/*
One shortcoming of the Optional component is that it always constructs
its subcomponents before performing the test whether to display them.
Clearly when the test returns false, Optional has wasted its time
constructing components that won't in fact be displayed. This babel
plugin therefore reverses this order: perform the test first - and
only when it evaluates to true - go ahead and construct the
subcomponents.
To summarize, this plugin transforms:
<Optional test={test}>
<Child>
...
</Child>
</Optional>
to:
{Boolean(test) && <Child>...</Child> }
*/
module.exports = function(babel) {
const t = babel.types;
return {
inherits: require("babel-plugin-syntax-jsx"),
visitor: {
JSXElement: function(path) {
if (path.node.openingElement.name.name == 'Optional') {
let child = null;
path.node.children.forEach(item => {
if (item.type == 'JSXExpressionContainer') {
child = item.expression;
}
if (item.type == 'JSXElement') {
child = item;
}
});
let test = null;
path.node.openingElement.attributes.forEach(item => {
if (item.name.name == 'test') {
test = item.value.expression;
}
});
test = t.callExpression(t.identifier('Boolean'), [test]);
path.replaceWith(
t.blockStatement(
[t.expressionStatement(
t.logicalExpression('&&', test, child))], [])
);
}
}
}
};
};