Skip to content

Commit 2a07d5e

Browse files
committed
fix(formatting): trailing space
Closes #135 BREAKING CHANGE: Trailing are now preserved. In some rare case, `react-element-to-jsx-string` failed to respect the JSX specs for the trailing space. Event is the space were in the final output. There were silentrly ignored by JSX parser. This commit fix this bug by protecting the trailing space in the output. If we take the JSX: ```jsx <div> foo <strong>bar</strong> baz </div> ``` Before it was converted to (the trailing space are replace by `*` for the readability): ```html <div> foo* <strong> bar </strong> *baz </div> ``` Now there are preserved: ```html <div> foo{' '} <strong> bar </strong> {' '}baz </div> ```
1 parent 2747f1b commit 2a07d5e

File tree

3 files changed

+36
-3
lines changed

3 files changed

+36
-3
lines changed

src/formatter/formatProp.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export default (
3939
formattedPropValue === '{false}' &&
4040
!hasDefaultValue
4141
) {
42-
// If a boolean is false an is not different from it's default, we do not render the attribute
42+
// If a boolean is false and not different from it's default, we do not render the attribute
4343
attributeFormattedInline = '';
4444
attributeFormattedMultiline = '';
4545
} else if (useBooleanShorthandSyntax && formattedPropValue === '{true}') {

src/formatter/formatTreeNode.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,19 @@ const escape = (s: string) => {
1616
return `{\`${s}\`}`;
1717
};
1818

19+
const preserveTrailingSpace = (s: string) => {
20+
let result = s;
21+
if (result.endsWith(' ')) {
22+
result = result.replace(/^(\S*)(\s*)$/, "$1{'$2'}");
23+
}
24+
25+
if (result.startsWith(' ')) {
26+
result = result.replace(/^(\s*)(\S*)$/, "{'$1'}$2");
27+
}
28+
29+
return result;
30+
};
31+
1932
export default (
2033
node: TreeNode,
2134
inline: boolean,
@@ -27,7 +40,9 @@ export default (
2740
}
2841

2942
if (node.type === 'string') {
30-
return node.value ? escape(String(node.value)) : '';
43+
return node.value
44+
? `${preserveTrailingSpace(escape(String(node.value)))}`
45+
: '';
3146
}
3247

3348
if (node.type === 'ReactElement') {

src/index.spec.js

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -556,6 +556,22 @@ describe('reactElementToJSXString(ReactElement)', () => {
556556
);
557557
});
558558

559+
it('reactElementToJSXString(<div>\nfoo <span>bar</span> baz\n</div>)', () => {
560+
expect(
561+
reactElementToJSXString(
562+
<div>
563+
foo <span>bar</span> baz
564+
</div>
565+
)
566+
).toEqual(`<div>
567+
foo{' '}
568+
<span>
569+
bar
570+
</span>
571+
{' '}baz
572+
</div>`);
573+
});
574+
559575
it('reactElementToJSXString(<div a={[1, 2, 3, 4]} />', () => {
560576
expect(reactElementToJSXString(<div a={[1, 2, 3, 4]} />)).toEqual(
561577
`<div
@@ -722,7 +738,9 @@ describe('reactElementToJSXString(ReactElement)', () => {
722738

723739
it('reactElementToJSXString(<div> {false} </div>)', () => {
724740
expect(reactElementToJSXString(<div> {false} </div>)).toEqual(
725-
'<div>\n \n</div>'
741+
`<div>
742+
{' '}
743+
</div>`
726744
);
727745
});
728746

0 commit comments

Comments
 (0)