ripple 0.2.43 → 0.2.44

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Ripple is a TypeScript UI framework for the web",
4
4
  "license": "MIT",
5
5
  "author": "Dominic Gannaway",
6
- "version": "0.2.43",
6
+ "version": "0.2.44",
7
7
  "type": "module",
8
8
  "module": "src/runtime/index.js",
9
9
  "main": "src/runtime/index.js",
@@ -139,15 +139,14 @@ function RipplePlugin(config) {
139
139
  }
140
140
 
141
141
  if (this.eat(tt.braceL)) {
142
- if (this.type.label === '@') {
142
+ if (this.value === 'ref') {
143
143
  this.next();
144
- if (this.value !== 'use') {
145
- this.unexpected();
144
+ if (this.type === tt.braceR) {
145
+ this.raise(this.start, '"ref" is a Ripple keyword and must be used in the form {ref fn}');
146
146
  }
147
- this.next();
148
147
  node.argument = this.parseMaybeAssign();
149
148
  this.expect(tt.braceR);
150
- return this.finishNode(node, 'UseAttribute');
149
+ return this.finishNode(node, 'RefAttribute');
151
150
  } else if (this.type === tt.ellipsis) {
152
151
  this.expect(tt.ellipsis);
153
152
  node.argument = this.parseMaybeAssign();
@@ -665,9 +665,9 @@ const visitors = {
665
665
  }
666
666
  } else if (attr.type === 'SpreadAttribute') {
667
667
  spread_attributes.push(b.spread(b.call('$.spread_object', visit(attr.argument, state))));
668
- } else if (attr.type === 'UseAttribute') {
668
+ } else if (attr.type === 'RefAttribute') {
669
669
  const id = state.flush_node();
670
- state.init.push(b.stmt(b.call('$.use', id, b.thunk(visit(attr.argument, state)))));
670
+ state.init.push(b.stmt(b.call('$.ref', id, b.thunk(visit(attr.argument, state)))));
671
671
  }
672
672
  }
673
673
 
@@ -770,8 +770,8 @@ const visitors = {
770
770
  ),
771
771
  ),
772
772
  );
