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
|
@@ -2,53 +2,51 @@ import { flushSync, track } from 'ripple';
|
|
|
2
2
|
|
|
3
3
|
describe('tsx expression', () => {
|
|
4
4
|
it('renders an empty <></> element', () => {
|
|
5
|
-
function App() {
|
|
6
|
-
|
|
7
|
-
<></>
|
|
8
|
-
</>;
|
|
5
|
+
function App() @{
|
|
6
|
+
<></>
|
|
9
7
|
}
|
|
10
8
|
render(App);
|
|
11
9
|
expect(container.textContent).toBe('');
|
|
12
10
|
});
|
|
13
11
|
|
|
14
12
|
it('renders an empty <></> fragment shorthand', () => {
|
|
15
|
-
function App() {
|
|
16
|
-
|
|
17
|
-
<></>
|
|
18
|
-
</>;
|
|
13
|
+
function App() @{
|
|
14
|
+
<></>
|
|
19
15
|
}
|
|
20
16
|
render(App);
|
|
21
17
|
expect(container.textContent).toBe('');
|
|
22
18
|
});
|
|
23
19
|
|
|
24
20
|
it('renders an empty <></> assigned to a variable', () => {
|
|
25
|
-
function App() {
|
|
26
|
-
|
|
27
|
-
|
|
21
|
+
function App() @{
|
|
22
|
+
const el = <></>;
|
|
23
|
+
<>
|
|
28
24
|
{el}
|
|
29
|
-
|
|
25
|
+
</>
|
|
30
26
|
}
|
|
31
27
|
render(App);
|
|
32
28
|
expect(container.textContent).toBe('');
|
|
33
29
|
});
|
|
34
30
|
|
|
35
31
|
it('renders an empty <></> fragment assigned to a variable', () => {
|
|
36
|
-
function App() {
|
|
37
|
-
|
|
38
|
-
|
|
32
|
+
function App() @{
|
|
33
|
+
const el = <></>;
|
|
34
|
+
<>
|
|
39
35
|
{el}
|
|
40
|
-
|
|
36
|
+
</>
|
|
41
37
|
}
|
|
42
38
|
render(App);
|
|
43
39
|
expect(container.textContent).toBe('');
|
|
44
40
|
});
|
|
45
41
|
|
|
46
42
|
it('renders a basic fragment shorthand element', () => {
|
|
47
|
-
function App() {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
{el}
|
|
43
|
+
function App() @{
|
|
44
|
+
const el = <>
|
|
45
|
+
<div>{'hello world'}</div>
|
|
51
46
|
</>;
|
|
47
|
+
<>
|
|
48
|
+
{el}
|
|
49
|
+
</>
|
|
52
50
|
}
|
|
53
51
|
render(App);
|
|
54
52
|
expect(container.textContent).toBe('hello world');
|
|
@@ -56,8 +54,8 @@ describe('tsx expression', () => {
|
|
|
56
54
|
});
|
|
57
55
|
|
|
58
56
|
it('applies scoped classes inside tsx blocks and fragment shorthand', () => {
|
|
59
|
-
function App() {
|
|
60
|
-
|
|
57
|
+
function App() @{
|
|
58
|
+
<>
|
|
61
59
|
<>
|
|
62
60
|
<div class="card">
|
|
63
61
|
<h2>{'tsx block'}</h2>
|
|
@@ -77,7 +75,7 @@ describe('tsx expression', () => {
|
|
|
77
75
|
color: red;
|
|
78
76
|
}
|
|
79
77
|
</style>
|
|
80
|
-
|
|
78
|
+
</>
|
|
81
79
|
}
|
|
82
80
|
|
|
83
81
|
render(App);
|
|
@@ -102,11 +100,11 @@ describe('tsx expression', () => {
|
|
|
102
100
|
});
|
|
103
101
|
|
|
104
102
|
it('renders a tsx element assigned to a variable', () => {
|
|
105
|
-
function App() {
|
|
106
|
-
|
|
107
|
-
|
|
103
|
+
function App() @{
|
|
104
|
+
const el = <span class="test">{'content'}</span>;
|
|
105
|
+
<>
|
|
108
106
|
{el}
|
|
109
|
-
|
|
107
|
+
</>
|
|
110
108
|
}
|
|
111
109
|
render(App);
|
|
112
110
|
const span = container.querySelector('span.test');
|
|
@@ -115,14 +113,14 @@ describe('tsx expression', () => {
|
|
|
115
113
|
});
|
|
116
114
|
|
|
117
115
|
it('renders a tsx element with multiple children', () => {
|
|
118
|
-
function App() {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
<div>"second"</div>
|
|
123
|
-
</>;
|
|
124
|
-
{el}
|
|
116
|
+
function App() @{
|
|
117
|
+
const el = <>
|
|
118
|
+
<div>first</div>
|
|
119
|
+
<div>second</div>
|
|
125
120
|
</>;
|
|
121
|
+
<>
|
|
122
|
+
{el}
|
|
123
|
+
</>
|
|
126
124
|
}
|
|
127
125
|
render(App);
|
|
128
126
|
const divs = container.querySelectorAll('div');
|
|
@@ -132,15 +130,15 @@ describe('tsx expression', () => {
|
|
|
132
130
|
});
|
|
133
131
|
|
|
134
132
|
it('renders a tsx element with nested elements', () => {
|
|
135
|
-
function App() {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
<
|
|
139
|
-
|
|
140
|
-
</div>
|
|
141
|
-
</>;
|
|
142
|
-
{el}
|
|
133
|
+
function App() @{
|
|
134
|
+
const el = <>
|
|
135
|
+
<div class="outer">
|
|
136
|
+
<span class="inner">nested</span>
|
|
137
|
+
</div>
|
|
143
138
|
</>;
|
|
139
|
+
<>
|
|
140
|
+
{el}
|
|
141
|
+
</>
|
|
144
142
|
}
|
|
145
143
|
render(App);
|
|
146
144
|
const outer = container.querySelector('div.outer');
|
|
@@ -151,11 +149,9 @@ describe('tsx expression', () => {
|
|
|
151
149
|
});
|
|
152
150
|
|
|
153
151
|
it('renders a tsx element inline in a parent element', () => {
|
|
154
|
-
function App() {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
<div class="parent">{el}</div>
|
|
158
|
-
</>;
|
|
152
|
+
function App() @{
|
|
153
|
+
const el = <span>{'inline'}</span>;
|
|
154
|
+
<div class="parent">{el}</div>
|
|
159
155
|
}
|
|
160
156
|
render(App);
|
|
161
157
|
const parent = container.querySelector('div.parent');
|
|
@@ -165,17 +161,17 @@ describe('tsx expression', () => {
|
|
|
165
161
|
});
|
|
166
162
|
|
|
167
163
|
it('renders a tsx element with reactive expressions', () => {
|
|
168
|
-
function App() {
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
164
|
+
function App() @{
|
|
165
|
+
let &[count] = track(0);
|
|
166
|
+
const el = <>
|
|
167
|
+
<div>
|
|
168
|
+
{'count: ' + count}
|
|
169
|
+
</div>
|
|
170
|
+
</>;
|
|
171
|
+
<>
|
|
176
172
|
{el}
|
|
177
173
|
<button onClick={() => count++}>{'increment'}</button>
|
|
178
|
-
|
|
174
|
+
</>
|
|
179
175
|
}
|
|
180
176
|
render(App);
|
|
181
177
|
expect(container.querySelector('div').textContent).toBe('count: 0');
|
|
@@ -186,15 +182,17 @@ describe('tsx expression', () => {
|
|
|
186
182
|
});
|
|
187
183
|
|
|
188
184
|
it('conditionally renders tsx elements', () => {
|
|
189
|
-
function App() {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
if (show) {
|
|
194
|
-
|
|
185
|
+
function App() @{
|
|
186
|
+
let &[show] = track(true);
|
|
187
|
+
const el = <div class="tsx-content">{'content'}</div>;
|
|
188
|
+
<>
|
|
189
|
+
@if (show) {
|
|
190
|
+
<>
|
|
191
|
+
{el}
|
|
192
|
+
</>
|
|
195
193
|
}
|
|
196
194
|
<button onClick={() => (show = !show)}>{'toggle'}</button>
|
|
197
|
-
|
|
195
|
+
</>
|
|
198
196
|
}
|
|
199
197
|
render(App);
|
|
200
198
|
expect(container.querySelector('.tsx-content')).toBeTruthy();
|
|
@@ -209,15 +207,13 @@ describe('tsx expression', () => {
|
|
|
209
207
|
});
|
|
210
208
|
|
|
211
209
|
it('renders tsx element passed as children prop', () => {
|
|
212
|
-
function Child(&{ children }) {
|
|
213
|
-
|
|
210
|
+
function Child(&{ children }) @{
|
|
211
|
+
<div class="wrapper">{children}</div>
|
|
214
212
|
}
|
|
215
213
|
|
|
216
|
-
function App() {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
<Child children={el} />
|
|
220
|
-
</>;
|
|
214
|
+
function App() @{
|
|
215
|
+
const el = <span>{'from tsx'}</span>;
|
|
216
|
+
<Child children={el} />
|
|
221
217
|
}
|
|
222
218
|
render(App);
|
|
223
219
|
const wrapper = container.querySelector('.wrapper');
|
|
@@ -227,11 +223,11 @@ describe('tsx expression', () => {
|
|
|
227
223
|
});
|
|
228
224
|
|
|
229
225
|
it('renders tsx element with text content only', () => {
|
|
230
|
-
function App() {
|
|
231
|
-
|
|
232
|
-
|
|
226
|
+
function App() @{
|
|
227
|
+
const el = <>just text</>;
|
|
228
|
+
<>
|
|
233
229
|
{el}
|
|
234
|
-
|
|
230
|
+
</>
|
|
235
231
|
}
|
|
236
232
|
|
|
237
233
|
render(App);
|
|
@@ -239,13 +235,13 @@ describe('tsx expression', () => {
|
|
|
239
235
|
});
|
|
240
236
|
|
|
241
237
|
it('renders tsx element with static attributes', () => {
|
|
242
|
-
function App() {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
238
|
+
function App() @{
|
|
239
|
+
const el = <div id="my-id" class="my-class" data-testid="test" aria-label="label">
|
|
240
|
+
content
|
|
241
|
+
</div>;
|
|
242
|
+
<>
|
|
247
243
|
{el}
|
|
248
|
-
|
|
244
|
+
</>
|
|
249
245
|
}
|
|
250
246
|
|
|
251
247
|
render(App);
|
|
@@ -257,13 +253,13 @@ describe('tsx expression', () => {
|
|
|
257
253
|
});
|
|
258
254
|
|
|
259
255
|
it('renders tsx element with dynamic attribute values', () => {
|
|
260
|
-
function App() {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
256
|
+
function App() @{
|
|
257
|
+
let &[name] = track('initial');
|
|
258
|
+
const el = <div id={name} class={'cls-' + name}>{'content'}</div>;
|
|
259
|
+
<>
|
|
264
260
|
{el}
|
|
265
261
|
<button onClick={() => (name = 'updated')}>{'update'}</button>
|
|
266
|
-
|
|
262
|
+
</>
|
|
267
263
|
}
|
|
268
264
|
|
|
269
265
|
render(App);
|
|
@@ -278,13 +274,15 @@ describe('tsx expression', () => {
|
|
|
278
274
|
});
|
|
279
275
|
|
|
280
276
|
it('renders tsx element with event handlers', () => {
|
|
281
|
-
function App() {
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
277
|
+
function App() @{
|
|
278
|
+
let &[clicked] = track(false);
|
|
279
|
+
const el = <button onClick={() => (clicked = true)}>{'click'}</button>;
|
|
280
|
+
<>
|
|
285
281
|
{el}
|
|
286
|
-
<div class="status">
|
|
287
|
-
|
|
282
|
+
<div class="status">
|
|
283
|
+
{clicked ? 'clicked' : 'not clicked'}
|
|
284
|
+
</div>
|
|
285
|
+
</>
|
|
288
286
|
}
|
|
289
287
|
|
|
290
288
|
render(App);
|
|
@@ -296,13 +294,13 @@ describe('tsx expression', () => {
|
|
|
296
294
|
});
|
|
297
295
|
|
|
298
296
|
it('renders tsx element with boolean attributes', () => {
|
|
299
|
-
function App() {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
297
|
+
function App() @{
|
|
298
|
+
let &[isDisabled] = track(true);
|
|
299
|
+
const el = <button disabled={isDisabled}>{'submit'}</button>;
|
|
300
|
+
<>
|
|
303
301
|
{el}
|
|
304
302
|
<button class="toggle" onClick={() => (isDisabled = !isDisabled)}>{'toggle'}</button>
|
|
305
|
-
|
|
303
|
+
</>
|
|
306
304
|
}
|
|
307
305
|
|
|
308
306
|
render(App);
|
|
@@ -314,13 +312,13 @@ describe('tsx expression', () => {
|
|
|
314
312
|
});
|
|
315
313
|
|
|
316
314
|
it('renders tsx element with style attribute', () => {
|
|
317
|
-
function App() {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
315
|
+
function App() @{
|
|
316
|
+
let &[color] = track('red');
|
|
317
|
+
const el = <div style={{ color }}>{'content'}</div>;
|
|
318
|
+
<>
|
|
321
319
|
{el}
|
|
322
320
|
<button onClick={() => (color = 'blue')}>{'change color'}</button>
|
|
323
|
-
|
|
321
|
+
</>
|
|
324
322
|
}
|
|
325
323
|
|
|
326
324
|
render(App);
|
|
@@ -332,22 +330,20 @@ describe('tsx expression', () => {
|
|
|
332
330
|
});
|
|
333
331
|
|
|
334
332
|
it('renders tsx element with multiple dynamic attributes', () => {
|
|
335
|
-
function App() {
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
</div>
|
|
347
|
-
</>;
|
|
333
|
+
function App() @{
|
|
334
|
+
let &[index] = track(0);
|
|
335
|
+
const el = <div
|
|
336
|
+
id={'item-' + index}
|
|
337
|
+
class={'item pos-' + index}
|
|
338
|
+
data-index={index}
|
|
339
|
+
title={'Item ' + index}
|
|
340
|
+
>
|
|
341
|
+
{'Item ' + index}
|
|
342
|
+
</div>;
|
|
343
|
+
<>
|
|
348
344
|
{el}
|
|
349
345
|
<button onClick={() => index++}>{'next'}</button>
|
|
350
|
-
|
|
346
|
+
</>
|
|
351
347
|
}
|
|
352
348
|
|
|
353
349
|
render(App);
|
|
@@ -366,12 +362,12 @@ describe('tsx expression', () => {
|
|
|
366
362
|
});
|
|
367
363
|
|
|
368
364
|
it('renders fragment shorthand passed directly as component prop', () => {
|
|
369
|
-
function Wrapper(&{ content }) {
|
|
370
|
-
|
|
365
|
+
function Wrapper(&{ content }) @{
|
|
366
|
+
<div class="wrapper">{content}</div>
|
|
371
367
|
}
|
|
372
368
|
|
|
373
|
-
function App() {
|
|
374
|
-
|
|
369
|
+
function App() @{
|
|
370
|
+
<Wrapper content={<><span class="inner">direct prop</span></>} />
|
|
375
371
|
}
|
|
376
372
|
|
|
377
373
|
render(App);
|
|
@@ -382,22 +378,15 @@ describe('tsx expression', () => {
|
|
|
382
378
|
});
|
|
383
379
|
|
|
384
380
|
it('renders fragment shorthand passed directly as children prop', () => {
|
|
385
|
-
function Card(&{ title, children }) {
|
|
386
|
-
|
|
387
|
-
<
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
</div>
|
|
391
|
-
</>;
|
|
381
|
+
function Card(&{ title, children }) @{
|
|
382
|
+
<div class="card">
|
|
383
|
+
<h2 class="card-title">{title}</h2>
|
|
384
|
+
<div class="card-body">{children}</div>
|
|
385
|
+
</div>
|
|
392
386
|
}
|
|
393
387
|
|
|
394
|
-
function App() {
|
|
395
|
-
|
|
396
|
-
<Card
|
|
397
|
-
title={<><span class="bold">"Title"</span></>}
|
|
398
|
-
children={<><p>"Card content here"</p></>}
|
|
399
|
-
/>
|
|
400
|
-
</>;
|
|
388
|
+
function App() @{
|
|
389
|
+
<Card title={<><span class="bold">Title</span></>} children={<><p>Card content here</p></>} />
|
|
401
390
|
}
|
|
402
391
|
|
|
403
392
|
render(App);
|
|
@@ -407,15 +396,15 @@ describe('tsx expression', () => {
|
|
|
407
396
|
});
|
|
408
397
|
|
|
409
398
|
it('renders tsx from function defined outside component', () => {
|
|
410
|
-
function createBadge(label) {
|
|
411
|
-
|
|
399
|
+
function createBadge(label) @{
|
|
400
|
+
<span class="badge">{label}</span>
|
|
412
401
|
}
|
|
413
402
|
|
|
414
|
-
function App() {
|
|
415
|
-
|
|
416
|
-
|
|
403
|
+
function App() @{
|
|
404
|
+
const badge = createBadge('New');
|
|
405
|
+
<>
|
|
417
406
|
{badge}
|
|
418
|
-
|
|
407
|
+
</>
|
|
419
408
|
}
|
|
420
409
|
|
|
421
410
|
render(App);
|
|
@@ -424,19 +413,19 @@ describe('tsx expression', () => {
|
|
|
424
413
|
});
|
|
425
414
|
|
|
426
415
|
it('renders tsx from function with multiple elements', () => {
|
|
427
|
-
function createListItem(item) {
|
|
428
|
-
|
|
416
|
+
function createListItem(item) @{
|
|
417
|
+
<li class="list-item">{item}</li>
|
|
429
418
|
}
|
|
430
419
|
|
|
431
|
-
function App() {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
420
|
+
function App() @{
|
|
421
|
+
const items = ['Apple', 'Banana', 'Cherry'];
|
|
422
|
+
<ul>
|
|
423
|
+
@for (const item of items) {
|
|
424
|
+
<>
|
|
436
425
|
{createListItem(item)}
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
426
|
+
</>
|
|
427
|
+
}
|
|
428
|
+
</ul>
|
|
440
429
|
}
|
|
441
430
|
|
|
442
431
|
render(App);
|
|
@@ -448,26 +437,24 @@ describe('tsx expression', () => {
|
|
|
448
437
|
});
|
|
449
438
|
|
|
450
439
|
it('renders tsx from factory function passed to component', () => {
|
|
451
|
-
function List(&{ renderItem, items }) {
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
440
|
+
function List(&{ renderItem, items }) @{
|
|
441
|
+
<ul class="list">
|
|
442
|
+
@for (const item of items) {
|
|
443
|
+
<>
|
|
455
444
|
{renderItem(item)}
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
445
|
+
</>
|
|
446
|
+
}
|
|
447
|
+
</ul>
|
|
459
448
|
}
|
|
460
449
|
|
|
461
|
-
function itemRenderer(item) {
|
|
462
|
-
|
|
463
|
-
<
|
|
464
|
-
|
|
465
|
-
</li>
|
|
466
|
-
</>;
|
|
450
|
+
function itemRenderer(item) @{
|
|
451
|
+
<li>
|
|
452
|
+
<span class="item-content">{item}</span>
|
|
453
|
+
</li>
|
|
467
454
|
}
|
|
468
455
|
|
|
469
|
-
function App() {
|
|
470
|
-
|
|
456
|
+
function App() @{
|
|
457
|
+
<List items={['One', 'Two', 'Three']} renderItem={itemRenderer} />
|
|
471
458
|
}
|
|
472
459
|
|
|
473
460
|
render(App);
|
|
@@ -479,24 +466,20 @@ describe('tsx expression', () => {
|
|
|
479
466
|
});
|
|
480
467
|
|
|
481
468
|
it('renders tsx from function with reactive state', () => {
|
|
482
|
-
function createCounter(label, getCount) {
|
|
483
|
-
|
|
484
|
-
<
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
{getCount()}
|
|
488
|
-
</span>
|
|
489
|
-
</div>
|
|
490
|
-
</>;
|
|
469
|
+
function createCounter(label, getCount) @{
|
|
470
|
+
<div class="counter-display">
|
|
471
|
+
<span class="label">{label}</span>
|
|
472
|
+
<span class="count">{getCount()}</span>
|
|
473
|
+
</div>
|
|
491
474
|
}
|
|
492
475
|
|
|
493
|
-
function App() {
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
476
|
+
function App() @{
|
|
477
|
+
let &[count] = track(0);
|
|
478
|
+
const counterElement = createCounter('Count:', () => count);
|
|
479
|
+
<>
|
|
497
480
|
{counterElement}
|
|
498
481
|
<button onClick={() => count++}>{'increment'}</button>
|
|
499
|
-
|
|
482
|
+
</>
|
|
500
483
|
}
|
|
501
484
|
|
|
502
485
|
render(App);
|
|
@@ -509,24 +492,22 @@ describe('tsx expression', () => {
|
|
|
509
492
|
});
|
|
510
493
|
|
|
511
494
|
it('renders nested tsx from multiple functions', () => {
|
|
512
|
-
function createIcon(name) {
|
|
513
|
-
|
|
495
|
+
function createIcon(name) @{
|
|
496
|
+
<i class={'icon icon-' + name} />
|
|
514
497
|
}
|
|
515
498
|
|
|
516
|
-
function createButton(icon, label) {
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
</button>
|
|
522
|
-
</>;
|
|
499
|
+
function createButton(icon, label) @{
|
|
500
|
+
<button class="icon-button">
|
|
501
|
+
{createIcon(icon)}
|
|
502
|
+
<span class="btn-label">{label}</span>
|
|
503
|
+
</button>
|
|
523
504
|
}
|
|
524
505
|
|
|
525
|
-
function App() {
|
|
526
|
-
|
|
527
|
-
|
|
506
|
+
function App() @{
|
|
507
|
+
const btn = createButton('save', 'Save');
|
|
508
|
+
<>
|
|
528
509
|
{btn}
|
|
529
|
-
|
|
510
|
+
</>
|
|
530
511
|
}
|
|
531
512
|
|
|
532
513
|
render(App);
|
|
@@ -537,23 +518,31 @@ describe('tsx expression', () => {
|
|
|
537
518
|
});
|
|
538
519
|
|
|
539
520
|
it('renders deeply nested tsx and tsrx expression values', () => {
|
|
540
|
-
function HelperItem({ item }) {
|
|
541
|
-
|
|
521
|
+
function HelperItem({ item }) @{
|
|
522
|
+
<div class="helper-item">{item}</div>
|
|
542
523
|
}
|
|
543
524
|
|
|
544
|
-
function MakeFragment({ label }) {
|
|
545
|
-
|
|
525
|
+
function MakeFragment({ label }) @{
|
|
526
|
+
const test = <>
|
|
527
|
+
{[1, 2, 3, 4].map(
|
|
528
|
+
(item) => @{
|
|
529
|
+
<HelperItem {item} />
|
|
530
|
+
},
|
|
531
|
+
)}
|
|
532
|
+
</>;
|
|
533
|
+
<>
|
|
546
534
|
<span class="label">{label}</span>
|
|
547
|
-
const test = <>{[1, 2, 3, 4].map((item) => <><HelperItem {item} /></>)}</>;
|
|
548
535
|
{test}
|
|
549
|
-
|
|
536
|
+
</>
|
|
550
537
|
}
|
|
551
538
|
|
|
552
|
-
function App() {
|
|
553
|
-
|
|
554
|
-
|
|
539
|
+
function App() @{
|
|
540
|
+
<>
|
|
541
|
+
<>
|
|
542
|
+
{[1, 2, 3].map((item) => <div class="app-item">{item}</div>)}
|
|
543
|
+
</>
|
|
555
544
|
<MakeFragment label="from helper" />
|
|
556
|
-
|
|
545
|
+
</>
|
|
557
546
|
}
|
|
558
547
|
|
|
559
548
|
render(App);
|
|
@@ -572,15 +561,15 @@ describe('tsx expression', () => {
|
|
|
572
561
|
});
|
|
573
562
|
|
|
574
563
|
it('renders tsrx nested directly inside a top-level tsx expression value', () => {
|
|
575
|
-
function App() {
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
</section>
|
|
581
|
-
</>;
|
|
582
|
-
{content}
|
|
564
|
+
function App() @{
|
|
565
|
+
const content = <>
|
|
566
|
+
<section class="outer">
|
|
567
|
+
{<><div class="inner">{'from tsrx'}</div></>}
|
|
568
|
+
</section>
|
|
583
569
|
</>;
|
|
570
|
+
<>
|
|
571
|
+
{content}
|
|
572
|
+
</>
|
|
584
573
|
}
|
|
585
574
|
|
|
586
575
|
render(App);
|
|
@@ -591,19 +580,19 @@ describe('tsx expression', () => {
|
|
|
591
580
|
});
|
|
592
581
|
|
|
593
582
|
it('renders nested elements from tsrx inside a top-level tsx value', () => {
|
|
594
|
-
function App() {
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
<
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
</div>
|
|
604
|
-
</>;
|
|
605
|
-
{content}
|
|
583
|
+
function App() @{
|
|
584
|
+
const content = <>
|
|
585
|
+
<div class="wrapper">
|
|
586
|
+
{<>
|
|
587
|
+
<section class="native">
|
|
588
|
+
<span class="nested-tsrx">{'inside nested tsrx'}</span>
|
|
589
|
+
</section>
|
|
590
|
+
</>}
|
|
591
|
+
</div>
|
|
606
592
|
</>;
|
|
593
|
+
<>
|
|
594
|
+
{content}
|
|
595
|
+
</>
|
|
607
596
|
}
|
|
608
597
|
|
|
609
598
|
render(App);
|
|
@@ -614,12 +603,12 @@ describe('tsx expression', () => {
|
|
|
614
603
|
});
|
|
615
604
|
|
|
616
605
|
it('renders tsx declared before a top-level tsx value', () => {
|
|
617
|
-
function App() {
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
606
|
+
function App() @{
|
|
607
|
+
const nested = <span class="nested-tsx">{'inside nested tsx'}</span>;
|
|
608
|
+
const content = <><div class="native">{nested}</div></>;
|
|
609
|
+
<>
|
|
621
610
|
{content}
|
|
622
|
-
|
|
611
|
+
</>
|
|
623
612
|
}
|
|
624
613
|
|
|
625
614
|
render(App);
|
|
@@ -630,20 +619,18 @@ describe('tsx expression', () => {
|
|
|
630
619
|
});
|
|
631
620
|
|
|
632
621
|
it('renders tsx as prop with fallback in component', () => {
|
|
633
|
-
function Alert(&{ icon, message }) {
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
</div>
|
|
639
|
-
</>;
|
|
622
|
+
function Alert(&{ icon, message }) @{
|
|
623
|
+
<div class="alert">
|
|
624
|
+
{icon}
|
|
625
|
+
<span class="message">{message}</span>
|
|
626
|
+
</div>
|
|
640
627
|
}
|
|
641
628
|
|
|
642
|
-
function App() {
|
|
643
|
-
|
|
629
|
+
function App() @{
|
|
630
|
+
<>
|
|
644
631
|
<Alert message="No icon" />
|
|
645
|
-
<Alert icon={<><span class="custom-icon">
|
|
646
|
-
|
|
632
|
+
<Alert icon={<><span class="custom-icon">{'✓'}</span></>} message="Custom icon" />
|
|
633
|
+
</>
|
|
647
634
|
}
|
|
648
635
|
|
|
649
636
|
render(App);
|
|
@@ -654,23 +641,23 @@ describe('tsx expression', () => {
|
|
|
654
641
|
});
|
|
655
642
|
|
|
656
643
|
it('renders tsx stored in array via function', () => {
|
|
657
|
-
function createItem(className, content) {
|
|
658
|
-
|
|
659
|
-
}
|
|
660
|
-
|
|
661
|
-
function App() {
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
644
|
+
function createItem(className, content) @{
|
|
645
|
+
<div class={className}>{content}</div>
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
function App() @{
|
|
649
|
+
const items = [
|
|
650
|
+
{ className: 'item-a', content: 'A' },
|
|
651
|
+
{ className: 'item-b', content: 'B' },
|
|
652
|
+
{ className: 'item-c', content: 'C' },
|
|
653
|
+
];
|
|
654
|
+
<div class="container">
|
|
655
|
+
@for (const item of items) {
|
|
656
|
+
<>
|
|
670
657
|
{createItem(item.className, item.content)}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
658
|
+
</>
|
|
659
|
+
}
|
|
660
|
+
</div>
|
|
674
661
|
}
|
|
675
662
|
|
|
676
663
|
render(App);
|
|
@@ -681,22 +668,23 @@ describe('tsx expression', () => {
|
|
|
681
668
|
});
|
|
682
669
|
|
|
683
670
|
it('renders tsx conditionally from function', () => {
|
|
684
|
-
function createContent(type) {
|
|
685
|
-
if (type === 'success') {
|
|
686
|
-
|
|
687
|
-
} else if (type === 'error') {
|
|
688
|
-
|
|
671
|
+
function createContent(type) @{
|
|
672
|
+
@if (type === 'success') {
|
|
673
|
+
<div class="success">Success!</div>
|
|
674
|
+
} @else if (type === 'error') {
|
|
675
|
+
<div class="error">Error!</div>
|
|
676
|
+
} @else {
|
|
677
|
+
<div class="default">Default</div>
|
|
689
678
|
}
|
|
690
|
-
return <><div class="default">"Default"</div></>;
|
|
691
679
|
}
|
|
692
680
|
|
|
693
|
-
function App() {
|
|
694
|
-
|
|
695
|
-
|
|
681
|
+
function App() @{
|
|
682
|
+
let &[status] = track('default');
|
|
683
|
+
<>
|
|
696
684
|
{createContent(status)}
|
|
697
685
|
<button class="set-success" onClick={() => (status = 'success')}>{'Success'}</button>
|
|
698
686
|
<button class="set-error" onClick={() => (status = 'error')}>{'Error'}</button>
|
|
699
|
-
|
|
687
|
+
</>
|
|
700
688
|
}
|
|
701
689
|
|
|
702
690
|
render(App);
|
|
@@ -715,12 +703,14 @@ describe('tsx expression', () => {
|
|
|
715
703
|
});
|
|
716
704
|
|
|
717
705
|
describe('tsrx expression', () => {
|
|
718
|
-
it('renders native
|
|
719
|
-
function App() {
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
{el}
|
|
706
|
+
it('renders native JSX text in an assigned fragment', () => {
|
|
707
|
+
function App() @{
|
|
708
|
+
const el = <>
|
|
709
|
+
<div>Hello world</div>
|
|
723
710
|
</>;
|
|
711
|
+
<>
|
|
712
|
+
{el}
|
|
713
|
+
</>
|
|
724
714
|
}
|
|
725
715
|
|
|
726
716
|
render(App);
|
|
@@ -731,14 +721,14 @@ describe('tsrx expression', () => {
|
|
|
731
721
|
});
|
|
732
722
|
|
|
733
723
|
it('runs setup statements before native template output', () => {
|
|
734
|
-
function App() {
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
<div>{label}</div>
|
|
739
|
-
</>;
|
|
740
|
-
{el}
|
|
724
|
+
function App() @{
|
|
725
|
+
const label = 'from setup';
|
|
726
|
+
const el = <>
|
|
727
|
+
<div>{label}</div>
|
|
741
728
|
</>;
|
|
729
|
+
<>
|
|
730
|
+
{el}
|
|
731
|
+
</>
|
|
742
732
|
}
|
|
743
733
|
|
|
744
734
|
render(App);
|
|
@@ -747,13 +737,17 @@ describe('tsrx expression', () => {
|
|
|
747
737
|
});
|
|
748
738
|
|
|
749
739
|
it('updates reactive expressions inside native fragments', () => {
|
|
750
|
-
function App() {
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
740
|
+
function App() @{
|
|
741
|
+
let &[count] = track(0);
|
|
742
|
+
const el = <>
|
|
743
|
+
<div>
|
|
744
|
+
{'count: ' + count}
|
|
745
|
+
</div>
|
|
746
|
+
</>;
|
|
747
|
+
<>
|
|
754
748
|
{el}
|
|
755
749
|
<button onClick={() => count++}>{'increment'}</button>
|
|
756
|
-
|
|
750
|
+
</>
|
|
757
751
|
}
|
|
758
752
|
|
|
759
753
|
render(App);
|
|
@@ -765,15 +759,15 @@ describe('tsrx expression', () => {
|
|
|
765
759
|
});
|
|
766
760
|
|
|
767
761
|
it('renders native control flow inside an assigned fragment', () => {
|
|
768
|
-
function App() {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
}
|
|
774
|
-
</>;
|
|
775
|
-
{el}
|
|
762
|
+
function App() @{
|
|
763
|
+
const el = <>
|
|
764
|
+
@if (true) {
|
|
765
|
+
<span>visible</span>
|
|
766
|
+
}
|
|
776
767
|
</>;
|
|
768
|
+
<>
|
|
769
|
+
{el}
|
|
770
|
+
</>
|
|
777
771
|
}
|
|
778
772
|
|
|
779
773
|
render(App);
|
|
@@ -782,12 +776,12 @@ describe('tsrx expression', () => {
|
|
|
782
776
|
});
|
|
783
777
|
|
|
784
778
|
it('renders fragments returned from component functions outside components', () => {
|
|
785
|
-
function MakeFragment({ label }) {
|
|
786
|
-
|
|
779
|
+
function MakeFragment({ label }) @{
|
|
780
|
+
<span>{label}</span>
|
|
787
781
|
}
|
|
788
782
|
|
|
789
|
-
function App() {
|
|
790
|
-
|
|
783
|
+
function App() @{
|
|
784
|
+
<MakeFragment label="from helper" />
|
|
791
785
|
}
|
|
792
786
|
|
|
793
787
|
render(App);
|