@tsrx/prettier-plugin 0.3.48 → 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.48",
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.48"
27
+ "prettier": "^3.8.3"
30
28
  },
31
29
  "dependencies": {
32
- "@tsrx/core": "0.0.27",
33
- "@tsrx/ripple": "0.0.29"
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
@@ -1632,6 +1632,10 @@ function printRippleNode(node, path, options, print, args) {
1632
1632
  nodeContent = ['{ref ', path.call(print, 'argument'), '}'];
1633
1633
  break;
1634
1634
 
1635
+ case 'RefExpression':
1636
+ nodeContent = ['ref ', path.call(print, 'argument')];
1637
+ break;
1638
+
1635
1639
  case 'SpreadAttribute': {
1636
1640
  /** @type {Doc[]} */
1637
1641
  const parts = ['{...', path.call(print, 'argument'), '}'];
@@ -2188,6 +2192,10 @@ function printRippleNode(node, path, options, print, args) {
2188
2192
  nodeContent = printTsxCompat(node, path, options, print);
2189
2193
  break;
2190
2194
 
2195
+ case 'Tsrx':
2196
+ nodeContent = printTsrx(node, path, options, print);
2197
+ break;
2198
+
2191
2199
  case 'Tsx':
2192
2200
  nodeContent = printTsx(node, path, options, print);
2193
2201
  break;
@@ -5623,6 +5631,15 @@ function printTsx(node, path, options, print) {
5623
5631
  return [tagName, closingTagName];
5624
5632
  }
5625
5633
 
5634
+ if (printedChildren.length > 1) {
5635
+ return group([
5636
+ tagName,
5637
+ indent([hardline, join(hardline, printedChildren)]),
5638
+ hardline,
5639
+ closingTagName,
5640
+ ]);
5641
+ }
5642
+
5626
5643
  // Use softline to allow single-line when content fits
5627
5644
  return group([
5628
5645
  tagName,
@@ -5632,6 +5649,51 @@ function printTsx(node, path, options, print) {
5632
5649
  ]);
5633
5650
  }
5634
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
+
5635
5697
  /**
5636
5698
  * Print a TSX compatibility node
5637
5699
  * @param {AST.TsxCompat} node - The TSX compat node
@@ -5831,6 +5893,17 @@ function printJSXElement(node, path, options, print) {
5831
5893
  if (childrenDocs.length === 1 && typeof childrenDocs[0] === 'string') {
5832
5894
  return ['<', tagName, typeArgsDoc, attributesDoc, '>', childrenDocs[0], '</', tagName, '>'];
5833
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
+ }
5834
5907
 
5835
5908
  // Multiple children or complex children - format with line breaks
5836
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