diff --git a/crates/rome_js_formatter/src/jsx/lists/child_list.rs b/crates/rome_js_formatter/src/jsx/lists/child_list.rs index a8ff3a1aad51..d8433811b85a 100644 --- a/crates/rome_js_formatter/src/jsx/lists/child_list.rs +++ b/crates/rome_js_formatter/src/jsx/lists/child_list.rs @@ -6,7 +6,6 @@ use crate::utils::jsx::{ use crate::JsFormatter; use rome_formatter::{format_args, write, CstFormatContext, FormatRuleWithOptions, VecBuffer}; use rome_js_syntax::{JsxAnyChild, JsxChildList}; -use rome_rowan::TextSize; use std::cell::RefCell; #[derive(Debug, Clone, Default)] @@ -185,7 +184,7 @@ impl FormatJsxChildList { // adefg // ``` if matches!(non_text, JsxAnyChild::JsxSelfClosingElement(_)) - && word.len() != TextSize::from(1) + && !word.is_ascii_punctuation() { Some(LineMode::Hard) } else { diff --git a/crates/rome_js_formatter/src/utils/jsx.rs b/crates/rome_js_formatter/src/utils/jsx.rs index 4af72989e606..f719223b458c 100644 --- a/crates/rome_js_formatter/src/utils/jsx.rs +++ b/crates/rome_js_formatter/src/utils/jsx.rs @@ -168,7 +168,7 @@ impl Format for JsxSpace { write![ formatter, [ - if_group_breaks(&format_args![JsxRawSpace, soft_line_break()]), + if_group_breaks(&format_args![JsxRawSpace, hard_line_break()]), if_group_fits_on_line(&space()) ] ] @@ -223,7 +223,7 @@ pub(crate) fn jsx_split_children( where I: IntoIterator, { - let mut builder = JsxSplitChildrenBuilder::default(); + let mut builder = JsxSplitChildrenBuilder::new(); for child in children.into_iter() { match child { @@ -309,45 +309,31 @@ where Ok(builder.finish()) } -#[derive(Debug, Default)] +/// The builder removes [JsxChild::EmptyLine], [JsxChild::Newline], [JsxChild::Whitespace] +/// if a next element is [JsxChild::Whitespace] +/// [Prettier applies]: https://github.com/prettier/prettier/blob/b0d9387b95cdd4e9d50f5999d3be53b0b5d03a97/src/language-js/print/jsx.js#L144-L180 +#[derive(Debug)] struct JsxSplitChildrenBuilder { - pending: Option, buffer: Vec, } impl JsxSplitChildrenBuilder { - fn is_last_whitespace(&self) -> bool { - matches!(self.buffer.last(), Some(JsxChild::Whitespace)) + fn new() -> Self { + JsxSplitChildrenBuilder { buffer: vec![] } } fn entry(&mut self, child: JsxChild) { - if let Some(pending) = self.pending.take() { - if matches!( - pending, - JsxChild::EmptyLine | JsxChild::Newline | JsxChild::Whitespace - ) { - if !matches!(child, JsxChild::Whitespace) && !self.is_last_whitespace() { - self.buffer.push(pending) - } - } else { - self.buffer.push(pending); + match self.buffer.last_mut() { + Some(last @ (JsxChild::EmptyLine | JsxChild::Newline | JsxChild::Whitespace)) + if matches!(child, JsxChild::Whitespace) => + { + *last = child } + _ => self.buffer.push(child), } - - self.pending = Some(child); } - fn finish(mut self) -> Vec { - if let Some(pending) = self.pending.take() { - if matches!(pending, JsxChild::Whitespace) { - if !self.is_last_whitespace() { - self.buffer.push(pending) - } - } else { - self.buffer.push(pending); - } - } - + fn finish(self) -> Vec { self.buffer } } @@ -417,8 +403,13 @@ pub(crate) struct JsxWord { } impl JsxWord { - pub fn len(&self) -> TextSize { - self.text.len() + pub fn is_ascii_punctuation(&self) -> bool { + self.text.chars().count() == 1 + && self + .text + .chars() + .next() + .map_or(false, |char| char.is_ascii_punctuation()) } } @@ -693,7 +684,7 @@ mod tests { fn split_children_remove_in_row_jsx_whitespaces() { let child_list = parse_jsx_children(r#"a{' '}{' '}{' '}c{" "}{' '}{" "}"#); - let children = jsx_split_children(&child_list).unwrap(); + let children = jsx_split_children(&child_list, &Comments::default()).unwrap(); assert_eq!( 4, @@ -714,7 +705,7 @@ mod tests { "#, ); - let children = jsx_split_children(&child_list).unwrap(); + let children = jsx_split_children(&child_list, &Comments::default()).unwrap(); assert_eq!( 4, diff --git a/crates/rome_js_formatter/tests/specs/jsx/element.jsx b/crates/rome_js_formatter/tests/specs/jsx/element.jsx index b22afc059328..6ddad1660e11 100644 --- a/crates/rome_js_formatter/tests/specs/jsx/element.jsx +++ b/crates/rome_js_formatter/tests/specs/jsx/element.jsx @@ -93,17 +93,7 @@ b3 = 1 ; -// one length text should insert soft line break -b4 = <>
a;
-// longer than one length text should insert hard line break
-b5 = <>
ab;
-
-// one length text should insert soft line break show last jsx whitespace
-b6 = <>a{' '}bb{" "}cc{" "}dd{" "}ee{" "}{" "}{" "}{" "}{" "}{" "};
-// longer than one length text should insert hard line break
-b7 = <>longer{' '}bb{" "}cc{" "}dd{" "}ee{" "}{" "}{" "}{" "}{" "}{" "};
-
-const b8 = 
+const b4 =
Text some link {' '} diff --git a/crates/rome_js_formatter/tests/specs/jsx/element.jsx.snap b/crates/rome_js_formatter/tests/specs/jsx/element.jsx.snap index 66eb6a9be4f6..c7e24c34ea62 100644 --- a/crates/rome_js_formatter/tests/specs/jsx/element.jsx.snap +++ b/crates/rome_js_formatter/tests/specs/jsx/element.jsx.snap @@ -98,17 +98,7 @@ b3 = 1 ; -// one length text should insert soft line break -b4 = <>
a;
-// longer than one length text should insert hard line break
-b5 = <>
ab;
-
-// one length text should insert soft line break show last jsx whitespace
-b6 = <>a{' '}bb{" "}cc{" "}dd{" "}ee{" "}{" "}{" "}{" "}{" "}{" "};
-// longer than one length text should insert hard line break
-b7 = <>longer{' '}bb{" "}cc{" "}dd{" "}ee{" "}{" "}{" "}{" "}{" "}{" "};
-
-const b8 = 
+const b4 =
Text some link {' '} @@ -368,7 +358,10 @@ c2 = ( // this group should fit one line jsx whitespaces are hidden b = (
- 1 + + + + 1
); @@ -381,14 +374,17 @@ b1 = ( 12312 `} {" "} - 1 + + + 1
); // this group fit one line and hide jsx whitespace b2 = ( <> - 123 1 + 123 + 1 ); @@ -403,35 +399,7 @@ b3 = ( ); -// one length text should insert soft line break -b4 = ( - <> -
a
-	
-);
-// longer than one length text should insert hard line break
-b5 = (
-	<>
-		
-		ab
-	
-);
-
-// one length text should insert soft line break show last jsx whitespace
-b6 = (
-	<>
-		a bb cc dd ee{" "}
-	
-);
-// longer than one length text should insert hard line break
-b7 = (
-	<>
-		
-		longer bb cc dd ee{" "}
-	
-);
-
-const b8 = (
+const b4 = (
 	
Text some link @@ -649,9 +617,9 @@ const breadcrumbItems = [ 2:
; 7: tooltip="A very long tooltip text that would otherwise make the attribute break 14: - 201: "ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace", - 222: "ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace", - 235: "ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace", - 260:
-  309: 		Uncle Boonmee Who Can Recall His Past Lives dir. Apichatpong Weerasethakul{" "}
+  179: 							"ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace",
+  200: 							"ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace",
+  213: 							"ui-monospace,SFMono-Regular,SF Mono,Consolas,Liberation Mono,Menlo,monospace",
+  238: 				
+  287: 		Uncle Boonmee Who Can Recall His Past Lives dir. Apichatpong Weerasethakul{" "}
 
diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js.snap
index 054555963c5e..48e50a2cb28f 100644
--- a/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js.snap
+++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/significant-space/test.js.snap
@@ -89,25 +89,18 @@ not_broken_begin =
 ```diff
 --- Prettier
 +++ Rome
-@@ -12,7 +12,7 @@
+@@ -12,8 +12,7 @@
  
  before_break1 = (
    
 -    {" "}
-+    
-     foo
-   
- );
-@@ -21,15 +21,16 @@
-   
-     {" "}
-+    />
-     foo
+-    foo
++     foo
    
  );
  
+@@ -28,8 +27,9 @@
+ 
  after_break = (
    
 -    foo{" "}
@@ -118,43 +111,15 @@ not_broken_begin =
    
  );
  
-@@ -79,7 +80,8 @@
- 
- regression_not_transformed_2 = (
-   
--    {" "}
-+    
-+    {" "}
-   
- );
- 
-@@ -92,13 +94,15 @@
- 
- similar_2 = (
-   
--    {" "}
-+    
-+    {" "}
-   
- );
- 
- similar_3 = (
-   
--     
-+    
-+    
-   
- );
- 
-@@ -111,7 +115,8 @@
+@@ -111,7 +111,8 @@
  
  not_broken_begin = (
    
-
long text long text long text long text long text long text long text - long texturl long text long text -+
-+ long text long text long text long text long text long text long text long -+ texturl long text long text ++
long text long text long text long text long text long text long text long text ++ url ++ long text long text
); ``` @@ -176,8 +141,7 @@ before = ( before_break1 = ( - - foo + foo ); @@ -185,7 +149,7 @@ before_break2 = ( + />{" "} foo ); @@ -244,8 +208,7 @@ regression_not_transformed_1 = ( regression_not_transformed_2 = ( - - {" "} + {" "} ); @@ -258,15 +221,13 @@ similar_1 = ( similar_2 = ( - - {" "} + {" "} ); similar_3 = ( - - + ); @@ -279,12 +240,18 @@ not_broken_end = ( not_broken_begin = (
-
- long text long text long text long text long text long text long text long - texturl long text long text +
long text long text long text long text long text long text long text long text + url + long text long text
); ``` +# Lines exceeding max width of 80 characters +``` + 15: foo + 95: {" "} + 114:
long text long text long text long text long text long text long text long text +``` diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js.snap deleted file mode 100644 index bd71e968e673..000000000000 --- a/crates/rome_js_formatter/tests/specs/prettier/jsx/stateless-arrow-fn/test.js.snap +++ /dev/null @@ -1,300 +0,0 @@ ---- -source: crates/rome_js_formatter/tests/prettier_tests.rs -info: - test_file: jsx/stateless-arrow-fn/test.js ---- - -# Input - -```js -const render1 = ({ styles }) => ( -
- Keep the wrapping parens. Put each key on its own line. -
-); - -const render2 = ({ styles }) =>
- Create wrapping parens. -
; - -const render3 = ({ styles }) =>
Create wrapping parens.
; - -const render4 = ({ styles }) =>
Create wrapping parens and indent all the things.
; - -const render5 = ({ styles }) =>
Keep it on one line.
; - -const render6 = ({ styles }) => ( -
-
ddd d dd d d dddd dddd hello
-
ddd d dd d d dddd dddd hello
-
-
ddd d dd d d dddd dddd hello
hello
-
-) - -const render7 = () => -
- Dont break each elem onto its own line. -
-
- -const render7A = () => ( -
-
-
-) - -const render7B = () => ( -
- Dont break plz - Dont break plz - Dont break plz -
-) - -const render8 = (props) =>
{props.text}
-const render9 = (props) =>
{props.looooooooooooooooooooooooooooooong_text}
-const render10 = (props) =>
{props.even_looooooooooooooooooooooooooooooooooooooooooonger_contents}
- -const notJSX = (aaaaaaaaaaaaaaaaa, bbbbbbbbbbb) => this.someLongCallWithParams(aaaaaa, bbbbbbb).anotherLongCallWithParams(cccccccccccc, dddddddddddddddddddddd) - -React.render( - - , document.querySelector('#react-root') -) - - -const renderTernary = (props) => - - {props.showTheThing ? - Hello world - : "hello " + "howdy! "} - {props.showTheThing ? - Hello world - : - null - } - {props.showTheThing ? null : - Hello world - } - {props.showTheOtherThing ?
I am here
:
} - {props.showTheOtherThing ?
I am here!!
: null} - -``` - - -# Prettier differences - -```diff ---- Prettier -+++ Rome -@@ -55,7 +55,7 @@ - attr4 - > - ddd d dd d d dddd dddd hello --
{" "} -+
- hello -
-
-@@ -65,7 +65,8 @@ -
- - Dont break each elem onto its own line. --
-+
-+
-
- ); - -@@ -81,7 +82,8 @@ -
- - {" "} -- Dont break plz -+ -+ Dont break plz - - - -``` - -# Output - -```js -const render1 = ({ styles }) => ( -
- Keep the wrapping parens. Put each key on its own line. -
-); - -const render2 = ({ styles }) => ( -
- Create wrapping parens. -
-); - -const render3 = ({ styles }) => ( -
- Create wrapping parens. -
-); - -const render4 = ({ styles }) => ( -
- Create wrapping parens and indent all the things. -
-); - -const render5 = ({ styles }) =>
Keep it on one line.
; - -const render6 = ({ styles }) => ( -
-
- ddd d dd d d dddd dddd hello -
-
- ddd d dd d d dddd dddd hello -
-
-
- ddd d dd d d dddd dddd hello -
- hello -
-
-); - -const render7 = () => ( -
- - Dont break each elem onto its own line. -
-
-
-); - -const render7A = () => ( -
-
-
-
-
-); - -const render7B = () => ( -
- - {" "} - - Dont break plz - - - - Dont break plz - - - Dont break plz - - -
-); - -const render8 = (props) =>
{props.text}
; -const render9 = (props) => ( -
{props.looooooooooooooooooooooooooooooong_text}
-); -const render10 = (props) => ( -
- {props.even_looooooooooooooooooooooooooooooooooooooooooonger_contents} -
-); - -const notJSX = (aaaaaaaaaaaaaaaaa, bbbbbbbbbbb) => - this.someLongCallWithParams(aaaaaa, bbbbbbb).anotherLongCallWithParams( - cccccccccccc, - dddddddddddddddddddddd, - ); - -React.render( - , - document.querySelector("#react-root"), -); - -const renderTernary = (props) => ( - - {props.showTheThing ? ( - - Hello world - - ) : ( - "hello " + "howdy! " - )} - {props.showTheThing ? ( - - Hello world - - ) : null} - {props.showTheThing ? null : ( - - Hello world - - )} - {props.showTheOtherThing ?
I am here
:
} - {props.showTheOtherThing ?
I am here!!
: null} - -); -``` - - - diff --git a/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js.snap b/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js.snap index 03eb80216919..7974ac96d6ee 100644 --- a/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js.snap +++ b/crates/rome_js_formatter/tests/specs/prettier/jsx/text-wrap/test.js.snap @@ -481,12 +481,12 @@ let myDiv = ReactTestUtils.renderIntoDocument( - f f + f f f f + f -+ ++ {" "} + f
); -@@ -32,15 +34,16 @@ +@@ -32,16 +34,18 @@ @@ -502,11 +502,14 @@ let myDiv = ReactTestUtils.renderIntoDocument( x = (
- {" "} -+ - f +- f ++ ++ f ++
); -@@ -66,15 +69,19 @@ + +@@ -66,15 +70,18 @@ x = (
@@ -514,8 +517,7 @@ let myDiv = ReactTestUtils.renderIntoDocument( - {stuff} {stuff} {stuff} after {stuff} after + before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after { + stuff -+ } -+ {stuff} {stuff} after {stuff} after ++ } {stuff} {stuff} after {stuff} after
); @@ -525,12 +527,22 @@ let myDiv = ReactTestUtils.renderIntoDocument( - school directors. + Please state your name and occupation for the board of + school -+ ++
{" "} + directors.
); -@@ -101,9 +108,10 @@ +@@ -89,8 +96,7 @@ + . +

+

+- Note: last_modified and schema record +- metadata are omitted for easier review. ++ Note: last_modified and schema record metadata are omitted for easier review. +

+
+ +@@ -101,9 +107,10 @@ x = ( @@ -539,12 +551,12 @@ let myDiv = ReactTestUtils.renderIntoDocument( - {graphActivity.startTime + graphActivity.length} + Starting at minute {graphActivity.startTime}, running for { + graphActivity.length -+ } ++ }{" "} + to minute {graphActivity.startTime + graphActivity.length} ); -@@ -176,19 +184,17 @@ +@@ -176,19 +183,17 @@ unstable_before = (
@@ -570,7 +582,7 @@ let myDiv = ReactTestUtils.renderIntoDocument(
); -@@ -213,24 +219,22 @@ +@@ -213,8 +218,7 @@ jsx_around_multiline_element = (
@@ -580,11 +592,7 @@ let myDiv = ReactTestUtils.renderIntoDocument( { "Enough text to make this element wrap on to multiple lines when formatting" } --
{" "} -+
- After -
- ); +@@ -225,8 +229,7 @@ jsx_around_multiline_element_second_pass = (
@@ -594,26 +602,19 @@ let myDiv = ReactTestUtils.renderIntoDocument( { "Enough text to make this element wrap on to multiple lines when formatting" } --
{" "} -+
- After -
- ); -@@ -251,8 +255,11 @@ +@@ -251,8 +254,9 @@ const Abc = () => { return (
- Please state your name and occupation for the board of - directors. -+ Please state your -+ {" "}name -+ and -+ {" "}occupation ++ Please state your name ++ and occupation + for the board of directors.
); }; -@@ -318,19 +325,25 @@ +@@ -318,7 +322,11 @@ line_after_br_2 = (
@@ -626,14 +627,7 @@ let myDiv = ReactTestUtils.renderIntoDocument(
); - br_followed_by_whitespace = ( -
--
text -+
-+ text -
- ); - +@@ -331,6 +339,7 @@ dont_preserve_blank_lines_when_jsx_contains_text = (
Zeroth
@@ -641,7 +635,7 @@ let myDiv = ReactTestUtils.renderIntoDocument(
First
Second
-@@ -346,15 +359,18 @@ +@@ -346,15 +355,17 @@ single_expression_child_tags = (
@@ -659,32 +653,22 @@ let myDiv = ReactTestUtils.renderIntoDocument( - {this.props.type}{" "} + texty text text text text text text text text text text text { + this.props.type -+ } -+ {" "} ++ }{" "}
); -@@ -362,9 +378,8 @@ +@@ -362,9 +373,7 @@ br_triggers_expression_break = (

- text text text text text text text text text text text { - this.props.type - }{" "} -+ text text text text text text text text text text text {this.props.type} -+ {" "} ++ text text text text text text text text text text text {this.props.type}{" "}
); -@@ -372,14 +387,14 @@ -
- - {variable} -- {" "} -+ - ({variable}) -
- ); +@@ -379,7 +388,7 @@ x = (
@@ -693,19 +677,18 @@ let myDiv = ReactTestUtils.renderIntoDocument( HRS
); -@@ -404,8 +419,9 @@ +@@ -404,8 +413,8 @@
- Line {startRange.row + 1}:{startRange.column + 1} -{" "} - {endRange.row + 1}:{endRange.column + 1} + Line {startRange.row + 1}:{startRange.column + 1} - {endRange.row + -+ 1} -+ :{endRange.column + 1} ++ 1}:{endRange.column + 1} {caller}
-@@ -436,13 +452,16 @@ +@@ -436,13 +445,16 @@ x = (
@@ -724,7 +707,7 @@ let myDiv = ReactTestUtils.renderIntoDocument(
); -@@ -496,19 +515,26 @@ +@@ -496,19 +508,26 @@ x = (
@@ -754,7 +737,7 @@ let myDiv = ReactTestUtils.renderIntoDocument(
); -@@ -528,7 +554,8 @@ +@@ -528,7 +547,8 @@ {name}’s{" "} @@ -764,16 +747,6 @@ let myDiv = ReactTestUtils.renderIntoDocument( You {type}ed this shipment to
); -@@ -564,7 +591,8 @@ - - let myDiv = ReactTestUtils.renderIntoDocument( -
--
, -+
-+ , -
-
, - ); ``` # Output @@ -792,7 +765,7 @@ x = (
f f f f f - + {" "} f
); @@ -824,8 +797,9 @@ x = ( // Wrapping tags x = (
- - f + + f +
); @@ -852,8 +826,7 @@ x = (
before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after { stuff - } - {stuff} {stuff} after {stuff} after + } {stuff} {stuff} after {stuff} after
); @@ -861,7 +834,7 @@ x = (
Please state your name and occupation for the board of school - + {" "} directors.
); @@ -877,8 +850,7 @@ function DiffOverview(props) { .

- Note: last_modified and schema record - metadata are omitted for easier review. + Note: last_modified and schema record metadata are omitted for easier review.

@@ -891,7 +863,7 @@ x = ( Starting at minute {graphActivity.startTime}, running for { graphActivity.length - } + }{" "} to minute {graphActivity.startTime + graphActivity.length} @@ -1004,7 +976,7 @@ jsx_around_multiline_element = ( { "Enough text to make this element wrap on to multiple lines when formatting" } -
+
{" "} After
); @@ -1015,7 +987,7 @@ jsx_around_multiline_element_second_pass = ( { "Enough text to make this element wrap on to multiple lines when formatting" } -
+
{" "} After
); @@ -1036,10 +1008,8 @@ x = ( const Abc = () => { return (
- Please state your - {" "}name - and - {" "}occupation + Please state your name + and occupation for the board of directors.
); @@ -1116,8 +1086,7 @@ line_after_br_2 = ( br_followed_by_whitespace = (
-
- text +
text
); @@ -1150,8 +1119,7 @@ expression_does_not_break = (
texty text text text text text text text text text text text { this.props.type - } - {" "} + }{" "}
); @@ -1159,8 +1127,7 @@ expression_does_not_break = ( br_triggers_expression_break = (

- text text text text text text text text text text text {this.props.type} - {" "} + text text text text text text text text text text text {this.props.type}{" "}
); @@ -1168,7 +1135,7 @@ jsx_whitespace_after_tag = (
{variable} - + {" "} ({variable})
); @@ -1201,8 +1168,7 @@ x = (
Line {startRange.row + 1}:{startRange.column + 1} - {endRange.row + - 1} - :{endRange.column + 1} + 1}:{endRange.column + 1} {caller}
@@ -1372,8 +1338,7 @@ this_really_should_split_across_lines = ( let myDiv = ReactTestUtils.renderIntoDocument(
-
- , +
,
, ); @@ -1382,9 +1347,11 @@ let myDiv = ReactTestUtils.renderIntoDocument( # Lines exceeding max width of 80 characters ``` - 72: before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after { - 122:
- 224: "Enough text to make this element wrap on to multiple lines when formatting" - 235: "Enough text to make this element wrap on to multiple lines when formatting" + 73: before {stuff} after {stuff} after {stuff} after {stuff} after {stuff} after { + 99: Note: last_modified and schema record metadata are omitted for easier review. + 121:
+ 223: "Enough text to make this element wrap on to multiple lines when formatting" + 234: "Enough text to make this element wrap on to multiple lines when formatting" + 376: text text text text text text text text text text text {this.props.type}{" "} ```