diff --git a/CHANGELOG.md b/CHANGELOG.md
index facc5f0d36..ec807a97d3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,10 @@
# 12.0.0-alpha.9 (Unreleased)
+#### :nail_care: Polish
+
+- Allow single newline in JSX. https://github.com/rescript-lang/rescript/pull/7269
+
# 12.0.0-alpha.8
#### :bug: Bug fix
diff --git a/compiler/syntax/src/res_printer.ml b/compiler/syntax/src/res_printer.ml
index 0b887d74fd..9b313a00ea 100644
--- a/compiler/syntax/src/res_printer.ml
+++ b/compiler/syntax/src/res_printer.ml
@@ -4429,33 +4429,51 @@ and print_jsx_children ~state (children_expr : Parsetree.expression) ~sep
match children_expr.pexp_desc with
| Pexp_construct ({txt = Longident.Lident "::"}, _) ->
let children, _ = ParsetreeViewer.collect_list_expressions children_expr in
- Doc.group
- (Doc.join ~sep
- (List.map
- (fun (expr : Parsetree.expression) ->
- let leading_line_comment_present =
- has_leading_line_comment cmt_tbl expr.pexp_loc
- in
- let expr_doc =
- print_expression_with_comments ~state expr cmt_tbl
- in
- let add_parens_or_braces expr_doc =
- (* {(20: int)} make sure that we also protect the expression inside *)
- let inner_doc =
- if Parens.braced_expr expr then add_parens expr_doc
- else expr_doc
- in
- if leading_line_comment_present then add_braces inner_doc
- else Doc.concat [Doc.lbrace; inner_doc; Doc.rbrace]
- in
- match Parens.jsx_child_expr expr with
- | Nothing -> expr_doc
- | Parenthesized -> add_parens_or_braces expr_doc
- | Braced braces_loc ->
- print_comments
- (add_parens_or_braces expr_doc)
- cmt_tbl braces_loc)
- children))
+ let print_expr (expr : Parsetree.expression) =
+ let leading_line_comment_present =
+ has_leading_line_comment cmt_tbl expr.pexp_loc
+ in
+ let expr_doc = print_expression_with_comments ~state expr cmt_tbl in
+ let add_parens_or_braces expr_doc =
+ (* {(20: int)} make sure that we also protect the expression inside *)
+ let inner_doc =
+ if Parens.braced_expr expr then add_parens expr_doc else expr_doc
+ in
+ if leading_line_comment_present then add_braces inner_doc
+ else Doc.concat [Doc.lbrace; inner_doc; Doc.rbrace]
+ in
+ match Parens.jsx_child_expr expr with
+ | Nothing -> expr_doc
+ | Parenthesized -> add_parens_or_braces expr_doc
+ | Braced braces_loc ->
+ print_comments (add_parens_or_braces expr_doc) cmt_tbl braces_loc
+ in
+ let get_first_leading_comment loc =
+ match get_first_leading_comment cmt_tbl loc with
+ | None -> loc
+ | Some comment -> Comment.loc comment
+ in
+ let get_loc expr =
+ match ParsetreeViewer.process_braces_attr expr with
+ | None, _ -> get_first_leading_comment expr.pexp_loc
+ | Some ({loc}, _), _ -> get_first_leading_comment loc
+ in
+ let rec loop prev acc exprs =
+ match exprs with
+ | [] -> List.rev acc
+ | expr :: tails ->
+ let start_loc = (get_loc expr).loc_start.pos_lnum in
+ let end_loc = (get_loc prev).loc_end.pos_lnum in
+ let expr_doc = print_expr expr in
+ let docs =
+ if start_loc - end_loc > 1 then
+ Doc.concat [Doc.hard_line; expr_doc] :: acc
+ else expr_doc :: acc
+ in
+ loop expr docs tails
+ in
+ let docs = loop children_expr [] children in
+ Doc.group (Doc.join ~sep docs)
| _ ->
let leading_line_comment_present =
has_leading_line_comment cmt_tbl children_expr.pexp_loc
diff --git a/tests/syntax_tests/data/printer/expr/expected/jsx.res.txt b/tests/syntax_tests/data/printer/expr/expected/jsx.res.txt
index 2384f5ecb6..5df8ca4e5a 100644
--- a/tests/syntax_tests/data/printer/expr/expected/jsx.res.txt
+++ b/tests/syntax_tests/data/printer/expr/expected/jsx.res.txt
@@ -351,6 +351,7 @@ module App = {
// comment
content
}
+
{
// comment
if condition() {
@@ -460,3 +461,67 @@ let x = {
let _ =