ripple 0.3.68 → 0.3.69

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.
Files changed (182) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/package.json +3 -3
  3. package/src/jsx-runtime.d.ts +2 -2
  4. package/src/runtime/element.js +1 -1
  5. package/src/runtime/index-client.js +11 -11
  6. package/src/runtime/index-server.js +7 -4
  7. package/src/runtime/internal/client/bindings.js +1 -1
  8. package/src/runtime/internal/client/blocks.js +13 -4
  9. package/src/runtime/internal/client/component.js +55 -0
  10. package/src/runtime/internal/client/composite.js +4 -2
  11. package/src/runtime/internal/client/expression.js +65 -7
  12. package/src/runtime/internal/client/hmr.js +54 -43
  13. package/src/runtime/internal/client/index.js +5 -1
  14. package/src/runtime/internal/client/portal.js +70 -69
  15. package/src/runtime/internal/client/render.js +3 -0
  16. package/src/runtime/internal/server/index.js +92 -8
  17. package/tests/client/__snapshots__/html.test.tsrx.snap +3 -3
  18. package/tests/client/array/array.copy-within.test.tsrx +33 -31
  19. package/tests/client/array/array.derived.test.tsrx +186 -169
  20. package/tests/client/array/array.iteration.test.tsrx +40 -37
  21. package/tests/client/array/array.mutations.test.tsrx +113 -101
  22. package/tests/client/array/array.static.test.tsrx +119 -101
  23. package/tests/client/array/array.to-methods.test.tsrx +24 -21
  24. package/tests/client/async-suspend.test.tsrx +247 -246
  25. package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +0 -1
  26. package/tests/client/basic/basic.attributes.test.tsrx +428 -423
  27. package/tests/client/basic/basic.collections.test.tsrx +109 -102
  28. package/tests/client/basic/basic.components.test.tsrx +323 -205
  29. package/tests/client/basic/basic.errors.test.tsrx +91 -91
  30. package/tests/client/basic/basic.events.test.tsrx +114 -115
  31. package/tests/client/basic/basic.get-set.test.tsrx +97 -87
  32. package/tests/client/basic/basic.hmr.test.tsrx +19 -16
  33. package/tests/client/basic/basic.reactivity.test.tsrx +199 -191
  34. package/tests/client/basic/basic.rendering.test.tsrx +272 -182
  35. package/tests/client/basic/basic.styling.test.tsrx +23 -22
  36. package/tests/client/basic/basic.utilities.test.tsrx +10 -8
  37. package/tests/client/boundaries.test.tsrx +26 -26
  38. package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +5 -5
  39. package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +5 -5
  40. package/tests/client/compiler/compiler.assignments.test.tsrx +77 -81
  41. package/tests/client/compiler/compiler.attributes.test.tsrx +15 -15
  42. package/tests/client/compiler/compiler.basic.test.tsrx +322 -314
  43. package/tests/client/compiler/compiler.regex.test.tsrx +44 -47
  44. package/tests/client/compiler/compiler.tracked-access.test.tsrx +38 -38
  45. package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
  46. package/tests/client/compiler/compiler.typescript.test.tsrx +2 -2
  47. package/tests/client/composite/composite.dynamic-components.test.tsrx +47 -48
  48. package/tests/client/composite/composite.generics.test.tsrx +168 -192
  49. package/tests/client/composite/composite.props.test.tsrx +97 -81
  50. package/tests/client/composite/composite.reactivity.test.tsrx +177 -147
  51. package/tests/client/composite/composite.render.test.tsrx +122 -105
  52. package/tests/client/computed-properties.test.tsrx +28 -28
  53. package/tests/client/context.test.tsrx +21 -21
  54. package/tests/client/css/global-additional-cases.test.tsrx +58 -58
  55. package/tests/client/css/global-advanced-selectors.test.tsrx +16 -16
  56. package/tests/client/css/global-at-rules.test.tsrx +10 -10
  57. package/tests/client/css/global-basic.test.tsrx +14 -14
  58. package/tests/client/css/global-classes-ids.test.tsrx +14 -14
  59. package/tests/client/css/global-combinators.test.tsrx +10 -10
  60. package/tests/client/css/global-complex-nesting.test.tsrx +14 -14
  61. package/tests/client/css/global-edge-cases.test.tsrx +18 -18
  62. package/tests/client/css/global-keyframes.test.tsrx +12 -12
  63. package/tests/client/css/global-nested.test.tsrx +10 -10
  64. package/tests/client/css/global-pseudo.test.tsrx +12 -12
  65. package/tests/client/css/global-scoping.test.tsrx +20 -20
  66. package/tests/client/css/style-identifier.test.tsrx +143 -291
  67. package/tests/client/date.test.tsrx +146 -133
  68. package/tests/client/dynamic-elements.test.tsrx +398 -365
  69. package/tests/client/events.test.tsrx +292 -290
  70. package/tests/client/for.test.tsrx +156 -153
  71. package/tests/client/head.test.tsrx +105 -96
  72. package/tests/client/html.test.tsrx +122 -26
  73. package/tests/client/input-value.test.tsrx +1361 -1314
  74. package/tests/client/lazy-array.test.tsrx +16 -13
  75. package/tests/client/lazy-destructuring.test.tsrx +257 -213
  76. package/tests/client/map.test.tsrx +65 -60
  77. package/tests/client/media-query.test.tsrx +22 -20
  78. package/tests/client/object.test.tsrx +87 -81
  79. package/tests/client/portal.test.tsrx +57 -51
  80. package/tests/client/ref.test.tsrx +233 -202
  81. package/tests/client/return.test.tsrx +71 -2560
  82. package/tests/client/set.test.tsrx +54 -45
  83. package/tests/client/svg.test.tsrx +216 -186
  84. package/tests/client/switch.test.tsrx +194 -193
  85. package/tests/client/track-async-hydration.test.tsrx +18 -14
  86. package/tests/client/tracked-index-access.test.tsrx +28 -18
  87. package/tests/client/try.test.tsrx +675 -548
  88. package/tests/client/tsx.test.tsrx +373 -311
  89. package/tests/client/typescript-generics.test.tsrx +145 -145
  90. package/tests/client/url/url.derived.test.tsrx +33 -28
  91. package/tests/client/url/url.parsing.test.tsrx +61 -51
  92. package/tests/client/url/url.partial-removal.test.tsrx +56 -48
  93. package/tests/client/url/url.reactivity.test.tsrx +142 -125
  94. package/tests/client/url/url.serialization.test.tsrx +13 -11
  95. package/tests/client/url-search-params/url-search-params.derived.test.tsrx +34 -29
  96. package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +25 -21
  97. package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +50 -45
  98. package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +111 -99
  99. package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +49 -43
  100. package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +14 -12
  101. package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +16 -14
  102. package/tests/hydration/basic.test.js +3 -3
  103. package/tests/hydration/compiled/client/basic.js +586 -651
  104. package/tests/hydration/compiled/client/composite.js +79 -104
  105. package/tests/hydration/compiled/client/events.js +140 -148
  106. package/tests/hydration/compiled/client/for.js +1005 -1018
  107. package/tests/hydration/compiled/client/head.js +124 -134
  108. package/tests/hydration/compiled/client/hmr.js +41 -48
  109. package/tests/hydration/compiled/client/html-in-template.js +38 -41
  110. package/tests/hydration/compiled/client/html.js +970 -1314
  111. package/tests/hydration/compiled/client/if-children.js +234 -249
  112. package/tests/hydration/compiled/client/if.js +182 -189
  113. package/tests/hydration/compiled/client/mixed-control-flow.js +347 -303
  114. package/tests/hydration/compiled/client/nested-control-flow.js +1084 -832
  115. package/tests/hydration/compiled/client/portal.js +65 -85
  116. package/tests/hydration/compiled/client/reactivity.js +84 -90
  117. package/tests/hydration/compiled/client/return.js +38 -1939
  118. package/tests/hydration/compiled/client/switch.js +218 -224
  119. package/tests/hydration/compiled/client/track-async-serialization.js +250 -259
  120. package/tests/hydration/compiled/client/try.js +123 -132
  121. package/tests/hydration/compiled/server/basic.js +773 -831
  122. package/tests/hydration/compiled/server/composite.js +166 -191
  123. package/tests/hydration/compiled/server/events.js +170 -184
  124. package/tests/hydration/compiled/server/for.js +851 -909
  125. package/tests/hydration/compiled/server/head.js +206 -216
  126. package/tests/hydration/compiled/server/hmr.js +64 -72
  127. package/tests/hydration/compiled/server/html-in-template.js +42 -76
  128. package/tests/hydration/compiled/server/html.js +1362 -1667
  129. package/tests/hydration/compiled/server/if-children.js +419 -445
  130. package/tests/hydration/compiled/server/if.js +194 -208
  131. package/tests/hydration/compiled/server/mixed-control-flow.js +249 -257
  132. package/tests/hydration/compiled/server/nested-control-flow.js +491 -515
  133. package/tests/hydration/compiled/server/portal.js +152 -160
  134. package/tests/hydration/compiled/server/reactivity.js +94 -106
  135. package/tests/hydration/compiled/server/return.js +28 -2172
  136. package/tests/hydration/compiled/server/switch.js +274 -286
  137. package/tests/hydration/compiled/server/track-async-serialization.js +340 -358
  138. package/tests/hydration/compiled/server/try.js +167 -185
  139. package/tests/hydration/components/basic.tsrx +320 -272
  140. package/tests/hydration/components/composite.tsrx +44 -32
  141. package/tests/hydration/components/events.tsrx +101 -91
  142. package/tests/hydration/components/for.tsrx +510 -452
  143. package/tests/hydration/components/head.tsrx +87 -80
  144. package/tests/hydration/components/hmr.tsrx +22 -17
  145. package/tests/hydration/components/html-in-template.tsrx +22 -17
  146. package/tests/hydration/components/html.tsrx +525 -443
  147. package/tests/hydration/components/if-children.tsrx +158 -148
  148. package/tests/hydration/components/if.tsrx +109 -95
  149. package/tests/hydration/components/mixed-control-flow.tsrx +100 -96
  150. package/tests/hydration/components/nested-control-flow.tsrx +215 -203
  151. package/tests/hydration/components/portal.tsrx +41 -34
  152. package/tests/hydration/components/reactivity.tsrx +37 -27
  153. package/tests/hydration/components/return.tsrx +12 -556
  154. package/tests/hydration/components/switch.tsrx +120 -114
  155. package/tests/hydration/components/track-async-serialization.tsrx +107 -91
  156. package/tests/hydration/components/try.tsrx +55 -40
  157. package/tests/hydration/html.test.js +4 -4
  158. package/tests/hydration/return.test.js +13 -532
  159. package/tests/server/await.test.tsrx +3 -3
  160. package/tests/server/basic.attributes.test.tsrx +264 -195
  161. package/tests/server/basic.components.test.tsrx +296 -169
  162. package/tests/server/basic.test.tsrx +300 -198
  163. package/tests/server/compiler.test.tsrx +62 -60
  164. package/tests/server/composite.props.test.tsrx +77 -63
  165. package/tests/server/composite.test.tsrx +168 -192
  166. package/tests/server/context.test.tsrx +18 -12
  167. package/tests/server/dynamic-elements.test.tsrx +197 -180
  168. package/tests/server/for.test.tsrx +85 -78
  169. package/tests/server/head.test.tsrx +50 -43
  170. package/tests/server/html-nesting-validation.test.tsrx +8 -8
  171. package/tests/server/if.test.tsrx +57 -51
  172. package/tests/server/lazy-destructuring.test.tsrx +366 -294
  173. package/tests/server/return.test.tsrx +76 -1355
  174. package/tests/server/streaming-ssr.test.tsrx +4 -75
  175. package/tests/server/style-identifier.test.tsrx +169 -148
  176. package/tests/server/switch.test.tsrx +91 -85
  177. package/tests/server/track-async-serialization.test.tsrx +105 -85
  178. package/tests/server/try.test.tsrx +374 -280
  179. package/tests/utils/compiler-compat-config.test.js +2 -2
  180. package/tests/utils/runtime-imports.test.js +10 -0
  181. package/types/index.d.ts +8 -0
  182. package/tests/client/__snapshots__/html.test.rsrx.snap +0 -40
