ripple 0.3.2 → 0.3.4
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.
- package/CHANGELOG.md +85 -0
- package/package.json +2 -2
- package/src/compiler/identifier-utils.js +0 -2
- package/src/compiler/phases/1-parse/index.js +101 -195
- package/src/compiler/phases/2-analyze/index.js +82 -174
- package/src/compiler/phases/2-analyze/prune.js +2 -2
- package/src/compiler/phases/3-transform/client/index.js +174 -264
- package/src/compiler/phases/3-transform/segments.js +0 -22
- package/src/compiler/phases/3-transform/server/index.js +185 -42
- package/src/compiler/types/index.d.ts +14 -33
- package/src/compiler/utils.js +32 -20
- package/src/runtime/index-client.js +0 -17
- package/src/runtime/internal/client/bindings.js +118 -7
- package/src/runtime/internal/client/render.js +5 -1
- package/src/runtime/internal/client/runtime.js +1 -1
- package/src/runtime/internal/client/types.d.ts +4 -0
- package/tests/client/array/array.copy-within.test.ripple +7 -7
- package/tests/client/array/array.derived.test.ripple +24 -24
- package/tests/client/array/array.iteration.test.ripple +7 -7
- package/tests/client/array/array.mutations.test.ripple +17 -17
- package/tests/client/array/array.to-methods.test.ripple +4 -4
- package/tests/client/async-suspend.test.ripple +3 -3
- package/tests/client/basic/basic.attributes.test.ripple +31 -31
- package/tests/client/basic/basic.collections.test.ripple +6 -6
- package/tests/client/basic/basic.components.test.ripple +8 -8
- package/tests/client/basic/basic.errors.test.ripple +31 -34
- package/tests/client/basic/basic.events.test.ripple +11 -11
- package/tests/client/basic/basic.get-set.test.ripple +18 -18
- package/tests/client/basic/basic.reactivity.test.ripple +36 -36
- package/tests/client/basic/basic.rendering.test.ripple +7 -7
- package/tests/client/basic/basic.utilities.test.ripple +4 -4
- package/tests/client/boundaries.test.ripple +7 -7
- package/tests/client/compiler/__snapshots__/compiler.typescript.test.ripple.snap +24 -0
- package/tests/client/compiler/compiler.assignments.test.ripple +12 -10
- package/tests/client/compiler/compiler.basic.test.ripple +58 -60
- package/tests/client/compiler/compiler.tracked-access.test.ripple +14 -8
- package/tests/client/compiler/compiler.typescript.test.ripple +31 -0
- package/tests/client/composite/composite.dynamic-components.test.ripple +6 -6
- package/tests/client/composite/composite.props.test.ripple +9 -9
- package/tests/client/composite/composite.reactivity.test.ripple +23 -23
- package/tests/client/composite/composite.render.test.ripple +52 -4
- package/tests/client/computed-properties.test.ripple +3 -3
- package/tests/client/context.test.ripple +3 -3
- package/tests/client/css/global-additional-cases.test.ripple +5 -2
- package/tests/client/css/style-identifier.test.ripple +40 -49
- package/tests/client/date.test.ripple +39 -39
- package/tests/client/dynamic-elements.test.ripple +37 -37
- package/tests/client/events.test.ripple +25 -25
- package/tests/client/for.test.ripple +8 -8
- package/tests/client/head.test.ripple +7 -7
- package/tests/client/html.test.ripple +2 -2
- package/tests/client/input-value.test.ripple +376 -177
- package/tests/client/lazy-destructuring.test.ripple +185 -0
- package/tests/client/map.test.ripple +20 -20
- package/tests/client/media-query.test.ripple +4 -4
- package/tests/client/object.test.ripple +5 -5
- package/tests/client/portal.test.ripple +4 -4
- package/tests/client/ref.test.ripple +3 -3
- package/tests/client/return.test.ripple +17 -17
- package/tests/client/set.test.ripple +10 -10
- package/tests/client/svg.test.ripple +6 -5
- package/tests/client/switch.test.ripple +10 -10
- package/tests/client/tracked-expression.test.ripple +3 -1
- package/tests/client/try.test.ripple +4 -4
- package/tests/client/url/url.derived.test.ripple +6 -7
- package/tests/client/url/url.parsing.test.ripple +9 -9
- package/tests/client/url/url.partial-removal.test.ripple +9 -9
- package/tests/client/url/url.reactivity.test.ripple +16 -16
- package/tests/client/url/url.serialization.test.ripple +3 -3
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +7 -8
- package/tests/client/url-search-params/url-search-params.initialization.test.ripple +6 -4
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +12 -12
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +18 -18
- package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +16 -16
- package/tests/client/url-search-params/url-search-params.serialization.test.ripple +4 -4
- package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +3 -3
- package/tests/hydration/build-components.js +4 -10
- package/tests/hydration/compiled/client/basic.js +4 -4
- package/tests/hydration/compiled/client/events.js +2 -0
- package/tests/hydration/compiled/client/for.js +2 -0
- package/tests/hydration/compiled/client/head.js +13 -11
- package/tests/hydration/compiled/client/hmr.js +4 -2
- package/tests/hydration/compiled/client/html.js +82 -95
- package/tests/hydration/compiled/client/if-children.js +8 -9
- package/tests/hydration/compiled/client/if.js +2 -0
- package/tests/hydration/compiled/client/mixed-control-flow.js +4 -2
- package/tests/hydration/compiled/client/portal.js +1 -1
- package/tests/hydration/compiled/client/reactivity.js +2 -0
- package/tests/hydration/compiled/client/return.js +2 -0
- package/tests/hydration/compiled/client/switch.js +2 -0
- package/tests/hydration/compiled/server/composite.js +2 -2
- package/tests/hydration/compiled/server/events.js +2 -0
- package/tests/hydration/compiled/server/for.js +2 -0
- package/tests/hydration/compiled/server/head.js +13 -11
- package/tests/hydration/compiled/server/hmr.js +2 -0
- package/tests/hydration/compiled/server/html.js +2 -0
- package/tests/hydration/compiled/server/if-children.js +2 -0
- package/tests/hydration/compiled/server/if.js +2 -0
- package/tests/hydration/compiled/server/mixed-control-flow.js +2 -0
- package/tests/hydration/compiled/server/portal.js +1 -1
- package/tests/hydration/compiled/server/reactivity.js +2 -0
- package/tests/hydration/compiled/server/return.js +2 -0
- package/tests/hydration/compiled/server/switch.js +2 -0
- package/tests/hydration/components/composite.ripple +1 -1
- package/tests/hydration/components/events.ripple +10 -8
- package/tests/hydration/components/for.ripple +22 -20
- package/tests/hydration/components/head.ripple +8 -6
- package/tests/hydration/components/hmr.ripple +3 -1
- package/tests/hydration/components/html.ripple +3 -1
- package/tests/hydration/components/if-children.ripple +9 -7
- package/tests/hydration/components/if.ripple +7 -5
- package/tests/hydration/components/mixed-control-flow.ripple +5 -3
- package/tests/hydration/components/portal.ripple +2 -2
- package/tests/hydration/components/reactivity.ripple +11 -9
- package/tests/hydration/components/return.ripple +13 -11
- package/tests/hydration/components/switch.ripple +6 -4
- package/tests/server/__snapshots__/compiler.test.ripple.snap +22 -0
- package/tests/server/await.test.ripple +2 -2
- package/tests/server/basic.attributes.test.ripple +21 -19
- package/tests/server/basic.components.test.ripple +5 -4
- package/tests/server/basic.test.ripple +21 -20
- package/tests/server/compiler.test.ripple +36 -5
- package/tests/server/composite.props.test.ripple +7 -6
- package/tests/server/context.test.ripple +3 -1
- package/tests/server/dynamic-elements.test.ripple +24 -24
- package/tests/server/head.test.ripple +7 -5
- package/tests/server/style-identifier.test.ripple +95 -16
- package/types/index.d.ts +4 -1
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
import * as _$_ from 'ripple/internal/server';
|
|
3
3
|
|
|
4
|
-
export async function Layout(__output,
|
|
4
|
+
export async function Layout(__output, __props) {
|
|
5
5
|
return _$_.async(async () => {
|
|
6
6
|
_$_.push_component();
|
|
7
7
|
__output.push('<div');
|
|
@@ -10,7 +10,7 @@ export async function Layout(__output, { children }) {
|
|
|
10
10
|
|
|
11
11
|
{
|
|
12
12
|
{
|
|
13
|
-
const comp = children;
|
|
13
|
+
const comp = __props.children;
|
|
14
14
|
const args = [__output, {}];
|
|
15
15
|
|
|
16
16
|
if (comp?.async) {
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
// @ts-nocheck
|
|
2
2
|
import * as _$_ from 'ripple/internal/server';
|
|
3
3
|
|
|
4
|
+
import { track } from 'ripple/server';
|
|
5
|
+
|
|
4
6
|
export function StaticTitle(__output) {
|
|
5
7
|
_$_.push_component();
|
|
6
8
|
__output.push('<div');
|
|
@@ -12,7 +14,7 @@ export function StaticTitle(__output) {
|
|
|
12
14
|
|
|
13
15
|
__output.push('</div>');
|
|
14
16
|
__output.target = 'head';
|
|
15
|
-
__output.push('<!--
|
|
17
|
+
__output.push('<!--qwqurq-->');
|
|
16
18
|
__output.push('<title');
|
|
17
19
|
__output.push('>');
|
|
18
20
|
|
|
@@ -46,7 +48,7 @@ export function ReactiveTitle(__output) {
|
|
|
46
48
|
|
|
47
49
|
__output.push('</div>');
|
|
48
50
|
__output.target = 'head';
|
|
49
|
-
__output.push('<!--
|
|
51
|
+
__output.push('<!--1h8nm28-->');
|
|
50
52
|
__output.push('<title');
|
|
51
53
|
__output.push('>');
|
|
52
54
|
|
|
@@ -70,7 +72,7 @@ export function MultipleHeadElements(__output) {
|
|
|
70
72
|
|
|
71
73
|
__output.push('</div>');
|
|
72
74
|
__output.target = 'head';
|
|
73
|
-
__output.push('<!--
|
|
75
|
+
__output.push('<!--9v67ol-->');
|
|
74
76
|
__output.push('<title');
|
|
75
77
|
__output.push('>');
|
|
76
78
|
|
|
@@ -105,7 +107,7 @@ export function ReactiveMetaTags(__output) {
|
|
|
105
107
|
|
|
106
108
|
__output.push('</div>');
|
|
107
109
|
__output.target = 'head';
|
|
108
|
-
__output.push('<!--
|
|
110
|
+
__output.push('<!--166unm-->');
|
|
109
111
|
__output.push('<title');
|
|
110
112
|
__output.push('>');
|
|
111
113
|
|
|
@@ -136,7 +138,7 @@ export function TitleWithTemplate(__output) {
|
|
|
136
138
|
|
|
137
139
|
__output.push('</div>');
|
|
138
140
|
__output.target = 'head';
|
|
139
|
-
__output.push('<!--
|
|
141
|
+
__output.push('<!--3o3mh2-->');
|
|
140
142
|
__output.push('<title');
|
|
141
143
|
__output.push('>');
|
|
142
144
|
|
|
@@ -160,7 +162,7 @@ export function EmptyTitle(__output) {
|
|
|
160
162
|
|
|
161
163
|
__output.push('</div>');
|
|
162
164
|
__output.target = 'head';
|
|
163
|
-
__output.push('<!--
|
|
165
|
+
__output.push('<!--kwo3k6-->');
|
|
164
166
|
__output.push('<title');
|
|
165
167
|
__output.push('>');
|
|
166
168
|
|
|
@@ -188,7 +190,7 @@ export function ConditionalTitle(__output) {
|
|
|
188
190
|
|
|
189
191
|
__output.push('</div>');
|
|
190
192
|
__output.target = 'head';
|
|
191
|
-
__output.push('<!--
|
|
193
|
+
__output.push('<!--c2i5xr-->');
|
|
192
194
|
__output.push('<title');
|
|
193
195
|
__output.push('>');
|
|
194
196
|
|
|
@@ -223,7 +225,7 @@ export function ComputedTitle(__output) {
|
|
|
223
225
|
|
|
224
226
|
__output.push('</div>');
|
|
225
227
|
__output.target = 'head';
|
|
226
|
-
__output.push('<!--
|
|
228
|
+
__output.push('<!--1h2z3z5-->');
|
|
227
229
|
__output.push('<title');
|
|
228
230
|
__output.push('>');
|
|
229
231
|
|
|
@@ -247,7 +249,7 @@ export function MultipleHeadBlocks(__output) {
|
|
|
247
249
|
|
|
248
250
|
__output.push('</div>');
|
|
249
251
|
__output.target = 'head';
|
|
250
|
-
__output.push('<!--
|
|
252
|
+
__output.push('<!--14rv3le-->');
|
|
251
253
|
__output.push('<title');
|
|
252
254
|
__output.push('>');
|
|
253
255
|
|
|
@@ -256,7 +258,7 @@ export function MultipleHeadBlocks(__output) {
|
|
|
256
258
|
}
|
|
257
259
|
|
|
258
260
|
__output.push('</title>');
|
|
259
|
-
__output.push('<!--
|
|
261
|
+
__output.push('<!--1eh1mn5-->');
|
|
260
262
|
__output.push('<meta');
|
|
261
263
|
__output.push(' name="author"');
|
|
262
264
|
__output.push(' content="Test Author"');
|
|
@@ -276,7 +278,7 @@ export function HeadWithStyle(__output) {
|
|
|
276
278
|
|
|
277
279
|
__output.push('</div>');
|
|
278
280
|
__output.target = 'head';
|
|
279
|
-
__output.push('<!--
|
|
281
|
+
__output.push('<!--1dxk6yg-->');
|
|
280
282
|
__output.push('<title');
|
|
281
283
|
__output.push('>');
|
|
282
284
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
+
import { track } from 'ripple';
|
|
2
|
+
|
|
1
3
|
// Event handling components for hydration testing
|
|
2
4
|
|
|
3
5
|
export component ClickCounter() {
|
|
4
|
-
let count =
|
|
6
|
+
let count = track(0);
|
|
5
7
|
<div>
|
|
6
8
|
<button
|
|
7
9
|
class="increment"
|
|
@@ -16,7 +18,7 @@ export component ClickCounter() {
|
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
export component IncrementDecrement() {
|
|
19
|
-
let count =
|
|
21
|
+
let count = track(0);
|
|
20
22
|
<div>
|
|
21
23
|
<button
|
|
22
24
|
class="decrement"
|
|
@@ -39,8 +41,8 @@ export component IncrementDecrement() {
|
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
export component MultipleEvents() {
|
|
42
|
-
let clicks =
|
|
43
|
-
let hovers =
|
|
44
|
+
let clicks = track(0);
|
|
45
|
+
let hovers = track(0);
|
|
44
46
|
<div>
|
|
45
47
|
<button
|
|
46
48
|
class="target"
|
|
@@ -59,8 +61,8 @@ export component MultipleEvents() {
|
|
|
59
61
|
}
|
|
60
62
|
|
|
61
63
|
export component MultiStateUpdate() {
|
|
62
|
-
let count =
|
|
63
|
-
let lastAction =
|
|
64
|
+
let count = track(0);
|
|
65
|
+
let lastAction = track('none');
|
|
64
66
|
|
|
65
67
|
const handleClick = () => {
|
|
66
68
|
@count++;
|
|
@@ -75,7 +77,7 @@ export component MultiStateUpdate() {
|
|
|
75
77
|
}
|
|
76
78
|
|
|
77
79
|
export component ToggleButton() {
|
|
78
|
-
let isOn =
|
|
80
|
+
let isOn = track(false);
|
|
79
81
|
<div>
|
|
80
82
|
<button
|
|
81
83
|
class="toggle"
|
|
@@ -93,7 +95,7 @@ export component ChildButton(props: { onClick: () => void; label: string }) {
|
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
export component ParentWithChildButton() {
|
|
96
|
-
let count =
|
|
98
|
+
let count = track(0);
|
|
97
99
|
<div>
|
|
98
100
|
<ChildButton
|
|
99
101
|
onClick={() => {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { track } from 'ripple';
|
|
2
|
+
|
|
1
3
|
// For loop components for hydration testing
|
|
2
4
|
|
|
3
5
|
export component StaticForLoop() {
|
|
@@ -32,7 +34,7 @@ export component KeyedForLoop() {
|
|
|
32
34
|
}
|
|
33
35
|
|
|
34
36
|
export component ReactiveForLoopAdd() {
|
|
35
|
-
let items =
|
|
37
|
+
let items = track(['A', 'B']);
|
|
36
38
|
<button
|
|
37
39
|
class="add"
|
|
38
40
|
onClick={() => {
|
|
@@ -49,7 +51,7 @@ export component ReactiveForLoopAdd() {
|
|
|
49
51
|
}
|
|
50
52
|
|
|
51
53
|
export component ReactiveForLoopRemove() {
|
|
52
|
-
let items =
|
|
54
|
+
let items = track(['A', 'B', 'C']);
|
|
53
55
|
<button
|
|
54
56
|
class="remove"
|
|
55
57
|
onClick={() => {
|
|
@@ -66,7 +68,7 @@ export component ReactiveForLoopRemove() {
|
|
|
66
68
|
}
|
|
67
69
|
|
|
68
70
|
export component ForLoopInteractive() {
|
|
69
|
-
let counts =
|
|
71
|
+
let counts = track([0, 0, 0]);
|
|
70
72
|
<div>
|
|
71
73
|
for (const count of @counts; index i) {
|
|
72
74
|
<div class={`item-${i}`}>
|
|
@@ -128,7 +130,7 @@ export component ForLoopComplexObjects() {
|
|
|
128
130
|
|
|
129
131
|
// Test reordering items in a keyed for loop
|
|
130
132
|
export component KeyedForLoopReorder() {
|
|
131
|
-
let items =
|
|
133
|
+
let items = track([
|
|
132
134
|
{ id: 1, name: 'First' },
|
|
133
135
|
{ id: 2, name: 'Second' },
|
|
134
136
|
{ id: 3, name: 'Third' },
|
|
@@ -150,7 +152,7 @@ export component KeyedForLoopReorder() {
|
|
|
150
152
|
|
|
151
153
|
// Test for loop with item property updates (keyed)
|
|
152
154
|
export component KeyedForLoopUpdate() {
|
|
153
|
-
let items =
|
|
155
|
+
let items = track([
|
|
154
156
|
{ id: 1, name: 'Item 1' },
|
|
155
157
|
{ id: 2, name: 'Item 2' },
|
|
156
158
|
]);
|
|
@@ -171,7 +173,7 @@ export component KeyedForLoopUpdate() {
|
|
|
171
173
|
|
|
172
174
|
// Test for loop with combined add/remove/reorder
|
|
173
175
|
export component ForLoopMixedOperations() {
|
|
174
|
-
let items =
|
|
176
|
+
let items = track(['A', 'B', 'C', 'D']);
|
|
175
177
|
<button
|
|
176
178
|
class="shuffle"
|
|
177
179
|
onClick={() => {
|
|
@@ -190,8 +192,8 @@ export component ForLoopMixedOperations() {
|
|
|
190
192
|
|
|
191
193
|
// Test for loop inside if block (combined control flow)
|
|
192
194
|
export component ForLoopInsideIf() {
|
|
193
|
-
let showList =
|
|
194
|
-
let items =
|
|
195
|
+
let showList = track(true);
|
|
196
|
+
let items = track(['X', 'Y', 'Z']);
|
|
195
197
|
<button
|
|
196
198
|
class="toggle"
|
|
197
199
|
onClick={() => {
|
|
@@ -219,7 +221,7 @@ export component ForLoopInsideIf() {
|
|
|
219
221
|
|
|
220
222
|
// Test for loop that transitions from empty to populated
|
|
221
223
|
export component ForLoopEmptyToPopulated() {
|
|
222
|
-
let items =
|
|
224
|
+
let items = track<string[]>([]);
|
|
223
225
|
<button
|
|
224
226
|
class="populate"
|
|
225
227
|
onClick={() => {
|
|
@@ -237,7 +239,7 @@ export component ForLoopEmptyToPopulated() {
|
|
|
237
239
|
|
|
238
240
|
// Test for loop that transitions from populated to empty
|
|
239
241
|
export component ForLoopPopulatedToEmpty() {
|
|
240
|
-
let items =
|
|
242
|
+
let items = track(['One', 'Two', 'Three']);
|
|
241
243
|
<button
|
|
242
244
|
class="clear"
|
|
243
245
|
onClick={() => {
|
|
@@ -255,7 +257,7 @@ export component ForLoopPopulatedToEmpty() {
|
|
|
255
257
|
|
|
256
258
|
// Test nested for loops with reactivity
|
|
257
259
|
export component NestedForLoopReactive() {
|
|
258
|
-
let grid =
|
|
260
|
+
let grid = track([
|
|
259
261
|
[1, 2],
|
|
260
262
|
[3, 4],
|
|
261
263
|
]);
|
|
@@ -328,7 +330,7 @@ export component ForLoopDeeplyNested() {
|
|
|
328
330
|
|
|
329
331
|
// Test for loop with index that gets updated
|
|
330
332
|
export component ForLoopIndexUpdate() {
|
|
331
|
-
let items =
|
|
333
|
+
let items = track(['First', 'Second', 'Third']);
|
|
332
334
|
<button
|
|
333
335
|
class="prepend"
|
|
334
336
|
onClick={() => {
|
|
@@ -346,7 +348,7 @@ export component ForLoopIndexUpdate() {
|
|
|
346
348
|
|
|
347
349
|
// Test keyed for loop with index
|
|
348
350
|
export component KeyedForLoopWithIndex() {
|
|
349
|
-
let items =
|
|
351
|
+
let items = track([
|
|
350
352
|
{ id: 'a', value: 'Alpha' },
|
|
351
353
|
{ id: 'b', value: 'Beta' },
|
|
352
354
|
{ id: 'c', value: 'Gamma' },
|
|
@@ -368,7 +370,7 @@ export component KeyedForLoopWithIndex() {
|
|
|
368
370
|
|
|
369
371
|
// Test for loop with sibling elements
|
|
370
372
|
export component ForLoopWithSiblings() {
|
|
371
|
-
let items =
|
|
373
|
+
let items = track(['A', 'B']);
|
|
372
374
|
<div class="wrapper">
|
|
373
375
|
<header class="before">{'Before'}</header>
|
|
374
376
|
for (const item of @items) {
|
|
@@ -401,7 +403,7 @@ export component ForLoopItemState() {
|
|
|
401
403
|
}
|
|
402
404
|
|
|
403
405
|
component TodoItem(props: { id: number; text: string }) {
|
|
404
|
-
let done =
|
|
406
|
+
let done = track(false);
|
|
405
407
|
<div class={`todo-${props.id}`}>
|
|
406
408
|
<input
|
|
407
409
|
type="checkbox"
|
|
@@ -427,7 +429,7 @@ export component ForLoopSingleItem() {
|
|
|
427
429
|
|
|
428
430
|
// Test for loop adding at beginning
|
|
429
431
|
export component ForLoopAddAtBeginning() {
|
|
430
|
-
let items =
|
|
432
|
+
let items = track(['B', 'C']);
|
|
431
433
|
<button
|
|
432
434
|
class="prepend"
|
|
433
435
|
onClick={() => {
|
|
@@ -445,7 +447,7 @@ export component ForLoopAddAtBeginning() {
|
|
|
445
447
|
|
|
446
448
|
// Test for loop adding in the middle
|
|
447
449
|
export component ForLoopAddInMiddle() {
|
|
448
|
-
let items =
|
|
450
|
+
let items = track(['A', 'C']);
|
|
449
451
|
<button
|
|
450
452
|
class="insert"
|
|
451
453
|
onClick={() => {
|
|
@@ -465,7 +467,7 @@ export component ForLoopAddInMiddle() {
|
|
|
465
467
|
|
|
466
468
|
// Test for loop removing from the middle
|
|
467
469
|
export component ForLoopRemoveFromMiddle() {
|
|
468
|
-
let items =
|
|
470
|
+
let items = track(['A', 'B', 'C']);
|
|
469
471
|
<button
|
|
470
472
|
class="remove-middle"
|
|
471
473
|
onClick={() => {
|
|
@@ -493,7 +495,7 @@ export component ForLoopLargeList() {
|
|
|
493
495
|
|
|
494
496
|
// Test for loop with swap operation
|
|
495
497
|
export component ForLoopSwap() {
|
|
496
|
-
let items =
|
|
498
|
+
let items = track(['A', 'B', 'C', 'D']);
|
|
497
499
|
<button
|
|
498
500
|
class="swap"
|
|
499
501
|
onClick={() => {
|
|
@@ -513,7 +515,7 @@ export component ForLoopSwap() {
|
|
|
513
515
|
|
|
514
516
|
// Test for loop with reverse operation
|
|
515
517
|
export component ForLoopReverse() {
|
|
516
|
-
let items =
|
|
518
|
+
let items = track(['A', 'B', 'C', 'D']);
|
|
517
519
|
<button
|
|
518
520
|
class="reverse"
|
|
519
521
|
onClick={() => {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { track } from 'ripple';
|
|
2
|
+
|
|
1
3
|
// Static title
|
|
2
4
|
export component StaticTitle() {
|
|
3
5
|
<head>
|
|
@@ -9,7 +11,7 @@ export component StaticTitle() {
|
|
|
9
11
|
|
|
10
12
|
// Reactive title
|
|
11
13
|
export component ReactiveTitle() {
|
|
12
|
-
let title =
|
|
14
|
+
let title = track('Initial Title');
|
|
13
15
|
|
|
14
16
|
<head>
|
|
15
17
|
<title>{@title}</title>
|
|
@@ -32,7 +34,7 @@ export component MultipleHeadElements() {
|
|
|
32
34
|
|
|
33
35
|
// Head with reactive meta tags
|
|
34
36
|
export component ReactiveMetaTags() {
|
|
35
|
-
let description =
|
|
37
|
+
let description = track('Initial description');
|
|
36
38
|
|
|
37
39
|
<head>
|
|
38
40
|
<title>{'My Page'}</title>
|
|
@@ -44,7 +46,7 @@ export component ReactiveMetaTags() {
|
|
|
44
46
|
|
|
45
47
|
// Title with template literal
|
|
46
48
|
export component TitleWithTemplate() {
|
|
47
|
-
let name =
|
|
49
|
+
let name = track('World');
|
|
48
50
|
|
|
49
51
|
<head>
|
|
50
52
|
<title>{`Hello ${@name}!`}</title>
|
|
@@ -63,8 +65,8 @@ export component EmptyTitle() {
|
|
|
63
65
|
|
|
64
66
|
// Title with conditional content
|
|
65
67
|
export component ConditionalTitle() {
|
|
66
|
-
let showPrefix =
|
|
67
|
-
let title =
|
|
68
|
+
let showPrefix = track(true);
|
|
69
|
+
let title = track('Main Page');
|
|
68
70
|
|
|
69
71
|
<head>
|
|
70
72
|
<title>{@showPrefix ? 'App - ' + @title : @title}</title>
|
|
@@ -75,7 +77,7 @@ export component ConditionalTitle() {
|
|
|
75
77
|
|
|
76
78
|
// Title with computed value
|
|
77
79
|
export component ComputedTitle() {
|
|
78
|
-
let count =
|
|
80
|
+
let count = track(0);
|
|
79
81
|
let prefix = 'Count: ';
|
|
80
82
|
|
|
81
83
|
<head>
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { track } from 'ripple';
|
|
2
|
+
|
|
1
3
|
// Components for testing HMR re-render after hydration.
|
|
2
4
|
// The key scenario: a layout wrapper whose root element contains children
|
|
3
5
|
// that use if/for blocks. After hydration, hydrate_node can be left pointing
|
|
@@ -17,7 +19,7 @@ export component Layout({ children }: { children: any }) {
|
|
|
17
19
|
|
|
18
20
|
// A child component with an if block (the key source of deep hydrate_node)
|
|
19
21
|
export component Content() {
|
|
20
|
-
let visible =
|
|
22
|
+
let visible = track(true);
|
|
21
23
|
|
|
22
24
|
<div class="content">
|
|
23
25
|
if (@visible) {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { track } from 'ripple';
|
|
2
|
+
|
|
1
3
|
export component StaticHtml() {
|
|
2
4
|
const html = '<p><strong>Bold</strong> text</p>';
|
|
3
5
|
<div>{html html}</div>
|
|
@@ -227,7 +229,7 @@ component NavItem({
|
|
|
227
229
|
}
|
|
228
230
|
|
|
229
231
|
component SidebarSection({ title, children }: { title: string; children: any }) {
|
|
230
|
-
let expanded =
|
|
232
|
+
let expanded = track(true);
|
|
231
233
|
<section class="sidebar-section">
|
|
232
234
|
<div class="section-header">
|
|
233
235
|
<h2>{title}</h2>
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { track } from 'ripple';
|
|
2
|
+
|
|
1
3
|
// Minimal repro for hydration issue with if block containing children
|
|
2
4
|
// Based on SidebarGroup pattern from website-new
|
|
3
5
|
|
|
4
6
|
export component IfWithChildren({ children }: { children: any }) {
|
|
5
|
-
let expanded =
|
|
7
|
+
let expanded = track(true);
|
|
6
8
|
|
|
7
9
|
<div class="container">
|
|
8
10
|
<div class="header" role="button" onClick={() => (@expanded = !@expanded)}>{'Toggle'}</div>
|
|
@@ -27,7 +29,7 @@ export component TestIfWithChildren() {
|
|
|
27
29
|
|
|
28
30
|
// Simpler variant - if block with static children
|
|
29
31
|
export component IfWithStaticChildren() {
|
|
30
|
-
let expanded =
|
|
32
|
+
let expanded = track(true);
|
|
31
33
|
|
|
32
34
|
<div class="container">
|
|
33
35
|
<div class="header" role="button" onClick={() => (@expanded = !@expanded)}>{'Toggle'}</div>
|
|
@@ -42,7 +44,7 @@ export component IfWithStaticChildren() {
|
|
|
42
44
|
|
|
43
45
|
// Variant with sibling elements before the if block (like SidebarGroup)
|
|
44
46
|
export component IfWithSiblingsAndChildren({ children }: { children: any }) {
|
|
45
|
-
let expanded =
|
|
47
|
+
let expanded = track(true);
|
|
46
48
|
|
|
47
49
|
<section class="group">
|
|
48
50
|
<div class="item" role="button" onClick={() => (@expanded = !@expanded)}>
|
|
@@ -73,7 +75,7 @@ export component TestIfWithSiblingsAndChildren() {
|
|
|
73
75
|
// This tests that hydrate_node is properly restored after processing an element's children
|
|
74
76
|
// before navigating to a dynamic sibling (if/for/switch)
|
|
75
77
|
export component ElementWithChildrenThenIf() {
|
|
76
|
-
let show =
|
|
78
|
+
let show = track(true);
|
|
77
79
|
|
|
78
80
|
<div class="wrapper">
|
|
79
81
|
<div class="nested-parent">
|
|
@@ -91,7 +93,7 @@ export component ElementWithChildrenThenIf() {
|
|
|
91
93
|
|
|
92
94
|
// More complex: multiple levels of nesting before if sibling
|
|
93
95
|
export component DeepNestingThenIf() {
|
|
94
|
-
let visible =
|
|
96
|
+
let visible = track(true);
|
|
95
97
|
|
|
96
98
|
<section class="outer">
|
|
97
99
|
<article class="middle">
|
|
@@ -114,7 +116,7 @@ export component DeepNestingThenIf() {
|
|
|
114
116
|
// followed by another sibling element. This requires pop() to restore hydrate_node
|
|
115
117
|
// because we descend into the first element to get the button children.
|
|
116
118
|
export component DomElementChildrenThenSibling() {
|
|
117
|
-
let activeTab =
|
|
119
|
+
let activeTab = track('code');
|
|
118
120
|
|
|
119
121
|
<div class="tabs">
|
|
120
122
|
<div class="tab-list">
|
|
@@ -147,7 +149,7 @@ export component DomElementChildrenThenSibling() {
|
|
|
147
149
|
// generate sibling() calls. This was causing incorrect pop() generation before next().
|
|
148
150
|
// Pattern: <ul> with dynamic <li> children -> static <h2> -> static <p> -> next()
|
|
149
151
|
export component DomChildrenThenStaticSiblings() {
|
|
150
|
-
let count =
|
|
152
|
+
let count = track(0);
|
|
151
153
|
|
|
152
154
|
<div class="container">
|
|
153
155
|
<ul class="list">
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { track } from 'ripple';
|
|
2
|
+
|
|
1
3
|
// If block components for hydration testing
|
|
2
4
|
|
|
3
5
|
export component IfTruthy() {
|
|
@@ -24,7 +26,7 @@ export component IfElse() {
|
|
|
24
26
|
}
|
|
25
27
|
|
|
26
28
|
export component ReactiveIf() {
|
|
27
|
-
let show =
|
|
29
|
+
let show = track(true);
|
|
28
30
|
<button
|
|
29
31
|
class="toggle"
|
|
30
32
|
onClick={() => {
|
|
@@ -39,7 +41,7 @@ export component ReactiveIf() {
|
|
|
39
41
|
}
|
|
40
42
|
|
|
41
43
|
export component ReactiveIfElse() {
|
|
42
|
-
let isOn =
|
|
44
|
+
let isOn = track(false);
|
|
43
45
|
<button
|
|
44
46
|
class="toggle"
|
|
45
47
|
onClick={() => {
|
|
@@ -56,8 +58,8 @@ export component ReactiveIfElse() {
|
|
|
56
58
|
}
|
|
57
59
|
|
|
58
60
|
export component NestedIf() {
|
|
59
|
-
let outer =
|
|
60
|
-
let inner =
|
|
61
|
+
let outer = track(true);
|
|
62
|
+
let inner = track(true);
|
|
61
63
|
<button
|
|
62
64
|
class="outer-toggle"
|
|
63
65
|
onClick={() => {
|
|
@@ -85,7 +87,7 @@ export component NestedIf() {
|
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
export component IfElseIfChain() {
|
|
88
|
-
let status =
|
|
90
|
+
let status = track<'loading' | 'success' | 'error'>('loading');
|
|
89
91
|
<div>
|
|
90
92
|
<button
|
|
91
93
|
class="success"
|