1 | 'use strict';
|
2 |
|
3 | var core = require('@babel/core');
|
4 |
|
5 | const positionMethod = {
|
6 | start: "unshiftContainer",
|
7 | end: "pushContainer"
|
8 | };
|
9 | const 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 |
|
71 | module.exports = addJSXAttribute;
|
72 |
|