diff --git a/tools/jscodeshift/wrap-ant-icons.js b/tools/jscodeshift/wrap-ant-icons.js index 8ed2fb22..662674bb 100644 --- a/tools/jscodeshift/wrap-ant-icons.js +++ b/tools/jscodeshift/wrap-ant-icons.js @@ -4,52 +4,64 @@ */ export default function transformer(file, api) { - const j = api.jscodeshift; - const root = j(file.source); + const j = api.jscodeshift + const root = j(file.source) - const ANT_SOURCE = '@ant-design/icons'; - const ANIMATED_IMPORT = '@stateless/AnimatedIcon'; + const ANT_SOURCE = '@ant-design/icons' + const ANIMATED_IMPORT = '@stateless/AnimatedIcon' // find import from '@ant-design/icons' - const antImports = root.find(j.ImportDeclaration, { source: { value: ANT_SOURCE } }); - if (antImports.size() === 0) return null; + const antImports = root.find(j.ImportDeclaration, { source: { value: ANT_SOURCE } }) + if (antImports.size() === 0) return null - const iconNames = []; + const iconNames = [] antImports.forEach((p) => { p.node.specifiers.forEach((s) => { if (s.type === 'ImportSpecifier') { - iconNames.push(s.local.name); + iconNames.push(s.local.name) } - }); - }); + }) + }) - if (iconNames.length === 0) return null; + if (iconNames.length === 0) return null // ensure AnimatedIcon is imported - const hasAnimatedImport = root.find(j.ImportDeclaration, { source: { value: ANIMATED_IMPORT } }).size() > 0; + const hasAnimatedImport = root.find(j.ImportDeclaration, { source: { value: ANIMATED_IMPORT } }).size() > 0 if (!hasAnimatedImport) { - const firstImport = root.find(j.ImportDeclaration).at(0); + const firstImport = root.find(j.ImportDeclaration).at(0) if (firstImport.size() > 0) { - firstImport.insertBefore(j.importDeclaration([j.importDefaultSpecifier(j.identifier('AnimatedIcon'))], j.literal(ANIMATED_IMPORT))); + firstImport.insertBefore( + j.importDeclaration([j.importDefaultSpecifier(j.identifier('AnimatedIcon'))], j.literal(ANIMATED_IMPORT)) + ) } else { - root.get().node.program.body.unshift(j.importDeclaration([j.importDefaultSpecifier(j.identifier('AnimatedIcon'))], j.literal(ANIMATED_IMPORT))); + root + .get() + .node.program.body.unshift( + j.importDeclaration([j.importDefaultSpecifier(j.identifier('AnimatedIcon'))], j.literal(ANIMATED_IMPORT)) + ) } } // Wrap JSXElements that match imported icon names root.find(j.JSXElement).forEach((p) => { - const opening = p.node.openingElement; - const name = opening.name; + const opening = p.node.openingElement + const name = opening.name if (name && name.type === 'JSXIdentifier' && iconNames.includes(name.name)) { // skip if already wrapped by AnimatedIcon - let parent = p.parentPath; + let parent = p.parentPath while (parent && parent.node) { - if (parent.node.type === 'JSXElement' && parent.node.openingElement.name && parent.node.openingElement.name.type === 'JSXIdentifier' && parent.node.openingElement.name.name === 'AnimatedIcon') return; - parent = parent.parentPath; + if ( + parent.node.type === 'JSXElement' && + parent.node.openingElement.name && + parent.node.openingElement.name.type === 'JSXIdentifier' && + parent.node.openingElement.name.name === 'AnimatedIcon' + ) + return + parent = parent.parentPath } // create wrapper - const iconElement = p.node; + const iconElement = p.node const wrapper = j.jsxElement( j.jsxOpeningElement(j.jsxIdentifier('AnimatedIcon'), [ j.jsxAttribute(j.jsxIdentifier('variant'), j.literal('spin')), @@ -57,24 +69,30 @@ export default function transformer(file, api) { ]), j.jsxClosingElement(j.jsxIdentifier('AnimatedIcon')), [iconElement] - ); + ) - j(p).replaceWith(wrapper); + j(p).replaceWith(wrapper) } - }); + }) // Also handle self-closing JSX (though JSXElement covers them as well) root.find(j.JSXSelfClosingElement).forEach((p) => { - const name = p.node.openingElement ? p.node.openingElement.name : p.node.name; + const name = p.node.openingElement ? p.node.openingElement.name : p.node.name if (name && name.type === 'JSXIdentifier' && iconNames.includes(name.name)) { // skip if already wrapped - let parent = p.parentPath; + let parent = p.parentPath while (parent && parent.node) { - if (parent.node.type === 'JSXElement' && parent.node.openingElement.name && parent.node.openingElement.name.type === 'JSXIdentifier' && parent.node.openingElement.name.name === 'AnimatedIcon') return; - parent = parent.parentPath; + if ( + parent.node.type === 'JSXElement' && + parent.node.openingElement.name && + parent.node.openingElement.name.type === 'JSXIdentifier' && + parent.node.openingElement.name.name === 'AnimatedIcon' + ) + return + parent = parent.parentPath } - const sc = p.node; + const sc = p.node const wrapper = j.jsxElement( j.jsxOpeningElement(j.jsxIdentifier('AnimatedIcon'), [ j.jsxAttribute(j.jsxIdentifier('variant'), j.literal('spin')), @@ -82,10 +100,10 @@ export default function transformer(file, api) { ]), j.jsxClosingElement(j.jsxIdentifier('AnimatedIcon')), [sc] - ); - j(p).replaceWith(wrapper); + ) + j(p).replaceWith(wrapper) } - }); + }) - return root.toSource({ quote: 'single' }); + return root.toSource({ quote: 'single' }) }