Skip to content

Commit

Permalink
[New] jsx-no-literals: add noAttributeStrings option
Browse files Browse the repository at this point in the history
Co-authored-by: TaLea Carpenter <taleacarpenter@gmail.com>
Co-authored-by: tanmoyopenroot <tanmoy.openroot@gmail.com>

Fixes ##2486
  • Loading branch information
tanmoyopenroot authored and ljharb committed Nov 15, 2019
1 parent 7434f19 commit 153eac8
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -8,6 +8,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
### Added
* [`button-has-type`]: support trivial ternary expressions ([#2748][] @Hypnosphi)
* [`jsx-handler-names`]: add `checkInlineFunction` option ([#2761][] @dididy)
* [`jsx-no-literals`]: add `noAttributeStrings` option ([#2782][] @TaLeaMonet)

### Fixed
* [`function-component-definition`]: ignore object properties ([#2771][] @stefan-wullems)
Expand All @@ -21,6 +22,7 @@ This change log adheres to standards from [Keep a CHANGELOG](http://keepachangel
[#2796]: https://github.com/yannickcr/eslint-plugin-react/pull/2796
[#2791]: https://github.com/yannickcr/eslint-plugin-react/pull/2791
[#2789]: https://github.com/yannickcr/eslint-plugin-react/pull/2789
[#2782]: https://github.com/yannickcr/eslint-plugin-react/pull/2782
[#2780]: https://github.com/yannickcr/eslint-plugin-react/pull/2780
[#2779]: https://github.com/yannickcr/eslint-plugin-react/pull/2779
[#2772]: https://github.com/yannickcr/eslint-plugin-react/pull/2772
Expand Down
19 changes: 17 additions & 2 deletions docs/rules/jsx-no-literals.md
Expand Up @@ -26,16 +26,17 @@ var Hello = <div>

## Rule Options

There are two options:
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.
* `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": [<enabled>, {"noStrings": true, "allowedStrings": ["allowed"], "ignoreProps": false}]
"react/jsx-no-literals": [<enabled>, {"noStrings": true, "allowedStrings": ["allowed"], "ignoreProps": false, "noAttributeStrings": true }]
```

In this configuration, the following are considered warnings:
Expand All @@ -54,6 +55,12 @@ var Hello = <div>
</div>;
```

```jsx
var Hello = <div>
<img alt="test"> </img>
</div>;
```

```jsx
var Hello = <div class='xx' />;
```
Expand All @@ -67,6 +74,7 @@ var Hello = <div class={`xx`} />;
```



The following are **not** considered warnings:

```jsx
Expand All @@ -91,6 +99,13 @@ var Hello = <div>
</div>;
```

```jsx
// a string value stored within a variable used as an attribute's value
var Hello = <div>
<img alt={imageDescription} {...props} />
</div>;
```

```jsx
// spread props object
var Hello = <Text {...props} />
Expand Down
44 changes: 35 additions & 9 deletions lib/rules/jsx-no-literals.js
Expand Up @@ -40,23 +40,37 @@ module.exports = {
},
ignoreProps: {
type: 'boolean'
},
noAttributeStrings: {
type: 'boolean'
}
},
additionalProperties: false
}]
},

create(context) {
const defaults = {noStrings: false, allowedStrings: [], ignoreProps: false};
const defaults = {
noStrings: false,
allowedStrings: [],
ignoreProps: false,
noAttributeStrings: false
};
const config = Object.assign({}, defaults, context.options[0] || {});
config.allowedStrings = new Set(config.allowedStrings.map(trimIfString));

const message = config.noStrings
? 'Strings not allowed in JSX files'
: 'Missing JSX expression container around literal string';
function defaultMessage() {
if (config.noAttributeStrings) {
return 'Strings not allowed in attributes';
}
if (config.noStrings) {
return 'Strings not allowed in JSX files';
}
return 'Missing JSX expression container around literal string';
}

function reportLiteralNode(node, customMessage) {
const errorMessage = customMessage || message;
const errorMessage = customMessage || defaultMessage();

context.report({
node,
Expand All @@ -77,10 +91,22 @@ module.exports = {
return false;
}
const parent = getParentIgnoringBinaryExpressions(node);
const standard = !/^[\s]+$/.test(node.value)
&& typeof node.value === 'string'
&& parent.type.indexOf('JSX') !== -1
&& parent.type !== 'JSXAttribute';

function isParentNodeStandard() {
if (!/^[\s]+$/.test(node.value) && typeof node.value === 'string' && parent.type.includes('JSX')) {
if (config.noAttributeStrings) {
return parent.type === 'JSXAttribute';
}
if (!config.noAttributeStrings) {
return parent.type !== 'JSXAttribute';
}
}

return false;
}

const standard = isParentNodeStandard();

if (config.noStrings) {
return standard;
}
Expand Down
17 changes: 17 additions & 0 deletions tests/lib/rules/jsx-no-literals.js
Expand Up @@ -39,6 +39,10 @@ function invalidProp(str) {
return `Invalid prop value: “${str}”`;
}

function attributeMessage(str) {
return `Strings not allowed in attributes: “${str}”`;
}

const ruleTester = new RuleTester({parserOptions});
ruleTester.run('jsx-no-literals', rule, {

Expand Down Expand Up @@ -331,6 +335,11 @@ ruleTester.run('jsx-no-literals', rule, {
} `,
parser: parsers.BABEL_ESLINT,
options: [{noStrings: true, ignoreProps: false}]
},
{
code: `
<img alt='blank image'></img>
`
}
),

Expand Down Expand Up @@ -527,6 +536,14 @@ ruleTester.run('jsx-no-literals', rule, {
errors: [
{message: stringsMessage('\'bar\'')}
]
},
{
code: `
<img alt='blank image'></img>
`,
options: [{noAttributeStrings: true}],
errors: [
{message: attributeMessage('\'blank image\'')}]
}
]
});

0 comments on commit 153eac8

Please sign in to comment.