@atlaskit/eslint-plugin-design-system
Version:
The essential plugin for use with the Atlassian Design System.
28 lines (24 loc) • 1.51 kB
JavaScript
import { isNodeOfType } from 'eslint-codemod-utils';
/**
* Given a component name finds its JSX usage
*/
export const getJsxElementByName = (componentName, scope) => {
const variableDeclaration = scope.variables.find(v => v.name === componentName);
if (!variableDeclaration) {
return;
}
// `@typescript-eslint/scope-manager` v8 records a reference for both the opening *and* the
// closing tag of an element, where v7 only recorded the opening one. So key off the opening
// elements rather than the raw reference count, which differs between the two.
const jsxOpeningElements = variableDeclaration.references.map(ref => ref === null || ref === void 0 ? void 0 : ref.identifier).filter(identifier => isNodeOfType(identifier, 'JSXIdentifier')).map(identifier => identifier.parent).filter(parent => isNodeOfType(parent, 'JSXOpeningElement'));
// Anything that isn't a JSX reference, beyond the declaration itself, means the component is
// also used somewhere we can't reason about.
const nonJsxReferences = variableDeclaration.references.filter(ref => !isNodeOfType(ref === null || ref === void 0 ? void 0 : ref.identifier, 'JSXIdentifier'));
// there should be exactly one JSX call site, and the declaration as the only other reference.
// we might consider handling multiple local JSX call sites in the future
// but "this is good enough for now"™️
if (jsxOpeningElements.length !== 1 || nonJsxReferences.length !== 1) {
return;
}
return jsxOpeningElements[0];
};