ripple 0.3.9 → 0.3.11
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 +43 -0
- package/package.json +2 -2
- package/src/compiler/errors.js +1 -1
- package/src/compiler/index.d.ts +3 -1
- package/src/compiler/phases/1-parse/index.js +195 -23
- package/src/compiler/phases/2-analyze/index.js +266 -108
- package/src/compiler/phases/2-analyze/prune.js +13 -5
- package/src/compiler/phases/3-transform/client/index.js +304 -80
- package/src/compiler/phases/3-transform/server/index.js +108 -43
- package/src/compiler/types/index.d.ts +28 -3
- package/src/compiler/types/parse.d.ts +3 -1
- package/src/compiler/utils.js +275 -1
- package/src/runtime/element.js +39 -0
- package/src/runtime/index-client.js +14 -4
- package/src/runtime/internal/client/composite.js +10 -6
- package/src/runtime/internal/client/expression.js +280 -0
- package/src/runtime/internal/client/index.js +4 -0
- package/src/runtime/internal/client/portal.js +12 -6
- package/src/runtime/internal/server/index.js +26 -1
- package/src/utils/builders.js +30 -0
- package/tests/client/basic/__snapshots__/basic.rendering.test.ripple.snap +1 -0
- package/tests/client/basic/basic.components.test.ripple +85 -87
- package/tests/client/basic/basic.errors.test.ripple +4 -8
- package/tests/client/basic/basic.rendering.test.ripple +27 -10
- package/tests/client/capture-error.js +12 -0
- package/tests/client/compiler/compiler.basic.test.ripple +76 -6
- package/tests/client/composite/composite.props.test.ripple +1 -3
- package/tests/client/composite/composite.render.test.ripple +91 -13
- package/tests/client/css/global-additional-cases.test.ripple +3 -3
- package/tests/client/return.test.ripple +101 -0
- package/tests/client/svg.test.ripple +4 -4
- package/tests/client/tsx.test.ripple +486 -0
- package/tests/hydration/basic.test.js +23 -0
- package/tests/hydration/compiled/client/basic.js +111 -75
- package/tests/hydration/compiled/client/composite.js +81 -46
- package/tests/hydration/compiled/client/events.js +18 -63
- package/tests/hydration/compiled/client/for.js +90 -183
- package/tests/hydration/compiled/client/head.js +10 -25
- package/tests/hydration/compiled/client/hmr.js +10 -13
- package/tests/hydration/compiled/client/html.js +251 -380
- package/tests/hydration/compiled/client/if-children.js +35 -45
- package/tests/hydration/compiled/client/if.js +2 -2
- package/tests/hydration/compiled/client/mixed-control-flow.js +24 -72
- package/tests/hydration/compiled/client/nested-control-flow.js +115 -391
- package/tests/hydration/compiled/client/portal.js +8 -20
- package/tests/hydration/compiled/client/reactivity.js +14 -47
- package/tests/hydration/compiled/client/return.js +2 -5
- package/tests/hydration/compiled/client/try.js +4 -4
- package/tests/hydration/compiled/server/basic.js +64 -31
- package/tests/hydration/compiled/server/composite.js +62 -29
- package/tests/hydration/compiled/server/hmr.js +24 -37
- package/tests/hydration/compiled/server/html.js +472 -611
- package/tests/hydration/compiled/server/if-children.js +77 -103
- package/tests/hydration/compiled/server/portal.js +8 -8
- package/tests/hydration/components/basic.ripple +15 -5
- package/tests/hydration/components/composite.ripple +13 -1
- package/tests/hydration/components/hmr.ripple +1 -3
- package/tests/hydration/components/html.ripple +13 -35
- package/tests/hydration/components/if-children.ripple +4 -8
- package/tests/hydration/composite.test.js +11 -0
- package/tests/server/basic.attributes.test.ripple +50 -0
- package/tests/server/basic.components.test.ripple +22 -28
- package/tests/server/basic.test.ripple +12 -0
- package/tests/server/compiler.test.ripple +25 -8
- package/tests/server/composite.props.test.ripple +1 -3
- package/tests/server/style-identifier.test.ripple +2 -4
- package/tests/utils/compiler-compat-config.test.js +38 -0
- package/tests/utils/vite-plugin-config.test.js +113 -0
- package/tsconfig.typecheck.json +2 -1
- package/types/index.d.ts +8 -11
|
@@ -3,68 +3,55 @@ import * as _$_ from 'ripple/internal/server';
|
|
|
3
3
|
|
|
4
4
|
import { track } from 'ripple/server';
|
|
5
5
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export function IfWithChildren(__output, { children }) {
|
|
7
|
+
_$_.push_component();
|
|
8
|
+
|
|
9
|
+
let lazy = _$_.track(true);
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
__output.push('<div');
|
|
12
|
+
__output.push(' class="container"');
|
|
13
|
+
__output.push('>');
|
|
11
14
|
|
|
15
|
+
{
|
|
12
16
|
__output.push('<div');
|
|
13
|
-
__output.push('
|
|
17
|
+
__output.push(' role="button"');
|
|
18
|
+
__output.push(' class="header"');
|
|
14
19
|
__output.push('>');
|
|
15
20
|
|
|
16
21
|
{
|
|
22
|
+
__output.push('Toggle');
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
__output.push('</div>');
|
|
26
|
+
__output.push('<!--[-->');
|
|
27
|
+
|
|
28
|
+
if (_$_.get(lazy)) {
|
|
17
29
|
__output.push('<div');
|
|
18
|
-
__output.push('
|
|
19
|
-
__output.push(' class="header"');
|
|
30
|
+
__output.push(' class="content"');
|
|
20
31
|
__output.push('>');
|
|
21
32
|
|
|
22
33
|
{
|
|
23
|
-
|
|
34
|
+
_$_.render_expression(__output, children);
|
|
24
35
|
}
|
|
25
36
|
|
|
26
37
|
__output.push('</div>');
|
|
27
|
-
__output.push('<!--[-->');
|
|
28
|
-
|
|
29
|
-
if (_$_.get(lazy)) {
|
|
30
|
-
__output.push('<div');
|
|
31
|
-
__output.push(' class="content"');
|
|
32
|
-
__output.push('>');
|
|
33
|
-
|
|
34
|
-
{
|
|
35
|
-
{
|
|
36
|
-
const comp = children;
|
|
37
|
-
const args = [__output, {}];
|
|
38
|
-
|
|
39
|
-
if (comp?.async) {
|
|
40
|
-
await comp(...args);
|
|
41
|
-
} else if (comp) {
|
|
42
|
-
comp(...args);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
__output.push('</div>');
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
__output.push('<!--]-->');
|
|
51
38
|
}
|
|
52
39
|
|
|
53
|
-
__output.push('
|
|
54
|
-
|
|
55
|
-
});
|
|
56
|
-
}
|
|
40
|
+
__output.push('<!--]-->');
|
|
41
|
+
}
|
|
57
42
|
|
|
58
|
-
|
|
43
|
+
__output.push('</div>');
|
|
44
|
+
_$_.pop_component();
|
|
45
|
+
}
|
|
59
46
|
|
|
60
|
-
export function ChildItem(__output, { text }) {
|
|
47
|
+
export function ChildItem(__output, { text: label }) {
|
|
61
48
|
_$_.push_component();
|
|
62
49
|
__output.push('<div');
|
|
63
50
|
__output.push(' class="item"');
|
|
64
51
|
__output.push('>');
|
|
65
52
|
|
|
66
53
|
{
|
|
67
|
-
__output.push(_$_.escape(
|
|
54
|
+
__output.push(_$_.escape(label));
|
|
68
55
|
}
|
|
69
56
|
|
|
70
57
|
__output.push('</div>');
|
|
@@ -80,7 +67,7 @@ export function TestIfWithChildren(__output) {
|
|
|
80
67
|
const args = [
|
|
81
68
|
__output,
|
|
82
69
|
{
|
|
83
|
-
children: function
|
|
70
|
+
children: _$_.ripple_element(function render_children(__output) {
|
|
84
71
|
_$_.push_component();
|
|
85
72
|
|
|
86
73
|
{
|
|
@@ -98,7 +85,7 @@ export function TestIfWithChildren(__output) {
|
|
|
98
85
|
}
|
|
99
86
|
|
|
100
87
|
_$_.pop_component();
|
|
101
|
-
}
|
|
88
|
+
})
|
|
102
89
|
}
|
|
103
90
|
];
|
|
104
91
|
|
|
@@ -164,94 +151,81 @@ export function IfWithStaticChildren(__output) {
|
|
|
164
151
|
_$_.pop_component();
|
|
165
152
|
}
|
|
166
153
|
|
|
167
|
-
export
|
|
168
|
-
|
|
169
|
-
|
|
154
|
+
export function IfWithSiblingsAndChildren(__output, { children }) {
|
|
155
|
+
_$_.push_component();
|
|
156
|
+
|
|
157
|
+
let lazy_2 = _$_.track(true);
|
|
170
158
|
|
|
171
|
-
|
|
159
|
+
__output.push('<section');
|
|
160
|
+
__output.push(' class="group"');
|
|
161
|
+
__output.push('>');
|
|
172
162
|
|
|
173
|
-
|
|
174
|
-
__output.push('
|
|
163
|
+
{
|
|
164
|
+
__output.push('<div');
|
|
165
|
+
__output.push(' role="button"');
|
|
166
|
+
__output.push(' class="item"');
|
|
175
167
|
__output.push('>');
|
|
176
168
|
|
|
177
169
|
{
|
|
178
170
|
__output.push('<div');
|
|
179
|
-
__output.push('
|
|
180
|
-
__output.push('
|
|
171
|
+
__output.push(' class="indicator"');
|
|
172
|
+
__output.push('>');
|
|
173
|
+
__output.push('</div>');
|
|
174
|
+
__output.push('<h2');
|
|
175
|
+
__output.push(' class="text"');
|
|
181
176
|
__output.push('>');
|
|
182
177
|
|
|
183
178
|
{
|
|
184
|
-
__output.push('
|
|
185
|
-
|
|
186
|
-
__output.push('>');
|
|
187
|
-
__output.push('</div>');
|
|
188
|
-
__output.push('<h2');
|
|
189
|
-
__output.push(' class="text"');
|
|
190
|
-
__output.push('>');
|
|
179
|
+
__output.push('Title');
|
|
180
|
+
}
|
|
191
181
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
182
|
+
__output.push('</h2>');
|
|
183
|
+
__output.push('<div');
|
|
184
|
+
__output.push(' class="caret"');
|
|
185
|
+
__output.push('>');
|
|
195
186
|
|
|
196
|
-
|
|
197
|
-
__output.push('<
|
|
198
|
-
__output.push('
|
|
187
|
+
{
|
|
188
|
+
__output.push('<svg');
|
|
189
|
+
__output.push(' xmlns="http://www.w3.org/2000/svg"');
|
|
190
|
+
__output.push(' width="18"');
|
|
191
|
+
__output.push(' height="18"');
|
|
192
|
+
__output.push(' viewBox="0 0 24 24"');
|
|
199
193
|
__output.push('>');
|
|
200
194
|
|
|
201
195
|
{
|
|
202
|
-
__output.push('<
|
|
203
|
-
__output.push('
|
|
204
|
-
__output.push(' width="18"');
|
|
205
|
-
__output.push(' height="18"');
|
|
206
|
-
__output.push(' viewBox="0 0 24 24"');
|
|
196
|
+
__output.push('<path');
|
|
197
|
+
__output.push(' d="m9 18 6-6-6-6"');
|
|
207
198
|
__output.push('>');
|
|
208
|
-
|
|
209
|
-
{
|
|
210
|
-
__output.push('<path');
|
|
211
|
-
__output.push(' d="m9 18 6-6-6-6"');
|
|
212
|
-
__output.push('>');
|
|
213
|
-
__output.push('</path>');
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
__output.push('</svg>');
|
|
199
|
+
__output.push('</path>');
|
|
217
200
|
}
|
|
218
201
|
|
|
219
|
-
__output.push('</
|
|
202
|
+
__output.push('</svg>');
|
|
220
203
|
}
|
|
221
204
|
|
|
222
205
|
__output.push('</div>');
|
|
223
|
-
|
|
206
|
+
}
|
|
224
207
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
__output.push(' class="items"');
|
|
228
|
-
__output.push('>');
|
|
208
|
+
__output.push('</div>');
|
|
209
|
+
__output.push('<!--[-->');
|
|
229
210
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
if (comp?.async) {
|
|
236
|
-
await comp(...args);
|
|
237
|
-
} else if (comp) {
|
|
238
|
-
comp(...args);
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
}
|
|
211
|
+
if (_$_.get(lazy_2)) {
|
|
212
|
+
__output.push('<div');
|
|
213
|
+
__output.push(' class="items"');
|
|
214
|
+
__output.push('>');
|
|
242
215
|
|
|
243
|
-
|
|
216
|
+
{
|
|
217
|
+
_$_.render_expression(__output, children);
|
|
244
218
|
}
|
|
245
219
|
|
|
246
|
-
__output.push('
|
|
220
|
+
__output.push('</div>');
|
|
247
221
|
}
|
|
248
222
|
|
|
249
|
-
__output.push('
|
|
250
|
-
|
|
251
|
-
});
|
|
252
|
-
}
|
|
223
|
+
__output.push('<!--]-->');
|
|
224
|
+
}
|
|
253
225
|
|
|
254
|
-
|
|
226
|
+
__output.push('</section>');
|
|
227
|
+
_$_.pop_component();
|
|
228
|
+
}
|
|
255
229
|
|
|
256
230
|
export function TestIfWithSiblingsAndChildren(__output) {
|
|
257
231
|
_$_.push_component();
|
|
@@ -262,7 +236,7 @@ export function TestIfWithSiblingsAndChildren(__output) {
|
|
|
262
236
|
const args = [
|
|
263
237
|
__output,
|
|
264
238
|
{
|
|
265
|
-
children: function
|
|
239
|
+
children: _$_.ripple_element(function render_children(__output) {
|
|
266
240
|
_$_.push_component();
|
|
267
241
|
|
|
268
242
|
{
|
|
@@ -280,7 +254,7 @@ export function TestIfWithSiblingsAndChildren(__output) {
|
|
|
280
254
|
}
|
|
281
255
|
|
|
282
256
|
_$_.pop_component();
|
|
283
|
-
}
|
|
257
|
+
})
|
|
284
258
|
}
|
|
285
259
|
];
|
|
286
260
|
|
|
@@ -27,7 +27,7 @@ export async function SimplePortal(__output) {
|
|
|
27
27
|
__output,
|
|
28
28
|
{
|
|
29
29
|
target: typeof document !== 'undefined' ? document.body : null,
|
|
30
|
-
children: function
|
|
30
|
+
children: _$_.ripple_element(function render_children(__output) {
|
|
31
31
|
_$_.push_component();
|
|
32
32
|
__output.push('<div');
|
|
33
33
|
__output.push(' class="portal-content"');
|
|
@@ -39,7 +39,7 @@ export async function SimplePortal(__output) {
|
|
|
39
39
|
|
|
40
40
|
__output.push('</div>');
|
|
41
41
|
_$_.pop_component();
|
|
42
|
-
}
|
|
42
|
+
})
|
|
43
43
|
}
|
|
44
44
|
];
|
|
45
45
|
|
|
@@ -88,7 +88,7 @@ export async function ConditionalPortal(__output) {
|
|
|
88
88
|
__output,
|
|
89
89
|
{
|
|
90
90
|
target: typeof document !== 'undefined' ? document.body : null,
|
|
91
|
-
children: function
|
|
91
|
+
children: _$_.ripple_element(function render_children(__output) {
|
|
92
92
|
_$_.push_component();
|
|
93
93
|
__output.push('<div');
|
|
94
94
|
__output.push(' class="portal-content"');
|
|
@@ -100,7 +100,7 @@ export async function ConditionalPortal(__output) {
|
|
|
100
100
|
|
|
101
101
|
__output.push('</div>');
|
|
102
102
|
_$_.pop_component();
|
|
103
|
-
}
|
|
103
|
+
})
|
|
104
104
|
}
|
|
105
105
|
];
|
|
106
106
|
|
|
@@ -146,7 +146,7 @@ export async function PortalWithMainContent(__output) {
|
|
|
146
146
|
__output,
|
|
147
147
|
{
|
|
148
148
|
target: typeof document !== 'undefined' ? document.body : null,
|
|
149
|
-
children: function
|
|
149
|
+
children: _$_.ripple_element(function render_children(__output) {
|
|
150
150
|
_$_.push_component();
|
|
151
151
|
__output.push('<div');
|
|
152
152
|
__output.push(' class="portal-content"');
|
|
@@ -158,7 +158,7 @@ export async function PortalWithMainContent(__output) {
|
|
|
158
158
|
|
|
159
159
|
__output.push('</div>');
|
|
160
160
|
_$_.pop_component();
|
|
161
|
-
}
|
|
161
|
+
})
|
|
162
162
|
}
|
|
163
163
|
];
|
|
164
164
|
|
|
@@ -219,7 +219,7 @@ export async function NestedContentWithPortal(__output) {
|
|
|
219
219
|
__output,
|
|
220
220
|
{
|
|
221
221
|
target: typeof document !== 'undefined' ? document.body : null,
|
|
222
|
-
children: function
|
|
222
|
+
children: _$_.ripple_element(function render_children(__output) {
|
|
223
223
|
_$_.push_component();
|
|
224
224
|
__output.push('<div');
|
|
225
225
|
__output.push(' class="portal-content"');
|
|
@@ -231,7 +231,7 @@ export async function NestedContentWithPortal(__output) {
|
|
|
231
231
|
|
|
232
232
|
__output.push('</div>');
|
|
233
233
|
_$_.pop_component();
|
|
234
|
-
}
|
|
234
|
+
})
|
|
235
235
|
}
|
|
236
236
|
];
|
|
237
237
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
// Basic static components for hydration testing
|
|
2
|
+
import { track } from 'ripple';
|
|
2
3
|
import type { Children } from 'ripple';
|
|
3
4
|
|
|
4
5
|
export component StaticText() {
|
|
@@ -60,9 +61,20 @@ export component WithGreeting() {
|
|
|
60
61
|
|
|
61
62
|
export component ExpressionContent() {
|
|
62
63
|
const value = 42;
|
|
63
|
-
const
|
|
64
|
+
const label = 'computed';
|
|
64
65
|
<div>{value}</div>
|
|
65
|
-
<span>{
|
|
66
|
+
<span>{label.toUpperCase()}</span>
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
component TextProp(&{ children }: { children: string }) {
|
|
70
|
+
<div class="text-prop">{children}</div>
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export component TextPropWithToggle() {
|
|
74
|
+
let &[show] = track(false);
|
|
75
|
+
|
|
76
|
+
<TextProp children={show ? 'hello' : ''} />
|
|
77
|
+
<button class="show-text" onClick={() => (show = true)}>{'Show'}</button>
|
|
66
78
|
}
|
|
67
79
|
|
|
68
80
|
// Test for static content in child component followed by sibling content
|
|
@@ -99,9 +111,7 @@ component Actions({ playgroundVisible = false }: { playgroundVisible: boolean })
|
|
|
99
111
|
|
|
100
112
|
component Layout({ children }: { children: Children }) {
|
|
101
113
|
<main>
|
|
102
|
-
<div class="container">
|
|
103
|
-
<children />
|
|
104
|
-
</div>
|
|
114
|
+
<div class="container">{children}</div>
|
|
105
115
|
</main>
|
|
106
116
|
}
|
|
107
117
|
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import type { Children } from 'ripple';
|
|
2
2
|
|
|
3
3
|
export component Layout(&{ children }: { children?: Children }) {
|
|
4
|
+
<div class="layout">{children}</div>
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export component TextWrappedLayout(&{ children }: { children?: Children }) {
|
|
4
8
|
<div class="layout">
|
|
5
|
-
|
|
9
|
+
{text 'before'}
|
|
10
|
+
{children}
|
|
11
|
+
{text 'after'}
|
|
6
12
|
</div>
|
|
7
13
|
}
|
|
8
14
|
|
|
@@ -37,3 +43,9 @@ export component LayoutWithMultiRootChild() {
|
|
|
37
43
|
<MultiRootChild />
|
|
38
44
|
</Layout>
|
|
39
45
|
}
|
|
46
|
+
|
|
47
|
+
export component LayoutWithTextAroundChildren() {
|
|
48
|
+
<TextWrappedLayout>
|
|
49
|
+
<SingleChild />
|
|
50
|
+
</TextWrappedLayout>
|
|
51
|
+
}
|
|
@@ -11,9 +11,7 @@ import { track } from 'ripple';
|
|
|
11
11
|
export component Layout({ children }: { children: any }) {
|
|
12
12
|
<div class="layout">
|
|
13
13
|
<nav class="nav">{'Navigation'}</nav>
|
|
14
|
-
<main class="main">
|
|
15
|
-
<children />
|
|
16
|
-
</main>
|
|
14
|
+
<main class="main">{children}</main>
|
|
17
15
|
</div>
|
|
18
16
|
}
|
|
19
17
|
|
|
@@ -38,9 +38,7 @@ export component HtmlWithReactivity() {
|
|
|
38
38
|
|
|
39
39
|
export component HtmlWrapper({ children }: { children: any }) {
|
|
40
40
|
<div class="wrapper">
|
|
41
|
-
<div class="inner">
|
|
42
|
-
<children />
|
|
43
|
-
</div>
|
|
41
|
+
<div class="inner">{children}</div>
|
|
44
42
|
</div>
|
|
45
43
|
}
|
|
46
44
|
|
|
@@ -105,9 +103,7 @@ export component DocLayout({
|
|
|
105
103
|
<div class="layout">
|
|
106
104
|
<div class="content-container">
|
|
107
105
|
<article>
|
|
108
|
-
<div>
|
|
109
|
-
<children />
|
|
110
|
-
</div>
|
|
106
|
+
<div>{children}</div>
|
|
111
107
|
</article>
|
|
112
108
|
if (editPath) {
|
|
113
109
|
<div class="edit-link">
|
|
@@ -168,14 +164,10 @@ export component HtmlWithUndefinedContent() {
|
|
|
168
164
|
component DynamicHeading({ level, children }: { level: number; children: any }) {
|
|
169
165
|
switch (level) {
|
|
170
166
|
case 1: {
|
|
171
|
-
<h1 class="heading">
|
|
172
|
-
<children />
|
|
173
|
-
</h1>
|
|
167
|
+
<h1 class="heading">{children}</h1>
|
|
174
168
|
}
|
|
175
169
|
case 2: {
|
|
176
|
-
<h2 class="heading">
|
|
177
|
-
<children />
|
|
178
|
-
</h2>
|
|
170
|
+
<h2 class="heading">{children}</h2>
|
|
179
171
|
}
|
|
180
172
|
}
|
|
181
173
|
}
|
|
@@ -193,9 +185,7 @@ component CodeBlock({ code }: { code: string }) {
|
|
|
193
185
|
|
|
194
186
|
component ContentWrapper({ children }: { children: any }) {
|
|
195
187
|
<div class="wrapper">
|
|
196
|
-
<div class="inner">
|
|
197
|
-
<children />
|
|
198
|
-
</div>
|
|
188
|
+
<div class="inner">{children}</div>
|
|
199
189
|
</div>
|
|
200
190
|
}
|
|
201
191
|
|
|
@@ -211,7 +201,7 @@ export component HtmlAfterSwitchInChildren() {
|
|
|
211
201
|
|
|
212
202
|
component NavItem({
|
|
213
203
|
href,
|
|
214
|
-
text,
|
|
204
|
+
text: label,
|
|
215
205
|
active = false,
|
|
216
206
|
}: {
|
|
217
207
|
href: string;
|
|
@@ -223,7 +213,7 @@ component NavItem({
|
|
|
223
213
|
<div class="indicator" />
|
|
224
214
|
}
|
|
225
215
|
<a {href}>
|
|
226
|
-
<span>{
|
|
216
|
+
<span>{label}</span>
|
|
227
217
|
</a>
|
|
228
218
|
</div>
|
|
229
219
|
}
|
|
@@ -236,9 +226,7 @@ component SidebarSection({ title, children }: { title: string; children: any })
|
|
|
236
226
|
<button onClick={() => (expanded = !expanded)}>{'Toggle'}</button>
|
|
237
227
|
</div>
|
|
238
228
|
if (expanded) {
|
|
239
|
-
<div class="section-items">
|
|
240
|
-
<children />
|
|
241
|
-
</div>
|
|
229
|
+
<div class="section-items">{children}</div>
|
|
242
230
|
}
|
|
243
231
|
</section>
|
|
244
232
|
}
|
|
@@ -293,9 +281,7 @@ export component LayoutWithSidebarAndMain() {
|
|
|
293
281
|
|
|
294
282
|
component ArticleWrapper({ children }: { children: any }) {
|
|
295
283
|
<article class="doc-content">
|
|
296
|
-
<div>
|
|
297
|
-
<children />
|
|
298
|
-
</div>
|
|
284
|
+
<div>{children}</div>
|
|
299
285
|
</article>
|
|
300
286
|
}
|
|
301
287
|
|
|
@@ -341,9 +327,7 @@ export component ArticleWithHtmlChildThenSibling() {
|
|
|
341
327
|
component InlineArticleLayout({ children }: { children: any }) {
|
|
342
328
|
<div class="content-container">
|
|
343
329
|
<article class="doc-content">
|
|
344
|
-
<div>
|
|
345
|
-
<children />
|
|
346
|
-
</div>
|
|
330
|
+
<div>{children}</div>
|
|
347
331
|
</article>
|
|
348
332
|
if (true) {
|
|
349
333
|
<div class="edit-link">
|
|
@@ -391,9 +375,7 @@ component DocsLayoutInner({
|
|
|
391
375
|
<div class="content">
|
|
392
376
|
<div class="content-container">
|
|
393
377
|
<article class="doc-content">
|
|
394
|
-
<div>
|
|
395
|
-
<children />
|
|
396
|
-
</div>
|
|
378
|
+
<div>{children}</div>
|
|
397
379
|
</article>
|
|
398
380
|
if (editPath) {
|
|
399
381
|
<div class="edit-link">
|
|
@@ -450,9 +432,7 @@ component DocsLayoutExact({
|
|
|
450
432
|
<div class="content">
|
|
451
433
|
<div class="content-container">
|
|
452
434
|
<article class="doc-content">
|
|
453
|
-
<div>
|
|
454
|
-
<children />
|
|
455
|
-
</div>
|
|
435
|
+
<div>{children}</div>
|
|
456
436
|
</article>
|
|
457
437
|
if (editPath) {
|
|
458
438
|
<div class="edit-link">
|
|
@@ -542,9 +522,7 @@ export component TemplateWithHtmlAndSiblings() {
|
|
|
542
522
|
component LayoutWithTemplate({ children, data }: { children: any; data: object }) {
|
|
543
523
|
<div class="layout">
|
|
544
524
|
<template id="page-data">{html JSON.stringify(data)}</template>
|
|
545
|
-
<main>
|
|
546
|
-
<children />
|
|
547
|
-
</main>
|
|
525
|
+
<main>{children}</main>
|
|
548
526
|
</div>
|
|
549
527
|
}
|
|
550
528
|
|
|
@@ -9,15 +9,13 @@ export component IfWithChildren({ children }: { children: any }) {
|
|
|
9
9
|
<div class="container">
|
|
10
10
|
<div class="header" role="button" onClick={() => (expanded = !expanded)}>{'Toggle'}</div>
|
|
11
11
|
if (expanded) {
|
|
12
|
-
<div class="content">
|
|
13
|
-
<children />
|
|
14
|
-
</div>
|
|
12
|
+
<div class="content">{children}</div>
|
|
15
13
|
}
|
|
16
14
|
</div>
|
|
17
15
|
}
|
|
18
16
|
|
|
19
|
-
export component ChildItem({ text }: { text: string }) {
|
|
20
|
-
<div class="item">{
|
|
17
|
+
export component ChildItem({ text: label }: { text: string }) {
|
|
18
|
+
<div class="item">{label}</div>
|
|
21
19
|
}
|
|
22
20
|
|
|
23
21
|
export component TestIfWithChildren() {
|
|
@@ -57,9 +55,7 @@ export component IfWithSiblingsAndChildren({ children }: { children: any }) {
|
|
|
57
55
|
</div>
|
|
58
56
|
</div>
|
|
59
57
|
if (expanded) {
|
|
60
|
-
<div class="items">
|
|
61
|
-
<children />
|
|
62
|
-
</div>
|
|
58
|
+
<div class="items">{children}</div>
|
|
63
59
|
}
|
|
64
60
|
</section>
|
|
65
61
|
}
|
|
@@ -39,4 +39,15 @@ describe('hydration > composite', () => {
|
|
|
39
39
|
'<div class=\"layout\"><h1>title</h1><p>description</p></div>',
|
|
40
40
|
);
|
|
41
41
|
});
|
|
42
|
+
|
|
43
|
+
it('hydrates explicit text around children', async () => {
|
|
44
|
+
await hydrateComponent(
|
|
45
|
+
ServerComponents.LayoutWithTextAroundChildren,
|
|
46
|
+
ClientComponents.LayoutWithTextAroundChildren,
|
|
47
|
+
);
|
|
48
|
+
expect(container.innerHTML).toBeHtml(
|
|
49
|
+
'<div class="layout">before<div class="single">single</div>after</div>',
|
|
50
|
+
);
|
|
51
|
+
expect(container.querySelector('.layout')?.textContent).toBe('beforesingleafter');
|
|
52
|
+
});
|
|
42
53
|
});
|
|
@@ -345,6 +345,56 @@ describe('basic server > attribute rendering', () => {
|
|
|
345
345
|
expect(body).toBeHtml('<input type="checkbox" disabled checked />');
|
|
346
346
|
});
|
|
347
347
|
|
|
348
|
+
it('renders formnovalidate as a boolean attribute', async () => {
|
|
349
|
+
component Basic() {
|
|
350
|
+
let &[formnovalidate] = track(true);
|
|
351
|
+
|
|
352
|
+
<button {formnovalidate}>{'Submit'}</button>
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const { body } = await render(Basic);
|
|
356
|
+
const { document } = parseHtml(body);
|
|
357
|
+
|
|
358
|
+
const button = document.querySelector('button');
|
|
359
|
+
|
|
360
|
+
expect(button.hasAttribute('formnovalidate')).toBe(true);
|
|
361
|
+
expect(button.getAttribute('formnovalidate')).toBe('');
|
|
362
|
+
expect(body).toBeHtml('<button formnovalidate>Submit</button>');
|
|
363
|
+
});
|
|
364
|
+
|
|
365
|
+
it('renders hidden as a boolean attribute when true', async () => {
|
|
366
|
+
component Basic() {
|
|
367
|
+
let &[hidden] = track(true);
|
|
368
|
+
|
|
369
|
+
<div {hidden}>{'Hidden content'}</div>
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
const { body } = await render(Basic);
|
|
373
|
+
const { document } = parseHtml(body);
|
|
374
|
+
|
|
375
|
+
const div = document.querySelector('div');
|
|
376
|
+
|
|
377
|
+
expect(div.hasAttribute('hidden')).toBe(true);
|
|
378
|
+
expect(div.getAttribute('hidden')).toBe('');
|
|
379
|
+
expect(body).toBeHtml('<div hidden>Hidden content</div>');
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
it('does not render hidden when false', async () => {
|
|
383
|
+
component Basic() {
|
|
384
|
+
let &[hidden] = track(false);
|
|
385
|
+
|
|
386
|
+
<div {hidden}>{'Visible content'}</div>
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
const { body } = await render(Basic);
|
|
390
|
+
const { document } = parseHtml(body);
|
|
391
|
+
|
|
392
|
+
const div = document.querySelector('div');
|
|
393
|
+
|
|
394
|
+
expect(div.hasAttribute('hidden')).toBe(false);
|
|
395
|
+
expect(body).toBeHtml('<div>Visible content</div>');
|
|
396
|
+
});
|
|
397
|
+
|
|
348
398
|
it('render multiple dynamic attributes', async () => {
|
|
349
399
|
component Basic() {
|
|
350
400
|
let &[theme] = track('light');
|