@tsrx/prettier-plugin 0.3.26 → 0.3.28
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/index.js +36 -24
- package/src/index.test.js +65 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsrx/prettier-plugin",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.28",
|
|
4
4
|
"description": "Ripple plugin for Prettier",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "src/index.js",
|
|
@@ -26,11 +26,11 @@
|
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^24.3.0",
|
|
28
28
|
"prettier": "^3.8.3",
|
|
29
|
-
"ripple": "0.3.
|
|
29
|
+
"ripple": "0.3.28"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@tsrx/core": "0.0.
|
|
33
|
-
"@tsrx/ripple": "0.0.
|
|
32
|
+
"@tsrx/core": "0.0.8",
|
|
33
|
+
"@tsrx/ripple": "0.0.10"
|
|
34
34
|
},
|
|
35
35
|
"files": [
|
|
36
36
|
"src/"
|
package/src/index.js
CHANGED
|
@@ -6047,35 +6047,47 @@ function printElement(element, path, options, print) {
|
|
|
6047
6047
|
|
|
6048
6048
|
const hasOpeningTagComments = openingTagCommentsSet.size > 0;
|
|
6049
6049
|
let attrIndex = 0;
|
|
6050
|
+
let hasBreakingAttribute = false;
|
|
6051
|
+
const attrDocs = hasAttributes
|
|
6052
|
+
? path.map((attrPath) => {
|
|
6053
|
+
const idx = attrIndex++;
|
|
6054
|
+
const commentsForAttr = openingTagCommentsByAttrIndex.get(idx);
|
|
6055
|
+
/** @type {Doc[]} */
|
|
6056
|
+
const parts = [];
|
|
6057
|
+
if (commentsForAttr) {
|
|
6058
|
+
for (const comment of commentsForAttr) {
|
|
6059
|
+
// Line comments (//) consume the rest of the line, so they must
|
|
6060
|
+
// use hardline to force a break. Block comments can use normal breaks.
|
|
6061
|
+
if (comment.type === 'Line') {
|
|
6062
|
+
parts.push(hardline);
|
|
6063
|
+
parts.push('//' + comment.value);
|
|
6064
|
+
} else if (comment.type === 'Block') {
|
|
6065
|
+
parts.push(attrLineBreak);
|
|
6066
|
+
parts.push('/*' + comment.value + '*/');
|
|
6067
|
+
}
|
|
6068
|
+
}
|
|
6069
|
+
}
|
|
6070
|
+
parts.push(attrLineBreak);
|
|
6071
|
+
const attrDoc = print(attrPath);
|
|
6072
|
+
parts.push(attrDoc);
|
|
6073
|
+
if (!hasBreakingAttribute && willBreak(attrDoc)) {
|
|
6074
|
+
hasBreakingAttribute = true;
|
|
6075
|
+
}
|
|
6076
|
+
return parts;
|
|
6077
|
+
}, 'attributes')
|
|
6078
|
+
: [];
|
|
6079
|
+
const shouldForceBreak = hasOpeningTagComments || hasBreakingAttribute;
|
|
6050
6080
|
const openingTag = group([
|
|
6051
6081
|
'<',
|
|
6052
6082
|
tagName,
|
|
6053
6083
|
hasAttributes
|
|
6054
6084
|
? indent([
|
|
6055
|
-
...
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
for (const comment of commentsForAttr) {
|
|
6062
|
-
// Line comments (//) consume the rest of the line, so they must
|
|
6063
|
-
// use hardline to force a break. Block comments can use normal breaks.
|
|
6064
|
-
if (comment.type === 'Line') {
|
|
6065
|
-
parts.push(hardline);
|
|
6066
|
-
parts.push('//' + comment.value);
|
|
6067
|
-
} else if (comment.type === 'Block') {
|
|
6068
|
-
parts.push(attrLineBreak);
|
|
6069
|
-
parts.push('/*' + comment.value + '*/');
|
|
6070
|
-
}
|
|
6071
|
-
}
|
|
6072
|
-
}
|
|
6073
|
-
parts.push(attrLineBreak);
|
|
6074
|
-
parts.push(print(attrPath));
|
|
6075
|
-
return parts;
|
|
6076
|
-
}, 'attributes'),
|
|
6077
|
-
// Force the group to break when there are line comments in the opening tag
|
|
6078
|
-
...(hasOpeningTagComments ? [breakParent] : []),
|
|
6085
|
+
...attrDocs,
|
|
6086
|
+
// Force the group to break when there are line comments in the opening tag,
|
|
6087
|
+
// or when any attribute value would break (e.g. multiline objects, ternaries).
|
|
6088
|
+
// This ensures attributes are broken onto separate lines rather than breaking
|
|
6089
|
+
// expression values inline on the same line as the tag name.
|
|
6090
|
+
...(shouldForceBreak ? [breakParent] : []),
|
|
6079
6091
|
])
|
|
6080
6092
|
: '',
|
|
6081
6093
|
// Add line break opportunity before > or />
|
package/src/index.test.js
CHANGED
|
@@ -926,6 +926,71 @@ export component Test({ a, b }: Props) {}`;
|
|
|
926
926
|
expect(result).toBeWithNewline(expected);
|
|
927
927
|
});
|
|
928
928
|
|
|
929
|
+
it('should prefer breaking attributes over breaking expression values (multiline object)', async () => {
|
|
930
|
+
const input = `component App() {
|
|
931
|
+
<div class={styles.item} data-active={state.active ? "true" : "false"} style={{ gridTemplateColumns: Icon ? "16px minmax(0, 1fr) auto" : "minmax(0, 1fr) auto" }}>
|
|
932
|
+
{'content'}
|
|
933
|
+
</div>
|
|
934
|
+
}`;
|
|
935
|
+
const expected = `component App() {
|
|
936
|
+
<div
|
|
937
|
+
class={styles.item}
|
|
938
|
+
data-active={state.active ? 'true' : 'false'}
|
|
939
|
+
style={{
|
|
940
|
+
gridTemplateColumns: Icon
|
|
941
|
+
? '16px minmax(0, 1fr) auto'
|
|
942
|
+
: 'minmax(0, 1fr) auto',
|
|
943
|
+
}}
|
|
944
|
+
>
|
|
945
|
+
{'content'}
|
|
946
|
+
</div>
|
|
947
|
+
}`;
|
|
948
|
+
|
|
949
|
+
const result = await format(input, { singleQuote: true, printWidth: 80 });
|
|
950
|
+
expect(result).toBeWithNewline(expected);
|
|
951
|
+
});
|
|
952
|
+
|
|
953
|
+
it('should prefer breaking attributes over breaking expression values (multiline object, bracketSameLine)', async () => {
|
|
954
|
+
const input = `component App() {
|
|
955
|
+
<div class={styles.item} data-active={state.active ? "true" : "false"} style={{ gridTemplateColumns: Icon ? "16px minmax(0, 1fr) auto" : "minmax(0, 1fr) auto" }}>
|
|
956
|
+
{'content'}
|
|
957
|
+
</div>
|
|
958
|
+
}`;
|
|
959
|
+
const expected = `component App() {
|
|
960
|
+
<div
|
|
961
|
+
class={styles.item}
|
|
962
|
+
data-active={state.active ? 'true' : 'false'}
|
|
963
|
+
style={{
|
|
964
|
+
gridTemplateColumns: Icon
|
|
965
|
+
? '16px minmax(0, 1fr) auto'
|
|
966
|
+
: 'minmax(0, 1fr) auto',
|
|
967
|
+
}}>
|
|
968
|
+
{'content'}
|
|
969
|
+
</div>
|
|
970
|
+
}`;
|
|
971
|
+
|
|
972
|
+
const result = await format(input, {
|
|
973
|
+
singleQuote: true,
|
|
974
|
+
printWidth: 80,
|
|
975
|
+
bracketSameLine: true,
|
|
976
|
+
});
|
|
977
|
+
expect(result).toBeWithNewline(expected);
|
|
978
|
+
});
|
|
979
|
+
|
|
980
|
+
it('should keep attributes on same line when no attribute value breaks', async () => {
|
|
981
|
+
const input = `component App() {
|
|
982
|
+
<button class="test another" onClick={handler}>
|
|
983
|
+
{'Click Me'}
|
|
984
|
+
</button>
|
|
985
|
+
}`;
|
|
986
|
+
const expected = `component App() {
|
|
987
|
+
<button class="test another" onClick={handler}>{'Click Me'}</button>
|
|
988
|
+
}`;
|
|
989
|
+
|
|
990
|
+
const result = await format(input, { singleQuote: true, printWidth: 80 });
|
|
991
|
+
expect(result).toBeWithNewline(expected);
|
|
992
|
+
});
|
|
993
|
+
|
|
929
994
|
it('should not format function parameter spread', async () => {
|
|
930
995
|
const expected = `component Two({ arg1, ...rest }) {}`;
|
|
931
996
|
|