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
|
@@ -2,8 +2,8 @@ import { RippleObject, track } from 'ripple';
|
|
|
2
2
|
|
|
3
3
|
describe('basic server > attribute rendering', () => {
|
|
4
4
|
it('render static attributes', async () => {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
function Basic() {
|
|
6
|
+
return <><div class="foo" id="bar" style="color: red;">{'Hello World'}</div></>;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
const { body } = await render(Basic);
|
|
@@ -18,16 +18,16 @@ describe('basic server > attribute rendering', () => {
|
|
|
18
18
|
});
|
|
19
19
|
|
|
20
20
|
it('render dynamic class attribute', async () => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
21
|
+
function Basic() {
|
|
22
|
+
return <>
|
|
23
|
+
let &[active] = track(false);
|
|
24
|
+
<div class={active ? 'active' : 'inactive'}>{'Dynamic Class'}</div>
|
|
25
|
+
<style>
|
|
26
|
+
.active {
|
|
27
|
+
color: green;
|
|
28
|
+
}
|
|
29
|
+
</style>
|
|
30
|
+
</>;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
const { body } = await render(Basic);
|
|
@@ -42,29 +42,30 @@ describe('basic server > attribute rendering', () => {
|
|
|
42
42
|
});
|
|
43
43
|
|
|
44
44
|
it('render class attribute with array, nested array, nested object', async () => {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
45
|
+
function Basic() {
|
|
46
|
+
return <>
|
|
47
|
+
<div
|
|
48
|
+
class={[
|
|
49
|
+
'foo',
|
|
50
|
+
'bar',
|
|
51
|
+
true && 'baz',
|
|
52
|
+
false && 'aaa',
|
|
53
|
+
null && 'bbb',
|
|
54
|
+
[
|
|
55
|
+
'ccc',
|
|
56
|
+
'ddd',
|
|
57
|
+
{ eee: true, fff: false },
|
|
58
|
+
],
|
|
59
|
+
]}
|
|
60
|
+
>
|
|
61
|
+
{'Class Array'}
|
|
62
|
+
</div>
|
|
63
|
+
<style>
|
|
64
|
+
.foo {
|
|
65
|
+
color: red;
|
|
66
|
+
}
|
|
67
|
+
</style>
|
|
68
|
+
</>;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
71
|
const { body } = await render(Basic);
|
|
@@ -88,32 +89,30 @@ describe('basic server > attribute rendering', () => {
|
|
|
88
89
|
});
|
|
89
90
|
|
|
90
91
|
it('applies scoped classes inside tsx blocks and fragment shorthand', async () => {
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
<
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
.card {
|
|
110
|
-
padding: 1rem;
|
|
111
|
-
}
|
|
92
|
+
function App() {
|
|
93
|
+
return <>
|
|
94
|
+
<tsx>
|
|
95
|
+
<div class="card">
|
|
96
|
+
<h2>
|
|
97
|
+
{'tsx block'}
|
|
98
|
+
</h2>
|
|
99
|
+
</div>
|
|
100
|
+
</tsx>
|
|
101
|
+
<>
|
|
102
|
+
<div class="card">
|
|
103
|
+
<h2>{'fragment shorthand'}</h2>
|
|
104
|
+
</div>
|
|
105
|
+
</>
|
|
106
|
+
<style>
|
|
107
|
+
.card {
|
|
108
|
+
padding: 1rem;
|
|
109
|
+
}
|
|
112
110
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
111
|
+
h2 {
|
|
112
|
+
color: red;
|
|
113
|
+
}
|
|
114
|
+
</style>
|
|
115
|
+
</>;
|
|
117
116
|
}
|
|
118
117
|
|
|
119
118
|
const { body } = await render(App);
|
|
@@ -139,16 +138,16 @@ describe('basic server > attribute rendering', () => {
|
|
|
139
138
|
});
|
|
140
139
|
|
|
141
140
|
it('render dynamic class object', async () => {
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
141
|
+
function Basic() {
|
|
142
|
+
return <>
|
|
143
|
+
let &[active] = track(false);
|
|
144
|
+
<div class={{ active: active, inactive: !active }}>{'Dynamic Class'}</div>
|
|
145
|
+
<style>
|
|
146
|
+
.active {
|
|
147
|
+
color: green;
|
|
148
|
+
}
|
|
149
|
+
</style>
|
|
150
|
+
</>;
|
|
152
151
|
}
|
|
153
152
|
|
|
154
153
|
const { body } = await render(Basic);
|
|
@@ -166,21 +165,21 @@ describe('basic server > attribute rendering', () => {
|
|
|
166
165
|
it(
|
|
167
166
|
'applies scoped ripple class to multiple elements with dynamic class expressions',
|
|
168
167
|
async () => {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
168
|
+
function Basic() {
|
|
169
|
+
return <>
|
|
170
|
+
let &[selected] = track(1);
|
|
171
|
+
<div class={selected === 0 ? 'selected' : ''}>{`div 1`}</div>
|
|
172
|
+
<div class={selected === 0 ? 'selected' : ''}>{`div 2`}</div>
|
|
173
|
+
<style>
|
|
174
|
+
div {
|
|
175
|
+
background: green;
|
|
176
|
+
color: white;
|
|
177
|
+
}
|
|
178
|
+
div.selected {
|
|
179
|
+
background: indigo;
|
|
180
|
+
}
|
|
181
|
+
</style>
|
|
182
|
+
</>;
|
|
184
183
|
}
|
|
185
184
|
|
|
186
185
|
const { body } = await render(Basic);
|
|
@@ -197,10 +196,11 @@ describe('basic server > attribute rendering', () => {
|
|
|
197
196
|
);
|
|
198
197
|
|
|
199
198
|
it('render dynamic id attribute', async () => {
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
199
|
+
function Basic() {
|
|
200
|
+
return <>
|
|
201
|
+
let &[count] = track(0);
|
|
202
|
+
<div id={`item-${count}`}>{'Dynamic ID'}</div>
|
|
203
|
+
</>;
|
|
204
204
|
}
|
|
205
205
|
|
|
206
206
|
const { body } = await render(Basic);
|
|
@@ -212,10 +212,11 @@ describe('basic server > attribute rendering', () => {
|
|
|
212
212
|
});
|
|
213
213
|
|
|
214
214
|
it('render dynamic style attribute', async () => {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
215
|
+
function Basic() {
|
|
216
|
+
return <>
|
|
217
|
+
let &[color] = track('red');
|
|
218
|
+
<div style={`color: ${color}; font-weight: bold;`}>{'Dynamic Style'}</div>
|
|
219
|
+
</>;
|
|
219
220
|
}
|
|
220
221
|
|
|
221
222
|
const { body } = await render(Basic);
|
|
@@ -228,10 +229,11 @@ describe('basic server > attribute rendering', () => {
|
|
|
228
229
|
});
|
|
229
230
|
|
|
230
231
|
it('render style attribute as dynamic object', async () => {
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
232
|
+
function Basic() {
|
|
233
|
+
return <>
|
|
234
|
+
let &[color] = track('red');
|
|
235
|
+
<div style={{ color: color, fontWeight: 'bold' }}>{'Dynamic Style'}</div>
|
|
236
|
+
</>;
|
|
235
237
|
}
|
|
236
238
|
|
|
237
239
|
const { body } = await render(Basic);
|
|
@@ -244,10 +246,11 @@ describe('basic server > attribute rendering', () => {
|
|
|
244
246
|
});
|
|
245
247
|
|
|
246
248
|
it('render tracked variable as style attribute', async () => {
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
249
|
+
function Basic() {
|
|
250
|
+
return <>
|
|
251
|
+
let &[style] = track({ color: 'red', fontWeight: 'bold' });
|
|
252
|
+
<div {style}>{'Dynamic Style'}</div>
|
|
253
|
+
</>;
|
|
251
254
|
}
|
|
252
255
|
|
|
253
256
|
const { body } = await render(Basic);
|
|
@@ -260,13 +263,14 @@ describe('basic server > attribute rendering', () => {
|
|
|
260
263
|
});
|
|
261
264
|
|
|
262
265
|
it('render tracked object as style attribute', async () => {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
266
|
+
function Basic() {
|
|
267
|
+
return <>
|
|
268
|
+
let style = new RippleObject({
|
|
269
|
+
color: 'red',
|
|
270
|
+
fontWeight: 'bold',
|
|
271
|
+
});
|
|
272
|
+
<div style={{ color: style.color, fontWeight: style.fontWeight }}>{'Dynamic Style'}</div>
|
|
273
|
+
</>;
|
|
270
274
|
}
|
|
271
275
|
|
|
272
276
|
const { body } = await render(Basic);
|
|
@@ -279,13 +283,14 @@ describe('basic server > attribute rendering', () => {
|
|
|
279
283
|
});
|
|
280
284
|
|
|
281
285
|
it('render spread attributes with style and class', async () => {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
286
|
+
function Basic() {
|
|
287
|
+
return <>
|
|
288
|
+
const attributes = {
|
|
289
|
+
style: { color: 'red', fontWeight: 'bold' },
|
|
290
|
+
class: ['foo', false && 'bar'],
|
|
291
|
+
};
|
|
292
|
+
<div {...attributes}>{'Attributes with style and class'}</div>
|
|
293
|
+
</>;
|
|
289
294
|
}
|
|
290
295
|
|
|
291
296
|
const { body } = await render(Basic);
|
|
@@ -300,13 +305,64 @@ describe('basic server > attribute rendering', () => {
|
|
|
300
305
|
expect(div.classList.contains('bar')).toBe(false);
|
|
301
306
|
});
|
|
302
307
|
|
|
303
|
-
it('
|
|
304
|
-
|
|
305
|
-
|
|
308
|
+
it('renders host innerHTML as content instead of an attribute', async () => {
|
|
309
|
+
function Basic() {
|
|
310
|
+
return <>
|
|
311
|
+
const html = '<span>Direct HTML</span>';
|
|
312
|
+
<code innerHTML={html} />
|
|
313
|
+
</>;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
const { body } = await render(Basic);
|
|
317
|
+
const { document } = parseHtml(body);
|
|
318
|
+
const code = document.querySelector('code');
|
|
319
|
+
|
|
320
|
+
expect(code.innerHTML).toBe('<span>Direct HTML</span>');
|
|
321
|
+
expect(code.hasAttribute('innerhtml')).toBe(false);
|
|
322
|
+
expect(body).toBeHtml('<code><span>Direct HTML</span></code>');
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
it('renders spread innerHTML as content instead of an attribute', async () => {
|
|
326
|
+
function Basic() {
|
|
327
|
+
return <>
|
|
328
|
+
const attributes = { innerHTML: '<span>Spread HTML</span>' };
|
|
329
|
+
<code {...attributes} />
|
|
330
|
+
</>;
|
|
331
|
+
}
|
|
306
332
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
333
|
+
const { body } = await render(Basic);
|
|
334
|
+
const { document } = parseHtml(body);
|
|
335
|
+
const code = document.querySelector('code');
|
|
336
|
+
|
|
337
|
+
expect(code.innerHTML).toBe('<span>Spread HTML</span>');
|
|
338
|
+
expect(code.hasAttribute('innerhtml')).toBe(false);
|
|
339
|
+
expect(body).toBeHtml('<code><span>Spread HTML</span></code>');
|
|
340
|
+
});
|
|
341
|
+
|
|
342
|
+
it('uses the last innerHTML value when spreads and direct props are mixed', async () => {
|
|
343
|
+
function Basic() {
|
|
344
|
+
return <>
|
|
345
|
+
const attributes = { innerHTML: '<span>Spread HTML</span>' };
|
|
346
|
+
<code {...attributes} innerHTML="<em>Direct HTML</em>" />
|
|
347
|
+
</>;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
const { body } = await render(Basic);
|
|
351
|
+
const { document } = parseHtml(body);
|
|
352
|
+
const code = document.querySelector('code');
|
|
353
|
+
|
|
354
|
+
expect(code.innerHTML).toBe('<em>Direct HTML</em>');
|
|
355
|
+
expect(code.hasAttribute('innerhtml')).toBe(false);
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
it('render spread props without duplication', async () => {
|
|
359
|
+
function Basic() {
|
|
360
|
+
return <>
|
|
361
|
+
const checkBoxProp = { name: 'car' };
|
|
362
|
+
<div>
|
|
363
|
+
<input {...checkBoxProp} type="checkbox" id="vehicle1" value="Bike" />
|
|
364
|
+
</div>
|
|
365
|
+
</>;
|
|
310
366
|
}
|
|
311
367
|
|
|
312
368
|
const { body } = await render(Basic);
|
|
@@ -330,11 +386,12 @@ describe('basic server > attribute rendering', () => {
|
|
|
330
386
|
});
|
|
331
387
|
|
|
332
388
|
it('render dynamic boolean attributes as false', async () => {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
389
|
+
function Basic() {
|
|
390
|
+
return <>
|
|
391
|
+
let &[disabled] = track(false);
|
|
392
|
+
let &[checked] = track(false);
|
|
393
|
+
<input type="checkbox" {disabled} {checked} />
|
|
394
|
+
</>;
|
|
338
395
|
}
|
|
339
396
|
|
|
340
397
|
const { body } = await render(Basic);
|
|
@@ -348,10 +405,11 @@ describe('basic server > attribute rendering', () => {
|
|
|
348
405
|
});
|
|
349
406
|
|
|
350
407
|
it('render dynamic boolean attributes as false via spread', async () => {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
408
|
+
function Basic() {
|
|
409
|
+
return <>
|
|
410
|
+
const spread = { disabled: false, checked: false };
|
|
411
|
+
<input type="checkbox" {...spread} />
|
|
412
|
+
</>;
|
|
355
413
|
}
|
|
356
414
|
|
|
357
415
|
const { body } = await render(Basic);
|
|
@@ -365,11 +423,12 @@ describe('basic server > attribute rendering', () => {
|
|
|
365
423
|
});
|
|
366
424
|
|
|
367
425
|
it('render dynamic boolean attributes as true', async () => {
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
426
|
+
function Basic() {
|
|
427
|
+
return <>
|
|
428
|
+
let &[disabled] = track(true);
|
|
429
|
+
let &[checked] = track(true);
|
|
430
|
+
<input type="checkbox" {disabled} {checked} />
|
|
431
|
+
</>;
|
|
373
432
|
}
|
|
374
433
|
|
|
375
434
|
const { body } = await render(Basic);
|
|
@@ -383,10 +442,11 @@ describe('basic server > attribute rendering', () => {
|
|
|
383
442
|
});
|
|
384
443
|
|
|
385
444
|
it('render dynamic boolean attributes as true via spread', async () => {
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
445
|
+
function Basic() {
|
|
446
|
+
return <>
|
|
447
|
+
const spread = { disabled: true, checked: true };
|
|
448
|
+
<input type="checkbox" {...spread} />
|
|
449
|
+
</>;
|
|
390
450
|
}
|
|
391
451
|
|
|
392
452
|
const { body } = await render(Basic);
|
|
@@ -400,10 +460,11 @@ describe('basic server > attribute rendering', () => {
|
|
|
400
460
|
});
|
|
401
461
|
|
|
402
462
|
it('renders formnovalidate as a boolean attribute', async () => {
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
463
|
+
function Basic() {
|
|
464
|
+
return <>
|
|
465
|
+
let &[formnovalidate] = track(true);
|
|
466
|
+
<button {formnovalidate}>{'Submit'}</button>
|
|
467
|
+
</>;
|
|
407
468
|
}
|
|
408
469
|
|
|
409
470
|
const { body } = await render(Basic);
|
|
@@ -417,10 +478,11 @@ describe('basic server > attribute rendering', () => {
|
|
|
417
478
|
});
|
|
418
479
|
|
|
419
480
|
it('renders hidden as a boolean attribute when true', async () => {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
481
|
+
function Basic() {
|
|
482
|
+
return <>
|
|
483
|
+
let &[hidden] = track(true);
|
|
484
|
+
<div {hidden}>{'Hidden content'}</div>
|
|
485
|
+
</>;
|
|
424
486
|
}
|
|
425
487
|
|
|
426
488
|
const { body } = await render(Basic);
|
|
@@ -434,10 +496,11 @@ describe('basic server > attribute rendering', () => {
|
|
|
434
496
|
});
|
|
435
497
|
|
|
436
498
|
it('does not render hidden when false', async () => {
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
499
|
+
function Basic() {
|
|
500
|
+
return <>
|
|
501
|
+
let &[hidden] = track(false);
|
|
502
|
+
<div {hidden}>{'Visible content'}</div>
|
|
503
|
+
</>;
|
|
441
504
|
}
|
|
442
505
|
|
|
443
506
|
const { body } = await render(Basic);
|
|
@@ -450,13 +513,14 @@ describe('basic server > attribute rendering', () => {
|
|
|
450
513
|
});
|
|
451
514
|
|
|
452
515
|
it('render multiple dynamic attributes', async () => {
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
516
|
+
function Basic() {
|
|
517
|
+
return <>
|
|
518
|
+
let &[theme] = track('light');
|
|
519
|
+
let &[size] = track('medium');
|
|
520
|
+
<div class={`theme-${theme} size-${size}`} data-theme={theme} data-size={size}>
|
|
521
|
+
{'Multiple Dynamic Attributes'}
|
|
522
|
+
</div>
|
|
523
|
+
</>;
|
|
460
524
|
}
|
|
461
525
|
|
|
462
526
|
const { body } = await render(Basic);
|
|
@@ -470,16 +534,17 @@ describe('basic server > attribute rendering', () => {
|
|
|
470
534
|
});
|
|
471
535
|
|
|
472
536
|
it('render conditional attributes', async () => {
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
537
|
+
function Basic() {
|
|
538
|
+
return <>
|
|
539
|
+
let &[showTitle] = track(false);
|
|
540
|
+
let &[showAria] = track(false);
|
|
541
|
+
<div
|
|
542
|
+
title={showTitle ? 'This is a title' : undefined}
|
|
543
|
+
aria-label={showAria ? 'Accessible label' : undefined}
|
|
544
|
+
>
|
|
545
|
+
{'Conditional Attributes'}
|
|
546
|
+
</div>
|
|
547
|
+
</>;
|
|
483
548
|
}
|
|
484
549
|
|
|
485
550
|
const { body } = await render(Basic);
|
|
@@ -492,13 +557,14 @@ describe('basic server > attribute rendering', () => {
|
|
|
492
557
|
});
|
|
493
558
|
|
|
494
559
|
it('render spread attributes', async () => {
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
560
|
+
function Basic() {
|
|
561
|
+
return <>
|
|
562
|
+
let &[attrs] = track<TestAttributes>({
|
|
563
|
+
class: 'initial',
|
|
564
|
+
id: 'test-1',
|
|
565
|
+
});
|
|
566
|
+
<div {...attrs}>{'Spread Attributes'}</div>
|
|
567
|
+
</>;
|
|
502
568
|
}
|
|
503
569
|
|
|
504
570
|
const { body } = await render(Basic);
|
|
@@ -512,16 +578,16 @@ describe('basic server > attribute rendering', () => {
|
|
|
512
578
|
});
|
|
513
579
|
|
|
514
580
|
it('renders with reactive attributes with nested reactive attributes', async () => {
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
581
|
+
function Basic() {
|
|
582
|
+
return <>
|
|
583
|
+
let &[value] = track('parent-class');
|
|
584
|
+
<p class={value}>{'Colored parent value'}</p>
|
|
585
|
+
<div>
|
|
586
|
+
let &[nested] = track('nested-class');
|
|
587
|
+
|
|
588
|
+
<p class={nested}>{'Colored nested value'}</p>
|
|
589
|
+
</div>
|
|
590
|
+
</>;
|
|
525
591
|
}
|
|
526
592
|
|
|
527
593
|
const { body } = await render(Basic);
|
|
@@ -534,10 +600,12 @@ describe('basic server > attribute rendering', () => {
|
|
|
534
600
|
});
|
|
535
601
|
|
|
536
602
|
it('handles boolean attributes with no prop value provides', async () => {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
<
|
|
540
|
-
|
|
603
|
+
function Basic() {
|
|
604
|
+
return <>
|
|
605
|
+
<div class="container">
|
|
606
|
+
<input type="checkbox" checked />
|
|
607
|
+
</div>
|
|
608
|
+
</>;
|
|
541
609
|
}
|
|
542
610
|
|
|
543
611
|
const { body } = await render(Basic);
|
|
@@ -545,14 +613,15 @@ describe('basic server > attribute rendering', () => {
|
|
|
545
613
|
});
|
|
546
614
|
|
|
547
615
|
it('handles boolean props correctly', async () => {
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
616
|
+
function Basic() {
|
|
617
|
+
return <>
|
|
618
|
+
<div data-disabled />
|
|
619
|
+
<Child isDisabled />
|
|
620
|
+
</>;
|
|
552
621
|
}
|
|
553
622
|
|
|
554
|
-
|
|
555
|
-
|
|
623
|
+
function Child({ isDisabled }: { isDisabled: boolean }) {
|
|
624
|
+
return <><input disabled={isDisabled} /></>;
|
|
556
625
|
}
|
|
557
626
|
|
|
558
627
|
const { body } = await render(Basic);
|