@tsrx/prettier-plugin 0.3.28 → 0.3.30
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 +35 -3
- package/src/index.test.js +52 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tsrx/prettier-plugin",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.30",
|
|
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.30"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@tsrx/core": "0.0.
|
|
33
|
-
"@tsrx/ripple": "0.0.
|
|
32
|
+
"@tsrx/core": "0.0.10",
|
|
33
|
+
"@tsrx/ripple": "0.0.12"
|
|
34
34
|
},
|
|
35
35
|
"files": [
|
|
36
36
|
"src/"
|
package/src/index.js
CHANGED
|
@@ -5554,6 +5554,7 @@ function createElementLevelCommentPartsTrimmed(comments) {
|
|
|
5554
5554
|
|
|
5555
5555
|
/**
|
|
5556
5556
|
* Print a Tsx node - renders Ripple template children inside <tsx>...</tsx>
|
|
5557
|
+
* or fragment shorthand <>...</> when the original source used a fragment.
|
|
5557
5558
|
* @param {AST.Tsx} node - The Tsx node
|
|
5558
5559
|
* @param {AstPath<AST.Tsx>} path - The AST path
|
|
5559
5560
|
* @param {RippleFormatOptions} options - Prettier options
|
|
@@ -5561,8 +5562,9 @@ function createElementLevelCommentPartsTrimmed(comments) {
|
|
|
5561
5562
|
* @returns {Doc}
|
|
5562
5563
|
*/
|
|
5563
5564
|
function printTsx(node, path, options, print) {
|
|
5564
|
-
const
|
|
5565
|
-
const
|
|
5565
|
+
const is_fragment = !node.openingElement?.name;
|
|
5566
|
+
const tagName = is_fragment ? '<>' : '<tsx>';
|
|
5567
|
+
const closingTagName = is_fragment ? '</>' : '</tsx>';
|
|
5566
5568
|
|
|
5567
5569
|
const hasChildren = Array.isArray(node.children) && node.children.length > 0;
|
|
5568
5570
|
|
|
@@ -5947,6 +5949,31 @@ function printMemberExpressionSimple(node, options, computed = false) {
|
|
|
5947
5949
|
return '';
|
|
5948
5950
|
}
|
|
5949
5951
|
|
|
5952
|
+
/**
|
|
5953
|
+
* Check whether an attribute value can expand into multiline content.
|
|
5954
|
+
* @param {AST.Expression | null | undefined} value - The attribute value node
|
|
5955
|
+
* @param {boolean} [is_nested_in_object=false] - Whether this value is nested within an object literal
|
|
5956
|
+
* @returns {boolean}
|
|
5957
|
+
*/
|
|
5958
|
+
function is_attribute_value_breakable(value, is_nested_in_object = false) {
|
|
5959
|
+
if (!value) return false;
|
|
5960
|
+
|
|
5961
|
+
switch (value.type) {
|
|
5962
|
+
case 'ConditionalExpression':
|
|
5963
|
+
// Keep simple top-level ternary attributes inline when they fit.
|
|
5964
|
+
// We only force-break when a conditional is nested in an object literal value.
|
|
5965
|
+
return is_nested_in_object;
|
|
5966
|
+
case 'ObjectExpression':
|
|
5967
|
+
return value.properties.some(
|
|
5968
|
+
(property) =>
|
|
5969
|
+
property.type === 'Property' &&
|
|
5970
|
+
is_attribute_value_breakable(/** @type {AST.Expression} */ (property.value), true),
|
|
5971
|
+
);
|
|
5972
|
+
default:
|
|
5973
|
+
return false;
|
|
5974
|
+
}
|
|
5975
|
+
}
|
|
5976
|
+
|
|
5950
5977
|
/**
|
|
5951
5978
|
* Print a Ripple Element node
|
|
5952
5979
|
* @param {AST.Element} element - The element node
|
|
@@ -6070,7 +6097,12 @@ function printElement(element, path, options, print) {
|
|
|
6070
6097
|
parts.push(attrLineBreak);
|
|
6071
6098
|
const attrDoc = print(attrPath);
|
|
6072
6099
|
parts.push(attrDoc);
|
|
6073
|
-
|
|
6100
|
+
const attr_node = /** @type {AST.Attribute | AST.SpreadAttribute} */ (attrPath.node);
|
|
6101
|
+
if (
|
|
6102
|
+
!hasBreakingAttribute &&
|
|
6103
|
+
(willBreak(attrDoc) ||
|
|
6104
|
+
(attr_node.type === 'Attribute' && is_attribute_value_breakable(attr_node.value)))
|
|
6105
|
+
) {
|
|
6074
6106
|
hasBreakingAttribute = true;
|
|
6075
6107
|
}
|
|
6076
6108
|
return parts;
|
package/src/index.test.js
CHANGED
|
@@ -926,7 +926,7 @@ export component Test({ a, b }: Props) {}`;
|
|
|
926
926
|
expect(result).toBeWithNewline(expected);
|
|
927
927
|
});
|
|
928
928
|
|
|
929
|
-
it('should prefer breaking attributes over
|
|
929
|
+
it('should prefer breaking attributes over inline breakable object values', async () => {
|
|
930
930
|
const input = `component App() {
|
|
931
931
|
<div class={styles.item} data-active={state.active ? "true" : "false"} style={{ gridTemplateColumns: Icon ? "16px minmax(0, 1fr) auto" : "minmax(0, 1fr) auto" }}>
|
|
932
932
|
{'content'}
|
|
@@ -936,21 +936,17 @@ export component Test({ a, b }: Props) {}`;
|
|
|
936
936
|
<div
|
|
937
937
|
class={styles.item}
|
|
938
938
|
data-active={state.active ? 'true' : 'false'}
|
|
939
|
-
style={{
|
|
940
|
-
gridTemplateColumns: Icon
|
|
941
|
-
? '16px minmax(0, 1fr) auto'
|
|
942
|
-
: 'minmax(0, 1fr) auto',
|
|
943
|
-
}}
|
|
939
|
+
style={{ gridTemplateColumns: Icon ? '16px minmax(0, 1fr) auto' : 'minmax(0, 1fr) auto' }}
|
|
944
940
|
>
|
|
945
941
|
{'content'}
|
|
946
942
|
</div>
|
|
947
943
|
}`;
|
|
948
944
|
|
|
949
|
-
const result = await format(input, { singleQuote: true, printWidth:
|
|
945
|
+
const result = await format(input, { singleQuote: true, printWidth: 200 });
|
|
950
946
|
expect(result).toBeWithNewline(expected);
|
|
951
947
|
});
|
|
952
948
|
|
|
953
|
-
it('should prefer breaking attributes over
|
|
949
|
+
it('should prefer breaking attributes over inline breakable object values (bracketSameLine)', async () => {
|
|
954
950
|
const input = `component App() {
|
|
955
951
|
<div class={styles.item} data-active={state.active ? "true" : "false"} style={{ gridTemplateColumns: Icon ? "16px minmax(0, 1fr) auto" : "minmax(0, 1fr) auto" }}>
|
|
956
952
|
{'content'}
|
|
@@ -960,18 +956,14 @@ export component Test({ a, b }: Props) {}`;
|
|
|
960
956
|
<div
|
|
961
957
|
class={styles.item}
|
|
962
958
|
data-active={state.active ? 'true' : 'false'}
|
|
963
|
-
style={{
|
|
964
|
-
gridTemplateColumns: Icon
|
|
965
|
-
? '16px minmax(0, 1fr) auto'
|
|
966
|
-
: 'minmax(0, 1fr) auto',
|
|
967
|
-
}}>
|
|
959
|
+
style={{ gridTemplateColumns: Icon ? '16px minmax(0, 1fr) auto' : 'minmax(0, 1fr) auto' }}>
|
|
968
960
|
{'content'}
|
|
969
961
|
</div>
|
|
970
962
|
}`;
|
|
971
963
|
|
|
972
964
|
const result = await format(input, {
|
|
973
965
|
singleQuote: true,
|
|
974
|
-
printWidth:
|
|
966
|
+
printWidth: 200,
|
|
975
967
|
bracketSameLine: true,
|
|
976
968
|
});
|
|
977
969
|
expect(result).toBeWithNewline(expected);
|
|
@@ -991,6 +983,18 @@ export component Test({ a, b }: Props) {}`;
|
|
|
991
983
|
expect(result).toBeWithNewline(expected);
|
|
992
984
|
});
|
|
993
985
|
|
|
986
|
+
it('should keep short top-level ternary attributes inline when they fit', async () => {
|
|
987
|
+
const input = `component App() {
|
|
988
|
+
<div class={selected === 0 ? "selected" : ""}>{\`div 1\`}</div>
|
|
989
|
+
}`;
|
|
990
|
+
const expected = `component App() {
|
|
991
|
+
<div class={selected === 0 ? 'selected' : ''}>{\`div 1\`}</div>
|
|
992
|
+
}`;
|
|
993
|
+
|
|
994
|
+
const result = await format(input, { singleQuote: true, printWidth: 100 });
|
|
995
|
+
expect(result).toBeWithNewline(expected);
|
|
996
|
+
});
|
|
997
|
+
|
|
994
998
|
it('should not format function parameter spread', async () => {
|
|
995
999
|
const expected = `component Two({ arg1, ...rest }) {}`;
|
|
996
1000
|
|
|
@@ -1935,6 +1939,40 @@ files = [...(files ?? []), ...dt.files];`;
|
|
|
1935
1939
|
expect(result).toBeWithNewline(expected);
|
|
1936
1940
|
});
|
|
1937
1941
|
|
|
1942
|
+
it('should preserve fragment shorthand in class methods', async () => {
|
|
1943
|
+
const input = `class Foo {
|
|
1944
|
+
bar() {
|
|
1945
|
+
return <>{"Hello"}</>;
|
|
1946
|
+
}
|
|
1947
|
+
}`;
|
|
1948
|
+
|
|
1949
|
+
const expected = `class Foo {
|
|
1950
|
+
bar() {
|
|
1951
|
+
return <>{'Hello'}</>;
|
|
1952
|
+
}
|
|
1953
|
+
}`;
|
|
1954
|
+
|
|
1955
|
+
const result = await format(input, { singleQuote: true, printWidth: 100 });
|
|
1956
|
+
expect(result).toBeWithNewline(expected);
|
|
1957
|
+
});
|
|
1958
|
+
|
|
1959
|
+
it('should preserve explicit tsx blocks in class methods', async () => {
|
|
1960
|
+
const input = `class Foo {
|
|
1961
|
+
bar() {
|
|
1962
|
+
return <tsx>{"Hello"}</tsx>;
|
|
1963
|
+
}
|
|
1964
|
+
}`;
|
|
1965
|
+
|
|
1966
|
+
const expected = `class Foo {
|
|
1967
|
+
bar() {
|
|
1968
|
+
return <tsx>{'Hello'}</tsx>;
|
|
1969
|
+
}
|
|
1970
|
+
}`;
|
|
1971
|
+
|
|
1972
|
+
const result = await format(input, { singleQuote: true, printWidth: 100 });
|
|
1973
|
+
expect(result).toBeWithNewline(expected);
|
|
1974
|
+
});
|
|
1975
|
+
|
|
1938
1976
|
it('should format class with a literal component method', async () => {
|
|
1939
1977
|
const input = `class TestClass {
|
|
1940
1978
|
component 'something'() {
|