Skip to content

Commit 634ee00

Browse files
authored
feat: make jsx.bracketSpacing high level config (#448)
1 parent b2e3720 commit 634ee00

12 files changed

+189
-31
lines changed

deployment/schema.json

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@
633633
"description": "Ex. `import {SomeExport, OtherExport} from \"my-module\";`"
634634
}]
635635
},
636-
"jsx.spaceBeforeSelfClosingTagSlash": {
636+
"jsxSelfClosingElement.spaceBeforeSlash": {
637637
"description": "Whether to add a space before a JSX element's slash when self closing.",
638638
"type": "boolean",
639639
"default": true,
@@ -793,6 +793,18 @@
793793
"binaryExpression.linePerExpression": {
794794
"$ref": "#/definitions/binaryExpression.linePerExpression"
795795
},
796+
"jsx.bracketPosition": {
797+
"$ref": "#/definitions/jsx.bracketPosition"
798+
},
799+
"jsxOpeningElement.bracketPosition": {
800+
"$ref": "#/definitions/jsx.bracketPosition"
801+
},
802+
"jsxSelfClosingElement.bracketPosition": {
803+
"$ref": "#/definitions/jsx.bracketPosition"
804+
},
805+
"jsx.forceNewLinesSurroundingContent": {
806+
"$ref": "#/definitions/jsx.forceNewLinesSurroundingContent"
807+
},
796808
"jsx.quoteStyle": {
797809
"$ref": "#/definitions/jsx.quoteStyle"
798810
},
@@ -916,8 +928,8 @@
916928
"importDeclaration.spaceSurroundingNamedImports": {
917929
"$ref": "#/definitions/importDeclaration.spaceSurroundingNamedImports"
918930
},
919-
"jsx.spaceBeforeSelfClosingTagSlash": {
920-
"$ref": "#/definitions/jsx.spaceBeforeSelfClosingTagSlash"
931+
"jsxSelfClosingElement.spaceBeforeSlash": {
932+
"$ref": "#/definitions/jsxSelfClosingElement.spaceBeforeSlash"
921933
},
922934
"jsxExpressionContainer.spaceSurroundingExpression": {
923935
"$ref": "#/definitions/jsxExpressionContainer.spaceSurroundingExpression"

src/configuration/builder.rs

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -128,14 +128,30 @@ impl ConfigurationBuilder {
128128
self.insert("jsx.forceNewLinesSurroundingContent", value.into())
129129
}
130130

131-
/// If the end angle bracket of a jsx open element or self closing element
131+
/// If the end angle bracket of a jsx opening element or self closing element
132132
/// should be on the same or next line when the attributes span multiple lines.
133133
///
134134
/// Default: `nextLine`
135135
pub fn jsx_bracket_position(&mut self, value: SameOrNextLinePosition) -> &mut Self {
136136
self.insert("jsx.bracketPosition", value.to_string().into())
137137
}
138138

139+
/// If the end angle bracket of a jsx opening element should be on the same
140+
/// or next line when the attributes span multiple lines.
141+
///
142+
/// Default: `nextLine`
143+
pub fn jsx_opening_element_bracket_position(&mut self, value: SameOrNextLinePosition) -> &mut Self {
144+
self.insert("jsxOpeningElement.bracketPosition", value.to_string().into())
145+
}
146+
147+
/// If the end angle bracket of a jsx self closing element should be on the same
148+
/// or next line when the attributes span multiple lines.
149+
///
150+
/// Default: `nextLine`
151+
pub fn jsx_self_closing_element_bracket_position(&mut self, value: SameOrNextLinePosition) -> &mut Self {
152+
self.insert("jsxSelfClosingElement.bracketPosition", value.to_string().into())
153+
}
154+
139155
/// Whether statements should end in a semi-colon.
140156
///
141157
/// Default: `SemiColons::Prefer`
@@ -357,8 +373,8 @@ impl ConfigurationBuilder {
357373
///
358374
/// * `true` (default) - Ex. `<Test />`
359375
/// * `false` - Ex. `<Test/>`
360-
pub fn jsx_space_before_self_closing_tag_slash(&mut self, value: bool) -> &mut Self {
361-
self.insert("jsx.spaceBeforeSelfClosingTagSlash", value.into())
376+
pub fn jsx_self_closing_element_space_before_slash(&mut self, value: bool) -> &mut Self {
377+
self.insert("jsxSelfClosingElement.spaceBeforeSlash", value.into())
362378
}
363379

364380
/// Whether to add a space surrounding the properties of an object expression.
@@ -1047,6 +1063,8 @@ mod tests {
10471063
.jsx_multi_line_parens(JsxMultiLineParens::Never)
10481064
.jsx_force_new_lines_surrounding_content(true)
10491065
.jsx_bracket_position(SameOrNextLinePosition::Maintain)
1066+
.jsx_opening_element_bracket_position(SameOrNextLinePosition::Maintain)
1067+
.jsx_self_closing_element_bracket_position(SameOrNextLinePosition::Maintain)
10501068
.semi_colons(SemiColons::Prefer)
10511069
.brace_position(BracePosition::NextLine)
10521070
.next_control_flow_position(NextControlFlowPosition::SameLine)
@@ -1202,7 +1220,7 @@ mod tests {
12021220
.if_statement_space_after_if_keyword(true)
12031221
.import_declaration_space_surrounding_named_imports(true)
12041222
.jsx_expression_container_space_surrounding_expression(true)
1205-
.jsx_space_before_self_closing_tag_slash(true)
1223+
.jsx_self_closing_element_space_before_slash(true)
12061224
.method_space_before_parentheses(true)
12071225
.object_expression_space_surrounding_properties(false)
12081226
.object_pattern_space_surrounding_properties(false)
@@ -1228,7 +1246,7 @@ mod tests {
12281246
.while_statement_space_around(true);
12291247

12301248
let inner_config = config.get_inner_config();
1231-
assert_eq!(inner_config.len(), 173);
1249+
assert_eq!(inner_config.len(), 175);
12321250
let diagnostics = resolve_config(inner_config, &resolve_global_config(ConfigKeyMap::new(), &Default::default()).config).diagnostics;
12331251
assert_eq!(diagnostics.len(), 0);
12341252
}

src/configuration/resolve_config.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,13 @@ pub fn resolve_config(config: ConfigKeyMap, global_config: &GlobalConfiguration)
3636
handle_renamed_config_property(
3737
&mut config,
3838
"jsxElement.spaceBeforeSelfClosingTagSlash",
39+
"jsxSelfClosingElement.spaceBeforeSlash",
40+
&mut diagnostics,
41+
);
42+
handle_renamed_config_property(
43+
&mut config,
3944
"jsx.spaceBeforeSelfClosingTagSlash",
45+
"jsxSelfClosingElement.spaceBeforeSlash",
4046
&mut diagnostics,
4147
);
4248

@@ -55,6 +61,7 @@ pub fn resolve_config(config: ConfigKeyMap, global_config: &GlobalConfiguration)
5561
let quote_style = get_value(&mut config, "quoteStyle", QuoteStyle::AlwaysDouble, &mut diagnostics);
5662
let quote_props = get_value(&mut config, "quoteProps", QuoteProps::Preserve, &mut diagnostics);
5763
let space_around = get_value(&mut config, "spaceAround", false, &mut diagnostics);
64+
let jsx_bracket_position = get_value(&mut config, "jsx.bracketPosition", SameOrNextLinePosition::NextLine, &mut diagnostics);
5865

5966
let resolved_config = Configuration {
6067
line_width: get_value(
@@ -91,7 +98,8 @@ pub fn resolve_config(config: ConfigKeyMap, global_config: &GlobalConfiguration)
9198
jsx_quote_style: get_value(&mut config, "jsx.quoteStyle", quote_style.to_jsx_quote_style(), &mut diagnostics),
9299
jsx_multi_line_parens: get_value(&mut config, "jsx.multiLineParens", JsxMultiLineParens::Prefer, &mut diagnostics),
93100
jsx_force_new_lines_surrounding_content: get_value(&mut config, "jsx.forceNewLinesSurroundingContent", false, &mut diagnostics),
94-
jsx_bracket_position: get_value(&mut config, "jsx.bracketPosition", SameOrNextLinePosition::NextLine, &mut diagnostics),
101+
jsx_opening_element_bracket_position: get_value(&mut config, "jsxOpeningElement.bracketPosition", jsx_bracket_position, &mut diagnostics),
102+
jsx_self_closing_element_bracket_position: get_value(&mut config, "jsxSelfClosingElement.bracketPosition", jsx_bracket_position, &mut diagnostics),
95103
member_expression_line_per_expression: get_value(&mut config, "memberExpression.linePerExpression", false, &mut diagnostics),
96104
type_literal_separator_kind_single_line: get_value(
97105
&mut config,
@@ -268,7 +276,7 @@ pub fn resolve_config(config: ConfigKeyMap, global_config: &GlobalConfiguration)
268276
if_statement_space_after_if_keyword: get_value(&mut config, "ifStatement.spaceAfterIfKeyword", true, &mut diagnostics),
269277
import_declaration_space_surrounding_named_imports: get_value(&mut config, "importDeclaration.spaceSurroundingNamedImports", true, &mut diagnostics),
270278
jsx_expression_container_space_surrounding_expression: get_value(&mut config, "jsxExpressionContainer.spaceSurroundingExpression", false, &mut diagnostics),
271-
jsx_space_before_self_closing_tag_slash: get_value(&mut config, "jsx.spaceBeforeSelfClosingTagSlash", true, &mut diagnostics),
279+
jsx_self_closing_element_space_before_slash: get_value(&mut config, "jsxSelfClosingElement.spaceBeforeSlash", true, &mut diagnostics),
272280
method_space_before_parentheses: get_value(&mut config, "method.spaceBeforeParentheses", false, &mut diagnostics),
273281
object_expression_space_surrounding_properties: get_value(
274282
&mut config,

src/configuration/types.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,10 @@ pub struct Configuration {
289289
pub jsx_multi_line_parens: JsxMultiLineParens,
290290
#[serde(rename = "jsx.forceNewLinesSurroundingContent")]
291291
pub jsx_force_new_lines_surrounding_content: bool,
292-
#[serde(rename = "jsx.bracketPosition")]
293-
pub jsx_bracket_position: SameOrNextLinePosition,
292+
#[serde(rename = "jsxOpeningElement.bracketPosition")]
293+
pub jsx_opening_element_bracket_position: SameOrNextLinePosition,
294+
#[serde(rename = "jsxSelfClosingElement.bracketPosition")]
295+
pub jsx_self_closing_element_bracket_position: SameOrNextLinePosition,
294296
#[serde(rename = "memberExpression.linePerExpression")]
295297
pub member_expression_line_per_expression: bool,
296298
#[serde(rename = "typeLiteral.separatorKind.singleLine")]
@@ -559,8 +561,8 @@ pub struct Configuration {
559561
pub import_declaration_space_surrounding_named_imports: bool,
560562
#[serde(rename = "jsxExpressionContainer.spaceSurroundingExpression")]
561563
pub jsx_expression_container_space_surrounding_expression: bool,
562-
#[serde(rename = "jsx.spaceBeforeSelfClosingTagSlash")]
563-
pub jsx_space_before_self_closing_tag_slash: bool,
564+
#[serde(rename = "jsxSelfClosingElement.spaceBeforeSlash")]
565+
pub jsx_self_closing_element_space_before_slash: bool,
564566
#[serde(rename = "method.spaceBeforeParentheses")]
565567
pub method_space_before_parentheses: bool,
566568
#[serde(rename = "objectExpression.spaceSurroundingProperties")]

src/generation/generate.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3598,7 +3598,7 @@ fn gen_jsx_namespaced_name<'a>(node: &'a JSXNamespacedName, context: &mut Contex
35983598
}
35993599

36003600
fn gen_jsx_opening_element<'a>(node: &'a JSXOpeningElement, context: &mut Context<'a>) -> PrintItems {
3601-
let space_before_self_closing_tag_slash = context.config.jsx_space_before_self_closing_tag_slash;
3601+
let space_before_self_closing_tag_slash = context.config.jsx_self_closing_element_space_before_slash;
36023602
let force_use_new_lines = get_force_is_multi_line(node, context);
36033603
let prefer_newline_before_close_bracket = get_should_prefer_newline_before_close_bracket(node, context);
36043604
let start_lsil = LineStartIndentLevel::new("openingElementStart");
@@ -3672,7 +3672,11 @@ fn gen_jsx_opening_element<'a>(node: &'a JSXOpeningElement, context: &mut Contex
36723672
}
36733673

36743674
fn get_should_prefer_newline_before_close_bracket(node: &JSXOpeningElement, context: &mut Context) -> bool {
3675-
match context.config.jsx_bracket_position {
3675+
let bracket_pos_config = match node.self_closing() {
3676+
true => context.config.jsx_self_closing_element_bracket_position,
3677+
false => context.config.jsx_opening_element_bracket_position,
3678+
};
3679+
match bracket_pos_config {
36763680
SameOrNextLinePosition::Maintain => {
36773681
if let Some(last_attr) = node.attrs.last() {
36783682
last_attr.end_line_fast(context.program) < node.end_line_fast(context.program)

tests/specs/jsx/JsxElement/JsxElement_BracketPosition_Maintain.txt renamed to tests/specs/jsx/JsxElement/JsxOpeningElement_BracketPosition_Maintain.txt

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-- file.tsx --
2-
~~ lineWidth: 50, jsx.bracketPosition: maintain ~~
2+
~~ lineWidth: 50, jsxOpeningElement.bracketPosition: maintain ~~
33
== should maintain the bracket position when there's attributes ==
44
const t = (
55
<Test
@@ -26,11 +26,6 @@ const w = (
2626
other={10}
2727
/>
2828
);
29-
const x = (
30-
<Test
31-
prop={5}
32-
other={10} />
33-
);
3429

3530
[expect]
3631
const t = (
@@ -57,11 +52,6 @@ const w = (
5752
other={10}
5853
/>
5954
);
60-
const x = (
61-
<Test
62-
prop={5}
63-
other={10} />
64-
);
6555

6656
== should maintain for single line ==
6757
const t = <MyComponent someProp={value} />;

tests/specs/jsx/JsxElement/JsxElement_BracketPosition_NextLine.txt renamed to tests/specs/jsx/JsxElement/JsxOpeningElement_BracketPosition_NextLine.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-- file.tsx --
2-
~~ lineWidth: 50, jsx.bracketPosition: nextLine ~~
2+
~~ lineWidth: 50, jsxOpeningElement.bracketPosition: nextLine ~~
33
== should move the bracket position to the next line ==
44
const t = (
55
<Test

tests/specs/jsx/JsxElement/JsxElement_BracketPosition_SameLine.txt renamed to tests/specs/jsx/JsxElement/JsxOpeningElement_BracketPosition_SameLine.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
-- file.tsx --
2-
~~ lineWidth: 50, jsx.bracketPosition: sameLine ~~
2+
~~ lineWidth: 50, jsxOpeningElement.bracketPosition: sameLine ~~
33
== should move the bracket position to the same line ==
44
const t = (
55
<Test
@@ -48,7 +48,8 @@ const v = (
4848
const w = (
4949
<Test
5050
prop={5}
51-
other={10} />
51+
other={10}
52+
/>
5253
);
5354

5455
== should maintain for single line ==
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
-- file.tsx --
2+
~~ lineWidth: 50, jsxSelfClosingElement.bracketPosition: maintain ~~
3+
== should maintain the bracket position when there's attributes ==
4+
const t = (
5+
<Test
6+
prop={5}
7+
other={10}>
8+
Test
9+
</Test>
10+
);
11+
const w = (
12+
<Test
13+
prop={5}
14+
other={10}
15+
/>
16+
);
17+
const x = (
18+
<Test
19+
prop={5}
20+
other={10} />
21+
);
22+
23+
[expect]
24+
const t = (
25+
<Test
26+
prop={5}
27+
other={10}
28+
>
29+
Test
30+
</Test>
31+
);
32+
const w = (
33+
<Test
34+
prop={5}
35+
other={10}
36+
/>
37+
);
38+
const x = (
39+
<Test
40+
prop={5}
41+
other={10} />
42+
);
43+
44+
== should maintain for single line ==
45+
const t = <MyComponent someProp={value} />;
46+
47+
[expect]
48+
const t = <MyComponent someProp={value} />;
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
-- file.tsx --
2+
~~ lineWidth: 50, jsxSelfClosingElement.bracketPosition: nextLine ~~
3+
== should move the bracket position to the next line ==
4+
const t = (
5+
<Test
6+
prop={5}
7+
other={10}>
8+
Test
9+
</Test>
10+
);
11+
const w = (
12+
<Test
13+
prop={5}
14+
other={10}
15+
/>
16+
);
17+
18+
[expect]
19+
const t = (
20+
<Test
21+
prop={5}
22+
other={10}
23+
>
24+
Test
25+
</Test>
26+
);
27+
const w = (
28+
<Test
29+
prop={5}
30+
other={10}
31+
/>
32+
);
33+
34+
== should maintain for single line ==
35+
const t = <MyComponent someProp={value} />;
36+
37+
[expect]
38+
const t = <MyComponent someProp={value} />;

0 commit comments

Comments
 (0)