ripple 0.3.72 → 0.3.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (172) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/package.json +3 -3
  3. package/src/jsx-runtime.d.ts +4 -10
  4. package/src/runtime/dynamic-client.js +33 -0
  5. package/src/runtime/dynamic-server.js +80 -0
  6. package/src/runtime/index-client.js +5 -13
  7. package/src/runtime/index-server.js +2 -0
  8. package/src/runtime/internal/client/blocks.js +6 -27
  9. package/src/runtime/internal/client/composite.js +11 -6
  10. package/src/runtime/internal/client/for.js +80 -5
  11. package/src/runtime/internal/client/index.js +0 -2
  12. package/src/runtime/internal/client/render.js +5 -2
  13. package/src/runtime/internal/client/types.d.ts +0 -10
  14. package/src/runtime/internal/server/index.js +8 -1
  15. package/tests/client/__snapshots__/computed-properties.test.tsrx.snap +8 -0
  16. package/tests/client/__snapshots__/for.test.tsrx.snap +22 -0
  17. package/tests/client/__snapshots__/html.test.tsrx.snap +4 -0
  18. package/tests/client/array/array.copy-within.test.tsrx +19 -19
  19. package/tests/client/array/array.derived.test.tsrx +97 -109
  20. package/tests/client/array/array.iteration.test.tsrx +28 -28
  21. package/tests/client/array/array.mutations.test.tsrx +68 -68
  22. package/tests/client/array/array.static.test.tsrx +82 -92
  23. package/tests/client/array/array.to-methods.test.tsrx +15 -15
  24. package/tests/client/async-suspend.test.tsrx +180 -179
  25. package/tests/client/basic/__snapshots__/basic.attributes.test.tsrx.snap +2 -0
  26. package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +4 -0
  27. package/tests/client/basic/basic.attributes.test.tsrx +273 -317
  28. package/tests/client/basic/basic.collections.test.tsrx +55 -61
  29. package/tests/client/basic/basic.components.test.tsrx +198 -220
  30. package/tests/client/basic/basic.errors.test.tsrx +70 -76
  31. package/tests/client/basic/basic.events.test.tsrx +80 -85
  32. package/tests/client/basic/basic.get-set.test.tsrx +54 -64
  33. package/tests/client/basic/basic.hmr.test.tsrx +15 -19
  34. package/tests/client/basic/basic.reactivity.test.tsrx +121 -135
  35. package/tests/client/basic/basic.rendering.test.tsrx +273 -178
  36. package/tests/client/basic/basic.styling.test.tsrx +16 -14
  37. package/tests/client/basic/basic.utilities.test.tsrx +8 -10
  38. package/tests/client/boundaries.test.tsrx +18 -18
  39. package/tests/client/compiler/compiler.assignments.test.tsrx +77 -76
  40. package/tests/client/compiler/compiler.attributes.test.tsrx +18 -14
  41. package/tests/client/compiler/compiler.basic.test.tsrx +357 -288
  42. package/tests/client/compiler/compiler.regex.test.tsrx +40 -44
  43. package/tests/client/compiler/compiler.tracked-access.test.tsrx +57 -38
  44. package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
  45. package/tests/client/compiler/compiler.typescript.test.tsrx +4 -3
  46. package/tests/client/composite/composite.dynamic-components.test.tsrx +62 -47
  47. package/tests/client/composite/composite.generics.test.tsrx +165 -167
  48. package/tests/client/composite/composite.props.test.tsrx +66 -74
  49. package/tests/client/composite/composite.reactivity.test.tsrx +132 -166
  50. package/tests/client/composite/composite.render.test.tsrx +92 -101
  51. package/tests/client/computed-properties.test.tsrx +14 -18
  52. package/tests/client/context.test.tsrx +14 -18
  53. package/tests/client/css/global-additional-cases.test.tsrx +493 -439
  54. package/tests/client/css/global-advanced-selectors.test.tsrx +169 -153
  55. package/tests/client/css/global-at-rules.test.tsrx +71 -66
  56. package/tests/client/css/global-basic.test.tsrx +105 -98
  57. package/tests/client/css/global-classes-ids.test.tsrx +128 -114
  58. package/tests/client/css/global-combinators.test.tsrx +83 -78
  59. package/tests/client/css/global-complex-nesting.test.tsrx +134 -120
  60. package/tests/client/css/global-edge-cases.test.tsrx +138 -120
  61. package/tests/client/css/global-keyframes.test.tsrx +108 -96
  62. package/tests/client/css/global-nested.test.tsrx +88 -78
  63. package/tests/client/css/global-pseudo.test.tsrx +104 -98
  64. package/tests/client/css/global-scoping.test.tsrx +145 -125
  65. package/tests/client/css/style-identifier.test.tsrx +65 -72
  66. package/tests/client/date.test.tsrx +83 -83
  67. package/tests/client/dynamic-elements.test.tsrx +318 -299
  68. package/tests/client/events.test.tsrx +252 -266
  69. package/tests/client/for.test.tsrx +120 -127
  70. package/tests/client/head.test.tsrx +74 -48
  71. package/tests/client/html.test.tsrx +37 -49
  72. package/tests/client/input-value.test.tsrx +1125 -1354
  73. package/tests/client/lazy-array.test.tsrx +10 -16
  74. package/tests/client/lazy-destructuring.test.tsrx +169 -221
  75. package/tests/client/map.test.tsrx +39 -41
  76. package/tests/client/media-query.test.tsrx +15 -19
  77. package/tests/client/object.test.tsrx +46 -56
  78. package/tests/client/portal.test.tsrx +31 -37
  79. package/tests/client/ref.test.tsrx +173 -193
  80. package/tests/client/return.test.tsrx +62 -37
  81. package/tests/client/set.test.tsrx +33 -33
  82. package/tests/client/svg.test.tsrx +197 -216
  83. package/tests/client/switch.test.tsrx +201 -191
  84. package/tests/client/track-async-hydration.test.tsrx +14 -18
  85. package/tests/client/tracked-index-access.test.tsrx +18 -28
  86. package/tests/client/try.test.tsrx +494 -619
  87. package/tests/client/tsx.test.tsrx +286 -292
  88. package/tests/client/typescript-generics.test.tsrx +121 -129
  89. package/tests/client/url/url.derived.test.tsrx +21 -25
  90. package/tests/client/url/url.parsing.test.tsrx +35 -35
  91. package/tests/client/url/url.partial-removal.test.tsrx +32 -32
  92. package/tests/client/url/url.reactivity.test.tsrx +68 -72
  93. package/tests/client/url/url.serialization.test.tsrx +8 -8
  94. package/tests/client/url-search-params/url-search-params.derived.test.tsrx +21 -27
  95. package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +16 -16
  96. package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +37 -37
  97. package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +56 -60
  98. package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +32 -34
  99. package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +9 -9
  100. package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +10 -10
  101. package/tests/hydration/compiled/client/basic.js +390 -319
  102. package/tests/hydration/compiled/client/composite.js +52 -44
  103. package/tests/hydration/compiled/client/for.js +734 -604
  104. package/tests/hydration/compiled/client/head.js +183 -103
  105. package/tests/hydration/compiled/client/html.js +93 -86
  106. package/tests/hydration/compiled/client/if-children.js +95 -71
  107. package/tests/hydration/compiled/client/if.js +113 -89
  108. package/tests/hydration/compiled/client/mixed-control-flow.js +225 -209
  109. package/tests/hydration/compiled/client/nested-control-flow.js +94 -98
  110. package/tests/hydration/compiled/client/reactivity.js +26 -24
  111. package/tests/hydration/compiled/client/return.js +8 -42
  112. package/tests/hydration/compiled/client/switch.js +208 -173
  113. package/tests/hydration/compiled/client/track-async-serialization.js +176 -128
  114. package/tests/hydration/compiled/client/try.js +29 -21
  115. package/tests/hydration/compiled/server/basic.js +210 -221
  116. package/tests/hydration/compiled/server/composite.js +13 -14
  117. package/tests/hydration/compiled/server/for.js +427 -444
  118. package/tests/hydration/compiled/server/head.js +199 -189
  119. package/tests/hydration/compiled/server/html.js +33 -41
  120. package/tests/hydration/compiled/server/if-children.js +114 -117
  121. package/tests/hydration/compiled/server/if.js +77 -83
  122. package/tests/hydration/compiled/server/mixed-control-flow.js +145 -150
  123. package/tests/hydration/compiled/server/nested-control-flow.js +10 -0
  124. package/tests/hydration/compiled/server/reactivity.js +24 -22
  125. package/tests/hydration/compiled/server/return.js +6 -18
  126. package/tests/hydration/compiled/server/switch.js +179 -176
  127. package/tests/hydration/compiled/server/track-async-serialization.js +88 -70
  128. package/tests/hydration/compiled/server/try.js +31 -35
  129. package/tests/hydration/components/basic.tsrx +216 -258
  130. package/tests/hydration/components/composite.tsrx +32 -42
  131. package/tests/hydration/components/events.tsrx +81 -101
  132. package/tests/hydration/components/for.tsrx +270 -336
  133. package/tests/hydration/components/head.tsrx +43 -39
  134. package/tests/hydration/components/hmr.tsrx +16 -22
  135. package/tests/hydration/components/html-in-template.tsrx +15 -21
  136. package/tests/hydration/components/html.tsrx +442 -526
  137. package/tests/hydration/components/if-children.tsrx +107 -125
  138. package/tests/hydration/components/if.tsrx +68 -90
  139. package/tests/hydration/components/mixed-control-flow.tsrx +65 -72
  140. package/tests/hydration/components/nested-control-flow.tsrx +202 -216
  141. package/tests/hydration/components/portal.tsrx +33 -41
  142. package/tests/hydration/components/reactivity.tsrx +26 -34
  143. package/tests/hydration/components/return.tsrx +4 -6
  144. package/tests/hydration/components/switch.tsrx +73 -78
  145. package/tests/hydration/components/track-async-serialization.tsrx +83 -93
  146. package/tests/hydration/components/try.tsrx +37 -51
  147. package/tests/hydration/switch.test.js +8 -8
  148. package/tests/server/await.test.tsrx +3 -3
  149. package/tests/server/basic.attributes.test.tsrx +117 -162
  150. package/tests/server/basic.components.test.tsrx +164 -194
  151. package/tests/server/basic.test.tsrx +299 -199
  152. package/tests/server/compiler.test.tsrx +142 -72
  153. package/tests/server/composite.props.test.tsrx +54 -58
  154. package/tests/server/composite.test.tsrx +165 -167
  155. package/tests/server/context.test.tsrx +13 -17
  156. package/tests/server/dynamic-elements.test.tsrx +147 -148
  157. package/tests/server/for.test.tsrx +115 -84
  158. package/tests/server/head.test.tsrx +54 -31
  159. package/tests/server/html-nesting-validation.test.tsrx +16 -8
  160. package/tests/server/if.test.tsrx +49 -59
  161. package/tests/server/lazy-destructuring.test.tsrx +288 -366
  162. package/tests/server/return.test.tsrx +58 -36
  163. package/tests/server/streaming-ssr.test.tsrx +4 -4
  164. package/tests/server/style-identifier.test.tsrx +61 -69
  165. package/tests/server/switch.test.tsrx +89 -97
  166. package/tests/server/track-async-serialization.test.tsrx +85 -103
  167. package/tests/server/try.test.tsrx +275 -360
  168. package/tests/utils/ref-types.test.js +72 -0
  169. package/tests/utils/vite-plugin-config.test.js +41 -74
  170. package/types/index.d.ts +29 -4
  171. package/src/runtime/internal/client/compat.js +0 -40
  172. package/tests/utils/compiler-compat-config.test.js +0 -38
