diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5f13995703..39b0db4059 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,11 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
## Unreleased
+### Fixed
+* [`jsx-curly-brace-presence`]: avoid warning on curlies containing quote characters ([#3214][] @ljharb)
+
+[#3214]: https://github.com/yannickcr/eslint-plugin-react/issues/3214
+
## [7.29.1] - 2022.02.25
### Fixed
diff --git a/lib/rules/jsx-curly-brace-presence.js b/lib/rules/jsx-curly-brace-presence.js
index 5b2ae5127f..b5a0e99537 100755
--- a/lib/rules/jsx-curly-brace-presence.js
+++ b/lib/rules/jsx-curly-brace-presence.js
@@ -39,9 +39,7 @@ const messages = {
module.exports = {
meta: {
docs: {
- description:
- 'Disallow unnecessary JSX expressions when literals alone are sufficient '
- + 'or enfore JSX expressions on literals in JSX children or attributes',
+ description: 'Disallow unnecessary JSX expressions when literals alone are sufficient or enfore JSX expressions on literals in JSX children or attributes',
category: 'Stylistic Issues',
recommended: false,
url: docsUrl('jsx-curly-brace-presence'),
@@ -274,13 +272,11 @@ module.exports = {
reportUnnecessaryCurly(JSXExpressionNode);
} else if (
expressionType === 'TemplateLiteral'
- && expression.expressions.length === 0
- && expression.quasis[0].value.raw.indexOf('\n') === -1
- && !isStringWithTrailingWhiteSpaces(expression.quasis[0].value.raw)
- && !needToEscapeCharacterForJSX(expression.quasis[0].value.raw, JSXExpressionNode) && (
- jsxUtil.isJSX(JSXExpressionNode.parent)
- || !containsQuoteCharacters(expression.quasis[0].value.cooked)
- )
+ && expression.expressions.length === 0
+ && expression.quasis[0].value.raw.indexOf('\n') === -1
+ && !isStringWithTrailingWhiteSpaces(expression.quasis[0].value.raw)
+ && !needToEscapeCharacterForJSX(expression.quasis[0].value.raw, JSXExpressionNode)
+ && !containsQuoteCharacters(expression.quasis[0].value.cooked)
) {
reportUnnecessaryCurly(JSXExpressionNode);
} else if (jsxUtil.isJSX(expression)) {
diff --git a/tests/lib/rules/jsx-curly-brace-presence.js b/tests/lib/rules/jsx-curly-brace-presence.js
index e01df9b89d..a0937b047b 100755
--- a/tests/lib/rules/jsx-curly-brace-presence.js
+++ b/tests/lib/rules/jsx-curly-brace-presence.js
@@ -454,6 +454,11 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
{
code: `} />`,
options: [{ propElementValues: 'ignore' }],
+ },
+ {
+ code: `
+
+ `,
}
)),
diff --git a/tests/lib/rules/no-unescaped-entities.js b/tests/lib/rules/no-unescaped-entities.js
index 097041e9b1..8971a1b3f7 100644
--- a/tests/lib/rules/no-unescaped-entities.js
+++ b/tests/lib/rules/no-unescaped-entities.js
@@ -315,6 +315,25 @@ ruleTester.run('no-unescaped-entities', rule, {
],
},
],
+ },
+ {
+ code: `
+
+ `,
+ errors: [
+ {
+ messageId: 'unescapedEntityAlts',
+ data: { entity: '"', alts: '`"`, `“`, `"`, `”`' },
+ line: 2,
+ column: 30,
+ },
+ {
+ messageId: 'unescapedEntityAlts',
+ data: { entity: '"', alts: '`"`, `“`, `"`, `”`' },
+ line: 2,
+ column: 34,
+ },
+ ],
}
)),
});