ripple 0.3.72 → 0.3.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +66 -0
- package/package.json +3 -3
- package/src/jsx-runtime.d.ts +2 -8
- package/src/runtime/index-client.js +3 -13
- package/src/runtime/internal/client/blocks.js +3 -25
- package/src/runtime/internal/client/for.js +80 -5
- package/src/runtime/internal/client/index.js +0 -2
- package/src/runtime/internal/client/types.d.ts +0 -10
- package/tests/client/__snapshots__/computed-properties.test.tsrx.snap +8 -0
- package/tests/client/__snapshots__/for.test.tsrx.snap +22 -0
- package/tests/client/__snapshots__/html.test.tsrx.snap +4 -0
- package/tests/client/array/array.copy-within.test.tsrx +19 -19
- package/tests/client/array/array.derived.test.tsrx +97 -109
- package/tests/client/array/array.iteration.test.tsrx +28 -28
- package/tests/client/array/array.mutations.test.tsrx +68 -68
- package/tests/client/array/array.static.test.tsrx +82 -92
- package/tests/client/array/array.to-methods.test.tsrx +15 -15
- package/tests/client/async-suspend.test.tsrx +180 -179
- package/tests/client/basic/__snapshots__/basic.attributes.test.tsrx.snap +2 -0
- package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +4 -0
- package/tests/client/basic/basic.attributes.test.tsrx +273 -317
- package/tests/client/basic/basic.collections.test.tsrx +55 -61
- package/tests/client/basic/basic.components.test.tsrx +196 -218
- package/tests/client/basic/basic.errors.test.tsrx +70 -76
- package/tests/client/basic/basic.events.test.tsrx +80 -85
- package/tests/client/basic/basic.get-set.test.tsrx +54 -64
- package/tests/client/basic/basic.hmr.test.tsrx +15 -19
- package/tests/client/basic/basic.reactivity.test.tsrx +121 -135
- package/tests/client/basic/basic.rendering.test.tsrx +273 -178
- package/tests/client/basic/basic.utilities.test.tsrx +8 -10
- package/tests/client/boundaries.test.tsrx +18 -18
- package/tests/client/compiler/compiler.assignments.test.tsrx +77 -76
- package/tests/client/compiler/compiler.attributes.test.tsrx +18 -14
- package/tests/client/compiler/compiler.basic.test.tsrx +357 -288
- package/tests/client/compiler/compiler.regex.test.tsrx +40 -44
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +57 -38
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
- package/tests/client/compiler/compiler.typescript.test.tsrx +4 -3
- package/tests/client/composite/composite.dynamic-components.test.tsrx +41 -44
- package/tests/client/composite/composite.generics.test.tsrx +165 -167
- package/tests/client/composite/composite.props.test.tsrx +66 -74
- package/tests/client/composite/composite.reactivity.test.tsrx +132 -166
- package/tests/client/composite/composite.render.test.tsrx +92 -101
- package/tests/client/computed-properties.test.tsrx +14 -18
- package/tests/client/context.test.tsrx +14 -18
- package/tests/client/css/global-additional-cases.test.tsrx +491 -437
- package/tests/client/css/global-advanced-selectors.test.tsrx +169 -153
- package/tests/client/css/global-at-rules.test.tsrx +71 -66
- package/tests/client/css/global-basic.test.tsrx +105 -98
- package/tests/client/css/global-classes-ids.test.tsrx +128 -114
- package/tests/client/css/global-combinators.test.tsrx +83 -78
- package/tests/client/css/global-complex-nesting.test.tsrx +134 -120
- package/tests/client/css/global-edge-cases.test.tsrx +138 -120
- package/tests/client/css/global-keyframes.test.tsrx +108 -96
- package/tests/client/css/global-nested.test.tsrx +88 -78
- package/tests/client/css/global-pseudo.test.tsrx +104 -98
- package/tests/client/css/global-scoping.test.tsrx +145 -125
- package/tests/client/css/style-identifier.test.tsrx +62 -69
- package/tests/client/date.test.tsrx +83 -83
- package/tests/client/dynamic-elements.test.tsrx +227 -283
- package/tests/client/events.test.tsrx +252 -266
- package/tests/client/for.test.tsrx +120 -127
- package/tests/client/head.test.tsrx +40 -48
- package/tests/client/html.test.tsrx +37 -49
- package/tests/client/input-value.test.tsrx +1125 -1354
- package/tests/client/lazy-array.test.tsrx +10 -16
- package/tests/client/lazy-destructuring.test.tsrx +169 -221
- package/tests/client/map.test.tsrx +39 -41
- package/tests/client/media-query.test.tsrx +15 -19
- package/tests/client/object.test.tsrx +46 -56
- package/tests/client/portal.test.tsrx +31 -37
- package/tests/client/ref.test.tsrx +173 -193
- package/tests/client/return.test.tsrx +62 -37
- package/tests/client/set.test.tsrx +33 -33
- package/tests/client/svg.test.tsrx +195 -215
- package/tests/client/switch.test.tsrx +201 -191
- package/tests/client/track-async-hydration.test.tsrx +14 -18
- package/tests/client/tracked-index-access.test.tsrx +18 -28
- package/tests/client/try.test.tsrx +494 -619
- package/tests/client/tsx.test.tsrx +286 -292
- package/tests/client/typescript-generics.test.tsrx +121 -129
- package/tests/client/url/url.derived.test.tsrx +21 -25
- package/tests/client/url/url.parsing.test.tsrx +35 -35
- package/tests/client/url/url.partial-removal.test.tsrx +32 -32
- package/tests/client/url/url.reactivity.test.tsrx +68 -72
- package/tests/client/url/url.serialization.test.tsrx +8 -8
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +21 -27
- package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +16 -16
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +37 -37
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +56 -60
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +32 -34
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +9 -9
- package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +10 -10
- package/tests/hydration/compiled/client/basic.js +390 -319
- package/tests/hydration/compiled/client/composite.js +52 -44
- package/tests/hydration/compiled/client/for.js +734 -604
- package/tests/hydration/compiled/client/head.js +183 -103
- package/tests/hydration/compiled/client/html.js +93 -86
- package/tests/hydration/compiled/client/if-children.js +95 -71
- package/tests/hydration/compiled/client/if.js +113 -89
- package/tests/hydration/compiled/client/mixed-control-flow.js +225 -209
- package/tests/hydration/compiled/client/nested-control-flow.js +94 -98
- package/tests/hydration/compiled/client/reactivity.js +26 -24
- package/tests/hydration/compiled/client/return.js +8 -42
- package/tests/hydration/compiled/client/switch.js +208 -173
- package/tests/hydration/compiled/client/track-async-serialization.js +176 -128
- package/tests/hydration/compiled/client/try.js +29 -21
- package/tests/hydration/compiled/server/basic.js +210 -221
- package/tests/hydration/compiled/server/composite.js +13 -14
- package/tests/hydration/compiled/server/for.js +427 -444
- package/tests/hydration/compiled/server/head.js +199 -189
- package/tests/hydration/compiled/server/html.js +33 -41
- package/tests/hydration/compiled/server/if-children.js +114 -117
- package/tests/hydration/compiled/server/if.js +77 -83
- package/tests/hydration/compiled/server/mixed-control-flow.js +145 -150
- package/tests/hydration/compiled/server/nested-control-flow.js +10 -0
- package/tests/hydration/compiled/server/reactivity.js +24 -22
- package/tests/hydration/compiled/server/return.js +6 -18
- package/tests/hydration/compiled/server/switch.js +179 -176
- package/tests/hydration/compiled/server/track-async-serialization.js +88 -70
- package/tests/hydration/compiled/server/try.js +31 -35
- package/tests/hydration/components/basic.tsrx +216 -258
- package/tests/hydration/components/composite.tsrx +32 -42
- package/tests/hydration/components/events.tsrx +81 -101
- package/tests/hydration/components/for.tsrx +270 -336
- package/tests/hydration/components/head.tsrx +43 -39
- package/tests/hydration/components/hmr.tsrx +16 -22
- package/tests/hydration/components/html-in-template.tsrx +15 -21
- package/tests/hydration/components/html.tsrx +442 -526
- package/tests/hydration/components/if-children.tsrx +107 -125
- package/tests/hydration/components/if.tsrx +68 -90
- package/tests/hydration/components/mixed-control-flow.tsrx +65 -72
- package/tests/hydration/components/nested-control-flow.tsrx +202 -216
- package/tests/hydration/components/portal.tsrx +33 -41
- package/tests/hydration/components/reactivity.tsrx +26 -34
- package/tests/hydration/components/return.tsrx +4 -6
- package/tests/hydration/components/switch.tsrx +73 -78
- package/tests/hydration/components/track-async-serialization.tsrx +83 -93
- package/tests/hydration/components/try.tsrx +37 -51
- package/tests/hydration/switch.test.js +8 -8
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +117 -162
- package/tests/server/basic.components.test.tsrx +163 -193
- package/tests/server/basic.test.tsrx +298 -198
- package/tests/server/compiler.test.tsrx +142 -72
- package/tests/server/composite.props.test.tsrx +54 -58
- package/tests/server/composite.test.tsrx +165 -167
- package/tests/server/context.test.tsrx +13 -17
- package/tests/server/dynamic-elements.test.tsrx +103 -135
- package/tests/server/for.test.tsrx +115 -84
- package/tests/server/head.test.tsrx +31 -31
- package/tests/server/html-nesting-validation.test.tsrx +16 -8
- package/tests/server/if.test.tsrx +49 -59
- package/tests/server/lazy-destructuring.test.tsrx +288 -366
- package/tests/server/return.test.tsrx +58 -36
- package/tests/server/streaming-ssr.test.tsrx +4 -4
- package/tests/server/style-identifier.test.tsrx +58 -66
- package/tests/server/switch.test.tsrx +89 -97
- package/tests/server/track-async-serialization.test.tsrx +85 -103
- package/tests/server/try.test.tsrx +275 -360
- package/tests/utils/ref-types.test.js +72 -0
- package/tests/utils/vite-plugin-config.test.js +41 -74
- package/types/index.d.ts +1 -0
- package/src/runtime/internal/client/compat.js +0 -40
- package/tests/utils/compiler-compat-config.test.js +0 -38
|
@@ -3,8 +3,8 @@ import { RippleArray, RippleObject, flushSync, track } from 'ripple';
|
|
|
3
3
|
|
|
4
4
|
describe('basic client > attribute rendering', () => {
|
|
5
5
|
it('render static attributes', () => {
|
|
6
|
-
function Basic() {
|
|
7
|
-
|
|
6
|
+
function Basic() @{
|
|
7
|
+
<div class="foo" id="bar" style="color: red;">{'Hello World'}</div>
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
render(Basic);
|
|
@@ -13,23 +13,21 @@ describe('basic client > attribute rendering', () => {
|
|
|
13
13
|
});
|
|
14
14
|
|
|
15
15
|
it('render dynamic class attribute', () => {
|
|
16
|
-
function Basic() {
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
function Basic() @{
|
|
17
|
+
let &[active] = track(false);
|
|
18
|
+
<>
|
|
19
19
|
<button
|
|
20
20
|
onClick={() => {
|
|
21
21
|
active = !active;
|
|
22
22
|
}}
|
|
23
|
-
>
|
|
24
|
-
{'Toggle'}
|
|
25
|
-
</button>
|
|
23
|
+
>{'Toggle'}</button>
|
|
26
24
|
<div class={active ? 'active' : 'inactive'}>{'Dynamic Class'}</div>
|
|
27
25
|
<style>
|
|
28
26
|
.active {
|
|
29
27
|
color: green;
|
|
30
28
|
}
|
|
31
29
|
</style>
|
|
32
|
-
|
|
30
|
+
</>
|
|
33
31
|
}
|
|
34
32
|
|
|
35
33
|
render(Basic);
|
|
@@ -51,8 +49,8 @@ describe('basic client > attribute rendering', () => {
|
|
|
51
49
|
});
|
|
52
50
|
|
|
53
51
|
it('render class attribute with array, nested array, nested object', () => {
|
|
54
|
-
function Basic() {
|
|
55
|
-
|
|
52
|
+
function Basic() @{
|
|
53
|
+
<>
|
|
56
54
|
<div
|
|
57
55
|
class={[
|
|
58
56
|
'foo',
|
|
@@ -66,15 +64,13 @@ describe('basic client > attribute rendering', () => {
|
|
|
66
64
|
{ eee: true, fff: false },
|
|
67
65
|
],
|
|
68
66
|
]}
|
|
69
|
-
>
|
|
70
|
-
{'Class Array'}
|
|
71
|
-
</div>
|
|
67
|
+
>{'Class Array'}</div>
|
|
72
68
|
<style>
|
|
73
69
|
.foo {
|
|
74
70
|
color: red;
|
|
75
71
|
}
|
|
76
72
|
</style>
|
|
77
|
-
|
|
73
|
+
</>
|
|
78
74
|
}
|
|
79
75
|
|
|
80
76
|
render(Basic);
|
|
@@ -94,23 +90,21 @@ describe('basic client > attribute rendering', () => {
|
|
|
94
90
|
});
|
|
95
91
|
|
|
96
92
|
it('render dynamic class object', () => {
|
|
97
|
-
function Basic() {
|
|
98
|
-
|
|
99
|
-
|
|
93
|
+
function Basic() @{
|
|
94
|
+
let &[active] = track(false);
|
|
95
|
+
<>
|
|
100
96
|
<button
|
|
101
97
|
onClick={() => {
|
|
102
98
|
active = !active;
|
|
103
99
|
}}
|
|
104
|
-
>
|
|
105
|
-
{'Toggle'}
|
|
106
|
-
</button>
|
|
100
|
+
>{'Toggle'}</button>
|
|
107
101
|
<div class={{ active: active, inactive: !active }}>{'Dynamic Class'}</div>
|
|
108
102
|
<style>
|
|
109
103
|
.active {
|
|
110
104
|
color: green;
|
|
111
105
|
}
|
|
112
106
|
</style>
|
|
113
|
-
|
|
107
|
+
</>
|
|
114
108
|
}
|
|
115
109
|
|
|
116
110
|
render(Basic);
|
|
@@ -135,9 +129,9 @@ describe('basic client > attribute rendering', () => {
|
|
|
135
129
|
});
|
|
136
130
|
|
|
137
131
|
it('applies scoped ripple class to multiple elements with dynamic class expressions', () => {
|
|
138
|
-
function Basic() {
|
|
139
|
-
|
|
140
|
-
|
|
132
|
+
function Basic() @{
|
|
133
|
+
let &[selected] = track(1);
|
|
134
|
+
<>
|
|
141
135
|
<div class={selected === 0 ? 'selected' : ''}>{`div 1`}</div>
|
|
142
136
|
<div class={selected === 0 ? 'selected' : ''}>{`div 2`}</div>
|
|
143
137
|
<style>
|
|
@@ -149,7 +143,7 @@ describe('basic client > attribute rendering', () => {
|
|
|
149
143
|
background: indigo;
|
|
150
144
|
}
|
|
151
145
|
</style>
|
|
152
|
-
|
|
146
|
+
</>
|
|
153
147
|
}
|
|
154
148
|
|
|
155
149
|
render(Basic);
|
|
@@ -164,18 +158,16 @@ describe('basic client > attribute rendering', () => {
|
|
|
164
158
|
});
|
|
165
159
|
|
|
166
160
|
it('render dynamic id attribute', () => {
|
|
167
|
-
function Basic() {
|
|
168
|
-
|
|
169
|
-
|
|
161
|
+
function Basic() @{
|
|
162
|
+
let &[count] = track(0);
|
|
163
|
+
<>
|
|
170
164
|
<button
|
|
171
165
|
onClick={() => {
|
|
172
166
|
count++;
|
|
173
167
|
}}
|
|
174
|
-
>
|
|
175
|
-
{'Increment'}
|
|
176
|
-
</button>
|
|
168
|
+
>{'Increment'}</button>
|
|
177
169
|
<div id={`item-${count}`}>{'Dynamic ID'}</div>
|
|
178
|
-
|
|
170
|
+
</>
|
|
179
171
|
}
|
|
180
172
|
|
|
181
173
|
render(Basic);
|
|
@@ -197,18 +189,16 @@ describe('basic client > attribute rendering', () => {
|
|
|
197
189
|
});
|
|
198
190
|
|
|
199
191
|
it('render dynamic style attribute', () => {
|
|
200
|
-
function Basic() {
|
|
201
|
-
|
|
202
|
-
|
|
192
|
+
function Basic() @{
|
|
193
|
+
let &[color] = track('red');
|
|
194
|
+
<>
|
|
203
195
|
<button
|
|
204
196
|
onClick={() => {
|
|
205
197
|
color = color === 'red' ? 'blue' : 'red';
|
|
206
198
|
}}
|
|
207
|
-
>
|
|
208
|
-
{'Change Color'}
|
|
209
|
-
</button>
|
|
199
|
+
>{'Change Color'}</button>
|
|
210
200
|
<div style={`color: ${color}; font-weight: bold;`}>{'Dynamic Style'}</div>
|
|
211
|
-
|
|
201
|
+
</>
|
|
212
202
|
}
|
|
213
203
|
|
|
214
204
|
render(Basic);
|
|
@@ -227,18 +217,16 @@ describe('basic client > attribute rendering', () => {
|
|
|
227
217
|
});
|
|
228
218
|
|
|
229
219
|
it('render style attribute as dynamic object', () => {
|
|
230
|
-
function Basic() {
|
|
231
|
-
|
|
232
|
-
|
|
220
|
+
function Basic() @{
|
|
221
|
+
let &[color] = track('red');
|
|
222
|
+
<>
|
|
233
223
|
<button
|
|
234
224
|
onClick={() => {
|
|
235
225
|
color = color === 'red' ? 'blue' : 'red';
|
|
236
226
|
}}
|
|
237
|
-
>
|
|
238
|
-
{'Change Color'}
|
|
239
|
-
</button>
|
|
227
|
+
>{'Change Color'}</button>
|
|
240
228
|
<div style={{ color: color, fontWeight: 'bold' }}>{'Dynamic Style'}</div>
|
|
241
|
-
|
|
229
|
+
</>
|
|
242
230
|
}
|
|
243
231
|
|
|
244
232
|
render(Basic);
|
|
@@ -257,15 +245,15 @@ describe('basic client > attribute rendering', () => {
|
|
|
257
245
|
});
|
|
258
246
|
|
|
259
247
|
it('render tracked variable as style attribute', () => {
|
|
260
|
-
function Basic() {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
248
|
+
function Basic() @{
|
|
249
|
+
let &[style] = track({ color: 'red', fontWeight: 'bold' });
|
|
250
|
+
function toggleColor() {
|
|
251
|
+
style = { ...style, color: style.color === 'red' ? 'blue' : 'red' };
|
|
252
|
+
}
|
|
253
|
+
<>
|
|
266
254
|
<button onClick={toggleColor}>{'Change Color'}</button>
|
|
267
255
|
<div {style}>{'Dynamic Style'}</div>
|
|
268
|
-
|
|
256
|
+
</>
|
|
269
257
|
}
|
|
270
258
|
|
|
271
259
|
render(Basic);
|
|
@@ -284,15 +272,15 @@ describe('basic client > attribute rendering', () => {
|
|
|
284
272
|
});
|
|
285
273
|
|
|
286
274
|
it('render tracked object as style attribute', () => {
|
|
287
|
-
function Basic() {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
275
|
+
function Basic() @{
|
|
276
|
+
let style = new RippleObject({ color: 'red', fontWeight: 'bold' });
|
|
277
|
+
function toggleColor() {
|
|
278
|
+
style.color = style.color === 'red' ? 'blue' : 'red';
|
|
279
|
+
}
|
|
280
|
+
<>
|
|
293
281
|
<button onClick={toggleColor}>{'Change Color'}</button>
|
|
294
282
|
<div style={{ color: style.color, fontWeight: style.fontWeight }}>{'Dynamic Style'}</div>
|
|
295
|
-
|
|
283
|
+
</>
|
|
296
284
|
}
|
|
297
285
|
|
|
298
286
|
render(Basic);
|
|
@@ -311,14 +299,12 @@ describe('basic client > attribute rendering', () => {
|
|
|
311
299
|
});
|
|
312
300
|
|
|
313
301
|
it('render spread attributes with style and class', () => {
|
|
314
|
-
function Basic() {
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
<div {...attributes}>{'Attributes with style and class'}</div>
|
|
321
|
-
</>;
|
|
302
|
+
function Basic() @{
|
|
303
|
+
const attributes = {
|
|
304
|
+
style: { color: 'red', fontWeight: 'bold' },
|
|
305
|
+
class: ['foo', false && 'bar'],
|
|
306
|
+
};
|
|
307
|
+
<div {...attributes}>{'Attributes with style and class'}</div>
|
|
322
308
|
}
|
|
323
309
|
|
|
324
310
|
render(Basic);
|
|
@@ -333,13 +319,11 @@ describe('basic client > attribute rendering', () => {
|
|
|
333
319
|
});
|
|
334
320
|
|
|
335
321
|
it('render spread props without duplication', () => {
|
|
336
|
-
function App() {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
<
|
|
340
|
-
|
|
341
|
-
</div>
|
|
342
|
-
</>;
|
|
322
|
+
function App() @{
|
|
323
|
+
const checkBoxProp = { name: 'car' };
|
|
324
|
+
<div>
|
|
325
|
+
<input {...checkBoxProp} type="checkbox" id="vehicle1" value="Bike" />
|
|
326
|
+
</div>
|
|
343
327
|
}
|
|
344
328
|
|
|
345
329
|
render(App);
|
|
@@ -359,20 +343,18 @@ describe('basic client > attribute rendering', () => {
|
|
|
359
343
|
});
|
|
360
344
|
|
|
361
345
|
it('render dynamic boolean attributes', () => {
|
|
362
|
-
function Basic() {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
346
|
+
function Basic() @{
|
|
347
|
+
let &[disabled] = track(false);
|
|
348
|
+
let &[checked] = track(false);
|
|
349
|
+
<>
|
|
366
350
|
<button
|
|
367
351
|
onClick={() => {
|
|
368
352
|
disabled = !disabled;
|
|
369
353
|
checked = !checked;
|
|
370
354
|
}}
|
|
371
|
-
>
|
|
372
|
-
{'Toggle'}
|
|
373
|
-
</button>
|
|
355
|
+
>{'Toggle'}</button>
|
|
374
356
|
<input type="checkbox" {disabled} {checked} />
|
|
375
|
-
|
|
357
|
+
</>
|
|
376
358
|
}
|
|
377
359
|
|
|
378
360
|
render(Basic);
|
|
@@ -391,22 +373,22 @@ describe('basic client > attribute rendering', () => {
|
|
|
391
373
|
});
|
|
392
374
|
|
|
393
375
|
it('render multiple dynamic attributes', () => {
|
|
394
|
-
function Basic() {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
376
|
+
function Basic() @{
|
|
377
|
+
let &[theme] = track('light');
|
|
378
|
+
let &[size] = track('medium');
|
|
379
|
+
<>
|
|
398
380
|
<button
|
|
399
381
|
onClick={() => {
|
|
400
382
|
theme = theme === 'light' ? 'dark' : 'light';
|
|
401
383
|
size = size === 'medium' ? 'large' : 'medium';
|
|
402
384
|
}}
|
|
403
|
-
>
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
{
|
|
408
|
-
</div>
|
|
409
|
-
|
|
385
|
+
>{'Toggle Theme & Size'}</button>
|
|
386
|
+
<div
|
|
387
|
+
class={`theme-${theme} size-${size}`}
|
|
388
|
+
data-theme={theme}
|
|
389
|
+
data-size={size}
|
|
390
|
+
>{'Multiple Dynamic Attributes'}</div>
|
|
391
|
+
</>
|
|
410
392
|
}
|
|
411
393
|
|
|
412
394
|
render(Basic);
|
|
@@ -427,25 +409,21 @@ describe('basic client > attribute rendering', () => {
|
|
|
427
409
|
});
|
|
428
410
|
|
|
429
411
|
it('render conditional attributes', () => {
|
|
430
|
-
function Basic() {
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
412
|
+
function Basic() @{
|
|
413
|
+
let &[showTitle] = track(false);
|
|
414
|
+
let &[showAria] = track(false);
|
|
415
|
+
<>
|
|
434
416
|
<button
|
|
435
417
|
onClick={() => {
|
|
436
418
|
showTitle = !showTitle;
|
|
437
419
|
showAria = !showAria;
|
|
438
420
|
}}
|
|
439
|
-
>
|
|
440
|
-
{'Toggle Attributes'}
|
|
441
|
-
</button>
|
|
421
|
+
>{'Toggle Attributes'}</button>
|
|
442
422
|
<div
|
|
443
423
|
title={showTitle ? 'This is a title' : undefined}
|
|
444
424
|
aria-label={showAria ? 'Accessible label' : undefined}
|
|
445
|
-
>
|
|
446
|
-
|
|
447
|
-
</div>
|
|
448
|
-
</>;
|
|
425
|
+
>{'Conditional Attributes'}</div>
|
|
426
|
+
</>
|
|
449
427
|
}
|
|
450
428
|
|
|
451
429
|
render(Basic);
|
|
@@ -470,12 +448,12 @@ describe('basic client > attribute rendering', () => {
|
|
|
470
448
|
});
|
|
471
449
|
|
|
472
450
|
it('render spread attributes', () => {
|
|
473
|
-
function Basic() {
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
451
|
+
function Basic() @{
|
|
452
|
+
let &[attrs] = track<TestAttributes>({
|
|
453
|
+
class: 'initial',
|
|
454
|
+
id: 'test-1',
|
|
455
|
+
});
|
|
456
|
+
<>
|
|
479
457
|
<button
|
|
480
458
|
onClick={() => {
|
|
481
459
|
attrs = {
|
|
@@ -484,11 +462,9 @@ describe('basic client > attribute rendering', () => {
|
|
|
484
462
|
'data-extra': 'value',
|
|
485
463
|
};
|
|
486
464
|
}}
|
|
487
|
-
>
|
|
488
|
-
{'Update Attributes'}
|
|
489
|
-
</button>
|
|
465
|
+
>{'Update Attributes'}</button>
|
|
490
466
|
<div {...attrs}>{'Spread Attributes'}</div>
|
|
491
|
-
|
|
467
|
+
</>
|
|
492
468
|
}
|
|
493
469
|
|
|
494
470
|
render(Basic);
|
|
@@ -509,16 +485,15 @@ describe('basic client > attribute rendering', () => {
|
|
|
509
485
|
});
|
|
510
486
|
|
|
511
487
|
it('renders with reactive attributes with nested reactive attributes', () => {
|
|
512
|
-
function App() {
|
|
513
|
-
|
|
514
|
-
|
|
488
|
+
function App() @{
|
|
489
|
+
let &[value] = track('parent-class');
|
|
490
|
+
let &[nested] = track('nested-class');
|
|
491
|
+
<>
|
|
515
492
|
<p class={value}>{'Colored parent value'}</p>
|
|
516
493
|
<div>
|
|
517
|
-
let &[nested] = track('nested-class');
|
|
518
|
-
|
|
519
494
|
<p class={nested}>{'Colored nested value'}</p>
|
|
520
495
|
</div>
|
|
521
|
-
|
|
496
|
+
</>
|
|
522
497
|
}
|
|
523
498
|
|
|
524
499
|
render(App);
|
|
@@ -530,13 +505,11 @@ describe('basic client > attribute rendering', () => {
|
|
|
530
505
|
});
|
|
531
506
|
|
|
532
507
|
it('handles boolean attributes with no prop value provides', () => {
|
|
533
|
-
function App() {
|
|
534
|
-
|
|
535
|
-
<
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
</div>
|
|
539
|
-
</>;
|
|
508
|
+
function App() @{
|
|
509
|
+
<div class="container">
|
|
510
|
+
<button onClick={() => console.log('clicked!')} disabled>{'Button'}</button>
|
|
511
|
+
<input type="checkbox" checked />
|
|
512
|
+
</div>
|
|
540
513
|
}
|
|
541
514
|
|
|
542
515
|
render(App);
|
|
@@ -544,15 +517,15 @@ describe('basic client > attribute rendering', () => {
|
|
|
544
517
|
});
|
|
545
518
|
|
|
546
519
|
it('handles boolean props correctly', () => {
|
|
547
|
-
function App() {
|
|
548
|
-
|
|
520
|
+
function App() @{
|
|
521
|
+
<>
|
|
549
522
|
<div data-disabled />
|
|
550
523
|
<Child isDisabled />
|
|
551
|
-
|
|
524
|
+
</>
|
|
552
525
|
}
|
|
553
526
|
|
|
554
|
-
function Child({ isDisabled }: { isDisabled: boolean }) {
|
|
555
|
-
|
|
527
|
+
function Child({ isDisabled }: { isDisabled: boolean }) @{
|
|
528
|
+
<input disabled={isDisabled} />
|
|
556
529
|
}
|
|
557
530
|
|
|
558
531
|
render(App);
|
|
@@ -560,29 +533,27 @@ describe('basic client > attribute rendering', () => {
|
|
|
560
533
|
});
|
|
561
534
|
|
|
562
535
|
it('handles reactive event handler changes', () => {
|
|
563
|
-
function Basic() {
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
536
|
+
function Basic() @{
|
|
537
|
+
let &[count] = track(0);
|
|
538
|
+
let &[mode] = track<'increment' | 'decrement'>('increment');
|
|
539
|
+
const incrementHandler = () => {
|
|
540
|
+
count++;
|
|
541
|
+
};
|
|
542
|
+
const decrementHandler = () => {
|
|
543
|
+
count--;
|
|
544
|
+
};
|
|
545
|
+
<>
|
|
573
546
|
<button
|
|
574
547
|
onClick={() => {
|
|
575
548
|
mode = mode === 'increment' ? 'decrement' : 'increment';
|
|
576
549
|
}}
|
|
577
550
|
class="toggle-mode"
|
|
578
|
-
>
|
|
579
|
-
{'Toggle Mode'}
|
|
580
|
-
</button>
|
|
551
|
+
>{'Toggle Mode'}</button>
|
|
581
552
|
<button onClick={mode === 'increment' ? incrementHandler : decrementHandler} class="action">
|
|
582
553
|
{mode === 'increment' ? '+' : '-'}
|
|
583
554
|
</button>
|
|
584
555
|
<div class="count">{count}</div>
|
|
585
|
-
|
|
556
|
+
</>
|
|
586
557
|
}
|
|
587
558
|
|
|
588
559
|
render(Basic);
|
|
@@ -616,23 +587,21 @@ describe('basic client > attribute rendering', () => {
|
|
|
616
587
|
});
|
|
617
588
|
|
|
618
589
|
it('handles events with capture option', () => {
|
|
619
|
-
function Basic() {
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
<
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
</div>
|
|
635
|
-
</>;
|
|
590
|
+
function Basic() @{
|
|
591
|
+
let captureOrder: RippleArray<string> = new RippleArray();
|
|
592
|
+
const handleCaptureClick = {
|
|
593
|
+
handleEvent() {
|
|
594
|
+
captureOrder.push('capture');
|
|
595
|
+
},
|
|
596
|
+
capture: true,
|
|
597
|
+
};
|
|
598
|
+
const handleBubbleClick = () => {
|
|
599
|
+
captureOrder.push('bubble');
|
|
600
|
+
};
|
|
601
|
+
<div onClick={handleCaptureClick} class="outer">
|
|
602
|
+
<button onClick={handleBubbleClick} class="inner">{'Click'}</button>
|
|
603
|
+
<div class="order">{captureOrder.join(' -> ')}</div>
|
|
604
|
+
</div>
|
|
636
605
|
}
|
|
637
606
|
|
|
638
607
|
render(Basic);
|
|
@@ -649,20 +618,18 @@ describe('basic client > attribute rendering', () => {
|
|
|
649
618
|
});
|
|
650
619
|
|
|
651
620
|
it('handles events with Capture suffix in the name', () => {
|
|
652
|
-
function Basic() {
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
<
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
</div>
|
|
665
|
-
</>;
|
|
621
|
+
function Basic() @{
|
|
622
|
+
let captureOrder: RippleArray<string> = new RippleArray();
|
|
623
|
+
const handleCaptureClick = () => {
|
|
624
|
+
captureOrder.push('capture');
|
|
625
|
+
};
|
|
626
|
+
const handleBubbleClick = () => {
|
|
627
|
+
captureOrder.push('bubble');
|
|
628
|
+
};
|
|
629
|
+
<div onClickCapture={handleCaptureClick} class="outer">
|
|
630
|
+
<button onClick={handleBubbleClick} class="inner">{'Click'}</button>
|
|
631
|
+
<div class="order">{captureOrder.join(' -> ')}</div>
|
|
632
|
+
</div>
|
|
666
633
|
}
|
|
667
634
|
|
|
668
635
|
render(Basic);
|
|
@@ -679,20 +646,18 @@ describe('basic client > attribute rendering', () => {
|
|
|
679
646
|
});
|
|
680
647
|
|
|
681
648
|
it('handles custom events with customName option', () => {
|
|
682
|
-
function Basic() {
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
<div>
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
</div>
|
|
695
|
-
</>;
|
|
649
|
+
function Basic() @{
|
|
650
|
+
let &[customEventCount] = track(0);
|
|
651
|
+
const handleCustom = {
|
|
652
|
+
handleEvent(event: CustomEvent) {
|
|
653
|
+
customEventCount += event.detail.value;
|
|
654
|
+
},
|
|
655
|
+
customName: 'MyCustomEvent',
|
|
656
|
+
};
|
|
657
|
+
<div>
|
|
658
|
+
<div onMyCustomEvent={handleCustom} class="custom-target">{'Custom'}</div>
|
|
659
|
+
<div class="custom-count">{customEventCount}</div>
|
|
660
|
+
</div>
|
|
696
661
|
}
|
|
697
662
|
|
|
698
663
|
render(Basic);
|
|
@@ -714,26 +679,24 @@ describe('basic client > attribute rendering', () => {
|
|
|
714
679
|
});
|
|
715
680
|
|
|
716
681
|
it('handles events with delegated: false option to bypass delegation', () => {
|
|
717
|
-
function Basic() {
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
<
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
</div>
|
|
736
|
-
</>;
|
|
682
|
+
function Basic() @{
|
|
683
|
+
let &[delegatedCount] = track(0);
|
|
684
|
+
let &[nonDelegatedCount] = track(0);
|
|
685
|
+
const delegatedHandler = () => {
|
|
686
|
+
delegatedCount++;
|
|
687
|
+
};
|
|
688
|
+
const nonDelegatedHandler = {
|
|
689
|
+
handleEvent() {
|
|
690
|
+
nonDelegatedCount++;
|
|
691
|
+
},
|
|
692
|
+
delegated: false,
|
|
693
|
+
};
|
|
694
|
+
<div>
|
|
695
|
+
<button onClick={delegatedHandler} class="delegated-btn">{'Delegated'}</button>
|
|
696
|
+
<button onClick={nonDelegatedHandler} class="non-delegated-btn">{'Non-Delegated'}</button>
|
|
697
|
+
<div class="delegated-count">{delegatedCount}</div>
|
|
698
|
+
<div class="non-delegated-count">{nonDelegatedCount}</div>
|
|
699
|
+
</div>
|
|
737
700
|
}
|
|
738
701
|
|
|
739
702
|
render(Basic);
|
|
@@ -762,33 +725,32 @@ describe('basic client > attribute rendering', () => {
|
|
|
762
725
|
const delegatedClicks: number[] = [];
|
|
763
726
|
const nonDelegatedClicks: number[] = [];
|
|
764
727
|
|
|
765
|
-
function Basic() {
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
<div>
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
</div>
|
|
728
|
+
function Basic() @{
|
|
729
|
+
const makeDelegatedHandler = (id: number) => () => {
|
|
730
|
+
delegatedClicks.push(id);
|
|
731
|
+
};
|
|
732
|
+
const makeNonDelegatedHandler = (id: number) => ({
|
|
733
|
+
handleEvent() {
|
|
734
|
+
nonDelegatedClicks.push(id);
|
|
735
|
+
},
|
|
736
|
+
delegated: false,
|
|
737
|
+
});
|
|
738
|
+
const buttonIds = [0, 1, 2, 3, 4];
|
|
739
|
+
<div>
|
|
740
|
+
<div class="delegated-buttons">
|
|
741
|
+
@for (const i of buttonIds) {
|
|
742
|
+
<button onClick={makeDelegatedHandler(i)} class={`delegated-${i}`}>{`D${i}`}</button>
|
|
743
|
+
}
|
|
744
|
+
</div>
|
|
745
|
+
<div class="non-delegated-buttons">
|
|
746
|
+
@for (const i of buttonIds) {
|
|
747
|
+
<button
|
|
748
|
+
onClick={makeNonDelegatedHandler(i)}
|
|
749
|
+
class={`non-delegated-${i}`}
|
|
750
|
+
>{`ND${i}`}</button>
|
|
751
|
+
}
|
|
790
752
|
</div>
|
|
791
|
-
|
|
753
|
+
</div>
|
|
792
754
|
}
|
|
793
755
|
|
|
794
756
|
render(Basic);
|
|
@@ -826,25 +788,23 @@ describe('basic client > attribute rendering', () => {
|
|
|
826
788
|
});
|
|
827
789
|
|
|
828
790
|
it('handles events defined as function directly vs as object', () => {
|
|
829
|
-
function Basic() {
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
<
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
</div>
|
|
847
|
-
</>;
|
|
791
|
+
function Basic() @{
|
|
792
|
+
let &[functionCount] = track(0);
|
|
793
|
+
let &[objectCount] = track(0);
|
|
794
|
+
const functionHandler = () => {
|
|
795
|
+
functionCount++;
|
|
796
|
+
};
|
|
797
|
+
const objectHandler = {
|
|
798
|
+
handleEvent() {
|
|
799
|
+
objectCount++;
|
|
800
|
+
},
|
|
801
|
+
};
|
|
802
|
+
<div>
|
|
803
|
+
<button onClick={functionHandler} class="function-btn">{'Function'}</button>
|
|
804
|
+
<button onClick={objectHandler} class="object-btn">{'Object'}</button>
|
|
805
|
+
<div class="function-count">{functionCount}</div>
|
|
806
|
+
<div class="object-count">{objectCount}</div>
|
|
807
|
+
</div>
|
|
848
808
|
}
|
|
849
809
|
|
|
850
810
|
render(Basic);
|
|
@@ -878,46 +838,44 @@ describe('basic client > attribute rendering', () => {
|
|
|
878
838
|
});
|
|
879
839
|
|
|
880
840
|
it('handles passive event option', () => {
|
|
881
|
-
function Basic() {
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
<div>
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
: 'not-prevented'}
|
|
918
|
-
</div>
|
|
841
|
+
function Basic() @{
|
|
842
|
+
let &[passiveDefaultPrevented] = track<boolean | null>(null);
|
|
843
|
+
let &[nonPassiveDefaultPrevented] = track<boolean | null>(null);
|
|
844
|
+
const passiveHandler = {
|
|
845
|
+
handleEvent(event: Event) {
|
|
846
|
+
event.preventDefault();
|
|
847
|
+
// In passive listeners, preventDefault() is ignored
|
|
848
|
+
passiveDefaultPrevented = event.defaultPrevented;
|
|
849
|
+
},
|
|
850
|
+
passive: true,
|
|
851
|
+
delegated: false, // Need to ensure it's not delegated to test passive properly
|
|
852
|
+
};
|
|
853
|
+
const nonPassiveHandler = {
|
|
854
|
+
handleEvent(event: Event) {
|
|
855
|
+
event.preventDefault();
|
|
856
|
+
// In non-passive listeners, preventDefault() works
|
|
857
|
+
nonPassiveDefaultPrevented = event.defaultPrevented;
|
|
858
|
+
},
|
|
859
|
+
delegated: false,
|
|
860
|
+
};
|
|
861
|
+
<div>
|
|
862
|
+
<div onWheel={passiveHandler} class="passive-target">{'Passive'}</div>
|
|
863
|
+
<div onWheel={nonPassiveHandler} class="non-passive-target">{'Non-Passive'}</div>
|
|
864
|
+
<div class="passive-result">
|
|
865
|
+
{passiveDefaultPrevented === null
|
|
866
|
+
? 'not-tested'
|
|
867
|
+
: passiveDefaultPrevented
|
|
868
|
+
? 'prevented'
|
|
869
|
+
: 'not-prevented'}
|
|
870
|
+
</div>
|
|
871
|
+
<div class="non-passive-result">
|
|
872
|
+
{nonPassiveDefaultPrevented === null
|
|
873
|
+
? 'not-tested'
|
|
874
|
+
: nonPassiveDefaultPrevented
|
|
875
|
+
? 'prevented'
|
|
876
|
+
: 'not-prevented'}
|
|
919
877
|
</div>
|
|
920
|
-
|
|
878
|
+
</div>
|
|
921
879
|
}
|
|
922
880
|
|
|
923
881
|
render(Basic);
|
|
@@ -942,26 +900,24 @@ describe('basic client > attribute rendering', () => {
|
|
|
942
900
|
});
|
|
943
901
|
|
|
944
902
|
it('handles once option to fire event only once', () => {
|
|
945
|
-
function Basic() {
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
<
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
</div>
|
|
964
|
-
</>;
|
|
903
|
+
function Basic() @{
|
|
904
|
+
let &[onceCount] = track(0);
|
|
905
|
+
let &[regularCount] = track(0);
|
|
906
|
+
const onceHandler = {
|
|
907
|
+
handleEvent() {
|
|
908
|
+
onceCount++;
|
|
909
|
+
},
|
|
910
|
+
once: true,
|
|
911
|
+
};
|
|
912
|
+
const regularHandler = () => {
|
|
913
|
+
regularCount++;
|
|
914
|
+
};
|
|
915
|
+
<div>
|
|
916
|
+
<button onClick={onceHandler} class="once-btn">{'Once'}</button>
|
|
917
|
+
<button onClick={regularHandler} class="regular-btn">{'Regular'}</button>
|
|
918
|
+
<div class="once-count">{onceCount}</div>
|
|
919
|
+
<div class="regular-count">{regularCount}</div>
|
|
920
|
+
</div>
|
|
965
921
|
}
|
|
966
922
|
|
|
967
923
|
render(Basic);
|