ripple 0.3.7 → 0.3.8
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 +7 -0
- package/package.json +2 -2
- package/src/compiler/phases/1-parse/index.js +37 -194
- package/src/compiler/phases/2-analyze/index.js +63 -18
- package/src/compiler/phases/3-transform/client/index.js +19 -3
- package/src/compiler/phases/3-transform/server/index.js +16 -24
- package/src/compiler/types/parse.d.ts +0 -8
- package/src/runtime/internal/client/composite.js +2 -2
- package/tests/client/array/array.copy-within.test.ripple +12 -12
- package/tests/client/array/array.derived.test.ripple +46 -46
- package/tests/client/array/array.iteration.test.ripple +10 -10
- package/tests/client/array/array.mutations.test.ripple +20 -20
- package/tests/client/array/array.to-methods.test.ripple +6 -6
- package/tests/client/async-suspend.test.ripple +5 -5
- package/tests/client/basic/basic.attributes.test.ripple +81 -81
- package/tests/client/basic/basic.collections.test.ripple +9 -9
- package/tests/client/basic/basic.components.test.ripple +28 -28
- package/tests/client/basic/basic.errors.test.ripple +18 -18
- package/tests/client/basic/basic.events.test.ripple +37 -37
- package/tests/client/basic/basic.get-set.test.ripple +6 -6
- package/tests/client/basic/basic.reactivity.test.ripple +68 -68
- package/tests/client/basic/basic.rendering.test.ripple +19 -19
- package/tests/client/basic/basic.utilities.test.ripple +3 -3
- package/tests/client/boundaries.test.ripple +12 -12
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.ripple.snap +5 -5
- package/tests/client/compiler/compiler.assignments.test.ripple +19 -19
- package/tests/client/compiler/compiler.basic.test.ripple +16 -16
- package/tests/client/compiler/compiler.tracked-access.test.ripple +2 -2
- package/tests/client/composite/composite.dynamic-components.test.ripple +9 -9
- package/tests/client/composite/composite.props.test.ripple +11 -11
- package/tests/client/composite/composite.reactivity.test.ripple +43 -43
- package/tests/client/composite/composite.render.test.ripple +3 -3
- package/tests/client/computed-properties.test.ripple +4 -4
- package/tests/client/date.test.ripple +42 -42
- package/tests/client/dynamic-elements.test.ripple +42 -42
- package/tests/client/events.test.ripple +70 -70
- package/tests/client/for.test.ripple +25 -25
- package/tests/client/head.test.ripple +19 -19
- package/tests/client/html.test.ripple +3 -3
- package/tests/client/input-value.test.ripple +84 -84
- package/tests/client/lazy-destructuring.test.ripple +71 -16
- package/tests/client/map.test.ripple +16 -16
- package/tests/client/media-query.test.ripple +7 -7
- package/tests/client/portal.test.ripple +11 -11
- package/tests/client/ref.test.ripple +4 -4
- package/tests/client/return.test.ripple +52 -52
- package/tests/client/set.test.ripple +6 -6
- package/tests/client/svg.test.ripple +5 -5
- package/tests/client/switch.test.ripple +44 -44
- package/tests/client/try.test.ripple +5 -5
- package/tests/client/url/url.derived.test.ripple +6 -6
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +8 -8
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +10 -10
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +10 -10
- package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +18 -18
- package/tests/client/url-search-params/url-search-params.serialization.test.ripple +2 -2
- package/tests/hydration/compiled/client/events.js +25 -25
- package/tests/hydration/compiled/client/for.js +70 -66
- package/tests/hydration/compiled/client/head.js +25 -25
- package/tests/hydration/compiled/client/hmr.js +2 -2
- package/tests/hydration/compiled/client/html.js +3 -3
- package/tests/hydration/compiled/client/if-children.js +24 -24
- package/tests/hydration/compiled/client/if.js +18 -18
- package/tests/hydration/compiled/client/mixed-control-flow.js +9 -9
- package/tests/hydration/compiled/client/portal.js +3 -3
- package/tests/hydration/compiled/client/reactivity.js +16 -16
- package/tests/hydration/compiled/client/return.js +40 -40
- package/tests/hydration/compiled/client/switch.js +12 -12
- package/tests/hydration/compiled/server/events.js +19 -19
- package/tests/hydration/compiled/server/for.js +41 -41
- package/tests/hydration/compiled/server/head.js +26 -26
- package/tests/hydration/compiled/server/hmr.js +2 -2
- package/tests/hydration/compiled/server/html.js +2 -2
- package/tests/hydration/compiled/server/if-children.js +16 -16
- package/tests/hydration/compiled/server/if.js +11 -11
- package/tests/hydration/compiled/server/mixed-control-flow.js +6 -6
- package/tests/hydration/compiled/server/portal.js +2 -2
- package/tests/hydration/compiled/server/reactivity.js +16 -16
- package/tests/hydration/compiled/server/return.js +25 -25
- package/tests/hydration/compiled/server/switch.js +8 -8
- package/tests/hydration/components/events.ripple +25 -25
- package/tests/hydration/components/for.ripple +66 -66
- package/tests/hydration/components/head.ripple +16 -16
- package/tests/hydration/components/hmr.ripple +2 -2
- package/tests/hydration/components/html.ripple +3 -3
- package/tests/hydration/components/if-children.ripple +24 -24
- package/tests/hydration/components/if.ripple +18 -18
- package/tests/hydration/components/mixed-control-flow.ripple +9 -9
- package/tests/hydration/components/portal.ripple +3 -3
- package/tests/hydration/components/reactivity.ripple +16 -16
- package/tests/hydration/components/return.ripple +40 -40
- package/tests/hydration/components/switch.ripple +20 -20
- package/tests/server/await.test.ripple +3 -3
- package/tests/server/basic.attributes.test.ripple +34 -34
- package/tests/server/basic.components.test.ripple +10 -10
- package/tests/server/basic.test.ripple +38 -40
- package/tests/server/composite.props.test.ripple +9 -9
- package/tests/server/dynamic-elements.test.ripple +13 -12
- package/tests/server/head.test.ripple +11 -11
- package/tests/server/lazy-destructuring.test.ripple +27 -4
|
@@ -4,11 +4,11 @@ import { track } from 'ripple';
|
|
|
4
4
|
// Based on SidebarGroup pattern from website-new
|
|
5
5
|
|
|
6
6
|
export component IfWithChildren({ children }: { children: any }) {
|
|
7
|
-
let expanded = track(true);
|
|
7
|
+
let &[expanded] = track(true);
|
|
8
8
|
|
|
9
9
|
<div class="container">
|
|
10
|
-
<div class="header" role="button" onClick={() => (
|
|
11
|
-
if (
|
|
10
|
+
<div class="header" role="button" onClick={() => (expanded = !expanded)}>{'Toggle'}</div>
|
|
11
|
+
if (expanded) {
|
|
12
12
|
<div class="content">
|
|
13
13
|
<children />
|
|
14
14
|
</div>
|
|
@@ -29,11 +29,11 @@ export component TestIfWithChildren() {
|
|
|
29
29
|
|
|
30
30
|
// Simpler variant - if block with static children
|
|
31
31
|
export component IfWithStaticChildren() {
|
|
32
|
-
let expanded = track(true);
|
|
32
|
+
let &[expanded] = track(true);
|
|
33
33
|
|
|
34
34
|
<div class="container">
|
|
35
|
-
<div class="header" role="button" onClick={() => (
|
|
36
|
-
if (
|
|
35
|
+
<div class="header" role="button" onClick={() => (expanded = !expanded)}>{'Toggle'}</div>
|
|
36
|
+
if (expanded) {
|
|
37
37
|
<div class="content">
|
|
38
38
|
<span>{'Static child 1'}</span>
|
|
39
39
|
<span>{'Static child 2'}</span>
|
|
@@ -44,10 +44,10 @@ export component IfWithStaticChildren() {
|
|
|
44
44
|
|
|
45
45
|
// Variant with sibling elements before the if block (like SidebarGroup)
|
|
46
46
|
export component IfWithSiblingsAndChildren({ children }: { children: any }) {
|
|
47
|
-
let expanded = track(true);
|
|
47
|
+
let &[expanded] = track(true);
|
|
48
48
|
|
|
49
49
|
<section class="group">
|
|
50
|
-
<div class="item" role="button" onClick={() => (
|
|
50
|
+
<div class="item" role="button" onClick={() => (expanded = !expanded)}>
|
|
51
51
|
<div class="indicator" />
|
|
52
52
|
<h2 class="text">{'Title'}</h2>
|
|
53
53
|
<div class="caret">
|
|
@@ -56,7 +56,7 @@ export component IfWithSiblingsAndChildren({ children }: { children: any }) {
|
|
|
56
56
|
</svg>
|
|
57
57
|
</div>
|
|
58
58
|
</div>
|
|
59
|
-
if (
|
|
59
|
+
if (expanded) {
|
|
60
60
|
<div class="items">
|
|
61
61
|
<children />
|
|
62
62
|
</div>
|
|
@@ -75,7 +75,7 @@ export component TestIfWithSiblingsAndChildren() {
|
|
|
75
75
|
// This tests that hydrate_node is properly restored after processing an element's children
|
|
76
76
|
// before navigating to a dynamic sibling (if/for/switch)
|
|
77
77
|
export component ElementWithChildrenThenIf() {
|
|
78
|
-
let show = track(true);
|
|
78
|
+
let &[show] = track(true);
|
|
79
79
|
|
|
80
80
|
<div class="wrapper">
|
|
81
81
|
<div class="nested-parent">
|
|
@@ -83,17 +83,17 @@ export component ElementWithChildrenThenIf() {
|
|
|
83
83
|
<span class="deep">{'Deep content'}</span>
|
|
84
84
|
</div>
|
|
85
85
|
</div>
|
|
86
|
-
if (
|
|
86
|
+
if (show) {
|
|
87
87
|
<div class="conditional">{'Conditional content'}</div>
|
|
88
88
|
}
|
|
89
89
|
</div>
|
|
90
90
|
|
|
91
|
-
<button class="toggle" onClick={() => (
|
|
91
|
+
<button class="toggle" onClick={() => (show = !show)}>{'Toggle'}</button>
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
// More complex: multiple levels of nesting before if sibling
|
|
95
95
|
export component DeepNestingThenIf() {
|
|
96
|
-
let visible = track(true);
|
|
96
|
+
let &[visible] = track(true);
|
|
97
97
|
|
|
98
98
|
<section class="outer">
|
|
99
99
|
<article class="middle">
|
|
@@ -104,39 +104,39 @@ export component DeepNestingThenIf() {
|
|
|
104
104
|
</p>
|
|
105
105
|
</div>
|
|
106
106
|
</article>
|
|
107
|
-
if (
|
|
107
|
+
if (visible) {
|
|
108
108
|
<footer class="footer">{'Footer'}</footer>
|
|
109
109
|
}
|
|
110
110
|
</section>
|
|
111
111
|
|
|
112
|
-
<button class="btn" onClick={() => (
|
|
112
|
+
<button class="btn" onClick={() => (visible = !visible)}>{'Toggle'}</button>
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
// Test case for CodeBlock pattern: element with only DOM element children (like buttons)
|
|
116
116
|
// followed by another sibling element. This requires pop() to restore hydrate_node
|
|
117
117
|
// because we descend into the first element to get the button children.
|
|
118
118
|
export component DomElementChildrenThenSibling() {
|
|
119
|
-
let activeTab = track('code');
|
|
119
|
+
let &[activeTab] = track('code');
|
|
120
120
|
|
|
121
121
|
<div class="tabs">
|
|
122
122
|
<div class="tab-list">
|
|
123
123
|
<button
|
|
124
124
|
class="tab"
|
|
125
|
-
aria-selected={
|
|
126
|
-
onClick={() => (
|
|
125
|
+
aria-selected={activeTab === 'code' ? 'true' : 'false'}
|
|
126
|
+
onClick={() => (activeTab = 'code')}
|
|
127
127
|
>
|
|
128
128
|
{'Code'}
|
|
129
129
|
</button>
|
|
130
130
|
<button
|
|
131
131
|
class="tab"
|
|
132
|
-
aria-selected={
|
|
133
|
-
onClick={() => (
|
|
132
|
+
aria-selected={activeTab === 'preview' ? 'true' : 'false'}
|
|
133
|
+
onClick={() => (activeTab = 'preview')}
|
|
134
134
|
>
|
|
135
135
|
{'Preview'}
|
|
136
136
|
</button>
|
|
137
137
|
</div>
|
|
138
138
|
<div class="panel">
|
|
139
|
-
if (
|
|
139
|
+
if (activeTab === 'code') {
|
|
140
140
|
<pre class="code">{'const x = 1;'}</pre>
|
|
141
141
|
} else {
|
|
142
142
|
<div class="preview">{'Preview content'}</div>
|
|
@@ -149,13 +149,13 @@ export component DomElementChildrenThenSibling() {
|
|
|
149
149
|
// generate sibling() calls. This was causing incorrect pop() generation before next().
|
|
150
150
|
// Pattern: <ul> with dynamic <li> children -> static <h2> -> static <p> -> next()
|
|
151
151
|
export component DomChildrenThenStaticSiblings() {
|
|
152
|
-
let count = track(0);
|
|
152
|
+
let &[count] = track(0);
|
|
153
153
|
|
|
154
154
|
<div class="container">
|
|
155
155
|
<ul class="list">
|
|
156
156
|
<li class="item">
|
|
157
157
|
{'Item count: '}
|
|
158
|
-
{
|
|
158
|
+
{count}
|
|
159
159
|
</li>
|
|
160
160
|
<li class="item">{'Another item'}</li>
|
|
161
161
|
</ul>
|
|
@@ -163,7 +163,7 @@ export component DomChildrenThenStaticSiblings() {
|
|
|
163
163
|
<p class="para">{'Static paragraph'}</p>
|
|
164
164
|
</div>
|
|
165
165
|
|
|
166
|
-
<button class="inc" onClick={() =>
|
|
166
|
+
<button class="inc" onClick={() => count++}>{'Increment'}</button>
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
// Test case for completely static element children followed by static siblings.
|
|
@@ -26,31 +26,31 @@ export component IfElse() {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export component ReactiveIf() {
|
|
29
|
-
let show = track(true);
|
|
29
|
+
let &[show] = track(true);
|
|
30
30
|
<button
|
|
31
31
|
class="toggle"
|
|
32
32
|
onClick={() => {
|
|
33
|
-
|
|
33
|
+
show = !show;
|
|
34
34
|
}}
|
|
35
35
|
>
|
|
36
36
|
{'Toggle'}
|
|
37
37
|
</button>
|
|
38
|
-
if (
|
|
38
|
+
if (show) {
|
|
39
39
|
<div class="content">{'Content visible'}</div>
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
export component ReactiveIfElse() {
|
|
44
|
-
let isOn = track(false);
|
|
44
|
+
let &[isOn] = track(false);
|
|
45
45
|
<button
|
|
46
46
|
class="toggle"
|
|
47
47
|
onClick={() => {
|
|
48
|
-
|
|
48
|
+
isOn = !isOn;
|
|
49
49
|
}}
|
|
50
50
|
>
|
|
51
51
|
{'Toggle'}
|
|
52
52
|
</button>
|
|
53
|
-
if (
|
|
53
|
+
if (isOn) {
|
|
54
54
|
<div class="on">{'ON'}</div>
|
|
55
55
|
} else {
|
|
56
56
|
<div class="off">{'OFF'}</div>
|
|
@@ -58,12 +58,12 @@ export component ReactiveIfElse() {
|
|
|
58
58
|
}
|
|
59
59
|
|
|
60
60
|
export component NestedIf() {
|
|
61
|
-
let outer = track(true);
|
|
62
|
-
let inner = track(true);
|
|
61
|
+
let &[outer] = track(true);
|
|
62
|
+
let &[inner] = track(true);
|
|
63
63
|
<button
|
|
64
64
|
class="outer-toggle"
|
|
65
65
|
onClick={() => {
|
|
66
|
-
|
|
66
|
+
outer = !outer;
|
|
67
67
|
}}
|
|
68
68
|
>
|
|
69
69
|
{'Outer'}
|
|
@@ -71,15 +71,15 @@ export component NestedIf() {
|
|
|
71
71
|
<button
|
|
72
72
|
class="inner-toggle"
|
|
73
73
|
onClick={() => {
|
|
74
|
-
|
|
74
|
+
inner = !inner;
|
|
75
75
|
}}
|
|
76
76
|
>
|
|
77
77
|
{'Inner'}
|
|
78
78
|
</button>
|
|
79
|
-
if (
|
|
79
|
+
if (outer) {
|
|
80
80
|
<div class="outer-content">
|
|
81
81
|
{'Outer'}
|
|
82
|
-
if (
|
|
82
|
+
if (inner) {
|
|
83
83
|
<span class="inner-content">{'Inner'}</span>
|
|
84
84
|
}
|
|
85
85
|
</div>
|
|
@@ -87,12 +87,12 @@ export component NestedIf() {
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
export component IfElseIfChain() {
|
|
90
|
-
let status = track<'loading' | 'success' | 'error'>('loading');
|
|
90
|
+
let &[status] = track<'loading' | 'success' | 'error'>('loading');
|
|
91
91
|
<div>
|
|
92
92
|
<button
|
|
93
93
|
class="success"
|
|
94
94
|
onClick={() => {
|
|
95
|
-
|
|
95
|
+
status = 'success';
|
|
96
96
|
}}
|
|
97
97
|
>
|
|
98
98
|
{'Success'}
|
|
@@ -100,7 +100,7 @@ export component IfElseIfChain() {
|
|
|
100
100
|
<button
|
|
101
101
|
class="error"
|
|
102
102
|
onClick={() => {
|
|
103
|
-
|
|
103
|
+
status = 'error';
|
|
104
104
|
}}
|
|
105
105
|
>
|
|
106
106
|
{'Error'}
|
|
@@ -108,14 +108,14 @@ export component IfElseIfChain() {
|
|
|
108
108
|
<button
|
|
109
109
|
class="loading"
|
|
110
110
|
onClick={() => {
|
|
111
|
-
|
|
111
|
+
status = 'loading';
|
|
112
112
|
}}
|
|
113
113
|
>
|
|
114
114
|
{'Loading'}
|
|
115
115
|
</button>
|
|
116
|
-
if (
|
|
116
|
+
if (status === 'loading') {
|
|
117
117
|
<div class="state">{'Loading...'}</div>
|
|
118
|
-
} else if (
|
|
118
|
+
} else if (status === 'success') {
|
|
119
119
|
<div class="state">{'Success!'}</div>
|
|
120
120
|
} else {
|
|
121
121
|
<div class="state">{'Error occurred'}</div>
|
|
@@ -31,9 +31,9 @@ export component MixedControlFlowStatic() {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
export component MixedControlFlowReactive() {
|
|
34
|
-
let show = track(true);
|
|
35
|
-
let mode = track<'a' | 'b'>('a');
|
|
36
|
-
let items = track([
|
|
34
|
+
let &[show] = track(true);
|
|
35
|
+
let &[mode] = track<'a' | 'b'>('a');
|
|
36
|
+
let &[items] = track([
|
|
37
37
|
{ id: 1, label: 'One' },
|
|
38
38
|
{ id: 2, label: 'Two' },
|
|
39
39
|
]);
|
|
@@ -41,7 +41,7 @@ export component MixedControlFlowReactive() {
|
|
|
41
41
|
<button
|
|
42
42
|
class="toggle-show"
|
|
43
43
|
onClick={() => {
|
|
44
|
-
|
|
44
|
+
show = !show;
|
|
45
45
|
}}
|
|
46
46
|
>
|
|
47
47
|
{'Toggle Show'}
|
|
@@ -49,7 +49,7 @@ export component MixedControlFlowReactive() {
|
|
|
49
49
|
<button
|
|
50
50
|
class="toggle-mode"
|
|
51
51
|
onClick={() => {
|
|
52
|
-
|
|
52
|
+
mode = mode === 'a' ? 'b' : 'a';
|
|
53
53
|
}}
|
|
54
54
|
>
|
|
55
55
|
{'Toggle Mode'}
|
|
@@ -57,16 +57,16 @@ export component MixedControlFlowReactive() {
|
|
|
57
57
|
<button
|
|
58
58
|
class="add-item"
|
|
59
59
|
onClick={() => {
|
|
60
|
-
|
|
60
|
+
items = [...items, { id: 3, label: 'Three' }];
|
|
61
61
|
}}
|
|
62
62
|
>
|
|
63
63
|
{'Add Item'}
|
|
64
64
|
</button>
|
|
65
65
|
|
|
66
|
-
if (
|
|
66
|
+
if (show) {
|
|
67
67
|
<div class="mixed-reactive-list">
|
|
68
|
-
for (const item of
|
|
69
|
-
switch (
|
|
68
|
+
for (const item of items; key item.id) {
|
|
69
|
+
switch (mode) {
|
|
70
70
|
case 'a':
|
|
71
71
|
try {
|
|
72
72
|
<p class={`item item-${item.id}`}>{`A:${item.label}`}</p>
|
|
@@ -13,11 +13,11 @@ export component SimplePortal() {
|
|
|
13
13
|
|
|
14
14
|
// Portal with conditional rendering
|
|
15
15
|
export component ConditionalPortal() {
|
|
16
|
-
let show = track(true);
|
|
16
|
+
let &[show] = track(true);
|
|
17
17
|
|
|
18
18
|
<div class="container">
|
|
19
|
-
<button class="toggle" onClick={() => (
|
|
20
|
-
if (
|
|
19
|
+
<button class="toggle" onClick={() => (show = !show)}>{'Toggle'}</button>
|
|
20
|
+
if (show) {
|
|
21
21
|
<Portal target={typeof document !== 'undefined' ? document.body : null}>
|
|
22
22
|
<div class="portal-content">{'Portal is visible'}</div>
|
|
23
23
|
</Portal>
|
|
@@ -3,14 +3,14 @@ import { track } from 'ripple';
|
|
|
3
3
|
// Reactive components for hydration testing
|
|
4
4
|
|
|
5
5
|
export component TrackedState() {
|
|
6
|
-
let count = track(0);
|
|
7
|
-
<div class="count">{
|
|
6
|
+
let &[count] = track(0);
|
|
7
|
+
<div class="count">{count}</div>
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export component CounterWithInitial(props: { initial: number }) {
|
|
11
|
-
let count = track(props.initial);
|
|
11
|
+
let &[count] = track(props.initial);
|
|
12
12
|
<div>
|
|
13
|
-
<span class="count">{
|
|
13
|
+
<span class="count">{count}</span>
|
|
14
14
|
</div>
|
|
15
15
|
}
|
|
16
16
|
|
|
@@ -19,24 +19,24 @@ export component CounterWrapper() {
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
export component ComputedValues() {
|
|
22
|
-
let a = track(2);
|
|
23
|
-
let b = track(3);
|
|
24
|
-
const sum = () =>
|
|
22
|
+
let &[a] = track(2);
|
|
23
|
+
let &[b] = track(3);
|
|
24
|
+
const sum = () => a + b;
|
|
25
25
|
<div class="sum">{sum()}</div>
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
export component MultipleTracked() {
|
|
29
|
-
let x = track(10);
|
|
30
|
-
let y = track(20);
|
|
31
|
-
let z = track(30);
|
|
32
|
-
<div class="x">{
|
|
33
|
-
<div class="y">{
|
|
34
|
-
<div class="z">{
|
|
29
|
+
let &[x] = track(10);
|
|
30
|
+
let &[y] = track(20);
|
|
31
|
+
let &[z] = track(30);
|
|
32
|
+
<div class="x">{x}</div>
|
|
33
|
+
<div class="y">{y}</div>
|
|
34
|
+
<div class="z">{z}</div>
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
export component DerivedState() {
|
|
38
|
-
let firstName = track('John');
|
|
39
|
-
let lastName = track('Doe');
|
|
40
|
-
const fullName = () => `${
|
|
38
|
+
let &[firstName] = track('John');
|
|
39
|
+
let &[lastName] = track('Doe');
|
|
40
|
+
const fullName = () => `${firstName} ${lastName}`;
|
|
41
41
|
<div class="name">{fullName()}</div>
|
|
42
42
|
}
|
|
@@ -266,17 +266,17 @@ export component ReturnWithElseBothReturn() {
|
|
|
266
266
|
|
|
267
267
|
// Reactive return - starts true, can toggle to false
|
|
268
268
|
export component ReactiveReturnTrueToFalse() {
|
|
269
|
-
let condition = track(true);
|
|
269
|
+
let &[condition] = track(true);
|
|
270
270
|
|
|
271
271
|
<button
|
|
272
272
|
class="toggle"
|
|
273
273
|
onClick={() => {
|
|
274
|
-
|
|
274
|
+
condition = !condition;
|
|
275
275
|
}}
|
|
276
276
|
>
|
|
277
277
|
{'Toggle'}
|
|
278
278
|
</button>
|
|
279
|
-
if (
|
|
279
|
+
if (condition) {
|
|
280
280
|
<div class="guard">{'guard hit'}</div>
|
|
281
281
|
return;
|
|
282
282
|
}
|
|
@@ -285,17 +285,17 @@ export component ReactiveReturnTrueToFalse() {
|
|
|
285
285
|
|
|
286
286
|
// Reactive return - starts false, can toggle to true
|
|
287
287
|
export component ReactiveReturnFalseToTrue() {
|
|
288
|
-
let condition = track(false);
|
|
288
|
+
let &[condition] = track(false);
|
|
289
289
|
|
|
290
290
|
<button
|
|
291
291
|
class="toggle"
|
|
292
292
|
onClick={() => {
|
|
293
|
-
|
|
293
|
+
condition = !condition;
|
|
294
294
|
}}
|
|
295
295
|
>
|
|
296
296
|
{'Toggle'}
|
|
297
297
|
</button>
|
|
298
|
-
if (
|
|
298
|
+
if (condition) {
|
|
299
299
|
<div class="guard">{'guard hit'}</div>
|
|
300
300
|
return;
|
|
301
301
|
}
|
|
@@ -305,19 +305,19 @@ export component ReactiveReturnFalseToTrue() {
|
|
|
305
305
|
// Reactive nested return - only inner condition (b) is tracked
|
|
306
306
|
export component ReactiveNestedReturn() {
|
|
307
307
|
let a = true;
|
|
308
|
-
let b = track(true);
|
|
308
|
+
let &[b] = track(true);
|
|
309
309
|
|
|
310
310
|
<button
|
|
311
311
|
class="toggle"
|
|
312
312
|
onClick={() => {
|
|
313
|
-
|
|
313
|
+
b = !b;
|
|
314
314
|
}}
|
|
315
315
|
>
|
|
316
316
|
{'Toggle'}
|
|
317
317
|
</button>
|
|
318
318
|
if (a) {
|
|
319
319
|
<div class="a">{'a'}</div>
|
|
320
|
-
if (
|
|
320
|
+
if (b) {
|
|
321
321
|
<div class="b">{'b'}</div>
|
|
322
322
|
return;
|
|
323
323
|
}
|
|
@@ -398,29 +398,29 @@ export component MultipleSiblingReturns() {
|
|
|
398
398
|
|
|
399
399
|
// Reactive sibling returns - cycles first -> second -> fallback
|
|
400
400
|
export component ReactiveSiblingReturns() {
|
|
401
|
-
let mode = track('first');
|
|
401
|
+
let &[mode] = track('first');
|
|
402
402
|
|
|
403
403
|
<button
|
|
404
404
|
class="toggle"
|
|
405
405
|
onClick={() => {
|
|
406
|
-
if (
|
|
407
|
-
|
|
408
|
-
} else if (
|
|
409
|
-
|
|
406
|
+
if (mode === 'first') {
|
|
407
|
+
mode = 'second';
|
|
408
|
+
} else if (mode === 'second') {
|
|
409
|
+
mode = 'none';
|
|
410
410
|
} else {
|
|
411
|
-
|
|
411
|
+
mode = 'first';
|
|
412
412
|
}
|
|
413
413
|
}}
|
|
414
414
|
>
|
|
415
415
|
{'Toggle'}
|
|
416
416
|
</button>
|
|
417
417
|
|
|
418
|
-
if (
|
|
418
|
+
if (mode === 'first') {
|
|
419
419
|
<div class="first">{'first guard'}</div>
|
|
420
420
|
return;
|
|
421
421
|
}
|
|
422
422
|
|
|
423
|
-
if (
|
|
423
|
+
if (mode === 'second') {
|
|
424
424
|
<div class="second">{'second guard'}</div>
|
|
425
425
|
return;
|
|
426
426
|
}
|
|
@@ -430,13 +430,13 @@ export component ReactiveSiblingReturns() {
|
|
|
430
430
|
|
|
431
431
|
// Reactive nested returns with tracked outer and inner conditions
|
|
432
432
|
export component ReactiveOuterInnerReturns() {
|
|
433
|
-
let a = track(true);
|
|
434
|
-
let b = track(true);
|
|
433
|
+
let &[a] = track(true);
|
|
434
|
+
let &[b] = track(true);
|
|
435
435
|
|
|
436
436
|
<button
|
|
437
437
|
class="toggle-a"
|
|
438
438
|
onClick={() => {
|
|
439
|
-
|
|
439
|
+
a = !a;
|
|
440
440
|
}}
|
|
441
441
|
>
|
|
442
442
|
{'Toggle A'}
|
|
@@ -445,40 +445,40 @@ export component ReactiveOuterInnerReturns() {
|
|
|
445
445
|
<button
|
|
446
446
|
class="toggle-b"
|
|
447
447
|
onClick={() => {
|
|
448
|
-
|
|
448
|
+
b = !b;
|
|
449
449
|
}}
|
|
450
450
|
>
|
|
451
451
|
{'Toggle B'}
|
|
452
452
|
</button>
|
|
453
453
|
|
|
454
|
-
if (
|
|
454
|
+
if (a) {
|
|
455
455
|
<div class="a">{'a'}</div>
|
|
456
|
-
if (
|
|
456
|
+
if (b) {
|
|
457
457
|
<div class="b">{'b'}</div>
|
|
458
458
|
return;
|
|
459
459
|
}
|
|
460
460
|
}
|
|
461
461
|
|
|
462
|
-
<div class="rest">{
|
|
462
|
+
<div class="rest">{a ? 'a-on rest' : 'a-off rest'}</div>
|
|
463
463
|
}
|
|
464
464
|
|
|
465
465
|
// Reactive else-if return chain that transitions between return and non-return states
|
|
466
466
|
export component ReactiveElseIfReturns() {
|
|
467
|
-
let status = track(0);
|
|
467
|
+
let &[status] = track(0);
|
|
468
468
|
|
|
469
469
|
<button
|
|
470
470
|
class="toggle"
|
|
471
471
|
onClick={() => {
|
|
472
|
-
|
|
472
|
+
status = (status + 1) % 3;
|
|
473
473
|
}}
|
|
474
474
|
>
|
|
475
475
|
{'Toggle'}
|
|
476
476
|
</button>
|
|
477
477
|
|
|
478
|
-
if (
|
|
478
|
+
if (status === 0) {
|
|
479
479
|
<div class="zero">{'zero'}</div>
|
|
480
480
|
return;
|
|
481
|
-
} else if (
|
|
481
|
+
} else if (status === 1) {
|
|
482
482
|
<div class="one">{'one'}</div>
|
|
483
483
|
return;
|
|
484
484
|
}
|
|
@@ -489,15 +489,15 @@ export component ReactiveElseIfReturns() {
|
|
|
489
489
|
|
|
490
490
|
// Deeply nested independent return guards with multiple root-level siblings
|
|
491
491
|
export component ReactiveDeepNestedIndependentReturns() {
|
|
492
|
-
let c1 = track(false);
|
|
493
|
-
let c2 = track(false);
|
|
494
|
-
let c3 = track(false);
|
|
495
|
-
let c4 = track(false);
|
|
492
|
+
let &[c1] = track(false);
|
|
493
|
+
let &[c2] = track(false);
|
|
494
|
+
let &[c3] = track(false);
|
|
495
|
+
let &[c4] = track(false);
|
|
496
496
|
|
|
497
497
|
<button
|
|
498
498
|
class="toggle-c1"
|
|
499
499
|
onClick={() => {
|
|
500
|
-
|
|
500
|
+
c1 = !c1;
|
|
501
501
|
}}
|
|
502
502
|
>
|
|
503
503
|
{'Toggle C1'}
|
|
@@ -505,7 +505,7 @@ export component ReactiveDeepNestedIndependentReturns() {
|
|
|
505
505
|
<button
|
|
506
506
|
class="toggle-c2"
|
|
507
507
|
onClick={() => {
|
|
508
|
-
|
|
508
|
+
c2 = !c2;
|
|
509
509
|
}}
|
|
510
510
|
>
|
|
511
511
|
{'Toggle C2'}
|
|
@@ -513,7 +513,7 @@ export component ReactiveDeepNestedIndependentReturns() {
|
|
|
513
513
|
<button
|
|
514
514
|
class="toggle-c3"
|
|
515
515
|
onClick={() => {
|
|
516
|
-
|
|
516
|
+
c3 = !c3;
|
|
517
517
|
}}
|
|
518
518
|
>
|
|
519
519
|
{'Toggle C3'}
|
|
@@ -521,7 +521,7 @@ export component ReactiveDeepNestedIndependentReturns() {
|
|
|
521
521
|
<button
|
|
522
522
|
class="toggle-c4"
|
|
523
523
|
onClick={() => {
|
|
524
|
-
|
|
524
|
+
c4 = !c4;
|
|
525
525
|
}}
|
|
526
526
|
>
|
|
527
527
|
{'Toggle C4'}
|
|
@@ -529,7 +529,7 @@ export component ReactiveDeepNestedIndependentReturns() {
|
|
|
529
529
|
|
|
530
530
|
<div class="top">{'top'}</div>
|
|
531
531
|
|
|
532
|
-
if (
|
|
532
|
+
if (c1) {
|
|
533
533
|
<div class="hit-1">{'hit-1'}</div>
|
|
534
534
|
return;
|
|
535
535
|
}
|
|
@@ -537,7 +537,7 @@ export component ReactiveDeepNestedIndependentReturns() {
|
|
|
537
537
|
<div class="middle">{'middle'}</div>
|
|
538
538
|
<section class="nest-1">
|
|
539
539
|
<div class="nest-1-a">{'nest-1-a'}</div>
|
|
540
|
-
if (
|
|
540
|
+
if (c2) {
|
|
541
541
|
<div class="hit-2">{'hit-2'}</div>
|
|
542
542
|
return;
|
|
543
543
|
}
|
|
@@ -545,13 +545,13 @@ export component ReactiveDeepNestedIndependentReturns() {
|
|
|
545
545
|
<div class="nest-1-b">{'nest-1-b'}</div>
|
|
546
546
|
<section class="nest-2">
|
|
547
547
|
<div class="nest-2-a">{'nest-2-a'}</div>
|
|
548
|
-
if (
|
|
548
|
+
if (c3) {
|
|
549
549
|
<div class="hit-3">{'hit-3'}</div>
|
|
550
550
|
return;
|
|
551
551
|
}
|
|
552
552
|
|
|
553
553
|
<div class="nest-2-b">{'nest-2-b'}</div>
|
|
554
|
-
if (
|
|
554
|
+
if (c4) {
|
|
555
555
|
<div class="hit-4">{'hit-4'}</div>
|
|
556
556
|
return;
|
|
557
557
|
}
|