UNPKG

2.27 kBJavaScriptView Raw
1'use strict';
2
3var core = require('@babel/core');
4
5const positionMethod = {
6 start: "unshiftContainer",
7 end: "pushContainer"
8};
9const addJSXAttribute = (_, opts) => {
10 function getAttributeValue({
11 literal,
12 value
13 }) {
14 if (typeof value === "boolean") {
15 return core.types.jsxExpressionContainer(core.types.booleanLiteral(value));
16 }
17 if (typeof value === "number") {
18 return core.types.jsxExpressionContainer(core.types.numericLiteral(value));
19 }
20 if (typeof value === "string" && literal) {
21 return core.types.jsxExpressionContainer(core.template.ast(value).expression);
22 }
23 if (typeof value === "string") {
24 return core.types.stringLiteral(value);
25 }
26 return null;
27 }
28 function getAttribute({ spread, name, value, literal }) {
29 if (spread) {
30 return core.types.jsxSpreadAttribute(core.types.identifier(name));
31 }
32 return core.types.jsxAttribute(core.types.jsxIdentifier(name), getAttributeValue({ value, literal }));
33 }
34 return {
35 visitor: {
36 JSXOpeningElement(path) {
37 if (!core.types.isJSXIdentifier(path.node.name))
38 return;
39 if (!opts.elements.includes(path.node.name.name))
40 return;
41 opts.attributes.forEach(({
42 name,
43 value = null,
44 spread = false,
45 literal = false,
46 position = "end"
47 }) => {
48 const method = positionMethod[position];
49 const newAttribute = getAttribute({ spread, name, value, literal });
50 const attributes = path.get("attributes");
51 const isEqualAttribute = (attribute) => {
52 if (spread)
53 return attribute.isJSXSpreadAttribute() && attribute.get("argument").isIdentifier({ name });
54 return attribute.isJSXAttribute() && attribute.get("name").isJSXIdentifier({ name });
55 };
56 const replaced = attributes.some((attribute) => {
57 if (!isEqualAttribute(attribute))
58 return false;
59 attribute.replaceWith(newAttribute);
60 return true;
61 });
62 if (!replaced) {
63 path[method]("attributes", newAttribute);
64 }
65 });
66 }
67 }
68 };
69};
70
71module.exports = addJSXAttribute;
72//# sourceMappingURL=index.js.map