773
- } else if (attr.type === 'UseAttribute') {
774
- props.push(b.prop('init', b.call('$.use_prop'), visit(attr.argument, state), true));
773
+ } else if (attr.type === 'RefAttribute') {
774
+ props.push(b.prop('init', b.call('$.ref_prop'), visit(attr.argument, state), true));
775
775
  } else if (attr.type === 'AccessorAttribute') {
776
776
  // # means it's an accessor to the runtime
777
777
  tracked.push(b.literal('#' + attr.name.name));
@@ -1299,6 +1299,10 @@ const visitors = {
1299
1299
  },
1300
1300
 
1301
1301
  TemplateLiteral(node, context) {
1302
+ if (node.expressions.length === 0) {
1303
+ return b.literal(node.quasis[0].value.cooked);
1304
+ }
1305
+
1302
1306
  const expressions = node.expressions.map(expr => context.visit(expr));
1303
1307
  return b.template(node.quasis, expressions);
1304
1308
  },
@@ -1409,12 +1413,12 @@ function transform_ts_child(node, context) {
1409
1413
  const children = [];
1410
1414
  let has_children_props = false;
1411
1415
 
1412
- // Filter out UseAttributes and handle them separately
1413
- const use_attributes = [];
1416
+ // Filter out RefAttributes and handle them separately
1417
+ const ref_attributes = [];
1414
1418
  const attributes = node.attributes
1415
1419
  .filter((attr) => {
1416
- if (attr.type === 'UseAttribute') {
1417
- use_attributes.push(attr);
1420
+ if (attr.type === 'RefAttribute') {
1421
+ ref_attributes.push(attr);
1418
1422
  return false;
1419
1423
  }
1420
1424
  return true;
@@ -1438,10 +1442,10 @@ function transform_ts_child(node, context) {
1438
1442
  }
1439
1443
  });
1440
1444
 
1441
- // Add UseAttribute references separately for sourcemap purposes
1442
- for (const use_attr of use_attributes) {
1445
+ // Add RefAttribute references separately for sourcemap purposes
1446
+ for (const ref_attr of ref_attributes) {
1443
1447
  const metadata = { await: false };
1444
- const argument = visit(use_attr.argument, { ...state, metadata });
1448
+ const argument = visit(ref_attr.argument, { ...state, metadata });
1445
1449
  state.init.push(b.stmt(argument));
1446
1450
  }
1447
1451
 
@@ -61,8 +61,8 @@ export function convert_source_map_to_mappings(source_map, source, generated_cod
61
61
  );
62
62
  const source_content = source.substring(source_offset, source_offset + segment_length);
63
63
 
64
- // Skip mappings for UseAttribute syntax to avoid overlapping sourcemaps
65
- if (source_content.includes('{@use ') || source_content.match(/\{\s*@use\s+/)) {
64
+ // Skip mappings for RefAttribute syntax to avoid overlapping sourcemaps
65
+ if (source_content.includes('{ref ') || source_content.match(/\{\s*ref\s+/)) {
66
66
  continue;
67
67
  }
68
68
 
@@ -50,3 +50,4 @@ export { user_effect as effect } from './internal/client/blocks.js';
50
50
 
51
51
  export { Portal } from './internal/client/portal.js';
52
52
 
53
+ export { ref_prop as createRefKey } from './internal/client/runtime.js';
@@ -99,23 +99,23 @@ export function async(fn) {
99
99
  * @param {() => (element: Element) => (void | (() => void))} get_fn
100
100
  * @returns {Block}
101
101
  */
102
- export function use(element, get_fn) {
102
+ export function ref(element, get_fn) {
103
103
  /** @type {(element: Element) => (void | (() => void) | undefined)} */
104
- var use_fn;
104
+ var ref_fn;
105
105
  /** @type {Block | null} */
106
106
  var e;
107
107
 
108
108
  return block(RENDER_BLOCK, () => {
109
- if (use_fn !== (use_fn = get_fn())) {
109
+ if (ref_fn !== (ref_fn = get_fn())) {
110
110
  if (e) {
111
111
  destroy_block(e);
112
112
  e = null;
113
113
  }
114
114
 
115
- if (use_fn) {
115
+ if (ref_fn) {
116
116
  e = branch(() => {
117
117
  effect(() => {
118
- return use_fn(element);
118
+ return ref_fn(element);
119
119
  });
120
120
  });
121
121
  }
@@ -22,5 +22,5 @@ export var UNINITIALIZED = Symbol();
22
22
  export var TRACKED_OBJECT = Symbol();
23
23
  export var SPREAD_OBJECT = Symbol();
24
24
  export var COMPUTED_PROPERTY = Symbol();
25
- export var USE_PROP = '@use';
25
+ export var REF_PROP = 'ref';
26
26
  export var ARRAY_SET_INDEX_AT = Symbol();
@@ -9,7 +9,7 @@ export {
9
9
  set_selected,
10
10
  } from './render.js';
11
11
 
12
- export { render, render_spread, async, use } from './blocks.js';
12
+ export { render, render_spread, async, ref } from './blocks.js';
13
13
 
14
14
  export { event, delegate } from './events.js';
15
15
 
@@ -42,7 +42,7 @@ export {
42
42
  push_component,
43
43
  pop_component,
44
44
  untrack,
45
- use_prop,
45
+ ref_prop,
46
46
  fallback,
47
47
  exclude_from_object,
48
48
  } from './runtime.js';
@@ -1,5 +1,5 @@
1
- import { destroy_block, use } from './blocks';
2
- import { USE_PROP } from './constants';
1
+ import { destroy_block, ref } from './blocks';
2
+ import { REF_PROP } from './constants';
3
3
  import { get_descriptors, get_own_property_symbols, get_prototype_of } from './utils';
4
4
 
5
5
  export function set_text(text, value) {
@@ -174,16 +174,16 @@ export function apply_element_spread(element, fn) {
174
174
  }
175
175
 
176
176
  for (const symbol of get_own_property_symbols(next)) {
177
- var use_fn = next[symbol];
177
+ var ref_fn = next[symbol];
178
178
 
179
- if (symbol.description === USE_PROP && (!prev || use_fn !== prev[symbol])) {
179
+ if (symbol.description === REF_PROP && (!prev || ref_fn !== prev[symbol])) {
180
180
  if (effects[symbol]) {
181
181
  destroy_block(effects[symbol]);
182
182
  }
183
- effects[symbol] = use(element, () => use_fn);
183
+ effects[symbol] = ref(element, () => ref_fn);
184
184
  }
185
185
 
186
- next[symbol] = use_fn;
186
+ next[symbol] = ref_fn;
187
187
  }
188
188
 
189
189
  set_attributes(element, next);
@@ -25,7 +25,7 @@ import {
25
25
  TRACKED_OBJECT,
26
26
  TRY_BLOCK,
27
27
  UNINITIALIZED,
28
- USE_PROP,
28
+ REF_PROP,
29
29
  ARRAY_SET_INDEX_AT,
30
30
  } from './constants';
31
31
  import { capture, suspend } from './try.js';
@@ -1203,8 +1203,8 @@ export function pop_component() {
1203
1203
  active_component = component.p;
1204
1204
  }
1205
1205
 
1206
- export function use_prop() {
1207
- return Symbol(USE_PROP);
1206
+ export function ref_prop() {
1207
+ return Symbol(REF_PROP);
1208
1208
  }
1209
1209
 
1210
1210
  /**
@@ -88,6 +88,27 @@ describe('basic', () => {
88
88
  expect(container.querySelector('div').textContent).toEqual('');
89
89
  });
90
90
 
91
+ it('render tick template literal for nested children', () => {
92
+ component Child({ $level, $children }) {
93
+ if($level == 1) {
94
+ <h1><$children /></h1>
95
+ }
96
+ if($level == 2) {
97
+ <h2><$children /></h2>
98
+ }
99
+ if($level == 3) {
100
+ <h3><$children /></h3>
101
+ }
102
+ }
103
+
104
+ component App() {
105
+ <Child $level={1}>{`Heading 1`} </Child>
106
+ }
107
+
108
+ render(App);
109
+ expect(container.querySelector('h1').textContent).toEqual('Heading 1');
110
+ });
111
+
91
112
  it('render dynamic class attribute', () => {
92
113
  component Basic() {
93
114
  let $active = false;
@@ -1,7 +1,7 @@
1
1
  import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
2
  import { mount, flushSync, RippleArray } from 'ripple';
3
3
 
4
- describe('@use element decorators', () => {
4
+ describe('refs', () => {
5
5
  let container;
6
6
 
7
7
  function render(component) {
@@ -24,7 +24,7 @@ describe('@use element decorators', () => {
24
24
  let div;
25
25
 
26
26
  component Component() {
27
- <div {@use (node) => { div = node; }}>{'Hello World'}</div>
27
+ <div {ref (node) => { div = node; }}>{'Hello World'}</div>
28
28
  }
29
29
  render(Component);
30
30
  flushSync();
@@ -37,11 +37,11 @@ describe('@use element decorators', () => {
37
37
  component Component() {
38
38
  let items = RippleArray.from([1, 2, 3]);
39
39
 
40
- function ref(node) {
40
+ function componentRef(node) {
41
41
  _node = node;
42
42
  }
43
43
 
44
- <Child {@use ref} {items} />
44
+ <Child {ref componentRef} {items} />
45
45
  }
46
46
 
47
47
  component Child(props) {
package/types/index.d.ts CHANGED
@@ -79,3 +79,5 @@ declare global {
79
79
  // Add other runtime functions as needed for TypeScript analysis
80
80
  };
81
81
  }
82
+
83
+ export declare function createRefKey(): symbol;