Skip to content

Commit 41a8130

Browse files
committed
feat: JSX opening and self-closing elements with a single string attribute should not go multi-line
Closes #293
1 parent d5ce354 commit 41a8130

File tree

2 files changed

+54
-2
lines changed

2 files changed

+54
-2
lines changed

src/parsing/parser.rs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3256,7 +3256,14 @@ fn parse_jsx_opening_element<'a>(node: &'a JSXOpeningElement, context: &mut Cont
32563256
items.extend(parse_node(type_args.into(), context));
32573257
}
32583258

3259-
if !node.attrs.is_empty() {
3259+
let single_line_space_at_end = node.self_closing() && space_before_self_closing_tag_slash;
3260+
if node.attrs.len() == 1 && node.type_args.is_none() && is_jsx_attr_with_string(&node.attrs[0]) {
3261+
items.push_str(" ");
3262+
items.extend(parse_node(node.attrs[0].into(), context));
3263+
if single_line_space_at_end {
3264+
items.push_str(" ");
3265+
}
3266+
} else if !node.attrs.is_empty() {
32603267
items.extend(parse_separated_values(
32613268
ParseSeparatedValuesParams {
32623269
nodes: node.attrs.iter().map(|p| NodeOrSeparator::Node(p.into())).collect(),
@@ -3265,7 +3272,7 @@ fn parse_jsx_opening_element<'a>(node: &'a JSXOpeningElement, context: &mut Cont
32653272
allow_blank_lines: false,
32663273
separator: Separator::none(),
32673274
single_line_space_at_start: true,
3268-
single_line_space_at_end: node.self_closing() && space_before_self_closing_tag_slash,
3275+
single_line_space_at_end,
32693276
custom_single_line_separator: None,
32703277
multi_line_options: parser_helpers::MultiLineOptions::surround_newlines_indented(),
32713278
force_possible_newline_at_start: false,
@@ -3312,6 +3319,15 @@ fn parse_jsx_opening_element<'a>(node: &'a JSXOpeningElement, context: &mut Cont
33123319
false
33133320
}
33143321
}
3322+
3323+
fn is_jsx_attr_with_string(node: &JSXAttrOrSpread) -> bool {
3324+
if let JSXAttrOrSpread::JSXAttr(attrib) = node {
3325+
if let Some(value) = attrib.value {
3326+
return value.kind() == NodeKind::Str;
3327+
}
3328+
}
3329+
return false;
3330+
}
33153331
}
33163332

33173333
fn parse_jsx_opening_fragment<'a>(_: &'a JSXOpeningFragment, _: &mut Context<'a>) -> PrintItems {

tests/specs/jsx/JsxElement/JsxElement_All.txt

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,3 +220,39 @@ return <E>Test: {type}</E>;
220220
return <E>Test: {type}</E>;
221221
return <E>{type} test</E>;
222222
return <E>{type} test</E>;
223+
224+
== should keep multi-line jsx element with single string attribute on same line ==
225+
const t = (
226+
<Element test="testing this out with some string that is long">
227+
Test
228+
</Element>
229+
);
230+
const u = (
231+
<Element test="testing this out with some string that is long" />
232+
);
233+
234+
[expect]
235+
const t = (
236+
<Element test="testing this out with some string that is long">
237+
Test
238+
</Element>
239+
);
240+
const u = (
241+
<Element test="testing this out with some string that is long" />
242+
);
243+
244+
== should not keep long multi-line jsx element with single string attribute on same line when has type arg ==
245+
const t = (
246+
<Element<arg> test="testing this out with some string that is long">
247+
Test
248+
</Element>
249+
);
250+
251+
[expect]
252+
const t = (
253+
<Element<arg>
254+
test="testing this out with some string that is long"
255+
>
256+
Test
257+
</Element>
258+
);

0 commit comments

Comments
 (0)