ripple 0.3.2 → 0.3.4
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 +85 -0
- package/package.json +2 -2
- package/src/compiler/identifier-utils.js +0 -2
- package/src/compiler/phases/1-parse/index.js +101 -195
- package/src/compiler/phases/2-analyze/index.js +82 -174
- package/src/compiler/phases/2-analyze/prune.js +2 -2
- package/src/compiler/phases/3-transform/client/index.js +174 -264
- package/src/compiler/phases/3-transform/segments.js +0 -22
- package/src/compiler/phases/3-transform/server/index.js +185 -42
- package/src/compiler/types/index.d.ts +14 -33
- package/src/compiler/utils.js +32 -20
- package/src/runtime/index-client.js +0 -17
- package/src/runtime/internal/client/bindings.js +118 -7
- package/src/runtime/internal/client/render.js +5 -1
- package/src/runtime/internal/client/runtime.js +1 -1
- package/src/runtime/internal/client/types.d.ts +4 -0
- package/tests/client/array/array.copy-within.test.ripple +7 -7
- package/tests/client/array/array.derived.test.ripple +24 -24
- package/tests/client/array/array.iteration.test.ripple +7 -7
- package/tests/client/array/array.mutations.test.ripple +17 -17
- package/tests/client/array/array.to-methods.test.ripple +4 -4
- package/tests/client/async-suspend.test.ripple +3 -3
- package/tests/client/basic/basic.attributes.test.ripple +31 -31
- package/tests/client/basic/basic.collections.test.ripple +6 -6
- package/tests/client/basic/basic.components.test.ripple +8 -8
- package/tests/client/basic/basic.errors.test.ripple +31 -34
- package/tests/client/basic/basic.events.test.ripple +11 -11
- package/tests/client/basic/basic.get-set.test.ripple +18 -18
- package/tests/client/basic/basic.reactivity.test.ripple +36 -36
- package/tests/client/basic/basic.rendering.test.ripple +7 -7
- package/tests/client/basic/basic.utilities.test.ripple +4 -4
- package/tests/client/boundaries.test.ripple +7 -7
- package/tests/client/compiler/__snapshots__/compiler.typescript.test.ripple.snap +24 -0
- package/tests/client/compiler/compiler.assignments.test.ripple +12 -10
- package/tests/client/compiler/compiler.basic.test.ripple +58 -60
- package/tests/client/compiler/compiler.tracked-access.test.ripple +14 -8
- package/tests/client/compiler/compiler.typescript.test.ripple +31 -0
- package/tests/client/composite/composite.dynamic-components.test.ripple +6 -6
- package/tests/client/composite/composite.props.test.ripple +9 -9
- package/tests/client/composite/composite.reactivity.test.ripple +23 -23
- package/tests/client/composite/composite.render.test.ripple +52 -4
- package/tests/client/computed-properties.test.ripple +3 -3
- package/tests/client/context.test.ripple +3 -3
- package/tests/client/css/global-additional-cases.test.ripple +5 -2
- package/tests/client/css/style-identifier.test.ripple +40 -49
- package/tests/client/date.test.ripple +39 -39
- package/tests/client/dynamic-elements.test.ripple +37 -37
- package/tests/client/events.test.ripple +25 -25
- package/tests/client/for.test.ripple +8 -8
- package/tests/client/head.test.ripple +7 -7
- package/tests/client/html.test.ripple +2 -2
- package/tests/client/input-value.test.ripple +376 -177
- package/tests/client/lazy-destructuring.test.ripple +185 -0
- package/tests/client/map.test.ripple +20 -20
- package/tests/client/media-query.test.ripple +4 -4
- package/tests/client/object.test.ripple +5 -5
- package/tests/client/portal.test.ripple +4 -4
- package/tests/client/ref.test.ripple +3 -3
- package/tests/client/return.test.ripple +17 -17
- package/tests/client/set.test.ripple +10 -10
- package/tests/client/svg.test.ripple +6 -5
- package/tests/client/switch.test.ripple +10 -10
- package/tests/client/tracked-expression.test.ripple +3 -1
- package/tests/client/try.test.ripple +4 -4
- package/tests/client/url/url.derived.test.ripple +6 -7
- package/tests/client/url/url.parsing.test.ripple +9 -9
- package/tests/client/url/url.partial-removal.test.ripple +9 -9
- package/tests/client/url/url.reactivity.test.ripple +16 -16
- package/tests/client/url/url.serialization.test.ripple +3 -3
- package/tests/client/url-search-params/url-search-params.derived.test.ripple +7 -8
- package/tests/client/url-search-params/url-search-params.initialization.test.ripple +6 -4
- package/tests/client/url-search-params/url-search-params.iteration.test.ripple +12 -12
- package/tests/client/url-search-params/url-search-params.mutation.test.ripple +18 -18
- package/tests/client/url-search-params/url-search-params.retrieval.test.ripple +16 -16
- package/tests/client/url-search-params/url-search-params.serialization.test.ripple +4 -4
- package/tests/client/url-search-params/url-search-params.tracked-url.test.ripple +3 -3
- package/tests/hydration/build-components.js +4 -10
- package/tests/hydration/compiled/client/basic.js +4 -4
- package/tests/hydration/compiled/client/events.js +2 -0
- package/tests/hydration/compiled/client/for.js +2 -0
- package/tests/hydration/compiled/client/head.js +13 -11
- package/tests/hydration/compiled/client/hmr.js +4 -2
- package/tests/hydration/compiled/client/html.js +82 -95
- package/tests/hydration/compiled/client/if-children.js +8 -9
- package/tests/hydration/compiled/client/if.js +2 -0
- package/tests/hydration/compiled/client/mixed-control-flow.js +4 -2
- package/tests/hydration/compiled/client/portal.js +1 -1
- package/tests/hydration/compiled/client/reactivity.js +2 -0
- package/tests/hydration/compiled/client/return.js +2 -0
- package/tests/hydration/compiled/client/switch.js +2 -0
- package/tests/hydration/compiled/server/composite.js +2 -2
- package/tests/hydration/compiled/server/events.js +2 -0
- package/tests/hydration/compiled/server/for.js +2 -0
- package/tests/hydration/compiled/server/head.js +13 -11
- package/tests/hydration/compiled/server/hmr.js +2 -0
- package/tests/hydration/compiled/server/html.js +2 -0
- package/tests/hydration/compiled/server/if-children.js +2 -0
- package/tests/hydration/compiled/server/if.js +2 -0
- package/tests/hydration/compiled/server/mixed-control-flow.js +2 -0
- package/tests/hydration/compiled/server/portal.js +1 -1
- package/tests/hydration/compiled/server/reactivity.js +2 -0
- package/tests/hydration/compiled/server/return.js +2 -0
- package/tests/hydration/compiled/server/switch.js +2 -0
- package/tests/hydration/components/composite.ripple +1 -1
- package/tests/hydration/components/events.ripple +10 -8
- package/tests/hydration/components/for.ripple +22 -20
- package/tests/hydration/components/head.ripple +8 -6
- package/tests/hydration/components/hmr.ripple +3 -1
- package/tests/hydration/components/html.ripple +3 -1
- package/tests/hydration/components/if-children.ripple +9 -7
- package/tests/hydration/components/if.ripple +7 -5
- package/tests/hydration/components/mixed-control-flow.ripple +5 -3
- package/tests/hydration/components/portal.ripple +2 -2
- package/tests/hydration/components/reactivity.ripple +11 -9
- package/tests/hydration/components/return.ripple +13 -11
- package/tests/hydration/components/switch.ripple +6 -4
- package/tests/server/__snapshots__/compiler.test.ripple.snap +22 -0
- package/tests/server/await.test.ripple +2 -2
- package/tests/server/basic.attributes.test.ripple +21 -19
- package/tests/server/basic.components.test.ripple +5 -4
- package/tests/server/basic.test.ripple +21 -20
- package/tests/server/compiler.test.ripple +36 -5
- package/tests/server/composite.props.test.ripple +7 -6
- package/tests/server/context.test.ripple +3 -1
- package/tests/server/dynamic-elements.test.ripple +24 -24
- package/tests/server/head.test.ripple +7 -5
- package/tests/server/style-identifier.test.ripple +95 -16
- package/types/index.d.ts +4 -1
|
@@ -3,8 +3,9 @@ import { compile } from 'ripple/compiler';
|
|
|
3
3
|
describe('Compiler: Tracked Object Direct Access Checks', () => {
|
|
4
4
|
it('should error on direct access to __v of a tracked object', () => {
|
|
5
5
|
const code = `
|
|
6
|
+
import { track } from 'ripple';
|
|
6
7
|
export default component App() {
|
|
7
|
-
let count =
|
|
8
|
+
let count = track(0);
|
|
8
9
|
console.log(count.__v);
|
|
9
10
|
}
|
|
10
11
|
`;
|
|
@@ -15,8 +16,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
|
|
|
15
16
|
|
|
16
17
|
it('should error on direct access to "a" (get/set config) of a tracked object', () => {
|
|
17
18
|
const code = `
|
|
19
|
+
import { track } from 'ripple';
|
|
18
20
|
export default component App() {
|
|
19
|
-
let myTracked =
|
|
21
|
+
let myTracked = track(0);
|
|
20
22
|
console.log(myTracked.a);
|
|
21
23
|
}
|
|
22
24
|
`;
|
|
@@ -27,8 +29,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
|
|
|
27
29
|
|
|
28
30
|
it('should error on direct access to "b" (block) of a tracked object', () => {
|
|
29
31
|
const code = `
|
|
32
|
+
import { track } from 'ripple';
|
|
30
33
|
export default component App() {
|
|
31
|
-
let myTracked =
|
|
34
|
+
let myTracked = track(0);
|
|
32
35
|
console.log(myTracked.b);
|
|
33
36
|
}
|
|
34
37
|
`;
|
|
@@ -39,8 +42,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
|
|
|
39
42
|
|
|
40
43
|
it('should error on direct access to "c" (clock) of a tracked object', () => {
|
|
41
44
|
const code = `
|
|
45
|
+
import { track } from 'ripple';
|
|
42
46
|
export default component App() {
|
|
43
|
-
let myTracked =
|
|
47
|
+
let myTracked = track(0);
|
|
44
48
|
console.log(myTracked.c);
|
|
45
49
|
}
|
|
46
50
|
`;
|
|
@@ -51,8 +55,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
|
|
|
51
55
|
|
|
52
56
|
it('should error on direct access to "f" (flags) of a tracked object', () => {
|
|
53
57
|
const code = `
|
|
58
|
+
import { track } from 'ripple';
|
|
54
59
|
export default component App() {
|
|
55
|
-
let myTracked =
|
|
60
|
+
let myTracked = track(0);
|
|
56
61
|
console.log(myTracked.f);
|
|
57
62
|
}
|
|
58
63
|
`;
|
|
@@ -63,8 +68,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
|
|
|
63
68
|
|
|
64
69
|
it('should compile successfully with correct @ syntax access', () => {
|
|
65
70
|
const code = `
|
|
71
|
+
import { track } from 'ripple';
|
|
66
72
|
export default component App() {
|
|
67
|
-
let count =
|
|
73
|
+
let count = track(0);
|
|
68
74
|
console.log(@count);
|
|
69
75
|
}
|
|
70
76
|
`;
|
|
@@ -73,9 +79,9 @@ describe('Compiler: Tracked Object Direct Access Checks', () => {
|
|
|
73
79
|
|
|
74
80
|
it('should compile successfully with correct get() function access', () => {
|
|
75
81
|
const code = `
|
|
76
|
-
import { get } from 'ripple';
|
|
82
|
+
import { get, track } from 'ripple';
|
|
77
83
|
export default component App() {
|
|
78
|
-
let count =
|
|
84
|
+
let count = track(0);
|
|
79
85
|
console.log(get(count));
|
|
80
86
|
}
|
|
81
87
|
`;
|
|
@@ -25,4 +25,35 @@ function getString(e: string = 'test') {
|
|
|
25
25
|
|
|
26
26
|
expect(result.js.code).toMatchSnapshot();
|
|
27
27
|
});
|
|
28
|
+
|
|
29
|
+
it('removes class TypeScript syntax from JS output', () => {
|
|
30
|
+
const source = `interface BaseEvent {}
|
|
31
|
+
|
|
32
|
+
class PrintEvent implements BaseEvent {
|
|
33
|
+
text: string;
|
|
34
|
+
|
|
35
|
+
constructor(text: string) {
|
|
36
|
+
this.text = text;
|
|
37
|
+
}
|
|
38
|
+
}`;
|
|
39
|
+
|
|
40
|
+
const result = compile(source, 'test.ripple', { mode: 'client' });
|
|
41
|
+
|
|
42
|
+
expect(result.js.code).not.toContain('implements');
|
|
43
|
+
expect(result.js.code).toMatchSnapshot();
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('removes class extends type arguments from JS output', () => {
|
|
47
|
+
const source = `class StringMap extends Map<string, string> {
|
|
48
|
+
constructor() {
|
|
49
|
+
super();
|
|
50
|
+
}
|
|
51
|
+
}`;
|
|
52
|
+
|
|
53
|
+
const result = compile(source, 'test.ripple', { mode: 'client' });
|
|
54
|
+
|
|
55
|
+
expect(result.js.code).not.toContain('Map<string, string>');
|
|
56
|
+
expect(result.js.code).toContain('class StringMap extends Map');
|
|
57
|
+
expect(result.js.code).toMatchSnapshot();
|
|
58
|
+
});
|
|
28
59
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { flushSync } from 'ripple';
|
|
1
|
+
import { flushSync, track } from 'ripple';
|
|
2
2
|
|
|
3
3
|
describe('composite > dynamic components', () => {
|
|
4
4
|
it('supports rendering composite components using <@component> syntax', () => {
|
|
@@ -7,7 +7,7 @@ describe('composite > dynamic components', () => {
|
|
|
7
7
|
<div>{'Basic Component'}</div>
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
const tracked_basic =
|
|
10
|
+
const tracked_basic = track(() => basic);
|
|
11
11
|
|
|
12
12
|
<@tracked_basic />
|
|
13
13
|
}
|
|
@@ -24,7 +24,7 @@ describe('composite > dynamic components', () => {
|
|
|
24
24
|
<div>{'Basic Component'}</div>
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
const tracked_basic =
|
|
27
|
+
const tracked_basic = track(() => basic);
|
|
28
28
|
|
|
29
29
|
const obj = {
|
|
30
30
|
tracked_basic,
|
|
@@ -45,13 +45,13 @@ describe('composite > dynamic components', () => {
|
|
|
45
45
|
<div>{'Basic Component'}</div>
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
-
const tracked_basic =
|
|
48
|
+
const tracked_basic = track(() => basic);
|
|
49
49
|
|
|
50
50
|
const obj = {
|
|
51
51
|
tracked_basic,
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
const ripple_object =
|
|
54
|
+
const ripple_object = track(obj);
|
|
55
55
|
|
|
56
56
|
<@ripple_object.@tracked_basic />
|
|
57
57
|
}
|
|
@@ -72,7 +72,7 @@ describe('composite > dynamic components', () => {
|
|
|
72
72
|
}
|
|
73
73
|
|
|
74
74
|
component App() {
|
|
75
|
-
let thing =
|
|
75
|
+
let thing = track(() => Child1);
|
|
76
76
|
|
|
77
77
|
<div id="container">
|
|
78
78
|
<@thing />
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Tracked, Props } from 'ripple';
|
|
2
|
-
import { flushSync } from 'ripple';
|
|
2
|
+
import { effect, flushSync, track, trackSplit } from 'ripple';
|
|
3
3
|
|
|
4
4
|
describe('composite > props', () => {
|
|
5
5
|
it('correctly handles default prop values', () => {
|
|
@@ -8,7 +8,7 @@ describe('composite > props', () => {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
component App() {
|
|
11
|
-
let foo =
|
|
11
|
+
let foo = track(123);
|
|
12
12
|
|
|
13
13
|
<Child />
|
|
14
14
|
<Child {@foo} />
|
|
@@ -44,7 +44,7 @@ describe('composite > props', () => {
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
component App() {
|
|
47
|
-
let foo =
|
|
47
|
+
let foo = track(123);
|
|
48
48
|
|
|
49
49
|
<Child />
|
|
50
50
|
<Child {foo} />
|
|
@@ -62,7 +62,7 @@ describe('composite > props', () => {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
component App() {
|
|
65
|
-
let foo =
|
|
65
|
+
let foo = track(123);
|
|
66
66
|
|
|
67
67
|
<Child />
|
|
68
68
|
<Child {@foo} />
|
|
@@ -78,7 +78,7 @@ describe('composite > props', () => {
|
|
|
78
78
|
const logs: number[] = [];
|
|
79
79
|
|
|
80
80
|
component Counter({ count }: { count: Tracked<number> }) {
|
|
81
|
-
|
|
81
|
+
effect(() => {
|
|
82
82
|
logs.push(@count);
|
|
83
83
|
});
|
|
84
84
|
|
|
@@ -86,7 +86,7 @@ describe('composite > props', () => {
|
|
|
86
86
|
}
|
|
87
87
|
|
|
88
88
|
component App() {
|
|
89
|
-
const count =
|
|
89
|
+
const count = track(0);
|
|
90
90
|
|
|
91
91
|
<div>
|
|
92
92
|
<Counter {count} />
|
|
@@ -107,7 +107,7 @@ describe('composite > props', () => {
|
|
|
107
107
|
|
|
108
108
|
it('correctly retains prop accessors and reactivity when using rest props', () => {
|
|
109
109
|
component Button(props: Props) {
|
|
110
|
-
const [children, rest] =
|
|
110
|
+
const [children, rest] = trackSplit(props, ['children']);
|
|
111
111
|
<button {...@rest}>
|
|
112
112
|
<@children />
|
|
113
113
|
</button>
|
|
@@ -122,14 +122,14 @@ describe('composite > props', () => {
|
|
|
122
122
|
}
|
|
123
123
|
|
|
124
124
|
component Toggle(props: { pressed: Tracked<boolean> }) {
|
|
125
|
-
const [pressed, rest] =
|
|
125
|
+
const [pressed, rest] = trackSplit(props, ['pressed']);
|
|
126
126
|
const onClick = () => (@pressed = !@pressed);
|
|
127
127
|
<Button {...@rest} class={@pressed ? 'on' : 'off'} {onClick}>{'button 1'}</Button>
|
|
128
128
|
<Button class={@pressed ? 'on' : 'off'} {onClick}>{'button 2'}</Button>
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
component App() {
|
|
132
|
-
const pressed =
|
|
132
|
+
const pressed = track(true);
|
|
133
133
|
<Toggle {pressed} />
|
|
134
134
|
}
|
|
135
135
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Props, Tracked } from 'ripple';
|
|
2
|
-
import { flushSync } from 'ripple';
|
|
2
|
+
import { RippleObject, effect, flushSync, track, trackSplit } from 'ripple';
|
|
3
3
|
|
|
4
4
|
describe('composite > reactivity', () => {
|
|
5
5
|
it('renders composite components with object state', () => {
|
|
@@ -17,7 +17,7 @@ describe('composite > reactivity', () => {
|
|
|
17
17
|
component App() {
|
|
18
18
|
<div>
|
|
19
19
|
let obj = {
|
|
20
|
-
count:
|
|
20
|
+
count: track(0),
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
<span class="count">{obj.@count}</span>
|
|
@@ -55,7 +55,7 @@ describe('composite > reactivity', () => {
|
|
|
55
55
|
component App() {
|
|
56
56
|
<div>
|
|
57
57
|
let obj = {
|
|
58
|
-
count:
|
|
58
|
+
count: track(0),
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
<span class="count">{obj.@count}</span>
|
|
@@ -84,7 +84,7 @@ describe('composite > reactivity', () => {
|
|
|
84
84
|
|
|
85
85
|
it('parents and children have isolated state', () => {
|
|
86
86
|
component Button(props: { count: number }) {
|
|
87
|
-
let count =
|
|
87
|
+
let count = track(() => props.count);
|
|
88
88
|
<button
|
|
89
89
|
onClick={() => {
|
|
90
90
|
@count++;
|
|
@@ -96,7 +96,7 @@ describe('composite > reactivity', () => {
|
|
|
96
96
|
|
|
97
97
|
component App() {
|
|
98
98
|
<div>
|
|
99
|
-
let count =
|
|
99
|
+
let count = track(0);
|
|
100
100
|
|
|
101
101
|
<button
|
|
102
102
|
onClick={() => {
|
|
@@ -130,8 +130,8 @@ describe('composite > reactivity', () => {
|
|
|
130
130
|
});
|
|
131
131
|
|
|
132
132
|
it('parents and children have isolated connected state (destructured props)', () => {
|
|
133
|
-
component Button({ count }: { count: number }) {
|
|
134
|
-
let local_count =
|
|
133
|
+
component Button(&{ count }: { count: number }) {
|
|
134
|
+
let local_count = track(() => count);
|
|
135
135
|
<button
|
|
136
136
|
onClick={() => {
|
|
137
137
|
@local_count++;
|
|
@@ -143,7 +143,7 @@ describe('composite > reactivity', () => {
|
|
|
143
143
|
|
|
144
144
|
component App() {
|
|
145
145
|
<div>
|
|
146
|
-
let count =
|
|
146
|
+
let count = track(0);
|
|
147
147
|
|
|
148
148
|
<button
|
|
149
149
|
onClick={() => {
|
|
@@ -180,11 +180,11 @@ describe('composite > reactivity', () => {
|
|
|
180
180
|
let logs: string[] = [];
|
|
181
181
|
|
|
182
182
|
component App() {
|
|
183
|
-
const a =
|
|
184
|
-
const b =
|
|
185
|
-
const c =
|
|
183
|
+
const a = track(1);
|
|
184
|
+
const b = track(2);
|
|
185
|
+
const c = track(3);
|
|
186
186
|
|
|
187
|
-
const obj =
|
|
187
|
+
const obj = track(
|
|
188
188
|
() => ({
|
|
189
189
|
@a,
|
|
190
190
|
@b,
|
|
@@ -205,8 +205,8 @@ describe('composite > reactivity', () => {
|
|
|
205
205
|
</button>
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
-
component Child({ a, b, c }: { a: number; b: number; c: number }) {
|
|
209
|
-
|
|
208
|
+
component Child(&{ a, b, c }: { a: number; b: number; c: number }) {
|
|
209
|
+
effect(() => {
|
|
210
210
|
logs.push(`Child effect: ${a}, ${b}, ${c}`);
|
|
211
211
|
});
|
|
212
212
|
|
|
@@ -228,10 +228,10 @@ describe('composite > reactivity', () => {
|
|
|
228
228
|
});
|
|
229
229
|
|
|
230
230
|
it(
|
|
231
|
-
'keeps reactivity for spread props via intermediate components and usage of
|
|
231
|
+
'keeps reactivity for spread props via intermediate components and usage of trackSplit()',
|
|
232
232
|
() => {
|
|
233
233
|
component App() {
|
|
234
|
-
const count =
|
|
234
|
+
const count = track(0);
|
|
235
235
|
<CounterWrapper {@count} up={() => @count++} down={() => @count--} />
|
|
236
236
|
}
|
|
237
237
|
|
|
@@ -242,7 +242,7 @@ describe('composite > reactivity', () => {
|
|
|
242
242
|
}
|
|
243
243
|
|
|
244
244
|
component Counter(props: Props) {
|
|
245
|
-
const [count, up, down, rest] =
|
|
245
|
+
const [count, up, down, rest] = trackSplit(props, ['count', 'up', 'down']);
|
|
246
246
|
<button onClick={() => @up()}>{'UP'}</button>
|
|
247
247
|
<button onClick={() => @down()}>{'DOWN'}</button>
|
|
248
248
|
<span {...@rest}>{`Counter: ${@count}`}</span>
|
|
@@ -270,18 +270,18 @@ describe('composite > reactivity', () => {
|
|
|
270
270
|
|
|
271
271
|
it('keeps reactivity on elements for element spreads and adds / removes dynamic props', () => {
|
|
272
272
|
component App() {
|
|
273
|
-
const count =
|
|
273
|
+
const count = track(0);
|
|
274
274
|
<CounterWrapper {@count} up={() => @count++} />
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
component CounterWrapper(props: { count: number; up: () => void }) {
|
|
278
|
-
const more: { double: Tracked<number>; another?: number; extra: number } =
|
|
279
|
-
double:
|
|
278
|
+
const more: { double: Tracked<number>; another?: number; extra: number } = new RippleObject({
|
|
279
|
+
double: track(() => props.count * 2),
|
|
280
280
|
another: 0,
|
|
281
281
|
extra: 100,
|
|
282
|
-
};
|
|
282
|
+
});
|
|
283
283
|
|
|
284
|
-
|
|
284
|
+
effect(() => {
|
|
285
285
|
props.count;
|
|
286
286
|
if (props.count === 1) {
|
|
287
287
|
delete more.another;
|
|
@@ -302,7 +302,7 @@ describe('composite > reactivity', () => {
|
|
|
302
302
|
another?: number;
|
|
303
303
|
extra: number;
|
|
304
304
|
}) {
|
|
305
|
-
const [count, up, rest] =
|
|
305
|
+
const [count, up, rest] = trackSplit(props, ['count', 'up']);
|
|
306
306
|
<div {...@rest}>{`Counter: ${@count} Double: ${props.@double}`}</div>
|
|
307
307
|
<button onClick={() => @up()}>{'UP'}</button>
|
|
308
308
|
}
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { flushSync,
|
|
1
|
+
import { RippleArray, flushSync, track, type Component } from 'ripple';
|
|
2
2
|
|
|
3
3
|
describe('composite > render', () => {
|
|
4
4
|
it('renders composite components', () => {
|
|
5
|
-
component Button({ count }: { count: number }) {
|
|
5
|
+
component Button(&{ count }: { count: number }) {
|
|
6
6
|
<div>{count}</div>
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
component App() {
|
|
10
|
-
let count =
|
|
10
|
+
let count = track(0);
|
|
11
11
|
|
|
12
12
|
<button onClick={() => @count++}>{'Increment'}</button>
|
|
13
13
|
<Button {@count} />
|
|
@@ -71,6 +71,54 @@ describe('composite > render', () => {
|
|
|
71
71
|
expect(container).toMatchSnapshot();
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
+
it('preserves distinct scoped ripple hashes for wrapper and child content', () => {
|
|
75
|
+
component App() {
|
|
76
|
+
component Wrapper({ children }) {
|
|
77
|
+
<div class="green">
|
|
78
|
+
{'Wrapper'}
|
|
79
|
+
<children />
|
|
80
|
+
</div>
|
|
81
|
+
|
|
82
|
+
<style>
|
|
83
|
+
.green {
|
|
84
|
+
color: green;
|
|
85
|
+
}
|
|
86
|
+
</style>
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
component Child() {
|
|
90
|
+
<div class="red">{'Child'}</div>
|
|
91
|
+
|
|
92
|
+
<style>
|
|
93
|
+
.red {
|
|
94
|
+
color: red;
|
|
95
|
+
}
|
|
96
|
+
</style>
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
<Wrapper>
|
|
100
|
+
<Child />
|
|
101
|
+
</Wrapper>
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
render(App);
|
|
105
|
+
|
|
106
|
+
const wrapper = container.querySelector('.green');
|
|
107
|
+
const child = container.querySelector('.red');
|
|
108
|
+
const wrapper_scopes = Array.from(wrapper.classList).filter(
|
|
109
|
+
(name) => name.startsWith('ripple-'),
|
|
110
|
+
);
|
|
111
|
+
const child_scopes = Array.from(child.classList).filter((name) => name.startsWith('ripple-'));
|
|
112
|
+
|
|
113
|
+
expect(wrapper_scopes).toHaveLength(1);
|
|
114
|
+
expect(child_scopes).toHaveLength(1);
|
|
115
|
+
|
|
116
|
+
const wrapper_scope = wrapper_scopes[0];
|
|
117
|
+
const child_scope = child_scopes.find((name) => name !== wrapper_scope) || child_scopes[0];
|
|
118
|
+
|
|
119
|
+
expect(wrapper_scope).not.toBe(child_scope);
|
|
120
|
+
});
|
|
121
|
+
|
|
74
122
|
it('handles generics', () => {
|
|
75
123
|
component ArrayTest() {
|
|
76
124
|
let items = new RippleArray<number>();
|
|
@@ -83,7 +131,7 @@ describe('composite > render', () => {
|
|
|
83
131
|
});
|
|
84
132
|
|
|
85
133
|
it('should not render <undefined> tag when a passed in component is undefined', () => {
|
|
86
|
-
component Child({
|
|
134
|
+
component Child(&{
|
|
87
135
|
children,
|
|
88
136
|
NonExistent,
|
|
89
137
|
...props
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { flushSync } from 'ripple';
|
|
1
|
+
import { flushSync, track } from 'ripple';
|
|
2
2
|
|
|
3
3
|
describe('computed tracked properties', () => {
|
|
4
4
|
it('should update a property using assignment', () => {
|
|
5
5
|
component App() {
|
|
6
6
|
let obj = {
|
|
7
|
-
[0]:
|
|
7
|
+
[0]: track(0),
|
|
8
8
|
};
|
|
9
9
|
|
|
10
10
|
<div>{obj.@[0]}</div>
|
|
@@ -31,7 +31,7 @@ describe('computed tracked properties', () => {
|
|
|
31
31
|
it('should update a property using update expressions', () => {
|
|
32
32
|
component App() {
|
|
33
33
|
let obj = {
|
|
34
|
-
[0]:
|
|
34
|
+
[0]: track(0),
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
<div>{obj.@[0]}</div>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { describe, it, expect } from 'vitest';
|
|
2
|
-
import { flushSync } from 'ripple';
|
|
2
|
+
import { Context, flushSync } from 'ripple';
|
|
3
3
|
|
|
4
4
|
describe('context', () => {
|
|
5
5
|
it('creates a reactive ref with initial value', () => {
|
|
6
|
-
const MyContext =
|
|
6
|
+
const MyContext = Context<string | null>(null);
|
|
7
7
|
|
|
8
8
|
component Child() {
|
|
9
9
|
const value = MyContext.get();
|
|
@@ -25,7 +25,7 @@ describe('context', () => {
|
|
|
25
25
|
});
|
|
26
26
|
|
|
27
27
|
it('handles context captured inside a computed tracked', () => {
|
|
28
|
-
const MyContext =
|
|
28
|
+
const MyContext = Context<number | null>(null);
|
|
29
29
|
|
|
30
30
|
const doubleContext = () => {
|
|
31
31
|
const value = MyContext.get() as number;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { track } from 'ripple';
|
|
1
2
|
import { compile } from 'ripple/compiler';
|
|
2
3
|
|
|
3
4
|
describe('CSS :global additional use cases', () => {
|
|
@@ -428,9 +429,10 @@ component Child1() {
|
|
|
428
429
|
'handles sibling combinators with dynamic component and :global before scoped elements',
|
|
429
430
|
() => {
|
|
430
431
|
const source = `
|
|
432
|
+
import { track } from 'ripple';
|
|
431
433
|
|
|
432
434
|
export component Test({ children }) {
|
|
433
|
-
const DynamicComponent =
|
|
435
|
+
const DynamicComponent = track(() => Child1);
|
|
434
436
|
<div>
|
|
435
437
|
<p class="before">{'before'}</p>
|
|
436
438
|
|
|
@@ -474,9 +476,10 @@ component Child1() {
|
|
|
474
476
|
'handles sibling combinators with dynamic element or regular element and :global before scoped elements',
|
|
475
477
|
() => {
|
|
476
478
|
const source = `
|
|
479
|
+
import { track } from 'ripple';
|
|
477
480
|
|
|
478
481
|
export component Test({ children, classes }) {
|
|
479
|
-
const dynamicElement =
|
|
482
|
+
const dynamicElement = track('div');
|
|
480
483
|
<div>
|
|
481
484
|
<p class="before">{'before'}</p>
|
|
482
485
|
// Use Dynamic Element but it's the same with a regular one
|