Improve JSX output when there is a single expression (#2274)
parent
95a5f11be9
commit
be600337eb
|
@ -3739,7 +3739,7 @@ function printJSXChildren(path, options, print, jsxWhitespace) {
|
|||
children.push(jsxWhitespace);
|
||||
}
|
||||
} else {
|
||||
// Ideally this would be a `softline` to allow a break between
|
||||
// Ideally this would be a `hardline` to allow a break between
|
||||
// tags and text.
|
||||
// Unfortunately Facebook have a custom translation pipeline
|
||||
// (https://github.com/prettier/prettier/issues/1581#issuecomment-300975032)
|
||||
|
@ -3762,23 +3762,14 @@ function printJSXChildren(path, options, print, jsxWhitespace) {
|
|||
children.push(jsxWhitespace);
|
||||
}
|
||||
} else {
|
||||
// Convert `{" "}` to jsxWhitespace so it can be printed as a standard
|
||||
// space if needed.
|
||||
if (isJSXWhitespaceExpression(child)) {
|
||||
children.push("");
|
||||
children.push(jsxWhitespace);
|
||||
return;
|
||||
}
|
||||
|
||||
const printedChild = print(childPath);
|
||||
children.push(printedChild);
|
||||
|
||||
const next = n.children[i + 1];
|
||||
const directlyFollowedByMeaningfulText =
|
||||
next && isMeaningfulJSXText(next) && !/^[ \n\r\t]/.test(rawText(next));
|
||||
const followedByJSXWhitespace = next && isJSXWhitespaceExpression(next);
|
||||
if (directlyFollowedByMeaningfulText || followedByJSXWhitespace) {
|
||||
// Potentially this could be a softline as well.
|
||||
if (directlyFollowedByMeaningfulText) {
|
||||
// Potentially this could be a hardline as well.
|
||||
// See the comment above about the Facebook translation pipeline as
|
||||
// to why this is an empty string.
|
||||
children.push("");
|
||||
|
@ -3837,11 +3828,30 @@ function printJSXElement(path, options, print) {
|
|||
return openingLines;
|
||||
}
|
||||
|
||||
// Convert `{" "}` to text nodes containing a space.
|
||||
// This makes it easy to turn them into `jsxWhitespace` which
|
||||
// can then print as either a space or `{" "}` when breaking.
|
||||
n.children = n.children.map(child => {
|
||||
if (isJSXWhitespaceExpression(child)) {
|
||||
return {
|
||||
type: "JSXText",
|
||||
value: " ",
|
||||
raw: " "
|
||||
};
|
||||
}
|
||||
return child;
|
||||
});
|
||||
|
||||
const parent = path.getParentNode();
|
||||
const parentContainsText =
|
||||
parent.type === "JSXElement" &&
|
||||
parent.children.filter(child => isMeaningfulJSXText(child)).length > 0;
|
||||
|
||||
const containsTag =
|
||||
n.children.filter(child => child.type === "JSXElement").length > 0;
|
||||
const containsMultipleExpressions =
|
||||
n.children.filter(child => child.type === "JSXExpressionContainer").length >
|
||||
1;
|
||||
const numExpressions = n.children.filter(
|
||||
child => child.type === "JSXExpressionContainer"
|
||||
).length;
|
||||
const containsMultipleAttributes = n.openingElement.attributes.length > 1;
|
||||
|
||||
// Record any breaks. Should never go from true to false, only false to true.
|
||||
|
@ -3849,7 +3859,7 @@ function printJSXElement(path, options, print) {
|
|||
willBreak(openingLines) ||
|
||||
containsTag ||
|
||||
containsMultipleAttributes ||
|
||||
containsMultipleExpressions;
|
||||
(parentContainsText ? numExpressions > 1 : numExpressions > 0);
|
||||
|
||||
const rawJsxWhitespace = options.singleQuote ? "{' '}" : '{" "}';
|
||||
const jsxWhitespace = ifBreak(concat([rawJsxWhitespace, softline]), " ");
|
||||
|
|
|
@ -304,7 +304,10 @@ export const bem = block =>
|
|||
<FlatList
|
||||
renderItem={(
|
||||
info // $FlowExpectedError - bad widgetCount type 6, should be Object
|
||||
) => <span>{info.item.widget.missingProp}</span>}
|
||||
) =>
|
||||
<span>
|
||||
{info.item.widget.missingProp}
|
||||
</span>}
|
||||
data={data}
|
||||
/>;
|
||||
|
||||
|
|
|
@ -497,7 +497,9 @@ Observable.of(process)
|
|||
.takeUntil(exit);
|
||||
|
||||
// Comments disappear inside of JSX
|
||||
<div>{/* Some comment */}</div>;
|
||||
<div>
|
||||
{/* Some comment */}
|
||||
</div>;
|
||||
|
||||
// Comments in JSX tag are placed in a non optimal way
|
||||
<div
|
||||
|
@ -596,15 +598,23 @@ exports[`jsx.js 1`] = `
|
|||
|
||||
<div>{/*<div> Some very v ery very very long line to break line width limit </div>*/}</div>;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
<div>{/* comment */}</div>;
|
||||
<div>
|
||||
{/* comment */}
|
||||
</div>;
|
||||
|
||||
<div>{/* comment */}</div>;
|
||||
<div>
|
||||
{/* comment */}
|
||||
</div>;
|
||||
|
||||
<div>{/* comment
|
||||
*/}</div>;
|
||||
<div>
|
||||
{/* comment
|
||||
*/}
|
||||
</div>;
|
||||
|
||||
<div>{a /* comment
|
||||
*/}</div>;
|
||||
<div>
|
||||
{a /* comment
|
||||
*/}
|
||||
</div>;
|
||||
|
||||
<div>
|
||||
{
|
||||
|
@ -614,9 +624,13 @@ exports[`jsx.js 1`] = `
|
|||
}
|
||||
</div>;
|
||||
|
||||
<div>{/* comment */}</div>;
|
||||
<div>
|
||||
{/* comment */}
|
||||
</div>;
|
||||
|
||||
<div>{/* comment */}</div>;
|
||||
<div>
|
||||
{/* comment */}
|
||||
</div>;
|
||||
|
||||
<div>
|
||||
{
|
||||
|
|
|
@ -222,8 +222,12 @@ declare function ExpectsProps(props: { name: string }, children: any): string;
|
|||
declare function ExpectsChildrenTuple(props: any, children: [string]): string;
|
||||
<ExpectsChildrenTuple />; // Error - mising child
|
||||
<ExpectsChildrenTuple>Hi</ExpectsChildrenTuple>; // No error
|
||||
<ExpectsChildrenTuple>{123}</ExpectsChildrenTuple>; // Error: number ~> string
|
||||
<ExpectsChildrenTuple>Hi {"there"}</ExpectsChildrenTuple>; // Error: too many children
|
||||
<ExpectsChildrenTuple>
|
||||
{123}
|
||||
</ExpectsChildrenTuple>; // Error: number ~> string
|
||||
<ExpectsChildrenTuple>
|
||||
Hi {"there"}
|
||||
</ExpectsChildrenTuple>; // Error: too many children
|
||||
|
||||
declare function ExpectsChildrenArray(
|
||||
props: any,
|
||||
|
@ -231,8 +235,12 @@ declare function ExpectsChildrenArray(
|
|||
): string;
|
||||
<ExpectsChildrenArray />; // No error - 0 children is fine
|
||||
<ExpectsChildrenArray>Hi</ExpectsChildrenArray>; // No error - 1 child is fine
|
||||
<ExpectsChildrenArray>{123}</ExpectsChildrenArray>; // Error: number ~> string
|
||||
<ExpectsChildrenArray>Hi {"there"}</ExpectsChildrenArray>; // No error - 2 children is fine
|
||||
<ExpectsChildrenArray>
|
||||
{123}
|
||||
</ExpectsChildrenArray>; // Error: number ~> string
|
||||
<ExpectsChildrenArray>
|
||||
Hi {"there"}
|
||||
</ExpectsChildrenArray>; // No error - 2 children is fine
|
||||
|
||||
`;
|
||||
|
||||
|
|
|
@ -793,7 +793,11 @@ class Example extends React.Component {
|
|||
props: { bar: string };
|
||||
|
||||
render() {
|
||||
return <div>{this.props.bar}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.props.bar}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -865,7 +869,11 @@ var ReactClass = React.createClass({
|
|||
render: function(): any {
|
||||
// Any state access here seems to make state any
|
||||
this.state;
|
||||
return <div>{this.state.bar.qux}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.state.bar.qux}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -973,7 +981,11 @@ var C = React.createClass({
|
|||
|
||||
render() {
|
||||
this.setState({ y: 0 });
|
||||
return <div>{this.state.z}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.state.z}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -741,7 +741,11 @@ class Bar extends React.Component {
|
|||
test: number
|
||||
};
|
||||
render() {
|
||||
return <div>{this.props.test}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.props.test}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1619,9 +1623,17 @@ var Example = React.createClass({
|
|||
},
|
||||
render() {
|
||||
if (typeof this.props.prop === "string") {
|
||||
return <div>{this.props.prop}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.props.prop}
|
||||
</div>
|
||||
);
|
||||
} else {
|
||||
return <div>{this.props.prop.toFixed(2)}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.props.prop.toFixed(2)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -38,7 +38,11 @@ var HelloLocal = React.createClass({
|
|||
},
|
||||
|
||||
render: function(): React.Element<*> {
|
||||
return <div>{this.props.name}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.props.name}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -82,7 +86,11 @@ var Hello = React.createClass({
|
|||
},
|
||||
|
||||
render: function(): React.Element<*> {
|
||||
return <div>{this.props.name}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.props.name}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -128,7 +136,11 @@ class HelloLocal extends React.Component<void, { name: string }, void> {
|
|||
name: React.PropTypes.string.isRequired
|
||||
};
|
||||
render(): React.Element<*> {
|
||||
return <div>{this.props.name}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.props.name}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -174,7 +186,11 @@ class Hello extends React.Component<void, { name: string }, void> {
|
|||
};
|
||||
|
||||
render(): React.Element<*> {
|
||||
return <div>{this.props.name}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.props.name}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -220,7 +236,11 @@ class HelloLocal extends React.Component<void, Props, void> {
|
|||
props: Props;
|
||||
|
||||
render(): React.Element<*> {
|
||||
return <div>{this.props.name}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.props.name}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -266,7 +286,11 @@ class Hello extends React.Component<{}, Props, void> {
|
|||
static defaultProps: {};
|
||||
|
||||
render(): React.Element<*> {
|
||||
return <div>{this.props.name}</div>;
|
||||
return (
|
||||
<div>
|
||||
{this.props.name}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -160,9 +160,14 @@ const render7B = () =>
|
|||
</span>
|
||||
</div>;
|
||||
|
||||
const render8 = props => <div>{props.text}</div>;
|
||||
const render8 = props =>
|
||||
<div>
|
||||
{props.text}
|
||||
</div>;
|
||||
const render9 = props =>
|
||||
<div>{props.looooooooooooooooooooooooooooooong_text}</div>;
|
||||
<div>
|
||||
{props.looooooooooooooooooooooooooooooong_text}
|
||||
</div>;
|
||||
const render10 = props =>
|
||||
<div>
|
||||
{props.even_looooooooooooooooooooooooooooooooooooooooooonger_contents}
|
||||
|
|
|
@ -284,7 +284,9 @@ const els = items.map(item => (
|
|||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
const els = items.map(item =>
|
||||
<div className="whatever">
|
||||
<span>{children}</span>
|
||||
<span>
|
||||
{children}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
|
|
@ -38,9 +38,15 @@ const MyCoolList = ({ things }) =>
|
|||
|
||||
const MyCoolThing = ({ thingo }) => <li>{thingo}</li>;
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
const MyCoolList = ({ things }) => <ul>{things.map(MyCoolThing)}</ul>;
|
||||
const MyCoolList = ({ things }) =>
|
||||
<ul>
|
||||
{things.map(MyCoolThing)}
|
||||
</ul>;
|
||||
|
||||
const MyCoolThing = ({ thingo }) => <li>{thingo}</li>;
|
||||
const MyCoolThing = ({ thingo }) =>
|
||||
<li>
|
||||
{thingo}
|
||||
</li>;
|
||||
|
||||
`;
|
||||
|
||||
|
|
Loading…
Reference in New Issue