ripple 0.3.69 → 0.3.71

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 CHANGED
@@ -1,5 +1,24 @@
1
1
  # ripple
2
2
 
3
+ ## 0.3.71
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+ [[`0574e73`](https://github.com/Ripple-TS/ripple/commit/0574e73830a549f515cef6aa8c0a1e38c79b06cc),
9
+ [`0574e73`](https://github.com/Ripple-TS/ripple/commit/0574e73830a549f515cef6aa8c0a1e38c79b06cc)]:
10
+ - @tsrx/core@0.1.19
11
+ - @tsrx/ripple@0.1.19
12
+
13
+ ## 0.3.70
14
+
15
+ ### Patch Changes
16
+
17
+ - Updated dependencies
18
+ [[`5c0b0ff`](https://github.com/Ripple-TS/ripple/commit/5c0b0ff031ddfb319bb048d627e2d2a2a49c1f1d)]:
19
+ - @tsrx/core@0.1.18
20
+ - @tsrx/ripple@0.1.18
21
+
3
22
  ## 0.3.69
4
23
 
5
24
  ### Patch Changes
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Ripple is an elegant TypeScript UI framework",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.3.69",
6
+ "version": "0.3.71",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index-client.js",
9
9
  "main": "src/runtime/index-client.js",
@@ -74,8 +74,8 @@
74
74
  "clsx": "^2.1.1",
75
75
  "devalue": "^5.8.1",
76
76
  "esm-env": "^1.2.2",
77
- "@tsrx/core": "0.1.17",
78
- "@tsrx/ripple": "0.1.17"
77
+ "@tsrx/core": "0.1.19",
78
+ "@tsrx/ripple": "0.1.19"
79
79
  },
80
80
  "devDependencies": {
81
81
  "@types/estree": "^1.0.8",
@@ -524,6 +524,36 @@ function App() { return <>
524
524
  expect(result).toContain('const content = <div class="native">');
525
525
  });
526
526
 
527
+ it('keeps assigned style blocks anchored in to_ts output', () => {
528
+ const source = `
529
+ function App() { return <>
530
+ const styles = <style>
531
+ .logo { display: block; }
532
+ </style>;
533
+
534
+ <div class={styles.logo} />
535
+ </>; }
536
+ `;
537
+ const result = compile_to_volar_mappings(source, 'test.tsrx', { loose: true });
538
+ const source_offset = source.indexOf('<style>') + 1;
539
+ const mapping = result.mappings.find((mapping: {
540
+ sourceOffsets: number[];
541
+ lengths: number[];
542
+ }) => {
543
+ const start = mapping.sourceOffsets[0];
544
+ const end = start + mapping.lengths[0];
545
+ return source_offset >= start && source_offset < end;
546
+ });
547
+
548
+ expect(result.code).toContain('<style></style>');
549
+ expect(result.code).toContain('const styles = {');
550
+ expect(result.code).not.toContain('(<style></style>,');
551
+ expect(result.code).toContain('\'logo\'');
552
+ expect(mapping).toBeDefined();
553
+ expect(mapping?.data.completion).toBe(true);
554
+ expect(mapping?.data.verification).toBe(false);
555
+ });
556
+
527
557
  it('maps identifiers from native expression values in to_ts output', () => {
528
558
  const source = `
529
559
  function App() { return <>
@@ -1,23 +1,27 @@
1
1
  import { track } from 'ripple';
2
2
  import { compile } from '@tsrx/ripple';
3
3
 
4
- describe('style refs', () => {
4
+ const external_styles = <style>
5
+ .external {
6
+ color: tomato;
7
+ }
8
+ </style>;
9
+
10
+ describe('style class maps', () => {
5
11
  describe('basic usage with components', () => {
6
- it('passes scoped classes to a child component via a style ref', () => {
12
+ it('passes scoped classes to a child component via a style expression', () => {
7
13
  function Child({ className }: { className: string }) {
8
14
  return <><div class={className}>{'styled child'}</div></>;
9
15
  }
10
16
 
11
17
  function Parent() {
12
- let styles;
13
- return <>
14
- <Child className={styles.highlight} />
15
- <style ref={(s) => (styles = s)}>
16
- .highlight {
17
- color: red;
18
- }
19
- </style>
20
- </>;
18
+ const styles = <style>
19
+ .highlight {
20
+ color: red;
21
+ }
22
+ </style>;
23
+
24
+ return <><Child className={styles.highlight} /></>;
21
25
  }
22
26
 
23
27
  render(Parent);
@@ -30,7 +34,7 @@ describe('style refs', () => {
30
34
  expect(classes.some((cls: string) => cls === 'highlight')).toBe(true);
31
35
  });
32
36
 
33
- it('passes multiple style ref classes to a child component', () => {
37
+ it('passes multiple style expression classes to a child component', () => {
34
38
  function Child({ primary, secondary }: { primary: string; secondary: string }) {
35
39
  return <>
36
40
  <div class={primary}>{'primary'}</div>
@@ -39,18 +43,16 @@ describe('style refs', () => {
39
43
  }
40
44
 
41
45
  function Parent() {
42
- let styles;
43
- return <>
44
- <Child primary={styles.primary} secondary={styles.secondary} />
45
- <style ref={(s) => (styles = s)}>
46
- .primary {
47
- color: blue;
48
- }
49
- .secondary {
50
- color: gray;
51
- }
52
- </style>
53
- </>;
46
+ const styles = <style>
47
+ .primary {
48
+ color: blue;
49
+ }
50
+ .secondary {
51
+ color: gray;
52
+ }
53
+ </style>;
54
+
55
+ return <><Child primary={styles.primary} secondary={styles.secondary} /></>;
54
56
  }
55
57
 
56
58
  render(Parent);
@@ -70,44 +72,43 @@ describe('style refs', () => {
70
72
  expect(spanClasses.some((cls: string) => cls === 'secondary')).toBe(true);
71
73
  });
72
74
 
73
- it('allows style ref classes on child components with children', () => {
75
+ it('allows style expression classes on child components with children', () => {
74
76
  const source = `
75
77
  function Child({ className }) { return <>
76
78
  <div class={className}>"hello world"</div>
77
79
  </>; }
78
80
  function App() {
79
- let styles;
81
+ const styles = <style>
82
+ .container {
83
+ color: red;
84
+ }
85
+ </style>;
86
+
80
87
  return <>
81
88
  <Child className={styles.container}>"hello world"</Child>
82
-
83
- <style ref={(s) => styles = s}>
84
- .container {
85
- color: red;
86
- }
87
- </style>
88
89
  </>;
89
90
  }`;
90
91
 
91
92
  expect(() => compile(source, 'test.tsrx')).not.toThrow();
92
93
  });
93
94
 
94
- it('passes scoped classes to a dynamic child component via a style ref', () => {
95
+ it('passes scoped classes to a dynamic child component via a style expression', () => {
95
96
  function Child({ cls }: { cls: string }) {
96
97
  return <><span class={cls}>{'text'}</span></>;
97
98
  }
98
99
 
99
100
  function Parent() {
100
- let styles;
101
+ const styles = <style>
102
+ .text {
103
+ color: red;
104
+ }
105
+ </style>;
106
+
101
107
  return <>
102
108
  let dynamic = track(() => Child);
103
109
  <div class="wrapper">
104
110
  <@dynamic cls={styles.text} />
105
111
  </div>
106
- <style ref={(s) => (styles = s)}>
107
- .text {
108
- color: red;
109
- }
110
- </style>
111
112
  </>;
112
113
  }
113
114
 
@@ -120,7 +121,25 @@ function App() {
120
121
  expect(classes.some((cls: string) => cls === 'text')).toBe(true);
121
122
  });
122
123
 
123
- it('child can combine its own classes with a parent style ref class', () => {
124
+ it('passes style expression classes declared outside the component', () => {
125
+ function Child({ cls }: { cls: string }) {
126
+ return <><span class={cls}>{'text'}</span></>;
127
+ }
128
+
129
+ function Parent() {
130
+ return <Child cls={external_styles.external} />;
131
+ }
132
+
133
+ render(Parent);
134
+
135
+ const span = container.querySelector('span');
136
+ expect(span).toBeTruthy();
137
+ const classes = Array.from(span.classList);
138
+ expect(classes.some((cls: string) => cls.startsWith('tsrx-'))).toBe(true);
139
+ expect(classes.some((cls: string) => cls === 'external')).toBe(true);
140
+ });
141
+
142
+ it('child can combine its own classes with a parent style expression class', () => {
124
143
  function Card({ className }: { className?: string }) {
125
144
  return <>
126
145
  <div class={['card-base', className ?? '']}>{'card content'}</div>
@@ -133,15 +152,13 @@ function App() {
133
152
  }
134
153
 
135
154
  function App() {
136
- let styles;
137
- return <>
138
- <Card className={styles.themed} />
139
- <style ref={(s) => (styles = s)}>
140
- .themed {
141
- background: purple;
142
- }
143
- </style>
144
- </>;
155
+ const styles = <style>
156
+ .themed {
157
+ background: purple;
158
+ }
159
+ </style>;
160
+
161
+ return <><Card className={styles.themed} /></>;
145
162
  }
146
163
 
147
164
  render(App);
@@ -159,19 +176,19 @@ function App() {
159
176
  }
160
177
 
161
178
  function App() {
162
- let styles;
179
+ const styles = <style>
180
+ .dual {
181
+ color: blue;
182
+ }
183
+ .parent .dual {
184
+ font-weight: bold;
185
+ }
186
+ </style>;
187
+
163
188
  return <>
164
189
  <div class="parent">
165
190
  <Child cls={styles.dual} />
166
191
  </div>
167
- <style ref={(s) => (styles = s)}>
168
- .dual {
169
- color: blue;
170
- }
171
- .parent .dual {
172
- font-weight: bold;
173
- }
174
- </style>
175
192
  </>;
176
193
  }
177
194
 
@@ -223,15 +240,14 @@ function Child({ cls }) { return <>
223
240
  <div class={cls}>{'text'}</div>
224
241
  </>; }
225
242
  export function App() {
226
- let styles;
243
+ const styles = <style>
244
+ .highlight {
245
+ color: red;
246
+ }
247
+ </style>;
248
+
227
249
  return <>
228
250
  <Child cls={styles.highlight} />
229
-
230
- <style ref={(s) => styles = s}>
231
- .highlight {
232
- color: red;
233
- }
234
- </style>
235
251
  </>;
236
252
  }`;
237
253
  const { code } = compile(source, 'test.tsrx');
@@ -246,15 +262,14 @@ function Child({ cls }) { return <>
246
262
  <div class={cls}>{'text'}</div>
247
263
  </>; }
248
264
  export function App() {
249
- let styles;
265
+ const styles = <style>
266
+ .highlight {
267
+ color: red;
268
+ }
269
+ </style>;
270
+
250
271
  return <>
251
272
  <Child cls={styles.highlight} />
252
-
253
- <style ref={(s) => styles = s}>
254
- .highlight {
255
- color: red;
256
- }
257
- </style>
258
273
  </>;
259
274
  }`;
260
275
  const { code } = compile(source, 'test.tsrx', { mode: 'server' });
@@ -1,23 +1,27 @@
1
1
  import { track } from 'ripple';
2
2
  import { compile } from '@tsrx/ripple';
3
3
 
4
- describe('style refs (server)', () => {
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 classes to a child component via a style ref', async () => {
12
+ it('passes scoped classes to a child component via a style expression', async () => {
7
13
  function Child({ className }: { className: string }) {
8
14
  return <><div class={className}>{'styled child'}</div></>;
9
15
  }
10
16
 
11
17
  function Parent() {
12
- let styles;
13
- return <>
14
- <Child className={styles.highlight} />
15
- <style ref={(s) => (styles = s)}>
16
- .highlight {
17
- color: red;
18
- }
19
- </style>
20
- </>;
18
+ const styles = <style>
19
+ .highlight {
20
+ color: red;
21
+ }
22
+ </style>;
23
+
24
+ return <><Child className={styles.highlight} /></>;
21
25
  }
22
26
 
23
27
  const { body } = await render(Parent);
@@ -31,7 +35,7 @@ describe('style refs (server)', () => {
31
35
  expect(classes.some((cls: string) => cls === 'highlight')).toBe(true);
32
36
  });
33
37
 
34
- it('passes multiple style ref classes to a child component', async () => {
38
+ it('passes multiple style expression classes to a child component', async () => {
35
39
  function Child({ primary, secondary }: { primary: string; secondary: string }) {
36
40
  return <>
37
41
  <div class={primary}>{'primary'}</div>
@@ -40,18 +44,16 @@ describe('style refs (server)', () => {
40
44
  }
41
45
 
42
46
  function Parent() {
43
- let styles;
44
- return <>
45
- <Child primary={styles.primary} secondary={styles.secondary} />
46
- <style ref={(s) => (styles = s)}>
47
- .primary {
48
- color: blue;
49
- }
50
- .secondary {
51
- color: gray;
52
- }
53
- </style>
54
- </>;
47
+ const styles = <style>
48
+ .primary {
49
+ color: blue;
50
+ }
51
+ .secondary {
52
+ color: gray;
53
+ }
54
+ </style>;
55
+
56
+ return <><Child primary={styles.primary} secondary={styles.secondary} /></>;
55
57
  }
56
58
 
57
59
  const { body } = await render(Parent);
@@ -74,21 +76,19 @@ describe('style refs (server)', () => {
74
76
  });
75
77
 
76
78
  describe('parent styling applied to child', () => {
77
- it('allows parent to style child elements via a style ref prop', async () => {
79
+ it('allows parent to style child elements via a style expression prop', async () => {
78
80
  function Button({ extraClass }: { extraClass?: string }) {
79
81
  return <><button class={extraClass ?? ''}>{'Click me'}</button></>;
80
82
  }
81
83
 
82
84
  function App() {
83
- let styles;
84
- return <>
85
- <Button extraClass={styles.fancy} />
86
- <style ref={(s) => (styles = s)}>
87
- .fancy {
88
- background: gold;
89
- }
90
- </style>
91
- </>;
85
+ const styles = <style>
86
+ .fancy {
87
+ background: gold;
88
+ }
89
+ </style>;
90
+
91
+ return <><Button extraClass={styles.fancy} /></>;
92
92
  }
93
93
 
94
94
  const { body } = await render(App);
@@ -101,7 +101,7 @@ describe('style refs (server)', () => {
101
101
  expect(classes.some((cls: string) => cls === 'fancy')).toBe(true);
102
102
  });
103
103
 
104
- it('child can combine its own classes with a parent style ref class', async () => {
104
+ it('child can combine its own classes with a parent style expression class', async () => {
105
105
  function Card({ className }: { className?: string }) {
106
106
  return <>
107
107
  <div class={['card-base', className ?? '']}>{'card content'}</div>
@@ -114,15 +114,13 @@ describe('style refs (server)', () => {
114
114
  }
115
115
 
116
116
  function App() {
117
- let styles;
118
- return <>
119
- <Card className={styles.themed} />
120
- <style ref={(s) => (styles = s)}>
121
- .themed {
122
- background: purple;
123
- }
124
- </style>
125
- </>;
117
+ const styles = <style>
118
+ .themed {
119
+ background: purple;
120
+ }
121
+ </style>;
122
+
123
+ return <><Card className={styles.themed} /></>;
126
124
  }
127
125
 
128
126
  const { body } = await render(App);
@@ -141,19 +139,19 @@ describe('style refs (server)', () => {
141
139
  }
142
140
 
143
141
  function App() {
144
- let styles;
142
+ const styles = <style>
143
+ .dual {
144
+ color: blue;
145
+ }
146
+ .parent .dual {
147
+ font-weight: bold;
148
+ }
149
+ </style>;
150
+
145
151
  return <>
146
152
  <div class="parent">
147
153
  <Child cls={styles.dual} />
148
154
  </div>
149
- <style ref={(s) => (styles = s)}>
150
- .dual {
151
- color: blue;
152
- }
153
- .parent .dual {
154
- font-weight: bold;
155
- }
156
- </style>
157
155
  </>;
158
156
  }
159
157
 
@@ -168,23 +166,23 @@ describe('style refs (server)', () => {
168
166
  });
169
167
  });
170
168
 
171
- it('passes scoped classes to a dynamic child component via a style ref', async () => {
169
+ it('passes scoped classes to a dynamic child component via a style expression', async () => {
172
170
  function Child({ cls }: { cls: string }) {
173
171
  return <><span class={cls}>{'text'}</span></>;
174
172
  }
175
173
 
176
174
  function Parent() {
177
- let styles;
175
+ const styles = <style>
176
+ .text {
177
+ color: red;
178
+ }
179
+ </style>;
180
+
178
181
  return <>
179
182
  let dynamic = track(() => Child);
180
183
  <div class="wrapper">
181
184
  <@dynamic cls={styles.text} />
182
185
  </div>
183
- <style ref={(s) => (styles = s)}>
184
- .text {
185
- color: red;
186
- }
187
- </style>
188
186
  </>;
189
187
  }
190
188
 
@@ -198,6 +196,28 @@ describe('style refs (server)', () => {
198
196
  expect(classes.some((cls: string) => cls === 'text')).toBe(true);
199
197
  });
200
198
 
199
+ it('passes style expression classes declared outside the component', async () => {
200
+ function Child({ cls }: { cls: string }) {
201
+ return <><span class={cls}>{'text'}</span></>;
202
+ }
203
+
204
+ function Parent() {
205
+ return <Child cls={external_styles.external} />;
206
+ }
207
+
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
+
201
221
  it('preserves caller scoped hash through wrapper children', async () => {
202
222
  function Wrapper({ children }) {
203
223
  return <>
@@ -283,15 +303,14 @@ function Child({ cls }: { cls: string }) { return <>
283
303
  <div class={cls}>{'text'}</div>
284
304
  </>; }
285
305
  export function App() {
286
- let styles;
306
+ const styles = <style>
307
+ .highlight {
308
+ color: red;
309
+ }
310
+ </style>;
311
+
287
312
  return <>
288
313
  <Child cls={styles.highlight} />
289
-
290
- <style ref={(s) => styles = s}>
291
- .highlight {
292
- color: red;
293
- }
294
- </style>
295
314
  </>;
296
315
  }`;
297
316
  const { code } = compile(source, 'test.tsrx', { mode: 'server' });
@@ -307,15 +326,13 @@ export function App() {
307
326
  }
308
327
 
309
328
  function App() {
310
- let styles;
311
- return <>
312
- <Child cls={styles.styled} />
313
- <style ref={(s) => (styles = s)}>
314
- .styled {
315
- font-weight: bold;
316
- }
317
- </style>
318
- </>;
329
+ const styles = <style>
330
+ .styled {
331
+ font-weight: bold;
332
+ }
333
+ </style>;
334
+
335
+ return <><Child cls={styles.styled} /></>;
319
336
  }
320
337
 
321
338
  const { body, css } = await render(App);