Skip to content

Commit 099b14c

Browse files
taozhou-gleanljharb
authored andcommitted
[Fix] jsx-curly-brace-presence: handle single and only expression template literals
1 parent 8f24366 commit 099b14c

File tree

3 files changed

+32
-0
lines changed

3 files changed

+32
-0
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ This change log adheres to standards from [Keep a CHANGELOG](https://keepachange
1010

1111
### Fixed
1212
* [`no-array-index-key`]: consider flatMap ([#3530][] @k-yle)
13+
* [`jsx-curly-brace-presence`]: handle single and only expression template literals ([#3538][] @taozhou-glean)
1314

15+
[#3538]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3538
1416
[#3530]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3530
1517
[#3529]: https://github.com/jsx-eslint/eslint-plugin-react/pull/3529
1618

lib/rules/jsx-curly-brace-presence.js

+10
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,10 @@ module.exports = {
131131
return containsLineTerminators(text) && text.trim() === '';
132132
}
133133

134+
function isSingleExpressionTemplateLiteral(child) {
135+
return child.type === 'TemplateLiteral' && child.expressions.length === 1 && child.quasis.map((quasis) => quasis.value.raw).join('') === '';
136+
}
137+
134138
function wrapNonHTMLEntities(text) {
135139
const HTML_ENTITY = '<HTML_ENTITY>';
136140
const withCurlyBraces = text.split(HTML_ENTITY_REGEX()).map((word) => (
@@ -177,6 +181,9 @@ module.exports = {
177181
if (jsxUtil.isJSX(expression)) {
178182
const sourceCode = context.getSourceCode();
179183
textToReplace = sourceCode.getText(expression);
184+
} else if (isSingleExpressionTemplateLiteral(expression)) {
185+
const sourceCode = context.getSourceCode();
186+
textToReplace = `{${sourceCode.getText(expression.expressions[0])}}`;
180187
} else {
181188
const expressionType = expression && expression.type;
182189
const parentType = JSXExpressionNode.parent.type;
@@ -279,6 +286,9 @@ module.exports = {
279286
&& !containsQuoteCharacters(expression.quasis[0].value.cooked)
280287
) {
281288
reportUnnecessaryCurly(JSXExpressionNode);
289+
} else if (
290+
isSingleExpressionTemplateLiteral(expression)) {
291+
reportUnnecessaryCurly(JSXExpressionNode);
282292
} else if (jsxUtil.isJSX(expression)) {
283293
reportUnnecessaryCurly(JSXExpressionNode);
284294
}

tests/lib/rules/jsx-curly-brace-presence.js

+20
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,14 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
468468
`,
469469
features: ['no-ts'],
470470
options: ['never'],
471+
},
472+
{
473+
code: '<App label={`${label}${suffix}`} />',
474+
options: [{ props: 'never' }],
475+
},
476+
{
477+
code: '<App>{`${label}${suffix}`}</App>',
478+
options: [{ children: 'never' }],
471479
}
472480
)),
473481

@@ -931,6 +939,18 @@ ruleTester.run('jsx-curly-brace-presence', rule, {
931939
errors: [{ messageId: 'unnecessaryCurly' }],
932940
options: [{ props: 'never', children: 'never', propElementValues: 'never' }],
933941
features: ['no-ts'],
942+
},
943+
{
944+
code: '<App label={`${label}`} />',
945+
output: '<App label={label} />',
946+
errors: [{ messageId: 'unnecessaryCurly' }],
947+
options: [{ props: 'never', children: 'never', propElementValues: 'never' }],
948+
},
949+
{
950+
code: '<App>{`${label}`}</App>',
951+
output: '<App>{label}</App>',
952+
errors: [{ messageId: 'unnecessaryCurly' }],
953+
options: [{ props: 'never', children: 'never', propElementValues: 'never' }],
934954
}
935955
)),
936956
});

0 commit comments

Comments
 (0)