ripple 0.3.72 → 0.3.76

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.
Files changed (172) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/package.json +3 -3
  3. package/src/jsx-runtime.d.ts +4 -10
  4. package/src/runtime/dynamic-client.js +33 -0
  5. package/src/runtime/dynamic-server.js +80 -0
  6. package/src/runtime/index-client.js +5 -13
  7. package/src/runtime/index-server.js +2 -0
  8. package/src/runtime/internal/client/blocks.js +6 -27
  9. package/src/runtime/internal/client/composite.js +11 -6
  10. package/src/runtime/internal/client/for.js +80 -5
  11. package/src/runtime/internal/client/index.js +0 -2
  12. package/src/runtime/internal/client/render.js +5 -2
  13. package/src/runtime/internal/client/types.d.ts +0 -10
  14. package/src/runtime/internal/server/index.js +8 -1
  15. package/tests/client/__snapshots__/computed-properties.test.tsrx.snap +8 -0
  16. package/tests/client/__snapshots__/for.test.tsrx.snap +22 -0
  17. package/tests/client/__snapshots__/html.test.tsrx.snap +4 -0
  18. package/tests/client/array/array.copy-within.test.tsrx +19 -19
  19. package/tests/client/array/array.derived.test.tsrx +97 -109
  20. package/tests/client/array/array.iteration.test.tsrx +28 -28
  21. package/tests/client/array/array.mutations.test.tsrx +68 -68
  22. package/tests/client/array/array.static.test.tsrx +82 -92
  23. package/tests/client/array/array.to-methods.test.tsrx +15 -15
  24. package/tests/client/async-suspend.test.tsrx +180 -179
  25. package/tests/client/basic/__snapshots__/basic.attributes.test.tsrx.snap +2 -0
  26. package/tests/client/basic/__snapshots__/basic.rendering.test.tsrx.snap +4 -0
  27. package/tests/client/basic/basic.attributes.test.tsrx +273 -317
  28. package/tests/client/basic/basic.collections.test.tsrx +55 -61
  29. package/tests/client/basic/basic.components.test.tsrx +198 -220
  30. package/tests/client/basic/basic.errors.test.tsrx +70 -76
  31. package/tests/client/basic/basic.events.test.tsrx +80 -85
  32. package/tests/client/basic/basic.get-set.test.tsrx +54 -64
  33. package/tests/client/basic/basic.hmr.test.tsrx +15 -19
  34. package/tests/client/basic/basic.reactivity.test.tsrx +121 -135
  35. package/tests/client/basic/basic.rendering.test.tsrx +273 -178
  36. package/tests/client/basic/basic.styling.test.tsrx +16 -14
  37. package/tests/client/basic/basic.utilities.test.tsrx +8 -10
  38. package/tests/client/boundaries.test.tsrx +18 -18
  39. package/tests/client/compiler/compiler.assignments.test.tsrx +77 -76
  40. package/tests/client/compiler/compiler.attributes.test.tsrx +18 -14
  41. package/tests/client/compiler/compiler.basic.test.tsrx +357 -288
  42. package/tests/client/compiler/compiler.regex.test.tsrx +40 -44
  43. package/tests/client/compiler/compiler.tracked-access.test.tsrx +57 -38
  44. package/tests/client/compiler/compiler.try-in-function.test.tsrx +16 -16
  45. package/tests/client/compiler/compiler.typescript.test.tsrx +4 -3
  46. package/tests/client/composite/composite.dynamic-components.test.tsrx +62 -47
  47. package/tests/client/composite/composite.generics.test.tsrx +165 -167
  48. package/tests/client/composite/composite.props.test.tsrx +66 -74
  49. package/tests/client/composite/composite.reactivity.test.tsrx +132 -166
  50. package/tests/client/composite/composite.render.test.tsrx +92 -101
  51. package/tests/client/computed-properties.test.tsrx +14 -18
  52. package/tests/client/context.test.tsrx +14 -18
  53. package/tests/client/css/global-additional-cases.test.tsrx +493 -439
  54. package/tests/client/css/global-advanced-selectors.test.tsrx +169 -153
  55. package/tests/client/css/global-at-rules.test.tsrx +71 -66
  56. package/tests/client/css/global-basic.test.tsrx +105 -98
  57. package/tests/client/css/global-classes-ids.test.tsrx +128 -114
  58. package/tests/client/css/global-combinators.test.tsrx +83 -78
  59. package/tests/client/css/global-complex-nesting.test.tsrx +134 -120
  60. package/tests/client/css/global-edge-cases.test.tsrx +138 -120
  61. package/tests/client/css/global-keyframes.test.tsrx +108 -96
  62. package/tests/client/css/global-nested.test.tsrx +88 -78
  63. package/tests/client/css/global-pseudo.test.tsrx +104 -98
  64. package/tests/client/css/global-scoping.test.tsrx +145 -125
  65. package/tests/client/css/style-identifier.test.tsrx +65 -72
  66. package/tests/client/date.test.tsrx +83 -83
  67. package/tests/client/dynamic-elements.test.tsrx +318 -299
  68. package/tests/client/events.test.tsrx +252 -266
  69. package/tests/client/for.test.tsrx +120 -127
  70. package/tests/client/head.test.tsrx +74 -48
  71. package/tests/client/html.test.tsrx +37 -49
  72. package/tests/client/input-value.test.tsrx +1125 -1354
  73. package/tests/client/lazy-array.test.tsrx +10 -16
  74. package/tests/client/lazy-destructuring.test.tsrx +169 -221
  75. package/tests/client/map.test.tsrx +39 -41
  76. package/tests/client/media-query.test.tsrx +15 -19
  77. package/tests/client/object.test.tsrx +46 -56
  78. package/tests/client/portal.test.tsrx +31 -37
  79. package/tests/client/ref.test.tsrx +173 -193
  80. package/tests/client/return.test.tsrx +62 -37
  81. package/tests/client/set.test.tsrx +33 -33
  82. package/tests/client/svg.test.tsrx +197 -216
  83. package/tests/client/switch.test.tsrx +201 -191
  84. package/tests/client/track-async-hydration.test.tsrx +14 -18
  85. package/tests/client/tracked-index-access.test.tsrx +18 -28
  86. package/tests/client/try.test.tsrx +494 -619
  87. package/tests/client/tsx.test.tsrx +286 -292
  88. package/tests/client/typescript-generics.test.tsrx +121 -129
  89. package/tests/client/url/url.derived.test.tsrx +21 -25
  90. package/tests/client/url/url.parsing.test.tsrx +35 -35
  91. package/tests/client/url/url.partial-removal.test.tsrx +32 -32
  92. package/tests/client/url/url.reactivity.test.tsrx +68 -72
  93. package/tests/client/url/url.serialization.test.tsrx +8 -8
  94. package/tests/client/url-search-params/url-search-params.derived.test.tsrx +21 -27
  95. package/tests/client/url-search-params/url-search-params.initialization.test.tsrx +16 -16
  96. package/tests/client/url-search-params/url-search-params.iteration.test.tsrx +37 -37
  97. package/tests/client/url-search-params/url-search-params.mutation.test.tsrx +56 -60
  98. package/tests/client/url-search-params/url-search-params.retrieval.test.tsrx +32 -34
  99. package/tests/client/url-search-params/url-search-params.serialization.test.tsrx +9 -9
  100. package/tests/client/url-search-params/url-search-params.tracked-url.test.tsrx +10 -10
  101. package/tests/hydration/compiled/client/basic.js +390 -319
  102. package/tests/hydration/compiled/client/composite.js +52 -44
  103. package/tests/hydration/compiled/client/for.js +734 -604
  104. package/tests/hydration/compiled/client/head.js +183 -103
  105. package/tests/hydration/compiled/client/html.js +93 -86
  106. package/tests/hydration/compiled/client/if-children.js +95 -71
  107. package/tests/hydration/compiled/client/if.js +113 -89
  108. package/tests/hydration/compiled/client/mixed-control-flow.js +225 -209
  109. package/tests/hydration/compiled/client/nested-control-flow.js +94 -98
  110. package/tests/hydration/compiled/client/reactivity.js +26 -24
  111. package/tests/hydration/compiled/client/return.js +8 -42
  112. package/tests/hydration/compiled/client/switch.js +208 -173
  113. package/tests/hydration/compiled/client/track-async-serialization.js +176 -128
  114. package/tests/hydration/compiled/client/try.js +29 -21
  115. package/tests/hydration/compiled/server/basic.js +210 -221
  116. package/tests/hydration/compiled/server/composite.js +13 -14
  117. package/tests/hydration/compiled/server/for.js +427 -444
  118. package/tests/hydration/compiled/server/head.js +199 -189
  119. package/tests/hydration/compiled/server/html.js +33 -41
  120. package/tests/hydration/compiled/server/if-children.js +114 -117
  121. package/tests/hydration/compiled/server/if.js +77 -83
  122. package/tests/hydration/compiled/server/mixed-control-flow.js +145 -150
  123. package/tests/hydration/compiled/server/nested-control-flow.js +10 -0
  124. package/tests/hydration/compiled/server/reactivity.js +24 -22
  125. package/tests/hydration/compiled/server/return.js +6 -18
  126. package/tests/hydration/compiled/server/switch.js +179 -176
  127. package/tests/hydration/compiled/server/track-async-serialization.js +88 -70
  128. package/tests/hydration/compiled/server/try.js +31 -35
  129. package/tests/hydration/components/basic.tsrx +216 -258
  130. package/tests/hydration/components/composite.tsrx +32 -42
  131. package/tests/hydration/components/events.tsrx +81 -101
  132. package/tests/hydration/components/for.tsrx +270 -336
  133. package/tests/hydration/components/head.tsrx +43 -39
  134. package/tests/hydration/components/hmr.tsrx +16 -22
  135. package/tests/hydration/components/html-in-template.tsrx +15 -21
  136. package/tests/hydration/components/html.tsrx +442 -526
  137. package/tests/hydration/components/if-children.tsrx +107 -125
  138. package/tests/hydration/components/if.tsrx +68 -90
  139. package/tests/hydration/components/mixed-control-flow.tsrx +65 -72
  140. package/tests/hydration/components/nested-control-flow.tsrx +202 -216
  141. package/tests/hydration/components/portal.tsrx +33 -41
  142. package/tests/hydration/components/reactivity.tsrx +26 -34
  143. package/tests/hydration/components/return.tsrx +4 -6
  144. package/tests/hydration/components/switch.tsrx +73 -78
  145. package/tests/hydration/components/track-async-serialization.tsrx +83 -93
  146. package/tests/hydration/components/try.tsrx +37 -51
  147. package/tests/hydration/switch.test.js +8 -8
  148. package/tests/server/await.test.tsrx +3 -3
  149. package/tests/server/basic.attributes.test.tsrx +117 -162
  150. package/tests/server/basic.components.test.tsrx +164 -194
  151. package/tests/server/basic.test.tsrx +299 -199
  152. package/tests/server/compiler.test.tsrx +142 -72
  153. package/tests/server/composite.props.test.tsrx +54 -58
  154. package/tests/server/composite.test.tsrx +165 -167
  155. package/tests/server/context.test.tsrx +13 -17
  156. package/tests/server/dynamic-elements.test.tsrx +147 -148
  157. package/tests/server/for.test.tsrx +115 -84
  158. package/tests/server/head.test.tsrx +54 -31
  159. package/tests/server/html-nesting-validation.test.tsrx +16 -8
  160. package/tests/server/if.test.tsrx +49 -59
  161. package/tests/server/lazy-destructuring.test.tsrx +288 -366
  162. package/tests/server/return.test.tsrx +58 -36
  163. package/tests/server/streaming-ssr.test.tsrx +4 -4
  164. package/tests/server/style-identifier.test.tsrx +61 -69
  165. package/tests/server/switch.test.tsrx +89 -97
  166. package/tests/server/track-async-serialization.test.tsrx +85 -103
  167. package/tests/server/try.test.tsrx +275 -360
  168. package/tests/utils/ref-types.test.js +72 -0
  169. package/tests/utils/vite-plugin-config.test.js +41 -74
  170. package/types/index.d.ts +29 -4
  171. package/src/runtime/internal/client/compat.js +0 -40
  172. package/tests/utils/compiler-compat-config.test.js +0 -38
