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.
- package/CHANGELOG.md +75 -0
- package/package.json +3 -3
- package/src/jsx-runtime.d.ts +2 -8
- package/src/runtime/index-client.js +3 -13
- package/src/runtime/internal/client/blocks.js +3 -25
- package/src/runtime/internal/client/for.js +80 -5
- package/src/runtime/internal/client/index.js +0 -2
- package/src/runtime/internal/client/types.d.ts +0 -10
- package/tests/client/__snapshots__/computed-properties.test.tsrx.snap +8 -0
- package/tests/client/__snapshots__/for.test.tsrx.snap +22 -0
- package/tests/client/__snapshots__/html.test.tsrx.snap +4 -0
- package/tests/client/array/array.copy-within.test.tsrx +19 -19
- package/tests/client/array/array.derived.test.tsrx +97 -109
- package/tests/client/array/array.iteration.test.tsrx +28 -28
- package/tests/client/array/array.mutations.test.tsrx +68 -68
- package/tests/client/array/array.static.test.tsrx +82 -92
- package/tests/client/array/array.to-methods.test.tsrx +15 -15
- package/tests/client/async-suspend.test.tsrx +180 -179
- package/tests/client/basic/__snapshots__/basic.attributes.test.tsrx.snap +2 -0
- package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +4 -0
- package/tests/client/basic/basic.attributes.test.tsrx +273 -317
- package/tests/client/basic/basic.collections.test.tsrx +59 -71
- package/tests/client/basic/basic.components.test.tsrx +196 -222
- package/tests/client/basic/basic.errors.test.tsrx +72 -78
- package/tests/client/basic/basic.events.test.tsrx +80 -85
- package/tests/client/basic/basic.get-set.test.tsrx +54 -64
- package/tests/client/basic/basic.hmr.test.tsrx +15 -19
- package/tests/client/basic/basic.reactivity.test.tsrx +121 -135
- package/tests/client/basic/basic.rendering.test.tsrx +273 -178
- package/tests/client/basic/basic.utilities.test.tsrx +8 -10
- package/tests/client/boundaries.test.tsrx +18 -18
- package/tests/client/compiler/compiler.assignments.test.tsrx +77 -76
- package/tests/client/compiler/compiler.attributes.test.tsrx +18 -14
- package/tests/client/compiler/compiler.basic.test.tsrx +364 -296
- package/tests/client/compiler/compiler.regex.test.tsrx +40 -44
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +57 -38
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
- package/tests/client/compiler/compiler.typescript.test.tsrx +4 -3
- package/tests/client/composite/composite.dynamic-components.test.tsrx +41 -44
- package/tests/client/composite/composite.generics.test.tsrx +165 -167
- package/tests/client/composite/composite.props.test.tsrx +66 -74
- package/tests/client/composite/composite.reactivity.test.tsrx +132 -166
- package/tests/client/composite/composite.render.test.tsrx +92 -101
- package/tests/client/computed-properties.test.tsrx +14 -18
- package/tests/client/context.test.tsrx +14 -18
- package/tests/client/css/global-additional-cases.test.tsrx +491 -437
- package/tests/client/css/global-advanced-selectors.test.tsrx +169 -153
- package/tests/client/css/global-at-rules.test.tsrx +71 -66
- package/tests/client/css/global-basic.test.tsrx +105 -98
- package/tests/client/css/global-classes-ids.test.tsrx +128 -114
- package/tests/client/css/global-combinators.test.tsrx +83 -78
- package/tests/client/css/global-complex-nesting.test.tsrx +134 -120
- package/tests/client/css/global-edge-cases.test.tsrx +138 -120
- package/tests/client/css/global-keyframes.test.tsrx +108 -96
- package/tests/client/css/global-nested.test.tsrx +88 -78
- package/tests/client/css/global-pseudo.test.tsrx +104 -98
- package/tests/client/css/global-scoping.test.tsrx +145 -125
- package/tests/client/css/style-identifier.test.tsrx +62 -69
- package/tests/client/date.test.tsrx +83 -83
- package/tests/client/dynamic-elements.test.tsrx +227 -283
- package/tests/client/events.test.tsrx +252 -266
- package/tests/client/for.test.tsrx +120 -127
- package/tests/client/head.test.tsrx +40 -48
- package/tests/client/html.test.tsrx +37 -49
- package/tests/client/input-value.test.tsrx +1125 -1354
- package/tests/client/lazy-array.test.tsrx +10 -16
- package/tests/client/lazy-destructuring.test.tsrx +169 -221
- package/tests/client/map.test.tsrx +39 -41
- package/tests/client/media-query.test.tsrx +15 -19
- package/tests/client/object.test.tsrx +46 -56
- package/tests/client/portal.test.tsrx +31 -37
- package/tests/client/ref.test.tsrx +173 -193
- package/tests/client/return.test.tsrx +62 -37
- package/tests/client/set.test.tsrx +33 -33
- package/tests/client/svg.test.tsrx +195 -215
- package/tests/client/switch.test.tsrx +201 -191
- package/tests/client/track-async-hydration.test.tsrx +14 -18
- package/tests/client/tracked-index-access.test.tsrx +18 -28
- package/tests/client/try.test.tsrx +494 -619
- package/tests/client/tsx.test.tsrx +290 -371
- package/tests/client/typescript-generics.test.tsrx +121 -129
- package/tests/client/url/url.derived.test.tsrx +21 -25
- package/tests/client/url/url.parsing.test.tsrx +35 -35
- package/tests/client/url/url.partial-removal.test.tsrx +32 -32
- package/tests/client/url/url.reactivity.test.tsrx +68 -72
- package/tests/client/url/url.serialization.test.tsrx +8 -8
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +21 -27
- package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +16 -16
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +37 -37
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +56 -60
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +32 -34
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +9 -9
- package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +10 -10
- package/tests/hydration/compiled/client/basic.js +396 -325
- package/tests/hydration/compiled/client/composite.js +52 -44
- package/tests/hydration/compiled/client/for.js +734 -604
- package/tests/hydration/compiled/client/head.js +183 -103
- package/tests/hydration/compiled/client/html.js +93 -86
- package/tests/hydration/compiled/client/if-children.js +95 -71
- package/tests/hydration/compiled/client/if.js +113 -89
- package/tests/hydration/compiled/client/mixed-control-flow.js +225 -209
- package/tests/hydration/compiled/client/nested-control-flow.js +94 -98
- package/tests/hydration/compiled/client/reactivity.js +26 -24
- package/tests/hydration/compiled/client/return.js +8 -42
- package/tests/hydration/compiled/client/switch.js +208 -173
- package/tests/hydration/compiled/client/track-async-serialization.js +176 -128
- package/tests/hydration/compiled/client/try.js +29 -21
- package/tests/hydration/compiled/server/basic.js +210 -221
- package/tests/hydration/compiled/server/composite.js +13 -14
- package/tests/hydration/compiled/server/for.js +427 -444
- package/tests/hydration/compiled/server/head.js +199 -189
- package/tests/hydration/compiled/server/html.js +33 -41
- package/tests/hydration/compiled/server/if-children.js +114 -117
- package/tests/hydration/compiled/server/if.js +77 -83
- package/tests/hydration/compiled/server/mixed-control-flow.js +145 -150
- package/tests/hydration/compiled/server/nested-control-flow.js +10 -0
- package/tests/hydration/compiled/server/reactivity.js +24 -22
- package/tests/hydration/compiled/server/return.js +6 -18
- package/tests/hydration/compiled/server/switch.js +179 -176
- package/tests/hydration/compiled/server/track-async-serialization.js +88 -70
- package/tests/hydration/compiled/server/try.js +31 -35
- package/tests/hydration/components/basic.tsrx +216 -286
- package/tests/hydration/components/composite.tsrx +32 -42
- package/tests/hydration/components/events.tsrx +81 -101
- package/tests/hydration/components/for.tsrx +270 -336
- package/tests/hydration/components/head.tsrx +43 -39
- package/tests/hydration/components/hmr.tsrx +16 -22
- package/tests/hydration/components/html-in-template.tsrx +15 -21
- package/tests/hydration/components/html.tsrx +442 -526
- package/tests/hydration/components/if-children.tsrx +107 -125
- package/tests/hydration/components/if.tsrx +68 -90
- package/tests/hydration/components/mixed-control-flow.tsrx +65 -72
- package/tests/hydration/components/nested-control-flow.tsrx +202 -216
- package/tests/hydration/components/portal.tsrx +33 -41
- package/tests/hydration/components/reactivity.tsrx +26 -34
- package/tests/hydration/components/return.tsrx +4 -6
- package/tests/hydration/components/switch.tsrx +73 -78
- package/tests/hydration/components/track-async-serialization.tsrx +83 -93
- package/tests/hydration/components/try.tsrx +37 -51
- package/tests/hydration/switch.test.js +8 -8
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +120 -167
- package/tests/server/basic.components.test.tsrx +163 -197
- package/tests/server/basic.test.tsrx +298 -220
- package/tests/server/compiler.test.tsrx +142 -72
- package/tests/server/composite.props.test.tsrx +54 -58
- package/tests/server/composite.test.tsrx +165 -167
- package/tests/server/context.test.tsrx +13 -17
- package/tests/server/dynamic-elements.test.tsrx +103 -135
- package/tests/server/for.test.tsrx +115 -84
- package/tests/server/head.test.tsrx +31 -31
- package/tests/server/html-nesting-validation.test.tsrx +16 -8
- package/tests/server/if.test.tsrx +49 -59
- package/tests/server/lazy-destructuring.test.tsrx +288 -366
- package/tests/server/return.test.tsrx +58 -36
- package/tests/server/streaming-ssr.test.tsrx +4 -4
- package/tests/server/style-identifier.test.tsrx +58 -66
- package/tests/server/switch.test.tsrx +89 -97
- package/tests/server/track-async-serialization.test.tsrx +85 -103
- package/tests/server/try.test.tsrx +275 -360
- package/tests/utils/ref-types.test.js +72 -0
- package/tests/utils/vite-plugin-config.test.js +41 -74
- package/types/index.d.ts +1 -0
- package/src/runtime/internal/client/compat.js +0 -40
- package/tests/utils/compiler-compat-config.test.js +0 -38
|
@@ -2,304 +2,268 @@ import { track } from 'ripple';
|
|
|
2
2
|
|
|
3
3
|
// For loop components for hydration testing
|
|
4
4
|
|
|
5
|
-
export function StaticForLoop() {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
</ul>
|
|
13
|
-
</>;
|
|
5
|
+
export function StaticForLoop() @{
|
|
6
|
+
const items = ['Apple', 'Banana', 'Cherry'];
|
|
7
|
+
<ul>
|
|
8
|
+
@for (const item of items) {
|
|
9
|
+
<li>{item}</li>
|
|
10
|
+
}
|
|
11
|
+
</ul>
|
|
14
12
|
}
|
|
15
13
|
|
|
16
|
-
export function ForLoopWithIndex() {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
</ul>
|
|
24
|
-
</>;
|
|
14
|
+
export function ForLoopWithIndex() @{
|
|
15
|
+
const items = ['A', 'B', 'C'];
|
|
16
|
+
<ul>
|
|
17
|
+
@for (const item of items; index i) {
|
|
18
|
+
<li>{`${i}: ${item}`}</li>
|
|
19
|
+
}
|
|
20
|
+
</ul>
|
|
25
21
|
}
|
|
26
22
|
|
|
27
|
-
export function KeyedForLoop() {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</ul>
|
|
39
|
-
</>;
|
|
23
|
+
export function KeyedForLoop() @{
|
|
24
|
+
const items = [
|
|
25
|
+
{ id: 1, name: 'First' },
|
|
26
|
+
{ id: 2, name: 'Second' },
|
|
27
|
+
{ id: 3, name: 'Third' },
|
|
28
|
+
];
|
|
29
|
+
<ul>
|
|
30
|
+
@for (const item of items; key item.id) {
|
|
31
|
+
<li>{item.name}</li>
|
|
32
|
+
}
|
|
33
|
+
</ul>
|
|
40
34
|
}
|
|
41
35
|
|
|
42
|
-
export function ReactiveForLoopAdd() {
|
|
43
|
-
|
|
44
|
-
|
|
36
|
+
export function ReactiveForLoopAdd() @{
|
|
37
|
+
let &[items] = track(['A', 'B']);
|
|
38
|
+
<>
|
|
45
39
|
<button
|
|
46
40
|
class="add"
|
|
47
41
|
onClick={() => {
|
|
48
42
|
items = [...items, 'C'];
|
|
49
43
|
}}
|
|
50
|
-
>
|
|
51
|
-
{'Add'}
|
|
52
|
-
</button>
|
|
44
|
+
>{'Add'}</button>
|
|
53
45
|
<ul>
|
|
54
|
-
for (const item of items) {
|
|
46
|
+
@for (const item of items) {
|
|
55
47
|
<li>{item}</li>
|
|
56
48
|
}
|
|
57
49
|
</ul>
|
|
58
|
-
|
|
50
|
+
</>
|
|
59
51
|
}
|
|
60
52
|
|
|
61
|
-
export function ReactiveForLoopRemove() {
|
|
62
|
-
|
|
63
|
-
|
|
53
|
+
export function ReactiveForLoopRemove() @{
|
|
54
|
+
let &[items] = track(['A', 'B', 'C']);
|
|
55
|
+
<>
|
|
64
56
|
<button
|
|
65
57
|
class="remove"
|
|
66
58
|
onClick={() => {
|
|
67
59
|
items = items.slice(0, -1);
|
|
68
60
|
}}
|
|
69
|
-
>
|
|
70
|
-
{'Remove'}
|
|
71
|
-
</button>
|
|
61
|
+
>{'Remove'}</button>
|
|
72
62
|
<ul>
|
|
73
|
-
for (const item of items) {
|
|
63
|
+
@for (const item of items) {
|
|
74
64
|
<li>{item}</li>
|
|
75
65
|
}
|
|
76
66
|
</ul>
|
|
77
|
-
|
|
67
|
+
</>
|
|
78
68
|
}
|
|
79
69
|
|
|
80
|
-
export function ForLoopInteractive() {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
</div>
|
|
98
|
-
}
|
|
99
|
-
</div>
|
|
100
|
-
</>;
|
|
70
|
+
export function ForLoopInteractive() @{
|
|
71
|
+
let &[counts] = track([0, 0, 0]);
|
|
72
|
+
<div>
|
|
73
|
+
@for (const count of counts; index i) {
|
|
74
|
+
<div class={`item-${i}`}>
|
|
75
|
+
<span class="value">{count}</span>
|
|
76
|
+
<button
|
|
77
|
+
class="increment"
|
|
78
|
+
onClick={() => {
|
|
79
|
+
const newCounts = [...counts];
|
|
80
|
+
newCounts[i]++;
|
|
81
|
+
counts = newCounts;
|
|
82
|
+
}}
|
|
83
|
+
>{'+'}</button>
|
|
84
|
+
</div>
|
|
85
|
+
}
|
|
86
|
+
</div>
|
|
101
87
|
}
|
|
102
88
|
|
|
103
|
-
export function NestedForLoop() {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
</div>
|
|
118
|
-
</>;
|
|
89
|
+
export function NestedForLoop() @{
|
|
90
|
+
const grid = [
|
|
91
|
+
[1, 2],
|
|
92
|
+
[3, 4],
|
|
93
|
+
];
|
|
94
|
+
<div class="grid">
|
|
95
|
+
@for (const row of grid; index rowIndex) {
|
|
96
|
+
<div class={`row-${rowIndex}`}>
|
|
97
|
+
@for (const cell of row; index colIndex) {
|
|
98
|
+
<span class={`cell-${rowIndex}-${colIndex}`}>{cell}</span>
|
|
99
|
+
}
|
|
100
|
+
</div>
|
|
101
|
+
}
|
|
102
|
+
</div>
|
|
119
103
|
}
|
|
120
104
|
|
|
121
|
-
export function EmptyForLoop() {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
</div>
|
|
129
|
-
</>;
|
|
105
|
+
export function EmptyForLoop() @{
|
|
106
|
+
const items: string[] = [];
|
|
107
|
+
<div class="container">
|
|
108
|
+
@for (const item of items) {
|
|
109
|
+
<span>{item}</span>
|
|
110
|
+
}
|
|
111
|
+
</div>
|
|
130
112
|
}
|
|
131
113
|
|
|
132
|
-
export function ForLoopComplexObjects() {
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
<
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
</div>
|
|
146
|
-
</>;
|
|
114
|
+
export function ForLoopComplexObjects() @{
|
|
115
|
+
const users = [
|
|
116
|
+
{ id: 1, name: 'Alice', role: 'Admin' },
|
|
117
|
+
{ id: 2, name: 'Bob', role: 'User' },
|
|
118
|
+
];
|
|
119
|
+
<div>
|
|
120
|
+
@for (const user of users; key user.id) {
|
|
121
|
+
<div class={`user-${user.id}`}>
|
|
122
|
+
<span class="name">{user.name}</span>
|
|
123
|
+
<span class="role">{user.role}</span>
|
|
124
|
+
</div>
|
|
125
|
+
}
|
|
126
|
+
</div>
|
|
147
127
|
}
|
|
148
128
|
|
|
149
129
|
// Test reordering items in a keyed for loop
|
|
150
|
-
export function KeyedForLoopReorder() {
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
130
|
+
export function KeyedForLoopReorder() @{
|
|
131
|
+
let &[items] = track([
|
|
132
|
+
{ id: 1, name: 'First' },
|
|
133
|
+
{ id: 2, name: 'Second' },
|
|
134
|
+
{ id: 3, name: 'Third' },
|
|
135
|
+
]);
|
|
136
|
+
<>
|
|
157
137
|
<button
|
|
158
138
|
class="reorder"
|
|
159
139
|
onClick={() => {
|
|
160
140
|
items = [items[2], items[0], items[1]];
|
|
161
141
|
}}
|
|
162
|
-
>
|
|
163
|
-
{'Reorder'}
|
|
164
|
-
</button>
|
|
142
|
+
>{'Reorder'}</button>
|
|
165
143
|
<ul>
|
|
166
|
-
for (const item of items; key item.id) {
|
|
144
|
+
@for (const item of items; key item.id) {
|
|
167
145
|
<li class={`item-${item.id}`}>{item.name}</li>
|
|
168
146
|
}
|
|
169
147
|
</ul>
|
|
170
|
-
|
|
148
|
+
</>
|
|
171
149
|
}
|
|
172
150
|
|
|
173
151
|
// Test for loop with item property updates (keyed)
|
|
174
|
-
export function KeyedForLoopUpdate() {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
152
|
+
export function KeyedForLoopUpdate() @{
|
|
153
|
+
let &[items] = track([
|
|
154
|
+
{ id: 1, name: 'Item 1' },
|
|
155
|
+
{ id: 2, name: 'Item 2' },
|
|
156
|
+
]);
|
|
157
|
+
<>
|
|
180
158
|
<button
|
|
181
159
|
class="update"
|
|
182
160
|
onClick={() => {
|
|
183
161
|
items = items.map((item) => (item.id === 1 ? { ...item, name: 'Updated' } : item));
|
|
184
162
|
}}
|
|
185
|
-
>
|
|
186
|
-
{'Update'}
|
|
187
|
-
</button>
|
|
163
|
+
>{'Update'}</button>
|
|
188
164
|
<ul>
|
|
189
|
-
for (const item of items; key item.id) {
|
|
165
|
+
@for (const item of items; key item.id) {
|
|
190
166
|
<li class={`item-${item.id}`}>{item.name}</li>
|
|
191
167
|
}
|
|
192
168
|
</ul>
|
|
193
|
-
|
|
169
|
+
</>
|
|
194
170
|
}
|
|
195
171
|
|
|
196
172
|
// Test for loop with combined add/remove/reorder
|
|
197
|
-
export function ForLoopMixedOperations() {
|
|
198
|
-
|
|
199
|
-
|
|
173
|
+
export function ForLoopMixedOperations() @{
|
|
174
|
+
let &[items] = track(['A', 'B', 'C', 'D']);
|
|
175
|
+
<>
|
|
200
176
|
<button
|
|
201
177
|
class="shuffle"
|
|
202
178
|
onClick={() => {
|
|
203
179
|
// Remove B, add E, reorder to D, C, A, E
|
|
204
180
|
items = ['D', 'C', 'A', 'E'];
|
|
205
181
|
}}
|
|
206
|
-
>
|
|
207
|
-
{'Shuffle'}
|
|
208
|
-
</button>
|
|
182
|
+
>{'Shuffle'}</button>
|
|
209
183
|
<ul>
|
|
210
|
-
for (const item of items) {
|
|
184
|
+
@for (const item of items) {
|
|
211
185
|
<li class={`item-${item}`}>{item}</li>
|
|
212
186
|
}
|
|
213
187
|
</ul>
|
|
214
|
-
|
|
188
|
+
</>
|
|
215
189
|
}
|
|
216
190
|
|
|
217
191
|
// Test for loop inside if block (combined control flow)
|
|
218
|
-
export function ForLoopInsideIf() {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
192
|
+
export function ForLoopInsideIf() @{
|
|
193
|
+
let &[showList] = track(true);
|
|
194
|
+
let &[items] = track(['X', 'Y', 'Z']);
|
|
195
|
+
<>
|
|
222
196
|
<button
|
|
223
197
|
class="toggle"
|
|
224
198
|
onClick={() => {
|
|
225
199
|
showList = !showList;
|
|
226
200
|
}}
|
|
227
|
-
>
|
|
228
|
-
{'Toggle List'}
|
|
229
|
-
</button>
|
|
201
|
+
>{'Toggle List'}</button>
|
|
230
202
|
<button
|
|
231
203
|
class="add"
|
|
232
204
|
onClick={() => {
|
|
233
205
|
items = [...items, 'W'];
|
|
234
206
|
}}
|
|
235
|
-
>
|
|
236
|
-
|
|
237
|
-
</button>
|
|
238
|
-
if (showList) {
|
|
207
|
+
>{'Add Item'}</button>
|
|
208
|
+
@if (showList) {
|
|
239
209
|
<ul class="list">
|
|
240
|
-
for (const item of items) {
|
|
210
|
+
@for (const item of items) {
|
|
241
211
|
<li>{item}</li>
|
|
242
212
|
}
|
|
243
213
|
</ul>
|
|
244
214
|
}
|
|
245
|
-
|
|
215
|
+
</>
|
|
246
216
|
}
|
|
247
217
|
|
|
248
218
|
// Test for loop that transitions from empty to populated
|
|
249
|
-
export function ForLoopEmptyToPopulated() {
|
|
250
|
-
|
|
251
|
-
|
|
219
|
+
export function ForLoopEmptyToPopulated() @{
|
|
220
|
+
let &[items] = track<string[]>([]);
|
|
221
|
+
<>
|
|
252
222
|
<button
|
|
253
223
|
class="populate"
|
|
254
224
|
onClick={() => {
|
|
255
225
|
items = ['One', 'Two', 'Three'];
|
|
256
226
|
}}
|
|
257
|
-
>
|
|
258
|
-
{'Populate'}
|
|
259
|
-
</button>
|
|
227
|
+
>{'Populate'}</button>
|
|
260
228
|
<ul class="list">
|
|
261
|
-
for (const item of items) {
|
|
229
|
+
@for (const item of items) {
|
|
262
230
|
<li>{item}</li>
|
|
263
231
|
}
|
|
264
232
|
</ul>
|
|
265
|
-
|
|
233
|
+
</>
|
|
266
234
|
}
|
|
267
235
|
|
|
268
236
|
// Test for loop that transitions from populated to empty
|
|
269
|
-
export function ForLoopPopulatedToEmpty() {
|
|
270
|
-
|
|
271
|
-
|
|
237
|
+
export function ForLoopPopulatedToEmpty() @{
|
|
238
|
+
let &[items] = track(['One', 'Two', 'Three']);
|
|
239
|
+
<>
|
|
272
240
|
<button
|
|
273
241
|
class="clear"
|
|
274
242
|
onClick={() => {
|
|
275
243
|
items = [];
|
|
276
244
|
}}
|
|
277
|
-
>
|
|
278
|
-
{'Clear'}
|
|
279
|
-
</button>
|
|
245
|
+
>{'Clear'}</button>
|
|
280
246
|
<ul class="list">
|
|
281
|
-
for (const item of items) {
|
|
247
|
+
@for (const item of items) {
|
|
282
248
|
<li>{item}</li>
|
|
283
249
|
}
|
|
284
250
|
</ul>
|
|
285
|
-
|
|
251
|
+
</>
|
|
286
252
|
}
|
|
287
253
|
|
|
288
254
|
// Test nested for loops with reactivity
|
|
289
|
-
export function NestedForLoopReactive() {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
255
|
+
export function NestedForLoopReactive() @{
|
|
256
|
+
let &[grid] = track([
|
|
257
|
+
[1, 2],
|
|
258
|
+
[3, 4],
|
|
259
|
+
]);
|
|
260
|
+
<div class="nested-for-reactive">
|
|
295
261
|
<button
|
|
296
262
|
class="add-row"
|
|
297
263
|
onClick={() => {
|
|
298
264
|
grid = [...grid, [5, 6]];
|
|
299
265
|
}}
|
|
300
|
-
>
|
|
301
|
-
{'Add Row'}
|
|
302
|
-
</button>
|
|
266
|
+
>{'Add Row'}</button>
|
|
303
267
|
<button
|
|
304
268
|
class="update-cell"
|
|
305
269
|
onClick={() => {
|
|
@@ -307,112 +271,104 @@ export function NestedForLoopReactive() {
|
|
|
307
271
|
newGrid[0][0] = 99;
|
|
308
272
|
grid = newGrid;
|
|
309
273
|
}}
|
|
310
|
-
>
|
|
311
|
-
{'Update Cell'}
|
|
312
|
-
</button>
|
|
274
|
+
>{'Update Cell'}</button>
|
|
313
275
|
<div class="grid">
|
|
314
|
-
for (const row of grid; index rowIndex) {
|
|
276
|
+
@for (const row of grid; index rowIndex) {
|
|
315
277
|
<div class={`row-${rowIndex}`}>
|
|
316
|
-
for (const cell of row; index colIndex) {
|
|
278
|
+
@for (const cell of row; index colIndex) {
|
|
317
279
|
<span class={`cell-${rowIndex}-${colIndex}`}>{cell}</span>
|
|
318
280
|
}
|
|
319
281
|
</div>
|
|
320
282
|
}
|
|
321
283
|
</div>
|
|
322
|
-
|
|
284
|
+
</div>
|
|
323
285
|
}
|
|
324
286
|
|
|
325
287
|
// Test for loop with deeply nested data
|
|
326
|
-
export function ForLoopDeeplyNested() {
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
<
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
<
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
</div>
|
|
362
|
-
</>;
|
|
288
|
+
export function ForLoopDeeplyNested() @{
|
|
289
|
+
const departments = [
|
|
290
|
+
{
|
|
291
|
+
id: 'd1',
|
|
292
|
+
name: 'Engineering',
|
|
293
|
+
teams: [
|
|
294
|
+
{ id: 't1', name: 'Frontend', members: ['Alice', 'Bob'] },
|
|
295
|
+
{ id: 't2', name: 'Backend', members: ['Charlie'] },
|
|
296
|
+
],
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
id: 'd2',
|
|
300
|
+
name: 'Design',
|
|
301
|
+
teams: [
|
|
302
|
+
{ id: 't3', name: 'UX', members: ['Diana', 'Eve', 'Frank'] },
|
|
303
|
+
],
|
|
304
|
+
},
|
|
305
|
+
];
|
|
306
|
+
<div class="org">
|
|
307
|
+
@for (const dept of departments; key dept.id) {
|
|
308
|
+
<div class={`dept-${dept.id}`}>
|
|
309
|
+
<h2 class="dept-name">{dept.name}</h2>
|
|
310
|
+
@for (const team of dept.teams; key team.id) {
|
|
311
|
+
<div class={`team-${team.id}`}>
|
|
312
|
+
<h3 class="team-name">{team.name}</h3>
|
|
313
|
+
<ul>
|
|
314
|
+
@for (const member of team.members) {
|
|
315
|
+
<li class="member">{member}</li>
|
|
316
|
+
}
|
|
317
|
+
</ul>
|
|
318
|
+
</div>
|
|
319
|
+
}
|
|
320
|
+
</div>
|
|
321
|
+
}
|
|
322
|
+
</div>
|
|
363
323
|
}
|
|
364
324
|
|
|
365
325
|
// Test for loop with index that gets updated
|
|
366
|
-
export function ForLoopIndexUpdate() {
|
|
367
|
-
|
|
368
|
-
|
|
326
|
+
export function ForLoopIndexUpdate() @{
|
|
327
|
+
let &[items] = track(['First', 'Second', 'Third']);
|
|
328
|
+
<>
|
|
369
329
|
<button
|
|
370
330
|
class="prepend"
|
|
371
331
|
onClick={() => {
|
|
372
332
|
items = ['Zeroth', ...items];
|
|
373
333
|
}}
|
|
374
|
-
>
|
|
375
|
-
{'Prepend'}
|
|
376
|
-
</button>
|
|
334
|
+
>{'Prepend'}</button>
|
|
377
335
|
<ul>
|
|
378
|
-
for (const item of items; index i) {
|
|
336
|
+
@for (const item of items; index i) {
|
|
379
337
|
<li class={`item-${i}`}>{`[${i}] ${item}`}</li>
|
|
380
338
|
}
|
|
381
339
|
</ul>
|
|
382
|
-
|
|
340
|
+
</>
|
|
383
341
|
}
|
|
384
342
|
|
|
385
343
|
// Test keyed for loop with index
|
|
386
|
-
export function KeyedForLoopWithIndex() {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
344
|
+
export function KeyedForLoopWithIndex() @{
|
|
345
|
+
let &[items] = track([
|
|
346
|
+
{ id: 'a', value: 'Alpha' },
|
|
347
|
+
{ id: 'b', value: 'Beta' },
|
|
348
|
+
{ id: 'c', value: 'Gamma' },
|
|
349
|
+
]);
|
|
350
|
+
<>
|
|
393
351
|
<button
|
|
394
352
|
class="reorder"
|
|
395
353
|
onClick={() => {
|
|
396
354
|
items = [items[1], items[2], items[0]];
|
|
397
355
|
}}
|
|
398
|
-
>
|
|
399
|
-
{'Rotate'}
|
|
400
|
-
</button>
|
|
356
|
+
>{'Rotate'}</button>
|
|
401
357
|
<ul>
|
|
402
|
-
for (const item of items; index i; key item.id) {
|
|
358
|
+
@for (const item of items; index i; key item.id) {
|
|
403
359
|
<li class={`item-${item.id}`} data-index={i}>{`[${i}] ${item.id}: ${item.value}`}</li>
|
|
404
360
|
}
|
|
405
361
|
</ul>
|
|
406
|
-
|
|
362
|
+
</>
|
|
407
363
|
}
|
|
408
364
|
|
|
409
365
|
// Test for loop with sibling elements
|
|
410
|
-
export function ForLoopWithSiblings() {
|
|
411
|
-
|
|
412
|
-
|
|
366
|
+
export function ForLoopWithSiblings() @{
|
|
367
|
+
let &[items] = track(['A', 'B']);
|
|
368
|
+
<>
|
|
413
369
|
<div class="wrapper">
|
|
414
370
|
<header class="before">{'Before'}</header>
|
|
415
|
-
for (const item of items) {
|
|
371
|
+
@for (const item of items) {
|
|
416
372
|
<div class={`item-${item}`}>{item}</div>
|
|
417
373
|
}
|
|
418
374
|
<footer class="after">{'After'}</footer>
|
|
@@ -422,83 +378,71 @@ export function ForLoopWithSiblings() {
|
|
|
422
378
|
onClick={() => {
|
|
423
379
|
items = [...items, 'C'];
|
|
424
380
|
}}
|
|
425
|
-
>
|
|
426
|
-
|
|
427
|
-
</button>
|
|
428
|
-
</>;
|
|
381
|
+
>{'Add'}</button>
|
|
382
|
+
</>
|
|
429
383
|
}
|
|
430
384
|
|
|
431
385
|
// Test for loop items with their own reactive state
|
|
432
|
-
export function ForLoopItemState() {
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
</div>
|
|
444
|
-
</>;
|
|
386
|
+
export function ForLoopItemState() @{
|
|
387
|
+
const initialItems = [
|
|
388
|
+
{ id: 1, text: 'Todo 1' },
|
|
389
|
+
{ id: 2, text: 'Todo 2' },
|
|
390
|
+
{ id: 3, text: 'Todo 3' },
|
|
391
|
+
];
|
|
392
|
+
<div>
|
|
393
|
+
@for (const item of initialItems; key item.id) {
|
|
394
|
+
<TodoItem id={item.id} text={item.text} />
|
|
395
|
+
}
|
|
396
|
+
</div>
|
|
445
397
|
}
|
|
446
398
|
|
|
447
|
-
function TodoItem(props: { id: number; text: string }) {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
<
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
{props.text}
|
|
461
|
-
</span>
|
|
462
|
-
</div>
|
|
463
|
-
</>;
|
|
399
|
+
function TodoItem(props: { id: number; text: string }) @{
|
|
400
|
+
let &[done] = track(false);
|
|
401
|
+
<div class={`todo-${props.id}`}>
|
|
402
|
+
<input
|
|
403
|
+
type="checkbox"
|
|
404
|
+
class="checkbox"
|
|
405
|
+
checked={done}
|
|
406
|
+
onChange={(e) => {
|
|
407
|
+
done = (e.target as HTMLInputElement).checked;
|
|
408
|
+
}}
|
|
409
|
+
/>
|
|
410
|
+
<span class={done ? 'completed' : 'pending'}>{props.text}</span>
|
|
411
|
+
</div>
|
|
464
412
|
}
|
|
465
413
|
|
|
466
414
|
// Test for loop with single item
|
|
467
|
-
export function ForLoopSingleItem() {
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
</ul>
|
|
475
|
-
</>;
|
|
415
|
+
export function ForLoopSingleItem() @{
|
|
416
|
+
const items = ['Only'];
|
|
417
|
+
<ul>
|
|
418
|
+
@for (const item of items) {
|
|
419
|
+
<li class="single">{item}</li>
|
|
420
|
+
}
|
|
421
|
+
</ul>
|
|
476
422
|
}
|
|
477
423
|
|
|
478
424
|
// Test for loop adding at beginning
|
|
479
|
-
export function ForLoopAddAtBeginning() {
|
|
480
|
-
|
|
481
|
-
|
|
425
|
+
export function ForLoopAddAtBeginning() @{
|
|
426
|
+
let &[items] = track(['B', 'C']);
|
|
427
|
+
<>
|
|
482
428
|
<button
|
|
483
429
|
class="prepend"
|
|
484
430
|
onClick={() => {
|
|
485
431
|
items = ['A', ...items];
|
|
486
432
|
}}
|
|
487
|
-
>
|
|
488
|
-
{'Prepend A'}
|
|
489
|
-
</button>
|
|
433
|
+
>{'Prepend A'}</button>
|
|
490
434
|
<ul>
|
|
491
|
-
for (const item of items) {
|
|
435
|
+
@for (const item of items) {
|
|
492
436
|
<li class={`item-${item}`}>{item}</li>
|
|
493
437
|
}
|
|
494
438
|
</ul>
|
|
495
|
-
|
|
439
|
+
</>
|
|
496
440
|
}
|
|
497
441
|
|
|
498
442
|
// Test for loop adding in the middle
|
|
499
|
-
export function ForLoopAddInMiddle() {
|
|
500
|
-
|
|
501
|
-
|
|
443
|
+
export function ForLoopAddInMiddle() @{
|
|
444
|
+
let &[items] = track(['A', 'C']);
|
|
445
|
+
<>
|
|
502
446
|
<button
|
|
503
447
|
class="insert"
|
|
504
448
|
onClick={() => {
|
|
@@ -506,53 +450,47 @@ export function ForLoopAddInMiddle() {
|
|
|
506
450
|
copy.splice(1, 0, 'B');
|
|
507
451
|
items = copy;
|
|
508
452
|
}}
|
|
509
|
-
>
|
|
510
|
-
{'Insert B'}
|
|
511
|
-
</button>
|
|
453
|
+
>{'Insert B'}</button>
|
|
512
454
|
<ul>
|
|
513
|
-
for (const item of items) {
|
|
455
|
+
@for (const item of items) {
|
|
514
456
|
<li class={`item-${item}`}>{item}</li>
|
|
515
457
|
}
|
|
516
458
|
</ul>
|
|
517
|
-
|
|
459
|
+
</>
|
|
518
460
|
}
|
|
519
461
|
|
|
520
462
|
// Test for loop removing from the middle
|
|
521
|
-
export function ForLoopRemoveFromMiddle() {
|
|
522
|
-
|
|
523
|
-
|
|
463
|
+
export function ForLoopRemoveFromMiddle() @{
|
|
464
|
+
let &[items] = track(['A', 'B', 'C']);
|
|
465
|
+
<>
|
|
524
466
|
<button
|
|
525
467
|
class="remove-middle"
|
|
526
468
|
onClick={() => {
|
|
527
469
|
items = items.filter((item) => item !== 'B');
|
|
528
470
|
}}
|
|
529
|
-
>
|
|
530
|
-
{'Remove B'}
|
|
531
|
-
</button>
|
|
471
|
+
>{'Remove B'}</button>
|
|
532
472
|
<ul>
|
|
533
|
-
for (const item of items) {
|
|
473
|
+
@for (const item of items) {
|
|
534
474
|
<li class={`item-${item}`}>{item}</li>
|
|
535
475
|
}
|
|
536
476
|
</ul>
|
|
537
|
-
|
|
477
|
+
</>
|
|
538
478
|
}
|
|
539
479
|
|
|
540
480
|
// Test for loop with large list
|
|
541
|
-
export function ForLoopLargeList() {
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
</ul>
|
|
549
|
-
</>;
|
|
481
|
+
export function ForLoopLargeList() @{
|
|
482
|
+
const items = Array.from({ length: 50 }, (_, i) => `Item ${i + 1}`);
|
|
483
|
+
<ul class="large-list">
|
|
484
|
+
@for (const item of items; index i) {
|
|
485
|
+
<li class={`item-${i}`}>{item}</li>
|
|
486
|
+
}
|
|
487
|
+
</ul>
|
|
550
488
|
}
|
|
551
489
|
|
|
552
490
|
// Test for loop with swap operation
|
|
553
|
-
export function ForLoopSwap() {
|
|
554
|
-
|
|
555
|
-
|
|
491
|
+
export function ForLoopSwap() @{
|
|
492
|
+
let &[items] = track(['A', 'B', 'C', 'D']);
|
|
493
|
+
<>
|
|
556
494
|
<button
|
|
557
495
|
class="swap"
|
|
558
496
|
onClick={() => {
|
|
@@ -560,33 +498,29 @@ export function ForLoopSwap() {
|
|
|
560
498
|
[copy[0], copy[3]] = [copy[3], copy[0]];
|
|
561
499
|
items = copy;
|
|
562
500
|
}}
|
|
563
|
-
>
|
|
564
|
-
{'Swap First and Last'}
|
|
565
|
-
</button>
|
|
501
|
+
>{'Swap First and Last'}</button>
|
|
566
502
|
<ul>
|
|
567
|
-
for (const item of items) {
|
|
503
|
+
@for (const item of items) {
|
|
568
504
|
<li class={`item-${item}`}>{item}</li>
|
|
569
505
|
}
|
|
570
506
|
</ul>
|
|
571
|
-
|
|
507
|
+
</>
|
|
572
508
|
}
|
|
573
509
|
|
|
574
510
|
// Test for loop with reverse operation
|
|
575
|
-
export function ForLoopReverse() {
|
|
576
|
-
|
|
577
|
-
|
|
511
|
+
export function ForLoopReverse() @{
|
|
512
|
+
let &[items] = track(['A', 'B', 'C', 'D']);
|
|
513
|
+
<>
|
|
578
514
|
<button
|
|
579
515
|
class="reverse"
|
|
580
516
|
onClick={() => {
|
|
581
517
|
items = [...items].reverse();
|
|
582
518
|
}}
|
|
583
|
-
>
|
|
584
|
-
{'Reverse'}
|
|
585
|
-
</button>
|
|
519
|
+
>{'Reverse'}</button>
|
|
586
520
|
<ul>
|
|
587
|
-
for (const item of items) {
|
|
521
|
+
@for (const item of items) {
|
|
588
522
|
<li class={`item-${item}`}>{item}</li>
|
|
589
523
|
}
|
|
590
524
|
</ul>
|
|
591
|
-
|
|
525
|
+
</>
|
|
592
526
|
}
|