@atlaskit/eslint-plugin-design-system
Version:
The essential plugin for use with the Atlassian Design System.
102 lines (100 loc) • 5.03 kB
JavaScript
;
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;