UNPKG

@atlaskit/eslint-plugin-design-system

Version:

The essential plugin for use with the Atlassian Design System.

102 lines (100 loc) 5.03 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.hrefRequiredSuggestionText = exports.default = void 0; var _eslintCodemodUtils = require("eslint-codemod-utils"); var _contextCompat = require("@atlaskit/eslint-utils/context-compat"); var _createLintRule = require("../utils/create-lint-rule"); var _getImportName = require("../utils/get-import-name"); var _getUniqueButtonItemName = require("./get-unique-button-item-name"); var _hasImportOfName = require("./has-import-of-name"); var _insertButtonItemDefaultImport = require("./insert-button-item-default-import"); var _insertButtonItemImport = require("./insert-button-item-import"); var _utils = require("./utils"); var hrefRequiredSuggestionText = exports.hrefRequiredSuggestionText = 'Convert LinkItem to ButtonItem'; var rule = (0, _createLintRule.createLintRule)({ meta: { name: 'use-href-in-link-item', type: 'suggestion', fixable: 'code', hasSuggestions: true, docs: { description: 'Inform developers of eventual requirement of `href` prop in `LinkItem` component. Elements with a `link` role require an `href` attribute for users to properly navigate, particularly those using assistive technologies. If no valid `href` is required for your use case, consider using a `ButtonItem` instead.', recommended: true, severity: 'warn' }, messages: { hrefRequired: 'A valid `href` will be required in future releases on LinkItem. This may be able to be replaced by a ButtonItem.' } }, create: function create(context) { var menuNode = null; var buttonItemDefaultImportNode = null; var linkItemDefaultImportNode = null; var customDefaultLinkItemSpecifier = null; var allImportDeclarations = []; return { ImportDeclaration: function ImportDeclaration(node) { if (node.source.value === '@atlaskit/menu') { menuNode = node; } else if (node.source.value === '@atlaskit/menu/link-item') { linkItemDefaultImportNode = node; customDefaultLinkItemSpecifier = node.specifiers[0].local.name; } else if (node.source.value === '@atlaskit/menu/button-item') { buttonItemDefaultImportNode = node; } allImportDeclarations.push(node); }, JSXElement: function JSXElement(node) { if (!(0, _eslintCodemodUtils.isNodeOfType)(node, 'JSXElement')) { return; } if (!(0, _eslintCodemodUtils.isNodeOfType)(node.openingElement.name, 'JSXIdentifier')) { return; } // Get the name of the LinkItem import var linkItemImportName = customDefaultLinkItemSpecifier || (0, _getImportName.getImportName)((0, _contextCompat.getScope)(context, node), '@atlaskit/menu', 'LinkItem'); if (node.openingElement.name.name === linkItemImportName) { // and if href prop does not exist var linkProps = node.openingElement.attributes.filter(function (attr) { return (0, _eslintCodemodUtils.isNodeOfType)(attr, 'JSXAttribute'); }).filter(function (attr) { return attr.name.type === 'JSXIdentifier'; }); var href = linkProps.find(function (attr) { return attr.name.name === 'href'; }); if ((0, _utils.hrefHasInvalidValue)((0, _contextCompat.getScope)(context, node), href)) { context.report({ node: node, messageId: 'hrefRequired', suggest: [{ desc: hrefRequiredSuggestionText, fix: function fix(fixer) { var importFix = null; var uniqueButtonItemName = (0, _getUniqueButtonItemName.getUniqueButtonItemName)(menuNode, allImportDeclarations); if ( // Default link item import but no button item imports linkItemDefaultImportNode && !buttonItemDefaultImportNode && (!menuNode || menuNode && !(0, _hasImportOfName.hasImportOfName)(menuNode, 'ButtonItem'))) { importFix = (0, _insertButtonItemDefaultImport.insertButtonItemDefaultImport)(fixer, linkItemDefaultImportNode); } else if ( // No button item imports of any kind menuNode && !(0, _hasImportOfName.hasImportOfName)(menuNode, 'ButtonItem') && !buttonItemDefaultImportNode) { importFix = (0, _insertButtonItemImport.insertButtonItemImport)(fixer, menuNode, uniqueButtonItemName); } var fixes = (importFix ? [importFix] : []).concat(href ? [fixer.remove(href)] : [], [fixer.replaceText(node.openingElement.name, uniqueButtonItemName)]); if (node.closingElement) { fixes.push(fixer.replaceText(node.closingElement.name, uniqueButtonItemName)); } return fixes; } }] }); } } } }; } }); var _default = exports.default = rule;