ripple 0.3.71 → 0.3.74

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 (165) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/package.json +3 -3
  3. package/src/jsx-runtime.d.ts +2 -8
  4. package/src/runtime/index-client.js +3 -13
  5. package/src/runtime/internal/client/blocks.js +3 -25
  6. package/src/runtime/internal/client/for.js +80 -5
  7. package/src/runtime/internal/client/index.js +0 -2
  8. package/src/runtime/internal/client/types.d.ts +0 -10
  9. package/tests/client/__snapshots__/computed-properties.test.tsrx.snap +8 -0
  10. package/tests/client/__snapshots__/for.test.tsrx.snap +22 -0
  11. package/tests/client/__snapshots__/html.test.tsrx.snap +4 -0
  12. package/tests/client/array/array.copy-within.test.tsrx +19 -19
  13. package/tests/client/array/array.derived.test.tsrx +97 -109
  14. package/tests/client/array/array.iteration.test.tsrx +28 -28
  15. package/tests/client/array/array.mutations.test.tsrx +68 -68
  16. package/tests/client/array/array.static.test.tsrx +82 -92
  17. package/tests/client/array/array.to-methods.test.tsrx +15 -15
  18. package/tests/client/async-suspend.test.tsrx +180 -179
  19. package/tests/client/basic/__snapshots__/basic.attributes.test.tsrx.snap +2 -0
  20. package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +4 -0
  21. package/tests/client/basic/basic.attributes.test.tsrx +273 -317
  22. package/tests/client/basic/basic.collections.test.tsrx +59 -71
  23. package/tests/client/basic/basic.components.test.tsrx +196 -222
  24. package/tests/client/basic/basic.errors.test.tsrx +72 -78
  25. package/tests/client/basic/basic.events.test.tsrx +80 -85
  26. package/tests/client/basic/basic.get-set.test.tsrx +54 -64
  27. package/tests/client/basic/basic.hmr.test.tsrx +15 -19
  28. package/tests/client/basic/basic.reactivity.test.tsrx +121 -135
  29. package/tests/client/basic/basic.rendering.test.tsrx +273 -178
  30. package/tests/client/basic/basic.utilities.test.tsrx +8 -10
  31. package/tests/client/boundaries.test.tsrx +18 -18
  32. package/tests/client/compiler/compiler.assignments.test.tsrx +77 -76
  33. package/tests/client/compiler/compiler.attributes.test.tsrx +18 -14
  34. package/tests/client/compiler/compiler.basic.test.tsrx +364 -296
  35. package/tests/client/compiler/compiler.regex.test.tsrx +40 -44
  36. package/tests/client/compiler/compiler.tracked-access.test.tsrx +57 -38
  37. package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
  38. package/tests/client/compiler/compiler.typescript.test.tsrx +4 -3
  39. package/tests/client/composite/composite.dynamic-components.test.tsrx +41 -44
  40. package/tests/client/composite/composite.generics.test.tsrx +165 -167
  41. package/tests/client/composite/composite.props.test.tsrx +66 -74
  42. package/tests/client/composite/composite.reactivity.test.tsrx +132 -166
  43. package/tests/client/composite/composite.render.test.tsrx +92 -101
  44. package/tests/client/computed-properties.test.tsrx +14 -18
  45. package/tests/client/context.test.tsrx +14 -18
  46. package/tests/client/css/global-additional-cases.test.tsrx +491 -437
  47. package/tests/client/css/global-advanced-selectors.test.tsrx +169 -153
  48. package/tests/client/css/global-at-rules.test.tsrx +71 -66
  49. package/tests/client/css/global-basic.test.tsrx +105 -98
  50. package/tests/client/css/global-classes-ids.test.tsrx +128 -114
  51. package/tests/client/css/global-combinators.test.tsrx +83 -78
  52. package/tests/client/css/global-complex-nesting.test.tsrx +134 -120
  53. package/tests/client/css/global-edge-cases.test.tsrx +138 -120
  54. package/tests/client/css/global-keyframes.test.tsrx +108 -96
  55. package/tests/client/css/global-nested.test.tsrx +88 -78
  56. package/tests/client/css/global-pseudo.test.tsrx +104 -98
  57. package/tests/client/css/global-scoping.test.tsrx +145 -125
  58. package/tests/client/css/style-identifier.test.tsrx +62 -69
  59. package/tests/client/date.test.tsrx +83 -83
  60. package/tests/client/dynamic-elements.test.tsrx +227 -283
  61. package/tests/client/events.test.tsrx +252 -266
  62. package/tests/client/for.test.tsrx +120 -127
  63. package/tests/client/head.test.tsrx +40 -48
  64. package/tests/client/html.test.tsrx +37 -49
  65. package/tests/client/input-value.test.tsrx +1125 -1354
  66. package/tests/client/lazy-array.test.tsrx +10 -16
  67. package/tests/client/lazy-destructuring.test.tsrx +169 -221
  68. package/tests/client/map.test.tsrx +39 -41
  69. package/tests/client/media-query.test.tsrx +15 -19
  70. package/tests/client/object.test.tsrx +46 -56
  71. package/tests/client/portal.test.tsrx +31 -37
  72. package/tests/client/ref.test.tsrx +173 -193
  73. package/tests/client/return.test.tsrx +62 -37
  74. package/tests/client/set.test.tsrx +33 -33
  75. package/tests/client/svg.test.tsrx +195 -215
  76. package/tests/client/switch.test.tsrx +201 -191
  77. package/tests/client/track-async-hydration.test.tsrx +14 -18
  78. package/tests/client/tracked-index-access.test.tsrx +18 -28
  79. package/tests/client/try.test.tsrx +494 -619
  80. package/tests/client/tsx.test.tsrx +290 -371
  81. package/tests/client/typescript-generics.test.tsrx +121 -129
  82. package/tests/client/url/url.derived.test.tsrx +21 -25
  83. package/tests/client/url/url.parsing.test.tsrx +35 -35
  84. package/tests/client/url/url.partial-removal.test.tsrx +32 -32
  85. package/tests/client/url/url.reactivity.test.tsrx +68 -72
  86. package/tests/client/url/url.serialization.test.tsrx +8 -8
  87. package/tests/client/url-search-params/url-search-params.derived.test.tsrx +21 -27
  88. package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +16 -16
  89. package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +37 -37
  90. package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +56 -60
  91. package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +32 -34
  92. package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +9 -9
  93. package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +10 -10
  94. package/tests/hydration/compiled/client/basic.js +396 -325
  95. package/tests/hydration/compiled/client/composite.js +52 -44
  96. package/tests/hydration/compiled/client/for.js +734 -604
  97. package/tests/hydration/compiled/client/head.js +183 -103
  98. package/tests/hydration/compiled/client/html.js +93 -86
  99. package/tests/hydration/compiled/client/if-children.js +95 -71
  100. package/tests/hydration/compiled/client/if.js +113 -89
  101. package/tests/hydration/compiled/client/mixed-control-flow.js +225 -209
  102. package/tests/hydration/compiled/client/nested-control-flow.js +94 -98
  103. package/tests/hydration/compiled/client/reactivity.js +26 -24
  104. package/tests/hydration/compiled/client/return.js +8 -42
  105. package/tests/hydration/compiled/client/switch.js +208 -173
  106. package/tests/hydration/compiled/client/track-async-serialization.js +176 -128
  107. package/tests/hydration/compiled/client/try.js +29 -21
  108. package/tests/hydration/compiled/server/basic.js +210 -221
  109. package/tests/hydration/compiled/server/composite.js +13 -14
  110. package/tests/hydration/compiled/server/for.js +427 -444
  111. package/tests/hydration/compiled/server/head.js +199 -189
  112. package/tests/hydration/compiled/server/html.js +33 -41
  113. package/tests/hydration/compiled/server/if-children.js +114 -117
  114. package/tests/hydration/compiled/server/if.js +77 -83
  115. package/tests/hydration/compiled/server/mixed-control-flow.js +145 -150
  116. package/tests/hydration/compiled/server/nested-control-flow.js +10 -0
  117. package/tests/hydration/compiled/server/reactivity.js +24 -22
  118. package/tests/hydration/compiled/server/return.js +6 -18
  119. package/tests/hydration/compiled/server/switch.js +179 -176
  120. package/tests/hydration/compiled/server/track-async-serialization.js +88 -70
  121. package/tests/hydration/compiled/server/try.js +31 -35
  122. package/tests/hydration/components/basic.tsrx +216 -286
  123. package/tests/hydration/components/composite.tsrx +32 -42
  124. package/tests/hydration/components/events.tsrx +81 -101
  125. package/tests/hydration/components/for.tsrx +270 -336
  126. package/tests/hydration/components/head.tsrx +43 -39
  127. package/tests/hydration/components/hmr.tsrx +16 -22
  128. package/tests/hydration/components/html-in-template.tsrx +15 -21
  129. package/tests/hydration/components/html.tsrx +442 -526
  130. package/tests/hydration/components/if-children.tsrx +107 -125
  131. package/tests/hydration/components/if.tsrx +68 -90
  132. package/tests/hydration/components/mixed-control-flow.tsrx +65 -72
  133. package/tests/hydration/components/nested-control-flow.tsrx +202 -216
  134. package/tests/hydration/components/portal.tsrx +33 -41
  135. package/tests/hydration/components/reactivity.tsrx +26 -34
  136. package/tests/hydration/components/return.tsrx +4 -6
  137. package/tests/hydration/components/switch.tsrx +73 -78
  138. package/tests/hydration/components/track-async-serialization.tsrx +83 -93
  139. package/tests/hydration/components/try.tsrx +37 -51
  140. package/tests/hydration/switch.test.js +8 -8
  141. package/tests/server/await.test.tsrx +3 -3
  142. package/tests/server/basic.attributes.test.tsrx +120 -167
  143. package/tests/server/basic.components.test.tsrx +163 -197
  144. package/tests/server/basic.test.tsrx +298 -220
  145. package/tests/server/compiler.test.tsrx +142 -72
  146. package/tests/server/composite.props.test.tsrx +54 -58
  147. package/tests/server/composite.test.tsrx +165 -167
  148. package/tests/server/context.test.tsrx +13 -17
  149. package/tests/server/dynamic-elements.test.tsrx +103 -135
  150. package/tests/server/for.test.tsrx +115 -84
  151. package/tests/server/head.test.tsrx +31 -31
  152. package/tests/server/html-nesting-validation.test.tsrx +16 -8
  153. package/tests/server/if.test.tsrx +49 -59
  154. package/tests/server/lazy-destructuring.test.tsrx +288 -366
  155. package/tests/server/return.test.tsrx +58 -36
  156. package/tests/server/streaming-ssr.test.tsrx +4 -4
  157. package/tests/server/style-identifier.test.tsrx +58 -66
  158. package/tests/server/switch.test.tsrx +89 -97
  159. package/tests/server/track-async-serialization.test.tsrx +85 -103
  160. package/tests/server/try.test.tsrx +275 -360
  161. package/tests/utils/ref-types.test.js +72 -0
  162. package/tests/utils/vite-plugin-config.test.js +41 -74
  163. package/types/index.d.ts +1 -0
  164. package/src/runtime/internal/client/compat.js +0 -40
  165. package/tests/utils/compiler-compat-config.test.js +0 -38
