UNPKG

@atlaskit/eslint-plugin-design-system

Version:

The essential plugin for use with the Atlassian Design System.

234 lines (228 loc) 9.28 kB
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } /* eslint-disable @repo/internal/react/require-jsdoc */ import { isNodeOfType } from 'eslint-codemod-utils'; import { getSourceCode } from '@atlaskit/eslint-utils/context-compat'; import { JSXElementHelper } from '../../../ast-nodes/jsx-element-helper'; import { Root } from '../../../ast-nodes/root'; import { addColorInheritAttributeFix } from './add-color-inherit-attribute-fix'; import { allowedAttrs } from './allowed-attrs'; import { updateTestIdAttributeFix } from './update-test-id-attribute-fix'; export var ParagraphElements = { lint: function lint(node, _ref) { var context = _ref.context, config = _ref.config; if (!isNodeOfType(node, 'JSXElement')) { return; } // Check whether all criteria needed to make a transformation are met var _ParagraphElements$_c = ParagraphElements._check(node, { context: context, config: config }), success = _ParagraphElements$_c.success, autoFixable = _ParagraphElements$_c.autoFixable, refs = _ParagraphElements$_c.refs; if (success && autoFixable) { if (refs.siblings.length > 1) { var _refs$siblings$0$loc, _refs$siblings$loc; /** * Highlighting from first opening element to last closing element * to indicate fix will change all p elements and wrap them in a Stack, * falls back to first opening element. */ var startLoc = (_refs$siblings$0$loc = refs.siblings[0].loc) === null || _refs$siblings$0$loc === void 0 ? void 0 : _refs$siblings$0$loc.start; var endLoc = (_refs$siblings$loc = refs.siblings[refs.siblings.length - 1].loc) === null || _refs$siblings$loc === void 0 ? void 0 : _refs$siblings$loc.end; var fix = ParagraphElements._fixMultiple(node, { context: context, config: config, refs: refs }); context.report(_objectSpread({ loc: startLoc && endLoc && { start: startLoc, end: endLoc }, node: node.openingElement, messageId: 'preferPrimitivesStackedText' }, config.enableUnsafeAutofix ? { fix: fix } : { suggest: [{ desc: "Convert to Text and Stack", fix: fix }] })); } else { var _fix = ParagraphElements._fixSingle(node, { context: context, config: config }); context.report(_objectSpread({ node: node.openingElement, messageId: 'preferPrimitivesText' }, config.enableUnsafeAutofix ? { fix: _fix } : { suggest: [{ desc: "Convert to Text", fix: _fix }] })); } } else if (success && config.enableUnsafeReport) { context.report({ node: node.openingElement, messageId: 'preferPrimitivesText' }); } }, _check: function _check(node, _ref2) { var context = _ref2.context, config = _ref2.config; if (!config.patterns.includes('paragraph-elements')) { return { success: false, refs: { siblings: [] } }; } var elementName = JSXElementHelper.getName(node); if (elementName !== 'p') { return { success: false, refs: { siblings: [] } }; } if (!node.children.length) { return { success: false, refs: { siblings: [] } }; } // All siblings have to be paragraph elements with no unallowed props if (!isNodeOfType(node.parent, 'JSXElement')) { return { success: true, autoFixable: false, refs: { siblings: [] } }; } var siblings = JSXElementHelper.getChildren(node.parent); if (siblings.length > 1) { var _siblings$0$range, _node$range, _siblings$0$range2, _node$range2; // Only report for the first p element by comparing node location if (((_siblings$0$range = siblings[0].range) === null || _siblings$0$range === void 0 ? void 0 : _siblings$0$range[0]) !== ((_node$range = node.range) === null || _node$range === void 0 ? void 0 : _node$range[0]) || ((_siblings$0$range2 = siblings[0].range) === null || _siblings$0$range2 === void 0 ? void 0 : _siblings$0$range2[1]) !== ((_node$range2 = node.range) === null || _node$range2 === void 0 ? void 0 : _node$range2[1])) { return { success: true, autoFixable: false, refs: { siblings: siblings } }; } // Only report when every sibling is a p element var siblingsMatch = siblings.every(function (child) { if (!isNodeOfType(child, 'JSXElement')) { return false; } if (JSXElementHelper.getName(child) !== 'p') { return false; } return JSXElementHelper.hasAllowedAttrsOnly(child, allowedAttrs); }); if (!siblingsMatch) { return { success: true, autoFixable: false, refs: { siblings: siblings } }; } } else if (!JSXElementHelper.hasAllowedAttrsOnly(node, allowedAttrs)) { return { success: true, autoFixable: false, refs: { siblings: siblings } }; } var importDeclaration = Root.findImportsByModule(getSourceCode(context).ast.body, '@atlaskit/primitives'); // If there is more than one `@atlaskit/primitives` import, then it becomes difficult to determine which import to transform if (importDeclaration.length > 1) { return { success: true, autoFixable: false, refs: { siblings: siblings } }; } return { success: true, autoFixable: true, refs: { siblings: siblings } }; }, _fixSingle: function _fixSingle(node, _ref3) { var context = _ref3.context, config = _ref3.config; return function (fixer) { var importFix = Root.upsertNamedImportDeclaration({ module: '@atlaskit/primitives', specifiers: ['Text'] }, context, fixer); var elementNameFixes = JSXElementHelper.updateName(node, 'Text', fixer); var asAttributeFix = JSXElementHelper.addAttribute(node, 'as', 'p', fixer); var colorAttributeFix = addColorInheritAttributeFix(node, config, fixer); var testAttributeFix = updateTestIdAttributeFix(node, fixer); return [importFix].concat(_toConsumableArray(elementNameFixes), [asAttributeFix, colorAttributeFix, testAttributeFix]).filter(function (fix) { return Boolean(fix); }); // Some of the transformers can return arrays with undefined, so filter them out }; }, _fixMultiple: function _fixMultiple(node, _ref4) { var context = _ref4.context, config = _ref4.config, refs = _ref4.refs; return function (fixer) { if (!isNodeOfType(node.parent, 'JSXElement') || !node.parent.closingElement) { return []; } var importFix = Root.upsertNamedImportDeclaration({ module: '@atlaskit/primitives', specifiers: ['Text', 'Stack'] }, context, fixer); // Update all siblings elements and their attributes var siblingFixes = refs.siblings.map(function (sibling) { if (isNodeOfType(sibling, 'JSXElement')) { var elementNameFixes = JSXElementHelper.updateName(sibling, 'Text', fixer); var asAttributeFix = JSXElementHelper.addAttribute(sibling, 'as', 'p', fixer); var colorAttributeFix = addColorInheritAttributeFix(sibling, config, fixer); var testAttributeFix = updateTestIdAttributeFix(sibling, fixer); return [].concat(_toConsumableArray(elementNameFixes), [asAttributeFix, colorAttributeFix, testAttributeFix]); } return undefined; }).flat(); // Wrap in <Stack /> when more than 1 sibling var wrapperOpenElementFix = fixer.insertTextAfter(node.parent.openingElement, "<Stack space='space.150'>"); var wrapperCloseElementFix = fixer.insertTextBefore(node.parent.closingElement, '</Stack>'); return [importFix].concat(_toConsumableArray(siblingFixes), [wrapperOpenElementFix, wrapperCloseElementFix]).filter(function (fix) { return Boolean(fix); }); // Some of the transformers can return arrays with undefined, so filter them out }; } };