@@ -8,17 +8,27 @@ import type {
8
8
  } from 'ripple';
9
9
 
10
10
  describe('basic server > components & composition', () => {
11
- it('renders with component composition and children', async () => {
12
- component Card(props: PropsWithChildren<{}>) {
13
- <div class="card">{props.children}</div>
11
+ async function render_expected_invalid_component(App: Component) {
12
+ const console_error_spy = vi.spyOn(console, 'error').mockImplementation(() => {});
13
+ try {
14
+ return await render(App);
15
+ } finally {
16
+ console_error_spy.mockRestore();
14
17
  }
18
+ }
15
19
 
16
- component Basic() {
17
- component children() {
18
- <p>{'Card content here'}</p>
19
- }
20
+ it('renders with component composition and children', async () => {
21
+ function Card(props: PropsWithChildren<{}>) {
22
+ return <><div class="card">{props.children}</div></>;
23
+ }
20
24
 
21
- <Card {children} />
25
+ function Basic() {
26
+ return <>
27
+ function children() {
28
+ return <><p>{'Card content here'}</p></>;
29
+ }
30
+ <Card {children} />
31
+ </>;
22
32
  }
23
33
 
24
34
  const { body } = await render(Basic);
@@ -32,19 +42,21 @@ describe('basic server > components & composition', () => {
32
42
  });
33
43
 
34
44
  it('does not render a falsy component call', async () => {
35
- component Card(props: PropsWithChildrenOptional<{ test: Component }>) {
36
- // @ts-expect-error - ripple automatically handles falsy children
37
- <div class="card">
38
- {props.children}
39
- </div>
40
- }
41
-
42
- component Basic() {
43
- component test() {
44
- <p>{'Card content here'}</p>
45
- }
46
-
47
- <Card {test} />
45
+ function Card(props: PropsWithChildrenOptional<{ test: Component }>) {
46
+ return <>
47
+ <div class="card">
48
+ {props.children}
49
+ </div>
50
+ </>;
51
+ }
52
+
53
+ function Basic() {
54
+ return <>
55
+ function test() {
56
+ return <><p>{'Card content here'}</p></>;
57
+ }
58
+ <Card {test} />
59
+ </>;
48
60
  }
49
61
 
50
62
  const { body } = await render(Basic);
@@ -59,15 +71,17 @@ describe('basic server > components & composition', () => {
59
71
  });
60
72
 
61
73
  it('renders a component when children is set a component prop', async () => {
62
- component Card(props: PropsWithChildren<{}>) {
63
- <div class="card">{props.children}</div>
74
+ function Card(props: PropsWithChildren<{}>) {
75
+ return <><div class="card">{props.children}</div></>;
64
76
  }
65
77
 
66
- component Basic() {
67
- component children() {
68
- <p>{'Card content here'}</p>
69
- }
70
- <Card {children} />
78
+ function Basic() {
79
+ return <>
80
+ function children() {
81
+ return <><p>{'Card content here'}</p></>;
82
+ }
83
+ <Card {children} />
84
+ </>;
71
85
  }
72
86
 
73
87
  const { body } = await render(Basic);
@@ -80,38 +94,119 @@ describe('basic server > components & composition', () => {
80
94
  expect(paragraph.textContent).toBe('Card content here');
81
95
  });
82
96
 
97
+ it('renders direct component function calls as values', async () => {
98
+ function Test({ label }: { label: string }) {
99
+ return <><span>{label}</span></>;
100
+ }
101
+
102
+ function App() {
103
+ return <>{Test({ label: 'direct call' })}</>;
104
+ }
105
+
106
+ const { body } = await render(App);
107
+ const { document } = parseHtml(body);
108
+
109
+ expect(document.querySelector('span')?.textContent).toBe('direct call');
110
+ });
111
+
112
+ it('renders arrays and primitives returned from component calls', async () => {
113
+ function Test() {
114
+ const item = <span>{'A'}</span>;
115
+ return [item, 'B', null, undefined];
116
+ }
117
+
118
+ function App() {
119
+ return <><Test /></>;
120
+ }
121
+
122
+ const { body } = await render(App);
123
+
124
+ expect(body).toContain('<span>A</span>');
125
+ expect(body).toContain('B');
126
+ });
127
+
128
+ it('throws when a TSRXElement value is used as a component type', async () => {
129
+ function Test() {
130
+ return <><span>{'value'}</span></>;
131
+ }
132
+
133
+ function App() {
134
+ const El = Test({});
135
+ return <><El /></>;
136
+ }
137
+
138
+ const result = await render_expected_invalid_component(App);
139
+
140
+ expect(result.topLevelError?.message).toContain('Invalid component type');
141
+ });
142
+
143
+ it('allows a plain function as a component type', async () => {
144
+ function Func() {
145
+ return 'plain';
146
+ }
147
+
148
+ function App() {
149
+ return <><Func /></>;
150
+ }
151
+
152
+ const { body } = await render(App);
153
+
154
+ expect(body).toBeHtml('plain');
155
+ });
156
+
157
+ it('allows a compat-only function as a component type', async () => {
158
+ function CompatOnly() {
159
+ return <tsx>
160
+ <div>
161
+ {'compat'}
162
+ </div>
163
+ </tsx>;
164
+ }
165
+
166
+ function App() {
167
+ return <><CompatOnly /></>;
168
+ }
169
+
170
+ const { body } = await render(App);
171
+
172
+ expect(body).toBeHtml('<div>compat</div>');
173
+ });
174
+
83
175
  it('renders with nested components and prop passing', async () => {
84
- component Button(props: PropsWithExtras<{
176
+ function Button(props: PropsWithExtras<{
85
177
  variant: string;
86
178
  label: string;
87
179
  onClick: EventListener;
88
180
  }>) {
89
- <button class={props.variant} onClick={props.onClick}>{props.label}</button>
181
+ return <><button class={props.variant} onClick={props.onClick}>{props.label}</button></>;
90
182
  }
91
183
 
92
- component Card(props: PropsWithExtras<{
184
+ function Card(props: PropsWithExtras<{
93
185
  title: string;
94
186
  content: string;
95
187
  buttonText: string;
96
188
  onAction: EventListener;
97
189
  }>) {
98
- <div class="card">
99
- <h3>{props.title}</h3>
100
- <p>{props.content}</p>
101
- <Button variant="primary" label={props.buttonText} onClick={props.onAction} />
102
- </div>
103
- }
104
-
105
- component Basic() {
106
- let &[clicked] = track(false);
107
-
108
- <Card
109
- title="Test Card"
110
- content="This is a test card"
111
- buttonText="Click me"
112
- onAction={() => (clicked = true)}
113
- />
114
- <div class="status">{clicked ? 'Clicked' : 'Not clicked'}</div>
190
+ return <>
191
+ <div class="card">
192
+ <h3>{props.title}</h3>
193
+ <p>{props.content}</p>
194
+ <Button variant="primary" label={props.buttonText} onClick={props.onAction} />
195
+ </div>
196
+ </>;
197
+ }
198
+
199
+ function Basic() {
200
+ return <>
201
+ let &[clicked] = track(false);
202
+ <Card
203
+ title="Test Card"
204
+ content="This is a test card"
205
+ buttonText="Click me"
206
+ onAction={() => (clicked = true)}
207
+ />
208
+ <div class="status">{clicked ? 'Clicked' : 'Not clicked'}</div>
209
+ </>;
115
210
  }
116
211
 
117
212
  const { body } = await render(Basic);
@@ -131,27 +226,30 @@ describe('basic server > components & composition', () => {
131
226
  });
132
227
 
133
228
  it('renders with reactive component props', async () => {
134
- component ChildComponent(props: PropsWithExtras<{
229
+ function ChildComponent(props: PropsWithExtras<{
135
230
  text: Tracked<string>;
136
231
  count: Tracked<number>;
137
232
  }>) {
138
- <div class="child-content">{props.text.value}</div>
139
- <div class="child-count">{props.count.value}</div>
140
- }
141
-
142
- component Basic() {
143
- let &[message, messageTracked] = track('Hello');
144
- let &[number, numberTracked] = track(1);
145
-
146
- <ChildComponent text={messageTracked} count={numberTracked} />
147
- <button
148
- onClick={() => {
149
- message = message === 'Hello' ? 'Goodbye' : 'Hello';
150
- number++;
151
- }}
152
- >
153
- {'Update Props'}
154
- </button>
233
+ return <>
234
+ <div class="child-content">{props.text.value}</div>
235
+ <div class="child-count">{props.count.value}</div>
236
+ </>;
237
+ }
238
+
239
+ function Basic() {
240
+ return <>
241
+ let &[message, messageTracked] = track('Hello');
242
+ let &[number, numberTracked] = track(1);
243
+ <ChildComponent text={messageTracked} count={numberTracked} />
244
+ <button
245
+ onClick={() => {
246
+ message = message === 'Hello' ? 'Goodbye' : 'Hello';
247
+ number++;
248
+ }}
249
+ >
250
+ {'Update Props'}
251
+ </button>
252
+ </>;
155
253
  }
156
254
 
157
255
  const { body } = await render(Basic);
@@ -165,29 +263,36 @@ describe('basic server > components & composition', () => {
165
263
  });
166
264
 
167
265
  it('renders components as named and anonymous properties', async () => {
266
+ function Span() {
267
+ return <><span>{'Hello from Span'}</span></>;
268
+ }
269
+
270
+ function Button({ children }: PropsWithChildren<{}>) {
271
+ return <><button>{children}</button></>;
272
+ }
273
+
274
+ function ArrowButton({ children }: PropsWithChildren<{}>) {
275
+ return <><button class="arrow-button">{children}</button></>;
276
+ }
277
+
168
278
  const UI = {
169
- span: component Span() {
170
- <span>{'Hello from Span'}</span>
171
- },
172
- button: component({ children }: PropsWithChildren<{}>) {
173
- <button>{children}</button>
174
- },
175
- arrowButton: component({ children }: PropsWithChildren<{}>) => {
176
- <button class="arrow-button">{children}</button>
177
- },
279
+ span: Span,
280
+ button: Button,
281
+ arrowButton: ArrowButton,
178
282
  };
179
283
 
180
- component App() {
181
- component children() {
182
- <span>{'Click me!'}</span>
183
- }
184
-
185
- <div>
186
- <h1>{'Component as Property Test'}</h1>
187
- <UI.span />
188
- <UI.button {children} />
189
- <UI.arrowButton {children} />
190
- </div>
284
+ function App() {
285
+ return <>
286
+ function children() {
287
+ return <><span>{'Click me!'}</span></>;
288
+ }
289
+ <div>
290
+ <h1>{'Component as Property Test'}</h1>
291
+ <UI.span />
292
+ <UI.button {children} />
293
+ <UI.arrowButton {children} />
294
+ </div>
295
+ </>;
191
296
  }
192
297
 
193
298
  const { body } = await render(App);
@@ -207,14 +312,16 @@ describe('basic server > components & composition', () => {
207
312
  });
208
313
 
209
314
  it('handles empty string children', async () => {
210
- component Button({ children }: PropsWithChildren<{}>) {
211
- {children}
315
+ function Button({ children }: PropsWithChildren<{}>) {
316
+ return <>{children}</>;
212
317
  }
213
318
 
214
- component App() {
215
- let content = '';
216
- <Button>{''}</Button>
217
- <Button>{content}</Button>
319
+ function App() {
320
+ return <>
321
+ let content = '';
322
+ <Button>{''}</Button>
323
+ <Button>{content}</Button>
324
+ </>;
218
325
  }
219
326
 
220
327
  const { body } = await render(App);
@@ -224,17 +331,19 @@ describe('basic server > components & composition', () => {
224
331
  });
225
332
 
226
333
  it('handles component without any output', async () => {
227
- component Noop() {
228
- // No output
334
+ function Noop() {
335
+ return <></>;
229
336
  }
230
337
 
231
- component Op() {
232
- <div>{'Some HTML content'}</div>
338
+ function Op() {
339
+ return <><div>{'Some HTML content'}</div></>;
233
340
  }
234
341
 
235
- component App() {
236
- let Content = track(() => Noop);
237
- <@Content />
342
+ function App() {
343
+ return <>
344
+ let Content = track(() => Noop);
345
+ <@Content />
346
+ </>;
238
347
  }
239
348
 
240
349
  const { body } = await render(App);
@@ -244,12 +353,12 @@ describe('basic server > components & composition', () => {
244
353
  });
245
354
 
246
355
  it('renders explicit children prop without spread', async () => {
247
- component Card(props: PropsWithChildren<{}>) {
248
- <div class="card">{props.children}</div>
356
+ function Card(props: PropsWithChildren<{}>) {
357
+ return <><div class="card">{props.children}</div></>;
249
358
  }
250
359
 
251
- component App() {
252
- <Card children="fallback text" />
360
+ function App() {
361
+ return <><Card children="fallback text" /></>;
253
362
  }
254
363
 
255
364
  const { body } = await render(App);
@@ -258,13 +367,15 @@ describe('basic server > components & composition', () => {
258
367
  });
259
368
 
260
369
  it('renders explicit children before spread', async () => {
261
- component Card(props: PropsWithChildren<{ id: string }>) {
262
- <div class="card">{props.children}</div>
370
+ function Card(props: PropsWithChildren<{ id: string }>) {
371
+ return <><div class="card">{props.children}</div></>;
263
372
  }
264
373
 
265
- component App() {
266
- const extra = { id: '1' };
267
- <Card children="fallback text" {...extra} />
374
+ function App() {
375
+ return <>
376
+ const extra = { id: '1' };
377
+ <Card children="fallback text" {...extra} />
378
+ </>;
268
379
  }
269
380
 
270
381
  const { body } = await render(App);
@@ -273,13 +384,15 @@ describe('basic server > components & composition', () => {
273
384
  });
274
385
 
275
386
  it('renders spread before explicit children', async () => {
276
- component Card(props: PropsWithChildren<{ id: string }>) {
277
- <div class="card">{props.children}</div>
387
+ function Card(props: PropsWithChildren<{ id: string }>) {
388
+ return <><div class="card">{props.children}</div></>;
278
389
  }
279
390
 
280
- component App() {
281
- const extra = { id: '1' };
282
- <Card {...extra} children="fallback text" />
391
+ function App() {
392
+ return <>
393
+ const extra = { id: '1' };
394
+ <Card {...extra} children="fallback text" />
395
+ </>;
283
396
  }
284
397
 
285
398
  const { body } = await render(App);
@@ -288,15 +401,17 @@ describe('basic server > components & composition', () => {
288
401
  });
289
402
 
290
403
  it('template children override explicit children before spread', async () => {
291
- component Card(props: PropsWithChildren<{ id: string }>) {
292
- <div class="card">{props.children}</div>
404
+ function Card(props: PropsWithChildren<{ id: string }>) {
405
+ return <><div class="card">{props.children}</div></>;
293
406
  }
294
407
 
295
- component App() {
296
- const extra = { id: '1' };
297
- <Card children="fallback text" {...extra}>
298
- <span>{'template content'}</span>
299
- </Card>
408
+ function App() {
409
+ return <>
410
+ const extra = { id: '1' };
411
+ <Card children="fallback text" {...extra}>
412
+ <span>{'template content'}</span>
413
+ </Card>
414
+ </>;
300
415
  }
301
416
 
302
417
  const { body } = await render(App);
@@ -306,15 +421,17 @@ describe('basic server > components & composition', () => {
306
421
  });
307
422
 
308
423
  it('template children override explicit children after spread', async () => {
309
- component Card(props: PropsWithChildren<{ id: string }>) {
310
- <div class="card">{props.children}</div>
424
+ function Card(props: PropsWithChildren<{ id: string }>) {
425
+ return <><div class="card">{props.children}</div></>;
311
426
  }
312
427
 
313
- component App() {
314
- const extra = { id: '1' };
315
- <Card {...extra} children="fallback text">
316
- <span>{'template content'}</span>
317
- </Card>
428
+ function App() {
429
+ return <>
430
+ const extra = { id: '1' };
431
+ <Card {...extra} children="fallback text">
432
+ <span>{'template content'}</span>
433
+ </Card>
434
+ </>;
318
435
  }
319
436
 
320
437
  const { body } = await render(App);
@@ -324,17 +441,19 @@ describe('basic server > components & composition', () => {
324
441
  });
325
442
 
326
443
  it('spread can override explicit children when no template children', async () => {
327
- component Card(props: PropsWithChildren<{ id: string }>) {
328
- <div class="card">{props.children}</div>
444
+ function Card(props: PropsWithChildren<{ id: string }>) {
445
+ return <><div class="card">{props.children}</div></>;
329
446
  }
330
447
 
331
- component App() {
332
- const extra = { id: '1', children: 'from spread' };
333
- <Card
334
- // @ts-ignore
335
- children="explicit"
336
- {...extra}
337
- />
448
+ function App() {
449
+ return <>
450
+ const extra = { id: '1', children: 'from spread' };
451
+ <Card
452
+ // @ts-ignore
453
+ children="explicit"
454
+ {...extra}
455
+ />
456
+ </>;
338
457
  }
339
458
 
340
459
  const { body } = await render(App);
@@ -343,13 +462,15 @@ describe('basic server > components & composition', () => {
343
462
  });
344
463
 
345
464
  it('explicit children overrides spread children when it comes after', async () => {
346
- component Card(props: PropsWithChildren<{ id: string }>) {
347
- <div class="card">{props.children}</div>
465
+ function Card(props: PropsWithChildren<{ id: string }>) {
466
+ return <><div class="card">{props.children}</div></>;
348
467
  }
349
468
 
350
- component App() {
351
- const extra = { id: '1', children: 'from spread' };
352
- <Card {...extra} children="explicit" />
469
+ function App() {
470
+ return <>
471
+ const extra = { id: '1', children: 'from spread' };
472
+ <Card {...extra} children="explicit" />
473
+ </>;
353
474
  }
354
475
 
355
476
  const { body } = await render(App);
@@ -358,18 +479,20 @@ describe('basic server > components & composition', () => {
358
479
  });
359
480
 
360
481
  it('renders components declared inside composite element children', async () => {
361
- component Wrapper(props: PropsWithChildren<{}>) {
362
- <div class="wrapper">{props.children}</div>
482
+ function Wrapper(props: PropsWithChildren<{}>) {
483
+ return <><div class="wrapper">{props.children}</div></>;
363
484
  }
364
485
 
365
- component App() {
366
- <Wrapper>
367
- component Inner() {
368
- <span class="inner">{'inner content'}</span>
369
- }
486
+ function App() {
487
+ return <>
488
+ <Wrapper>
489
+ function Inner() {
490
+ return <><span class="inner">{'inner content'}</span></>;
491
+ }
370
492
 
371
- <Inner />
372
- </Wrapper>
493
+ <Inner />
494
+ </Wrapper>
495
+ </>;
373
496
  }
374
497
 
375
498
  const { body } = await render(App);
@@ -378,25 +501,29 @@ describe('basic server > components & composition', () => {
378
501
  });
379
502
 
380
503
  it('renders nested components declared inside composite children with prop passing', async () => {
381
- component Wrapper(props: PropsWithChildren<{}>) {
382
- <div class="wrapper">{props.children}</div>
383
- }
384
-
385
- component App() {
386
- <Wrapper>
387
- component Z() {
388
- <div class="z">{'I am Z'}</div>
389
- }
390
-
391
- component Child(&{ Z }: { Z: Component }) {
392
- <div class="child">
393
- {'Child Component: '}
394
- <Z />
395
- </div>
396
- }
397
-
398
- <Child {Z} />
399
- </Wrapper>
504
+ function Wrapper(props: PropsWithChildren<{}>) {
505
+ return <><div class="wrapper">{props.children}</div></>;
506
+ }
507
+
508
+ function App() {
509
+ return <>
510
+ <Wrapper>
511
+ function Z() {
512
+ return <><div class="z">{'I am Z'}</div></>;
513
+ }
514
+
515
+ function Child(&{ Z }: { Z: Component }) {
516
+ return <>
517
+ <div class="child">
518
+ {'Child Component: '}
519
+ <Z />
520
+ </div>
521
+ </>;
522
+ }
523
+
524
+ <Child {Z} />
525
+ </Wrapper>
526
+ </>;
400
527
  }
401
528
 
402
529
  const { body } = await render(App);