ripple 0.3.13 → 0.3.15
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/CHANGELOG.md +35 -0
- package/package.json +5 -30
- package/src/runtime/array.js +38 -38
- package/src/runtime/create-subscriber.js +2 -2
- package/src/runtime/internal/client/bindings.js +4 -6
- package/src/runtime/internal/client/events.js +8 -3
- package/src/runtime/internal/client/hmr.js +5 -17
- package/src/runtime/internal/client/runtime.js +1 -0
- package/src/runtime/internal/server/blocks.js +7 -9
- package/src/runtime/internal/server/index.js +14 -22
- package/src/runtime/media-query.js +34 -33
- package/src/runtime/object.js +7 -10
- package/src/runtime/proxy.js +2 -3
- package/src/runtime/reactive-value.js +23 -21
- package/src/utils/ast.js +1 -1
- package/src/utils/attributes.js +43 -0
- package/src/utils/builders.js +2 -2
- package/tests/client/basic/basic.components.test.rsrx +103 -1
- package/tests/client/basic/basic.errors.test.rsrx +1 -1
- package/tests/client/basic/basic.styling.test.rsrx +1 -1
- package/tests/client/compiler/compiler.assignments.test.rsrx +1 -1
- package/tests/client/compiler/compiler.attributes.test.rsrx +1 -1
- package/tests/client/compiler/compiler.basic.test.rsrx +51 -14
- package/tests/client/compiler/compiler.tracked-access.test.rsrx +1 -1
- package/tests/client/compiler/compiler.try-in-function.test.rsrx +1 -1
- package/tests/client/compiler/compiler.typescript.test.rsrx +1 -1
- package/tests/client/css/global-additional-cases.test.rsrx +1 -1
- package/tests/client/css/global-advanced-selectors.test.rsrx +1 -1
- package/tests/client/css/global-at-rules.test.rsrx +1 -1
- package/tests/client/css/global-basic.test.rsrx +1 -1
- package/tests/client/css/global-classes-ids.test.rsrx +1 -1
- package/tests/client/css/global-combinators.test.rsrx +1 -1
- package/tests/client/css/global-complex-nesting.test.rsrx +1 -1
- package/tests/client/css/global-edge-cases.test.rsrx +1 -1
- package/tests/client/css/global-keyframes.test.rsrx +1 -1
- package/tests/client/css/global-nested.test.rsrx +1 -1
- package/tests/client/css/global-pseudo.test.rsrx +1 -1
- package/tests/client/css/global-scoping.test.rsrx +1 -1
- package/tests/client/css/style-identifier.test.rsrx +1 -1
- package/tests/client/return.test.rsrx +1 -1
- package/tests/hydration/build-components.js +1 -1
- package/tests/server/basic.components.test.rsrx +114 -0
- package/tests/server/compiler.test.rsrx +38 -1
- package/tests/server/style-identifier.test.rsrx +1 -1
- package/tests/setup-server.js +1 -1
- package/tests/utils/compiler-compat-config.test.js +1 -1
- package/types/index.d.ts +1 -1
- package/src/compiler/comment-utils.js +0 -91
- package/src/compiler/errors.js +0 -77
- package/src/compiler/identifier-utils.js +0 -80
- package/src/compiler/index.d.ts +0 -127
- package/src/compiler/index.js +0 -89
- package/src/compiler/phases/1-parse/index.js +0 -3007
- package/src/compiler/phases/1-parse/style.js +0 -704
- package/src/compiler/phases/2-analyze/css-analyze.js +0 -160
- package/src/compiler/phases/2-analyze/index.js +0 -2208
- package/src/compiler/phases/2-analyze/prune.js +0 -1131
- package/src/compiler/phases/2-analyze/validation.js +0 -168
- package/src/compiler/phases/3-transform/client/index.js +0 -5264
- package/src/compiler/phases/3-transform/segments.js +0 -2125
- package/src/compiler/phases/3-transform/server/index.js +0 -1749
- package/src/compiler/phases/3-transform/stylesheet.js +0 -545
- package/src/compiler/scope.js +0 -476
- package/src/compiler/source-map-utils.js +0 -358
- package/src/compiler/types/acorn.d.ts +0 -11
- package/src/compiler/types/estree-jsx.d.ts +0 -11
- package/src/compiler/types/estree.d.ts +0 -11
- package/src/compiler/types/index.d.ts +0 -1411
- package/src/compiler/types/parse.d.ts +0 -1723
- package/src/compiler/utils.js +0 -1258
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
Tracked,
|
|
3
|
-
Props,
|
|
4
3
|
PropsWithChildren,
|
|
5
4
|
PropsWithExtras,
|
|
6
5
|
Component,
|
|
@@ -414,4 +413,107 @@ describe('basic client > components & composition', () => {
|
|
|
414
413
|
button.click();
|
|
415
414
|
}).not.toThrow();
|
|
416
415
|
});
|
|
416
|
+
|
|
417
|
+
it('renders explicit children prop without spread', () => {
|
|
418
|
+
component Card(props: PropsWithChildren<{}>) {
|
|
419
|
+
<div class="card">{props.children}</div>
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
component App() {
|
|
423
|
+
<Card children="fallback text" />
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
render(App);
|
|
427
|
+
expect(container.querySelector('.card').textContent).toBe('fallback text');
|
|
428
|
+
});
|
|
429
|
+
|
|
430
|
+
it('renders explicit children before spread', () => {
|
|
431
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
432
|
+
<div class="card">{props.children}</div>
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
component App() {
|
|
436
|
+
const extra = { id: '1' };
|
|
437
|
+
<Card children="fallback text" {...extra} />
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
render(App);
|
|
441
|
+
expect(container.querySelector('.card').textContent).toBe('fallback text');
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
it('renders spread before explicit children', () => {
|
|
445
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
446
|
+
<div class="card">{props.children}</div>
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
component App() {
|
|
450
|
+
const extra = { id: '1' };
|
|
451
|
+
<Card {...extra} children="fallback text" />
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
render(App);
|
|
455
|
+
expect(container.querySelector('.card').textContent).toBe('fallback text');
|
|
456
|
+
});
|
|
457
|
+
|
|
458
|
+
it('template children override explicit children before spread', () => {
|
|
459
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
460
|
+
<div class="card">{props.children}</div>
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
component App() {
|
|
464
|
+
const extra = { id: '1' };
|
|
465
|
+
<Card children="fallback text" {...extra}>
|
|
466
|
+
<span>{'template content'}</span>
|
|
467
|
+
</Card>
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
render(App);
|
|
471
|
+
expect(container.querySelector('.card span').textContent).toBe('template content');
|
|
472
|
+
expect(container.querySelector('.card').textContent).toBe('template content');
|
|
473
|
+
});
|
|
474
|
+
|
|
475
|
+
it('template children override explicit children after spread', () => {
|
|
476
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
477
|
+
<div class="card">{props.children}</div>
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
component App() {
|
|
481
|
+
const extra = { id: '1' };
|
|
482
|
+
<Card {...extra} children="fallback text">
|
|
483
|
+
<span>{'template content'}</span>
|
|
484
|
+
</Card>
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
render(App);
|
|
488
|
+
expect(container.querySelector('.card span').textContent).toBe('template content');
|
|
489
|
+
expect(container.querySelector('.card').textContent).toBe('template content');
|
|
490
|
+
});
|
|
491
|
+
|
|
492
|
+
it('spread can override explicit children when no template children', () => {
|
|
493
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
494
|
+
<div class="card">{props.children}</div>
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
component App() {
|
|
498
|
+
const extra = { id: '1', children: 'from spread' };
|
|
499
|
+
<Card children="explicit" {...extra} />
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
render(App);
|
|
503
|
+
expect(container.querySelector('.card').textContent).toBe('from spread');
|
|
504
|
+
});
|
|
505
|
+
|
|
506
|
+
it('explicit children overrides spread children when it comes after', () => {
|
|
507
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
508
|
+
<div class="card">{props.children}</div>
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
component App() {
|
|
512
|
+
const extra = { id: '1', children: 'from spread' };
|
|
513
|
+
<Card {...extra} children="explicit" />
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
render(App);
|
|
517
|
+
expect(container.querySelector('.card').textContent).toBe('explicit');
|
|
518
|
+
});
|
|
417
519
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { parse, compile, compile_to_volar_mappings } from 'ripple
|
|
2
|
-
import {
|
|
1
|
+
import { parse, compile, compile_to_volar_mappings } from '@tsrx/ripple';
|
|
2
|
+
import { obfuscateIdentifier } from '@tsrx/core';
|
|
3
3
|
import type * as AST from 'estree';
|
|
4
4
|
|
|
5
5
|
function count_occurrences(string: string, subString: string): number {
|
|
@@ -59,7 +59,7 @@ describe('compiler > basics', () => {
|
|
|
59
59
|
const explicit_text = elements[1].children[0] as AST.TextNode;
|
|
60
60
|
|
|
61
61
|
expect(elements).toHaveLength(2);
|
|
62
|
-
expect(expression.type).toBe('
|
|
62
|
+
expect(expression.type).toBe('TSRXExpression');
|
|
63
63
|
expect((expression.expression as AST.Identifier).name).toBe('markup');
|
|
64
64
|
expect(explicit_text.type).toBe('Text');
|
|
65
65
|
expect((explicit_text.expression as AST.Identifier).name).toBe('markup');
|
|
@@ -321,15 +321,15 @@ describe('compiler > basics', () => {
|
|
|
321
321
|
// `;
|
|
322
322
|
// const result = compile_to_volar_mappings(source, 'test.ripple').code;
|
|
323
323
|
|
|
324
|
-
// expect(count_occurrences(result,
|
|
324
|
+
// expect(count_occurrences(result, obfuscateIdentifier('RippleArray'))).toBe(2);
|
|
325
325
|
// expect(count_occurrences(result, 'TA')).toBe(1);
|
|
326
|
-
// expect(count_occurrences(result,
|
|
326
|
+
// expect(count_occurrences(result, obfuscateIdentifier('RippleObject'))).toBe(2);
|
|
327
327
|
// expect(count_occurrences(result, 'TO')).toBe(1);
|
|
328
|
-
// expect(count_occurrences(result,
|
|
328
|
+
// expect(count_occurrences(result, obfuscateIdentifier('RippleSet'))).toBe(2);
|
|
329
329
|
// expect(count_occurrences(result, 'TS')).toBe(1);
|
|
330
|
-
// expect(count_occurrences(result,
|
|
330
|
+
// expect(count_occurrences(result, obfuscateIdentifier('RippleMap'))).toBe(2);
|
|
331
331
|
// expect(count_occurrences(result, 'TM')).toBe(1);
|
|
332
|
-
// expect(count_occurrences(result,
|
|
332
|
+
// expect(count_occurrences(result, obfuscateIdentifier('createRefKey'))).toBe(2);
|
|
333
333
|
// expect(count_occurrences(result, 'crk')).toBe(1);
|
|
334
334
|
// },
|
|
335
335
|
// );
|
|
@@ -347,11 +347,11 @@ describe('compiler > basics', () => {
|
|
|
347
347
|
// `;
|
|
348
348
|
// const result = compile_to_volar_mappings(source, 'test.ripple').code;
|
|
349
349
|
|
|
350
|
-
// expect(count_occurrences(result,
|
|
351
|
-
// expect(count_occurrences(result,
|
|
352
|
-
// expect(count_occurrences(result,
|
|
353
|
-
// expect(count_occurrences(result,
|
|
354
|
-
// expect(count_occurrences(result,
|
|
350
|
+
// expect(count_occurrences(result, obfuscateIdentifier('RippleArray'))).toBe(2);
|
|
351
|
+
// expect(count_occurrences(result, obfuscateIdentifier('RippleObject'))).toBe(2);
|
|
352
|
+
// expect(count_occurrences(result, obfuscateIdentifier('RippleSet'))).toBe(2);
|
|
353
|
+
// expect(count_occurrences(result, obfuscateIdentifier('RippleMap'))).toBe(2);
|
|
354
|
+
// expect(count_occurrences(result, obfuscateIdentifier('createRefKey'))).toBe(2);
|
|
355
355
|
// });
|
|
356
356
|
|
|
357
357
|
it('prints longhand tracked property values in to_ts output while preserving [\'#v\']', () => {
|
|
@@ -535,8 +535,9 @@ export component App() {
|
|
|
535
535
|
|
|
536
536
|
const result = compile(source, 'test.ripple', { mode: 'client' }).js.code;
|
|
537
537
|
|
|
538
|
+
// Template children should take precedence - explicit children prop should be removed
|
|
538
539
|
expect((result.match(/children:/g) || []).length).toBe(1);
|
|
539
|
-
expect(result).toContain('children: _$_.
|
|
540
|
+
expect(result).toContain('children: _$_.ripple_element(');
|
|
540
541
|
});
|
|
541
542
|
|
|
542
543
|
it('should not error on `this` MemberExpression with a UpdateExpression', () => {
|
|
@@ -654,4 +655,40 @@ export component App() {}`;
|
|
|
654
655
|
|
|
655
656
|
expect(result).toContain('class StringMap extends Map<string, string> {}');
|
|
656
657
|
});
|
|
658
|
+
|
|
659
|
+
it('wraps children in normalize_children for explicit children prop passed to component', () => {
|
|
660
|
+
const source = `
|
|
661
|
+
component Card(props) {
|
|
662
|
+
<div>{props.children}</div>
|
|
663
|
+
}
|
|
664
|
+
|
|
665
|
+
export component App() {
|
|
666
|
+
const content = 'hello';
|
|
667
|
+
|
|
668
|
+
<Card children={content} />
|
|
669
|
+
}
|
|
670
|
+
`;
|
|
671
|
+
|
|
672
|
+
const result = compile(source, 'test.ripple', { mode: 'client' }).js.code;
|
|
673
|
+
|
|
674
|
+
expect(result).toContain('_$_.normalize_children(');
|
|
675
|
+
});
|
|
676
|
+
|
|
677
|
+
it('uses spread_props for spreads that may contain children', () => {
|
|
678
|
+
const source = `
|
|
679
|
+
component Card(props) {
|
|
680
|
+
<div>{props.children}</div>
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
export component App() {
|
|
684
|
+
const props = { children: 'hello' };
|
|
685
|
+
|
|
686
|
+
<Card {...props} />
|
|
687
|
+
}
|
|
688
|
+
`;
|
|
689
|
+
|
|
690
|
+
const result = compile(source, 'test.ripple', { mode: 'client' }).js.code;
|
|
691
|
+
|
|
692
|
+
expect(result).toContain('_$_.spread_props(');
|
|
693
|
+
});
|
|
657
694
|
});
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
2
|
import { flushSync, track } from 'ripple';
|
|
3
|
-
import { compile } from 'ripple
|
|
3
|
+
import { compile } from '@tsrx/ripple';
|
|
4
4
|
|
|
5
5
|
describe('returns in prohibited scopes', () => {
|
|
6
6
|
it('throws error when return is used in module scope', () => {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Or used as vitest globalSetup
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { compile } from 'ripple
|
|
7
|
+
import { compile } from '@tsrx/ripple';
|
|
8
8
|
import { readFileSync, writeFileSync, mkdirSync, readdirSync } from 'fs';
|
|
9
9
|
import { join, basename } from 'path';
|
|
10
10
|
import { fileURLToPath } from 'url';
|
|
@@ -235,4 +235,118 @@ describe('basic server > components & composition', () => {
|
|
|
235
235
|
|
|
236
236
|
expect(document.querySelector('div')).toBeNull();
|
|
237
237
|
});
|
|
238
|
+
|
|
239
|
+
it('renders explicit children prop without spread', async () => {
|
|
240
|
+
component Card(props: PropsWithChildren<{}>) {
|
|
241
|
+
<div class="card">{props.children}</div>
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
component App() {
|
|
245
|
+
<Card children="fallback text" />
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
const { body } = await render(App);
|
|
249
|
+
const { document } = parseHtml(body);
|
|
250
|
+
expect(document.querySelector('.card').textContent).toBe('fallback text');
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
it('renders explicit children before spread', async () => {
|
|
254
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
255
|
+
<div class="card">{props.children}</div>
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
component App() {
|
|
259
|
+
const extra = { id: '1' };
|
|
260
|
+
<Card children="fallback text" {...extra} />
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
const { body } = await render(App);
|
|
264
|
+
const { document } = parseHtml(body);
|
|
265
|
+
expect(document.querySelector('.card').textContent).toBe('fallback text');
|
|
266
|
+
});
|
|
267
|
+
|
|
268
|
+
it('renders spread before explicit children', async () => {
|
|
269
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
270
|
+
<div class="card">{props.children}</div>
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
component App() {
|
|
274
|
+
const extra = { id: '1' };
|
|
275
|
+
<Card {...extra} children="fallback text" />
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
const { body } = await render(App);
|
|
279
|
+
const { document } = parseHtml(body);
|
|
280
|
+
expect(document.querySelector('.card').textContent).toBe('fallback text');
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
it('template children override explicit children before spread', async () => {
|
|
284
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
285
|
+
<div class="card">{props.children}</div>
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
component App() {
|
|
289
|
+
const extra = { id: '1' };
|
|
290
|
+
<Card children="fallback text" {...extra}>
|
|
291
|
+
<span>{'template content'}</span>
|
|
292
|
+
</Card>
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
const { body } = await render(App);
|
|
296
|
+
const { document } = parseHtml(body);
|
|
297
|
+
expect(document.querySelector('.card span').textContent).toBe('template content');
|
|
298
|
+
expect(document.querySelector('.card').textContent).toBe('template content');
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
it('template children override explicit children after spread', async () => {
|
|
302
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
303
|
+
<div class="card">{props.children}</div>
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
component App() {
|
|
307
|
+
const extra = { id: '1' };
|
|
308
|
+
<Card {...extra} children="fallback text">
|
|
309
|
+
<span>{'template content'}</span>
|
|
310
|
+
</Card>
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const { body } = await render(App);
|
|
314
|
+
const { document } = parseHtml(body);
|
|
315
|
+
expect(document.querySelector('.card span').textContent).toBe('template content');
|
|
316
|
+
expect(document.querySelector('.card').textContent).toBe('template content');
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
it('spread can override explicit children when no template children', async () => {
|
|
320
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
321
|
+
<div class="card">{props.children}</div>
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
component App() {
|
|
325
|
+
const extra = { id: '1', children: 'from spread' };
|
|
326
|
+
<Card
|
|
327
|
+
// @ts-ignore
|
|
328
|
+
children="explicit"
|
|
329
|
+
{...extra}
|
|
330
|
+
/>
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const { body } = await render(App);
|
|
334
|
+
const { document } = parseHtml(body);
|
|
335
|
+
expect(document.querySelector('.card').textContent).toBe('from spread');
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
it('explicit children overrides spread children when it comes after', async () => {
|
|
339
|
+
component Card(props: PropsWithChildren<{ id: string }>) {
|
|
340
|
+
<div class="card">{props.children}</div>
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
component App() {
|
|
344
|
+
const extra = { id: '1', children: 'from spread' };
|
|
345
|
+
<Card {...extra} children="explicit" />
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
const { body } = await render(App);
|
|
349
|
+
const { document } = parseHtml(body);
|
|
350
|
+
expect(document.querySelector('.card').textContent).toBe('explicit');
|
|
351
|
+
});
|
|
238
352
|
});
|
|
@@ -112,8 +112,9 @@ export component App() {
|
|
|
112
112
|
|
|
113
113
|
const result = compile(source, 'test.ripple', { mode: 'server' }).js.code;
|
|
114
114
|
|
|
115
|
+
// Template children should take precedence - explicit children prop should be removed
|
|
115
116
|
expect((result.match(/children:/g) || []).length).toBe(1);
|
|
116
|
-
expect(result).toContain('children: _$_.
|
|
117
|
+
expect(result).toContain('children: _$_.ripple_element(');
|
|
117
118
|
});
|
|
118
119
|
});
|
|
119
120
|
|
|
@@ -199,4 +200,40 @@ describe('compiler server block tests', () => {
|
|
|
199
200
|
|
|
200
201
|
expect(() => compile(source, 'test.ripple', { mode: 'server' })).toThrowError();
|
|
201
202
|
});
|
|
203
|
+
|
|
204
|
+
it('wraps children in normalize_children for explicit children prop passed to component', () => {
|
|
205
|
+
const source = `
|
|
206
|
+
component Card(props) {
|
|
207
|
+
<div>{props.children}</div>
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export component App() {
|
|
211
|
+
const content = 'hello';
|
|
212
|
+
|
|
213
|
+
<Card children={content} />
|
|
214
|
+
}
|
|
215
|
+
`;
|
|
216
|
+
|
|
217
|
+
const result = compile(source, 'test.ripple', { mode: 'server' }).js.code;
|
|
218
|
+
|
|
219
|
+
expect(result).toContain('_$_.normalize_children(');
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
it('passes spread through to component when spread may contain children', () => {
|
|
223
|
+
const source = `
|
|
224
|
+
component Card(props) {
|
|
225
|
+
<div>{props.children}</div>
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export component App() {
|
|
229
|
+
const props = { children: 'hello' };
|
|
230
|
+
|
|
231
|
+
<Card {...props} />
|
|
232
|
+
}
|
|
233
|
+
`;
|
|
234
|
+
|
|
235
|
+
const result = compile(source, 'test.ripple', { mode: 'server' }).js.code;
|
|
236
|
+
|
|
237
|
+
expect(result).toContain('...props');
|
|
238
|
+
});
|
|
202
239
|
});
|
package/tests/setup-server.js
CHANGED
package/types/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export type RippleElement = {
|
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
/** Type for implicit children fragments rendered with `{children}`. */
|
|
11
|
-
export type Children = RippleElement;
|
|
11
|
+
export type Children = RippleElement | Component | string | number | boolean | null | undefined;
|
|
12
12
|
|
|
13
13
|
export function mount(
|
|
14
14
|
component: Component,
|