@@ -10,17 +10,16 @@ import { did_error } from '../capture-error.js';
10
10
 
11
11
  describe('basic client > components & composition', () => {
12
12
  it('renders with component composition and children', () => {
13
- function Card(props: PropsWithChildren<{}>) {
14
- return <><div class="card">{props.children}</div></>;
13
+ function Card(props: PropsWithChildren<{}>) @{
14
+ <div class="card">{props.children}</div>
15
15
  }
16
16
 
17
- function Basic() {
18
- return <>
19
- function children() {
20
- return <><p>{'Card content here'}</p></>;
21
- }
22
- <Card {children} />
23
- </>;
17
+ function children() @{
18
+ <p>{'Card content here'}</p>
19
+ }
20
+
21
+ function Basic() @{
22
+ <Card {children} />
24
23
  }
25
24
 
26
25
  render(Basic);
@@ -33,23 +32,21 @@ describe('basic client > components & composition', () => {
33
32
  });
34
33
 
35
34
  it('does not render a falsy component call', () => {
36
- function Card(props: PropsWithChildrenOptional<{ test?: Component }>) {
37
- return <>
38
- <div class="card">
39
- if (props.children) {
35
+ function Card(props: PropsWithChildrenOptional<{ test?: Component }>) @{
36
+ <div class="card">
37
+ @if (props.children) {
38
+ <>
40
39
  {props.children}
41
- }
42
- </div>
43
- </>;
40
+ </>
41
+ }
42
+ </div>
44
43
  }
45
44
 
46
- function Basic() {
47
- return <>
48
- function test() {
49
- return <><p>{'Card content here'}</p></>;
50
- }
51
- <Card {test} />
52
- </>;
45
+ function Basic() @{
46
+ function test() @{
47
+ <p>{'Card content here'}</p>
48
+ }
49
+ <Card {test} />
53
50
  }
54
51
 
55
52
  render(Basic);
@@ -62,25 +59,28 @@ describe('basic client > components & composition', () => {
62
59
  });
63
60
 
64
61
  it('allows tracked variables alongside explicit component props', () => {
65
- function Card(props: PropsWithChildrenOptional<{ test?: Component }>) {
66
- return <>
67
- <div class="card">
68
- if (props.children) {
62
+ function Card(props: PropsWithChildrenOptional<{ test?: Component }>) @{
63
+ <div class="card">
64
+ @if (props.children) {
65
+ <>
69
66
  {props.children}
70
- }
71
- </div>
72
- </>;
67
+ </>
68
+ }
69
+ </div>
73
70
  }
74
71
 
75
- function Basic() {
76
- return <>
77
- let &[test] = track(false);
78
- function TestSlot() {
79
- return <><p>{'Card content here'}</p></>;
80
- }
72
+ function TestSlot() @{
73
+ <p>{'Card content here'}</p>
74
+ }
75
+
76
+ function Basic() @{
77
+ let &[test] = track(false);
78
+ <>
81
79
  <Card test={TestSlot} />
82
- <div>{test ? 'yes' : 'no'}</div>
83
- </>;
80
+ <div>
81
+ {test ? 'yes' : 'no'}
82
+ </div>
83
+ </>
84
84
  }
85
85
 
86
86
  render(Basic);
@@ -94,17 +94,16 @@ describe('basic client > components & composition', () => {
94
94
  });
95
95
 
96
96
  it('renders a component when children is set a component prop', () => {
97
- function Card(props: PropsWithChildren<{}>) {
98
- return <><div class="card">{props.children}</div></>;
97
+ function Card(props: PropsWithChildren<{}>) @{
98
+ <div class="card">{props.children}</div>
99
99
  }
100
100
 
101
- function Basic() {
102
- return <>
103
- function children() {
104
- return <><p>{'Card content here'}</p></>;
105
- }
106
- <Card {children} />
107
- </>;
101
+ function children() @{
102
+ <p>{'Card content here'}</p>
103
+ }
104
+
105
+ function Basic() @{
106
+ <Card {children} />
108
107
  }
109
108
 
110
109
  render(Basic);
@@ -117,12 +116,14 @@ describe('basic client > components & composition', () => {
117
116
  });
118
117
 
119
118
  it('renders direct component function calls as values', () => {
120
- function Test({ label }: { label: string }) {
121
- return <><span>{label}</span></>;
119
+ function Test({ label }: { label: string }) @{
120
+ <span>{label}</span>
122
121
  }
123
122
 
124
- function App() {
125
- return <>{Test({ label: 'direct call' })}</>;
123
+ function App() @{
124
+ <>
125
+ {Test({ label: 'direct call' })}
126
+ </>
126
127
  }
127
128
 
128
129
  render(App);
@@ -136,8 +137,8 @@ describe('basic client > components & composition', () => {
136
137
  return [item, 'B', null, undefined];
137
138
  }
138
139
 
139
- function App() {
140
- return <><Test /></>;
140
+ function App() @{
141
+ <Test />
141
142
  }
142
143
 
143
144
  render(App);
@@ -146,13 +147,13 @@ describe('basic client > components & composition', () => {
146
147
  });
147
148
 
148
149
  it('throws when a TSRXElement value is used as a component type', () => {
149
- function Test() {
150
- return <><span>{'value'}</span></>;
150
+ function Test() @{
151
+ <span>{'value'}</span>
151
152
  }
152
153
 
153
- function App() {
154
+ function App() @{
154
155
  const El = Test({});
155
- return <><El /></>;
156
+ <El />
156
157
  }
157
158
 
158
159
  expect(() => render(App)).toThrow('Invalid component type');
@@ -163,8 +164,8 @@ describe('basic client > components & composition', () => {
163
164
  return 'plain';
164
165
  }
165
166
 
166
- function App() {
167
- return <><Func /></>;
167
+ function App() @{
168
+ <Func />
168
169
  }
169
170
 
170
171
  render(App);
@@ -173,16 +174,12 @@ describe('basic client > components & composition', () => {
173
174
  });
174
175
 
175
176
  it('allows a compat-only function as a component type', () => {
176
- function CompatOnly() {
177
- return <tsx>
178
- <div>
179
- {'compat'}
180
- </div>
181
- </tsx>;
177
+ function CompatOnly() @{
178
+ <div>{'compat'}</div>
182
179
  }
183
180
 
184
- function App() {
185
- return <><CompatOnly /></>;
181
+ function App() @{
182
+ <CompatOnly />
186
183
  }
187
184
 
188
185
  render(App);
@@ -195,8 +192,8 @@ describe('basic client > components & composition', () => {
195
192
  variant: string;
196
193
  label: string;
197
194
  onClick: EventListener;
198
- }>) {
199
- return <><button class={props.variant} onClick={props.onClick}>{props.label}</button></>;
195
+ }>) @{
196
+ <button class={props.variant} onClick={props.onClick}>{props.label}</button>
200
197
  }
201
198
 
202
199
  function Card(props: PropsWithExtras<{
@@ -204,27 +201,27 @@ describe('basic client > components & composition', () => {
204
201
  content: string;
205
202
  buttonText: string;
206
203
  onAction: EventListener;
207
- }>) {
208
- return <>
209
- <div class="card">
210
- <h3>{props.title}</h3>
211
- <p>{props.content}</p>
212
- <Button variant="primary" label={props.buttonText} onClick={props.onAction} />
213
- </div>
214
- </>;
204
+ }>) @{
205
+ <div class="card">
206
+ <h3>{props.title}</h3>
207
+ <p>{props.content}</p>
208
+ <Button variant="primary" label={props.buttonText} onClick={props.onAction} />
209
+ </div>
215
210
  }
216
211
 
217
- function Basic() {
218
- return <>
219
- let &[clicked] = track(false);
212
+ function Basic() @{
213
+ let &[clicked] = track(false);
214
+ <>
220
215
  <Card
221
216
  title="Test Card"
222
217
  content="This is a test card"
223
218
  buttonText="Click me"
224
219
  onAction={() => (clicked = true)}
225
220
  />
226
- <div class="status">{clicked ? 'Clicked' : 'Not clicked'}</div>
227
- </>;
221
+ <div class="status">
222
+ {clicked ? 'Clicked' : 'Not clicked'}
223
+ </div>
224
+ </>
228
225
  }
229
226
 
230
227
  render(Basic);
@@ -251,27 +248,25 @@ describe('basic client > components & composition', () => {
251
248
  function ChildComponent(props: PropsWithExtras<{
252
249
  text: Tracked<string>;
253
250
  count: Tracked<number>;
254
- }>) {
255
- return <>
251
+ }>) @{
252
+ <>
256
253
  <div class="child-content">{props.text.value}</div>
257
254
  <div class="child-count">{props.count.value}</div>
258
- </>;
255
+ </>
259
256
  }
260
257
 
261
- function Basic() {
262
- return <>
263
- let &[message, messageTracked] = track('Hello');
264
- let &[number, numberTracked] = track(1);
258
+ function Basic() @{
259
+ let &[message, messageTracked] = track('Hello');
260
+ let &[number, numberTracked] = track(1);
261
+ <>
265
262
  <ChildComponent text={messageTracked} count={numberTracked} />
266
263
  <button
267
264
  onClick={() => {
268
265
  message = message === 'Hello' ? 'Goodbye' : 'Hello';
269
266
  number++;
270
267
  }}
271
- >
272
- {'Update Props'}
273
- </button>
274
- </>;
268
+ >{'Update Props'}</button>
269
+ </>
275
270
  }
276
271
 
277
272
  render(Basic);
@@ -297,16 +292,16 @@ describe('basic client > components & composition', () => {
297
292
  });
298
293
 
299
294
  it('updates explicit text children props reactively', () => {
300
- function TextProp(&{ children }: PropsWithChildren<{}>) {
301
- return <><div class="text-prop">{children}</div></>;
295
+ function TextProp(&{ children }: PropsWithChildren<{}>) @{
296
+ <div class="text-prop">{children}</div>
302
297
  }
303
298
 
304
- function Basic() {
305
- return <>
306
- let &[show] = track(false);
299
+ function Basic() @{
300
+ let &[show] = track(false);
301
+ <>
307
302
  <TextProp children={show ? 'hello' : ''} />
308
303
  <button class="show-text" onClick={() => (show = true)}>{'Show'}</button>
309
- </>;
304
+ </>
310
305
  }
311
306
 
312
307
  render(Basic);
@@ -320,7 +315,7 @@ describe('basic client > components & composition', () => {
320
315
  });
321
316
 
322
317
  it('it retains this context with bracketed prop functions and keeps original chaining', () => {
323
- function App() {
318
+ function App() @{
324
319
  const SYMBOL_PROP = Symbol();
325
320
  let &[hasError] = track(false);
326
321
  const obj: {
@@ -369,7 +364,7 @@ describe('basic client > components & composition', () => {
369
364
  });
370
365
  }
371
366
 
372
- return <>
367
+ <>
373
368
  <button onClick={() => obj['increment']()}>{'Increment'}</button>
374
369
  <button onClick={() => obj[SYMBOL_PROP]()}>{'Increment'}</button>
375
370
  <button onClick={trigger_nonexistent}>{'Nonexistent'}</button>
@@ -379,7 +374,7 @@ describe('basic client > components & composition', () => {
379
374
  <button onClick={() => obj.arr[obj.arr.length - 1]()}>{'BinaryExpression prop'}</button>
380
375
  <span>{obj.count.value}</span>
381
376
  <span>{hasError}</span>
382
- </>;
377
+ </>
383
378
  }
384
379
 
385
380
  render(App);
@@ -430,16 +425,16 @@ describe('basic client > components & composition', () => {
430
425
  });
431
426
 
432
427
  it('renders components as named and anonymous properties', () => {
433
- function Span() {
434
- return <><span>{'Hello from Span'}</span></>;
428
+ function Span() @{
429
+ <span>{'Hello from Span'}</span>
435
430
  }
436
431
 
437
- function Button({ children }: PropsWithChildren<{}>) {
438
- return <><button>{children}</button></>;
432
+ function Button({ children }: PropsWithChildren<{}>) @{
433
+ <button>{children}</button>
439
434
  }
440
435
 
441
- function ArrowButton({ children }: PropsWithChildren<{}>) {
442
- return <><button class="arrow-button">{children}</button></>;
436
+ function ArrowButton({ children }: PropsWithChildren<{}>) @{
437
+ <button class="arrow-button">{children}</button>
443
438
  }
444
439
 
445
440
  const UI = {
@@ -448,18 +443,17 @@ describe('basic client > components & composition', () => {
448
443
  arrowButton: ArrowButton,
449
444
  };
450
445
 
451
- function App() {
452
- return <>
453
- function children() {
454
- return <><span>{'Click me!'}</span></>;
455
- }
456
- <div>
457
- <h1>{'Component as Property Test'}</h1>
458
- <UI.span />
459
- <UI.button {children} />
460
- <UI.arrowButton {children} />
461
- </div>
462
- </>;
446
+ function children() @{
447
+ <span>{'Click me!'}</span>
448
+ }
449
+
450
+ function App() @{
451
+ <div>
452
+ <h1>{'Component as Property Test'}</h1>
453
+ <UI.span />
454
+ <UI.button {children} />
455
+ <UI.arrowButton {children} />
456
+ </div>
463
457
  }
464
458
 
465
459
  render(App);
@@ -478,16 +472,18 @@ describe('basic client > components & composition', () => {
478
472
  });
479
473
 
480
474
  it('handles empty string children', () => {
481
- function Button({ children }: PropsWithChildren<{}>) {
482
- return <>{children}</>;
475
+ function Button({ children }: PropsWithChildren<{}>) @{
476
+ <>
477
+ {children}
478
+ </>
483
479
  }
484
480
 
485
- function App() {
486
- return <>
487
- let content = '';
481
+ function App() @{
482
+ let content = '';
483
+ <>
488
484
  <Button>{''}</Button>
489
485
  <Button>{content}</Button>
490
- </>;
486
+ </>
491
487
  }
492
488
 
493
489
  expect(() => {
@@ -496,20 +492,20 @@ describe('basic client > components & composition', () => {
496
492
  });
497
493
 
498
494
  it('handles component without any output', () => {
499
- function Noop() {
500
- return <></>;
495
+ function Noop() @{
496
+ <></>
501
497
  }
502
498
 
503
- function Op() {
504
- return <><div>{'Some HTML content'}</div></>;
499
+ function Op() @{
500
+ <div>{'Some HTML content'}</div>
505
501
  }
506
502
 
507
- function App() {
508
- return <>
509
- let &[Content] = track(() => Noop);
503
+ function App() @{
504
+ let &[Content] = track(() => Noop);
505
+ <>
510
506
  <@Content />
511
507
  <button onClick={() => (Content = Op)}>{'Show Op'}</button>
512
- </>;
508
+ </>
513
509
  }
514
510
 
515
511
  render(App);
@@ -522,12 +518,12 @@ describe('basic client > components & composition', () => {
522
518
  });
523
519
 
524
520
  it('renders explicit children prop without spread', () => {
525
- function Card(props: PropsWithChildren<{}>) {
526
- return <><div class="card">{props.children}</div></>;
521
+ function Card(props: PropsWithChildren<{}>) @{
522
+ <div class="card">{props.children}</div>
527
523
  }
528
524
 
529
- function App() {
530
- return <><Card children="fallback text" /></>;
525
+ function App() @{
526
+ <Card children="fallback text" />
531
527
  }
532
528
 
533
529
  render(App);
@@ -535,15 +531,13 @@ describe('basic client > components & composition', () => {
535
531
  });
536
532
 
537
533
  it('renders explicit children before spread', () => {
538
- function Card(props: PropsWithChildren<{ id: string }>) {
539
- return <><div class="card">{props.children}</div></>;
534
+ function Card(props: PropsWithChildren<{ id: string }>) @{
535
+ <div class="card">{props.children}</div>
540
536
  }
541
537
 
542
- function App() {
543
- return <>
544
- const extra = { id: '1' };
545
- <Card children="fallback text" {...extra} />
546
- </>;
538
+ function App() @{
539
+ const extra = { id: '1' };
540
+ <Card children="fallback text" {...extra} />
547
541
  }
548
542
 
549
543
  render(App);
@@ -551,15 +545,13 @@ describe('basic client > components & composition', () => {
551
545
  });
552
546
 
553
547
  it('renders spread before explicit children', () => {
554
- function Card(props: PropsWithChildren<{ id: string }>) {
555
- return <><div class="card">{props.children}</div></>;
548
+ function Card(props: PropsWithChildren<{ id: string }>) @{
549
+ <div class="card">{props.children}</div>
556
550
  }
557
551
 
558
- function App() {
559
- return <>
560
- const extra = { id: '1' };
561
- <Card {...extra} children="fallback text" />
562
- </>;
552
+ function App() @{
553
+ const extra = { id: '1' };
554
+ <Card {...extra} children="fallback text" />
563
555
  }
564
556
 
565
557
  render(App);
@@ -567,17 +559,15 @@ describe('basic client > components & composition', () => {
567
559
  });
568
560
 
569
561
  it('template children override explicit children before spread', () => {
570
- function Card(props: PropsWithChildren<{ id: string }>) {
571
- return <><div class="card">{props.children}</div></>;
562
+ function Card(props: PropsWithChildren<{ id: string }>) @{
563
+ <div class="card">{props.children}</div>
572
564
  }
573
565
 
574
- function App() {
575
- return <>
576
- const extra = { id: '1' };
577
- <Card children="fallback text" {...extra}>
578
- <span>{'template content'}</span>
579
- </Card>
580
- </>;
566
+ function App() @{
567
+ const extra = { id: '1' };
568
+ <Card children="fallback text" {...extra}>
569
+ <span>{'template content'}</span>
570
+ </Card>
581
571
  }
582
572
 
583
573
  render(App);
@@ -586,17 +576,15 @@ describe('basic client > components & composition', () => {
586
576
  });
587
577
 
588
578
  it('template children override explicit children after spread', () => {
589
- function Card(props: PropsWithChildren<{ id: string }>) {
590
- return <><div class="card">{props.children}</div></>;
579
+ function Card(props: PropsWithChildren<{ id: string }>) @{
580
+ <div class="card">{props.children}</div>
591
581
  }
592
582
 
593
- function App() {
594
- return <>
595
- const extra = { id: '1' };
596
- <Card {...extra} children="fallback text">
597
- <span>{'template content'}</span>
598
- </Card>
599
- </>;
583
+ function App() @{
584
+ const extra = { id: '1' };
585
+ <Card {...extra} children="fallback text">
586
+ <span>{'template content'}</span>
587
+ </Card>
600
588
  }
601
589
 
602
590
  render(App);
@@ -605,19 +593,13 @@ describe('basic client > components & composition', () => {
605
593
  });
606
594
 
607
595
  it('spread can override explicit children when no template children', () => {
608
- function Card(props: PropsWithChildren<{ id: string }>) {
609
- return <><div class="card">{props.children}</div></>;
596
+ function Card(props: PropsWithChildren<{ id: string }>) @{
597
+ <div class="card">{props.children}</div>
610
598
  }
611
599
 
612
- function App() {
613
- return <>
614
- const extra = { id: '1', children: 'from spread' };
615
- <Card
616
- // @ts-expect-error children specified more than once
617
- children="explicit"
618
- {...extra}
619
- />
620
- </>;
600
+ function App() @{
601
+ const extra = { id: '1', children: 'from spread' };
602
+ <Card children="explicit" {...extra} />
621
603
  }
622
604
 
623
605
  render(App);
@@ -625,15 +607,13 @@ describe('basic client > components & composition', () => {
625
607
  });
626
608
 
627
609
  it('explicit children overrides spread children when it comes after', () => {
628
- function Card(props: PropsWithChildren<{ id: string }>) {
629
- return <><div class="card">{props.children}</div></>;
610
+ function Card(props: PropsWithChildren<{ id: string }>) @{
611
+ <div class="card">{props.children}</div>
630
612
  }
631
613
 
632
- function App() {
633
- return <>
634
- const extra = { id: '1', children: 'from spread' };
635
- <Card {...extra} children="explicit" />
636
- </>;
614
+ function App() @{
615
+ const extra = { id: '1', children: 'from spread' };
616
+ <Card {...extra} children="explicit" />
637
617
  }
638
618
 
639
619
  render(App);
@@ -641,20 +621,18 @@ describe('basic client > components & composition', () => {
641
621
  });
642
622
 
643
623
  it('renders components declared inside composite element children', () => {
644
- function Wrapper(props: PropsWithChildren<{}>) {
645
- return <><div class="wrapper">{props.children}</div></>;
624
+ function Wrapper(props: PropsWithChildren<{}>) @{
625
+ <div class="wrapper">{props.children}</div>
646
626
  }
647
627
 
648
- function App() {
649
- return <>
650
- <Wrapper>
651
- function Inner() {
652
- return <><span class="inner">{'inner content'}</span></>;
653
- }
628
+ function Inner() @{
629
+ <span class="inner">{'inner content'}</span>
630
+ }
654
631
 
655
- <Inner />
656
- </Wrapper>
657
- </>;
632
+ function App() @{
633
+ <Wrapper>
634
+ <Inner />
635
+ </Wrapper>
658
636
  }
659
637
 
660
638
  render(App);
@@ -662,29 +640,25 @@ describe('basic client > components & composition', () => {
662
640
  });
663
641
 
664
642
  it('renders nested components declared inside composite children with prop passing', () => {
665
- function Wrapper(props: PropsWithChildren<{}>) {
666
- return <><div class="wrapper">{props.children}</div></>;
667
- }
668
-
669
- function App() {
670
- return <>
671
- <Wrapper>
672
- function Z() {
673
- return <><div class="z">{'I am Z'}</div></>;
674
- }
675
-
676
- function Child(&{ Z }: { Z: Component }) {
677
- return <>
678
- <div class="child">
679
- {'Child Component: '}
680
- <Z />
681
- </div>
682
- </>;
683
- }
684
-
685
- <Child {Z} />
686
- </Wrapper>
687
- </>;
643
+ function Wrapper(props: PropsWithChildren<{}>) @{
644
+ <div class="wrapper">{props.children}</div>
645
+ }
646
+
647
+ function Z() @{
648
+ <div class="z">{'I am Z'}</div>
649
+ }
650
+
651
+ function Child(&{ Z }: { Z: Component }) @{
652
+ <div class="child">
653
+ {'Child Component: '}
654
+ <Z />
655
+ </div>
656
+ }
657
+
658
+ function App() @{
659
+ <Wrapper>
660
+ <Child {Z} />
661
+ </Wrapper>
688
662
  }
689
663
 
690
664
  render(App);