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
@@ -3,21 +3,19 @@ import { effect, flushSync, on, track } from 'ripple';
3
3
 
4
4
  describe('on() event handler', () => {
5
5
  it('should attach multiple handlers via onClick attribute (delegated)', () => {
6
- function Basic() {
7
- return <>
8
- let &[count1] = track(0);
9
- let &[count2] = track(0);
6
+ function Basic() @{
7
+ let &[count1] = track(0);
8
+ let &[count2] = track(0);
9
+ <>
10
10
  <button
11
11
  onClick={() => {
12
12
  count1++;
13
13
  count2++;
14
14
  }}
15
- >
16
- {'Click me'}
17
- </button>
15
+ >{'Click me'}</button>
18
16
  <div class="count1">{count1}</div>
19
17
  <div class="count2">{count2}</div>
20
- </>;
18
+ </>
21
19
  }
22
20
 
23
21
  render(Basic);
@@ -36,18 +34,18 @@ describe('on() event handler', () => {
36
34
  });
37
35
 
38
36
  it('should attach and remove a single event handler', () => {
39
- function Basic() {
40
- return <>
41
- let &[count] = track(0);
42
- const setupListener = (node: HTMLButtonElement) => {
43
- const remove = on(node, 'click', () => {
44
- count++;
45
- });
46
- return remove;
47
- };
37
+ function Basic() @{
38
+ let &[count] = track(0);
39
+ const setupListener = (node: HTMLButtonElement) => {
40
+ const remove = on(node, 'click', () => {
41
+ count++;
42
+ });
43
+ return remove;
44
+ };
45
+ <>
48
46
  <button ref={setupListener}>{'Click me'}</button>
49
47
  <div class="count">{count}</div>
50
- </>;
48
+ </>
51
49
  }
52
50
 
53
51
  render(Basic);
@@ -68,26 +66,26 @@ describe('on() event handler', () => {
68
66
  });
69
67
 
70
68
  it('should handle multiple different event types on same element', () => {
71
- function Basic() {
72
- return <>
73
- let &[clickCount] = track(0);
74
- let &[mousedownCount] = track(0);
75
- const setupListeners = (node: HTMLButtonElement) => {
76
- const remove1 = on(node, 'click', () => {
77
- clickCount++;
78
- });
79
- const remove2 = on(node, 'mousedown', () => {
80
- mousedownCount++;
81
- });
82
- return () => {
83
- remove1();
84
- remove2();
85
- };
69
+ function Basic() @{
70
+ let &[clickCount] = track(0);
71
+ let &[mousedownCount] = track(0);
72
+ const setupListeners = (node: HTMLButtonElement) => {
73
+ const remove1 = on(node, 'click', () => {
74
+ clickCount++;
75
+ });
76
+ const remove2 = on(node, 'mousedown', () => {
77
+ mousedownCount++;
78
+ });
79
+ return () => {
80
+ remove1();
81
+ remove2();
86
82
  };
83
+ };
84
+ <>
87
85
  <button ref={setupListeners}>{'Test'}</button>
88
86
  <div class="click-count">{clickCount}</div>
89
87
  <div class="mousedown-count">{mousedownCount}</div>
90
- </>;
88
+ </>
91
89
  }
92
90
 
93
91
  render(Basic);
@@ -118,28 +116,28 @@ describe('on() event handler', () => {
118
116
  });
119
117
 
120
118
  it('should handle multiple handlers for same event type on same element', () => {
121
- function Basic() {
122
- return <>
123
- let &[callOrder] = track<number[]>([]);
124
- const setupListeners = (node: HTMLButtonElement) => {
125
- const remove1 = on(node, 'click', () => {
126
- callOrder = [...callOrder, 1];
127
- });
128
- const remove2 = on(node, 'click', () => {
129
- callOrder = [...callOrder, 2];
130
- });
131
- const remove3 = on(node, 'click', () => {
132
- callOrder = [...callOrder, 3];
133
- });
134
- return () => {
135
- remove1();
136
- remove2();
137
- remove3();
138
- };
119
+ function Basic() @{
120
+ let &[callOrder] = track<number[]>([]);
121
+ const setupListeners = (node: HTMLButtonElement) => {
122
+ const remove1 = on(node, 'click', () => {
123
+ callOrder = [...callOrder, 1];
124
+ });
125
+ const remove2 = on(node, 'click', () => {
126
+ callOrder = [...callOrder, 2];
127
+ });
128
+ const remove3 = on(node, 'click', () => {
129
+ callOrder = [...callOrder, 3];
130
+ });
131
+ return () => {
132
+ remove1();
133
+ remove2();
134
+ remove3();
139
135
  };
136
+ };
137
+ <>
140
138
  <button ref={setupListeners}>{'Click me'}</button>
141
139
  <div class="order">{callOrder.join(',')}</div>
142
- </>;
140
+ </>
143
141
  }
144
142
 
145
143
  render(Basic);
@@ -161,44 +159,40 @@ describe('on() event handler', () => {
161
159
  });
162
160
 
163
161
  it('should remove specific handler without affecting others', () => {
164
- function Basic() {
165
- return <>
166
- let &[handler1Called] = track(0);
167
- let &[handler2Called] = track(0);
168
- let &[handler3Called] = track(0);
169
- let removeHandler2: OnEventListenerRemover | undefined;
170
- const setupListeners = (node: HTMLButtonElement) => {
171
- const remove1 = on(node, 'click', () => {
172
- handler1Called++;
173
- });
174
- removeHandler2 = on(node, 'click', () => {
175
- handler2Called++;
176
- });
177
- const remove3 = on(node, 'click', () => {
178
- handler3Called++;
179
- });
180
- return () => {
181
- remove1();
182
- removeHandler2?.();
183
- remove3();
184
- };
162
+ function Basic() @{
163
+ let &[handler1Called] = track(0);
164
+ let &[handler2Called] = track(0);
165
+ let &[handler3Called] = track(0);
166
+ let removeHandler2: OnEventListenerRemover | undefined;
167
+ const setupListeners = (node: HTMLButtonElement) => {
168
+ const remove1 = on(node, 'click', () => {
169
+ handler1Called++;
170
+ });
171
+ removeHandler2 = on(node, 'click', () => {
172
+ handler2Called++;
173
+ });
174
+ const remove3 = on(node, 'click', () => {
175
+ handler3Called++;
176
+ });
177
+ return () => {
178
+ remove1();
179
+ removeHandler2?.();
180
+ remove3();
185
181
  };
186
- <div>
187
- <button class="test-btn" ref={setupListeners}>{'Click me'}</button>
188
- <button
189
- class="remove-btn"
190
- onClick={() => {
191
- removeHandler2?.();
192
- removeHandler2 = undefined;
193
- }}
194
- >
195
- {'Remove handler 2'}
196
- </button>
197
- <div class="h1">{handler1Called}</div>
198
- <div class="h2">{handler2Called}</div>
199
- <div class="h3">{handler3Called}</div>
200
- </div>
201
- </>;
182
+ };
183
+ <div>
184
+ <button class="test-btn" ref={setupListeners}>{'Click me'}</button>
185
+ <button
186
+ class="remove-btn"
187
+ onClick={() => {
188
+ removeHandler2?.();
189
+ removeHandler2 = undefined;
190
+ }}
191
+ >{'Remove handler 2'}</button>
192
+ <div class="h1">{handler1Called}</div>
193
+ <div class="h2">{handler2Called}</div>
194
+ <div class="h3">{handler3Called}</div>
195
+ </div>
202
196
  }
203
197
 
204
198
  render(Basic);
@@ -239,31 +233,33 @@ describe('on() event handler', () => {
239
233
  it(
240
234
  'should handle change event with multiple handlers (like bindChecked and bindIndeterminate)',
241
235
  () => {
242
- function Basic() {
243
- return <>
244
- let &[checked] = track(false);
245
- let &[indeterminate] = track(true);
246
- const setupListeners = (node: HTMLInputElement) => {
247
- node.indeterminate = indeterminate;
248
- node.checked = checked;
249
-
250
- const remove1 = on(node, 'change', () => {
251
- checked = node.checked;
252
- });
253
- const remove2 = on(node, 'change', () => {
254
- indeterminate = node.indeterminate;
255
- });
256
- return () => {
257
- remove1();
258
- remove2();
259
- };
236
+ function Basic() @{
237
+ let &[checked] = track(false);
238
+ let &[indeterminate] = track(true);
239
+ const setupListeners = (node: HTMLInputElement) => {
240
+ node.indeterminate = indeterminate;
241
+ node.checked = checked;
242
+
243
+ const remove1 = on(node, 'change', () => {
244
+ checked = node.checked;
245
+ });
246
+ const remove2 = on(node, 'change', () => {
247
+ indeterminate = node.indeterminate;
248
+ });
249
+ return () => {
250
+ remove1();
251
+ remove2();
260
252
  };
261
- <div>
262
- <input type="checkbox" ref={setupListeners} />
263
- <div class="checked">{checked ? 'true' : 'false'}</div>
264
- <div class="indeterminate">{indeterminate ? 'true' : 'false'}</div>
253
+ };
254
+ <div>
255
+ <input type="checkbox" ref={setupListeners} />
256
+ <div class="checked">
257
+ {checked ? 'true' : 'false'}
265
258
  </div>
266
- </>;
259
+ <div class="indeterminate">
260
+ {indeterminate ? 'true' : 'false'}
261
+ </div>
262
+ </div>
267
263
  }
268
264
 
269
265
  render(Basic);
@@ -288,18 +284,18 @@ describe('on() event handler', () => {
288
284
  );
289
285
 
290
286
  it('should support non-delegated events', () => {
291
- function Basic() {
292
- return <>
293
- let &[focusCount] = track(0);
294
- const setupListener = (node: HTMLInputElement) => {
295
- const remove = on(node, 'focus', () => {
296
- focusCount++;
297
- });
298
- return remove;
299
- };
287
+ function Basic() @{
288
+ let &[focusCount] = track(0);
289
+ const setupListener = (node: HTMLInputElement) => {
290
+ const remove = on(node, 'focus', () => {
291
+ focusCount++;
292
+ });
293
+ return remove;
294
+ };
295
+ <>
300
296
  <input ref={setupListener} />
301
297
  <div class="focus-count">{focusCount}</div>
302
- </>;
298
+ </>
303
299
  }
304
300
 
305
301
  render(Basic);
@@ -320,44 +316,40 @@ describe('on() event handler', () => {
320
316
  });
321
317
 
322
318
  it('should handle removal of all handlers for same event type', () => {
323
- function Basic() {
324
- return <>
325
- let &[count] = track(0);
326
- let remove1: OnEventListenerRemover | undefined;
327
- let remove2: OnEventListenerRemover | undefined;
328
- let remove3: OnEventListenerRemover | undefined;
329
- const setupListeners = (node: HTMLButtonElement) => {
330
- remove1 = on(node, 'click', () => {
331
- count++;
332
- });
333
- remove2 = on(node, 'click', () => {
334
- count += 10;
335
- });
336
- remove3 = on(node, 'click', () => {
337
- count += 100;
338
- });
339
- return () => {
319
+ function Basic() @{
320
+ let &[count] = track(0);
321
+ let remove1: OnEventListenerRemover | undefined;
322
+ let remove2: OnEventListenerRemover | undefined;
323
+ let remove3: OnEventListenerRemover | undefined;
324
+ const setupListeners = (node: HTMLButtonElement) => {
325
+ remove1 = on(node, 'click', () => {
326
+ count++;
327
+ });
328
+ remove2 = on(node, 'click', () => {
329
+ count += 10;
330
+ });
331
+ remove3 = on(node, 'click', () => {
332
+ count += 100;
333
+ });
334
+ return () => {
335
+ remove1?.();
336
+ remove2?.();
337
+ remove3?.();
338
+ };
339
+ };
340
+ <div>
341
+ <button class="test-btn" ref={setupListeners}>{'Click me'}</button>
342
+ <button
343
+ class="remove-all"
344
+ onClick={() => {
340
345
  remove1?.();
341
346
  remove2?.();
342
347
  remove3?.();
343
- };
344
- };
345
- <div>
346
- <button class="test-btn" ref={setupListeners}>{'Click me'}</button>
347
- <button
348
- class="remove-all"
349
- onClick={() => {
350
- remove1?.();
351
- remove2?.();
352
- remove3?.();
353
- remove1 = remove2 = remove3 = undefined;
354
- }}
355
- >
356
- {'Remove all'}
357
- </button>
358
- <div class="count">{count}</div>
359
- </div>
360
- </>;
348
+ remove1 = remove2 = remove3 = undefined;
349
+ }}
350
+ >{'Remove all'}</button>
351
+ <div class="count">{count}</div>
352
+ </div>
361
353
  }
362
354
 
363
355
  render(Basic);
@@ -385,27 +377,27 @@ describe('on() event handler', () => {
385
377
  });
386
378
 
387
379
  it('should not add duplicate handlers when same handler is attached multiple times', () => {
388
- function Basic() {
389
- return <>
390
- let &[count] = track(0);
391
- const sharedHandler = () => {
392
- count++;
393
- };
394
- const setupListeners = (node: HTMLButtonElement) => {
395
- // Attach the same handler multiple times
396
- const remove1 = on(node, 'click', sharedHandler);
397
- const remove2 = on(node, 'click', sharedHandler);
398
- const remove3 = on(node, 'click', sharedHandler);
399
-
400
- return () => {
401
- remove1?.();
402
- remove2?.();
403
- remove3?.();
404
- };
380
+ function Basic() @{
381
+ let &[count] = track(0);
382
+ const sharedHandler = () => {
383
+ count++;
384
+ };
385
+ const setupListeners = (node: HTMLButtonElement) => {
386
+ // Attach the same handler multiple times
387
+ const remove1 = on(node, 'click', sharedHandler);
388
+ const remove2 = on(node, 'click', sharedHandler);
389
+ const remove3 = on(node, 'click', sharedHandler);
390
+
391
+ return () => {
392
+ remove1?.();
393
+ remove2?.();
394
+ remove3?.();
405
395
  };
396
+ };
397
+ <>
406
398
  <button ref={setupListeners}>{'Click me'}</button>
407
399
  <div class="count">{count}</div>
408
- </>;
400
+ </>
409
401
  }
410
402
 
411
403
  render(Basic);
@@ -427,27 +419,27 @@ describe('on() event handler', () => {
427
419
  });
428
420
 
429
421
  it('should allow duplicate handlers when delegated is false (no deduplication)', () => {
430
- function Basic() {
431
- return <>
432
- let &[count] = track(0);
433
- const sharedHandler = () => {
434
- count++;
435
- };
436
- const setupListeners = (node: HTMLButtonElement) => {
437
- // Attach the same handler multiple times with delegated: false
438
- const remove1 = on(node, 'click', sharedHandler, { delegated: false });
439
- const remove2 = on(node, 'click', sharedHandler, { delegated: false });
440
- const remove3 = on(node, 'click', sharedHandler, { delegated: false });
441
-
442
- return () => {
443
- remove1?.();
444
- remove2?.();
445
- remove3?.();
446
- };
422
+ function Basic() @{
423
+ let &[count] = track(0);
424
+ const sharedHandler = () => {
425
+ count++;
426
+ };
427
+ const setupListeners = (node: HTMLButtonElement) => {
428
+ // Attach the same handler multiple times with delegated: false
429
+ const remove1 = on(node, 'click', sharedHandler, { delegated: false });
430
+ const remove2 = on(node, 'click', sharedHandler, { delegated: false });
431
+ const remove3 = on(node, 'click', sharedHandler, { delegated: false });
432
+
433
+ return () => {
434
+ remove1?.();
435
+ remove2?.();
436
+ remove3?.();
447
437
  };
438
+ };
439
+ <>
448
440
  <button ref={setupListeners}>{'Click me'}</button>
449
441
  <div class="count">{count}</div>
450
- </>;
442
+ </>
451
443
  }
452
444
 
453
445
  render(Basic);
@@ -470,26 +462,26 @@ describe('on() event handler', () => {
470
462
  });
471
463
 
472
464
  it('should fire capture event on parent before bubbling event on child', () => {
473
- function Basic() {
474
- return <>
475
- let &[callOrder] = track<string[]>([]);
476
- const parentCaptureHandler = () => {
477
- callOrder = [...callOrder, 'parent-capture'];
478
- };
479
- const childBubbleHandler = () => {
480
- callOrder = [...callOrder, 'child-bubble'];
481
- };
482
- const setupParent = (node: HTMLDivElement) => {
483
- return on(node, 'clickCapture', parentCaptureHandler);
484
- };
485
- const setupChild = (node: HTMLButtonElement) => {
486
- return on(node, 'click', childBubbleHandler);
487
- };
465
+ function Basic() @{
466
+ let &[callOrder] = track<string[]>([]);
467
+ const parentCaptureHandler = () => {
468
+ callOrder = [...callOrder, 'parent-capture'];
469
+ };
470
+ const childBubbleHandler = () => {
471
+ callOrder = [...callOrder, 'child-bubble'];
472
+ };
473
+ const setupParent = (node: HTMLDivElement) => {
474
+ return on(node, 'clickCapture', parentCaptureHandler);
475
+ };
476
+ const setupChild = (node: HTMLButtonElement) => {
477
+ return on(node, 'click', childBubbleHandler);
478
+ };
479
+ <>
488
480
  <div ref={setupParent} class="parent">
489
481
  <button ref={setupChild} class="child">{'Click me'}</button>
490
482
  </div>
491
483
  <div class="order">{callOrder.join(',')}</div>
492
- </>;
484
+ </>
493
485
  }
494
486
 
495
487
  render(Basic);
@@ -512,28 +504,28 @@ describe('on() event handler', () => {
512
504
  });
513
505
 
514
506
  it('should fire handler only once when once option is true', () => {
515
- function Basic() {
516
- return <>
517
- let &[count] = track(0);
518
- let &[permanentCount] = track(0);
519
- const setupListeners = (node: HTMLButtonElement) => {
520
- const onceHandler = on(node, 'click', () => {
521
- count++;
522
- }, { once: true });
523
-
524
- const permanentHandler = on(node, 'click', () => {
525
- permanentCount++;
526
- });
507
+ function Basic() @{
508
+ let &[count] = track(0);
509
+ let &[permanentCount] = track(0);
510
+ const setupListeners = (node: HTMLButtonElement) => {
511
+ const onceHandler = on(node, 'click', () => {
512
+ count++;
513
+ }, { once: true });
527
514
 
528
- return () => {
529
- onceHandler?.();
530
- permanentHandler?.();
531
- };
515
+ const permanentHandler = on(node, 'click', () => {
516
+ permanentCount++;
517
+ });
518
+
519
+ return () => {
520
+ onceHandler?.();
521
+ permanentHandler?.();
532
522
  };
523
+ };
524
+ <>
533
525
  <button ref={setupListeners}>{'Click me'}</button>
534
526
  <div class="once-count">{count}</div>
535
527
  <div class="permanent-count">{permanentCount}</div>
536
- </>;
528
+ </>
537
529
  }
538
530
 
539
531
  render(Basic);
@@ -566,20 +558,18 @@ describe('on() event handler', () => {
566
558
  });
567
559
 
568
560
  it('should handle click events on window', () => {
569
- function Basic() {
570
- return <>
571
- let &[windowClickCount] = track(0);
572
- effect(() => {
573
- const removeWindowListener = on(window, 'click', () => {
574
- windowClickCount++;
575
- });
576
- return removeWindowListener;
561
+ function Basic() @{
562
+ let &[windowClickCount] = track(0);
563
+ effect(() => {
564
+ const removeWindowListener = on(window, 'click', () => {
565
+ windowClickCount++;
577
566
  });
578
- <div>
579
- <button class="test-btn">{'Click me'}</button>
580
- <div class="window-count">{windowClickCount}</div>
581
- </div>
582
- </>;
567
+ return removeWindowListener;
568
+ });
569
+ <div>
570
+ <button class="test-btn">{'Click me'}</button>
571
+ <div class="window-count">{windowClickCount}</div>
572
+ </div>
583
573
  }
584
574
 
585
575
  render(Basic);
@@ -602,20 +592,18 @@ describe('on() event handler', () => {
602
592
  });
603
593
 
604
594
  it('should handle click events on document', () => {
605
- function Basic() {
606
- return <>
607
- let &[documentClickCount] = track(0);
608
- effect(() => {
609
- const removeDocumentListener = on(document, 'click', () => {
610
- documentClickCount++;
611
- });
612
- return removeDocumentListener;
595
+ function Basic() @{
596
+ let &[documentClickCount] = track(0);
597
+ effect(() => {
598
+ const removeDocumentListener = on(document, 'click', () => {
599
+ documentClickCount++;
613
600
  });
614
- <div>
615
- <button class="test-btn">{'Click me'}</button>
616
- <div class="document-count">{documentClickCount}</div>
617
- </div>
618
- </>;
601
+ return removeDocumentListener;
602
+ });
603
+ <div>
604
+ <button class="test-btn">{'Click me'}</button>
605
+ <div class="document-count">{documentClickCount}</div>
606
+ </div>
619
607
  }
620
608
 
621
609
  render(Basic);
@@ -638,20 +626,18 @@ describe('on() event handler', () => {
638
626
  });
639
627
 
640
628
  it('should handle click events on body', () => {
641
- function Basic() {
642
- return <>
643
- let &[bodyClickCount] = track(0);
644
- effect(() => {
645
- const removeBodyListener = on(document.body, 'click', () => {
646
- bodyClickCount++;
647
- });
648
- return removeBodyListener;
629
+ function Basic() @{
630
+ let &[bodyClickCount] = track(0);
631
+ effect(() => {
632
+ const removeBodyListener = on(document.body, 'click', () => {
633
+ bodyClickCount++;
649
634
  });
650
- <div>
651
- <button class="test-btn">{'Click me'}</button>
652
- <div class="body-count">{bodyClickCount}</div>
653
- </div>
654
- </>;
635
+ return removeBodyListener;
636
+ });
637
+ <div>
638
+ <button class="test-btn">{'Click me'}</button>
639
+ <div class="body-count">{bodyClickCount}</div>
640
+ </div>
655
641
  }
656
642
 
657
643
  render(Basic);