eslint-plugin-styled-component-jsx-attributes
Version:
A simple plugin for enforcing the use of the id attribute on styled components.
93 lines (78 loc) • 3.56 kB
JavaScript
;
var mergeStyledAttrsWithNodeAttrs = require('../mergeStyledAttrsWithNodeAttrs');
var mapChainExpressions = require('../mapChainExpressions');
var _require = require('util'),
inspect = _require.inspect;
module.exports = function (context, styledComponents, rule, name) {
return {
JSXOpeningElement: function JSXOpeningElement(node) {
// Early return if node is invalid
if (!node) {
return;
}
var func = function func(inspectee) {
return name.includes('scope') && context.report(node, inspect(inspectee || node));
};
try {
// Handle different possible node structures
var elementName;
if (node.name) {
if (node.name.name) {
// Standard JSX element: <Button />
elementName = node.name.name;
} else if (node.name.type === 'JSXMemberExpression') {
// JSX member expression: <Namespace.Component />
elementName = "".concat(node.name.object.name, ".").concat(node.name.property.name);
}
} // If we couldn't extract a name, try to use the component's displayName or default to a generic identifier
if (!elementName && node.name) {
// Try to get any available identifier for the component
elementName = "UnnamedComponent_" + (node._paths || node.start || Math.random().toString(36).substr(2, 9));
}
var styledComponent = elementName ? styledComponents[elementName] : null;
if (styledComponent) {
var tag = styledComponent.tag,
attrs = styledComponent.attrs;
var originalNodeAttr = node.attributes;
var originalNodeName = node.name;
try {
var allAttrs = mergeStyledAttrsWithNodeAttrs(attrs, originalNodeAttr);
node.attributes = mapChainExpressions(allAttrs); // Convert JSXMemberExpression to JSXIdentifier, so it'll be properly handled by eslint-plugin-jsx-a11y plugin
node.name = {
type: 'JSXIdentifier',
name: tag || 'div',
// Provide a fallback tag if undefined
start: originalNodeName.start,
end: originalNodeName.end,
loc: originalNodeName.loc,
range: originalNodeName.range,
parent: originalNodeName.parent
};
try {
var ruleHandlers = rule.create(context, styledComponent);
if (ruleHandlers && typeof ruleHandlers.JSXOpeningElement === 'function') {
ruleHandlers.JSXOpeningElement(node);
}
} catch (ruleError) {
// Catch errors from rule application but don't break the linting process
if (context.report && typeof context.report === 'function') {
context.report({
node: node,
message: "Error applying rule: ".concat(ruleError.message || 'Unknown error')
});
}
}
} catch (error) {// Additional error handling to catch any unexpected issues
// This ensures linting will continue even if something goes wrong
} finally {
// Always restore the original node structure
node.name = originalNodeName;
node.attributes = originalNodeAttr;
}
}
} catch (outerError) {// Global try-catch to ensure the parser never crashes
// Even if we encounter completely unexpected node structures
}
}
};
};