Skip to content

Commit 9653071

Browse files
Merge pull request #20912 from uniqueiniquity/jsxFragmentFormatting
Fix formatting for JSX fragment tags
2 parents 8ed4e66 + 80b7983 commit 9653071

File tree

3 files changed

+34
-5
lines changed

3 files changed

+34
-5
lines changed

Diff for: src/services/formatting/rules.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -231,8 +231,8 @@ namespace ts.formatting {
231231
rule("SpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.Space),
232232
rule("NoSpaceAfterConstructor", SyntaxKind.ConstructorKeyword, SyntaxKind.OpenParenToken, [isOptionDisabledOrUndefined("insertSpaceAfterConstructor"), isNonJsxSameLineTokenContext], RuleAction.Delete),
233233

234-
rule("SpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext, isNextTokenNotCloseBracket], RuleAction.Space),
235-
rule("NoSpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementContext], RuleAction.Delete),
234+
rule("SpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionEnabled("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNextTokenNotCloseBracket], RuleAction.Space),
235+
rule("NoSpaceAfterComma", SyntaxKind.CommaToken, anyToken, [isOptionDisabledOrUndefined("insertSpaceAfterCommaDelimiter"), isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext], RuleAction.Delete),
236236

237237
// Insert space after function keyword for anonymous functions
238238
rule("SpaceAfterAnonymousFunctionKeyword", SyntaxKind.FunctionKeyword, SyntaxKind.OpenParenToken, [isOptionEnabled("insertSpaceAfterFunctionKeywordForAnonymousFunctions"), isFunctionDeclContext], RuleAction.Space),
@@ -319,7 +319,7 @@ namespace ts.formatting {
319319
"SpaceBetweenStatements",
320320
[SyntaxKind.CloseParenToken, SyntaxKind.DoKeyword, SyntaxKind.ElseKeyword, SyntaxKind.CaseKeyword],
321321
anyToken,
322-
[isNonJsxSameLineTokenContext, isNonJsxElementContext, isNotForContext],
322+
[isNonJsxSameLineTokenContext, isNonJsxElementOrFragmentContext, isNotForContext],
323323
RuleAction.Space),
324324
// This low-pri rule takes care of "try {" and "finally {" in case the rule SpaceBeforeOpenBraceInControl didn't execute on FormatOnEnter.
325325
rule("SpaceAfterTryFinally", [SyntaxKind.TryKeyword, SyntaxKind.FinallyKeyword], SyntaxKind.OpenBraceToken, [isNonJsxSameLineTokenContext], RuleAction.Space),
@@ -614,8 +614,8 @@ namespace ts.formatting {
614614
return context.TokensAreOnSameLine() && context.contextNode.kind !== SyntaxKind.JsxText;
615615
}
616616

617-
function isNonJsxElementContext(context: FormattingContext): boolean {
618-
return context.contextNode.kind !== SyntaxKind.JsxElement;
617+
function isNonJsxElementOrFragmentContext(context: FormattingContext): boolean {
618+
return context.contextNode.kind !== SyntaxKind.JsxElement && context.contextNode.kind !== SyntaxKind.JsxFragment;
619619
}
620620

621621
function isJsxExpressionContext(context: FormattingContext): boolean {

Diff for: src/services/formatting/smartIndenter.ts

+3
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,7 @@ namespace ts.formatting {
508508
case SyntaxKind.ArrayBindingPattern:
509509
case SyntaxKind.ObjectBindingPattern:
510510
case SyntaxKind.JsxOpeningElement:
511+
case SyntaxKind.JsxOpeningFragment:
511512
case SyntaxKind.JsxSelfClosingElement:
512513
case SyntaxKind.JsxExpression:
513514
case SyntaxKind.MethodSignature:
@@ -554,6 +555,8 @@ namespace ts.formatting {
554555
(!!(<ImportClause>child).namedBindings && (<ImportClause>child).namedBindings.kind !== SyntaxKind.NamedImports);
555556
case SyntaxKind.JsxElement:
556557
return childKind !== SyntaxKind.JsxClosingElement;
558+
case SyntaxKind.JsxFragment:
559+
return childKind !== SyntaxKind.JsxClosingFragment;
557560
}
558561
// No explicit rule for given nodes so the result will follow the default value argument
559562
return indentByDefault;

Diff for: tests/cases/fourslash/formattingJsxElements.ts

+26
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@
4747
//// )
4848
////}
4949
////
50+
////const bar = (
51+
//// <>
52+
//// /*fragmentChildIndent*/<p>text</p>
53+
//// </>
54+
////);
55+
////
56+
////const bar2 = <>
57+
//// <p>text</p>
58+
//// /*fragmentClosingTagIndent*/</>;
59+
////
5060
////(function () {
5161
//// return <div
5262
////className=""/*attrAutoformat*/
@@ -68,8 +78,12 @@
6878
////
6979
////<div>,{integer}</div>;/*commaInJsxElement*/
7080
////<div>, {integer}</div>;/*commaInJsxElement2*/
81+
////<>,{integer}</>;/*commaInJsxFragment*/
82+
////<>, {integer}</>;/*commaInJsxFragment2*/
7183
////<span>)</span>;/*closingParenInJsxElement*/
7284
////<span>) </span>;/*closingParenInJsxElement2*/
85+
////<>)</>;/*closingParenInJsxFragment*/
86+
////<>) </>;/*closingParenInJsxFragment2*/
7387
////<Router routes = { 3 } / >;/*jsxExpressionSpaces*/
7488
////<Router routes={ (3) } />;/*jsxExpressionSpaces2*/
7589
////<Router routes={() => {}}/*jsxExpressionSpaces3*/
@@ -111,6 +125,10 @@ verify.currentLineContentIs(' class3={');
111125
goTo.marker("6");
112126
verify.currentLineContentIs(' } />');
113127

128+
goTo.marker("fragmentChildIndent");
129+
verify.currentLineContentIs(" <p>text</p>");
130+
goTo.marker("fragmentClosingTagIndent");
131+
verify.currentLineContentIs("</>;");
114132

115133
goTo.marker("attrAutoformat");
116134
verify.currentLineContentIs(' className=""');
@@ -139,10 +157,18 @@ goTo.marker("commaInJsxElement");
139157
verify.currentLineContentIs("<div>,{integer}</div>;");
140158
goTo.marker("commaInJsxElement2");
141159
verify.currentLineContentIs("<div>, {integer}</div>;");
160+
goTo.marker("commaInJsxFragment");
161+
verify.currentLineContentIs("<>,{integer}</>;");
162+
goTo.marker("commaInJsxFragment2");
163+
verify.currentLineContentIs("<>, {integer}</>;");
142164
goTo.marker("closingParenInJsxElement");
143165
verify.currentLineContentIs("<span>)</span>;");
144166
goTo.marker("closingParenInJsxElement2");
145167
verify.currentLineContentIs("<span>) </span>;");
168+
goTo.marker("closingParenInJsxFragment");
169+
verify.currentLineContentIs("<>)</>;");
170+
goTo.marker("closingParenInJsxFragment2");
171+
verify.currentLineContentIs("<>) </>;");
146172
goTo.marker("jsxExpressionSpaces");
147173
verify.currentLineContentIs("<Router routes={3} />;");
148174
goTo.marker("jsxExpressionSpaces2");

0 commit comments

Comments
 (0)