@@ -2,280 +2,266 @@
2
2
  // Each component tests one specific combination of for / if / switch.
3
3
 
4
4
  // ── for + if (2 items shown, 1 hidden) ────────────────────────────────────────
5
- export function ForIf() {
6
- return <>
7
- const items = [
8
- { id: 1, show: true, label: 'One' },
9
- { id: 2, show: true, label: 'Two' },
10
- { id: 3, show: false, label: 'Three' },
11
- ];
12
- <ul class="for-if">
13
- for (const item of items; key item.id) {
14
- if (item.show) {
15
- <li class={`item item-${item.id}`}>{item.label}</li>
16
- }
5
+ export function ForIf() @{
6
+ const items = [
7
+ { id: 1, show: true, label: 'One' },
8
+ { id: 2, show: true, label: 'Two' },
9
+ { id: 3, show: false, label: 'Three' },
10
+ ];
11
+ <ul class="for-if">
12
+ @for (const item of items; key item.id) {
13
+ @if (item.show) {
14
+ <li class={`item item-${item.id}`}>{item.label}</li>
17
15
  }
18
- </ul>
19
- </>;
16
+ }
17
+ </ul>
20
18
  }
21
19
 
22
20
  // ── for + switch (3 items, alternating cases) ─────────────────────────────────
23
- export function ForSwitch() {
24
- return <>
25
- const items = [
26
- { id: 1, kind: 'a' },
27
- { id: 2, kind: 'b' },
28
- { id: 3, kind: 'a' },
29
- ];
30
- <ul class="for-switch">
31
- for (const item of items; key item.id) {
32
- switch (item.kind) {
33
- case 'a':
34
- <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
35
- break;
36
- default:
37
- <li class={`item item-${item.id} kind-b`}>{`B-${item.id}`}</li>
21
+ export function ForSwitch() @{
22
+ const items = [
23
+ { id: 1, kind: 'a' },
24
+ { id: 2, kind: 'b' },
25
+ { id: 3, kind: 'a' },
26
+ ];
27
+ <ul class="for-switch">
28
+ @for (const item of items; key item.id) {
29
+ @switch (item.kind) {
30
+ @case 'a': {
31
+ <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
32
+ }
33
+ @default: {
34
+ <li class={`item item-${item.id} kind-b`}>{`B-${item.id}`}</li>
38
35
  }
39
36
  }
40
- </ul>
41
- </>;
37
+ }
38
+ </ul>
42
39
  }
43
40
 
44
41
  // ── if + switch (no for loop) ─────────────────────────────────────────────────
45
- export function IfSwitch() {
46
- return <>
47
- const show = true;
48
- const kind = 'a';
49
- <div class="if-switch">
50
- if (show) {
51
- switch (kind) {
52
- case 'a':
53
- <p class="case-a">{'Case A'}</p>
54
- break;
55
- default:
56
- <p class="case-default">{'Default'}</p>
42
+ export function IfSwitch() @{
43
+ const show = true;
44
+ const kind = 'a';
45
+ <div class="if-switch">
46
+ @if (show) {
47
+ @switch (kind) {
48
+ @case 'a': {
49
+ <p class="case-a">Case A</p>
50
+ }
51
+ @default: {
52
+ <p class="case-default">{'Default'}</p>
57
53
  }
58
54
  }
59
- </div>
60
- </>;
55
+ }
56
+ </div>
61
57
  }
62
58
 
63
59
  // ── if + switch where if is false ─────────────────────────────────────────────
64
- export function IfSwitchHidden() {
65
- return <>
66
- const show = false;
67
- const kind = 'a';
68
- <div class="if-switch-hidden">
69
- if (show) {
70
- switch (kind) {
71
- case 'a':
72
- <p class="case-a">{'Case A'}</p>
73
- break;
74
- default:
75
- <p class="case-default">{'Default'}</p>
60
+ export function IfSwitchHidden() @{
61
+ const show = false;
62
+ const kind = 'a';
63
+ <div class="if-switch-hidden">
64
+ @if (show) {
65
+ @switch (kind) {
66
+ @case 'a': {
67
+ <p class="case-a">Case A</p>
68
+ }
69
+ @default: {
70
+ <p class="case-default">{'Default'}</p>
76
71
  }
77
72
  }
78
- <p class="after">{'after'}</p>
79
- </div>
80
- </>;
73
+ }
74
+ <p class="after">{'after'}</p>
75
+ </div>
81
76
  }
82
77
 
83
78
  // ── for + if + switch, single item (no inter-item cursor advance needed) ───────
84
- export function ForIfSwitchSingle() {
85
- return <>
86
- const items = [
87
- { id: 1, kind: 'a', show: true },
88
- ];
89
- <ul class="for-if-switch-single">
90
- for (const item of items; key item.id) {
91
- if (item.show) {
92
- switch (item.kind) {
93
- case 'a':
94
- <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
95
- break;
96
- default:
97
- <li class={`item item-${item.id} kind-default`}>{`D-${item.id}`}</li>
79
+ export function ForIfSwitchSingle() @{
80
+ const items = [
81
+ { id: 1, kind: 'a', show: true },
82
+ ];
83
+ <ul class="for-if-switch-single">
84
+ @for (const item of items; key item.id) {
85
+ @if (item.show) {
86
+ @switch (item.kind) {
87
+ @case 'a': {
88
+ <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
89
+ }
90
+ @default: {
91
+ <li class={`item item-${item.id} kind-default`}>{`D-${item.id}`}</li>
98
92
  }
99
93
  }
100
94
  }
101
- </ul>
102
- </>;
95
+ }
96
+ </ul>
103
97
  }
104
98
 
105
99
  // ── for + if + switch, two items shown (the cursor-advance regression) ─────────
106
- export function ForIfSwitchMulti() {
107
- return <>
108
- const items = [
109
- { id: 1, kind: 'a', show: true },
110
- { id: 2, kind: 'b', show: true },
111
- ];
112
- <ul class="for-if-switch-multi">
113
- for (const item of items; key item.id) {
114
- if (item.show) {
115
- switch (item.kind) {
116
- case 'a':
117
- <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
118
- break;
119
- default:
120
- <li class={`item item-${item.id} kind-b`}>{`B-${item.id}`}</li>
100
+ export function ForIfSwitchMulti() @{
101
+ const items = [
102
+ { id: 1, kind: 'a', show: true },
103
+ { id: 2, kind: 'b', show: true },
104
+ ];
105
+ <ul class="for-if-switch-multi">
106
+ @for (const item of items; key item.id) {
107
+ @if (item.show) {
108
+ @switch (item.kind) {
109
+ @case 'a': {
110
+ <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
111
+ }
112
+ @default: {
113
+ <li class={`item item-${item.id} kind-b`}>{`B-${item.id}`}</li>
121
114
  }
122
115
  }
123
116
  }
124
- </ul>
125
- </>;
117
+ }
118
+ </ul>
126
119
  }
127
120
 
128
121
  // ── for + if + switch, last item hidden (if=false path between items) ──────────
129
- export function ForIfSwitchWithDisabled() {
130
- return <>
131
- const items = [
132
- { id: 1, kind: 'a', show: true },
133
- { id: 2, kind: 'b', show: false },
134
- { id: 3, kind: 'a', show: true },
135
- ];
136
- <ul class="for-if-switch-disabled">
137
- for (const item of items; key item.id) {
138
- if (item.show) {
139
- switch (item.kind) {
140
- case 'a':
141
- <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
142
- break;
143
- default:
144
- <li class={`item item-${item.id} kind-b`}>{`B-${item.id}`}</li>
122
+ export function ForIfSwitchWithDisabled() @{
123
+ const items = [
124
+ { id: 1, kind: 'a', show: true },
125
+ { id: 2, kind: 'b', show: false },
126
+ { id: 3, kind: 'a', show: true },
127
+ ];
128
+ <ul class="for-if-switch-disabled">
129
+ @for (const item of items; key item.id) {
130
+ @if (item.show) {
131
+ @switch (item.kind) {
132
+ @case 'a': {
133
+ <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
134
+ }
135
+ @default: {
136
+ <li class={`item item-${item.id} kind-b`}>{`B-${item.id}`}</li>
145
137
  }
146
138
  }
147
139
  }
148
- </ul>
149
- </>;
140
+ }
141
+ </ul>
150
142
  }
151
143
 
152
144
  // ── switch + try (no for/if) ──────────────────────────────────────────────────
153
- export function SwitchTry() {
154
- return <>
155
- const kind = 'a';
156
- <div class="switch-try">
157
- switch (kind) {
158
- case 'a':
159
- try {
160
- <p class="resolved-a">{'A resolved'}</p>
161
- } pending {
162
- <p class="pending-a">{'A pending'}</p>
163
- }
164
- break;
165
- default:
166
- <p class="default">{'Default'}</p>
145
+ export function SwitchTry() @{
146
+ const kind = 'a';
147
+ <div class="switch-try">
148
+ @switch (kind) {
149
+ @case 'a': {
150
+ @try {
151
+ <p class="resolved-a">{'A resolved'}</p>
152
+ } @pending {
153
+ <p class="pending-a">{'A pending'}</p>
154
+ }
155
+ }
156
+ @default: {
157
+ <p class="default">{'Default'}</p>
167
158
  }
168
- </div>
169
- </>;
159
+ }
160
+ </div>
170
161
  }
171
162
 
172
163
  // ── for + switch + try (no if) ────────────────────────────────────────────────
173
- export function ForSwitchTry() {
174
- return <>
175
- const items = [
176
- { id: 1, kind: 'a' },
177
- { id: 2, kind: 'b' },
178
- ];
179
- <ul class="for-switch-try">
180
- for (const item of items; key item.id) {
181
- switch (item.kind) {
182
- case 'a':
183
- try {
184
- <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
185
- } pending {
186
- <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
187
- }
188
- break;
189
- default:
190
- try {
191
- <li class={`item item-${item.id} kind-b`}>{`B-${item.id}`}</li>
192
- } pending {
193
- <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
194
- }
164
+ export function ForSwitchTry() @{
165
+ const items = [
166
+ { id: 1, kind: 'a' },
167
+ { id: 2, kind: 'b' },
168
+ ];
169
+ <ul class="for-switch-try">
170
+ @for (const item of items; key item.id) {
171
+ @switch (item.kind) {
172
+ @case 'a': {
173
+ @try {
174
+ <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
175
+ } @pending {
176
+ <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
177
+ }
178
+ }
179
+ @default: {
180
+ @try {
181
+ <li class={`item item-${item.id} kind-b`}>{`B-${item.id}`}</li>
182
+ } @pending {
183
+ <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
184
+ }
195
185
  }
196
186
  }
197
- </ul>
198
- </>;
187
+ }
188
+ </ul>
199
189
  }
200
190
 
201
191
  // ── for + if + try (no switch) ────────────────────────────────────────────────
202
- export function ForIfTry() {
203
- return <>
204
- const items = [
205
- { id: 1, show: true },
206
- { id: 2, show: true },
207
- ];
208
- <ul class="for-if-try">
209
- for (const item of items; key item.id) {
210
- if (item.show) {
211
- try {
212
- <li class={`item item-${item.id}`}>{`item-${item.id}`}</li>
213
- } pending {
214
- <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
215
- }
192
+ export function ForIfTry() @{
193
+ const items = [
194
+ { id: 1, show: true },
195
+ { id: 2, show: true },
196
+ ];
197
+ <ul class="for-if-try">
198
+ @for (const item of items; key item.id) {
199
+ @if (item.show) {
200
+ @try {
201
+ <li class={`item item-${item.id}`}>{`item-${item.id}`}</li>
202
+ } @pending {
203
+ <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
216
204
  }
217
205
  }
218
- </ul>
219
- </>;
206
+ }
207
+ </ul>
220
208
  }
221
209
 
222
210
  // ── for + if + switch + try, single item ─────────────────────────────────────
223
- export function ForIfSwitchTrySingle() {
224
- return <>
225
- const items = [
226
- { id: 1, kind: 'a', show: true },
227
- ];
228
- <ul class="for-if-switch-try-single">
229
- for (const item of items; key item.id) {
230
- if (item.show) {
231
- switch (item.kind) {
232
- case 'a':
233
- try {
234
- <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
235
- } pending {
236
- <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
237
- }
238
- break;
239
- default:
240
- try {
241
- <li class={`item item-${item.id} kind-default`}>{`D-${item.id}`}</li>
242
- } pending {
243
- <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
244
- }
211
+ export function ForIfSwitchTrySingle() @{
212
+ const items = [
213
+ { id: 1, kind: 'a', show: true },
214
+ ];
215
+ <ul class="for-if-switch-try-single">
216
+ @for (const item of items; key item.id) {
217
+ @if (item.show) {
218
+ @switch (item.kind) {
219
+ @case 'a': {
220
+ @try {
221
+ <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
222
+ } @pending {
223
+ <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
224
+ }
225
+ }
226
+ @default: {
227
+ @try {
228
+ <li class={`item item-${item.id} kind-default`}>{`D-${item.id}`}</li>
229
+ } @pending {
230
+ <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
231
+ }
245
232
  }
246
233
  }
247
234
  }
248
- </ul>
249
- </>;
235
+ }
236
+ </ul>
250
237
  }
251
238
 
252
239
  // ── for + if + switch + try, multiple items (matches MixedControlFlowStatic) ──
253
- export function ForIfSwitchTryMulti() {
254
- return <>
255
- const items = [
256
- { id: 1, kind: 'a', show: true },
257
- { id: 2, kind: 'b', show: true },
258
- ];
259
- <ul class="for-if-switch-try-multi">
260
- for (const item of items; key item.id) {
261
- if (item.show) {
262
- switch (item.kind) {
263
- case 'a':
264
- try {
265
- <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
266
- } pending {
267
- <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
268
- }
269
- break;
270
- default:
271
- try {
272
- <li class={`item item-${item.id} kind-b`}>{`B-${item.id}`}</li>
273
- } pending {
274
- <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
275
- }
240
+ export function ForIfSwitchTryMulti() @{
241
+ const items = [
242
+ { id: 1, kind: 'a', show: true },
243
+ { id: 2, kind: 'b', show: true },
244
+ ];
245
+ <ul class="for-if-switch-try-multi">
246
+ @for (const item of items; key item.id) {
247
+ @if (item.show) {
248
+ @switch (item.kind) {
249
+ @case 'a': {
250
+ @try {
251
+ <li class={`item item-${item.id} kind-a`}>{`A-${item.id}`}</li>
252
+ } @pending {
253
+ <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
254
+ }
255
+ }
256
+ @default: {
257
+ @try {
258
+ <li class={`item item-${item.id} kind-b`}>{`B-${item.id}`}</li>
259
+ } @pending {
260
+ <li class={`pending pending-${item.id}`}>{`pending ${item.id}`}</li>
261
+ }
276
262
  }
277
263
  }
278
264
  }
279
- </ul>
280
- </>;
265
+ }
266
+ </ul>
281
267
  }
@@ -2,55 +2,47 @@
2
2
  import { Portal, track } from 'ripple';
3
3
 
4
4
  // Simple portal with static content
5
- export function SimplePortal() {
6
- return <>
7
- <div class="container">
8
- <h1>{'Main Content'}</h1>
9
- <Portal target={typeof document !== 'undefined' ? document.body : null}>
10
- <div class="portal-content">{'Portal content'}</div>
11
- </Portal>
12
- </div>
13
- </>;
5
+ export function SimplePortal() @{
6
+ <div class="container">
7
+ <h1>{'Main Content'}</h1>
8
+ <Portal target={typeof document !== 'undefined' ? document.body : null}>
9
+ <div class="portal-content">{'Portal content'}</div>
10
+ </Portal>
11
+ </div>
14
12
  }
15
13
 
16
14
  // Portal with conditional rendering
17
- export function ConditionalPortal() {
18
- return <>
19
- let &[show] = track(true);
20
- <div class="container">
21
- <button class="toggle" onClick={() => (show = !show)}>{'Toggle'}</button>
22
- if (show) {
23
- <Portal target={typeof document !== 'undefined' ? document.body : null}>
24
- <div class="portal-content">{'Portal is visible'}</div>
25
- </Portal>
26
- }
27
- </div>
28
- </>;
15
+ export function ConditionalPortal() @{
16
+ let &[show] = track(true);
17
+ <div class="container">
18
+ <button class="toggle" onClick={() => (show = !show)}>{'Toggle'}</button>
19
+ @if (show) {
20
+ <Portal target={typeof document !== 'undefined' ? document.body : null}>
21
+ <div class="portal-content">{'Portal is visible'}</div>
22
+ </Portal>
23
+ }
24
+ </div>
29
25
  }
30
26
 
31
27
  // Component with portal that shouldn't break on initial load
32
- export function PortalWithMainContent() {
33
- return <>
34
- <div>
35
- <div class="main-content">{'Main page content'}</div>
36
- <Portal target={typeof document !== 'undefined' ? document.body : null}>
37
- <div class="portal-content">{'Modal content'}</div>
38
- </Portal>
39
- <div class="footer">{'Footer'}</div>
40
- </div>
41
- </>;
28
+ export function PortalWithMainContent() @{
29
+ <div>
30
+ <div class="main-content">{'Main page content'}</div>
31
+ <Portal target={typeof document !== 'undefined' ? document.body : null}>
32
+ <div class="portal-content">{'Modal content'}</div>
33
+ </Portal>
34
+ <div class="footer">{'Footer'}</div>
35
+ </div>
42
36
  }
43
37
 
44
38
  // Nested portals scenario
45
- export function NestedContentWithPortal() {
46
- return <>
47
- <div class="outer">
48
- <div class="inner">
49
- <span>{'Nested content'}</span>
50
- </div>
51
- <Portal target={typeof document !== 'undefined' ? document.body : null}>
52
- <div class="portal-content">{'Portal content'}</div>
53
- </Portal>
39
+ export function NestedContentWithPortal() @{
40
+ <div class="outer">
41
+ <div class="inner">
42
+ <span>{'Nested content'}</span>
54
43
  </div>
55
- </>;
44
+ <Portal target={typeof document !== 'undefined' ? document.body : null}>
45
+ <div class="portal-content">{'Portal content'}</div>
46
+ </Portal>
47
+ </div>
56
48
  }
@@ -2,51 +2,43 @@ import { track } from 'ripple';
2
2
 
3
3
  // Reactive components for hydration testing
4
4
 
5
- export function TrackedState() {
6
- return <>
7
- let &[count] = track(0);
8
- <div class="count">{count}</div>
9
- </>;
5
+ export function TrackedState() @{
6
+ let &[count] = track(0);
7
+ <div class="count">{count}</div>
10
8
  }
11
9
 
12
- export function CounterWithInitial(props: { initial: number }) {
13
- return <>
14
- let &[count] = track(props.initial);
15
- <div>
16
- <span class="count">{count}</span>
17
- </div>
18
- </>;
10
+ export function CounterWithInitial(props: { initial: number }) @{
11
+ let &[count] = track(props.initial);
12
+ <div>
13
+ <span class="count">{count}</span>
14
+ </div>
19
15
  }
20
16
 
21
- export function CounterWrapper() {
22
- return <><CounterWithInitial initial={5} /></>;
17
+ export function CounterWrapper() @{
18
+ <CounterWithInitial initial={5} />
23
19
  }
24
20
 
25
- export function ComputedValues() {
26
- return <>
27
- let &[a] = track(2);
28
- let &[b] = track(3);
29
- const sum = () => a + b;
30
- <div class="sum">{sum()}</div>
31
- </>;
21
+ export function ComputedValues() @{
22
+ let &[a] = track(2);
23
+ let &[b] = track(3);
24
+ const sum = () => a + b;
25
+ <div class="sum">{sum()}</div>
32
26
  }
33
27
 
34
- export function MultipleTracked() {
35
- return <>
36
- let &[x] = track(10);
37
- let &[y] = track(20);
38
- let &[z] = track(30);
28
+ export function MultipleTracked() @{
29
+ let &[x] = track(10);
30
+ let &[y] = track(20);
31
+ let &[z] = track(30);
32
+ <div class="multiple-tracked">
39
33
  <div class="x">{x}</div>
40
34
  <div class="y">{y}</div>
41
35
  <div class="z">{z}</div>
42
- </>;
36
+ </div>
43
37
  }
44
38
 
45
- export function DerivedState() {
46
- return <>
47
- let &[firstName] = track('John');
48
- let &[lastName] = track('Doe');
49
- const fullName = () => `${firstName} ${lastName}`;
50
- <div class="name">{fullName()}</div>
51
- </>;
39
+ export function DerivedState() @{
40
+ let &[firstName] = track('John');
41
+ let &[lastName] = track('Doe');
42
+ const fullName = () => `${firstName} ${lastName}`;
43
+ <div class="name">{fullName()}</div>
52
44
  }