@atlaskit/eslint-plugin-design-system
Version:
The essential plugin for use with the Atlassian Design System.
130 lines (128 loc) • 3.87 kB
JavaScript
/* eslint-disable @repo/internal/react/require-jsdoc */
import { isNodeOfType } from 'eslint-codemod-utils';
import { JSXElementHelper } from '../../../ast-nodes/jsx-element-helper';
import { Root } from '../../../ast-nodes/root';
import { allowedAttrs } from './allowed-attrs';
import { updateTestIdAttributeFix } from './update-test-id-attribute-fix';
const tagSizeMap = {
h1: 'xlarge',
h2: 'large',
h3: 'medium',
h4: 'small',
h5: 'xsmall',
h6: 'xxsmall'
};
export const NativeElements = {
lint(node, {
context,
config
}) {
// Check whether all criteria needed to make a transformation are met
const {
success,
autoFixable
} = NativeElements._check(node, {
context,
config
});
if (success && autoFixable) {
const fix = NativeElements._fix(node, {
context,
config
});
context.report({
node,
messageId: 'preferHeading',
...(config.enableUnsafeAutofix ? {
fix
} : {
suggest: [{
desc: `Convert to Heading`,
fix
}]
})
});
} else if (success && config.enableUnsafeReport) {
context.report({
node,
messageId: 'preferHeading'
});
}
},
_check(node, {
config
}) {
if (!config.patterns.includes('native-elements')) {
return {
success: false
};
}
if (!isNodeOfType(node, 'JSXElement')) {
return {
success: false
};
}
if (!node.children.length) {
return {
success: false
};
}
const elementName = JSXElementHelper.getName(node);
if (!Object.keys(tagSizeMap).includes(elementName)) {
return {
success: false
};
}
if (!node.parent) {
return {
success: true,
autoFixable: false
};
}
// Element has to be first element of its siblings
if (!(isNodeOfType(node.parent, 'JSXElement') || isNodeOfType(node.parent, 'JSXFragment'))) {
return {
success: true,
autoFixable: false
};
}
const siblings = JSXElementHelper.getChildren(node.parent);
if (siblings.length > 1) {
var _siblings$0$range, _node$range, _siblings$0$range2, _node$range2;
// Only report if element is first child element
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
};
}
}
if (!JSXElementHelper.hasAllowedAttrsOnly(node, allowedAttrs)) {
return {
success: true,
autoFixable: false
};
}
return {
success: true,
autoFixable: true
};
},
_fix(node, {
context
}) {
return fixer => {
// change to default import
const importFix = Root.upsertDefaultImportDeclaration({
module: '@atlaskit/heading',
localName: 'Heading'
}, context, fixer);
const elementName = JSXElementHelper.getName(node);
const elementNameFixes = JSXElementHelper.updateName(node, 'Heading', fixer);
const size = tagSizeMap[elementName];
const asAttributeFix = JSXElementHelper.addAttribute(node, 'size', size, fixer);
const testAttributeFix = updateTestIdAttributeFix(node, fixer);
return [importFix, ...elementNameFixes, asAttributeFix, testAttributeFix].filter(fix => Boolean(fix)); // Some of the transformers can return arrays with undefined, so filter them out
};
}
};