@ripple-ts/prettier-plugin 0.2.157 → 0.2.158
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 +2 -2
- package/src/index.js +75 -21
- package/src/index.test.js +76 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ripple-ts/prettier-plugin",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.158",
|
|
4
4
|
"description": "Ripple plugin for Prettier",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "src/index.js",
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"prettier": "^3.6.2",
|
|
28
|
-
"ripple": "0.2.
|
|
28
|
+
"ripple": "0.2.158"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {},
|
|
31
31
|
"files": [
|
package/src/index.js
CHANGED
|
@@ -1168,6 +1168,11 @@ function printRippleNode(node, path, options, print, args) {
|
|
|
1168
1168
|
break;
|
|
1169
1169
|
}
|
|
1170
1170
|
|
|
1171
|
+
case 'JSXExpressionContainer': {
|
|
1172
|
+
nodeContent = concat(['{', path.call(print, 'expression'), '}']);
|
|
1173
|
+
break;
|
|
1174
|
+
}
|
|
1175
|
+
|
|
1171
1176
|
case 'NewExpression':
|
|
1172
1177
|
nodeContent = printNewExpression(node, path, options, print);
|
|
1173
1178
|
break;
|
|
@@ -4325,29 +4330,59 @@ function printTsxCompat(node, path, options, print) {
|
|
|
4325
4330
|
}
|
|
4326
4331
|
|
|
4327
4332
|
// Print JSXElement children - they remain as JSX
|
|
4328
|
-
// Filter out whitespace-only JSXText nodes
|
|
4333
|
+
// Filter out whitespace-only JSXText nodes and merge adjacent text-like nodes
|
|
4329
4334
|
const finalChildren = [];
|
|
4335
|
+
let accumulatedText = '';
|
|
4330
4336
|
|
|
4331
4337
|
for (let i = 0; i < node.children.length; i++) {
|
|
4332
4338
|
const child = node.children[i];
|
|
4333
4339
|
|
|
4334
|
-
//
|
|
4335
|
-
|
|
4336
|
-
continue;
|
|
4337
|
-
}
|
|
4340
|
+
// Check if this is a text-like node (JSXText or Identifier in JSX context)
|
|
4341
|
+
const isTextLike = child.type === 'JSXText' || child.type === 'Identifier';
|
|
4338
4342
|
|
|
4339
|
-
|
|
4340
|
-
|
|
4343
|
+
if (isTextLike) {
|
|
4344
|
+
// Get the text content
|
|
4345
|
+
let text;
|
|
4346
|
+
if (child.type === 'JSXText') {
|
|
4347
|
+
text = child.value.trim();
|
|
4348
|
+
} else if (child.type === 'Identifier') {
|
|
4349
|
+
text = child.name;
|
|
4350
|
+
}
|
|
4341
4351
|
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4352
|
+
if (text) {
|
|
4353
|
+
if (accumulatedText) {
|
|
4354
|
+
accumulatedText += ' ' + text;
|
|
4355
|
+
} else {
|
|
4356
|
+
accumulatedText = text;
|
|
4357
|
+
}
|
|
4358
|
+
}
|
|
4359
|
+
} else {
|
|
4360
|
+
// Before adding non-text node, flush accumulated text
|
|
4361
|
+
if (accumulatedText) {
|
|
4362
|
+
if (finalChildren.length > 0) {
|
|
4363
|
+
finalChildren.push(hardline);
|
|
4364
|
+
}
|
|
4365
|
+
finalChildren.push(accumulatedText);
|
|
4366
|
+
accumulatedText = '';
|
|
4367
|
+
}
|
|
4368
|
+
|
|
4369
|
+
if (finalChildren.length > 0) {
|
|
4346
4370
|
finalChildren.push(hardline);
|
|
4347
4371
|
}
|
|
4372
|
+
|
|
4373
|
+
const printedChild = path.call(print, 'children', i);
|
|
4374
|
+
finalChildren.push(printedChild);
|
|
4348
4375
|
}
|
|
4349
4376
|
}
|
|
4350
4377
|
|
|
4378
|
+
// Don't forget any remaining accumulated text
|
|
4379
|
+
if (accumulatedText) {
|
|
4380
|
+
if (finalChildren.length > 0) {
|
|
4381
|
+
finalChildren.push(hardline);
|
|
4382
|
+
}
|
|
4383
|
+
finalChildren.push(accumulatedText);
|
|
4384
|
+
}
|
|
4385
|
+
|
|
4351
4386
|
// Format the TsxCompat element
|
|
4352
4387
|
const elementOutput = group([
|
|
4353
4388
|
tagName,
|
|
@@ -4404,26 +4439,45 @@ function printJSXElement(node, path, options, print) {
|
|
|
4404
4439
|
return concat(['<', tagName, attributesDoc, '></', tagName, '>']);
|
|
4405
4440
|
}
|
|
4406
4441
|
|
|
4407
|
-
// Format children - filter out empty text nodes
|
|
4442
|
+
// Format children - filter out empty text nodes and merge adjacent text nodes
|
|
4408
4443
|
const childrenDocs = [];
|
|
4444
|
+
let currentText = '';
|
|
4445
|
+
|
|
4409
4446
|
for (let i = 0; i < node.children.length; i++) {
|
|
4410
4447
|
const child = node.children[i];
|
|
4411
4448
|
|
|
4412
4449
|
if (child.type === 'JSXText') {
|
|
4413
|
-
//
|
|
4414
|
-
const
|
|
4415
|
-
if (
|
|
4416
|
-
|
|
4450
|
+
// Accumulate text content, preserving spaces between words
|
|
4451
|
+
const trimmed = child.value.trim();
|
|
4452
|
+
if (trimmed) {
|
|
4453
|
+
if (currentText) {
|
|
4454
|
+
currentText += ' ' + trimmed;
|
|
4455
|
+
} else {
|
|
4456
|
+
currentText = trimmed;
|
|
4457
|
+
}
|
|
4417
4458
|
}
|
|
4418
|
-
} else if (child.type === 'JSXExpressionContainer') {
|
|
4419
|
-
// Handle JSX expression containers
|
|
4420
|
-
childrenDocs.push(concat(['{', path.call(print, 'children', i, 'expression'), '}']));
|
|
4421
4459
|
} else {
|
|
4422
|
-
//
|
|
4423
|
-
|
|
4460
|
+
// If we have accumulated text, push it before the non-text node
|
|
4461
|
+
if (currentText) {
|
|
4462
|
+
childrenDocs.push(currentText);
|
|
4463
|
+
currentText = '';
|
|
4464
|
+
}
|
|
4465
|
+
|
|
4466
|
+
if (child.type === 'JSXExpressionContainer') {
|
|
4467
|
+
// Handle JSX expression containers
|
|
4468
|
+
childrenDocs.push(concat(['{', path.call(print, 'children', i, 'expression'), '}']));
|
|
4469
|
+
} else {
|
|
4470
|
+
// Handle nested JSX elements
|
|
4471
|
+
childrenDocs.push(path.call(print, 'children', i));
|
|
4472
|
+
}
|
|
4424
4473
|
}
|
|
4425
4474
|
}
|
|
4426
4475
|
|
|
4476
|
+
// Don't forget any remaining text
|
|
4477
|
+
if (currentText) {
|
|
4478
|
+
childrenDocs.push(currentText);
|
|
4479
|
+
}
|
|
4480
|
+
|
|
4427
4481
|
// Check if content can be inlined (single text node or single expression)
|
|
4428
4482
|
if (childrenDocs.length === 1 && typeof childrenDocs[0] === 'string') {
|
|
4429
4483
|
return concat(['<', tagName, attributesDoc, '>', childrenDocs[0], '</', tagName, '>']);
|
package/src/index.test.js
CHANGED
|
@@ -3812,6 +3812,82 @@ component Polygon() {
|
|
|
3812
3812
|
const result = await format(input, { singleQuote: true });
|
|
3813
3813
|
expect(result).toBeWithNewline(expected);
|
|
3814
3814
|
});
|
|
3815
|
+
|
|
3816
|
+
it('should format JSXExpressionContainer with function calls', async () => {
|
|
3817
|
+
const input = `function foo(){return 123}component App(){<div><tsx:react>{foo()}</tsx:react></div>}`;
|
|
3818
|
+
|
|
3819
|
+
const expected = `function foo() {
|
|
3820
|
+
return 123;
|
|
3821
|
+
}
|
|
3822
|
+
component App() {
|
|
3823
|
+
<div>
|
|
3824
|
+
<tsx:react>
|
|
3825
|
+
{foo()}
|
|
3826
|
+
</tsx:react>
|
|
3827
|
+
</div>
|
|
3828
|
+
}`;
|
|
3829
|
+
|
|
3830
|
+
const result = await format(input);
|
|
3831
|
+
expect(result).toBeWithNewline(expected);
|
|
3832
|
+
});
|
|
3833
|
+
|
|
3834
|
+
it('should format JSXExpressionContainer with function calls', async () => {
|
|
3835
|
+
const input = `function foo(){return 123}component App(){<div><tsx:react>{foo()}<div>Hello world</div>Hello world</tsx:react></div>}`;
|
|
3836
|
+
|
|
3837
|
+
const expected = `function foo() {
|
|
3838
|
+
return 123;
|
|
3839
|
+
}
|
|
3840
|
+
component App() {
|
|
3841
|
+
<div>
|
|
3842
|
+
<tsx:react>
|
|
3843
|
+
{foo()}
|
|
3844
|
+
<div>Hello world</div>
|
|
3845
|
+
Hello world
|
|
3846
|
+
</tsx:react>
|
|
3847
|
+
</div>
|
|
3848
|
+
}`;
|
|
3849
|
+
|
|
3850
|
+
const result = await format(input);
|
|
3851
|
+
expect(result).toBeWithNewline(expected);
|
|
3852
|
+
});
|
|
3853
|
+
|
|
3854
|
+
it('should format JSXExpressionContainer with function calls #2', async () => {
|
|
3855
|
+
const input = `export component App() {
|
|
3856
|
+
<tsx:react>
|
|
3857
|
+
Hello world
|
|
3858
|
+
<DemoContext.Provider value={"Hello from Context!"}>
|
|
3859
|
+
<Child count={@count} />
|
|
3860
|
+
</DemoContext.Provider>
|
|
3861
|
+
</tsx:react>
|
|
3862
|
+
}`;
|
|
3863
|
+
const expected = `export component App() {
|
|
3864
|
+
<tsx:react>
|
|
3865
|
+
Hello world
|
|
3866
|
+
<DemoContext.Provider value={"Hello from Context!"}>
|
|
3867
|
+
<Child count={@count} />
|
|
3868
|
+
</DemoContext.Provider>
|
|
3869
|
+
</tsx:react>
|
|
3870
|
+
}`;
|
|
3871
|
+
|
|
3872
|
+
const result = await format(input);
|
|
3873
|
+
expect(result).toBeWithNewline(expected);
|
|
3874
|
+
});
|
|
3875
|
+
it('should format JSXExpressionContainer with complex expressions', async () => {
|
|
3876
|
+
const input = `component App(){let count=track(0);<tsx:react><div>{count*2+10}</div>{getMessage("test")}</tsx:react>}`;
|
|
3877
|
+
|
|
3878
|
+
const expected = `component App() {
|
|
3879
|
+
let count = track(0);
|
|
3880
|
+
<tsx:react>
|
|
3881
|
+
<div>
|
|
3882
|
+
{count * 2 + 10}
|
|
3883
|
+
</div>
|
|
3884
|
+
{getMessage('test')}
|
|
3885
|
+
</tsx:react>
|
|
3886
|
+
}`;
|
|
3887
|
+
|
|
3888
|
+
const result = await format(input, { singleQuote: true });
|
|
3889
|
+
expect(result).toBeWithNewline(expected);
|
|
3890
|
+
});
|
|
3815
3891
|
});
|
|
3816
3892
|
});
|
|
3817
3893
|
});
|