@tsrx/prettier-plugin 0.3.49 → 0.3.51

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsrx/prettier-plugin",
3
- "version": "0.3.49",
3
+ "version": "0.3.51",
4
4
  "description": "Ripple plugin for Prettier",
5
5
  "type": "module",
6
6
  "module": "src/index.js",
@@ -20,17 +20,15 @@
20
20
  "directory": "packages/prettier-plugin"
21
21
  },
22
22
  "peerDependencies": {
23
- "ripple": "*",
24
23
  "prettier": ">=2.0.0"
25
24
  },
26
25
  "devDependencies": {
27
26
  "@types/node": "^24.3.0",
28
- "prettier": "^3.8.3",
29
- "ripple": "0.3.49"
27
+ "prettier": "^3.8.3"
30
28
  },
31
29
  "dependencies": {
32
- "@tsrx/core": "0.0.28",
33
- "@tsrx/ripple": "0.0.30"
30
+ "@tsrx/core": "0.1.1",
31
+ "@tsrx/ripple": "0.1.1"
34
32
  },
35
33
  "files": [
36
34
  "src/"
package/src/index.js CHANGED
@@ -2192,6 +2192,10 @@ function printRippleNode(node, path, options, print, args) {
2192
2192
  nodeContent = printTsxCompat(node, path, options, print);
2193
2193
  break;
2194
2194
 
2195
+ case 'Tsrx':
2196
+ nodeContent = printTsrx(node, path, options, print);
2197
+ break;
2198
+
2195
2199
  case 'Tsx':
2196
2200
  nodeContent = printTsx(node, path, options, print);
2197
2201
  break;
@@ -5627,6 +5631,15 @@ function printTsx(node, path, options, print) {
5627
5631
  return [tagName, closingTagName];
5628
5632
  }
5629
5633
 
5634
+ if (printedChildren.length > 1) {
5635
+ return group([
5636
+ tagName,
5637
+ indent([hardline, join(hardline, printedChildren)]),
5638
+ hardline,
5639
+ closingTagName,
5640
+ ]);
5641
+ }
5642
+
5630
5643
  // Use softline to allow single-line when content fits
5631
5644
  return group([
5632
5645
  tagName,
@@ -5636,6 +5649,51 @@ function printTsx(node, path, options, print) {
5636
5649
  ]);
5637
5650
  }
5638
5651
 
5652
+ /**
5653
+ * Print a Tsrx node - renders native TSRX template children inside
5654
+ * <tsrx>...</tsrx>.
5655
+ * @param {AST.Tsrx} node - The Tsrx node
5656
+ * @param {AstPath<AST.Tsrx>} path - The AST path
5657
+ * @param {RippleFormatOptions} options - Prettier options
5658
+ * @param {PrintFn} print - Print callback
5659
+ * @returns {Doc}
5660
+ */
5661
+ function printTsrx(node, path, options, print) {
5662
+ const tagName = '<tsrx>';
5663
+ const closingTagName = '</tsrx>';
5664
+ const hasChildren = Array.isArray(node.children) && node.children.length > 0;
5665
+
5666
+ if (!hasChildren) {
5667
+ return [tagName, closingTagName];
5668
+ }
5669
+
5670
+ const printedChildren = [];
5671
+
5672
+ for (let i = 0; i < node.children.length; i++) {
5673
+ const child = node.children[i];
5674
+
5675
+ if (child.type === 'JSXText') {
5676
+ const text = child.value.trim();
5677
+ if (!text) continue;
5678
+ printedChildren.push(text);
5679
+ } else {
5680
+ const printedChild = path.call(print, 'children', i);
5681
+ printedChildren.push(printedChild);
5682
+ }
5683
+ }
5684
+
5685
+ if (printedChildren.length === 0) {
5686
+ return [tagName, closingTagName];
5687
+ }
5688
+
5689
+ return group([
5690
+ tagName,
5691
+ indent([hardline, join(hardline, printedChildren)]),
5692
+ hardline,
5693
+ closingTagName,
5694
+ ]);
5695
+ }
5696
+
5639
5697
  /**
5640
5698
  * Print a TSX compatibility node
5641
5699
  * @param {AST.TsxCompat} node - The TSX compat node
@@ -5835,6 +5893,17 @@ function printJSXElement(node, path, options, print) {
5835
5893
  if (childrenDocs.length === 1 && typeof childrenDocs[0] === 'string') {
5836
5894
  return ['<', tagName, typeArgsDoc, attributesDoc, '>', childrenDocs[0], '</', tagName, '>'];
5837
5895
  }
5896
+ const meaningfulChildren = node.children.filter(
5897
+ (child) => child.type !== 'JSXText' || child.value.trim(),
5898
+ );
5899
+ const singleMeaningfulChild = meaningfulChildren.length === 1 ? meaningfulChildren[0] : null;
5900
+ if (
5901
+ childrenDocs.length === 1 &&
5902
+ singleMeaningfulChild?.type === 'JSXExpressionContainer' &&
5903
+ singleMeaningfulChild.expression.type === 'Identifier'
5904
+ ) {
5905
+ return ['<', tagName, typeArgsDoc, attributesDoc, '>', childrenDocs[0], '</', tagName, '>'];
5906
+ }
5838
5907
 
5839
5908
  // Multiple children or complex children - format with line breaks
5840
5909
  const formattedChildren = [];
package/src/index.test.js CHANGED
@@ -102,6 +102,61 @@ describe('prettier-plugin', () => {
102
102
  expect(typeof result.cursorOffset).toBe('number');
103
103
  });
104
104
 
105
+ it('should format tsrx expression fragments', async () => {
106
+ const input = `component App(){const content=<tsrx>const label="Hi";<div>"Hello" {label}</div></tsrx>;{content}}`;
107
+ const expected = `component App() {
108
+ const content = <tsrx>
109
+ const label = 'Hi';
110
+ <div>
111
+ "Hello"
112
+ {label}
113
+ </div>
114
+ </tsrx>;
115
+ {content}
116
+ }`;
117
+ const result = await format(input, { singleQuote: true });
118
+ expect(result).toBeWithNewline(expected);
119
+ });
120
+
121
+ it('should keep sibling children in tsrx expression fragments on separate lines', async () => {
122
+ const input = `function Test(p1,p2){return <tsrx><div>"Hello"</div><div>{p1}</div><div>{p2}</div></tsrx>}`;
123
+ const expected = `function Test(p1, p2) {
124
+ return <tsrx>
125
+ <div>"Hello"</div>
126
+ <div>{p1}</div>
127
+ <div>{p2}</div>
128
+ </tsrx>;
129
+ }`;
130
+ const result = await format(input);
131
+ expect(result).toBeWithNewline(expected);
132
+ });
133
+
134
+ it('should format shorthand tsx fragments like JSX fragments', async () => {
135
+ const input = `function Test(p1,p2){return <><div>Hello</div><div>{p1}</div><div>{p2}</div></>}`;
136
+ const expected = `function Test(p1, p2) {
137
+ return <>
138
+ <div>Hello</div>
139
+ <div>{p1}</div>
140
+ <div>{p2}</div>
141
+ </>;
142
+ }`;
143
+ const result = await format(input);
144
+ expect(result).toBeWithNewline(expected);
145
+ });
146
+
147
+ it('should format tsx expression fragments like shorthand fragments', async () => {
148
+ const input = `function Test(p1,p2){return <tsx><div>Hello</div><div>{p1}</div><div>{p2}</div></tsx>}`;
149
+ const expected = `function Test(p1, p2) {
150
+ return <tsx>
151
+ <div>Hello</div>
152
+ <div>{p1}</div>
153
+ <div>{p2}</div>
154
+ </tsx>;
155
+ }`;
156
+ const result = await format(input);
157
+ expect(result).toBeWithNewline(expected);
158
+ });
159
+
105
160
  it('should format whitespace correctly', async () => {
106
161
  const input = `export component Test(){
107
162
  let count=0