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
@@ -105,14 +105,12 @@ describe('use value()', () => {
105
105
  it('should update value on input', () => {
106
106
  const logs: string[] = [];
107
107
 
108
- function App() {
109
- return <>
110
- const text = track('');
111
- effect(() => {
112
- logs.push('text changed', text.value);
113
- });
114
- <input type="text" ref={bindValue(text)} />
115
- </>;
108
+ function App() @{
109
+ const text = track('');
110
+ effect(() => {
111
+ logs.push('text changed', text.value);
112
+ });
113
+ <input type="text" ref={bindValue(text)} />
116
114
  }
117
115
  render(App);
118
116
  flushSync();
@@ -128,14 +126,12 @@ describe('use value()', () => {
128
126
  it('should update value on input with getter and setter', () => {
129
127
  const logs: string[] = [];
130
128
 
131
- function App() {
132
- return <>
133
- const text = new RippleObject({ value: '' });
134
- effect(() => {
135
- logs.push('text changed', text.value);
136
- });
137
- <input type="text" ref={bindValue(() => text.value, (v) => (text.value = v))} />
138
- </>;
129
+ function App() @{
130
+ const text = new RippleObject({ value: '' });
131
+ effect(() => {
132
+ logs.push('text changed', text.value);
133
+ });
134
+ <input type="text" ref={bindValue(() => text.value, (v) => (text.value = v))} />
139
135
  }
140
136
  render(App);
141
137
  flushSync();
@@ -151,14 +147,12 @@ describe('use value()', () => {
151
147
  it('should update value on input with a predefined value', () => {
152
148
  const logs: string[] = [];
153
149
 
154
- function App() {
155
- return <>
156
- const text = track('foo');
157
- effect(() => {
158
- logs.push('text changed', text.value);
159
- });
160
- <input type="text" ref={bindValue(text)} />
161
- </>;
150
+ function App() @{
151
+ const text = track('foo');
152
+ effect(() => {
153
+ logs.push('text changed', text.value);
154
+ });
155
+ <input type="text" ref={bindValue(text)} />
162
156
  }
163
157
  render(App);
164
158
  flushSync();
@@ -175,14 +169,12 @@ describe('use value()', () => {
175
169
  it('should update value on input with a predefined value and with a getter and setter', () => {
176
170
  const logs: string[] = [];
177
171
 
178
- function App() {
179
- return <>
180
- const text = new RippleObject({ value: 'foo' });
181
- effect(() => {
182
- logs.push('text changed', text.value);
183
- });
184
- <input type="text" ref={bindValue(() => text.value, (v) => (text.value = v))} />
185
- </>;
172
+ function App() @{
173
+ const text = new RippleObject({ value: 'foo' });
174
+ effect(() => {
175
+ logs.push('text changed', text.value);
176
+ });
177
+ <input type="text" ref={bindValue(() => text.value, (v) => (text.value = v))} />
186
178
  }
187
179
  render(App);
188
180
  flushSync();
@@ -197,14 +189,12 @@ describe('use value()', () => {
197
189
  });
198
190
 
199
191
  it('should update text input element when tracked value changes', () => {
200
- function App() {
201
- return <>
202
- const text = track('initial');
203
- <div>
204
- <input type="text" ref={bindValue(text)} />
205
- <button onClick={() => (text.value = 'updated')}>{'Update'}</button>
206
- </div>
207
- </>;
192
+ function App() @{
193
+ const text = track('initial');
194
+ <div>
195
+ <input type="text" ref={bindValue(text)} />
196
+ <button onClick={() => (text.value = 'updated')}>{'Update'}</button>
197
+ </div>
208
198
  }
209
199
  render(App);
210
200
  flushSync();
@@ -221,14 +211,12 @@ describe('use value()', () => {
221
211
  });
222
212
 
223
213
  it('should update text input element when tracked value changes with a getter and setter', () => {
224
- function App() {
225
- return <>
226
- const text = new RippleObject({ value: 'initial' });
227
- <div>
228
- <input type="text" ref={bindValue(() => text.value, (v) => (text.value = v))} />
229
- <button onClick={() => (text.value = 'updated')}>{'Update'}</button>
230
- </div>
231
- </>;
214
+ function App() @{
215
+ const text = new RippleObject({ value: 'initial' });
216
+ <div>
217
+ <input type="text" ref={bindValue(() => text.value, (v) => (text.value = v))} />
218
+ <button onClick={() => (text.value = 'updated')}>{'Update'}</button>
219
+ </div>
232
220
  }
233
221
  render(App);
234
222
  flushSync();
@@ -247,14 +235,12 @@ describe('use value()', () => {
247
235
  it('should update checked on input', () => {
248
236
  const logs: (string | boolean)[] = [];
249
237
 
250
- function App() {
251
- return <>
252
- const value = track(false);
253
- effect(() => {
254
- logs.push('checked changed', value.value);
255
- });
256
- <input type="checkbox" ref={bindChecked(value)} />
257
- </>;
238
+ function App() @{
239
+ const value = track(false);
240
+ effect(() => {
241
+ logs.push('checked changed', value.value);
242
+ });
243
+ <input type="checkbox" ref={bindChecked(value)} />
258
244
  }
259
245
  render(App);
260
246
  flushSync();
@@ -271,17 +257,12 @@ describe('use value()', () => {
271
257
  it('should update checked on input with a getter and setter', () => {
272
258
  const logs: (string | boolean)[] = [];
273
259
 
274
- function App() {
275
- return <>
276
- const obj = new RippleObject({ value: false });
277
- effect(() => {
278
- logs.push('checked changed', obj.value);
279
- });
280
- <input
281
- type="checkbox"
282
- ref={bindChecked(() => obj.value, (v: boolean) => (obj.value = v))}
283
- />
284
- </>;
260
+ function App() @{
261
+ const obj = new RippleObject({ value: false });
262
+ effect(() => {
263
+ logs.push('checked changed', obj.value);
264
+ });
265
+ <input type="checkbox" ref={bindChecked(() => obj.value, (v: boolean) => (obj.value = v))} />
285
266
  }
286
267
  render(App);
287
268
  flushSync();
@@ -296,14 +277,12 @@ describe('use value()', () => {
296
277
  });
297
278
 
298
279
  it('should update checkbox element when tracked value changes', () => {
299
- function App() {
300
- return <>
301
- const value = track(false);
302
- <div>
303
- <input type="checkbox" ref={bindChecked(value)} />
304
- <button onClick={() => (value.value = true)}>{'Check'}</button>
305
- </div>
306
- </>;
280
+ function App() @{
281
+ const value = track(false);
282
+ <div>
283
+ <input type="checkbox" ref={bindChecked(value)} />
284
+ <button onClick={() => (value.value = true)}>{'Check'}</button>
285
+ </div>
307
286
  }
308
287
  render(App);
309
288
  flushSync();
@@ -320,17 +299,15 @@ describe('use value()', () => {
320
299
  });
321
300
 
322
301
  it('should update checkbox element when tracked value changes with a getter and setter', () => {
323
- function App() {
324
- return <>
325
- const obj = new RippleObject({ value: false });
326
- <div>
327
- <input
328
- type="checkbox"
329
- ref={bindChecked(() => obj.value, (v: boolean) => (obj.value = v))}
330
- />
331
- <button onClick={() => (obj.value = true)}>{'Check'}</button>
332
- </div>
333
- </>;
302
+ function App() @{
303
+ const obj = new RippleObject({ value: false });
304
+ <div>
305
+ <input
306
+ type="checkbox"
307
+ ref={bindChecked(() => obj.value, (v: boolean) => (obj.value = v))}
308
+ />
309
+ <button onClick={() => (obj.value = true)}>{'Check'}</button>
310
+ </div>
334
311
  }
335
312
  render(App);
336
313
  flushSync();
@@ -349,14 +326,12 @@ describe('use value()', () => {
349
326
  it('should update indeterminate on input', () => {
350
327
  const logs: (string | boolean)[] = [];
351
328
 
352
- function App() {
353
- return <>
354
- const value = track(false);
355
- effect(() => {
356
- logs.push('indeterminate changed', value.value);
357
- });
358
- <input type="checkbox" ref={bindIndeterminate(value)} />
359
- </>;
329
+ function App() @{
330
+ const value = track(false);
331
+ effect(() => {
332
+ logs.push('indeterminate changed', value.value);
333
+ });
334
+ <input type="checkbox" ref={bindIndeterminate(value)} />
360
335
  }
361
336
  render(App);
362
337
  flushSync();
@@ -375,17 +350,15 @@ describe('use value()', () => {
375
350
  it('should update indeterminate on input with a getter and setter', () => {
376
351
  const logs: (string | boolean)[] = [];
377
352
 
378
- function App() {
379
- return <>
380
- const obj = new RippleObject({ value: false });
381
- effect(() => {
382
- logs.push('indeterminate changed', obj.value);
383
- });
384
- <input
385
- type="checkbox"
386
- ref={bindIndeterminate(() => obj.value, (v: boolean) => (obj.value = v))}
387
- />
388
- </>;
353
+ function App() @{
354
+ const obj = new RippleObject({ value: false });
355
+ effect(() => {
356
+ logs.push('indeterminate changed', obj.value);
357
+ });
358
+ <input
359
+ type="checkbox"
360
+ ref={bindIndeterminate(() => obj.value, (v: boolean) => (obj.value = v))}
361
+ />
389
362
  }
390
363
  render(App);
391
364
  flushSync();
@@ -402,14 +375,12 @@ describe('use value()', () => {
402
375
  });
403
376
 
404
377
  it('should update checkbox indeterminate element when tracked value changes', () => {
405
- function App() {
406
- return <>
407
- const value = track(false);
408
- <div>
409
- <input type="checkbox" ref={bindIndeterminate(value)} />
410
- <button onClick={() => (value.value = true)}>{'Set Indeterminate'}</button>
411
- </div>
412
- </>;
378
+ function App() @{
379
+ const value = track(false);
380
+ <div>
381
+ <input type="checkbox" ref={bindIndeterminate(value)} />
382
+ <button onClick={() => (value.value = true)}>{'Set Indeterminate'}</button>
383
+ </div>
413
384
  }
414
385
  render(App);
415
386
  flushSync();
@@ -428,17 +399,15 @@ describe('use value()', () => {
428
399
  it(
429
400
  'should update checkbox indeterminate element when tracked value changes with a getter and setter',
430
401
  () => {
431
- function App() {
432
- return <>
433
- const obj = new RippleObject({ value: false });
434
- <div>
435
- <input
436
- type="checkbox"
437
- ref={bindIndeterminate(() => obj.value, (v: boolean) => (obj.value = v))}
438
- />
439
- <button onClick={() => (obj.value = true)}>{'Set Indeterminate'}</button>
440
- </div>
441
- </>;
402
+ function App() @{
403
+ const obj = new RippleObject({ value: false });
404
+ <div>
405
+ <input
406
+ type="checkbox"
407
+ ref={bindIndeterminate(() => obj.value, (v: boolean) => (obj.value = v))}
408
+ />
409
+ <button onClick={() => (obj.value = true)}>{'Set Indeterminate'}</button>
410
+ </div>
442
411
  }
443
412
  render(App);
444
413
  flushSync();
@@ -458,18 +427,16 @@ describe('use value()', () => {
458
427
  it('should update select value on change', () => {
459
428
  const logs: string[] = [];
460
429
 
461
- function App() {
462
- return <>
463
- const select = track('2');
464
- effect(() => {
465
- logs.push('select changed', select.value);
466
- });
467
- <select ref={bindValue(select)}>
468
- <option value="1">{'One'}</option>
469
- <option value="2">{'Two'}</option>
470
- <option value="3">{'Three'}</option>
471
- </select>
472
- </>;
430
+ function App() @{
431
+ const select = track('2');
432
+ effect(() => {
433
+ logs.push('select changed', select.value);
434
+ });
435
+ <select ref={bindValue(select)}>
436
+ <option value="1">{'One'}</option>
437
+ <option value="2">{'Two'}</option>
438
+ <option value="3">{'Three'}</option>
439
+ </select>
473
440
  }
474
441
 
475
442
  render(App);
@@ -487,18 +454,16 @@ describe('use value()', () => {
487
454
  it('should update select value on change with a getter and setter', () => {
488
455
  const logs: string[] = [];
489
456
 
490
- function App() {
491
- return <>
492
- const select = new RippleObject({ value: '2' });
493
- effect(() => {
494
- logs.push('select changed', select.value);
495
- });
496
- <select ref={bindValue(() => select.value, (v) => (select.value = v))}>
497
- <option value="1">{'One'}</option>
498
- <option value="2">{'Two'}</option>
499
- <option value="3">{'Three'}</option>
500
- </select>
501
- </>;
457
+ function App() @{
458
+ const select = new RippleObject({ value: '2' });
459
+ effect(() => {
460
+ logs.push('select changed', select.value);
461
+ });
462
+ <select ref={bindValue(() => select.value, (v) => (select.value = v))}>
463
+ <option value="1">{'One'}</option>
464
+ <option value="2">{'Two'}</option>
465
+ <option value="3">{'Three'}</option>
466
+ </select>
502
467
  }
503
468
 
504
469
  render(App);
@@ -514,18 +479,16 @@ describe('use value()', () => {
514
479
  });
515
480
 
516
481
  it('should update select element when tracked value changes', () => {
517
- function App() {
518
- return <>
519
- const select = track('1');
520
- <div>
521
- <select ref={bindValue(select)}>
522
- <option value="1">{'One'}</option>
523
- <option value="2">{'Two'}</option>
524
- <option value="3">{'Three'}</option>
525
- </select>
526
- <button onClick={() => (select.value = '3')}>{'Update'}</button>
527
- </div>
528
- </>;
482
+ function App() @{
483
+ const select = track('1');
484
+ <div>
485
+ <select ref={bindValue(select)}>
486
+ <option value="1">{'One'}</option>
487
+ <option value="2">{'Two'}</option>
488
+ <option value="3">{'Three'}</option>
489
+ </select>
490
+ <button onClick={() => (select.value = '3')}>{'Update'}</button>
491
+ </div>
529
492
  }
530
493
 
531
494
  render(App);
@@ -543,18 +506,16 @@ describe('use value()', () => {
543
506
  });
544
507
 
545
508
  it('should update select element when tracked value changes with a getter and setter', () => {
546
- function App() {
547
- return <>
548
- const select = new RippleObject({ value: '1' });
549
- <div>
550
- <select ref={bindValue(() => select.value, (v) => (select.value = v))}>
551
- <option value="1">{'One'}</option>
552
- <option value="2">{'Two'}</option>
553
- <option value="3">{'Three'}</option>
554
- </select>
555
- <button onClick={() => (select.value = '3')}>{'Update'}</button>
556
- </div>
557
- </>;
509
+ function App() @{
510
+ const select = new RippleObject({ value: '1' });
511
+ <div>
512
+ <select ref={bindValue(() => select.value, (v) => (select.value = v))}>
513
+ <option value="1">{'One'}</option>
514
+ <option value="2">{'Two'}</option>
515
+ <option value="3">{'Three'}</option>
516
+ </select>
517
+ <button onClick={() => (select.value = '3')}>{'Update'}</button>
518
+ </div>
558
519
  }
559
520
 
560
521
  render(App);
@@ -574,18 +535,16 @@ describe('use value()', () => {
574
535
  it('should bind checkbox group', () => {
575
536
  const logs: string[] = [];
576
537
 
577
- function App() {
578
- return <>
579
- const selected = track(['b']);
580
- effect(() => {
581
- logs.push('selected changed', JSON.stringify(selected.value));
582
- });
583
- <div>
584
- <input type="checkbox" value="a" ref={bindGroup(selected)} />
585
- <input type="checkbox" value="b" ref={bindGroup(selected)} />
586
- <input type="checkbox" value="c" ref={bindGroup(selected)} />
587
- </div>
588
- </>;
538
+ function App() @{
539
+ const selected = track(['b']);
540
+ effect(() => {
541
+ logs.push('selected changed', JSON.stringify(selected.value));
542
+ });
543
+ <div>
544
+ <input type="checkbox" value="a" ref={bindGroup(selected)} />
545
+ <input type="checkbox" value="b" ref={bindGroup(selected)} />
546
+ <input type="checkbox" value="c" ref={bindGroup(selected)} />
547
+ </div>
589
548
  }
590
549
 
591
550
  render(App);
@@ -622,30 +581,28 @@ describe('use value()', () => {
622
581
  it('should bind checkbox group with a getter and setter', () => {
623
582
  const logs: string[] = [];
624
583
 
625
- function App() {
626
- return <>
627
- const obj = new RippleObject({ selected: ['b'] });
628
- effect(() => {
629
- logs.push('selected changed', JSON.stringify(obj.selected));
630
- });
631
- <div>
632
- <input
633
- type="checkbox"
634
- value="a"
635
- ref={bindGroup(() => obj.selected, (v: string[]) => (obj.selected = v))}
636
- />
637
- <input
638
- type="checkbox"
639
- value="b"
640
- ref={bindGroup(() => obj.selected, (v: string[]) => (obj.selected = v))}
641
- />
642
- <input
643
- type="checkbox"
644
- value="c"
645
- ref={bindGroup(() => obj.selected, (v: string[]) => (obj.selected = v))}
646
- />
647
- </div>
648
- </>;
584
+ function App() @{
585
+ const obj = new RippleObject({ selected: ['b'] });
586
+ effect(() => {
587
+ logs.push('selected changed', JSON.stringify(obj.selected));
588
+ });
589
+ <div>
590
+ <input
591
+ type="checkbox"
592
+ value="a"
593
+ ref={bindGroup(() => obj.selected, (v: string[]) => (obj.selected = v))}
594
+ />
595
+ <input
596
+ type="checkbox"
597
+ value="b"
598
+ ref={bindGroup(() => obj.selected, (v: string[]) => (obj.selected = v))}
599
+ />
600
+ <input
601
+ type="checkbox"
602
+ value="c"
603
+ ref={bindGroup(() => obj.selected, (v: string[]) => (obj.selected = v))}
604
+ />
605
+ </div>
649
606
  }
650
607
 
651
608
  render(App);
@@ -682,18 +639,16 @@ describe('use value()', () => {
682
639
  it('should bind radio group', () => {
683
640
  const logs: string[] = [];
684
641
 
685
- function App() {
686
- return <>
687
- const selected = track('b');
688
- effect(() => {
689
- logs.push('selected changed', selected.value);
690
- });
691
- <div>
692
- <input type="radio" name="test" value="a" ref={bindGroup(selected)} />
693
- <input type="radio" name="test" value="b" ref={bindGroup(selected)} />
694
- <input type="radio" name="test" value="c" ref={bindGroup(selected)} />
695
- </div>
696
- </>;
642
+ function App() @{
643
+ const selected = track('b');
644
+ effect(() => {
645
+ logs.push('selected changed', selected.value);
646
+ });
647
+ <div>
648
+ <input type="radio" name="test" value="a" ref={bindGroup(selected)} />
649
+ <input type="radio" name="test" value="b" ref={bindGroup(selected)} />
650
+ <input type="radio" name="test" value="c" ref={bindGroup(selected)} />
651
+ </div>
697
652
  }
698
653
 
699
654
  render(App);
@@ -729,33 +684,31 @@ describe('use value()', () => {
729
684
  it('should bind radio group with a getter and setter', () => {
730
685
  const logs: string[] = [];
731
686
 
732
- function App() {
733
- return <>
734
- const selected = new RippleObject({ value: 'b' });
735
- effect(() => {
736
- logs.push('selected changed', selected.value);
737
- });
738
- <div>
739
- <input
740
- type="radio"
741
- name="test"
742
- value="a"
743
- ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
744
- />
745
- <input
746
- type="radio"
747
- name="test"
748
- value="b"
749
- ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
750
- />
751
- <input
752
- type="radio"
753
- name="test"
754
- value="c"
755
- ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
756
- />
757
- </div>
758
- </>;
687
+ function App() @{
688
+ const selected = new RippleObject({ value: 'b' });
689
+ effect(() => {
690
+ logs.push('selected changed', selected.value);
691
+ });
692
+ <div>
693
+ <input
694
+ type="radio"
695
+ name="test"
696
+ value="a"
697
+ ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
698
+ />
699
+ <input
700
+ type="radio"
701
+ name="test"
702
+ value="b"
703
+ ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
704
+ />
705
+ <input
706
+ type="radio"
707
+ name="test"
708
+ value="c"
709
+ ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
710
+ />
711
+ </div>
759
712
  }
760
713
 
761
714
  render(App);
@@ -789,16 +742,14 @@ describe('use value()', () => {
789
742
  });
790
743
 
791
744
  it('should update checkbox group from tracked value change', () => {
792
- function App() {
793
- return <>
794
- const selected = track(['a']);
795
- <div>
796
- <input type="checkbox" value="a" ref={bindGroup(selected)} />
797
- <input type="checkbox" value="b" ref={bindGroup(selected)} />
798
- <input type="checkbox" value="c" ref={bindGroup(selected)} />
799
- <button onClick={() => (selected.value = ['b', 'c'])}>{'Update'}</button>
800
- </div>
801
- </>;
745
+ function App() @{
746
+ const selected = track(['a']);
747
+ <div>
748
+ <input type="checkbox" value="a" ref={bindGroup(selected)} />
749
+ <input type="checkbox" value="b" ref={bindGroup(selected)} />
750
+ <input type="checkbox" value="c" ref={bindGroup(selected)} />
751
+ <button onClick={() => (selected.value = ['b', 'c'])}>{'Update'}</button>
752
+ </div>
802
753
  }
803
754
 
804
755
  render(App);
@@ -820,28 +771,26 @@ describe('use value()', () => {
820
771
  });
821
772
 
822
773
  it('should update checkbox group from tracked value change with a getter and setter', () => {
823
- function App() {
824
- return <>
825
- const selected = new RippleObject({ value: ['a'] });
826
- <div>
827
- <input
828
- type="checkbox"
829
- value="a"
830
- ref={bindGroup(() => selected.value, (v: string[]) => (selected.value = v))}
831
- />
832
- <input
833
- type="checkbox"
834
- value="b"
835
- ref={bindGroup(() => selected.value, (v: string[]) => (selected.value = v))}
836
- />
837
- <input
838
- type="checkbox"
839
- value="c"
840
- ref={bindGroup(() => selected.value, (v: string[]) => (selected.value = v))}
841
- />
842
- <button onClick={() => (selected.value = ['b', 'c'])}>{'Update'}</button>
843
- </div>
844
- </>;
774
+ function App() @{
775
+ const selected = new RippleObject({ value: ['a'] });
776
+ <div>
777
+ <input
778
+ type="checkbox"
779
+ value="a"
780
+ ref={bindGroup(() => selected.value, (v: string[]) => (selected.value = v))}
781
+ />
782
+ <input
783
+ type="checkbox"
784
+ value="b"
785
+ ref={bindGroup(() => selected.value, (v: string[]) => (selected.value = v))}
786
+ />
787
+ <input
788
+ type="checkbox"
789
+ value="c"
790
+ ref={bindGroup(() => selected.value, (v: string[]) => (selected.value = v))}
791
+ />
792
+ <button onClick={() => (selected.value = ['b', 'c'])}>{'Update'}</button>
793
+ </div>
845
794
  }
846
795
 
847
796
  render(App);
@@ -863,16 +812,14 @@ describe('use value()', () => {
863
812
  });
864
813
 
865
814
  it('should update radio group from tracked value change', () => {
866
- function App() {
867
- return <>
868
- const selected = track('a');
869
- <div>
870
- <input type="radio" name="test" value="a" ref={bindGroup(selected)} />
871
- <input type="radio" name="test" value="b" ref={bindGroup(selected)} />
872
- <input type="radio" name="test" value="c" ref={bindGroup(selected)} />
873
- <button onClick={() => (selected.value = 'c')}>{'Update'}</button>
874
- </div>
875
- </>;
815
+ function App() @{
816
+ const selected = track('a');
817
+ <div>
818
+ <input type="radio" name="test" value="a" ref={bindGroup(selected)} />
819
+ <input type="radio" name="test" value="b" ref={bindGroup(selected)} />
820
+ <input type="radio" name="test" value="c" ref={bindGroup(selected)} />
821
+ <button onClick={() => (selected.value = 'c')}>{'Update'}</button>
822
+ </div>
876
823
  }
877
824
 
878
825
  render(App);
@@ -894,31 +841,29 @@ describe('use value()', () => {
894
841
  });
895
842
 
896
843
  it('should update radio group from tracked value change with a getter and setter', () => {
897
- function App() {
898
- return <>
899
- const selected = new RippleObject({ value: 'a' });
900
- <div>
901
- <input
902
- type="radio"
903
- name="test"
904
- value="a"
905
- ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
906
- />
907
- <input
908
- type="radio"
909
- name="test"
910
- value="b"
911
- ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
912
- />
913
- <input
914
- type="radio"
915
- name="test"
916
- value="c"
917
- ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
918
- />
919
- <button onClick={() => (selected.value = 'c')}>{'Update'}</button>
920
- </div>
921
- </>;
844
+ function App() @{
845
+ const selected = new RippleObject({ value: 'a' });
846
+ <div>
847
+ <input
848
+ type="radio"
849
+ name="test"
850
+ value="a"
851
+ ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
852
+ />
853
+ <input
854
+ type="radio"
855
+ name="test"
856
+ value="b"
857
+ ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
858
+ />
859
+ <input
860
+ type="radio"
861
+ name="test"
862
+ value="c"
863
+ ref={bindGroup(() => selected.value, (v: string) => (selected.value = v))}
864
+ />
865
+ <button onClick={() => (selected.value = 'c')}>{'Update'}</button>
866
+ </div>
922
867
  }
923
868
 
924
869
  render(App);
@@ -940,14 +885,12 @@ describe('use value()', () => {
940
885
  });
941
886
 
942
887
  it('should handle checkbox group with initial empty array', () => {
943
- function App() {
944
- return <>
945
- const selected = track([]);
946
- <div>
947
- <input type="checkbox" value="a" ref={bindGroup(selected)} />
948
- <input type="checkbox" value="b" ref={bindGroup(selected)} />
949
- </div>
950
- </>;
888
+ function App() @{
889
+ const selected = track([]);
890
+ <div>
891
+ <input type="checkbox" value="a" ref={bindGroup(selected)} />
892
+ <input type="checkbox" value="b" ref={bindGroup(selected)} />
893
+ </div>
951
894
  }
952
895
 
953
896
  render(App);
@@ -967,22 +910,20 @@ describe('use value()', () => {
967
910
  });
968
911
 
969
912
  it('should handle checkbox group with initial empty array with a getter and setter', () => {
970
- function App() {
971
- return <>
972
- const selected: RippleObject<{ value: string[] }> = new RippleObject({ value: [] });
973
- <div>
974
- <input
975
- type="checkbox"
976
- value="a"
977
- ref={bindGroup(() => selected.value, (v: string[]) => (selected.value = v))}
978
- />
979
- <input
980
- type="checkbox"
981
- value="b"
982
- ref={bindGroup(() => selected.value, (v: string[]) => (selected.value = v))}
983
- />
984
- </div>
985
- </>;
913
+ function App() @{
914
+ const selected: RippleObject<{ value: string[] }> = new RippleObject({ value: [] });
915
+ <div>
916
+ <input
917
+ type="checkbox"
918
+ value="a"
919
+ ref={bindGroup(() => selected.value, (v: string[]) => (selected.value = v))}
920
+ />
921
+ <input
922
+ type="checkbox"
923
+ value="b"
924
+ ref={bindGroup(() => selected.value, (v: string[]) => (selected.value = v))}
925
+ />
926
+ </div>
986
927
  }
987
928
 
988
929
  render(App);
@@ -1002,11 +943,9 @@ describe('use value()', () => {
1002
943
  });
1003
944
 
1004
945
  it('should handle number input type', () => {
1005
- function App() {
1006
- return <>
1007
- const value = track(42);
1008
- <input type="number" ref={bindValue(value)} />
1009
- </>;
946
+ function App() @{
947
+ const value = track(42);
948
+ <input type="number" ref={bindValue(value)} />
1010
949
  }
1011
950
 
1012
951
  render(App);
@@ -1023,11 +962,9 @@ describe('use value()', () => {
1023
962
  });
1024
963
 
1025
964
  it('should handle number input type with a getter and setter', () => {
1026
- function App() {
1027
- return <>
1028
- const obj = new RippleObject({ value: 42 });
1029
- <input type="number" ref={bindValue(() => obj.value, (v) => (obj.value = v))} />
1030
- </>;
965
+ function App() @{
966
+ const obj = new RippleObject({ value: 42 });
967
+ <input type="number" ref={bindValue(() => obj.value, (v) => (obj.value = v))} />
1031
968
  }
1032
969
 
1033
970
  render(App);
@@ -1044,14 +981,12 @@ describe('use value()', () => {
1044
981
  });
1045
982
 
1046
983
  it('should update number input element when tracked value changes', () => {
1047
- function App() {
1048
- return <>
1049
- const value = track(10);
1050
- <div>
1051
- <input type="number" ref={bindValue(value)} />
1052
- <button onClick={() => (value.value = 99)}>{'Update'}</button>
1053
- </div>
1054
- </>;
984
+ function App() @{
985
+ const value = track(10);
986
+ <div>
987
+ <input type="number" ref={bindValue(value)} />
988
+ <button onClick={() => (value.value = 99)}>{'Update'}</button>
989
+ </div>
1055
990
  }
1056
991
 
1057
992
  render(App);
@@ -1071,14 +1006,12 @@ describe('use value()', () => {
1071
1006
  it(
1072
1007
  'should update number input element when tracked value changes with a getter and setter',
1073
1008
  () => {
1074
- function App() {
1075
- return <>
1076
- const obj = new RippleObject({ value: 10 });
1077
- <div>
1078
- <input type="number" ref={bindValue(() => obj.value, (v) => (obj.value = v))} />
1079
- <button onClick={() => (obj.value = 99)}>{'Update'}</button>
1080
- </div>
1081
- </>;
1009
+ function App() @{
1010
+ const obj = new RippleObject({ value: 10 });
1011
+ <div>
1012
+ <input type="number" ref={bindValue(() => obj.value, (v) => (obj.value = v))} />
1013
+ <button onClick={() => (obj.value = 99)}>{'Update'}</button>
1014
+ </div>
1082
1015
  }
1083
1016
 
1084
1017
  render(App);
@@ -1097,11 +1030,9 @@ describe('use value()', () => {
1097
1030
  );
1098
1031
 
1099
1032
  it('should handle range input type', () => {
1100
- function App() {
1101
- return <>
1102
- const value = track(50);
1103
- <input type="range" min="0" max="100" ref={bindValue(value)} />
1104
- </>;
1033
+ function App() @{
1034
+ const value = track(50);
1035
+ <input type="range" min="0" max="100" ref={bindValue(value)} />
1105
1036
  }
1106
1037
 
1107
1038
  render(App);
@@ -1118,16 +1049,14 @@ describe('use value()', () => {
1118
1049
  });
1119
1050
 
1120
1051
  it('should handle range input type with a getter and setter', () => {
1121
- function App() {
1122
- return <>
1123
- const obj = new RippleObject({ value: 50 });
1124
- <input
1125
- type="range"
1126
- min="0"
1127
- max="100"
1128
- ref={bindValue(() => obj.value, (v) => (obj.value = v))}
1129
- />
1130
- </>;
1052
+ function App() @{
1053
+ const obj = new RippleObject({ value: 50 });
1054
+ <input
1055
+ type="range"
1056
+ min="0"
1057
+ max="100"
1058
+ ref={bindValue(() => obj.value, (v) => (obj.value = v))}
1059
+ />
1131
1060
  }
1132
1061
 
1133
1062
  render(App);
@@ -1144,14 +1073,12 @@ describe('use value()', () => {
1144
1073
  });
1145
1074
 
1146
1075
  it('should update range input element when tracked value changes', () => {
1147
- function App() {
1148
- return <>
1149
- const value = track(25);
1150
- <div>
1151
- <input type="range" min="0" max="100" ref={bindValue(value)} />
1152
- <button onClick={() => (value.value = 80)}>{'Update'}</button>
1153
- </div>
1154
- </>;
1076
+ function App() @{
1077
+ const value = track(25);
1078
+ <div>
1079
+ <input type="range" min="0" max="100" ref={bindValue(value)} />
1080
+ <button onClick={() => (value.value = 80)}>{'Update'}</button>
1081
+ </div>
1155
1082
  }
1156
1083
 
1157
1084
  render(App);
@@ -1171,19 +1098,17 @@ describe('use value()', () => {
1171
1098
  it(
1172
1099
  'should update range input element when tracked value changes with a getter and setter',
1173
1100
  () => {
1174
- function App() {
1175
- return <>
1176
- const obj = new RippleObject({ value: 25 });
1177
- <div>
1178
- <input
1179
- type="range"
1180
- min="0"
1181
- max="100"
1182
- ref={bindValue(() => obj.value, (v) => (obj.value = v))}
1183
- />
1184
- <button onClick={() => (obj.value = 80)}>{'Update'}</button>
1185
- </div>
1186
- </>;
1101
+ function App() @{
1102
+ const obj = new RippleObject({ value: 25 });
1103
+ <div>
1104
+ <input
1105
+ type="range"
1106
+ min="0"
1107
+ max="100"
1108
+ ref={bindValue(() => obj.value, (v) => (obj.value = v))}
1109
+ />
1110
+ <button onClick={() => (obj.value = 80)}>{'Update'}</button>
1111
+ </div>
1187
1112
  }
1188
1113
 
1189
1114
  render(App);
@@ -1202,11 +1127,9 @@ describe('use value()', () => {
1202
1127
  );
1203
1128
 
1204
1129
  it('should handle empty number input as null', () => {
1205
- function App() {
1206
- return <>
1207
- const value = track(null);
1208
- <input type="number" ref={bindValue(value)} />
1209
- </>;
1130
+ function App() @{
1131
+ const value = track(null);
1132
+ <input type="number" ref={bindValue(value)} />
1210
1133
  }
1211
1134
 
1212
1135
  render(App);
@@ -1223,11 +1146,9 @@ describe('use value()', () => {
1223
1146
  });
1224
1147
 
1225
1148
  it('should handle empty number input as null with a getter and setter', () => {
1226
- function App() {
1227
- return <>
1228
- const obj = new RippleObject({ value: null });
1229
- <input type="number" ref={bindValue(() => obj.value, (v) => (obj.value = v))} />
1230
- </>;
1149
+ function App() @{
1150
+ const obj = new RippleObject({ value: null });
1151
+ <input type="number" ref={bindValue(() => obj.value, (v) => (obj.value = v))} />
1231
1152
  }
1232
1153
 
1233
1154
  render(App);
@@ -1244,11 +1165,9 @@ describe('use value()', () => {
1244
1165
  });
1245
1166
 
1246
1167
  it('should handle date input type', () => {
1247
- function App() {
1248
- return <>
1249
- const value = track('2025-11-14');
1250
- <input type="date" ref={bindValue(value)} />
1251
- </>;
1168
+ function App() @{
1169
+ const value = track('2025-11-14');
1170
+ <input type="date" ref={bindValue(value)} />
1252
1171
  }
1253
1172
 
1254
1173
  render(App);
@@ -1265,11 +1184,9 @@ describe('use value()', () => {
1265
1184
  });
1266
1185
 
1267
1186
  it('should handle date input type with a getter and setter', () => {
1268
- function App() {
1269
- return <>
1270
- const obj = new RippleObject({ value: '2025-11-14' });
1271
- <input type="date" ref={bindValue(() => obj.value, (v) => (obj.value = v))} />
1272
- </>;
1187
+ function App() @{
1188
+ const obj = new RippleObject({ value: '2025-11-14' });
1189
+ <input type="date" ref={bindValue(() => obj.value, (v) => (obj.value = v))} />
1273
1190
  }
1274
1191
 
1275
1192
  render(App);
@@ -1286,14 +1203,12 @@ describe('use value()', () => {
1286
1203
  });
1287
1204
 
1288
1205
  it('should update date input element when tracked value changes', () => {
1289
- function App() {
1290
- return <>
1291
- const value = track('2025-01-01');
1292
- <div>
1293
- <input type="date" ref={bindValue(value)} />
1294
- <button onClick={() => (value.value = '2025-12-31')}>{'Update'}</button>
1295
- </div>
1296
- </>;
1206
+ function App() @{
1207
+ const value = track('2025-01-01');
1208
+ <div>
1209
+ <input type="date" ref={bindValue(value)} />
1210
+ <button onClick={() => (value.value = '2025-12-31')}>{'Update'}</button>
1211
+ </div>
1297
1212
  }
1298
1213
 
1299
1214
  render(App);
@@ -1311,14 +1226,12 @@ describe('use value()', () => {
1311
1226
  });
1312
1227
 
1313
1228
  it('should update date input element when tracked value changes with a getter and setter', () => {
1314
- function App() {
1315
- return <>
1316
- const obj = new RippleObject({ value: '2025-01-01' });
1317
- <div>
1318
- <input type="date" ref={bindValue(() => obj.value, (v) => (obj.value = v))} />
1319
- <button onClick={() => (obj.value = '2025-12-31')}>{'Update'}</button>
1320
- </div>
1321
- </>;
1229
+ function App() @{
1230
+ const obj = new RippleObject({ value: '2025-01-01' });
1231
+ <div>
1232
+ <input type="date" ref={bindValue(() => obj.value, (v) => (obj.value = v))} />
1233
+ <button onClick={() => (obj.value = '2025-12-31')}>{'Update'}</button>
1234
+ </div>
1322
1235
  }
1323
1236
 
1324
1237
  render(App);
@@ -1336,16 +1249,14 @@ describe('use value()', () => {
1336
1249
  });
1337
1250
 
1338
1251
  it('should handle select with multiple attribute', () => {
1339
- function App() {
1340
- return <>
1341
- const selected = track(['2', '3']);
1342
- <select multiple ref={bindValue(selected)}>
1343
- <option value="1">{'One'}</option>
1344
- <option value="2">{'Two'}</option>
1345
- <option value="3">{'Three'}</option>
1346
- <option value="4">{'Four'}</option>
1347
- </select>
1348
- </>;
1252
+ function App() @{
1253
+ const selected = track(['2', '3']);
1254
+ <select multiple ref={bindValue(selected)}>
1255
+ <option value="1">{'One'}</option>
1256
+ <option value="2">{'Two'}</option>
1257
+ <option value="3">{'Three'}</option>
1258
+ <option value="4">{'Four'}</option>
1259
+ </select>
1349
1260
  }
1350
1261
 
1351
1262
  render(App);
@@ -1371,16 +1282,14 @@ describe('use value()', () => {
1371
1282
  });
1372
1283
 
1373
1284
  it('should handle select with multiple attribute with a getter and setter', () => {
1374
- function App() {
1375
- return <>
1376
- const selected = track(['2', '3']);
1377
- <select multiple ref={bindValue(() => selected.value, (v) => (selected.value = v))}>
1378
- <option value="1">{'One'}</option>
1379
- <option value="2">{'Two'}</option>
1380
- <option value="3">{'Three'}</option>
1381
- <option value="4">{'Four'}</option>
1382
- </select>
1383
- </>;
1285
+ function App() @{
1286
+ const selected = track(['2', '3']);
1287
+ <select multiple ref={bindValue(() => selected.value, (v) => (selected.value = v))}>
1288
+ <option value="1">{'One'}</option>
1289
+ <option value="2">{'Two'}</option>
1290
+ <option value="3">{'Three'}</option>
1291
+ <option value="4">{'Four'}</option>
1292
+ </select>
1384
1293
  }
1385
1294
 
1386
1295
  render(App);
@@ -1406,19 +1315,17 @@ describe('use value()', () => {
1406
1315
  });
1407
1316
 
1408
1317
  it('should update multiple select element when tracked value changes', () => {
1409
- function App() {
1410
- return <>
1411
- const selected = track(['1']);
1412
- <div>
1413
- <select multiple ref={bindValue(selected)}>
1414
- <option value="1">{'One'}</option>
1415
- <option value="2">{'Two'}</option>
1416
- <option value="3">{'Three'}</option>
1417
- <option value="4">{'Four'}</option>
1418
- </select>
1419
- <button onClick={() => (selected.value = ['2', '4'])}>{'Update'}</button>
1420
- </div>
1421
- </>;
1318
+ function App() @{
1319
+ const selected = track(['1']);
1320
+ <div>
1321
+ <select multiple ref={bindValue(selected)}>
1322
+ <option value="1">{'One'}</option>
1323
+ <option value="2">{'Two'}</option>
1324
+ <option value="3">{'Three'}</option>
1325
+ <option value="4">{'Four'}</option>
1326
+ </select>
1327
+ <button onClick={() => (selected.value = ['2', '4'])}>{'Update'}</button>
1328
+ </div>
1422
1329
  }
1423
1330
 
1424
1331
  render(App);
@@ -1445,19 +1352,17 @@ describe('use value()', () => {
1445
1352
  it(
1446
1353
  'should update multiple select element when tracked value changes with a getter and setter',
1447
1354
  () => {
1448
- function App() {
1449
- return <>
1450
- const selected = track(['1']);
1451
- <div>
1452
- <select multiple ref={bindValue(() => selected.value, (v) => (selected.value = v))}>
1453
- <option value="1">{'One'}</option>
1454
- <option value="2">{'Two'}</option>
1455
- <option value="3">{'Three'}</option>
1456
- <option value="4">{'Four'}</option>
1457
- </select>
1458
- <button onClick={() => (selected.value = ['2', '4'])}>{'Update'}</button>
1459
- </div>
1460
- </>;
1355
+ function App() @{
1356
+ const selected = track(['1']);
1357
+ <div>
1358
+ <select multiple ref={bindValue(() => selected.value, (v) => (selected.value = v))}>
1359
+ <option value="1">{'One'}</option>
1360
+ <option value="2">{'Two'}</option>
1361
+ <option value="3">{'Three'}</option>
1362
+ <option value="4">{'Four'}</option>
1363
+ </select>
1364
+ <button onClick={() => (selected.value = ['2', '4'])}>{'Update'}</button>
1365
+ </div>
1461
1366
  }
1462
1367
 
1463
1368
  render(App);
@@ -1483,14 +1388,12 @@ describe('use value()', () => {
1483
1388
  );
1484
1389
 
1485
1390
  it('should handle select without initial value and fall back to first option', () => {
1486
- function App() {
1487
- return <>
1488
- const selected = track();
1489
- <select ref={bindValue(selected)}>
1490
- <option value="1">{'One'}</option>
1491
- <option value="2">{'Two'}</option>
1492
- </select>
1493
- </>;
1391
+ function App() @{
1392
+ const selected = track();
1393
+ <select ref={bindValue(selected)}>
1394
+ <option value="1">{'One'}</option>
1395
+ <option value="2">{'Two'}</option>
1396
+ </select>
1494
1397
  }
1495
1398
 
1496
1399
  render(App);
@@ -1504,14 +1407,12 @@ describe('use value()', () => {
1504
1407
  it(
1505
1408
  'should handle select without initial value and fall back to first option with a getter and setter',
1506
1409
  () => {
1507
- function App() {
1508
- return <>
1509
- const selected = track();
1510
- <select ref={bindValue(() => selected.value, (v) => (selected.value = v))}>
1511
- <option value="1">{'One'}</option>
1512
- <option value="2">{'Two'}</option>
1513
- </select>
1514
- </>;
1410
+ function App() @{
1411
+ const selected = track();
1412
+ <select ref={bindValue(() => selected.value, (v) => (selected.value = v))}>
1413
+ <option value="1">{'One'}</option>
1414
+ <option value="2">{'Two'}</option>
1415
+ </select>
1515
1416
  }
1516
1417
 
1517
1418
  render(App);
@@ -1524,14 +1425,12 @@ describe('use value()', () => {
1524
1425
  );
1525
1426
 
1526
1427
  it('should handle select with disabled options', () => {
1527
- function App() {
1528
- return <>
1529
- const selected = track();
1530
- <select ref={bindValue(selected)}>
1531
- <option value="1" disabled>{'One'}</option>
1532
- <option value="2">{'Two'}</option>
1533
- </select>
1534
- </>;
1428
+ function App() @{
1429
+ const selected = track();
1430
+ <select ref={bindValue(selected)}>
1431
+ <option value="1" disabled>{'One'}</option>
1432
+ <option value="2">{'Two'}</option>
1433
+ </select>
1535
1434
  }
1536
1435
 
1537
1436
  render(App);
@@ -1543,14 +1442,12 @@ describe('use value()', () => {
1543
1442
  });
1544
1443
 
1545
1444
  it('should handle select with disabled options with a getter and setter', () => {
1546
- function App() {
1547
- return <>
1548
- const selected = track();
1549
- <select ref={bindValue(() => selected.value, (v) => (selected.value = v))}>
1550
- <option value="1" disabled>{'One'}</option>
1551
- <option value="2">{'Two'}</option>
1552
- </select>
1553
- </>;
1445
+ function App() @{
1446
+ const selected = track();
1447
+ <select ref={bindValue(() => selected.value, (v) => (selected.value = v))}>
1448
+ <option value="1" disabled>{'One'}</option>
1449
+ <option value="2">{'Two'}</option>
1450
+ </select>
1554
1451
  }
1555
1452
 
1556
1453
  render(App);
@@ -1562,15 +1459,13 @@ describe('use value()', () => {
1562
1459
  });
1563
1460
 
1564
1461
  it('should preselect numeric option values in select bindValue', () => {
1565
- function App() {
1566
- return <>
1567
- const selected = track(2);
1568
- <select ref={bindValue(selected)}>
1569
- <option value={1}>{'One'}</option>
1570
- <option value={2}>{'Two'}</option>
1571
- <option value={3}>{'Three'}</option>
1572
- </select>
1573
- </>;
1462
+ function App() @{
1463
+ const selected = track(2);
1464
+ <select ref={bindValue(selected)}>
1465
+ <option value={1}>{'One'}</option>
1466
+ <option value={2}>{'Two'}</option>
1467
+ <option value={3}>{'Three'}</option>
1468
+ </select>
1574
1469
  }
1575
1470
 
1576
1471
  render(App);
@@ -1585,15 +1480,13 @@ describe('use value()', () => {
1585
1480
  });
1586
1481
 
1587
1482
  it('should preselect numeric option values in select bindValue with a getter and setter', () => {
1588
- function App() {
1589
- return <>
1590
- const selected = track(2);
1591
- <select ref={bindValue(() => selected.value, (v) => (selected.value = v))}>
1592
- <option value={1}>{'One'}</option>
1593
- <option value={2}>{'Two'}</option>
1594
- <option value={3}>{'Three'}</option>
1595
- </select>
1596
- </>;
1483
+ function App() @{
1484
+ const selected = track(2);
1485
+ <select ref={bindValue(() => selected.value, (v) => (selected.value = v))}>
1486
+ <option value={1}>{'One'}</option>
1487
+ <option value={2}>{'Two'}</option>
1488
+ <option value={3}>{'Three'}</option>
1489
+ </select>
1597
1490
  }
1598
1491
 
1599
1492
  render(App);
@@ -1610,18 +1503,16 @@ describe('use value()', () => {
1610
1503
  it('should preserve numeric select values on change', () => {
1611
1504
  const logs: number[] = [];
1612
1505
 
1613
- function App() {
1614
- return <>
1615
- const selected = track(2);
1616
- effect(() => {
1617
- logs.push(selected.value);
1618
- });
1619
- <select ref={bindValue(selected)}>
1620
- <option value={1}>{'One'}</option>
1621
- <option value={2}>{'Two'}</option>
1622
- <option value={3}>{'Three'}</option>
1623
- </select>
1624
- </>;
1506
+ function App() @{
1507
+ const selected = track(2);
1508
+ effect(() => {
1509
+ logs.push(selected.value);
1510
+ });
1511
+ <select ref={bindValue(selected)}>
1512
+ <option value={1}>{'One'}</option>
1513
+ <option value={2}>{'Two'}</option>
1514
+ <option value={3}>{'Three'}</option>
1515
+ </select>
1625
1516
  }
1626
1517
 
1627
1518
  render(App);
@@ -1637,22 +1528,20 @@ describe('use value()', () => {
1637
1528
  });
1638
1529
 
1639
1530
  it('should reselect tracked value when matching option is added later', async () => {
1640
- function App() {
1641
- return <>
1642
- const selected = track(5);
1643
- const options = RippleArray([
1644
- { id: 1, text: 'One' },
1645
- { id: 2, text: 'Two' },
1646
- ]);
1647
- <div>
1648
- <select ref={bindValue(selected)}>
1649
- for (const option of options) {
1650
- <option value={option.id}>{option.text}</option>
1651
- }
1652
- </select>
1653
- <button onClick={() => options.push({ id: 5, text: 'Five' })}>{'Add'}</button>
1654
- </div>
1655
- </>;
1531
+ function App() @{
1532
+ const selected = track(5);
1533
+ const options = RippleArray([
1534
+ { id: 1, text: 'One' },
1535
+ { id: 2, text: 'Two' },
1536
+ ]);
1537
+ <div>
1538
+ <select ref={bindValue(selected)}>
1539
+ @for (const option of options) {
1540
+ <option value={option.id}>{option.text}</option>
1541
+ }
1542
+ </select>
1543
+ <button onClick={() => options.push({ id: 5, text: 'Five' })}>{'Add'}</button>
1544
+ </div>
1656
1545
  }
1657
1546
 
1658
1547
  render(App);
@@ -1673,25 +1562,23 @@ describe('use value()', () => {
1673
1562
  });
1674
1563
 
1675
1564
  it('should reselect tracked value when option lists are replaced later', async () => {
1676
- function App() {
1677
- return <>
1678
- const selected = track(22);
1679
- const options = RippleArray([
1680
- { id: 1, text: 'One' },
1681
- ]);
1682
- effect(() => {
1683
- const timeout = setTimeout(() => {
1684
- options.splice(0, options.length, { id: 21, text: 'Tokyo' }, { id: 22, text: 'Osaka' });
1685
- }, 0);
1686
-
1687
- return () => clearTimeout(timeout);
1688
- });
1689
- <select ref={bindValue(selected)}>
1690
- for (const option of options) {
1691
- <option value={option.id}>{option.text}</option>
1692
- }
1693
- </select>
1694
- </>;
1565
+ function App() @{
1566
+ const selected = track(22);
1567
+ const options = RippleArray([
1568
+ { id: 1, text: 'One' },
1569
+ ]);
1570
+ effect(() => {
1571
+ const timeout = setTimeout(() => {
1572
+ options.splice(0, options.length, { id: 21, text: 'Tokyo' }, { id: 22, text: 'Osaka' });
1573
+ }, 0);
1574
+
1575
+ return () => clearTimeout(timeout);
1576
+ });
1577
+ <select ref={bindValue(selected)}>
1578
+ @for (const option of options) {
1579
+ <option value={option.id}>{option.text}</option>
1580
+ }
1581
+ </select>
1695
1582
  }
1696
1583
 
1697
1584
  render(App);
@@ -1706,23 +1593,27 @@ describe('use value()', () => {
1706
1593
  });
1707
1594
 
1708
1595
  it('should accurately reflect values mutated through a tracked setter', () => {
1709
- function App() {
1710
- return <>
1711
- let value = track(
1712
- '',
1713
- (val) => {
1714
- return val;
1715
- },
1716
- (next) => {
1717
- if (next.includes('c')) {
1718
- next = next.replace(/c/g, '');
1719
- }
1720
- return next;
1721
- },
1722
- );
1723
- <input type="text" ref={bindValue(value)} />
1724
- <div>{value.value}</div>
1725
- </>;
1596
+ function App() @{
1597
+ let value = track(
1598
+ '',
1599
+ (val) => {
1600
+ return val;
1601
+ },
1602
+ (next) => {
1603
+ if (next.includes('c')) {
1604
+ next = next.replace(/c/g, '');
1605
+ }
1606
+ return next;
1607
+ },
1608
+ );
1609
+ <>
1610
+ <>
1611
+ <>
1612
+ <input type="text" ref={bindValue(value)} />
1613
+ <div>{value.value}</div>
1614
+ </>
1615
+ </>
1616
+ </>
1726
1617
  }
1727
1618
 
1728
1619
  render(App);
@@ -1743,23 +1634,23 @@ describe('use value()', () => {
1743
1634
  });
1744
1635
 
1745
1636
  it('should accurately reflect values when a getter modifies value', () => {
1746
- function App() {
1747
- return <>
1748
- let value = track(
1749
- '',
1750
- (val) => {
1751
- if (val.includes('c')) {
1752
- val = val.replace(/c/g, '');
1753
- }
1754
- return val;
1755
- },
1756
- (next) => {
1757
- return next;
1758
- },
1759
- );
1637
+ function App() @{
1638
+ let value = track(
1639
+ '',
1640
+ (val) => {
1641
+ if (val.includes('c')) {
1642
+ val = val.replace(/c/g, '');
1643
+ }
1644
+ return val;
1645
+ },
1646
+ (next) => {
1647
+ return next;
1648
+ },
1649
+ );
1650
+ <>
1760
1651
  <input type="text" ref={bindValue(value)} />
1761
1652
  <div>{value.value}</div>
1762
- </>;
1653
+ </>
1763
1654
  }
1764
1655
 
1765
1656
  render(App);
@@ -1780,23 +1671,23 @@ describe('use value()', () => {
1780
1671
  });
1781
1672
 
1782
1673
  it('should always prefer what getter returns even if setter mutates next', () => {
1783
- function App() {
1784
- return <>
1785
- let value = track(
1786
- '',
1787
- (val) => {
1788
- return val.replace(/[c,b]+/g, '');
1789
- },
1790
- (next) => {
1791
- if (next.includes('c')) {
1792
- next = next.replace(/c/g, '');
1793
- }
1794
- return next;
1795
- },
1796
- );
1674
+ function App() @{
1675
+ let value = track(
1676
+ '',
1677
+ (val) => {
1678
+ return val.replace(/[c,b]+/g, '');
1679
+ },
1680
+ (next) => {
1681
+ if (next.includes('c')) {
1682
+ next = next.replace(/c/g, '');
1683
+ }
1684
+ return next;
1685
+ },
1686
+ );
1687
+ <>
1797
1688
  <input type="text" ref={bindValue(value)} />
1798
1689
  <div>{value.value}</div>
1799
- </>;
1690
+ </>
1800
1691
  }
1801
1692
 
1802
1693
  render(App);
@@ -1819,32 +1710,32 @@ describe('use value()', () => {
1819
1710
  it(
1820
1711
  'should accurately reflect values mutated through an effect even after a setter mutation',
1821
1712
  () => {
1822
- function App() {
1823
- return <>
1824
- let value = track(
1825
- '',
1826
- (val) => {
1827
- return val;
1828
- },
1829
- (next) => {
1830
- if (next.includes('c')) {
1831
- next = next.replace(/c/g, '');
1832
- }
1833
- return next;
1834
- },
1835
- );
1836
- effect(() => {
1837
- value.value;
1838
-
1839
- untrack(() => {
1840
- if (value.value.includes('a')) {
1841
- value.value = value.value.replace(/a/g, '');
1842
- }
1843
- });
1713
+ function App() @{
1714
+ let value = track(
1715
+ '',
1716
+ (val) => {
1717
+ return val;
1718
+ },
1719
+ (next) => {
1720
+ if (next.includes('c')) {
1721
+ next = next.replace(/c/g, '');
1722
+ }
1723
+ return next;
1724
+ },
1725
+ );
1726
+ effect(() => {
1727
+ value.value;
1728
+
1729
+ untrack(() => {
1730
+ if (value.value.includes('a')) {
1731
+ value.value = value.value.replace(/a/g, '');
1732
+ }
1844
1733
  });
1734
+ });
1735
+ <>
1845
1736
  <input type="text" ref={bindValue(value)} />
1846
1737
  <div>{value.value}</div>
1847
- </>;
1738
+ </>
1848
1739
  }
1849
1740
 
1850
1741
  render(App);
@@ -1863,25 +1754,23 @@ describe('use value()', () => {
1863
1754
  expect(input.value).toBe('b');
1864
1755
  expect(div.textContent).toBe('b');
1865
1756
  },
1866
- );
1867
-
1868
- it('should accurately reflect values mutated through a tracked setter via bind accessors', () => {
1869
- function App() {
1870
- return <>
1871
- let value = track('');
1872
- const value_accessors: [GetFunction<string>, SetFunction<string>] = [
1873
- () => {
1874
- return value.value;
1875
- },
1876
- (v: string) => {
1877
- if (v.includes('c')) {
1878
- v = v.replace(/c/g, '');
1879
- }
1880
- value.value = v;
1881
- },
1882
- ];
1883
- <input type="text" ref={bindValue(...value_accessors)} />
1884
- </>;
1757
+ );
1758
+
1759
+ it('should accurately reflect values mutated through a tracked setter via bind accessors', () => {
1760
+ function App() @{
1761
+ let value = track('');
1762
+ const value_accessors: [GetFunction<string>, SetFunction<string>] = [
1763
+ () => {
1764
+ return value.value;
1765
+ },
1766
+ (v: string) => {
1767
+ if (v.includes('c')) {
1768
+ v = v.replace(/c/g, '');
1769
+ }
1770
+ value.value = v;
1771
+ },
1772
+ ];
1773
+ <input type="text" ref={bindValue(...value_accessors)} />
1885
1774
  }
1886
1775
 
1887
1776
  render(App);
@@ -1899,22 +1788,20 @@ describe('use value()', () => {
1899
1788
  });
1900
1789
 
1901
1790
  it('should prefer what getter returns via bind accessors', () => {
1902
- function App() {
1903
- return <>
1904
- let value = track('');
1905
- const value_accessors: [GetFunction<string>, SetFunction<string>] = [
1906
- () => {
1907
- if (value.value.includes('c')) {
1908
- return value.value.replace(/c/g, '');
1909
- }
1910
- return value.value;
1911
- },
1912
- (v: string) => {
1913
- value.value = v;
1914
- },
1915
- ];
1916
- <input type="text" ref={bindValue(...value_accessors)} />
1917
- </>;
1791
+ function App() @{
1792
+ let value = track('');
1793
+ const value_accessors: [GetFunction<string>, SetFunction<string>] = [
1794
+ () => {
1795
+ if (value.value.includes('c')) {
1796
+ return value.value.replace(/c/g, '');
1797
+ }
1798
+ return value.value;
1799
+ },
1800
+ (v: string) => {
1801
+ value.value = v;
1802
+ },
1803
+ ];
1804
+ <input type="text" ref={bindValue(...value_accessors)} />
1918
1805
  }
1919
1806
 
1920
1807
  render(App);
@@ -1934,22 +1821,20 @@ describe('use value()', () => {
1934
1821
  it(
1935
1822
  'should always prefer what getter returns even if setter mutates next via bind accessors',
1936
1823
  () => {
1937
- function App() {
1938
- return <>
1939
- let value = track('');
1940
- const value_accessors: [GetFunction<string>, SetFunction<string>] = [
1941
- () => {
1942
- return value.value.replace(/[c,b]+/g, '');
1943
- },
1944
- (v: string) => {
1945
- if (v.includes('c')) {
1946
- v = v.replace(/c/g, '');
1947
- }
1948
- value.value = v;
1949
- },
1950
- ];
1951
- <input type="text" ref={bindValue(...value_accessors)} />
1952
- </>;
1824
+ function App() @{
1825
+ let value = track('');
1826
+ const value_accessors: [GetFunction<string>, SetFunction<string>] = [
1827
+ () => {
1828
+ return value.value.replace(/[c,b]+/g, '');
1829
+ },
1830
+ (v: string) => {
1831
+ if (v.includes('c')) {
1832
+ v = v.replace(/c/g, '');
1833
+ }
1834
+ value.value = v;
1835
+ },
1836
+ ];
1837
+ <input type="text" ref={bindValue(...value_accessors)} />
1953
1838
  }
1954
1839
 
1955
1840
  render(App);
@@ -1970,31 +1855,29 @@ describe('use value()', () => {
1970
1855
  it(
1971
1856
  'should accurately reflect values mutated through an effect even after a setter mutation via bind accessors',
1972
1857
  () => {
1973
- function App() {
1974
- return <>
1975
- let value = track('');
1976
- const value_accessors: [GetFunction<string>, SetFunction<string>] = [
1977
- () => {
1978
- return value.value;
1979
- },
1980
- (v: string) => {
1981
- if (v.includes('c')) {
1982
- v = v.replace(/c/g, '');
1983
- }
1984
- value.value = v;
1985
- },
1986
- ];
1987
- effect(() => {
1988
- value.value;
1989
-
1990
- untrack(() => {
1991
- if (value.value.includes('a')) {
1992
- value.value = value.value.replace(/a/g, '');
1993
- }
1994
- });
1858
+ function App() @{
1859
+ let value = track('');
1860
+ const value_accessors: [GetFunction<string>, SetFunction<string>] = [
1861
+ () => {
1862
+ return value.value;
1863
+ },
1864
+ (v: string) => {
1865
+ if (v.includes('c')) {
1866
+ v = v.replace(/c/g, '');
1867
+ }
1868
+ value.value = v;
1869
+ },
1870
+ ];
1871
+ effect(() => {
1872
+ value.value;
1873
+
1874
+ untrack(() => {
1875
+ if (value.value.includes('a')) {
1876
+ value.value = value.value.replace(/a/g, '');
1877
+ }
1995
1878
  });
1996
- <input type="text" ref={bindValue(...value_accessors)} />
1997
- </>;
1879
+ });
1880
+ <input type="text" ref={bindValue(...value_accessors)} />
1998
1881
  }
1999
1882
 
2000
1883
  render(App);
@@ -2015,20 +1898,20 @@ describe('use value()', () => {
2015
1898
  it(
2016
1899
  'should keep the input.value unchanged and synced with the tracked when the setter blocks updates to the tracked via bind accessors',
2017
1900
  () => {
2018
- function App() {
2019
- return <>
2020
- let value = track('');
2021
- const value_accessors: [GetFunction<string>, SetFunction<string>] = [
2022
- () => {
2023
- return value.value;
2024
- },
2025
- (v: string) => {
2026
- // no update
2027
- },
2028
- ];
1901
+ function App() @{
1902
+ let value = track('');
1903
+ const value_accessors: [GetFunction<string>, SetFunction<string>] = [
1904
+ () => {
1905
+ return value.value;
1906
+ },
1907
+ (v: string) => {
1908
+ // no update
1909
+ },
1910
+ ];
1911
+ <>
2029
1912
  <input type="text" ref={bindValue(...value_accessors)} />
2030
1913
  <div>{value.value}</div>
2031
- </>;
1914
+ </>
2032
1915
  }
2033
1916
 
2034
1917
  render(App);
@@ -2051,20 +1934,20 @@ describe('use value()', () => {
2051
1934
  it(
2052
1935
  'should keep the input.value unchanged and synced with the tracked when the setter blocks updates to the tracked via track get / set',
2053
1936
  () => {
2054
- function App() {
2055
- return <>
2056
- let value = track(
2057
- '',
2058
- (v) => {
2059
- return v;
2060
- },
2061
- () => {
2062
- return '';
2063
- },
2064
- );
1937
+ function App() @{
1938
+ let value = track(
1939
+ '',
1940
+ (v) => {
1941
+ return v;
1942
+ },
1943
+ () => {
1944
+ return '';
1945
+ },
1946
+ );
1947
+ <>
2065
1948
  <input type="text" ref={bindValue(value)} />
2066
1949
  <div>{value.value}</div>
2067
- </>;
1950
+ </>
2068
1951
  }
2069
1952
 
2070
1953
  render(App);
@@ -2089,14 +1972,12 @@ describe('bindClientWidth and bindClientHeight', () => {
2089
1972
  it('should bind element clientWidth', () => {
2090
1973
  const logs: number[] = [];
2091
1974
 
2092
- function App() {
2093
- return <>
2094
- const width = track(0);
2095
- effect(() => {
2096
- logs.push(width.value);
2097
- });
2098
- <div ref={bindClientWidth(width)} />
2099
- </>;
1975
+ function App() @{
1976
+ const width = track(0);
1977
+ effect(() => {
1978
+ logs.push(width.value);
1979
+ });
1980
+ <div ref={bindClientWidth(width)} />
2100
1981
  }
2101
1982
 
2102
1983
  render(App);
@@ -2120,14 +2001,12 @@ describe('bindClientWidth and bindClientHeight', () => {
2120
2001
  it('should bind element clientWidth with a getter and setter', () => {
2121
2002
  const logs: number[] = [];
2122
2003
 
2123
- function App() {
2124
- return <>
2125
- const width = new RippleObject({ value: 0 });
2126
- effect(() => {
2127
- logs.push(width.value);
2128
- });
2129
- <div ref={bindClientWidth(() => width.value, (v: number) => (width.value = v))} />
2130
- </>;
2004
+ function App() @{
2005
+ const width = new RippleObject({ value: 0 });
2006
+ effect(() => {
2007
+ logs.push(width.value);
2008
+ });
2009
+ <div ref={bindClientWidth(() => width.value, (v: number) => (width.value = v))} />
2131
2010
  }
2132
2011
 
2133
2012
  render(App);
@@ -2151,14 +2030,12 @@ describe('bindClientWidth and bindClientHeight', () => {
2151
2030
  it('should bind element clientHeight', () => {
2152
2031
  const logs: number[] = [];
2153
2032
 
2154
- function App() {
2155
- return <>
2156
- const height = track(0);
2157
- effect(() => {
2158
- logs.push(height.value);
2159
- });
2160
- <div ref={bindClientHeight(height)} />
2161
- </>;
2033
+ function App() @{
2034
+ const height = track(0);
2035
+ effect(() => {
2036
+ logs.push(height.value);
2037
+ });
2038
+ <div ref={bindClientHeight(height)} />
2162
2039
  }
2163
2040
 
2164
2041
  render(App);
@@ -2182,14 +2059,12 @@ describe('bindClientWidth and bindClientHeight', () => {
2182
2059
  it('should bind element clientHeight with a getter and setter', () => {
2183
2060
  const logs: number[] = [];
2184
2061
 
2185
- function App() {
2186
- return <>
2187
- const height = new RippleObject({ value: 0 });
2188
- effect(() => {
2189
- logs.push(height.value);
2190
- });
2191
- <div ref={bindClientHeight(() => height.value, (v: number) => (height.value = v))} />
2192
- </>;
2062
+ function App() @{
2063
+ const height = new RippleObject({ value: 0 });
2064
+ effect(() => {
2065
+ logs.push(height.value);
2066
+ });
2067
+ <div ref={bindClientHeight(() => height.value, (v: number) => (height.value = v))} />
2193
2068
  }
2194
2069
 
2195
2070
  render(App);
@@ -2215,14 +2090,12 @@ describe('bindOffsetWidth and bindOffsetHeight', () => {
2215
2090
  it('should bind element offsetWidth', () => {
2216
2091
  const logs: number[] = [];
2217
2092
 
2218
- function App() {
2219
- return <>
2220
- const width = track(0);
2221
- effect(() => {
2222
- logs.push(width.value);
2223
- });
2224
- <div ref={bindOffsetWidth(width)} />
2225
- </>;
2093
+ function App() @{
2094
+ const width = track(0);
2095
+ effect(() => {
2096
+ logs.push(width.value);
2097
+ });
2098
+ <div ref={bindOffsetWidth(width)} />
2226
2099
  }
2227
2100
 
2228
2101
  render(App);
@@ -2246,14 +2119,12 @@ describe('bindOffsetWidth and bindOffsetHeight', () => {
2246
2119
  it('should bind element offsetWidth with a getter and setter', () => {
2247
2120
  const logs: number[] = [];
2248
2121
 
2249
- function App() {
2250
- return <>
2251
- const width = new RippleObject({ value: 0 });
2252
- effect(() => {
2253
- logs.push(width.value);
2254
- });
2255
- <div ref={bindOffsetWidth(() => width.value, (v: number) => (width.value = v))} />
2256
- </>;
2122
+ function App() @{
2123
+ const width = new RippleObject({ value: 0 });
2124
+ effect(() => {
2125
+ logs.push(width.value);
2126
+ });
2127
+ <div ref={bindOffsetWidth(() => width.value, (v: number) => (width.value = v))} />
2257
2128
  }
2258
2129
 
2259
2130
  render(App);
@@ -2277,14 +2148,12 @@ describe('bindOffsetWidth and bindOffsetHeight', () => {
2277
2148
  it('should bind element offsetHeight', () => {
2278
2149
  const logs: number[] = [];
2279
2150
 
2280
- function App() {
2281
- return <>
2282
- const height = track(0);
2283
- effect(() => {
2284
- logs.push(height.value);
2285
- });
2286
- <div ref={bindOffsetHeight(height)} />
2287
- </>;
2151
+ function App() @{
2152
+ const height = track(0);
2153
+ effect(() => {
2154
+ logs.push(height.value);
2155
+ });
2156
+ <div ref={bindOffsetHeight(height)} />
2288
2157
  }
2289
2158
 
2290
2159
  render(App);
@@ -2308,14 +2177,12 @@ describe('bindOffsetWidth and bindOffsetHeight', () => {
2308
2177
  it('should bind element offsetHeight with a getter and setter', () => {
2309
2178
  const logs: number[] = [];
2310
2179
 
2311
- function App() {
2312
- return <>
2313
- const height = new RippleObject({ value: 0 });
2314
- effect(() => {
2315
- logs.push(height.value);
2316
- });
2317
- <div ref={bindOffsetHeight(() => height.value, (v: number) => (height.value = v))} />
2318
- </>;
2180
+ function App() @{
2181
+ const height = new RippleObject({ value: 0 });
2182
+ effect(() => {
2183
+ logs.push(height.value);
2184
+ });
2185
+ <div ref={bindOffsetHeight(() => height.value, (v: number) => (height.value = v))} />
2319
2186
  }
2320
2187
 
2321
2188
  render(App);
@@ -2341,14 +2208,12 @@ describe('bindContentRect', () => {
2341
2208
  it('should bind element contentRect', () => {
2342
2209
  const logs: DOMRectReadOnly[] = [];
2343
2210
 
2344
- function App() {
2345
- return <>
2346
- const rect = track(null);
2347
- effect(() => {
2348
- if (rect.value) logs.push(rect.value);
2349
- });
2350
- <div ref={bindContentRect(rect)} />
2351
- </>;
2211
+ function App() @{
2212
+ const rect = track(null);
2213
+ effect(() => {
2214
+ if (rect.value) logs.push(rect.value);
2215
+ });
2216
+ <div ref={bindContentRect(rect)} />
2352
2217
  }
2353
2218
 
2354
2219
  render(App);
@@ -2371,21 +2236,19 @@ describe('bindContentRect', () => {
2371
2236
  it('should bind element contentRect with a getter and setter', () => {
2372
2237
  const logs: DOMRectReadOnly[] = [];
2373
2238
 
2374
- function App() {
2375
- return <>
2376
- const rect: RippleObject<{ value: DOMRectReadOnly | null }> = new RippleObject({
2377
- value: null,
2378
- });
2379
- effect(() => {
2380
- if (rect.value) logs.push(rect.value);
2381
- });
2382
- <div
2383
- ref={bindContentRect<null | DOMRectReadOnly>(
2384
- () => rect.value,
2385
- (v: DOMRectReadOnly) => (rect.value = v),
2386
- )}
2387
- />
2388
- </>;
2239
+ function App() @{
2240
+ const rect: RippleObject<{ value: DOMRectReadOnly | null }> = new RippleObject({
2241
+ value: null,
2242
+ });
2243
+ effect(() => {
2244
+ if (rect.value) logs.push(rect.value);
2245
+ });
2246
+ <div
2247
+ ref={bindContentRect<null | DOMRectReadOnly>(
2248
+ () => rect.value,
2249
+ (v: DOMRectReadOnly) => (rect.value = v),
2250
+ )}
2251
+ />
2389
2252
  }
2390
2253
 
2391
2254
  render(App);
@@ -2410,14 +2273,12 @@ describe('bindContentBoxSize', () => {
2410
2273
  it('should bind element contentBoxSize', () => {
2411
2274
  const logs: any[] = [];
2412
2275
 
2413
- function App() {
2414
- return <>
2415
- const boxSize = track(null);
2416
- effect(() => {
2417
- if (boxSize.value) logs.push(boxSize.value);
2418
- });
2419
- <div ref={bindContentBoxSize(boxSize)} />
2420
- </>;
2276
+ function App() @{
2277
+ const boxSize = track(null);
2278
+ effect(() => {
2279
+ if (boxSize.value) logs.push(boxSize.value);
2280
+ });
2281
+ <div ref={bindContentBoxSize(boxSize)} />
2421
2282
  }
2422
2283
 
2423
2284
  render(App);
@@ -2443,21 +2304,19 @@ describe('bindContentBoxSize', () => {
2443
2304
  { blockSize: 200, inlineSize: 300 },
2444
2305
  ];
2445
2306
 
2446
- function App() {
2447
- return <>
2448
- const boxSize: RippleObject<{ value: typeof mockBoxSize | null }> = new RippleObject({
2449
- value: null,
2450
- });
2451
- effect(() => {
2452
- if (boxSize.value) logs.push(boxSize.value);
2453
- });
2454
- <div
2455
- ref={bindContentBoxSize<null | typeof mockBoxSize>(
2456
- () => boxSize.value,
2457
- (v: typeof mockBoxSize) => (boxSize.value = v),
2458
- )}
2459
- />
2460
- </>;
2307
+ function App() @{
2308
+ const boxSize: RippleObject<{ value: typeof mockBoxSize | null }> = new RippleObject({
2309
+ value: null,
2310
+ });
2311
+ effect(() => {
2312
+ if (boxSize.value) logs.push(boxSize.value);
2313
+ });
2314
+ <div
2315
+ ref={bindContentBoxSize<null | typeof mockBoxSize>(
2316
+ () => boxSize.value,
2317
+ (v: typeof mockBoxSize) => (boxSize.value = v),
2318
+ )}
2319
+ />
2461
2320
  }
2462
2321
 
2463
2322
  render(App);
@@ -2479,14 +2338,12 @@ describe('bindBorderBoxSize', () => {
2479
2338
  it('should bind element borderBoxSize', () => {
2480
2339
  const logs: any[] = [];
2481
2340
 
2482
- function App() {
2483
- return <>
2484
- const boxSize = track(null);
2485
- effect(() => {
2486
- if (boxSize.value) logs.push(boxSize.value);
2487
- });
2488
- <div ref={bindBorderBoxSize(boxSize)} />
2489
- </>;
2341
+ function App() @{
2342
+ const boxSize = track(null);
2343
+ effect(() => {
2344
+ if (boxSize.value) logs.push(boxSize.value);
2345
+ });
2346
+ <div ref={bindBorderBoxSize(boxSize)} />
2490
2347
  }
2491
2348
 
2492
2349
  render(App);
@@ -2512,21 +2369,19 @@ describe('bindBorderBoxSize', () => {
2512
2369
  { blockSize: 220, inlineSize: 320 },
2513
2370
  ];
2514
2371
 
2515
- function App() {
2516
- return <>
2517
- const boxSize: RippleObject<{ value: typeof mockBoxSize | null }> = new RippleObject({
2518
- value: null,
2519
- });
2520
- effect(() => {
2521
- if (boxSize.value) logs.push(boxSize.value);
2522
- });
2523
- <div
2524
- ref={bindBorderBoxSize<null | typeof mockBoxSize>(
2525
- () => boxSize.value,
2526
- (v: typeof mockBoxSize) => (boxSize.value = v),
2527
- )}
2528
- />
2529
- </>;
2372
+ function App() @{
2373
+ const boxSize: RippleObject<{ value: typeof mockBoxSize | null }> = new RippleObject({
2374
+ value: null,
2375
+ });
2376
+ effect(() => {
2377
+ if (boxSize.value) logs.push(boxSize.value);
2378
+ });
2379
+ <div
2380
+ ref={bindBorderBoxSize<null | typeof mockBoxSize>(
2381
+ () => boxSize.value,
2382
+ (v: typeof mockBoxSize) => (boxSize.value = v),
2383
+ )}
2384
+ />
2530
2385
  }
2531
2386
 
2532
2387
  render(App);
@@ -2548,14 +2403,12 @@ describe('bindDevicePixelContentBoxSize', () => {
2548
2403
  it('should bind element devicePixelContentBoxSize', () => {
2549
2404
  const logs: any[] = [];
2550
2405
 
2551
- function App() {
2552
- return <>
2553
- const boxSize = track(null);
2554
- effect(() => {
2555
- if (boxSize.value) logs.push(boxSize.value);
2556
- });
2557
- <div ref={bindDevicePixelContentBoxSize(boxSize)} />
2558
- </>;
2406
+ function App() @{
2407
+ const boxSize = track(null);
2408
+ effect(() => {
2409
+ if (boxSize.value) logs.push(boxSize.value);
2410
+ });
2411
+ <div ref={bindDevicePixelContentBoxSize(boxSize)} />
2559
2412
  }
2560
2413
 
2561
2414
  render(App);
@@ -2581,21 +2434,19 @@ describe('bindDevicePixelContentBoxSize', () => {
2581
2434
  { blockSize: 400, inlineSize: 600 },
2582
2435
  ];
2583
2436
 
2584
- function App() {
2585
- return <>
2586
- const boxSize: RippleObject<{ value: typeof mockBoxSize | null }> = new RippleObject({
2587
- value: null,
2588
- });
2589
- effect(() => {
2590
- if (boxSize.value) logs.push(boxSize.value);
2591
- });
2592
- <div
2593
- ref={bindDevicePixelContentBoxSize<null | typeof mockBoxSize>(
2594
- () => boxSize.value,
2595
- (v: typeof mockBoxSize) => (boxSize.value = v),
2596
- )}
2597
- />
2598
- </>;
2437
+ function App() @{
2438
+ const boxSize: RippleObject<{ value: typeof mockBoxSize | null }> = new RippleObject({
2439
+ value: null,
2440
+ });
2441
+ effect(() => {
2442
+ if (boxSize.value) logs.push(boxSize.value);
2443
+ });
2444
+ <div
2445
+ ref={bindDevicePixelContentBoxSize<null | typeof mockBoxSize>(
2446
+ () => boxSize.value,
2447
+ (v: typeof mockBoxSize) => (boxSize.value = v),
2448
+ )}
2449
+ />
2599
2450
  }
2600
2451
 
2601
2452
  render(App);
@@ -2617,14 +2468,12 @@ describe('bindInnerHTML', () => {
2617
2468
  it('should bind element innerHTML', () => {
2618
2469
  const logs: string[] = [];
2619
2470
 
2620
- function App() {
2621
- return <>
2622
- const html = track('<strong>Hello</strong>');
2623
- effect(() => {
2624
- logs.push(html.value);
2625
- });
2626
- <div contenteditable="true" ref={bindInnerHTML(html)} />
2627
- </>;
2471
+ function App() @{
2472
+ const html = track('<strong>Hello</strong>');
2473
+ effect(() => {
2474
+ logs.push(html.value);
2475
+ });
2476
+ <div contenteditable="true" ref={bindInnerHTML(html)} />
2628
2477
  }
2629
2478
 
2630
2479
  render(App);
@@ -2643,17 +2492,15 @@ describe('bindInnerHTML', () => {
2643
2492
  it('should bind element innerHTML', () => {
2644
2493
  const logs: string[] = [];
2645
2494
 
2646
- function App() {
2647
- return <>
2648
- const html = new RippleObject({ value: '<strong>Hello</strong>' });
2649
- effect(() => {
2650
- logs.push(html.value);
2651
- });
2652
- <div
2653
- contenteditable="true"
2654
- ref={bindInnerHTML(() => html.value, (v: string) => (html.value = v))}
2655
- />
2656
- </>;
2495
+ function App() @{
2496
+ const html = new RippleObject({ value: '<strong>Hello</strong>' });
2497
+ effect(() => {
2498
+ logs.push(html.value);
2499
+ });
2500
+ <div
2501
+ contenteditable="true"
2502
+ ref={bindInnerHTML(() => html.value, (v: string) => (html.value = v))}
2503
+ />
2657
2504
  }
2658
2505
 
2659
2506
  render(App);
@@ -2670,14 +2517,12 @@ describe('bindInnerHTML', () => {
2670
2517
  });
2671
2518
 
2672
2519
  it('should update innerHTML when tracked value changes', () => {
2673
- function App() {
2674
- return <>
2675
- const html = track('<p>Initial</p>');
2676
- <div>
2677
- <div contenteditable="true" ref={bindInnerHTML(html)} />
2678
- <button onClick={() => (html.value = '<p>Updated</p>')}>{'Update'}</button>
2679
- </div>
2680
- </>;
2520
+ function App() @{
2521
+ const html = track('<p>Initial</p>');
2522
+ <div>
2523
+ <div contenteditable="true" ref={bindInnerHTML(html)} />
2524
+ <button onClick={() => (html.value = '<p>Updated</p>')}>{'Update'}</button>
2525
+ </div>
2681
2526
  }
2682
2527
 
2683
2528
  render(App);
@@ -2695,17 +2540,15 @@ describe('bindInnerHTML', () => {
2695
2540
  });
2696
2541
 
2697
2542
  it('should update innerHTML when tracked value changes with a getter and setter', () => {
2698
- function App() {
2699
- return <>
2700
- const html = new RippleObject({ value: '<p>Initial</p>' });
2701
- <div>
2702
- <div
2703
- contenteditable="true"
2704
- ref={bindInnerHTML(() => html.value, (v: string) => (html.value = v))}
2705
- />
2706
- <button onClick={() => (html.value = '<p>Updated</p>')}>{'Update'}</button>
2707
- </div>
2708
- </>;
2543
+ function App() @{
2544
+ const html = new RippleObject({ value: '<p>Initial</p>' });
2545
+ <div>
2546
+ <div
2547
+ contenteditable="true"
2548
+ ref={bindInnerHTML(() => html.value, (v: string) => (html.value = v))}
2549
+ />
2550
+ <button onClick={() => (html.value = '<p>Updated</p>')}>{'Update'}</button>
2551
+ </div>
2709
2552
  }
2710
2553
 
2711
2554
  render(App);
@@ -2723,11 +2566,9 @@ describe('bindInnerHTML', () => {
2723
2566
  });
2724
2567
 
2725
2568
  it('should handle null innerHTML value', () => {
2726
- function App() {
2727
- return <>
2728
- const html = track(null);
2729
- <div contenteditable="true" ref={bindInnerHTML(html)} />
2730
- </>;
2569
+ function App() @{
2570
+ const html = track(null);
2571
+ <div contenteditable="true" ref={bindInnerHTML(html)} />
2731
2572
  }
2732
2573
 
2733
2574
  render(App);
@@ -2739,14 +2580,12 @@ describe('bindInnerHTML', () => {
2739
2580
  });
2740
2581
 
2741
2582
  it('should handle null innerHTML value with a getter and setter', () => {
2742
- function App() {
2743
- return <>
2744
- const html: RippleObject<{ value: null | string }> = new RippleObject({ value: null });
2745
- <div
2746
- contenteditable="true"
2747
- ref={bindInnerHTML(() => html.value, (v: string | null) => (html.value = v))}
2748
- />
2749
- </>;
2583
+ function App() @{
2584
+ const html: RippleObject<{ value: null | string }> = new RippleObject({ value: null });
2585
+ <div
2586
+ contenteditable="true"
2587
+ ref={bindInnerHTML(() => html.value, (v: string | null) => (html.value = v))}
2588
+ />
2750
2589
  }
2751
2590
 
2752
2591
  render(App);
@@ -2762,14 +2601,12 @@ describe('bindInnerText', () => {
2762
2601
  it('should bind element innerText', () => {
2763
2602
  const logs: string[] = [];
2764
2603
 
2765
- function App() {
2766
- return <>
2767
- const text = track('Hello World');
2768
- effect(() => {
2769
- logs.push(text.value);
2770
- });
2771
- <div contenteditable="true" ref={bindInnerText(text)} />
2772
- </>;
2604
+ function App() @{
2605
+ const text = track('Hello World');
2606
+ effect(() => {
2607
+ logs.push(text.value);
2608
+ });
2609
+ <div contenteditable="true" ref={bindInnerText(text)} />
2773
2610
  }
2774
2611
 
2775
2612
  render(App);
@@ -2788,17 +2625,15 @@ describe('bindInnerText', () => {
2788
2625
  it('should bind element innerText with a getter and setter', () => {
2789
2626
  const logs: string[] = [];
2790
2627
 
2791
- function App() {
2792
- return <>
2793
- const text = new RippleObject({ value: 'Hello World' });
2794
- effect(() => {
2795
- logs.push(text.value);
2796
- });
2797
- <div
2798
- contenteditable="true"
2799
- ref={bindInnerText(() => text.value, (v: string) => (text.value = v))}
2800
- />
2801
- </>;
2628
+ function App() @{
2629
+ const text = new RippleObject({ value: 'Hello World' });
2630
+ effect(() => {
2631
+ logs.push(text.value);
2632
+ });
2633
+ <div
2634
+ contenteditable="true"
2635
+ ref={bindInnerText(() => text.value, (v: string) => (text.value = v))}
2636
+ />
2802
2637
  }
2803
2638
 
2804
2639
  render(App);
@@ -2815,14 +2650,12 @@ describe('bindInnerText', () => {
2815
2650
  });
2816
2651
 
2817
2652
  it('should update innerText when tracked value changes', () => {
2818
- function App() {
2819
- return <>
2820
- const text = track('Before');
2821
- <div>
2822
- <div contenteditable="true" ref={bindInnerText(text)} />
2823
- <button onClick={() => (text.value = 'After')}>{'Update'}</button>
2824
- </div>
2825
- </>;
2653
+ function App() @{
2654
+ const text = track('Before');
2655
+ <div>
2656
+ <div contenteditable="true" ref={bindInnerText(text)} />
2657
+ <button onClick={() => (text.value = 'After')}>{'Update'}</button>
2658
+ </div>
2826
2659
  }
2827
2660
 
2828
2661
  render(App);
@@ -2840,17 +2673,15 @@ describe('bindInnerText', () => {
2840
2673
  });
2841
2674
 
2842
2675
  it('should update innerText when tracked value changes with a getter and setter', () => {
2843
- function App() {
2844
- return <>
2845
- const text = new RippleObject({ value: 'Before' });
2846
- <div>
2847
- <div
2848
- contenteditable="true"
2849
- ref={bindInnerText(() => text.value, (v: string) => (text.value = v))}
2850
- />
2851
- <button onClick={() => (text.value = 'After')}>{'Update'}</button>
2852
- </div>
2853
- </>;
2676
+ function App() @{
2677
+ const text = new RippleObject({ value: 'Before' });
2678
+ <div>
2679
+ <div
2680
+ contenteditable="true"
2681
+ ref={bindInnerText(() => text.value, (v: string) => (text.value = v))}
2682
+ />
2683
+ <button onClick={() => (text.value = 'After')}>{'Update'}</button>
2684
+ </div>
2854
2685
  }
2855
2686
 
2856
2687
  render(App);
@@ -2872,14 +2703,12 @@ describe('bindTextContent', () => {
2872
2703
  it('should bind element textContent', () => {
2873
2704
  const logs: string[] = [];
2874
2705
 
2875
- function App() {
2876
- return <>
2877
- const text = track('Sample text');
2878
- effect(() => {
2879
- logs.push(text.value);
2880
- });
2881
- <div contenteditable="true" ref={bindTextContent(text)} />
2882
- </>;
2706
+ function App() @{
2707
+ const text = track('Sample text');
2708
+ effect(() => {
2709
+ logs.push(text.value);
2710
+ });
2711
+ <div contenteditable="true" ref={bindTextContent(text)} />
2883
2712
  }
2884
2713
 
2885
2714
  render(App);
@@ -2898,17 +2727,15 @@ describe('bindTextContent', () => {
2898
2727
  it('should bind element textContent with a getter and setter', () => {
2899
2728
  const logs: string[] = [];
2900
2729
 
2901
- function App() {
2902
- return <>
2903
- const text = new RippleObject({ value: 'Sample text' });
2904
- effect(() => {
2905
- logs.push(text.value);
2906
- });
2907
- <div
2908
- contenteditable="true"
2909
- ref={bindTextContent(() => text.value, (v: string) => (text.value = v))}
2910
- />
2911
- </>;
2730
+ function App() @{
2731
+ const text = new RippleObject({ value: 'Sample text' });
2732
+ effect(() => {
2733
+ logs.push(text.value);
2734
+ });
2735
+ <div
2736
+ contenteditable="true"
2737
+ ref={bindTextContent(() => text.value, (v: string) => (text.value = v))}
2738
+ />
2912
2739
  }
2913
2740
 
2914
2741
  render(App);
@@ -2925,14 +2752,12 @@ describe('bindTextContent', () => {
2925
2752
  });
2926
2753
 
2927
2754
  it('should update textContent when tracked value changes', () => {
2928
- function App() {
2929
- return <>
2930
- const text = track('Start');
2931
- <div>
2932
- <div contenteditable="true" ref={bindTextContent(text)} />
2933
- <button onClick={() => (text.value = 'End')}>{'Update'}</button>
2934
- </div>
2935
- </>;
2755
+ function App() @{
2756
+ const text = track('Start');
2757
+ <div>
2758
+ <div contenteditable="true" ref={bindTextContent(text)} />
2759
+ <button onClick={() => (text.value = 'End')}>{'Update'}</button>
2760
+ </div>
2936
2761
  }
2937
2762
 
2938
2763
  render(App);
@@ -2950,17 +2775,15 @@ describe('bindTextContent', () => {
2950
2775
  });
2951
2776
 
2952
2777
  it('should update textContent when tracked value changes with a getter and setter', () => {
2953
- function App() {
2954
- return <>
2955
- const text = new RippleObject({ value: 'Start' });
2956
- <div>
2957
- <div
2958
- contenteditable="true"
2959
- ref={bindTextContent(() => text.value, (v: string) => (text.value = v))}
2960
- />
2961
- <button onClick={() => (text.value = 'End')}>{'Update'}</button>
2962
- </div>
2963
- </>;
2778
+ function App() @{
2779
+ const text = new RippleObject({ value: 'Start' });
2780
+ <div>
2781
+ <div
2782
+ contenteditable="true"
2783
+ ref={bindTextContent(() => text.value, (v: string) => (text.value = v))}
2784
+ />
2785
+ <button onClick={() => (text.value = 'End')}>{'Update'}</button>
2786
+ </div>
2964
2787
  }
2965
2788
 
2966
2789
  render(App);
@@ -2978,11 +2801,9 @@ describe('bindTextContent', () => {
2978
2801
  });
2979
2802
 
2980
2803
  it('should handle null textContent value', () => {
2981
- function App() {
2982
- return <>
2983
- const text = track(null);
2984
- <div contenteditable="true" ref={bindTextContent(text)} />
2985
- </>;
2804
+ function App() @{
2805
+ const text = track(null);
2806
+ <div contenteditable="true" ref={bindTextContent(text)} />
2986
2807
  }
2987
2808
 
2988
2809
  render(App);
@@ -2994,17 +2815,15 @@ describe('bindTextContent', () => {
2994
2815
  });
2995
2816
 
2996
2817
  it('should handle null textContent value with a getter and setter', () => {
2997
- function App() {
2998
- return <>
2999
- const text: RippleObject<{ value: string | null }> = new RippleObject({ value: null });
3000
- <div
3001
- contenteditable="true"
3002
- ref={bindTextContent<string | null>(
3003
- () => text.value,
3004
- (v: string | null) => (text.value = v),
3005
- )}
3006
- />
3007
- </>;
2818
+ function App() @{
2819
+ const text: RippleObject<{ value: string | null }> = new RippleObject({ value: null });
2820
+ <div
2821
+ contenteditable="true"
2822
+ ref={bindTextContent<string | null>(
2823
+ () => text.value,
2824
+ (v: string | null) => (text.value = v),
2825
+ )}
2826
+ />
3008
2827
  }
3009
2828
 
3010
2829
  render(App);
@@ -3020,14 +2839,12 @@ describe('bindNode', () => {
3020
2839
  it('should update tracked value with element reference', () => {
3021
2840
  let capturedNode: HTMLElement | null = null;
3022
2841
 
3023
- function App() {
3024
- return <>
3025
- const nodeRef = track(null);
3026
- effect(() => {
3027
- capturedNode = nodeRef.value;
3028
- });
3029
- <div ref={bindNode(nodeRef)} />
3030
- </>;
2842
+ function App() @{
2843
+ const nodeRef = track(null);
2844
+ effect(() => {
2845
+ capturedNode = nodeRef.value;
2846
+ });
2847
+ <div ref={bindNode(nodeRef)} />
3031
2848
  }
3032
2849
 
3033
2850
  render(App);
@@ -3040,16 +2857,14 @@ describe('bindNode', () => {
3040
2857
  it('should update tracked value with element reference and with a getter and setter', () => {
3041
2858
  let capturedNode: HTMLElement | null = null;
3042
2859
 
3043
- function App() {
3044
- return <>
3045
- const nodeRef: RippleObject<{ value: HTMLElement | null }> = new RippleObject({
3046
- value: null,
3047
- });
3048
- effect(() => {
3049
- capturedNode = nodeRef.value;
3050
- });
3051
- <div ref={bindNode(() => nodeRef.value, (v: HTMLElement | null) => (nodeRef.value = v))} />
3052
- </>;
2860
+ function App() @{
2861
+ const nodeRef: RippleObject<{ value: HTMLElement | null }> = new RippleObject({
2862
+ value: null,
2863
+ });
2864
+ effect(() => {
2865
+ capturedNode = nodeRef.value;
2866
+ });
2867
+ <div ref={bindNode(() => nodeRef.value, (v: HTMLElement | null) => (nodeRef.value = v))} />
3053
2868
  }
3054
2869
 
3055
2870
  render(App);
@@ -3060,22 +2875,18 @@ describe('bindNode', () => {
3060
2875
  });
3061
2876
 
3062
2877
  it('should allow access to bound element', () => {
3063
- function App() {
3064
- return <>
3065
- const inputRef = track<HTMLInputElement | null>(null);
3066
- <div>
3067
- <input type="text" ref={bindNode(inputRef)} />
3068
- <button
3069
- onClick={() => {
3070
- if (inputRef.value) {
3071
- inputRef.value.value = 'Set by ref';
3072
- }
3073
- }}
3074
- >
3075
- {'Set Value'}
3076
- </button>
3077
- </div>
3078
- </>;
2878
+ function App() @{
2879
+ const inputRef = track<HTMLInputElement | null>(null);
2880
+ <div>
2881
+ <input type="text" ref={bindNode(inputRef)} />
2882
+ <button
2883
+ onClick={() => {
2884
+ if (inputRef.value) {
2885
+ inputRef.value.value = 'Set by ref';
2886
+ }
2887
+ }}
2888
+ >{'Set Value'}</button>
2889
+ </div>
3079
2890
  }
3080
2891
 
3081
2892
  render(App);
@@ -3093,27 +2904,23 @@ describe('bindNode', () => {
3093
2904
  });
3094
2905
 
3095
2906
  it('should allow access to bound element with a getter and setter', () => {
3096
- function App() {
3097
- return <>
3098
- const inputRef: RippleObject<{ node: HTMLInputElement | null }> = new RippleObject({
3099
- node: null,
3100
- });
3101
- <div>
3102
- <input
3103
- type="text"
3104
- ref={bindNode(() => inputRef.node, (v: HTMLInputElement | null) => (inputRef.node = v))}
3105
- />
3106
- <button
3107
- onClick={() => {
3108
- if (inputRef.node) {
3109
- inputRef.node.value = 'Set by ref';
3110
- }
3111
- }}
3112
- >
3113
- {'Set Value'}
3114
- </button>
3115
- </div>
3116
- </>;
2907
+ function App() @{
2908
+ const inputRef: RippleObject<{ node: HTMLInputElement | null }> = new RippleObject({
2909
+ node: null,
2910
+ });
2911
+ <div>
2912
+ <input
2913
+ type="text"
2914
+ ref={bindNode(() => inputRef.node, (v: HTMLInputElement | null) => (inputRef.node = v))}
2915
+ />
2916
+ <button
2917
+ onClick={() => {
2918
+ if (inputRef.node) {
2919
+ inputRef.node.value = 'Set by ref';
2920
+ }
2921
+ }}
2922
+ >{'Set Value'}</button>
2923
+ </div>
3117
2924
  }
3118
2925
 
3119
2926
  render(App);
@@ -3135,15 +2942,13 @@ describe('bindFiles', () => {
3135
2942
  it('should bind files from file input', () => {
3136
2943
  const logs: FileList[] = [];
3137
2944
 
3138
- function App() {
3139
- return <>
3140
- const files = track(null);
3141
- effect(() => {
3142
- files.value;
3143
- if (files.value) logs.push(files.value);
3144
- });
3145
- <input type="file" multiple ref={bindFiles(files)} />
3146
- </>;
2945
+ function App() @{
2946
+ const files = track(null);
2947
+ effect(() => {
2948
+ files.value;
2949
+ if (files.value) logs.push(files.value);
2950
+ });
2951
+ <input type="file" multiple ref={bindFiles(files)} />
3147
2952
  }
3148
2953
 
3149
2954
  render(App);
@@ -3176,19 +2981,17 @@ describe('bindFiles', () => {
3176
2981
  it('should bind files from file input with a getter and setter', () => {
3177
2982
  const logs: FileList[] = [];
3178
2983
 
3179
- function App() {
3180
- return <>
3181
- const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
3182
- effect(() => {
3183
- files.items;
3184
- if (files.items) logs.push(files.items);
3185
- });
3186
- <input
3187
- type="file"
3188
- multiple
3189
- ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
3190
- />
3191
- </>;
2984
+ function App() @{
2985
+ const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
2986
+ effect(() => {
2987
+ files.items;
2988
+ if (files.items) logs.push(files.items);
2989
+ });
2990
+ <input
2991
+ type="file"
2992
+ multiple
2993
+ ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
2994
+ />
3192
2995
  }
3193
2996
 
3194
2997
  render(App);
@@ -3221,14 +3024,12 @@ describe('bindFiles', () => {
3221
3024
  it('should update tracked value when files are selected', () => {
3222
3025
  let capturedFiles: FileList | null = null;
3223
3026
 
3224
- function App() {
3225
- return <>
3226
- const files = track<FileList | null>(null);
3227
- effect(() => {
3228
- capturedFiles = files.value;
3229
- });
3230
- <input type="file" ref={bindFiles(files)} />
3231
- </>;
3027
+ function App() @{
3028
+ const files = track<FileList | null>(null);
3029
+ effect(() => {
3030
+ capturedFiles = files.value;
3031
+ });
3032
+ <input type="file" ref={bindFiles(files)} />
3232
3033
  }
3233
3034
 
3234
3035
  render(App);
@@ -3256,17 +3057,15 @@ describe('bindFiles', () => {
3256
3057
  it('should update tracked value when files are selected with a getter and setter', () => {
3257
3058
  let capturedFiles: FileList | null = null;
3258
3059
 
3259
- function App() {
3260
- return <>
3261
- const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
3262
- effect(() => {
3263
- capturedFiles = files.items;
3264
- });
3265
- <input
3266
- type="file"
3267
- ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
3268
- />
3269
- </>;
3060
+ function App() @{
3061
+ const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
3062
+ effect(() => {
3063
+ capturedFiles = files.items;
3064
+ });
3065
+ <input
3066
+ type="file"
3067
+ ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
3068
+ />
3270
3069
  }
3271
3070
 
3272
3071
  render(App);
@@ -3294,27 +3093,23 @@ describe('bindFiles', () => {
3294
3093
  it('should allow clearing files via input.files', () => {
3295
3094
  let capturedFiles: FileList | null = null;
3296
3095
 
3297
- function App() {
3298
- return <>
3299
- const files = track<FileList | null>(null);
3300
- const input = track<HTMLInputElement | null>(null);
3301
- effect(() => {
3302
- capturedFiles = files.value;
3303
- });
3304
- <div>
3305
- <input type="file" ref={bindFiles<FileList>(files)} ref={bindNode(input)} />
3306
- <button
3307
- onClick={() => {
3308
- if (input.value) {
3309
- input.value.files = new DataTransfer().files;
3310
- input.value.dispatchEvent(new Event('change', { bubbles: true }));
3311
- }
3312
- }}
3313
- >
3314
- {'Clear'}
3315
- </button>
3316
- </div>
3317
- </>;
3096
+ function App() @{
3097
+ const files = track<FileList | null>(null);
3098
+ const input = track<HTMLInputElement | null>(null);
3099
+ effect(() => {
3100
+ capturedFiles = files.value;
3101
+ });
3102
+ <div>
3103
+ <input type="file" ref={bindFiles<FileList>(files)} ref={bindNode(input)} />
3104
+ <button
3105
+ onClick={() => {
3106
+ if (input.value) {
3107
+ input.value.files = new DataTransfer().files;
3108
+ input.value.dispatchEvent(new Event('change', { bubbles: true }));
3109
+ }
3110
+ }}
3111
+ >{'Clear'}</button>
3112
+ </div>
3318
3113
  }
3319
3114
 
3320
3115
  render(App);
@@ -3347,31 +3142,27 @@ describe('bindFiles', () => {
3347
3142
  it('should allow clearing files via input.files with a getter and setter', () => {
3348
3143
  let capturedFiles: FileList | null = null;
3349
3144
 
3350
- function App() {
3351
- return <>
3352
- const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
3353
- const input = track<HTMLInputElement | null>(null);
3354
- effect(() => {
3355
- capturedFiles = files.items;
3356
- });
3357
- <div>
3358
- <input
3359
- type="file"
3360
- ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
3361
- ref={bindNode(input)}
3362
- />
3363
- <button
3364
- onClick={() => {
3365
- if (input.value) {
3366
- input.value.files = new DataTransfer().files;
3367
- input.value.dispatchEvent(new Event('change', { bubbles: true }));
3368
- }
3369
- }}
3370
- >
3371
- {'Clear'}
3372
- </button>
3373
- </div>
3374
- </>;
3145
+ function App() @{
3146
+ const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
3147
+ const input = track<HTMLInputElement | null>(null);
3148
+ effect(() => {
3149
+ capturedFiles = files.items;
3150
+ });
3151
+ <div>
3152
+ <input
3153
+ type="file"
3154
+ ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
3155
+ ref={bindNode(input)}
3156
+ />
3157
+ <button
3158
+ onClick={() => {
3159
+ if (input.value) {
3160
+ input.value.files = new DataTransfer().files;
3161
+ input.value.dispatchEvent(new Event('change', { bubbles: true }));
3162
+ }
3163
+ }}
3164
+ >{'Clear'}</button>
3165
+ </div>
3375
3166
  }
3376
3167
 
3377
3168
  render(App);
@@ -3404,17 +3195,15 @@ describe('bindFiles', () => {
3404
3195
  it('should handle multiple file selections', () => {
3405
3196
  const fileCounts: number[] = [];
3406
3197
 
3407
- function App() {
3408
- return <>
3409
- const files = track<FileList | null>(null);
3410
- effect(() => {
3411
- files.value;
3412
- if (files.value) {
3413
- fileCounts.push(files.value.length);
3414
- }
3415
- });
3416
- <input type="file" multiple ref={bindFiles(files)} />
3417
- </>;
3198
+ function App() @{
3199
+ const files = track<FileList | null>(null);
3200
+ effect(() => {
3201
+ files.value;
3202
+ if (files.value) {
3203
+ fileCounts.push(files.value.length);
3204
+ }
3205
+ });
3206
+ <input type="file" multiple ref={bindFiles(files)} />
3418
3207
  }
3419
3208
 
3420
3209
  render(App);
@@ -3453,21 +3242,19 @@ describe('bindFiles', () => {
3453
3242
  it('should handle multiple file selections with a getter and setter', () => {
3454
3243
  const fileCounts: number[] = [];
3455
3244
 
3456
- function App() {
3457
- return <>
3458
- const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
3459
- effect(() => {
3460
- files.items;
3461
- if (files.items) {
3462
- fileCounts.push(files.items.length);
3463
- }
3464
- });
3465
- <input
3466
- type="file"
3467
- multiple
3468
- ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
3469
- />
3470
- </>;
3245
+ function App() @{
3246
+ const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
3247
+ effect(() => {
3248
+ files.items;
3249
+ if (files.items) {
3250
+ fileCounts.push(files.items.length);
3251
+ }
3252
+ });
3253
+ <input
3254
+ type="file"
3255
+ multiple
3256
+ ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
3257
+ />
3471
3258
  }
3472
3259
 
3473
3260
  render(App);
@@ -3506,17 +3293,15 @@ describe('bindFiles', () => {
3506
3293
  it('should handle file input without multiple attribute', () => {
3507
3294
  let capturedFile: File | null = null;
3508
3295
 
3509
- function App() {
3510
- return <>
3511
- const files = track<FileList | null>(null);
3512
- effect(() => {
3513
- files.value;
3514
- if (files.value && files.value.length > 0) {
3515
- capturedFile = files.value[0];
3516
- }
3517
- });
3518
- <input type="file" ref={bindFiles(files)} />
3519
- </>;
3296
+ function App() @{
3297
+ const files = track<FileList | null>(null);
3298
+ effect(() => {
3299
+ files.value;
3300
+ if (files.value && files.value.length > 0) {
3301
+ capturedFile = files.value[0];
3302
+ }
3303
+ });
3304
+ <input type="file" ref={bindFiles(files)} />
3520
3305
  }
3521
3306
 
3522
3307
  render(App);
@@ -3543,20 +3328,18 @@ describe('bindFiles', () => {
3543
3328
  it('should handle file input without multiple attribute with a getter and setter', () => {
3544
3329
  let capturedFile: File | null = null;
3545
3330
 
3546
- function App() {
3547
- return <>
3548
- const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
3549
- effect(() => {
3550
- files.items;
3551
- if (files.items && files.items.length > 0) {
3552
- capturedFile = files.items[0];
3553
- }
3554
- });
3555
- <input
3556
- type="file"
3557
- ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
3558
- />
3559
- </>;
3331
+ function App() @{
3332
+ const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
3333
+ effect(() => {
3334
+ files.items;
3335
+ if (files.items && files.items.length > 0) {
3336
+ capturedFile = files.items[0];
3337
+ }
3338
+ });
3339
+ <input
3340
+ type="file"
3341
+ ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
3342
+ />
3560
3343
  }
3561
3344
 
3562
3345
  render(App);
@@ -3583,14 +3366,12 @@ describe('bindFiles', () => {
3583
3366
  it('should handle empty file selection', () => {
3584
3367
  const logs: (FileList | null)[] = [];
3585
3368
 
3586
- function App() {
3587
- return <>
3588
- const files = track(null);
3589
- effect(() => {
3590
- logs.push(files.value);
3591
- });
3592
- <input type="file" ref={bindFiles(files)} />
3593
- </>;
3369
+ function App() @{
3370
+ const files = track(null);
3371
+ effect(() => {
3372
+ logs.push(files.value);
3373
+ });
3374
+ <input type="file" ref={bindFiles(files)} />
3594
3375
  }
3595
3376
 
3596
3377
  render(App);
@@ -3625,17 +3406,15 @@ describe('bindFiles', () => {
3625
3406
  it('should handle empty file selection with a getter and setter', () => {
3626
3407
  const logs: (FileList | null)[] = [];
3627
3408
 
3628
- function App() {
3629
- return <>
3630
- const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
3631
- effect(() => {
3632
- logs.push(files.items);
3633
- });
3634
- <input
3635
- type="file"
3636
- ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
3637
- />
3638
- </>;
3409
+ function App() @{
3410
+ const files: RippleObject<{ items: FileList | null }> = new RippleObject({ items: null });
3411
+ effect(() => {
3412
+ logs.push(files.items);
3413
+ });
3414
+ <input
3415
+ type="file"
3416
+ ref={bindFiles(() => files.items, (v: FileList | null) => (files.items = v))}
3417
+ />
3639
3418
  }
3640
3419
 
3641
3420
  render(App);
@@ -3671,8 +3450,8 @@ describe('bindFiles', () => {
3671
3450
  describe('error handling', () => {
3672
3451
  it('should throw error when bindValue receives non-tracked object', () => {
3673
3452
  expect(() => {
3674
- function App() {
3675
- return <><input type="text" ref={bindValue({ value: 'not tracked' })} /></>;
3453
+ function App() @{
3454
+ <input type="text" ref={bindValue({ value: 'not tracked' })} />
3676
3455
  }
3677
3456
  render(App);
3678
3457
  }).toThrow('bindValue() argument is not a tracked object');
@@ -3680,8 +3459,8 @@ describe('error handling', () => {
3680
3459
 
3681
3460
  it('should throw error when bindChecked receives non-tracked object', () => {
3682
3461
  expect(() => {
3683
- function App() {
3684
- return <><input type="checkbox" ref={bindChecked({ value: false })} /></>;
3462
+ function App() @{
3463
+ <input type="checkbox" ref={bindChecked({ value: false })} />
3685
3464
  }
3686
3465
  render(App);
3687
3466
  }).toThrow('bindChecked() argument is not a tracked object');
@@ -3689,8 +3468,8 @@ describe('error handling', () => {
3689
3468
 
3690
3469
  it('should throw error when bindIndeterminate receives non-tracked object', () => {
3691
3470
  expect(() => {
3692
- function App() {
3693
- return <><input type="checkbox" ref={bindIndeterminate({ value: false })} /></>;
3471
+ function App() @{
3472
+ <input type="checkbox" ref={bindIndeterminate({ value: false })} />
3694
3473
  }
3695
3474
  render(App);
3696
3475
  }).toThrow('bindIndeterminate() argument is not a tracked object');
@@ -3698,8 +3477,8 @@ describe('error handling', () => {
3698
3477
 
3699
3478
  it('should throw error when bindGroup receives non-tracked object', () => {
3700
3479
  expect(() => {
3701
- function App() {
3702
- return <><input type="checkbox" value="a" ref={bindGroup({ value: [] })} /></>;
3480
+ function App() @{
3481
+ <input type="checkbox" value="a" ref={bindGroup({ value: [] })} />
3703
3482
  }
3704
3483
  render(App);
3705
3484
  }).toThrow('bindGroup() argument is not a tracked object');
@@ -3707,8 +3486,8 @@ describe('error handling', () => {
3707
3486
 
3708
3487
  it('should throw error when bindClientWidth receives non-tracked object', () => {
3709
3488
  expect(() => {
3710
- function App() {
3711
- return <><div ref={bindClientWidth({ value: 0 })} /></>;
3489
+ function App() @{
3490
+ <div ref={bindClientWidth({ value: 0 })} />
3712
3491
  }
3713
3492
  render(App);
3714
3493
  }).toThrow('bindClientWidth() argument is not a tracked object');
@@ -3716,8 +3495,8 @@ describe('error handling', () => {
3716
3495
 
3717
3496
  it('should throw error when bindClientHeight receives non-tracked object', () => {
3718
3497
  expect(() => {
3719
- function App() {
3720
- return <><div ref={bindClientHeight({ value: 0 })} /></>;
3498
+ function App() @{
3499
+ <div ref={bindClientHeight({ value: 0 })} />
3721
3500
  }
3722
3501
  render(App);
3723
3502
  }).toThrow('bindClientHeight() argument is not a tracked object');
@@ -3725,8 +3504,8 @@ describe('error handling', () => {
3725
3504
 
3726
3505
  it('should throw error when bindOffsetWidth receives non-tracked object', () => {
3727
3506
  expect(() => {
3728
- function App() {
3729
- return <><div ref={bindOffsetWidth({ value: 0 })} /></>;
3507
+ function App() @{
3508
+ <div ref={bindOffsetWidth({ value: 0 })} />
3730
3509
  }
3731
3510
  render(App);
3732
3511
  }).toThrow('bindOffsetWidth() argument is not a tracked object');
@@ -3734,8 +3513,8 @@ describe('error handling', () => {
3734
3513
 
3735
3514
  it('should throw error when bindOffsetHeight receives non-tracked object', () => {
3736
3515
  expect(() => {
3737
- function App() {
3738
- return <><div ref={bindOffsetHeight({ value: 0 })} /></>;
3516
+ function App() @{
3517
+ <div ref={bindOffsetHeight({ value: 0 })} />
3739
3518
  }
3740
3519
  render(App);
3741
3520
  }).toThrow('bindOffsetHeight() argument is not a tracked object');
@@ -3743,8 +3522,8 @@ describe('error handling', () => {
3743
3522
 
3744
3523
  it('should throw error when bindContentRect receives non-tracked object', () => {
3745
3524
  expect(() => {
3746
- function App() {
3747
- return <><div ref={bindContentRect({ value: null })} /></>;
3525
+ function App() @{
3526
+ <div ref={bindContentRect({ value: null })} />
3748
3527
  }
3749
3528
  render(App);
3750
3529
  }).toThrow('bindContentRect() argument is not a tracked object');
@@ -3752,8 +3531,8 @@ describe('error handling', () => {
3752
3531
 
3753
3532
  it('should throw error when bindContentBoxSize receives non-tracked object', () => {
3754
3533
  expect(() => {
3755
- function App() {
3756
- return <><div ref={bindContentBoxSize({ value: null })} /></>;
3534
+ function App() @{
3535
+ <div ref={bindContentBoxSize({ value: null })} />
3757
3536
  }
3758
3537
  render(App);
3759
3538
  }).toThrow('bindContentBoxSize() argument is not a tracked object');
@@ -3761,8 +3540,8 @@ describe('error handling', () => {
3761
3540
 
3762
3541
  it('should throw error when bindBorderBoxSize receives non-tracked object', () => {
3763
3542
  expect(() => {
3764
- function App() {
3765
- return <><div ref={bindBorderBoxSize({ value: null })} /></>;
3543
+ function App() @{
3544
+ <div ref={bindBorderBoxSize({ value: null })} />
3766
3545
  }
3767
3546
  render(App);
3768
3547
  }).toThrow('bindBorderBoxSize() argument is not a tracked object');
@@ -3770,8 +3549,8 @@ describe('error handling', () => {
3770
3549
 
3771
3550
  it('should throw error when bindDevicePixelContentBoxSize receives non-tracked object', () => {
3772
3551
  expect(() => {
3773
- function App() {
3774
- return <><div ref={bindDevicePixelContentBoxSize({ value: null })} /></>;
3552
+ function App() @{
3553
+ <div ref={bindDevicePixelContentBoxSize({ value: null })} />
3775
3554
  }
3776
3555
  render(App);
3777
3556
  }).toThrow('bindDevicePixelContentBoxSize() argument is not a tracked object');
@@ -3779,8 +3558,8 @@ describe('error handling', () => {
3779
3558
 
3780
3559
  it('should throw error when bindInnerHTML receives non-tracked object', () => {
3781
3560
  expect(() => {
3782
- function App() {
3783
- return <><div ref={bindInnerHTML({ value: '' })} /></>;
3561
+ function App() @{
3562
+ <div ref={bindInnerHTML({ value: '' })} />
3784
3563
  }
3785
3564
  render(App);
3786
3565
  }).toThrow('bindInnerHTML() argument is not a tracked object');
@@ -3788,8 +3567,8 @@ describe('error handling', () => {
3788
3567
 
3789
3568
  it('should throw error when bindInnerText receives non-tracked object', () => {
3790
3569
  expect(() => {
3791
- function App() {
3792
- return <><div ref={bindInnerText({ value: '' })} /></>;
3570
+ function App() @{
3571
+ <div ref={bindInnerText({ value: '' })} />
3793
3572
  }
3794
3573
  render(App);
3795
3574
  }).toThrow('bindInnerText() argument is not a tracked object');
@@ -3797,8 +3576,8 @@ describe('error handling', () => {
3797
3576
 
3798
3577
  it('should throw error when bindTextContent receives non-tracked object', () => {
3799
3578
  expect(() => {
3800
- function App() {
3801
- return <><div ref={bindTextContent({ value: '' })} /></>;
3579
+ function App() @{
3580
+ <div ref={bindTextContent({ value: '' })} />
3802
3581
  }
3803
3582
  render(App);
3804
3583
  }).toThrow('bindTextContent() argument is not a tracked object');
@@ -3806,8 +3585,8 @@ describe('error handling', () => {
3806
3585
 
3807
3586
  it('should throw error when bindNode receives non-tracked object', () => {
3808
3587
  expect(() => {
3809
- function App() {
3810
- return <><div ref={bindNode({ value: null })} /></>;
3588
+ function App() @{
3589
+ <div ref={bindNode({ value: null })} />
3811
3590
  }
3812
3591
  render(App);
3813
3592
  }).toThrow('bindNode() argument is not a tracked object');
@@ -3815,8 +3594,8 @@ describe('error handling', () => {
3815
3594
 
3816
3595
  it('should throw error when bindFiles receives non-tracked object', () => {
3817
3596
  expect(() => {
3818
- function App() {
3819
- return <><input type="file" ref={bindFiles({ value: null })} /></>;
3597
+ function App() @{
3598
+ <input type="file" ref={bindFiles({ value: null })} />
3820
3599
  }
3821
3600
  render(App);
3822
3601
  }).toThrow('bindFiles() argument is not a tracked object');
@@ -3824,11 +3603,9 @@ describe('error handling', () => {
3824
3603
 
3825
3604
  it('should throw error when bindValue receives a getter but not a setter', () => {
3826
3605
  expect(() => {
3827
- function App() {
3828
- return <>
3829
- const value = track('');
3830
- <input type="text" ref={bindValue(() => value.value)} />
3831
- </>;
3606
+ function App() @{
3607
+ const value = track('');
3608
+ <input type="text" ref={bindValue(() => value.value)} />
3832
3609
  }
3833
3610
  render(App);
3834
3611
  }).toThrow(
@@ -3838,12 +3615,10 @@ describe('error handling', () => {
3838
3615
 
3839
3616
  it('should throw error when bindValue receives a getter and setter not a function', () => {
3840
3617
  expect(() => {
3841
- function App() {
3842
- return <>
3843
- const value = track('');
3844
- // @ts-expect-error invalid argument
3845
- <input type="text" ref={bindValue(() => value.value, 5)} />
3846
- </>;
3618
+ function App() @{
3619
+ const value = track('');
3620
+ // @ts-expect-error invalid argument
3621
+ <input type="text" ref={bindValue(() => value.value, 5)} />
3847
3622
  }
3848
3623
  render(App);
3849
3624
  }).toThrow(
@@ -3855,14 +3630,12 @@ describe('error handling', () => {
3855
3630
  'should throw error when bindValue on select multiple receives a non-array tracked value',
3856
3631
  () => {
3857
3632
  expect(() => {
3858
- function App() {
3859
- return <>
3860
- const value = track('2');
3861
- <select multiple ref={bindValue(value)}>
3862
- <option value="1">{'One'}</option>
3863
- <option value="2">{'Two'}</option>
3864
- </select>
3865
- </>;
3633
+ function App() @{
3634
+ const value = track('2');
3635
+ <select multiple ref={bindValue(value)}>
3636
+ <option value="1">{'One'}</option>
3637
+ <option value="2">{'Two'}</option>
3638
+ </select>
3866
3639
  }
3867
3640
 
3868
3641
  render(App);
@@ -3877,14 +3650,12 @@ describe('error handling', () => {
3877
3650
  'should throw error when bindValue on select multiple receives a non-array getter value',
3878
3651
  () => {
3879
3652
  expect(() => {
3880
- function App() {
3881
- return <>
3882
- const value = track('2');
3883
- <select multiple ref={bindValue(() => value.value, (v) => (value.value = v))}>
3884
- <option value="1">{'One'}</option>
3885
- <option value="2">{'Two'}</option>
3886
- </select>
3887
- </>;
3653
+ function App() @{
3654
+ const value = track('2');
3655
+ <select multiple ref={bindValue(() => value.value, (v) => (value.value = v))}>
3656
+ <option value="1">{'One'}</option>
3657
+ <option value="2">{'Two'}</option>
3658
+ </select>
3888
3659
  }
3889
3660
 
3890
3661
  render(App);
@@ -3899,8 +3670,8 @@ describe('error handling', () => {
3899
3670
  'should throw error when bindChecked receives non-tracked object with a getter but not a setter',
3900
3671
  () => {
3901
3672
  expect(() => {
3902
- function App() {
3903
- return <><input type="checkbox" ref={bindChecked(() => false)} /></>;
3673
+ function App() @{
3674
+ <input type="checkbox" ref={bindChecked(() => false)} />
3904
3675
  }
3905
3676
  render(App);
3906
3677
  }).toThrow(
@@ -3913,8 +3684,8 @@ describe('error handling', () => {
3913
3684
  'should throw error when bindChecked receives non-tracked object with a getter and setter not a function',
3914
3685
  () => {
3915
3686
  expect(() => {
3916
- function App() {
3917
- return <><input type="checkbox" ref={bindChecked(() => false, true)} /></>;
3687
+ function App() @{
3688
+ <input type="checkbox" ref={bindChecked(() => false, true)} />
3918
3689
  }
3919
3690
  render(App);
3920
3691
  }).toThrow(
@@ -3927,8 +3698,8 @@ describe('error handling', () => {
3927
3698
  'should throw error when bindIndeterminate receives non-tracked object with a getter and setter not a function',
3928
3699
  () => {
3929
3700
  expect(() => {
3930
- function App() {
3931
- return <><input type="checkbox" ref={bindIndeterminate(() => false, true)} /></>;
3701
+ function App() @{
3702
+ <input type="checkbox" ref={bindIndeterminate(() => false, true)} />
3932
3703
  }
3933
3704
  render(App);
3934
3705
  }).toThrow(
@@ -3941,8 +3712,8 @@ describe('error handling', () => {
3941
3712
  'should throw error when bindGroup receives non-tracked object with a getter and setter not a function',
3942
3713
  () => {
3943
3714
  expect(() => {
3944
- function App() {
3945
- return <><input type="checkbox" value="a" ref={bindGroup(() => [], true)} /></>;
3715
+ function App() @{
3716
+ <input type="checkbox" value="a" ref={bindGroup(() => [], true)} />
3946
3717
  }
3947
3718
  render(App);
3948
3719
  }).toThrow(
@@ -3955,8 +3726,8 @@ describe('error handling', () => {
3955
3726
  'should throw error when bindClientWidth receives non-tracked object with a getter and setter not a function',
3956
3727
  () => {
3957
3728
  expect(() => {
3958
- function App() {
3959
- return <><div ref={bindClientWidth(() => 0, true)} /></>;
3729
+ function App() @{
3730
+ <div ref={bindClientWidth(() => 0, true)} />
3960
3731
  }
3961
3732
  render(App);
3962
3733
  }).toThrow(
@@ -3969,8 +3740,8 @@ describe('error handling', () => {
3969
3740
  'should throw error when bindClientHeight receives non-tracked object with a getter and setter not a function',
3970
3741
  () => {
3971
3742
  expect(() => {
3972
- function App() {
3973
- return <><div ref={bindClientHeight(() => 0, true)} /></>;
3743
+ function App() @{
3744
+ <div ref={bindClientHeight(() => 0, true)} />
3974
3745
  }
3975
3746
  render(App);
3976
3747
  }).toThrow(
@@ -3983,8 +3754,8 @@ describe('error handling', () => {
3983
3754
  'should throw error when bindOffsetWidth receives non-tracked object with a getter and setter not a function',
3984
3755
  () => {
3985
3756
  expect(() => {
3986
- function App() {
3987
- return <><div ref={bindOffsetWidth(() => 0, true)} /></>;
3757
+ function App() @{
3758
+ <div ref={bindOffsetWidth(() => 0, true)} />
3988
3759
  }
3989
3760
  render(App);
3990
3761
  }).toThrow(
@@ -3997,8 +3768,8 @@ describe('error handling', () => {
3997
3768
  'should throw error when bindOffsetHeight receives non-tracked object with a getter and setter not a function',
3998
3769
  () => {
3999
3770
  expect(() => {
4000
- function App() {
4001
- return <><div ref={bindOffsetHeight(() => 0, true)} /></>;
3771
+ function App() @{
3772
+ <div ref={bindOffsetHeight(() => 0, true)} />
4002
3773
  }
4003
3774
  render(App);
4004
3775
  }).toThrow(
@@ -4011,8 +3782,8 @@ describe('error handling', () => {
4011
3782
  'should throw error when bindContentRect receives non-tracked object with a getter and setter not a function',
4012
3783
  () => {
4013
3784
  expect(() => {
4014
- function App() {
4015
- return <><div ref={bindContentRect(() => null, true)} /></>;
3785
+ function App() @{
3786
+ <div ref={bindContentRect(() => null, true)} />
4016
3787
  }
4017
3788
  render(App);
4018
3789
  }).toThrow(
@@ -4025,8 +3796,8 @@ describe('error handling', () => {
4025
3796
  'should throw error when bindContentBoxSize receives non-tracked object with a getter and setter not a function',
4026
3797
  () => {
4027
3798
  expect(() => {
4028
- function App() {
4029
- return <><div ref={bindContentBoxSize(() => null, true)} /></>;
3799
+ function App() @{
3800
+ <div ref={bindContentBoxSize(() => null, true)} />
4030
3801
  }
4031
3802
  render(App);
4032
3803
  }).toThrow(
@@ -4039,8 +3810,8 @@ describe('error handling', () => {
4039
3810
  'should throw error when bindBorderBoxSize receives non-tracked object with a getter and setter not a function',
4040
3811
  () => {
4041
3812
  expect(() => {
4042
- function App() {
4043
- return <><div ref={bindBorderBoxSize(() => null, true)} /></>;
3813
+ function App() @{
3814
+ <div ref={bindBorderBoxSize(() => null, true)} />
4044
3815
  }
4045
3816
  render(App);
4046
3817
  }).toThrow(
@@ -4053,8 +3824,8 @@ describe('error handling', () => {
4053
3824
  'should throw error when bindDevicePixelContentBoxSize receives non-tracked object with a getter and setter not a function',
4054
3825
  () => {
4055
3826
  expect(() => {
4056
- function App() {
4057
- return <><div ref={bindDevicePixelContentBoxSize(() => null, true)} /></>;
3827
+ function App() @{
3828
+ <div ref={bindDevicePixelContentBoxSize(() => null, true)} />
4058
3829
  }
4059
3830
  render(App);
4060
3831
  }).toThrow(
@@ -4067,8 +3838,8 @@ describe('error handling', () => {
4067
3838
  'should throw error when bindInnerHTML receives non-tracked object with a getter and setter not a function',
4068
3839
  () => {
4069
3840
  expect(() => {
4070
- function App() {
4071
- return <><div ref={bindInnerHTML(() => '', true)} /></>;
3841
+ function App() @{
3842
+ <div ref={bindInnerHTML(() => '', true)} />
4072
3843
  }
4073
3844
  render(App);
4074
3845
  }).toThrow(
@@ -4081,8 +3852,8 @@ describe('error handling', () => {
4081
3852
  'should throw error when bindInnerText receives non-tracked object with a getter and setter not a function',
4082
3853
  () => {
4083
3854
  expect(() => {
4084
- function App() {
4085
- return <><div ref={bindInnerText(() => '', true)} /></>;
3855
+ function App() @{
3856
+ <div ref={bindInnerText(() => '', true)} />
4086
3857
  }
4087
3858
  render(App);
4088
3859
  }).toThrow(
@@ -4095,8 +3866,8 @@ describe('error handling', () => {
4095
3866
  'should throw error when bindTextContent receives non-tracked object with a getter and setter not a function',
4096
3867
  () => {
4097
3868
  expect(() => {
4098
- function App() {
4099
- return <><div ref={bindTextContent(() => '', true)} /></>;
3869
+ function App() @{
3870
+ <div ref={bindTextContent(() => '', true)} />
4100
3871
  }
4101
3872
  render(App);
4102
3873
  }).toThrow(
@@ -4109,8 +3880,8 @@ describe('error handling', () => {
4109
3880
  'should throw error when bindNode receives non-tracked object with a getter and setter not a function',
4110
3881
  () => {
4111
3882
  expect(() => {
4112
- function App() {
4113
- return <><div ref={bindNode(() => null, true)} /></>;
3883
+ function App() @{
3884
+ <div ref={bindNode(() => null, true)} />
4114
3885
  }
4115
3886
  render(App);
4116
3887
  }).toThrow(
@@ -4123,8 +3894,8 @@ describe('error handling', () => {
4123
3894
  'should throw error when bindFiles receives non-tracked object with a getter and setter not a function',
4124
3895
  () => {
4125
3896
  expect(() => {
4126
- function App() {
4127
- return <><input type="file" ref={bindFiles(() => null, true)} /></>;
3897
+ function App() @{
3898
+ <input type="file" ref={bindFiles(() => null, true)} />
4128
3899
  }
4129
3900
  render(App);
4130
3901
  }).toThrow(