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
|
@@ -8,17 +8,27 @@ import type {
|
|
|
8
8
|
} from 'ripple';
|
|
9
9
|
|
|
10
10
|
describe('basic server > components & composition', () => {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
async function render_expected_invalid_component(App: Component) {
|
|
12
|
+
const console_error_spy = vi.spyOn(console, 'error').mockImplementation(() => {});
|
|
13
|
+
try {
|
|
14
|
+
return await render(App);
|
|
15
|
+
} finally {
|
|
16
|
+
console_error_spy.mockRestore();
|
|
14
17
|
}
|
|
18
|
+
}
|
|
15
19
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
+
it('renders with component composition and children', async () => {
|
|
21
|
+
function Card(props: PropsWithChildren<{}>) {
|
|
22
|
+
return <><div class="card">{props.children}</div></>;
|
|
23
|
+
}
|
|
20
24
|
|
|
21
|
-
|
|
25
|
+
function Basic() {
|
|
26
|
+
return <>
|
|
27
|
+
function children() {
|
|
28
|
+
return <><p>{'Card content here'}</p></>;
|
|
29
|
+
}
|
|
30
|
+
<Card {children} />
|
|
31
|
+
</>;
|
|
22
32
|
}
|
|
23
33
|
|
|
24
34
|
const { body } = await render(Basic);
|
|
@@ -32,19 +42,21 @@ describe('basic server > components & composition', () => {
|
|
|
32
42
|
});
|
|
33
43
|
|
|
34
44
|
it('does not render a falsy component call', async () => {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
function Card(props: PropsWithChildrenOptional<{ test: Component }>) {
|
|
46
|
+
return <>
|
|
47
|
+
<div class="card">
|
|
48
|
+
{props.children}
|
|
49
|
+
</div>
|
|
50
|
+
</>;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function Basic() {
|
|
54
|
+
return <>
|
|
55
|
+
function test() {
|
|
56
|
+
return <><p>{'Card content here'}</p></>;
|
|
57
|
+
}
|
|
58
|
+
<Card {test} />
|
|
59
|
+
</>;
|
|
48
60
|
}
|
|
49
61
|
|
|
50
62
|
const { body } = await render(Basic);
|
|
@@ -59,15 +71,17 @@ describe('basic server > components & composition', () => {
|
|
|
59
71
|
});
|
|
60
72
|
|
|
61
73
|
it('renders a component when children is set a component prop', async () => {
|
|
62
|
-
|
|
63
|
-
|
|
74
|
+
function Card(props: PropsWithChildren<{}>) {
|
|
75
|
+
return <><div class="card">{props.children}</div></>;
|
|
64
76
|
}
|
|
65
77
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
78
|
+
function Basic() {
|
|
79
|
+
return <>
|
|
80
|
+
function children() {
|
|
81
|
+
return <><p>{'Card content here'}</p></>;
|
|
82
|
+
}
|
|
83
|
+
<Card {children} />
|
|
84
|
+
</>;
|
|
71
85
|
}
|
|
72
86
|
|
|
73
87
|
const { body } = await render(Basic);
|
|
@@ -80,38 +94,119 @@ describe('basic server > components & composition', () => {
|
|
|
80
94
|
expect(paragraph.textContent).toBe('Card content here');
|
|
81
95
|
});
|
|
82
96
|
|
|
97
|
+
it('renders direct component function calls as values', async () => {
|
|
98
|
+
function Test({ label }: { label: string }) {
|
|
99
|
+
return <><span>{label}</span></>;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function App() {
|
|
103
|
+
return <>{Test({ label: 'direct call' })}</>;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const { body } = await render(App);
|
|
107
|
+
const { document } = parseHtml(body);
|
|
108
|
+
|
|
109
|
+
expect(document.querySelector('span')?.textContent).toBe('direct call');
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('renders arrays and primitives returned from component calls', async () => {
|
|
113
|
+
function Test() {
|
|
114
|
+
const item = <span>{'A'}</span>;
|
|
115
|
+
return [item, 'B', null, undefined];
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function App() {
|
|
119
|
+
return <><Test /></>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const { body } = await render(App);
|
|
123
|
+
|
|
124
|
+
expect(body).toContain('<span>A</span>');
|
|
125
|
+
expect(body).toContain('B');
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
it('throws when a TSRXElement value is used as a component type', async () => {
|
|
129
|
+
function Test() {
|
|
130
|
+
return <><span>{'value'}</span></>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
function App() {
|
|
134
|
+
const El = Test({});
|
|
135
|
+
return <><El /></>;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
const result = await render_expected_invalid_component(App);
|
|
139
|
+
|
|
140
|
+
expect(result.topLevelError?.message).toContain('Invalid component type');
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
it('allows a plain function as a component type', async () => {
|
|
144
|
+
function Func() {
|
|
145
|
+
return 'plain';
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function App() {
|
|
149
|
+
return <><Func /></>;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const { body } = await render(App);
|
|
153
|
+
|
|
154
|
+
expect(body).toBeHtml('plain');
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('allows a compat-only function as a component type', async () => {
|
|
158
|
+
function CompatOnly() {
|
|
159
|
+
return <tsx>
|
|
160
|
+
<div>
|
|
161
|
+
{'compat'}
|
|
162
|
+
</div>
|
|
163
|
+
</tsx>;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function App() {
|
|
167
|
+
return <><CompatOnly /></>;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const { body } = await render(App);
|
|
171
|
+
|
|
172
|
+
expect(body).toBeHtml('<div>compat</div>');
|
|
173
|
+
});
|
|
174
|
+
|
|
83
175
|
it('renders with nested components and prop passing', async () => {
|
|
84
|
-
|
|
176
|
+
function Button(props: PropsWithExtras<{
|
|
85
177
|
variant: string;
|
|
86
178
|
label: string;
|
|
87
179
|
onClick: EventListener;
|
|
88
180
|
}>) {
|
|
89
|
-
|
|
181
|
+
return <><button class={props.variant} onClick={props.onClick}>{props.label}</button></>;
|
|
90
182
|
}
|
|
91
183
|
|
|
92
|
-
|
|
184
|
+
function Card(props: PropsWithExtras<{
|
|
93
185
|
title: string;
|
|
94
186
|
content: string;
|
|
95
187
|
buttonText: string;
|
|
96
188
|
onAction: EventListener;
|
|
97
189
|
}>) {
|
|
98
|
-
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
190
|
+
return <>
|
|
191
|
+
<div class="card">
|
|
192
|
+
<h3>{props.title}</h3>
|
|
193
|
+
<p>{props.content}</p>
|
|
194
|
+
<Button variant="primary" label={props.buttonText} onClick={props.onAction} />
|
|
195
|
+
</div>
|
|
196
|
+
</>;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function Basic() {
|
|
200
|
+
return <>
|
|
201
|
+
let &[clicked] = track(false);
|
|
202
|
+
<Card
|
|
203
|
+
title="Test Card"
|
|
204
|
+
content="This is a test card"
|
|
205
|
+
buttonText="Click me"
|
|
206
|
+
onAction={() => (clicked = true)}
|
|
207
|
+
/>
|
|
208
|
+
<div class="status">{clicked ? 'Clicked' : 'Not clicked'}</div>
|
|
209
|
+
</>;
|
|
115
210
|
}
|
|
116
211
|
|
|
117
212
|
const { body } = await render(Basic);
|
|
@@ -131,27 +226,30 @@ describe('basic server > components & composition', () => {
|
|
|
131
226
|
});
|
|
132
227
|
|
|
133
228
|
it('renders with reactive component props', async () => {
|
|
134
|
-
|
|
229
|
+
function ChildComponent(props: PropsWithExtras<{
|
|
135
230
|
text: Tracked<string>;
|
|
136
231
|
count: Tracked<number>;
|
|
137
232
|
}>) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
233
|
+
return <>
|
|
234
|
+
<div class="child-content">{props.text.value}</div>
|
|
235
|
+
<div class="child-count">{props.count.value}</div>
|
|
236
|
+
</>;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function Basic() {
|
|
240
|
+
return <>
|
|
241
|
+
let &[message, messageTracked] = track('Hello');
|
|
242
|
+
let &[number, numberTracked] = track(1);
|
|
243
|
+
<ChildComponent text={messageTracked} count={numberTracked} />
|
|
244
|
+
<button
|
|
245
|
+
onClick={() => {
|
|
246
|
+
message = message === 'Hello' ? 'Goodbye' : 'Hello';
|
|
247
|
+
number++;
|
|
248
|
+
}}
|
|
249
|
+
>
|
|
250
|
+
{'Update Props'}
|
|
251
|
+
</button>
|
|
252
|
+
</>;
|
|
155
253
|
}
|
|
156
254
|
|
|
157
255
|
const { body } = await render(Basic);
|
|
@@ -165,29 +263,36 @@ describe('basic server > components & composition', () => {
|
|
|
165
263
|
});
|
|
166
264
|
|
|
167
265
|
it('renders components as named and anonymous properties', async () => {
|
|
266
|
+
function Span() {
|
|
267
|
+
return <><span>{'Hello from Span'}</span></>;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
function Button({ children }: PropsWithChildren<{}>) {
|
|
271
|
+
return <><button>{children}</button></>;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
function ArrowButton({ children }: PropsWithChildren<{}>) {
|
|
275
|
+
return <><button class="arrow-button">{children}</button></>;
|
|
276
|
+
}
|
|
277
|
+
|
|
168
278
|
const UI = {
|
|
169
|
-
span:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
button: component({ children }: PropsWithChildren<{}>) {
|
|
173
|
-
<button>{children}</button>
|
|
174
|
-
},
|
|
175
|
-
arrowButton: component({ children }: PropsWithChildren<{}>) => {
|
|
176
|
-
<button class="arrow-button">{children}</button>
|
|
177
|
-
},
|
|
279
|
+
span: Span,
|
|
280
|
+
button: Button,
|
|
281
|
+
arrowButton: ArrowButton,
|
|
178
282
|
};
|
|
179
283
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
284
|
+
function App() {
|
|
285
|
+
return <>
|
|
286
|
+
function children() {
|
|
287
|
+
return <><span>{'Click me!'}</span></>;
|
|
288
|
+
}
|
|
289
|
+
<div>
|
|
290
|
+
<h1>{'Component as Property Test'}</h1>
|
|
291
|
+
<UI.span />
|
|
292
|
+
<UI.button {children} />
|
|
293
|
+
<UI.arrowButton {children} />
|
|
294
|
+
</div>
|
|
295
|
+
</>;
|
|
191
296
|
}
|
|
192
297
|
|
|
193
298
|
const { body } = await render(App);
|
|
@@ -207,14 +312,16 @@ describe('basic server > components & composition', () => {
|
|
|
207
312
|
});
|
|
208
313
|
|
|
209
314
|
it('handles empty string children', async () => {
|
|
210
|
-
|
|
211
|
-
{children}
|
|
315
|
+
function Button({ children }: PropsWithChildren<{}>) {
|
|
316
|
+
return <>{children}</>;
|
|
212
317
|
}
|
|
213
318
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
319
|
+
function App() {
|
|
320
|
+
return <>
|
|
321
|
+
let content = '';
|
|
322
|
+
<Button>{''}</Button>
|
|
323
|
+
<Button>{content}</Button>
|
|
324
|
+
</>;
|
|
218
325
|
}
|
|
219
326
|
|
|
220
327
|
const { body } = await render(App);
|
|
@@ -224,17 +331,19 @@ describe('basic server > components & composition', () => {
|
|
|
224
331
|
});
|
|
225
332
|
|
|
226
333
|
it('handles component without any output', async () => {
|
|
227
|
-
|
|
228
|
-
|
|
334
|
+
function Noop() {
|
|
335
|
+
return <></>;
|
|
229
336
|
}
|
|
230
337
|
|
|
231
|
-
|
|
232
|
-
|
|
338
|
+
function Op() {
|
|
339
|
+
return <><div>{'Some HTML content'}</div></>;
|
|
233
340
|
}
|
|
234
341
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
342
|
+
function App() {
|
|
343
|
+
return <>
|
|
344
|
+
let Content = track(() => Noop);
|
|
345
|
+
<@Content />
|
|
346
|
+
</>;
|
|
238
347
|
}
|
|
239
348
|
|
|
240
349
|
const { body } = await render(App);
|
|
@@ -244,12 +353,12 @@ describe('basic server > components & composition', () => {
|
|
|
244
353
|
});
|
|
245
354
|
|
|
246
355
|
it('renders explicit children prop without spread', async () => {
|
|
247
|
-
|
|
248
|
-
|
|
356
|
+
function Card(props: PropsWithChildren<{}>) {
|
|
357
|
+
return <><div class="card">{props.children}</div></>;
|
|
249
358
|
}
|
|
250
359
|
|
|
251
|
-
|
|
252
|
-
|
|
360
|
+
function App() {
|
|
361
|
+
return <><Card children="fallback text" /></>;
|
|
253
362
|
}
|
|
254
363
|
|
|
255
364
|
const { body } = await render(App);
|
|
@@ -258,13 +367,15 @@ describe('basic server > components & composition', () => {
|
|
|
258
367
|
});
|
|
259
368
|
|
|
260
369
|
it('renders explicit children before spread', async () => {
|
|
261
|
-
|
|
262
|
-
|
|
370
|
+
function Card(props: PropsWithChildren<{ id: string }>) {
|
|
371
|
+
return <><div class="card">{props.children}</div></>;
|
|
263
372
|
}
|
|
264
373
|
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
374
|
+
function App() {
|
|
375
|
+
return <>
|
|
376
|
+
const extra = { id: '1' };
|
|
377
|
+
<Card children="fallback text" {...extra} />
|
|
378
|
+
</>;
|
|
268
379
|
}
|
|
269
380
|
|
|
270
381
|
const { body } = await render(App);
|
|
@@ -273,13 +384,15 @@ describe('basic server > components & composition', () => {
|
|
|
273
384
|
});
|
|
274
385
|
|
|
275
386
|
it('renders spread before explicit children', async () => {
|
|
276
|
-
|
|
277
|
-
|
|
387
|
+
function Card(props: PropsWithChildren<{ id: string }>) {
|
|
388
|
+
return <><div class="card">{props.children}</div></>;
|
|
278
389
|
}
|
|
279
390
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
391
|
+
function App() {
|
|
392
|
+
return <>
|
|
393
|
+
const extra = { id: '1' };
|
|
394
|
+
<Card {...extra} children="fallback text" />
|
|
395
|
+
</>;
|
|
283
396
|
}
|
|
284
397
|
|
|
285
398
|
const { body } = await render(App);
|
|
@@ -288,15 +401,17 @@ describe('basic server > components & composition', () => {
|
|
|
288
401
|
});
|
|
289
402
|
|
|
290
403
|
it('template children override explicit children before spread', async () => {
|
|
291
|
-
|
|
292
|
-
|
|
404
|
+
function Card(props: PropsWithChildren<{ id: string }>) {
|
|
405
|
+
return <><div class="card">{props.children}</div></>;
|
|
293
406
|
}
|
|
294
407
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
<
|
|
299
|
-
|
|
408
|
+
function App() {
|
|
409
|
+
return <>
|
|
410
|
+
const extra = { id: '1' };
|
|
411
|
+
<Card children="fallback text" {...extra}>
|
|
412
|
+
<span>{'template content'}</span>
|
|
413
|
+
</Card>
|
|
414
|
+
</>;
|
|
300
415
|
}
|
|
301
416
|
|
|
302
417
|
const { body } = await render(App);
|
|
@@ -306,15 +421,17 @@ describe('basic server > components & composition', () => {
|
|
|
306
421
|
});
|
|
307
422
|
|
|
308
423
|
it('template children override explicit children after spread', async () => {
|
|
309
|
-
|
|
310
|
-
|
|
424
|
+
function Card(props: PropsWithChildren<{ id: string }>) {
|
|
425
|
+
return <><div class="card">{props.children}</div></>;
|
|
311
426
|
}
|
|
312
427
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
<
|
|
317
|
-
|
|
428
|
+
function App() {
|
|
429
|
+
return <>
|
|
430
|
+
const extra = { id: '1' };
|
|
431
|
+
<Card {...extra} children="fallback text">
|
|
432
|
+
<span>{'template content'}</span>
|
|
433
|
+
</Card>
|
|
434
|
+
</>;
|
|
318
435
|
}
|
|
319
436
|
|
|
320
437
|
const { body } = await render(App);
|
|
@@ -324,17 +441,19 @@ describe('basic server > components & composition', () => {
|
|
|
324
441
|
});
|
|
325
442
|
|
|
326
443
|
it('spread can override explicit children when no template children', async () => {
|
|
327
|
-
|
|
328
|
-
|
|
444
|
+
function Card(props: PropsWithChildren<{ id: string }>) {
|
|
445
|
+
return <><div class="card">{props.children}</div></>;
|
|
329
446
|
}
|
|
330
447
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
448
|
+
function App() {
|
|
449
|
+
return <>
|
|
450
|
+
const extra = { id: '1', children: 'from spread' };
|
|
451
|
+
<Card
|
|
452
|
+
// @ts-ignore
|
|
453
|
+
children="explicit"
|
|
454
|
+
{...extra}
|
|
455
|
+
/>
|
|
456
|
+
</>;
|
|
338
457
|
}
|
|
339
458
|
|
|
340
459
|
const { body } = await render(App);
|
|
@@ -343,13 +462,15 @@ describe('basic server > components & composition', () => {
|
|
|
343
462
|
});
|
|
344
463
|
|
|
345
464
|
it('explicit children overrides spread children when it comes after', async () => {
|
|
346
|
-
|
|
347
|
-
|
|
465
|
+
function Card(props: PropsWithChildren<{ id: string }>) {
|
|
466
|
+
return <><div class="card">{props.children}</div></>;
|
|
348
467
|
}
|
|
349
468
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
469
|
+
function App() {
|
|
470
|
+
return <>
|
|
471
|
+
const extra = { id: '1', children: 'from spread' };
|
|
472
|
+
<Card {...extra} children="explicit" />
|
|
473
|
+
</>;
|
|
353
474
|
}
|
|
354
475
|
|
|
355
476
|
const { body } = await render(App);
|
|
@@ -358,18 +479,20 @@ describe('basic server > components & composition', () => {
|
|
|
358
479
|
});
|
|
359
480
|
|
|
360
481
|
it('renders components declared inside composite element children', async () => {
|
|
361
|
-
|
|
362
|
-
|
|
482
|
+
function Wrapper(props: PropsWithChildren<{}>) {
|
|
483
|
+
return <><div class="wrapper">{props.children}</div></>;
|
|
363
484
|
}
|
|
364
485
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
486
|
+
function App() {
|
|
487
|
+
return <>
|
|
488
|
+
<Wrapper>
|
|
489
|
+
function Inner() {
|
|
490
|
+
return <><span class="inner">{'inner content'}</span></>;
|
|
491
|
+
}
|
|
370
492
|
|
|
371
|
-
|
|
372
|
-
|
|
493
|
+
<Inner />
|
|
494
|
+
</Wrapper>
|
|
495
|
+
</>;
|
|
373
496
|
}
|
|
374
497
|
|
|
375
498
|
const { body } = await render(App);
|
|
@@ -378,25 +501,29 @@ describe('basic server > components & composition', () => {
|
|
|
378
501
|
});
|
|
379
502
|
|
|
380
503
|
it('renders nested components declared inside composite children with prop passing', async () => {
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
504
|
+
function Wrapper(props: PropsWithChildren<{}>) {
|
|
505
|
+
return <><div class="wrapper">{props.children}</div></>;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
function App() {
|
|
509
|
+
return <>
|
|
510
|
+
<Wrapper>
|
|
511
|
+
function Z() {
|
|
512
|
+
return <><div class="z">{'I am Z'}</div></>;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
function Child(&{ Z }: { Z: Component }) {
|
|
516
|
+
return <>
|
|
517
|
+
<div class="child">
|
|
518
|
+
{'Child Component: '}
|
|
519
|
+
<Z />
|
|
520
|
+
</div>
|
|
521
|
+
</>;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
<Child {Z} />
|
|
525
|
+
</Wrapper>
|
|
526
|
+
</>;
|
|
400
527
|
}
|
|
401
528
|
|
|
402
529
|
const { body } = await render(App);
|