| /** |
| * @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-Z0-9]|[A-Z0-9]+[a-z0-9]+(?:[A-Z0-9]+[a-z0-9]*)*)$/; |
| const ALL_CAPS_TAG_REGEX = /^[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); |
| |
| // 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) { |
| context.report({ |
| node, |
| message: `Imported JSX component ${name} must be in PascalCase` |
| }); |
| } |
| } |
| }; |
| } |
| }; |