ripple 0.3.72 → 0.3.76

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