UNPKG

babel-plugin-r-sugar

Version:

A Babel plugin that adds Vue-style v-if directive support to React

90 lines (84 loc) 4.1 kB
'use strict'; function vIfPlugin(path, t) { var _a, _b; // 安全检查 if (!((_b = (_a = path.node) === null || _a === void 0 ? void 0 : _a.openingElement) === null || _b === void 0 ? void 0 : _b.attributes)) return; const vIfAttribute = path.node.openingElement.attributes.find((attr) => attr.type === "JSXAttribute" && attr.name.name === "v-if"); if (!vIfAttribute || !vIfAttribute.value || vIfAttribute.value.type !== 'JSXExpressionContainer') return; path.node.openingElement.attributes = path.node.openingElement.attributes.filter(attr => attr !== vIfAttribute); const condition = vIfAttribute.value.expression; if (condition.type === 'JSXEmptyExpression') return; path.replaceWith(t.jsxExpressionContainer(t.conditionalExpression(condition, path.node, t.nullLiteral()))); } function tablePlugin(path, t) { var _a, _b, _c; // 安全检查 if (!((_b = (_a = path.node) === null || _a === void 0 ? void 0 : _a.openingElement) === null || _b === void 0 ? void 0 : _b.name)) return; // 检查是否是 Table 组件 if (path.node.openingElement.name.type !== 'JSXIdentifier' || path.node.openingElement.name.name !== 'Table') { return; } // 检查是否已经有 sticky 属性 const hasSticky = path.node.openingElement.attributes.some((attr) => attr.type === "JSXAttribute" && attr.name.name === "sticky"); if (hasSticky) return; // 检查是否有 noBabel 属性且包含 'sticky' const noBabelAttr = path.node.openingElement.attributes.find((attr) => attr.type === "JSXAttribute" && attr.name.name === "noBabel"); if (((_c = noBabelAttr === null || noBabelAttr === void 0 ? void 0 : noBabelAttr.value) === null || _c === void 0 ? void 0 : _c.type) === 'JSXExpressionContainer' && noBabelAttr.value.expression.type === 'ArrayExpression') { const noBabelArray = noBabelAttr.value.expression.elements; if (noBabelArray.some(element => (element === null || element === void 0 ? void 0 : element.type) === 'StringLiteral' && element.value === 'sticky')) { return; } } // 创建 sticky 属性 const stickyAttribute = t.jsxAttribute(t.jsxIdentifier("sticky"), t.jsxExpressionContainer(t.objectExpression([ t.objectProperty(t.identifier("offsetHeader"), t.numericLiteral(0)) ]))); // 添加 sticky 属性到组件 path.node.openingElement.attributes.push(stickyAttribute); } function formColonPlugin(path, t) { var _a, _b; // 安全检查 if (!((_b = (_a = path.node) === null || _a === void 0 ? void 0 : _a.openingElement) === null || _b === void 0 ? void 0 : _b.name)) return; // 检查是否是 Form 组件 if (path.node.openingElement.name.type !== 'JSXIdentifier' || path.node.openingElement.name.name !== 'Form') { return; } // 查找现有的 colon 属性 const colonAttributeIndex = path.node.openingElement.attributes.findIndex((attr) => attr.type === "JSXAttribute" && attr.name.name === "colon"); // 创建强制设置为 false 的 colon 属性 const colonAttribute = t.jsxAttribute(t.jsxIdentifier("colon"), t.jsxExpressionContainer(t.booleanLiteral(false))); if (colonAttributeIndex !== -1) { // 如果已存在 colon 属性,替换它 path.node.openingElement.attributes[colonAttributeIndex] = colonAttribute; } else { // 如果不存在 colon 属性,添加它 path.node.openingElement.attributes.push(colonAttribute); } } const reactVIfPlugin = function (babel) { return { name: "babel-plugin-react-v-if", visitor: { JSXElement(path, state) { // 处理v-if指令 vIfPlugin(path, babel.types); // 处理Table组件的sticky属性 tablePlugin(path, babel.types); // 处理Form组件的colon属性,强制设置为false formColonPlugin(path, babel.types); } } }; }; module.exports = reactVIfPlugin;