index.js 2.3 KB

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