UNPKG

@navikt/aksel

Version:

Aksel command line interface. Codemods and other utilities for Aksel users.

219 lines (218 loc) 9.72 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = transformer; const lineterminator_1 = require("../../../utils/lineterminator"); const headingSizeMap = { small: "xsmall", medium: "small", large: "medium", }; const bodySizeMap = { small: "small", medium: "medium", large: "large", }; const boxMarginMap = { small: "space-12", medium: "space-16", large: "space-16", }; function transformer(file, api) { var _a; const j = api.jscodeshift; const root = j(file.source); let localListName = "List"; let hasListImport = false; let dsReactImportPath = null; let localHeadingName = "Heading"; let hasHeadingImport = false; let localBodyShortName = "BodyShort"; let hasBodyShortImport = false; let localBoxName = "Box"; let hasBoxImport = false; // Find the local name for List import root.find(j.ImportDeclaration).forEach((path) => { var _a, _b; if (path.node.source.value === "@navikt/ds-react") { dsReactImportPath = path; (_a = path.node.specifiers) === null || _a === void 0 ? void 0 : _a.forEach((specifier) => { var _a, _b, _c, _d; if (specifier.type === "ImportSpecifier") { if (specifier.imported.name === "List") { localListName = ((_a = specifier.local) === null || _a === void 0 ? void 0 : _a.name) || "List"; hasListImport = true; } if (specifier.imported.name === "Heading") { localHeadingName = ((_b = specifier.local) === null || _b === void 0 ? void 0 : _b.name) || "Heading"; hasHeadingImport = true; } if (specifier.imported.name === "BodyShort") { localBodyShortName = ((_c = specifier.local) === null || _c === void 0 ? void 0 : _c.name) || "BodyShort"; hasBodyShortImport = true; } if (specifier.imported.name === "Box") { localBoxName = ((_d = specifier.local) === null || _d === void 0 ? void 0 : _d.name) || "Box"; hasBoxImport = true; } } }); } else if (path.node.source.value === "@navikt/ds-react/List") { (_b = path.node.specifiers) === null || _b === void 0 ? void 0 : _b.forEach((specifier) => { var _a; if (specifier.type === "ImportSpecifier") { if (specifier.imported.name === "List") { localListName = ((_a = specifier.local) === null || _a === void 0 ? void 0 : _a.name) || "List"; hasListImport = true; } } }); } }); if (!hasListImport) { return root.toSource((0, lineterminator_1.getLineTerminator)(file.source)); } const newImports = new Set(); root .find(j.JSXElement, { openingElement: { name: { name: localListName } }, }) .forEach((path) => { var _a, _b; const attributes = path.node.openingElement.attributes; const titleAttr = attributes.find((attr) => attr.type === "JSXAttribute" && attr.name.name === "title"); const descAttr = attributes.find((attr) => attr.type === "JSXAttribute" && attr.name.name === "description"); if (attributes.some((attr) => attr.type === "JSXAttribute" && attr.name.name === "data-aksel-migrated-v8")) { return; } const headingTagAttr = attributes.find((attr) => attr.type === "JSXAttribute" && attr.name.name === "headingTag"); const sizeAttr = attributes.find((attr) => attr.type === "JSXAttribute" && attr.name.name === "size"); // Extract values const titleValue = titleAttr === null || titleAttr === void 0 ? void 0 : titleAttr.value; const descValue = descAttr === null || descAttr === void 0 ? void 0 : descAttr.value; let sizeValue = "medium"; if (sizeAttr && ((_a = sizeAttr.value) === null || _a === void 0 ? void 0 : _a.type) === "StringLiteral") { sizeValue = sizeAttr.value.value; } let headingAs = "h3"; if (headingTagAttr && ((_b = headingTagAttr.value) === null || _b === void 0 ? void 0 : _b.type) === "StringLiteral") { headingAs = headingTagAttr.value.value; } // Separate attributes const listAttributes = [ j.jsxAttribute(j.jsxIdentifier("data-aksel-migrated-v8")), ]; const divAttributes = []; attributes.forEach((attr) => { if (attr.type !== "JSXAttribute") { // Spread attributes or others -> move to div divAttributes.push(attr); return; } const name = attr.name.name; if (name === "title" || name === "description" || name === "headingTag") { // Handled separately return; } if (name === "size" || name === "as" || name === "aria-label" || name === "aria-labelledby") { listAttributes.push(attr); } else { divAttributes.push(attr); } }); const newNodes = []; // Create Heading if (titleValue) { if (!hasHeadingImport) { newImports.add("Heading"); } const headingAttrs = [ j.jsxAttribute(j.jsxIdentifier("as"), j.stringLiteral(headingAs)), ]; const mappedSize = headingSizeMap[sizeValue]; if (mappedSize) { headingAttrs.push(j.jsxAttribute(j.jsxIdentifier("size"), j.stringLiteral(mappedSize))); } let children = []; if (titleValue.type === "StringLiteral") { children = [j.jsxText(titleValue.value)]; } else if (titleValue.type === "JSXExpressionContainer") { children = [titleValue]; } const heading = j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier(localHeadingName), headingAttrs), j.jsxClosingElement(j.jsxIdentifier(localHeadingName)), children); newNodes.push(heading); } // Create BodyShort if (descValue) { if (!hasBodyShortImport) { newImports.add("BodyShort"); } const bodyAttrs = []; const mappedSize = bodySizeMap[sizeValue]; if (mappedSize && mappedSize !== "medium") { bodyAttrs.push(j.jsxAttribute(j.jsxIdentifier("size"), j.stringLiteral(mappedSize))); } let children = []; if (descValue.type === "StringLiteral") { children = [j.jsxText(descValue.value)]; } else if (descValue.type === "JSXExpressionContainer") { children = [descValue]; } const body = j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier(localBodyShortName), bodyAttrs), j.jsxClosingElement(j.jsxIdentifier(localBodyShortName)), children); newNodes.push(body); } // Create Box if (!hasBoxImport) { newImports.add("Box"); } const boxAttrs = [ j.jsxAttribute(j.jsxIdentifier("marginBlock"), j.stringLiteral(boxMarginMap[sizeValue] || "space-16")), j.jsxAttribute(j.jsxIdentifier("asChild")), ]; // Reconstruct List element const newList = j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier(localListName), listAttributes), path.node.closingElement, path.node.children); const box = j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier(localBoxName), boxAttrs), j.jsxClosingElement(j.jsxIdentifier(localBoxName)), [newList]); newNodes.push(box); // Wrap in div if (newNodes.length === 1 && divAttributes.length === 0) { j(path).replaceWith(newNodes[0]); } else { const div = j.jsxElement(j.jsxOpeningElement(j.jsxIdentifier("div"), divAttributes), j.jsxClosingElement(j.jsxIdentifier("div")), newNodes); j(path).replaceWith(div); } }); // Add imports if (newImports.size > 0) { if (dsReactImportPath) { const existingSpecifiers = new Set((_a = dsReactImportPath.node.specifiers) === null || _a === void 0 ? void 0 : _a.map((specifier) => { var _a; return (_a = specifier.local) === null || _a === void 0 ? void 0 : _a.name; })); newImports.forEach((imp) => { var _a; if (!existingSpecifiers.has(imp)) { (_a = dsReactImportPath.node.specifiers) === null || _a === void 0 ? void 0 : _a.push(j.importSpecifier(j.identifier(imp))); } }); } else { const specifiers = Array.from(newImports).map((imp) => j.importSpecifier(j.identifier(imp))); const newImportDecl = j.importDeclaration(specifiers, j.stringLiteral("@navikt/ds-react")); const lastImport = root.find(j.ImportDeclaration).at(-1); if (lastImport.length > 0) { lastImport.insertAfter(newImportDecl); } else { root.get().node.program.body.unshift(newImportDecl); } } } return root.toSource((0, lineterminator_1.getLineTerminator)(file.source)); }