UNPKG

eslint-config-airbnb-standard

Version:

Airbnb's JS ESLint config + JS Standard Style + semicolons

81 lines (66 loc) 2.4 kB
/** * @fileoverview Enforce PascalCase for user-defined JSX components * @author Jake Marsh */ 'use strict'; const elementType = require('jsx-ast-utils/elementType'); const docsUrl = require('../util/docsUrl'); const jsxUtil = require('../util/jsx'); // ------------------------------------------------------------------------------ // Constants // ------------------------------------------------------------------------------ const PASCAL_CASE_REGEX = /^(.*[.])*([A-Z]|[A-Z]+[a-z0-9]+(?:[A-Z0-9]+[a-z0-9]*)*)$/; const ALL_CAPS_TAG_REGEX = /^[A-Z0-9]+([A-Z0-9_]*[A-Z0-9]+)?$/; // ------------------------------------------------------------------------------ // Rule Definition // ------------------------------------------------------------------------------ module.exports = { meta: { docs: { description: 'Enforce PascalCase for user-defined JSX components', category: 'Stylistic Issues', recommended: false, url: docsUrl('jsx-pascal-case') }, schema: [{ type: 'object', properties: { allowAllCaps: { type: 'boolean' }, ignore: { type: 'array' } }, additionalProperties: false }] }, create(context) { const configuration = context.options[0] || {}; const allowAllCaps = configuration.allowAllCaps || false; const ignore = configuration.ignore || []; return { JSXOpeningElement(node) { let name = elementType(node); if (name.length === 1) return undefined; // Get namespace if the type is JSXNamespacedName or JSXMemberExpression if (name.indexOf(':') > -1) { name = name.substring(0, name.indexOf(':')); } else if (name.indexOf('.') > -1) { name = name.substring(0, name.indexOf('.')); } const isPascalCase = PASCAL_CASE_REGEX.test(name); const isCompatTag = jsxUtil.isDOMComponent(node); const isAllowedAllCaps = allowAllCaps && ALL_CAPS_TAG_REGEX.test(name); const isIgnored = ignore.indexOf(name) !== -1; if (!isPascalCase && !isCompatTag && !isAllowedAllCaps && !isIgnored) { let message = `Imported JSX component ${name} must be in PascalCase`; if (allowAllCaps) { message += ' or SCREAMING_SNAKE_CASE'; } context.report({node, message}); } } }; } };