ripple 0.3.68 → 0.3.70
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 +57 -0
- package/package.json +3 -3
- package/src/jsx-runtime.d.ts +2 -2
- package/src/runtime/element.js +1 -1
- package/src/runtime/index-client.js +11 -11
- package/src/runtime/index-server.js +7 -4
- package/src/runtime/internal/client/bindings.js +1 -1
- package/src/runtime/internal/client/blocks.js +13 -4
- package/src/runtime/internal/client/component.js +55 -0
- package/src/runtime/internal/client/composite.js +4 -2
- package/src/runtime/internal/client/expression.js +65 -7
- package/src/runtime/internal/client/hmr.js +54 -43
- package/src/runtime/internal/client/index.js +5 -1
- package/src/runtime/internal/client/portal.js +70 -69
- package/src/runtime/internal/client/render.js +3 -0
- package/src/runtime/internal/server/index.js +92 -8
- package/tests/client/__snapshots__/html.test.tsrx.snap +3 -3
- package/tests/client/array/array.copy-within.test.tsrx +33 -31
- package/tests/client/array/array.derived.test.tsrx +186 -169
- package/tests/client/array/array.iteration.test.tsrx +40 -37
- package/tests/client/array/array.mutations.test.tsrx +113 -101
- package/tests/client/array/array.static.test.tsrx +119 -101
- package/tests/client/array/array.to-methods.test.tsrx +24 -21
- package/tests/client/async-suspend.test.tsrx +247 -246
- package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +0 -1
- package/tests/client/basic/basic.attributes.test.tsrx +428 -423
- package/tests/client/basic/basic.collections.test.tsrx +109 -102
- package/tests/client/basic/basic.components.test.tsrx +323 -205
- package/tests/client/basic/basic.errors.test.tsrx +91 -91
- package/tests/client/basic/basic.events.test.tsrx +114 -115
- package/tests/client/basic/basic.get-set.test.tsrx +97 -87
- package/tests/client/basic/basic.hmr.test.tsrx +19 -16
- package/tests/client/basic/basic.reactivity.test.tsrx +199 -191
- package/tests/client/basic/basic.rendering.test.tsrx +272 -182
- package/tests/client/basic/basic.styling.test.tsrx +23 -22
- package/tests/client/basic/basic.utilities.test.tsrx +10 -8
- package/tests/client/boundaries.test.tsrx +26 -26
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +5 -5
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +5 -5
- package/tests/client/compiler/compiler.assignments.test.tsrx +77 -81
- package/tests/client/compiler/compiler.attributes.test.tsrx +15 -15
- package/tests/client/compiler/compiler.basic.test.tsrx +322 -314
- package/tests/client/compiler/compiler.regex.test.tsrx +44 -47
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +38 -38
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
- package/tests/client/compiler/compiler.typescript.test.tsrx +2 -2
- package/tests/client/composite/composite.dynamic-components.test.tsrx +47 -48
- package/tests/client/composite/composite.generics.test.tsrx +168 -192
- package/tests/client/composite/composite.props.test.tsrx +97 -81
- package/tests/client/composite/composite.reactivity.test.tsrx +177 -147
- package/tests/client/composite/composite.render.test.tsrx +122 -105
- package/tests/client/computed-properties.test.tsrx +28 -28
- package/tests/client/context.test.tsrx +21 -21
- package/tests/client/css/global-additional-cases.test.tsrx +58 -58
- package/tests/client/css/global-advanced-selectors.test.tsrx +16 -16
- package/tests/client/css/global-at-rules.test.tsrx +10 -10
- package/tests/client/css/global-basic.test.tsrx +14 -14
- package/tests/client/css/global-classes-ids.test.tsrx +14 -14
- package/tests/client/css/global-combinators.test.tsrx +10 -10
- package/tests/client/css/global-complex-nesting.test.tsrx +14 -14
- package/tests/client/css/global-edge-cases.test.tsrx +18 -18
- package/tests/client/css/global-keyframes.test.tsrx +12 -12
- package/tests/client/css/global-nested.test.tsrx +10 -10
- package/tests/client/css/global-pseudo.test.tsrx +12 -12
- package/tests/client/css/global-scoping.test.tsrx +20 -20
- package/tests/client/css/style-identifier.test.tsrx +126 -259
- package/tests/client/date.test.tsrx +146 -133
- package/tests/client/dynamic-elements.test.tsrx +398 -365
- package/tests/client/events.test.tsrx +292 -290
- package/tests/client/for.test.tsrx +156 -153
- package/tests/client/head.test.tsrx +105 -96
- package/tests/client/html.test.tsrx +122 -26
- package/tests/client/input-value.test.tsrx +1361 -1314
- package/tests/client/lazy-array.test.tsrx +16 -13
- package/tests/client/lazy-destructuring.test.tsrx +257 -213
- package/tests/client/map.test.tsrx +65 -60
- package/tests/client/media-query.test.tsrx +22 -20
- package/tests/client/object.test.tsrx +87 -81
- package/tests/client/portal.test.tsrx +57 -51
- package/tests/client/ref.test.tsrx +233 -202
- package/tests/client/return.test.tsrx +71 -2560
- package/tests/client/set.test.tsrx +54 -45
- package/tests/client/svg.test.tsrx +216 -186
- package/tests/client/switch.test.tsrx +194 -193
- package/tests/client/track-async-hydration.test.tsrx +18 -14
- package/tests/client/tracked-index-access.test.tsrx +28 -18
- package/tests/client/try.test.tsrx +675 -548
- package/tests/client/tsx.test.tsrx +373 -311
- package/tests/client/typescript-generics.test.tsrx +145 -145
- package/tests/client/url/url.derived.test.tsrx +33 -28
- package/tests/client/url/url.parsing.test.tsrx +61 -51
- package/tests/client/url/url.partial-removal.test.tsrx +56 -48
- package/tests/client/url/url.reactivity.test.tsrx +142 -125
- package/tests/client/url/url.serialization.test.tsrx +13 -11
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +34 -29
- package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +25 -21
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +50 -45
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +111 -99
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +49 -43
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +14 -12
- package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +16 -14
- package/tests/hydration/basic.test.js +3 -3
- package/tests/hydration/compiled/client/basic.js +586 -651
- package/tests/hydration/compiled/client/composite.js +79 -104
- package/tests/hydration/compiled/client/events.js +140 -148
- package/tests/hydration/compiled/client/for.js +1005 -1018
- package/tests/hydration/compiled/client/head.js +124 -134
- package/tests/hydration/compiled/client/hmr.js +41 -48
- package/tests/hydration/compiled/client/html-in-template.js +38 -41
- package/tests/hydration/compiled/client/html.js +970 -1314
- package/tests/hydration/compiled/client/if-children.js +234 -249
- package/tests/hydration/compiled/client/if.js +182 -189
- package/tests/hydration/compiled/client/mixed-control-flow.js +347 -303
- package/tests/hydration/compiled/client/nested-control-flow.js +1084 -832
- package/tests/hydration/compiled/client/portal.js +65 -85
- package/tests/hydration/compiled/client/reactivity.js +84 -90
- package/tests/hydration/compiled/client/return.js +38 -1939
- package/tests/hydration/compiled/client/switch.js +218 -224
- package/tests/hydration/compiled/client/track-async-serialization.js +250 -259
- package/tests/hydration/compiled/client/try.js +123 -132
- package/tests/hydration/compiled/server/basic.js +773 -831
- package/tests/hydration/compiled/server/composite.js +166 -191
- package/tests/hydration/compiled/server/events.js +170 -184
- package/tests/hydration/compiled/server/for.js +851 -909
- package/tests/hydration/compiled/server/head.js +206 -216
- package/tests/hydration/compiled/server/hmr.js +64 -72
- package/tests/hydration/compiled/server/html-in-template.js +42 -76
- package/tests/hydration/compiled/server/html.js +1362 -1667
- package/tests/hydration/compiled/server/if-children.js +419 -445
- package/tests/hydration/compiled/server/if.js +194 -208
- package/tests/hydration/compiled/server/mixed-control-flow.js +249 -257
- package/tests/hydration/compiled/server/nested-control-flow.js +491 -515
- package/tests/hydration/compiled/server/portal.js +152 -160
- package/tests/hydration/compiled/server/reactivity.js +94 -106
- package/tests/hydration/compiled/server/return.js +28 -2172
- package/tests/hydration/compiled/server/switch.js +274 -286
- package/tests/hydration/compiled/server/track-async-serialization.js +340 -358
- package/tests/hydration/compiled/server/try.js +167 -185
- package/tests/hydration/components/basic.tsrx +320 -272
- package/tests/hydration/components/composite.tsrx +44 -32
- package/tests/hydration/components/events.tsrx +101 -91
- package/tests/hydration/components/for.tsrx +510 -452
- package/tests/hydration/components/head.tsrx +87 -80
- package/tests/hydration/components/hmr.tsrx +22 -17
- package/tests/hydration/components/html-in-template.tsrx +22 -17
- package/tests/hydration/components/html.tsrx +525 -443
- package/tests/hydration/components/if-children.tsrx +158 -148
- package/tests/hydration/components/if.tsrx +109 -95
- package/tests/hydration/components/mixed-control-flow.tsrx +100 -96
- package/tests/hydration/components/nested-control-flow.tsrx +215 -203
- package/tests/hydration/components/portal.tsrx +41 -34
- package/tests/hydration/components/reactivity.tsrx +37 -27
- package/tests/hydration/components/return.tsrx +12 -556
- package/tests/hydration/components/switch.tsrx +120 -114
- package/tests/hydration/components/track-async-serialization.tsrx +107 -91
- package/tests/hydration/components/try.tsrx +55 -40
- package/tests/hydration/html.test.js +4 -4
- package/tests/hydration/return.test.js +13 -532
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +264 -195
- package/tests/server/basic.components.test.tsrx +296 -169
- package/tests/server/basic.test.tsrx +300 -198
- package/tests/server/compiler.test.tsrx +62 -60
- package/tests/server/composite.props.test.tsrx +77 -63
- package/tests/server/composite.test.tsrx +168 -192
- package/tests/server/context.test.tsrx +18 -12
- package/tests/server/dynamic-elements.test.tsrx +197 -180
- package/tests/server/for.test.tsrx +85 -78
- package/tests/server/head.test.tsrx +50 -43
- package/tests/server/html-nesting-validation.test.tsrx +8 -8
- package/tests/server/if.test.tsrx +57 -51
- package/tests/server/lazy-destructuring.test.tsrx +366 -294
- package/tests/server/return.test.tsrx +76 -1355
- package/tests/server/streaming-ssr.test.tsrx +4 -75
- package/tests/server/style-identifier.test.tsrx +169 -131
- package/tests/server/switch.test.tsrx +91 -85
- package/tests/server/track-async-serialization.test.tsrx +105 -85
- package/tests/server/try.test.tsrx +374 -280
- package/tests/utils/compiler-compat-config.test.js +2 -2
- package/tests/utils/runtime-imports.test.js +10 -0
- package/types/index.d.ts +8 -0
- package/tests/client/__snapshots__/html.test.rsrx.snap +0 -40
|
@@ -3,191 +3,201 @@ import { track } from 'ripple';
|
|
|
3
3
|
// Minimal repro for hydration issue with if block containing children
|
|
4
4
|
// Based on SidebarGroup pattern from website-new
|
|
5
5
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
export function IfWithChildren({ children }: { children: any }) {
|
|
7
|
+
return <>
|
|
8
|
+
let &[expanded] = track(true);
|
|
9
|
+
<div class="container">
|
|
10
|
+
<div class="header" role="button" onClick={() => (expanded = !expanded)}>{'Toggle'}</div>
|
|
11
|
+
if (expanded) {
|
|
12
|
+
<div class="content">{children}</div>
|
|
13
|
+
}
|
|
14
|
+
</div>
|
|
15
|
+
</>;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
export
|
|
18
|
-
|
|
18
|
+
export function ChildItem({ text: label }: { text: string }) {
|
|
19
|
+
return <><div class="item">{label}</div></>;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
export
|
|
22
|
-
|
|
23
|
-
<
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
export function TestIfWithChildren() {
|
|
23
|
+
return <>
|
|
24
|
+
<IfWithChildren>
|
|
25
|
+
<ChildItem text="Item 1" />
|
|
26
|
+
<ChildItem text="Item 2" />
|
|
27
|
+
</IfWithChildren>
|
|
28
|
+
</>;
|
|
26
29
|
}
|
|
27
30
|
|
|
28
31
|
// Simpler variant - if block with static children
|
|
29
|
-
export
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
export function IfWithStaticChildren() {
|
|
33
|
+
return <>
|
|
34
|
+
let &[expanded] = track(true);
|
|
35
|
+
<div class="container">
|
|
36
|
+
<div class="header" role="button" onClick={() => (expanded = !expanded)}>{'Toggle'}</div>
|
|
37
|
+
if (expanded) {
|
|
38
|
+
<div class="content">
|
|
39
|
+
<span>{'Static child 1'}</span>
|
|
40
|
+
<span>{'Static child 2'}</span>
|
|
41
|
+
</div>
|
|
42
|
+
}
|
|
43
|
+
</div>
|
|
44
|
+
</>;
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
// Variant with sibling elements before the if block (like SidebarGroup)
|
|
44
|
-
export
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
48
|
+
export function IfWithSiblingsAndChildren({ children }: { children: any }) {
|
|
49
|
+
return <>
|
|
50
|
+
let &[expanded] = track(true);
|
|
51
|
+
<section class="group">
|
|
52
|
+
<div class="item" role="button" onClick={() => (expanded = !expanded)}>
|
|
53
|
+
<div class="indicator" />
|
|
54
|
+
<h2 class="text">{'Title'}</h2>
|
|
55
|
+
<div class="caret">
|
|
56
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24">
|
|
57
|
+
<path d="m9 18 6-6-6-6" />
|
|
58
|
+
</svg>
|
|
59
|
+
</div>
|
|
55
60
|
</div>
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
if (expanded) {
|
|
62
|
+
<div class="items">{children}</div>
|
|
63
|
+
}
|
|
64
|
+
</section>
|
|
65
|
+
</>;
|
|
61
66
|
}
|
|
62
67
|
|
|
63
|
-
export
|
|
64
|
-
|
|
65
|
-
<
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
export function TestIfWithSiblingsAndChildren() {
|
|
69
|
+
return <>
|
|
70
|
+
<IfWithSiblingsAndChildren>
|
|
71
|
+
<ChildItem text="Item A" />
|
|
72
|
+
<ChildItem text="Item B" />
|
|
73
|
+
</IfWithSiblingsAndChildren>
|
|
74
|
+
</>;
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
// Test case for hydration pop bug: element with nested children followed by dynamic if sibling
|
|
71
78
|
// This tests that hydrate_node is properly restored after processing an element's children
|
|
72
79
|
// before navigating to a dynamic sibling (if/for/switch)
|
|
73
|
-
export
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
export function ElementWithChildrenThenIf() {
|
|
81
|
+
return <>
|
|
82
|
+
let &[show] = track(true);
|
|
83
|
+
<div class="wrapper">
|
|
84
|
+
<div class="nested-parent">
|
|
85
|
+
<div class="nested-child">
|
|
86
|
+
<span class="deep">{'Deep content'}</span>
|
|
87
|
+
</div>
|
|
80
88
|
</div>
|
|
89
|
+
if (show) {
|
|
90
|
+
<div class="conditional">{'Conditional content'}</div>
|
|
91
|
+
}
|
|
81
92
|
</div>
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
</div>
|
|
86
|
-
|
|
87
|
-
<button class="toggle" onClick={() => (show = !show)}>{'Toggle'}</button>
|
|
93
|
+
<button class="toggle" onClick={() => (show = !show)}>{'Toggle'}</button>
|
|
94
|
+
</>;
|
|
88
95
|
}
|
|
89
96
|
|
|
90
97
|
// More complex: multiple levels of nesting before if sibling
|
|
91
|
-
export
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
98
|
+
export function DeepNestingThenIf() {
|
|
99
|
+
return <>
|
|
100
|
+
let &[visible] = track(true);
|
|
101
|
+
<section class="outer">
|
|
102
|
+
<article class="middle">
|
|
103
|
+
<div class="inner">
|
|
104
|
+
<p class="leaf">
|
|
105
|
+
<strong>{'Bold'}</strong>
|
|
106
|
+
<em>{'Italic'}</em>
|
|
107
|
+
</p>
|
|
108
|
+
</div>
|
|
109
|
+
</article>
|
|
110
|
+
if (visible) {
|
|
111
|
+
<footer class="footer">{'Footer'}</footer>
|
|
112
|
+
}
|
|
113
|
+
</section>
|
|
114
|
+
<button class="btn" onClick={() => (visible = !visible)}>{'Toggle'}</button>
|
|
115
|
+
</>;
|
|
109
116
|
}
|
|
110
117
|
|
|
111
118
|
// Test case for CodeBlock pattern: element with only DOM element children (like buttons)
|
|
112
119
|
// followed by another sibling element. This requires pop() to restore hydrate_node
|
|
113
120
|
// because we descend into the first element to get the button children.
|
|
114
|
-
export
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
121
|
+
export function DomElementChildrenThenSibling() {
|
|
122
|
+
return <>
|
|
123
|
+
let &[activeTab] = track('code');
|
|
124
|
+
<div class="tabs">
|
|
125
|
+
<div class="tab-list">
|
|
126
|
+
<button
|
|
127
|
+
class="tab"
|
|
128
|
+
aria-selected={activeTab === 'code' ? 'true' : 'false'}
|
|
129
|
+
onClick={() => (activeTab = 'code')}
|
|
130
|
+
>
|
|
131
|
+
{'Code'}
|
|
132
|
+
</button>
|
|
133
|
+
<button
|
|
134
|
+
class="tab"
|
|
135
|
+
aria-selected={activeTab === 'preview' ? 'true' : 'false'}
|
|
136
|
+
onClick={() => (activeTab = 'preview')}
|
|
137
|
+
>
|
|
138
|
+
{'Preview'}
|
|
139
|
+
</button>
|
|
140
|
+
</div>
|
|
141
|
+
<div class="panel">
|
|
142
|
+
if (activeTab === 'code') {
|
|
143
|
+
<pre class="code">{'const x = 1;'}</pre>
|
|
144
|
+
} else {
|
|
145
|
+
<div class="preview">{'Preview content'}</div>
|
|
146
|
+
}
|
|
147
|
+
</div>
|
|
140
148
|
</div>
|
|
141
|
-
|
|
149
|
+
</>;
|
|
142
150
|
}
|
|
143
151
|
|
|
144
152
|
// Test case for element with DOM children followed by static siblings that don't
|
|
145
153
|
// generate sibling() calls. This was causing incorrect pop() generation before next().
|
|
146
154
|
// Pattern: <ul> with dynamic <li> children -> static <h2> -> static <p> -> next()
|
|
147
|
-
export
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
155
|
+
export function DomChildrenThenStaticSiblings() {
|
|
156
|
+
return <>
|
|
157
|
+
let &[count] = track(0);
|
|
158
|
+
<div class="container">
|
|
159
|
+
<ul class="list">
|
|
160
|
+
<li class="item">
|
|
161
|
+
{'Item count: '}
|
|
162
|
+
{count}
|
|
163
|
+
</li>
|
|
164
|
+
<li class="item">{'Another item'}</li>
|
|
165
|
+
</ul>
|
|
166
|
+
<h2 class="heading">{'Static Heading'}</h2>
|
|
167
|
+
<p class="para">{'Static paragraph'}</p>
|
|
168
|
+
</div>
|
|
169
|
+
<button class="inc" onClick={() => count++}>{'Increment'}</button>
|
|
170
|
+
</>;
|
|
163
171
|
}
|
|
164
172
|
|
|
165
173
|
// Test case for completely static element children followed by static siblings.
|
|
166
174
|
// Pattern from introduction page: <ul> with static <li> (strong, code, text)
|
|
167
175
|
// followed by static <h2> and <p>. No pop() should be generated for these.
|
|
168
|
-
export
|
|
169
|
-
|
|
170
|
-
<
|
|
171
|
-
<
|
|
172
|
-
<
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
<
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
<
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
176
|
+
export function StaticListThenStaticSiblings() {
|
|
177
|
+
return <>
|
|
178
|
+
<div class="wrapper">
|
|
179
|
+
<ul class="features">
|
|
180
|
+
<li>
|
|
181
|
+
<strong>{'Feature One'}</strong>
|
|
182
|
+
{': Description of feature one with '}
|
|
183
|
+
<code>{'code'}</code>
|
|
184
|
+
{' reference'}
|
|
185
|
+
</li>
|
|
186
|
+
<li>
|
|
187
|
+
<strong>{'Feature Two'}</strong>
|
|
188
|
+
{': Another feature description'}
|
|
189
|
+
</li>
|
|
190
|
+
<li>
|
|
191
|
+
<strong>{'Feature Three'}</strong>
|
|
192
|
+
{': Third feature'}
|
|
193
|
+
</li>
|
|
194
|
+
</ul>
|
|
195
|
+
<h2 class="section-heading">{'Section Heading'}</h2>
|
|
196
|
+
<p class="section-content">
|
|
197
|
+
{'Static paragraph with '}
|
|
198
|
+
<a href="/link">{'a link'}</a>
|
|
199
|
+
{' and more text.'}
|
|
200
|
+
</p>
|
|
201
|
+
</div>
|
|
202
|
+
</>;
|
|
193
203
|
}
|
|
@@ -2,123 +2,137 @@ import { track } from 'ripple';
|
|
|
2
2
|
|
|
3
3
|
// If block components for hydration testing
|
|
4
4
|
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export component IfFalsy() {
|
|
13
|
-
const show = false;
|
|
14
|
-
if (show) {
|
|
15
|
-
<div class="shown">{'Visible'}</div>
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export component IfElse() {
|
|
20
|
-
const isLoggedIn = true;
|
|
21
|
-
if (isLoggedIn) {
|
|
22
|
-
<div class="logged-in">{'Welcome back!'}</div>
|
|
23
|
-
} else {
|
|
24
|
-
<div class="logged-out">{'Please log in'}</div>
|
|
25
|
-
}
|
|
5
|
+
export function IfTruthy() {
|
|
6
|
+
return <>
|
|
7
|
+
const show = true;
|
|
8
|
+
if (show) {
|
|
9
|
+
<div class="shown">{'Visible'}</div>
|
|
10
|
+
}
|
|
11
|
+
</>;
|
|
26
12
|
}
|
|
27
13
|
|
|
28
|
-
export
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
>
|
|
36
|
-
{'Toggle'}
|
|
37
|
-
</button>
|
|
38
|
-
if (show) {
|
|
39
|
-
<div class="content">{'Content visible'}</div>
|
|
40
|
-
}
|
|
14
|
+
export function IfFalsy() {
|
|
15
|
+
return <>
|
|
16
|
+
const show = false;
|
|
17
|
+
if (show) {
|
|
18
|
+
<div class="shown">{'Visible'}</div>
|
|
19
|
+
}
|
|
20
|
+
</>;
|
|
41
21
|
}
|
|
42
22
|
|
|
43
|
-
export
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
</button>
|
|
53
|
-
if (isOn) {
|
|
54
|
-
<div class="on">{'ON'}</div>
|
|
55
|
-
} else {
|
|
56
|
-
<div class="off">{'OFF'}</div>
|
|
57
|
-
}
|
|
23
|
+
export function IfElse() {
|
|
24
|
+
return <>
|
|
25
|
+
const isLoggedIn = true;
|
|
26
|
+
if (isLoggedIn) {
|
|
27
|
+
<div class="logged-in">{'Welcome back!'}</div>
|
|
28
|
+
} else {
|
|
29
|
+
<div class="logged-out">{'Please log in'}</div>
|
|
30
|
+
}
|
|
31
|
+
</>;
|
|
58
32
|
}
|
|
59
33
|
|
|
60
|
-
export
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
}}
|
|
76
|
-
>
|
|
77
|
-
{'Inner'}
|
|
78
|
-
</button>
|
|
79
|
-
if (outer) {
|
|
80
|
-
<div class="outer-content">
|
|
81
|
-
{'Outer'}
|
|
82
|
-
if (inner) {
|
|
83
|
-
<span class="inner-content">{'Inner'}</span>
|
|
84
|
-
}
|
|
85
|
-
</div>
|
|
86
|
-
}
|
|
34
|
+
export function ReactiveIf() {
|
|
35
|
+
return <>
|
|
36
|
+
let &[show] = track(true);
|
|
37
|
+
<button
|
|
38
|
+
class="toggle"
|
|
39
|
+
onClick={() => {
|
|
40
|
+
show = !show;
|
|
41
|
+
}}
|
|
42
|
+
>
|
|
43
|
+
{'Toggle'}
|
|
44
|
+
</button>
|
|
45
|
+
if (show) {
|
|
46
|
+
<div class="content">{'Content visible'}</div>
|
|
47
|
+
}
|
|
48
|
+
</>;
|
|
87
49
|
}
|
|
88
50
|
|
|
89
|
-
export
|
|
90
|
-
|
|
91
|
-
|
|
51
|
+
export function ReactiveIfElse() {
|
|
52
|
+
return <>
|
|
53
|
+
let &[isOn] = track(false);
|
|
92
54
|
<button
|
|
93
|
-
class="
|
|
55
|
+
class="toggle"
|
|
94
56
|
onClick={() => {
|
|
95
|
-
|
|
57
|
+
isOn = !isOn;
|
|
96
58
|
}}
|
|
97
59
|
>
|
|
98
|
-
{'
|
|
60
|
+
{'Toggle'}
|
|
99
61
|
</button>
|
|
62
|
+
if (isOn) {
|
|
63
|
+
<div class="on">{'ON'}</div>
|
|
64
|
+
} else {
|
|
65
|
+
<div class="off">{'OFF'}</div>
|
|
66
|
+
}
|
|
67
|
+
</>;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function NestedIf() {
|
|
71
|
+
return <>
|
|
72
|
+
let &[outer] = track(true);
|
|
73
|
+
let &[inner] = track(true);
|
|
100
74
|
<button
|
|
101
|
-
class="
|
|
75
|
+
class="outer-toggle"
|
|
102
76
|
onClick={() => {
|
|
103
|
-
|
|
77
|
+
outer = !outer;
|
|
104
78
|
}}
|
|
105
79
|
>
|
|
106
|
-
{'
|
|
80
|
+
{'Outer'}
|
|
107
81
|
</button>
|
|
108
82
|
<button
|
|
109
|
-
class="
|
|
83
|
+
class="inner-toggle"
|
|
110
84
|
onClick={() => {
|
|
111
|
-
|
|
85
|
+
inner = !inner;
|
|
112
86
|
}}
|
|
113
87
|
>
|
|
114
|
-
{'
|
|
88
|
+
{'Inner'}
|
|
115
89
|
</button>
|
|
116
|
-
if (
|
|
117
|
-
<div class="
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
90
|
+
if (outer) {
|
|
91
|
+
<div class="outer-content">
|
|
92
|
+
{'Outer'}
|
|
93
|
+
if (inner) {
|
|
94
|
+
<span class="inner-content">{'Inner'}</span>
|
|
95
|
+
}
|
|
96
|
+
</div>
|
|
122
97
|
}
|
|
123
|
-
|
|
98
|
+
</>;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function IfElseIfChain() {
|
|
102
|
+
return <>
|
|
103
|
+
let &[status] = track<'loading' | 'success' | 'error'>('loading');
|
|
104
|
+
<div>
|
|
105
|
+
<button
|
|
106
|
+
class="success"
|
|
107
|
+
onClick={() => {
|
|
108
|
+
status = 'success';
|
|
109
|
+
}}
|
|
110
|
+
>
|
|
111
|
+
{'Success'}
|
|
112
|
+
</button>
|
|
113
|
+
<button
|
|
114
|
+
class="error"
|
|
115
|
+
onClick={() => {
|
|
116
|
+
status = 'error';
|
|
117
|
+
}}
|
|
118
|
+
>
|
|
119
|
+
{'Error'}
|
|
120
|
+
</button>
|
|
121
|
+
<button
|
|
122
|
+
class="loading"
|
|
123
|
+
onClick={() => {
|
|
124
|
+
status = 'loading';
|
|
125
|
+
}}
|
|
126
|
+
>
|
|
127
|
+
{'Loading'}
|
|
128
|
+
</button>
|
|
129
|
+
if (status === 'loading') {
|
|
130
|
+
<div class="state">{'Loading...'}</div>
|
|
131
|
+
} else if (status === 'success') {
|
|
132
|
+
<div class="state">{'Success!'}</div>
|
|
133
|
+
} else {
|
|
134
|
+
<div class="state">{'Error occurred'}</div>
|
|
135
|
+
}
|
|
136
|
+
</div>
|
|
137
|
+
</>;
|
|
124
138
|
}
|