@@ -4,15 +4,17 @@ import { compile } from '@tsrx/ripple';
4
4
  describe('CSS :global additional use cases', () => {
5
5
  it('handles :global as modifier with dot notation', () => {
6
6
  const source = `
7
- export function Test() { return <>
8
- <div class="x">{'content'}</div>
9
-
10
- <style>
11
- div :global.x {
12
- color: red;
13
- }
14
- </style>
15
- </>; }`;
7
+ export function Test() @{
8
+ <>
9
+ <div class="x">{'content'}</div>
10
+
11
+ <style>
12
+ div :global.x {
13
+ color: red;
14
+ }
15
+ </style>
16
+ </>
17
+ }`;
16
18
  const { css } = compile(source, 'test.tsrx');
17
19
 
18
20
  expect(css).toMatch(/div\.tsrx-[a-z0-9]+\.x {/);
@@ -20,17 +22,19 @@ export function Test() { return <>
20
22
 
21
23
  it('handles :global modifier in nested syntax', () => {
22
24
  const source = `
23
- export function Test() { return <>
24
- <div class="x">{'content'}</div>
25
-
26
- <style>
27
- div {
28
- :global.x {
29
- color: green;
25
+ export function Test() @{
26
+ <>
27
+ <div class="x">{'content'}</div>
28
+
29
+ <style>
30
+ div {
31
+ :global.x {
32
+ color: green;
33
+ }
30
34
  }
31
- }
32
- </style>
33
- </>; }`;
35
+ </style>
36
+ </>
37
+ }`;
34
38
  const { css } = compile(source, 'test.tsrx');
35
39
 
36
40
  expect(css).toContain('&.x {');
@@ -38,17 +42,19 @@ export function Test() { return <>
38
42
 
39
43
  it('handles :global with & nesting selector inside block', () => {
40
44
  const source = `
41
- export function Test() { return <>
42
- <div class="x">{'content'}</div>
43
-
44
- <style>
45
- div {
46
- & :global.x {
47
- color: green;
45
+ export function Test() @{
46
+ <>
47
+ <div class="x">{'content'}</div>
48
+
49
+ <style>
50
+ div {
51
+ & :global.x {
52
+ color: green;
53
+ }
48
54
  }
49
- }
50
- </style>
51
- </>; }`;
55
+ </style>
56
+ </>
57
+ }`;
52
58
  const { css } = compile(source, 'test.tsrx');
53
59
 
54
60
  expect(css).toContain('&.x {');
@@ -56,15 +62,17 @@ export function Test() { return <>
56
62
 
57
63
  it('handles :global with :is pseudo-class modifier', () => {
58
64
  const source = `
59
- export function Test() { return <>
60
- <div>{'content'}</div>
61
-
62
- <style>
63
- div :global:is(html.dark-mode *) {
64
- color: green;
65
- }
66
- </style>
67
- </>; }`;
65
+ export function Test() @{
66
+ <>
67
+ <div>{'content'}</div>
68
+
69
+ <style>
70
+ div :global:is(html.dark-mode *) {
71
+ color: green;
72
+ }
73
+ </style>
74
+ </>
75
+ }`;
68
76
  const { css } = compile(source, 'test.tsrx');
69
77
 
70
78
  expect(css).toMatch(/div\.tsrx-[a-z0-9]+:is\(html\.dark-mode \*\) {/);
@@ -72,17 +80,19 @@ export function Test() { return <>
72
80
 
73
81
  it('handles :global with & inside :global block', () => {
74
82
  const source = `
75
- export function Test() { return <>
76
- <div class="class">{'content'}</div>
77
-
78
- <style>
79
- div {
80
- &:global(.class) {
81
- color: green;
83
+ export function Test() @{
84
+ <>
85
+ <div class="class">{'content'}</div>
86
+
87
+ <style>
88
+ div {
89
+ &:global(.class) {
90
+ color: green;
91
+ }
82
92
  }
83
- }
84
- </style>
85
- </>; }`;
93
+ </style>
94
+ </>
95
+ }`;
86
96
  const { css } = compile(source, 'test.tsrx');
87
97
 
88
98
  expect(css).toMatch(/div\.tsrx-[a-z0-9]+ {/);
@@ -91,17 +101,19 @@ export function Test() { return <>
91
101
 
92
102
  it('handles :global(*) with & and descendant', () => {
93
103
  const source = `
94
- export function Test() { return <>
95
- <div class="class">{'content'}</div>
96
-
97
- <style>
98
- :global(*) {
99
- &:hover .class {
100
- color: green;
104
+ export function Test() @{
105
+ <>
106
+ <div class="class">{'content'}</div>
107
+
108
+ <style>
109
+ :global(*) {
110
+ &:hover .class {
111
+ color: green;
112
+ }
101
113
  }
102
- }
103
- </style>
104
- </>; }`;
114
+ </style>
115
+ </>
116
+ }`;
105
117
  const { css } = compile(source, 'test.tsrx');
106
118
 
107
119
  expect(css).toContain('* {');
@@ -110,16 +122,18 @@ export function Test() { return <>
110
122
 
111
123
  it('handles multiple :global selectors in list', () => {
112
124
  const source = `
113
- export function Test() { return <>
114
- <x>{'content'}</x>
115
- <y>{'content'}</y>
116
-
117
- <style>
118
- :global x, :global y {
119
- color: green;
120
- }
121
- </style>
122
- </>; }`;
125
+ export function Test() @{
126
+ <>
127
+ <x>{'content'}</x>
128
+ <y>{'content'}</y>
129
+
130
+ <style>
131
+ :global x, :global y {
132
+ color: green;
133
+ }
134
+ </style>
135
+ </>
136
+ }`;
123
137
  const { css } = compile(source, 'test.tsrx');
124
138
 
125
139
  expect(css).toContain(' x, y {');
@@ -127,19 +141,21 @@ export function Test() { return <>
127
141
 
128
142
  it('handles :global block with nested selector list', () => {
129
143
  const source = `
130
- export function Test() { return <>
131
- <div>
132
- <y>{'content'}</y>
133
- </div>
134
-
135
- <style>
136
- div :global, div :global y, unused :global {
137
- z {
138
- color: green;
144
+ export function Test() @{
145
+ <>
146
+ <div>
147
+ <y>{'content'}</y>
148
+ </div>
149
+
150
+ <style>
151
+ div :global, div :global y, unused :global {
152
+ z {
153
+ color: green;
154
+ }
139
155
  }
140
- }
141
- </style>
142
- </>; }`;
156
+ </style>
157
+ </>
158
+ }`;
143
159
  const { css } = compile(source, 'test.tsrx');
144
160
 
145
161
  expect(css).toMatch(/div\.tsrx-[a-z0-9]+/);
@@ -148,33 +164,35 @@ export function Test() { return <>
148
164
 
149
165
  it('handles keyframes inside :global block', () => {
150
166
  const source = `
151
- export function Test() { return <>
152
- <div class="x">{'animated'}</div>
167
+ export function Test() @{
168
+ <>
169
+ <div class="x">{'animated'}</div>
170
+
171
+ <style>
172
+ :global {
173
+ .x {
174
+ animation: test 1s;
175
+ }
153
176
 
154
- <style>
155
- :global {
156
- .x {
157
- animation: test 1s;
158
- }
177
+ .y {
178
+ animation: test-in 1s;
179
+ }
159
180
 
160
- .y {
161
- animation: test-in 1s;
181
+ @keyframes test-in {
182
+ to {
183
+ opacity: 1;
184
+ }
185
+ }
162
186
  }
163
187
 
164
- @keyframes test-in {
188
+ @keyframes test {
165
189
  to {
166
190
  opacity: 1;
167
191
  }
168
192
  }
169
- }
170
-
171
- @keyframes test {
172
- to {
173
- opacity: 1;
174
- }
175
- }
176
- </style>
177
- </>; }`;
193
+ </style>
194
+ </>
195
+ }`;
178
196
  const { css } = compile(source, 'test.tsrx');
179
197
 
180
198
  expect(css).toContain('@keyframes test-in {');
@@ -186,16 +204,18 @@ export function Test() { return <>
186
204
 
187
205
  it('handles global keyframes with no component elements', () => {
188
206
  const source = `
189
- export function Test() { return <>
190
- <div>{'content'}</div>
191
-
192
- <style>
193
- @keyframes -global-orphan {
194
- 0% { color: red; }
195
- 100% { color: blue; }
196
- }
197
- </style>
198
- </>; }`;
207
+ export function Test() @{
208
+ <>
209
+ <div>{'content'}</div>
210
+
211
+ <style>
212
+ @keyframes -global-orphan {
213
+ 0% { color: red; }
214
+ 100% { color: blue; }
215
+ }
216
+ </style>
217
+ </>
218
+ }`;
199
219
  const { css } = compile(source, 'test.tsrx');
200
220
 
201
221
  expect(css).toContain('@keyframes orphan');
@@ -204,22 +224,24 @@ export function Test() { return <>
204
224
 
205
225
  it('handles :global with class modifier syntax', () => {
206
226
  const source = `
207
- export function Test() { return <>
208
- <div class="blue">{'might be programmatically added'}</div>
209
- <span class="x blue">{'span content'}</span>
210
-
211
- <style>
212
- div:global(.blue) {
213
- color: blue;
214
- }
215
- span:global(.blue).x {
216
- color: blue;
217
- }
218
- span.x:global(.bg) {
219
- background: red;
220
- }
221
- </style>
222
- </>; }`;
227
+ export function Test() @{
228
+ <>
229
+ <div class="blue">{'might be programmatically added'}</div>
230
+ <span class="x blue">{'span content'}</span>
231
+
232
+ <style>
233
+ div:global(.blue) {
234
+ color: blue;
235
+ }
236
+ span:global(.blue).x {
237
+ color: blue;
238
+ }
239
+ span.x:global(.bg) {
240
+ background: red;
241
+ }
242
+ </style>
243
+ </>
244
+ }`;
223
245
  const { css } = compile(source, 'test.tsrx');
224
246
 
225
247
  expect(css).toMatch(/div\.tsrx-[a-z0-9]+\.blue {/);
@@ -229,15 +251,17 @@ export function Test() { return <>
229
251
 
230
252
  it('handles multiple :global() in descendant sequence', () => {
231
253
  const source = `
232
- export function Test() { return <>
233
- <p>{'this may or may not be styled'}</p>
234
-
235
- <style>
236
- :global(div) > :global(section) > p {
237
- color: red;
238
- }
239
- </style>
240
- </>; }`;
254
+ export function Test() @{
255
+ <>
256
+ <p>{'this may or may not be styled'}</p>
257
+
258
+ <style>
259
+ :global(div) > :global(section) > p {
260
+ color: red;
261
+ }
262
+ </style>
263
+ </>
264
+ }`;
241
265
  const { css } = compile(source, 'test.tsrx');
242
266
 
243
267
  expect(css).toContain('div > section > p');
@@ -246,19 +270,21 @@ export function Test() { return <>
246
270
 
247
271
  it('handles :is with :global and html context', () => {
248
272
  const source = `
249
- export function Test() { return <>
250
- <x>
251
- <y>
252
- <z>{'content'}</z>
253
- </y>
254
- </x>
255
-
256
- <style>
257
- x :is(:global(html *)) {
258
- color: green;
259
- }
260
- </style>
261
- </>; }`;
273
+ export function Test() @{
274
+ <>
275
+ <x>
276
+ <y>
277
+ <z>{'content'}</z>
278
+ </y>
279
+ </x>
280
+
281
+ <style>
282
+ x :is(:global(html *)) {
283
+ color: green;
284
+ }
285
+ </style>
286
+ </>
287
+ }`;
262
288
  const { css } = compile(source, 'test.tsrx');
263
289
 
264
290
  expect(css).toMatch(/x\.tsrx-[a-z0-9]+ :is\(html \*\) {/);
@@ -266,26 +292,28 @@ export function Test() { return <>
266
292
 
267
293
  it('handles :global block with :has inside', () => {
268
294
  const source = `
269
- export function Test() { return <>
270
- <div>
271
- <x>{'content'}</x>
272
- </div>
273
-
274
- <style>
275
- :global(.foo) {
276
- :has(x) {
277
- color: green;
295
+ export function Test() @{
296
+ <>
297
+ <div>
298
+ <x>{'content'}</x>
299
+ </div>
300
+
301
+ <style>
302
+ :global(.foo) {
303
+ :has(x) {
304
+ color: green;
305
+ }
306
+ &:has(x) {
307
+ color: green;
308
+ }
278
309
  }
279
- &:has(x) {
310
+
311
+ :global(.foo):has(x) {
280
312
  color: green;
281
313
  }
282
- }
283
-
284
- :global(.foo):has(x) {
285
- color: green;
286
- }
287
- </style>
288
- </>; }`;
314
+ </style>
315
+ </>
316
+ }`;
289
317
  const { css } = compile(source, 'test.tsrx');
290
318
 
291
319
  expect(css).toContain('.foo {');
@@ -296,51 +324,53 @@ export function Test() { return <>
296
324
 
297
325
  it('handles :not with :global in complex nesting', () => {
298
326
  const source = `
299
- export function Test() { return <>
300
- <p class="foo">{'foo'}</p>
301
- <p class="bar">
302
- {'bar'}
303
- <span>{'baz'}</span>
304
- </p>
305
- <span>{'buzz'}</span>
306
-
307
- <style>
308
- :not(:global(.foo)) {
309
- color: green;
310
- }
311
- :not(.foo):not(:global(.unused)) {
312
- color: green;
313
- }
314
- :global(.x):not(.foo) {
315
- color: green;
316
- }
317
- :global(.x) :not(p) {
318
- color: green;
319
- }
320
- :global(.x):not(p) {
321
- color: green;
322
- }
323
-
324
- :global(span):not(p span) {
325
- color: green;
326
- }
327
- span:not(:global(p span)) {
328
- color: green;
329
- }
330
- :global(span:not(p span)) {
331
- color: green;
332
- }
333
-
334
- :global(.x) {
335
- :not(.foo) {
327
+ export function Test() @{
328
+ <>
329
+ <p class="foo">{'foo'}</p>
330
+ <p class="bar">
331
+ {'bar'}
332
+ <span>{'baz'}</span>
333
+ </p>
334
+ <span>{'buzz'}</span>
335
+
336
+ <style>
337
+ :not(:global(.foo)) {
336
338
  color: green;
337
339
  }
338
- &:not(.foo) {
340
+ :not(.foo):not(:global(.unused)) {
339
341
  color: green;
340
342
  }
341
- }
342
- </style>
343
- </>; }`;
343
+ :global(.x):not(.foo) {
344
+ color: green;
345
+ }
346
+ :global(.x) :not(p) {
347
+ color: green;
348
+ }
349
+ :global(.x):not(p) {
350
+ color: green;
351
+ }
352
+
353
+ :global(span):not(p span) {
354
+ color: green;
355
+ }
356
+ span:not(:global(p span)) {
357
+ color: green;
358
+ }
359
+ :global(span:not(p span)) {
360
+ color: green;
361
+ }
362
+
363
+ :global(.x) {
364
+ :not(.foo) {
365
+ color: green;
366
+ }
367
+ &:not(.foo) {
368
+ color: green;
369
+ }
370
+ }
371
+ </style>
372
+ </>
373
+ }`;
344
374
  const { css } = compile(source, 'test.tsrx');
345
375
 
346
376
  expect(css).toContain(':not(.foo)');
@@ -349,33 +379,35 @@ export function Test() { return <>
349
379
 
350
380
  it('handles sibling combinators with children and :global before scoped elements', () => {
351
381
  const source = `
352
- export function Test({ children }) { return <>
353
- <div>
354
- <p class="before">{'before'}</p>
355
-
356
- {children}
357
-
358
- <p class="foo">
359
- <span>{'foo'}</span>
360
- </p>
361
- <p class="bar">{'bar'}</p>
362
- </div>
363
-
364
- <style>
365
- .before + .foo { color: green; }
366
- .before ~ .foo { color: green; }
367
- .before ~ .bar { color: green; }
368
-
369
- :global(.x) + .foo { color: green; }
370
- :global(.x) + .foo span { color: green; }
371
- :global(.x) ~ .foo { color: green; }
372
- :global(.x) ~ .foo span { color: green; }
373
- :global(.x) ~ .bar { color: green; }
374
-
375
- /* should be unused as this is not a possibility */
376
- :global(.x) + .bar { color: green; }
377
- </style>
378
- </>; }`;
382
+ export function Test({ children }) @{
383
+ <>
384
+ <div>
385
+ <p class="before">{'before'}</p>
386
+
387
+ {children}
388
+
389
+ <p class="foo">
390
+ <span>{'foo'}</span>
391
+ </p>
392
+ <p class="bar">{'bar'}</p>
393
+ </div>
394
+
395
+ <style>
396
+ .before + .foo { color: green; }
397
+ .before ~ .foo { color: green; }
398
+ .before ~ .bar { color: green; }
399
+
400
+ :global(.x) + .foo { color: green; }
401
+ :global(.x) + .foo span { color: green; }
402
+ :global(.x) ~ .foo { color: green; }
403
+ :global(.x) ~ .foo span { color: green; }
404
+ :global(.x) ~ .bar { color: green; }
405
+
406
+ /* should be unused as this is not a possibility */
407
+ :global(.x) + .bar { color: green; }
408
+ </style>
409
+ </>
410
+ }`;
379
411
  const { css } = compile(source, 'test.tsrx');
380
412
 
381
413
  expect(css).toMatch(/\.before\.tsrx-[a-z0-9]+ \+ \.foo:where\(\.tsrx-[a-z0-9]+\) {/);
@@ -386,37 +418,39 @@ export function Test({ children }) { return <>
386
418
 
387
419
  it('handles sibling combinators with component and :global before scoped elements', () => {
388
420
  const source = `
389
- export function Test({ children }) { return <>
390
- <div>
391
- <p class="before">{'before'}</p>
392
-
393
- <Child1 />
394
-
395
- <p class="foo">
396
- <span>{'foo'}</span>
397
- </p>
398
- <p class="bar">{'bar'}</p>
399
- </div>
400
-
401
- <style>
402
- .before + .foo { color: green; }
403
- .before ~ .foo { color: green; }
404
- .before ~ .bar { color: green; }
405
-
406
- :global(.x) + .foo { color: green; }
407
- :global(.x) + .foo span { color: green; }
408
- :global(.x) ~ .foo { color: green; }
409
- :global(.x) ~ .foo span { color: green; }
410
- :global(.x) ~ .bar { color: green; }
411
-
412
- /* should be unused as this is not a possibility */
413
- :global(.x) + .bar { color: green; }
414
- </style>
415
- </>; }
416
-
417
- function Child1() { return <>
421
+ export function Test({ children }) @{
422
+ <>
423
+ <div>
424
+ <p class="before">{'before'}</p>
425
+
426
+ <Child1 />
427
+
428
+ <p class="foo">
429
+ <span>{'foo'}</span>
430
+ </p>
431
+ <p class="bar">{'bar'}</p>
432
+ </div>
433
+
434
+ <style>
435
+ .before + .foo { color: green; }
436
+ .before ~ .foo { color: green; }
437
+ .before ~ .bar { color: green; }
438
+
439
+ :global(.x) + .foo { color: green; }
440
+ :global(.x) + .foo span { color: green; }
441
+ :global(.x) ~ .foo { color: green; }
442
+ :global(.x) ~ .foo span { color: green; }
443
+ :global(.x) ~ .bar { color: green; }
444
+
445
+ /* should be unused as this is not a possibility */
446
+ :global(.x) + .bar { color: green; }
447
+ </style>
448
+ </>
449
+ }
450
+
451
+ function Child1() @{
418
452
  <div>{'child1'}</div>
419
- </>; }`;
453
+ }`;
420
454
  const { css } = compile(source, 'test.tsrx');
421
455
 
422
456
  expect(css).toMatch(/\.before\.tsrx-[a-z0-9]+ \+ \.foo:where\(\.tsrx-[a-z0-9]+\) {/);
@@ -429,40 +463,42 @@ function Child1() { return <>
429
463
  'handles sibling combinators with dynamic component and :global before scoped elements',
430
464
  () => {
431
465
  const source = `
432
- import { track } from 'ripple';
466
+ import { Dynamic, track } from 'ripple';
433
467
 
434
- export function Test({ children }) { return <>
468
+ export function Test({ children }) @{
435
469
  const DynamicComponent = track(() => Child1);
436
- <div>
437
- <p class="before">{'before'}</p>
438
-
439
- <@DynamicComponent />
440
-
441
- <p class="foo">
442
- <span>{'foo'}</span>
443
- </p>
444
- <p class="bar">{'bar'}</p>
445
- </div>
446
-
447
- <style>
448
- .before + .foo { color: green; }
449
- .before ~ .foo { color: green; }
450
- .before ~ .bar { color: green; }
451
-
452
- :global(.x) + .foo { color: green; }
453
- :global(.x) + .foo span { color: green; }
454
- :global(.x) ~ .foo { color: green; }
455
- :global(.x) ~ .foo span { color: green; }
456
- :global(.x) ~ .bar { color: green; }
457
-
458
- /* should be unused as this is not a possibility */
459
- :global(.x) + .bar { color: green; }
460
- </style>
461
- </>; }
462
-
463
- function Child1() { return <>
470
+ <>
471
+ <div>
472
+ <p class="before">{'before'}</p>
473
+
474
+ <Dynamic is={DynamicComponent} />
475
+
476
+ <p class="foo">
477
+ <span>{'foo'}</span>
478
+ </p>
479
+ <p class="bar">{'bar'}</p>
480
+ </div>
481
+
482
+ <style>
483
+ .before + .foo { color: green; }
484
+ .before ~ .foo { color: green; }
485
+ .before ~ .bar { color: green; }
486
+
487
+ :global(.x) + .foo { color: green; }
488
+ :global(.x) + .foo span { color: green; }
489
+ :global(.x) ~ .foo { color: green; }
490
+ :global(.x) ~ .foo span { color: green; }
491
+ :global(.x) ~ .bar { color: green; }
492
+
493
+ /* should be unused as this is not a possibility */
494
+ :global(.x) + .bar { color: green; }
495
+ </style>
496
+ </>
497
+ }
498
+
499
+ function Child1() @{
464
500
  <div>{'child1'}</div>
465
- </>; }`;
501
+ }`;
466
502
  const { css } = compile(source, 'test.tsrx');
467
503
 
468
504
  expect(css).toMatch(/\.before\.tsrx-[a-z0-9]+ \+ \.foo:where\(\.tsrx-[a-z0-9]+\) {/);
@@ -476,36 +512,38 @@ function Child1() { return <>
476
512
  'handles sibling combinators with dynamic element or regular element and :global before scoped elements',
477
513
  () => {
478
514
  const source = `
479
- import { track } from 'ripple';
515
+ import { Dynamic, track } from 'ripple';
480
516
 
481
- export function Test({ children, classes }) { return <>
517
+ export function Test({ children, classes }) @{
482
518
  const dynamicElement = track('div');
483
- <div>
484
- <p class="before">{'before'}</p>
485
- // Use Dynamic Element but it's the same with a regular one
486
- <@dynamicElement class={classes} />
487
-
488
- <p class="foo">
489
- <span>{'foo'}</span>
490
- </p>
491
- <p class="bar">{'bar'}</p>
492
- </div>
493
-
494
- <style>
495
- .before + .foo { color: green; }
496
- .before ~ .foo { color: green; }
497
- .before ~ .bar { color: green; }
498
-
499
- :global(.x) + .foo { color: green; }
500
- :global(.x) + .foo span { color: green; }
501
- :global(.x) ~ .foo { color: green; }
502
- :global(.x) ~ .foo span { color: green; }
503
- :global(.x) ~ .bar { color: green; }
504
-
505
- /* should be unused as this is not a possibility */
506
- :global(.x) + .bar { color: green; }
507
- </style>
508
- </>; }`;
519
+ <>
520
+ <div>
521
+ <p class="before">{'before'}</p>
522
+ // Use Dynamic Element but it's the same with a regular one
523
+ <Dynamic is={dynamicElement} class={classes} />
524
+
525
+ <p class="foo">
526
+ <span>{'foo'}</span>
527
+ </p>
528
+ <p class="bar">{'bar'}</p>
529
+ </div>
530
+
531
+ <style>
532
+ .before + .foo { color: green; }
533
+ .before ~ .foo { color: green; }
534
+ .before ~ .bar { color: green; }
535
+
536
+ :global(.x) + .foo { color: green; }
537
+ :global(.x) + .foo span { color: green; }
538
+ :global(.x) ~ .foo { color: green; }
539
+ :global(.x) ~ .foo span { color: green; }
540
+ :global(.x) ~ .bar { color: green; }
541
+
542
+ /* should be unused as this is not a possibility */
543
+ :global(.x) + .bar { color: green; }
544
+ </style>
545
+ </>
546
+ }`;
509
547
 
510
548
  const { css } = compile(source, 'test.tsrx');
511
549
 
@@ -518,19 +556,21 @@ export function Test({ children, classes }) { return <>
518
556
 
519
557
  it('handles :global with multiple global descendants', () => {
520
558
  const source = `
521
- export function Test() { return <>
522
- <div class="root">
523
- <section class="whatever">
524
- <p>{'hello'}</p>
525
- </section>
526
- </div>
527
-
528
- <style>
529
- :global(html) :global(body) .root p {
530
- color: red;
531
- }
532
- </style>
533
- </>; }`;
559
+ export function Test() @{
560
+ <>
561
+ <div class="root">
562
+ <section class="whatever">
563
+ <p>{'hello'}</p>
564
+ </section>
565
+ </div>
566
+
567
+ <style>
568
+ :global(html) :global(body) .root p {
569
+ color: red;
570
+ }
571
+ </style>
572
+ </>
573
+ }`;
534
574
  const { css } = compile(source, 'test.tsrx');
535
575
 
536
576
  expect(css).toMatch(/html body \.root\.tsrx-[a-z0-9]+ p:where\(\.tsrx-[a-z0-9]+\) {/);
@@ -538,25 +578,27 @@ export function Test() { return <>
538
578
 
539
579
  it('handles nested @media with :global blocks', () => {
540
580
  const source = `
541
- export function Test() { return <>
542
- <div>{'content'}</div>
543
-
544
- <style>
545
- div {
546
- color: black;
547
-
548
- @media (min-width: 768px) {
549
- :global {
550
- .foo {
551
- color: red;
581
+ export function Test() @{
582
+ <>
583
+ <div>{'content'}</div>
584
+
585
+ <style>
586
+ div {
587
+ color: black;
588
+
589
+ @media (min-width: 768px) {
590
+ :global {
591
+ .foo {
592
+ color: red;
593
+ }
552
594
  }
553
- }
554
595
 
555
- color: blue;
596
+ color: blue;
597
+ }
556
598
  }
557
- }
558
- </style>
559
- </>; }`;
599
+ </style>
600
+ </>
601
+ }`;
560
602
  const { css } = compile(source, 'test.tsrx');
561
603
 
562
604
  expect(css).toContain('@media (min-width: 768px) {');
@@ -566,28 +608,30 @@ export function Test() { return <>
566
608
 
567
609
  it('handles :has with complex combinators', () => {
568
610
  const source = `
569
- export function Test() { return <>
570
- <g>
571
- <h>
572
- <i>{'content'}</i>
573
- </h>
574
- <j>
575
- <k>{'content'}</k>
576
- </j>
577
- </g>
578
-
579
- <style>
580
- g:has(> h > i) {
581
- color: green;
582
- }
583
- h:has(> h > i) {
584
- color: red;
585
- }
586
- g:has(+ j > k) {
587
- color: green;
588
- }
589
- </style>
590
- </>; }`;
611
+ export function Test() @{
612
+ <>
613
+ <g>
614
+ <h>
615
+ <i>{'content'}</i>
616
+ </h>
617
+ <j>
618
+ <k>{'content'}</k>
619
+ </j>
620
+ </g>
621
+
622
+ <style>
623
+ g:has(> h > i) {
624
+ color: green;
625
+ }
626
+ h:has(> h > i) {
627
+ color: red;
628
+ }
629
+ g:has(+ j > k) {
630
+ color: green;
631
+ }
632
+ </style>
633
+ </>
634
+ }`;
591
635
  const { css } = compile(source, 'test.tsrx');
592
636
 
593
637
  expect(css).toMatch(
@@ -598,20 +642,22 @@ export function Test() { return <>
598
642
 
599
643
  it('handles :global with attribute selectors containing special characters', () => {
600
644
  const source = `
601
- export function Test() { return <>
602
- <div>
603
- <h1 data-title="Hello, world!">{'hello world'}</h1>
604
- </div>
605
-
606
- <style>
607
- div :global(h1[data-title="Hello, world!"]) {
608
- color: red;
609
- }
610
- div :global(h1[attribute], video[autoplay]) {
611
- color: red;
612
- }
613
- </style>
614
- </>; }`;
645
+ export function Test() @{
646
+ <>
647
+ <div>
648
+ <h1 data-title="Hello, world!">{'hello world'}</h1>
649
+ </div>
650
+
651
+ <style>
652
+ div :global(h1[data-title="Hello, world!"]) {
653
+ color: red;
654
+ }
655
+ div :global(h1[attribute], video[autoplay]) {
656
+ color: red;
657
+ }
658
+ </style>
659
+ </>
660
+ }`;
615
661
  const { css } = compile(source, 'test.tsrx');
616
662
 
617
663
  expect(css).toMatch(/div\.tsrx-[a-z0-9]+ h1\[data-title="Hello, world!"\]/);
@@ -620,17 +666,19 @@ export function Test() { return <>
620
666
 
621
667
  it('handles escaped commas in :global class names', () => {
622
668
  const source = `
623
- export function Test() { return <>
624
- <div>
625
- <h1 class="h1,h2,h3">{'hello world'}</h1>
626
- </div>
627
-
628
- <style>
629
- div :global(.h1\\,h2\\,h3) {
630
- color: red;
631
- }
632
- </style>
633
- </>; }`;
669
+ export function Test() @{
670
+ <>
671
+ <div>
672
+ <h1 class="h1,h2,h3">{'hello world'}</h1>
673
+ </div>
674
+
675
+ <style>
676
+ div :global(.h1\\,h2\\,h3) {
677
+ color: red;
678
+ }
679
+ </style>
680
+ </>
681
+ }`;
634
682
  const { css } = compile(source, 'test.tsrx');
635
683
 
636
684
  expect(css).toMatch(/div\.tsrx-[a-z0-9]+ \.h1\\,h2\\,h3 {/);
@@ -641,21 +689,23 @@ export function Test() { return <>
641
689
  */
642
690
  it('handles :global with :is containing multiple selectors', () => {
643
691
  const source = `
644
- export function Test() { return <>
645
- <div>
646
- <h1>{'hello world'}</h1>
647
- <h2>{'subtitle'}</h2>
648
- </div>
649
-
650
- <style>
651
- div :global(:is(h1, h2)) {
652
- color: red;
653
- }
654
- div :global(:where(h1, h2)) {
655
- color: red;
656
- }
657
- </style>
658
- </>; }`;
692
+ export function Test() @{
693
+ <>
694
+ <div>
695
+ <h1>{'hello world'}</h1>
696
+ <h2>{'subtitle'}</h2>
697
+ </div>
698
+
699
+ <style>
700
+ div :global(:is(h1, h2)) {
701
+ color: red;
702
+ }
703
+ div :global(:where(h1, h2)) {
704
+ color: red;
705
+ }
706
+ </style>
707
+ </>
708
+ }`;
659
709
  const { css } = compile(source, 'test.tsrx');
660
710
 
661
711
  expect(css).toMatch(/div\.tsrx-[a-z0-9]+ :is\(h1, h2\)/);
@@ -664,19 +714,21 @@ export function Test() { return <>
664
714
 
665
715
  it('handles :global with :is containing compound selectors', () => {
666
716
  const source = `
667
- export function Test() { return <>
668
- <div>
669
- <h1>{'hello world'}</h1>
670
- <h2>{'subtitle'}</h2>
671
- <h3>{'sub-subtitle'}</h3>
672
- </div>
673
-
674
- <style>
675
- div :global(h1 ~ :is(h2, h3)) {
676
- color: red;
677
- }
678
- </style>
679
- </>; }`;
717
+ export function Test() @{
718
+ <>
719
+ <div>
720
+ <h1>{'hello world'}</h1>
721
+ <h2>{'subtitle'}</h2>
722
+ <h3>{'sub-subtitle'}</h3>
723
+ </div>
724
+
725
+ <style>
726
+ div :global(h1 ~ :is(h2, h3)) {
727
+ color: red;
728
+ }
729
+ </style>
730
+ </>
731
+ }`;
680
732
  const { css } = compile(source, 'test.tsrx');
681
733
 
682
734
  expect(css).toMatch(/div\.tsrx-[a-z0-9]+ h1 ~ :is\(h2, h3\)/);
@@ -684,20 +736,22 @@ export function Test() { return <>
684
736
 
685
737
  it('handles :global with pseudo-elements', () => {
686
738
  const source = `
687
- export function Test() { return <>
688
- <div>
689
- <h1 class="foo">{'hello world'}</h1>
690
- </div>
691
-
692
- <style>
693
- .foo :global(.bar)::after {
694
- color: red;
695
- }
696
- .foo :global(.bar)::after .baz {
697
- color: red;
698
- }
699
- </style>
700
- </>; }`;
739
+ export function Test() @{
740
+ <>
741
+ <div>
742
+ <h1 class="foo">{'hello world'}</h1>
743
+ </div>
744
+
745
+ <style>
746
+ .foo :global(.bar)::after {
747
+ color: red;
748
+ }
749
+ .foo :global(.bar)::after .baz {
750
+ color: red;
751
+ }
752
+ </style>
753
+ </>
754
+ }`;
701
755
  expect(() => compile(source, 'test.tsrx')).toThrow(
702
756
  ':global(...) can be at the start or end of a selector sequence, but not in the middle',
703
757
  );