Repository: jsx-eslint/eslint-plugin-react (js)

Issue:
[`jsx-no-literals`]: no errors for children when `noAttributeStrings: true`
```js
'react/jsx-no-literals': [2, { noAttributeStrings: true }],
```

```js
import React from 'react';

export const WithAttributes = ({}) => <div title="foo bar" />;
export const WithChildren = ({}) => <div>baz bob</div>;
export const WithAttributesAndChildren = ({}) => (
  <div title="foo bar">baz bob</div>
);

```

Expected: the JSX inside of `WithChildren` produces an error (like it does when `noAttributeStrings: false`)

Actual: the JSX inside of `WithChildren` does not produce an error

Pull request description:
[Fix] `jsx-no-literals`: properly error on children with noAttributeStrings: true
Fixes #3171

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 87480698..52dc09f1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,8 +9,12 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
 * [`jsx-newline`]: add `allowMultiline` option when prevent option is true ([#3311][] @TildaDares)
 
 ### Fixed
+* [`jsx-no-literals`]: properly error on children with noAttributeStrings: true ([#3317][] @TildaDares)
+
+### Changed
 * [Refactor] [`jsx-indent-props`]: improved readability of the checkNodesIndent function ([#3315][] @caroline223)
 
+[#3317]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3317
 [#3315]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3315
 [#3311]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3311
 
diff --git a/lib/rules/jsx-no-literals.js b/lib/rules/jsx-no-literals.js
index 7ad1ff62..7c528c52 100644
--- a/lib/rules/jsx-no-literals.js
+++ b/lib/rules/jsx-no-literals.js
@@ -70,7 +70,8 @@ module.exports = {
     config.allowedStrings = new Set(config.allowedStrings.map(trimIfString));
 
     function defaultMessageId() {
-      if (config.noAttributeStrings) {
+      const ancestorIsJSXElement = arguments.length >= 1 && arguments[0];
+      if (config.noAttributeStrings && !ancestorIsJSXElement) {
         return 'noStringsInAttributes';
       }
       if (config.noStrings) {
@@ -79,17 +80,6 @@ module.exports = {
       return 'literalNotInJSXExpression';
     }
 
-    function reportLiteralNode(node, messageId) {
-      messageId = messageId || defaultMessageId();
-
-      report(context, messages[messageId], messageId, {
-        node,
-        data: {
-          text: context.getSourceCode().getText(node).trim(),
-        },
-      });
-    }
-
     function getParentIgnoringBinaryExpressions(node) {
       let current = node;
       while (current.parent.type === 'BinaryExpression') {
@@ -107,7 +97,7 @@ module.exports = {
       function isParentNodeStandard() {
         if (!/^[\s]+$/.test(node.value) && typeof node.value === 'string' && parent.type.includes('JSX')) {
           if (config.noAttributeStrings) {
-            return parent.type === 'JSXAttribute';
+            return parent.type === 'JSXAttribute' || parent.type === 'JSXElement';
           }
           if (!config.noAttributeStrings) {
             return parent.type !== 'JSXAttribute';
@@ -146,6 +136,18 @@ module.exports = {
       return parentType === 'JSXFragment' || parentType === 'JSXElement' || grandParentType === 'JSXElement';
     }
 
+    function reportLiteralNode(node, messageId) {
+      const ancestorIsJSXElement = hasJSXElementParentOrGrandParent(node);
+      messageId = messageId || defaultMessageId(ancestorIsJSXElement);
+
+      report(context, messages[messageId], messageId, {
+        node,
+        data: {
+          text: context.getSourceCode().getText(node).trim(),
+        },
+      });
+    }
+
     // --------------------------------------------------------------------------
     // Public
     // --------------------------------------------------------------------------


Test patch:
diff --git a/tests/lib/rules/jsx-no-literals.js b/tests/lib/rules/jsx-no-literals.js
index d1cbcecb..42408790 100644
--- a/tests/lib/rules/jsx-no-literals.js
+++ b/tests/lib/rules/jsx-no-literals.js
@@ -613,5 +613,43 @@ ruleTester.run('jsx-no-literals', rule, {
         },
       ],
     },
+    {
+      code: 'export const WithChildren = ({}) => <div>baz bob</div>;',
+      options: [{ noAttributeStrings: true }],
+      errors: [
+        {
+          messageId: 'literalNotInJSXExpression',
+          data: { text: 'baz bob' },
+        },
+      ],
+    },
+    {
+      code: 'export const WithAttributes = ({}) => <div title="foo bar" />;',
+      options: [{ noAttributeStrings: true }],
+      errors: [
+        {
+          messageId: 'noStringsInAttributes',
+          data: { text: '"foo bar"' },
+        },
+      ],
+    },
+    {
+      code: `
+        export const WithAttributesAndChildren = ({}) => (
+          <div title="foo bar">baz bob</div>
+        );
+      `,
+      options: [{ noAttributeStrings: true }],
+      errors: [
+        {
+          messageId: 'noStringsInAttributes',
+          data: { text: '"foo bar"' },
+        },
+        {
+          messageId: 'literalNotInJSXExpression',
+          data: { text: 'baz bob' },
+        },
+      ],
+    },
   ]),
 });