ripple 0.3.68 → 0.3.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +57 -0
- package/package.json +3 -3
- package/src/jsx-runtime.d.ts +2 -2
- package/src/runtime/element.js +1 -1
- package/src/runtime/index-client.js +11 -11
- package/src/runtime/index-server.js +7 -4
- package/src/runtime/internal/client/bindings.js +1 -1
- package/src/runtime/internal/client/blocks.js +13 -4
- package/src/runtime/internal/client/component.js +55 -0
- package/src/runtime/internal/client/composite.js +4 -2
- package/src/runtime/internal/client/expression.js +65 -7
- package/src/runtime/internal/client/hmr.js +54 -43
- package/src/runtime/internal/client/index.js +5 -1
- package/src/runtime/internal/client/portal.js +70 -69
- package/src/runtime/internal/client/render.js +3 -0
- package/src/runtime/internal/server/index.js +92 -8
- package/tests/client/__snapshots__/html.test.tsrx.snap +3 -3
- package/tests/client/array/array.copy-within.test.tsrx +33 -31
- package/tests/client/array/array.derived.test.tsrx +186 -169
- package/tests/client/array/array.iteration.test.tsrx +40 -37
- package/tests/client/array/array.mutations.test.tsrx +113 -101
- package/tests/client/array/array.static.test.tsrx +119 -101
- package/tests/client/array/array.to-methods.test.tsrx +24 -21
- package/tests/client/async-suspend.test.tsrx +247 -246
- package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +0 -1
- package/tests/client/basic/basic.attributes.test.tsrx +428 -423
- package/tests/client/basic/basic.collections.test.tsrx +109 -102
- package/tests/client/basic/basic.components.test.tsrx +323 -205
- package/tests/client/basic/basic.errors.test.tsrx +91 -91
- package/tests/client/basic/basic.events.test.tsrx +114 -115
- package/tests/client/basic/basic.get-set.test.tsrx +97 -87
- package/tests/client/basic/basic.hmr.test.tsrx +19 -16
- package/tests/client/basic/basic.reactivity.test.tsrx +199 -191
- package/tests/client/basic/basic.rendering.test.tsrx +272 -182
- package/tests/client/basic/basic.styling.test.tsrx +23 -22
- package/tests/client/basic/basic.utilities.test.tsrx +10 -8
- package/tests/client/boundaries.test.tsrx +26 -26
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.rsrx.snap +5 -5
- package/tests/client/compiler/__snapshots__/compiler.assignments.test.tsrx.snap +5 -5
- package/tests/client/compiler/compiler.assignments.test.tsrx +77 -81
- package/tests/client/compiler/compiler.attributes.test.tsrx +15 -15
- package/tests/client/compiler/compiler.basic.test.tsrx +322 -314
- package/tests/client/compiler/compiler.regex.test.tsrx +44 -47
- package/tests/client/compiler/compiler.tracked-access.test.tsrx +38 -38
- package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
- package/tests/client/compiler/compiler.typescript.test.tsrx +2 -2
- package/tests/client/composite/composite.dynamic-components.test.tsrx +47 -48
- package/tests/client/composite/composite.generics.test.tsrx +168 -192
- package/tests/client/composite/composite.props.test.tsrx +97 -81
- package/tests/client/composite/composite.reactivity.test.tsrx +177 -147
- package/tests/client/composite/composite.render.test.tsrx +122 -105
- package/tests/client/computed-properties.test.tsrx +28 -28
- package/tests/client/context.test.tsrx +21 -21
- package/tests/client/css/global-additional-cases.test.tsrx +58 -58
- package/tests/client/css/global-advanced-selectors.test.tsrx +16 -16
- package/tests/client/css/global-at-rules.test.tsrx +10 -10
- package/tests/client/css/global-basic.test.tsrx +14 -14
- package/tests/client/css/global-classes-ids.test.tsrx +14 -14
- package/tests/client/css/global-combinators.test.tsrx +10 -10
- package/tests/client/css/global-complex-nesting.test.tsrx +14 -14
- package/tests/client/css/global-edge-cases.test.tsrx +18 -18
- package/tests/client/css/global-keyframes.test.tsrx +12 -12
- package/tests/client/css/global-nested.test.tsrx +10 -10
- package/tests/client/css/global-pseudo.test.tsrx +12 -12
- package/tests/client/css/global-scoping.test.tsrx +20 -20
- package/tests/client/css/style-identifier.test.tsrx +126 -259
- package/tests/client/date.test.tsrx +146 -133
- package/tests/client/dynamic-elements.test.tsrx +398 -365
- package/tests/client/events.test.tsrx +292 -290
- package/tests/client/for.test.tsrx +156 -153
- package/tests/client/head.test.tsrx +105 -96
- package/tests/client/html.test.tsrx +122 -26
- package/tests/client/input-value.test.tsrx +1361 -1314
- package/tests/client/lazy-array.test.tsrx +16 -13
- package/tests/client/lazy-destructuring.test.tsrx +257 -213
- package/tests/client/map.test.tsrx +65 -60
- package/tests/client/media-query.test.tsrx +22 -20
- package/tests/client/object.test.tsrx +87 -81
- package/tests/client/portal.test.tsrx +57 -51
- package/tests/client/ref.test.tsrx +233 -202
- package/tests/client/return.test.tsrx +71 -2560
- package/tests/client/set.test.tsrx +54 -45
- package/tests/client/svg.test.tsrx +216 -186
- package/tests/client/switch.test.tsrx +194 -193
- package/tests/client/track-async-hydration.test.tsrx +18 -14
- package/tests/client/tracked-index-access.test.tsrx +28 -18
- package/tests/client/try.test.tsrx +675 -548
- package/tests/client/tsx.test.tsrx +373 -311
- package/tests/client/typescript-generics.test.tsrx +145 -145
- package/tests/client/url/url.derived.test.tsrx +33 -28
- package/tests/client/url/url.parsing.test.tsrx +61 -51
- package/tests/client/url/url.partial-removal.test.tsrx +56 -48
- package/tests/client/url/url.reactivity.test.tsrx +142 -125
- package/tests/client/url/url.serialization.test.tsrx +13 -11
- package/tests/client/url-search-params/url-search-params.derived.test.tsrx +34 -29
- package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +25 -21
- package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +50 -45
- package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +111 -99
- package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +49 -43
- package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +14 -12
- package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +16 -14
- package/tests/hydration/basic.test.js +3 -3
- package/tests/hydration/compiled/client/basic.js +586 -651
- package/tests/hydration/compiled/client/composite.js +79 -104
- package/tests/hydration/compiled/client/events.js +140 -148
- package/tests/hydration/compiled/client/for.js +1005 -1018
- package/tests/hydration/compiled/client/head.js +124 -134
- package/tests/hydration/compiled/client/hmr.js +41 -48
- package/tests/hydration/compiled/client/html-in-template.js +38 -41
- package/tests/hydration/compiled/client/html.js +970 -1314
- package/tests/hydration/compiled/client/if-children.js +234 -249
- package/tests/hydration/compiled/client/if.js +182 -189
- package/tests/hydration/compiled/client/mixed-control-flow.js +347 -303
- package/tests/hydration/compiled/client/nested-control-flow.js +1084 -832
- package/tests/hydration/compiled/client/portal.js +65 -85
- package/tests/hydration/compiled/client/reactivity.js +84 -90
- package/tests/hydration/compiled/client/return.js +38 -1939
- package/tests/hydration/compiled/client/switch.js +218 -224
- package/tests/hydration/compiled/client/track-async-serialization.js +250 -259
- package/tests/hydration/compiled/client/try.js +123 -132
- package/tests/hydration/compiled/server/basic.js +773 -831
- package/tests/hydration/compiled/server/composite.js +166 -191
- package/tests/hydration/compiled/server/events.js +170 -184
- package/tests/hydration/compiled/server/for.js +851 -909
- package/tests/hydration/compiled/server/head.js +206 -216
- package/tests/hydration/compiled/server/hmr.js +64 -72
- package/tests/hydration/compiled/server/html-in-template.js +42 -76
- package/tests/hydration/compiled/server/html.js +1362 -1667
- package/tests/hydration/compiled/server/if-children.js +419 -445
- package/tests/hydration/compiled/server/if.js +194 -208
- package/tests/hydration/compiled/server/mixed-control-flow.js +249 -257
- package/tests/hydration/compiled/server/nested-control-flow.js +491 -515
- package/tests/hydration/compiled/server/portal.js +152 -160
- package/tests/hydration/compiled/server/reactivity.js +94 -106
- package/tests/hydration/compiled/server/return.js +28 -2172
- package/tests/hydration/compiled/server/switch.js +274 -286
- package/tests/hydration/compiled/server/track-async-serialization.js +340 -358
- package/tests/hydration/compiled/server/try.js +167 -185
- package/tests/hydration/components/basic.tsrx +320 -272
- package/tests/hydration/components/composite.tsrx +44 -32
- package/tests/hydration/components/events.tsrx +101 -91
- package/tests/hydration/components/for.tsrx +510 -452
- package/tests/hydration/components/head.tsrx +87 -80
- package/tests/hydration/components/hmr.tsrx +22 -17
- package/tests/hydration/components/html-in-template.tsrx +22 -17
- package/tests/hydration/components/html.tsrx +525 -443
- package/tests/hydration/components/if-children.tsrx +158 -148
- package/tests/hydration/components/if.tsrx +109 -95
- package/tests/hydration/components/mixed-control-flow.tsrx +100 -96
- package/tests/hydration/components/nested-control-flow.tsrx +215 -203
- package/tests/hydration/components/portal.tsrx +41 -34
- package/tests/hydration/components/reactivity.tsrx +37 -27
- package/tests/hydration/components/return.tsrx +12 -556
- package/tests/hydration/components/switch.tsrx +120 -114
- package/tests/hydration/components/track-async-serialization.tsrx +107 -91
- package/tests/hydration/components/try.tsrx +55 -40
- package/tests/hydration/html.test.js +4 -4
- package/tests/hydration/return.test.js +13 -532
- package/tests/server/await.test.tsrx +3 -3
- package/tests/server/basic.attributes.test.tsrx +264 -195
- package/tests/server/basic.components.test.tsrx +296 -169
- package/tests/server/basic.test.tsrx +300 -198
- package/tests/server/compiler.test.tsrx +62 -60
- package/tests/server/composite.props.test.tsrx +77 -63
- package/tests/server/composite.test.tsrx +168 -192
- package/tests/server/context.test.tsrx +18 -12
- package/tests/server/dynamic-elements.test.tsrx +197 -180
- package/tests/server/for.test.tsrx +85 -78
- package/tests/server/head.test.tsrx +50 -43
- package/tests/server/html-nesting-validation.test.tsrx +8 -8
- package/tests/server/if.test.tsrx +57 -51
- package/tests/server/lazy-destructuring.test.tsrx +366 -294
- package/tests/server/return.test.tsrx +76 -1355
- package/tests/server/streaming-ssr.test.tsrx +4 -75
- package/tests/server/style-identifier.test.tsrx +169 -131
- package/tests/server/switch.test.tsrx +91 -85
- package/tests/server/track-async-serialization.test.tsrx +105 -85
- package/tests/server/try.test.tsrx +374 -280
- package/tests/utils/compiler-compat-config.test.js +2 -2
- package/tests/utils/runtime-imports.test.js +10 -0
- package/types/index.d.ts +8 -0
- package/tests/client/__snapshots__/html.test.rsrx.snap +0 -40
|
@@ -2,8 +2,8 @@ import { create_ssr_stream } from 'ripple/server';
|
|
|
2
2
|
|
|
3
3
|
describe('create_ssr_stream', () => {
|
|
4
4
|
it('renders SSR HTML into the injected sink and exposes a web stream', async () => {
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
function App() {
|
|
6
|
+
return <><div>{'Hello, streaming SSR!'}</div></>;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
const { stream, sink } = create_ssr_stream();
|
|
@@ -16,8 +16,8 @@ describe('create_ssr_stream', () => {
|
|
|
16
16
|
});
|
|
17
17
|
|
|
18
18
|
it('closes the public stream when streaming finishes successfully', async () => {
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
function App() {
|
|
20
|
+
return <><p>{'stream closed'}</p></>;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
const { stream, sink } = create_ssr_stream();
|
|
@@ -42,74 +42,3 @@ describe('create_ssr_stream', () => {
|
|
|
42
42
|
expect(terminal_read.done).toBe(true);
|
|
43
43
|
});
|
|
44
44
|
});
|
|
45
|
-
|
|
46
|
-
// import { renderToStream } from 'ripple/server';
|
|
47
|
-
|
|
48
|
-
// describe('render to stream', () => {
|
|
49
|
-
// test('renderToStream renders a simple component', async ({ expect }) => {
|
|
50
|
-
// component Basic() {
|
|
51
|
-
// <div>{'Hello, streaming SSR!'}</div>
|
|
52
|
-
// }
|
|
53
|
-
|
|
54
|
-
// const stream = renderToStream(Basic);
|
|
55
|
-
|
|
56
|
-
// let result = '';
|
|
57
|
-
// await new Promise((resolve) => {
|
|
58
|
-
// stream.on('data', (chunk) => {
|
|
59
|
-
// result += chunk.toString();
|
|
60
|
-
// });
|
|
61
|
-
// stream.on('end', resolve);
|
|
62
|
-
// });
|
|
63
|
-
|
|
64
|
-
// expect(result).toBe('<div>Hello, streaming SSR!</div>');
|
|
65
|
-
// });
|
|
66
|
-
|
|
67
|
-
// test('renderToStream handles async components', async ({ expect }) => {
|
|
68
|
-
// component AsyncComponent() {
|
|
69
|
-
// await new Promise((resolve) => setTimeout(resolve, 10));
|
|
70
|
-
// <p>{'Async content loaded.'}</p>
|
|
71
|
-
// }
|
|
72
|
-
|
|
73
|
-
// const stream = renderToStream(AsyncComponent);
|
|
74
|
-
|
|
75
|
-
// let result = '';
|
|
76
|
-
// await new Promise((resolve) => {
|
|
77
|
-
// stream.on('data', (chunk) => {
|
|
78
|
-
// result += chunk.toString();
|
|
79
|
-
// });
|
|
80
|
-
// stream.on('end', resolve);
|
|
81
|
-
// });
|
|
82
|
-
|
|
83
|
-
// expect(result).toBe('<p>Async content loaded.</p>');
|
|
84
|
-
// });
|
|
85
|
-
|
|
86
|
-
// test('renderToStream handles await blocks with pending state', async ({ expect }) => {
|
|
87
|
-
// component AwaitComponent() {
|
|
88
|
-
// let data = 'initial';
|
|
89
|
-
// await new Promise((resolve) => setTimeout(() => {
|
|
90
|
-
// data = 'resolved';
|
|
91
|
-
// resolve('');
|
|
92
|
-
// }, 20));
|
|
93
|
-
// try {
|
|
94
|
-
// <div>
|
|
95
|
-
// {'Data: '}
|
|
96
|
-
// {data}
|
|
97
|
-
// </div>
|
|
98
|
-
// } pending {
|
|
99
|
-
// <div>{'Loading...'}</div>
|
|
100
|
-
// }
|
|
101
|
-
// }
|
|
102
|
-
|
|
103
|
-
// const stream = renderToStream(AwaitComponent);
|
|
104
|
-
|
|
105
|
-
// let result = '';
|
|
106
|
-
// await new Promise((resolve) => {
|
|
107
|
-
// stream.on('data', (chunk) => {
|
|
108
|
-
// result += chunk.toString();
|
|
109
|
-
// });
|
|
110
|
-
// stream.on('end', resolve);
|
|
111
|
-
// });
|
|
112
|
-
|
|
113
|
-
// expect(result).toBe('<!--[--><div>Loading...</div><div>Data: resolved</div><!--]-->');
|
|
114
|
-
// });
|
|
115
|
-
// });
|
|
@@ -1,21 +1,27 @@
|
|
|
1
1
|
import { track } from 'ripple';
|
|
2
2
|
import { compile } from '@tsrx/ripple';
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
const external_styles = <style>
|
|
5
|
+
.external {
|
|
6
|
+
color: tomato;
|
|
7
|
+
}
|
|
8
|
+
</style>;
|
|
9
|
+
|
|
10
|
+
describe('style class maps (server)', () => {
|
|
5
11
|
describe('basic usage with components', () => {
|
|
6
|
-
it('passes scoped
|
|
7
|
-
|
|
8
|
-
|
|
12
|
+
it('passes scoped classes to a child component via a style expression', async () => {
|
|
13
|
+
function Child({ className }: { className: string }) {
|
|
14
|
+
return <><div class={className}>{'styled child'}</div></>;
|
|
9
15
|
}
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
<style>
|
|
17
|
+
function Parent() {
|
|
18
|
+
const styles = <style>
|
|
15
19
|
.highlight {
|
|
16
20
|
color: red;
|
|
17
21
|
}
|
|
18
|
-
</style
|
|
22
|
+
</style>;
|
|
23
|
+
|
|
24
|
+
return <><Child className={styles.highlight} /></>;
|
|
19
25
|
}
|
|
20
26
|
|
|
21
27
|
const { body } = await render(Parent);
|
|
@@ -29,23 +35,25 @@ describe('{style} directive (server)', () => {
|
|
|
29
35
|
expect(classes.some((cls: string) => cls === 'highlight')).toBe(true);
|
|
30
36
|
});
|
|
31
37
|
|
|
32
|
-
it('passes multiple
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
it('passes multiple style expression classes to a child component', async () => {
|
|
39
|
+
function Child({ primary, secondary }: { primary: string; secondary: string }) {
|
|
40
|
+
return <>
|
|
41
|
+
<div class={primary}>{'primary'}</div>
|
|
42
|
+
<span class={secondary}>{'secondary'}</span>
|
|
43
|
+
</>;
|
|
36
44
|
}
|
|
37
45
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
<style>
|
|
46
|
+
function Parent() {
|
|
47
|
+
const styles = <style>
|
|
42
48
|
.primary {
|
|
43
49
|
color: blue;
|
|
44
50
|
}
|
|
45
51
|
.secondary {
|
|
46
52
|
color: gray;
|
|
47
53
|
}
|
|
48
|
-
</style
|
|
54
|
+
</style>;
|
|
55
|
+
|
|
56
|
+
return <><Child primary={styles.primary} secondary={styles.secondary} /></>;
|
|
49
57
|
}
|
|
50
58
|
|
|
51
59
|
const { body } = await render(Parent);
|
|
@@ -68,19 +76,19 @@ describe('{style} directive (server)', () => {
|
|
|
68
76
|
});
|
|
69
77
|
|
|
70
78
|
describe('parent styling applied to child', () => {
|
|
71
|
-
it('allows parent to style child elements via
|
|
72
|
-
|
|
73
|
-
|
|
79
|
+
it('allows parent to style child elements via a style expression prop', async () => {
|
|
80
|
+
function Button({ extraClass }: { extraClass?: string }) {
|
|
81
|
+
return <><button class={extraClass ?? ''}>{'Click me'}</button></>;
|
|
74
82
|
}
|
|
75
83
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
<style>
|
|
84
|
+
function App() {
|
|
85
|
+
const styles = <style>
|
|
80
86
|
.fancy {
|
|
81
87
|
background: gold;
|
|
82
88
|
}
|
|
83
|
-
</style
|
|
89
|
+
</style>;
|
|
90
|
+
|
|
91
|
+
return <><Button extraClass={styles.fancy} /></>;
|
|
84
92
|
}
|
|
85
93
|
|
|
86
94
|
const { body } = await render(App);
|
|
@@ -93,25 +101,26 @@ describe('{style} directive (server)', () => {
|
|
|
93
101
|
expect(classes.some((cls: string) => cls === 'fancy')).toBe(true);
|
|
94
102
|
});
|
|
95
103
|
|
|
96
|
-
it('child can combine its own classes with parent
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
it('child can combine its own classes with a parent style expression class', async () => {
|
|
105
|
+
function Card({ className }: { className?: string }) {
|
|
106
|
+
return <>
|
|
107
|
+
<div class={['card-base', className ?? '']}>{'card content'}</div>
|
|
108
|
+
<style>
|
|
109
|
+
.card-base {
|
|
110
|
+
border: 1px solid black;
|
|
111
|
+
}
|
|
112
|
+
</style>
|
|
113
|
+
</>;
|
|
105
114
|
}
|
|
106
115
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
<style>
|
|
116
|
+
function App() {
|
|
117
|
+
const styles = <style>
|
|
111
118
|
.themed {
|
|
112
119
|
background: purple;
|
|
113
120
|
}
|
|
114
|
-
</style
|
|
121
|
+
</style>;
|
|
122
|
+
|
|
123
|
+
return <><Card className={styles.themed} /></>;
|
|
115
124
|
}
|
|
116
125
|
|
|
117
126
|
const { body } = await render(App);
|
|
@@ -124,56 +133,57 @@ describe('{style} directive (server)', () => {
|
|
|
124
133
|
expect(classes.some((cls: string) => cls === 'themed')).toBe(true);
|
|
125
134
|
});
|
|
126
135
|
|
|
127
|
-
it(
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
136
|
+
it('passes a standalone class even when it also appears in descendant context', async () => {
|
|
137
|
+
function Child({ cls }: { cls: string }) {
|
|
138
|
+
return <><span class={cls}>{'text'}</span></>;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function App() {
|
|
142
|
+
const styles = <style>
|
|
143
|
+
.dual {
|
|
144
|
+
color: blue;
|
|
145
|
+
}
|
|
146
|
+
.parent .dual {
|
|
147
|
+
font-weight: bold;
|
|
148
|
+
}
|
|
149
|
+
</style>;
|
|
133
150
|
|
|
134
|
-
|
|
151
|
+
return <>
|
|
135
152
|
<div class="parent">
|
|
136
|
-
<Child cls={
|
|
153
|
+
<Child cls={styles.dual} />
|
|
137
154
|
</div>
|
|
155
|
+
</>;
|
|
156
|
+
}
|
|
138
157
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
color: blue;
|
|
142
|
-
}
|
|
143
|
-
.parent .dual {
|
|
144
|
-
font-weight: bold;
|
|
145
|
-
}
|
|
146
|
-
</style>
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
const { body } = await render(App);
|
|
150
|
-
const { document } = parseHtml(body);
|
|
158
|
+
const { body } = await render(App);
|
|
159
|
+
const { document } = parseHtml(body);
|
|
151
160
|
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
);
|
|
161
|
+
const span = document.querySelector('span');
|
|
162
|
+
expect(span).toBeTruthy();
|
|
163
|
+
const classes = Array.from(span.classList);
|
|
164
|
+
expect(classes.some((cls: string) => cls.startsWith('tsrx-'))).toBe(true);
|
|
165
|
+
expect(classes.some((cls: string) => cls === 'dual')).toBe(true);
|
|
166
|
+
});
|
|
159
167
|
});
|
|
160
168
|
|
|
161
|
-
it('passes scoped
|
|
162
|
-
|
|
163
|
-
|
|
169
|
+
it('passes scoped classes to a dynamic child component via a style expression', async () => {
|
|
170
|
+
function Child({ cls }: { cls: string }) {
|
|
171
|
+
return <><span class={cls}>{'text'}</span></>;
|
|
164
172
|
}
|
|
165
173
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
<div class="wrapper">
|
|
169
|
-
<@dynamic cls={style 'text'} />
|
|
170
|
-
</div>
|
|
171
|
-
|
|
172
|
-
<style>
|
|
174
|
+
function Parent() {
|
|
175
|
+
const styles = <style>
|
|
173
176
|
.text {
|
|
174
177
|
color: red;
|
|
175
178
|
}
|
|
176
|
-
</style
|
|
179
|
+
</style>;
|
|
180
|
+
|
|
181
|
+
return <>
|
|
182
|
+
let dynamic = track(() => Child);
|
|
183
|
+
<div class="wrapper">
|
|
184
|
+
<@dynamic cls={styles.text} />
|
|
185
|
+
</div>
|
|
186
|
+
</>;
|
|
177
187
|
}
|
|
178
188
|
|
|
179
189
|
const { body } = await render(Parent);
|
|
@@ -186,34 +196,60 @@ describe('{style} directive (server)', () => {
|
|
|
186
196
|
expect(classes.some((cls: string) => cls === 'text')).toBe(true);
|
|
187
197
|
});
|
|
188
198
|
|
|
189
|
-
it('
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
{'Wrapper'}
|
|
193
|
-
{children}
|
|
194
|
-
</div>
|
|
195
|
-
|
|
196
|
-
<style>
|
|
197
|
-
.green {
|
|
198
|
-
color: green;
|
|
199
|
-
}
|
|
200
|
-
</style>
|
|
199
|
+
it('passes style expression classes declared outside the component', async () => {
|
|
200
|
+
function Child({ cls }: { cls: string }) {
|
|
201
|
+
return <><span class={cls}>{'text'}</span></>;
|
|
201
202
|
}
|
|
202
203
|
|
|
203
|
-
|
|
204
|
-
<
|
|
204
|
+
function Parent() {
|
|
205
|
+
return <Child cls={external_styles.external} />;
|
|
206
|
+
}
|
|
205
207
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
208
|
+
const { body, css } = await render(Parent);
|
|
209
|
+
const { document } = parseHtml(body);
|
|
210
|
+
|
|
211
|
+
const span = document.querySelector('span');
|
|
212
|
+
expect(span).toBeTruthy();
|
|
213
|
+
const classes = Array.from(span.classList);
|
|
214
|
+
expect(classes.some((cls: string) => cls.startsWith('tsrx-'))).toBe(true);
|
|
215
|
+
expect(classes.some((cls: string) => cls === 'external')).toBe(true);
|
|
216
|
+
|
|
217
|
+
expect(css.size).toBeGreaterThan(0);
|
|
218
|
+
expect(Array.from(css).some((hash: string) => hash.startsWith('tsrx-'))).toBe(true);
|
|
219
|
+
});
|
|
220
|
+
|
|
221
|
+
it('preserves caller scoped hash through wrapper children', async () => {
|
|
222
|
+
function Wrapper({ children }) {
|
|
223
|
+
return <>
|
|
224
|
+
<div class="green">
|
|
225
|
+
{'Wrapper'}
|
|
226
|
+
{children}
|
|
227
|
+
</div>
|
|
228
|
+
<style>
|
|
229
|
+
.green {
|
|
230
|
+
color: green;
|
|
231
|
+
}
|
|
232
|
+
</style>
|
|
233
|
+
</>;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
function Child() {
|
|
237
|
+
return <>
|
|
238
|
+
<div class="red">{'Child'}</div>
|
|
239
|
+
<style>
|
|
240
|
+
.red {
|
|
241
|
+
color: red;
|
|
242
|
+
}
|
|
243
|
+
</style>
|
|
244
|
+
</>;
|
|
211
245
|
}
|
|
212
246
|
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
<
|
|
216
|
-
|
|
247
|
+
function App() {
|
|
248
|
+
return <>
|
|
249
|
+
<Wrapper>
|
|
250
|
+
<Child />
|
|
251
|
+
</Wrapper>
|
|
252
|
+
</>;
|
|
217
253
|
}
|
|
218
254
|
|
|
219
255
|
const { body } = await render(App);
|
|
@@ -232,22 +268,22 @@ describe('{style} directive (server)', () => {
|
|
|
232
268
|
});
|
|
233
269
|
|
|
234
270
|
it('applies caller scoped hash to slotted children through dynamic components', async () => {
|
|
235
|
-
|
|
236
|
-
|
|
271
|
+
function Wrapper({ children }) {
|
|
272
|
+
return <><section>{children}</section></>;
|
|
237
273
|
}
|
|
238
274
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
275
|
+
function App() {
|
|
276
|
+
return <>
|
|
277
|
+
const DynamicWrapper = track(() => Wrapper);
|
|
278
|
+
<@DynamicWrapper>
|
|
279
|
+
<div class="green">{'Slotted child'}</div>
|
|
280
|
+
</@DynamicWrapper>
|
|
281
|
+
<style>
|
|
282
|
+
.green {
|
|
283
|
+
color: green;
|
|
284
|
+
}
|
|
285
|
+
</style>
|
|
286
|
+
</>;
|
|
251
287
|
}
|
|
252
288
|
|
|
253
289
|
const { body } = await render(App);
|
|
@@ -261,40 +297,42 @@ describe('{style} directive (server)', () => {
|
|
|
261
297
|
});
|
|
262
298
|
|
|
263
299
|
describe('server compiler output', () => {
|
|
264
|
-
it('
|
|
300
|
+
it('emits style class maps', () => {
|
|
265
301
|
const source = `
|
|
266
|
-
|
|
302
|
+
function Child({ cls }: { cls: string }) { return <>
|
|
267
303
|
<div class={cls}>{'text'}</div>
|
|
268
|
-
}
|
|
269
|
-
export
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
<style>
|
|
304
|
+
</>; }
|
|
305
|
+
export function App() {
|
|
306
|
+
const styles = <style>
|
|
273
307
|
.highlight {
|
|
274
308
|
color: red;
|
|
275
309
|
}
|
|
276
|
-
</style
|
|
310
|
+
</style>;
|
|
311
|
+
|
|
312
|
+
return <>
|
|
313
|
+
<Child cls={styles.highlight} />
|
|
314
|
+
</>;
|
|
277
315
|
}`;
|
|
278
316
|
const { code } = compile(source, 'test.tsrx', { mode: 'server' });
|
|
279
317
|
|
|
280
318
|
expect(code).toContain('highlight');
|
|
281
|
-
expect(code).toMatch(/tsrx-[a-z0-9]
|
|
319
|
+
expect(code).toMatch(/tsrx-[a-z0-9]+ highlight/);
|
|
282
320
|
expect(code).toContain('register_css');
|
|
283
321
|
});
|
|
284
322
|
|
|
285
323
|
it('includes CSS hash in rendered HTML', async () => {
|
|
286
|
-
|
|
287
|
-
|
|
324
|
+
function Child({ cls }: { cls: string }) {
|
|
325
|
+
return <><div class={cls}>{'hello'}</div></>;
|
|
288
326
|
}
|
|
289
327
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
<style>
|
|
328
|
+
function App() {
|
|
329
|
+
const styles = <style>
|
|
294
330
|
.styled {
|
|
295
331
|
font-weight: bold;
|
|
296
332
|
}
|
|
297
|
-
</style
|
|
333
|
+
</style>;
|
|
334
|
+
|
|
335
|
+
return <><Child cls={styles.styled} /></>;
|
|
298
336
|
}
|
|
299
337
|
|
|
300
338
|
const { body, css } = await render(App);
|