diff --git a/docs/rules/jsx-no-literals.md b/docs/rules/jsx-no-literals.md index 1a69313951..248b5a5033 100644 --- a/docs/rules/jsx-no-literals.md +++ b/docs/rules/jsx-no-literals.md @@ -33,12 +33,13 @@ The supported options are: - `noStrings` (default: `false`) - Enforces no string literals used as children, wrapped or unwrapped. - `allowedStrings` - An array of unique string values that would otherwise warn, but will be ignored. - `ignoreProps` (default: `false`) - When `true` the rule ignores literals used in props, wrapped or unwrapped. +- `allowedProps` - An array of unique property names that would otherwise warn, but will be ignored. - `noAttributeStrings` (default: `false`) - Enforces no string literals used in attributes when set to `true`. To use, you can specify as follows: ```js -"react/jsx-no-literals": [, {"noStrings": true, "allowedStrings": ["allowed"], "ignoreProps": false, "noAttributeStrings": true }] +"react/jsx-no-literals": [, {"noStrings": true, "allowedStrings": ["allowed"], "ignoreProps": false, "allowedProps": ["allowed"], "noAttributeStrings": true }] ``` Examples of **incorrect** code for this rule, with the above configuration: @@ -64,7 +65,7 @@ var Hello =
``` ```jsx -var Hello =
; +var Hello =
; ``` ```jsx @@ -116,6 +117,11 @@ var Hello = var Hello =
``` +```jsx +// an allowed property +var Hello =
allowed
+``` + ```jsx // cache class Comp1 extends Component { diff --git a/lib/rules/jsx-no-literals.js b/lib/rules/jsx-no-literals.js index 4349b0829f..34c86163b3 100644 --- a/lib/rules/jsx-no-literals.js +++ b/lib/rules/jsx-no-literals.js @@ -51,6 +51,13 @@ module.exports = { ignoreProps: { type: 'boolean', }, + allowedProps: { + type: 'array', + uniqueItems: true, + items: { + type: 'string', + }, + }, noAttributeStrings: { type: 'boolean', }, @@ -63,11 +70,13 @@ module.exports = { const defaults = { noStrings: false, allowedStrings: [], + allowedProps: [], ignoreProps: false, noAttributeStrings: false, }; const config = Object.assign({}, defaults, context.options[0] || {}); config.allowedStrings = new Set(config.allowedStrings.map(trimIfString)); + config.allowedProps = new Set(config.allowedProps.map(trimIfString)); function defaultMessageId() { const ancestorIsJSXElement = arguments.length >= 1 && arguments[0]; @@ -99,7 +108,8 @@ module.exports = { function isParentNodeStandard() { if (!/^[\s]+$/.test(node.value) && typeof node.value === 'string' && parent.type.includes('JSX')) { if (config.noAttributeStrings) { - return parent.type === 'JSXAttribute' || parent.type === 'JSXElement'; + const isAllowedProp = parent.name && config.allowedProps.has(parent.name.name); + return (parent.type === 'JSXAttribute' || parent.type === 'JSXElement') && !isAllowedProp; } if (!config.noAttributeStrings) { return parent.type !== 'JSXAttribute'; @@ -163,8 +173,9 @@ module.exports = { JSXAttribute(node) { const isNodeValueString = node && node.value && node.value.type === 'Literal' && typeof node.value.value === 'string' && !config.allowedStrings.has(node.value.value); + const isAllowedProp = config.allowedProps.has(node.name.name); - if (config.noStrings && !config.ignoreProps && isNodeValueString) { + if (config.noStrings && !config.ignoreProps && isNodeValueString && !isAllowedProp) { const messageId = 'invalidPropValue'; reportLiteralNode(node, messageId); } diff --git a/tests/lib/rules/jsx-no-literals.js b/tests/lib/rules/jsx-no-literals.js index d547178d8b..011771d065 100644 --- a/tests/lib/rules/jsx-no-literals.js +++ b/tests/lib/rules/jsx-no-literals.js @@ -281,7 +281,7 @@ ruleTester.run('jsx-no-literals', rule, { }, { code: ` - blank image + blank image `, }, { @@ -296,6 +296,23 @@ ruleTester.run('jsx-no-literals', rule, { `, options: [{ noStrings: true, allowedStrings: ['—', '—'] }], }, + { + code: ` + blank image + `, + options: [{ noStrings: true, allowedProps: ['alt'] }], + }, + { + code: ` + class Comp1 extends Component { + asdf() {} + render() { + return ; + } + } + `, + options: [{ noStrings: true, allowedProps: ['class'] }], + }, ]), invalid: parsers.all([