@canvasengine/compiler 2.0.0-beta.11 → 2.0.0-beta.12

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/grammar.pegjs CHANGED
@@ -5,6 +5,34 @@
5
5
  `at line ${start.line}, column ${start.column} to line ${end.line}, column ${end.column}`;
6
6
  throw new Error(errorMessage);
7
7
  }
8
+
9
+ function formatAttributes(attributes) {
10
+ if (attributes.length === 0) {
11
+ return null;
12
+ }
13
+
14
+ // Check if there's exactly one attribute and it's a spread attribute
15
+ if (attributes.length === 1 && attributes[0].startsWith('...')) {
16
+ // Return the identifier directly, removing the '...'
17
+ return attributes[0].substring(3);
18
+ }
19
+
20
+ // Otherwise, format as an object literal
21
+ const formattedAttrs = attributes.map(attr => {
22
+ // If it's a spread attribute, keep it as is
23
+ if (attr.startsWith('...')) {
24
+ return attr;
25
+ }
26
+ // If it's a standalone attribute (doesn't contain ':'), format as shorthand property 'name'
27
+ if (!attr.includes(':')) {
28
+ return attr; // JS object literal shorthand
29
+ }
30
+ // Otherwise (key: value), keep it as is
31
+ return attr;
32
+ });
33
+
34
+ return `{ ${formattedAttrs.join(', ')} }`;
35
+ }
8
36
  }
9
37
 
10
38
  start
@@ -24,8 +52,8 @@ element
24
52
 
25
53
  selfClosingElement
26
54
  = _ "<" _ tagName:tagName _ attributes:attributes _ "/>" _ {
27
- const attrs = attributes.length > 0 ? `{ ${attributes.join(', ')} }` : null;
28
- return attrs ? `h(${tagName}, ${attrs})` : `h(${tagName})`;
55
+ const attrsString = formatAttributes(attributes);
56
+ return attrsString ? `h(${tagName}, ${attrsString})` : `h(${tagName})`;
29
57
  }
30
58
 
31
59
  openCloseElement
@@ -33,12 +61,12 @@ openCloseElement
33
61
  if (tagName !== closingTagName) {
34
62
  error("Mismatched opening and closing tags");
35
63
  }
36
- const attrs = attributes.length > 0 ? `{ ${attributes.join(', ')} }` : null;
64
+ const attrsString = formatAttributes(attributes);
37
65
  const children = content ? content : null;
38
- if (attrs && children) {
39
- return `h(${tagName}, ${attrs}, ${children})`;
40
- } else if (attrs) {
41
- return `h(${tagName}, ${attrs})`;
66
+ if (attrsString && children) {
67
+ return `h(${tagName}, ${attrsString}, ${children})`;
68
+ } else if (attrsString) {
69
+ return `h(${tagName}, ${attrsString})`;
42
70
  } else if (children) {
43
71
  return `h(${tagName}, null, ${children})`;
44
72
  } else {
@@ -61,6 +89,12 @@ attribute
61
89
  = staticAttribute
62
90
  / dynamicAttribute
63
91
  / eventHandler
92
+ / spreadAttribute
93
+
94
+ spreadAttribute
95
+ = "..." objectName:identifier {
96
+ return "..." + objectName;
97
+ }
64
98
 
65
99
  eventHandler
66
100
  = "@" eventName:identifier _ "=" _ "{" _ handlerName:attributeValue _ "}" {
@@ -177,7 +211,9 @@ ifCondition
177
211
  }
178
212
 
179
213
  tagName
180
- = [a-zA-Z][a-zA-Z0-9]* { return text(); }
214
+ = segments:([a-zA-Z][a-zA-Z0-9]* ("." [a-zA-Z][a-zA-Z0-9]*)*) {
215
+ return text();
216
+ }
181
217
 
182
218
  attributeName
183
219
  = [a-zA-Z][a-zA-Z0-9-]* { return text(); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@canvasengine/compiler",
3
- "version": "2.0.0-beta.11",
3
+ "version": "2.0.0-beta.12",
4
4
  "description": "",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -51,12 +51,24 @@ describe("Compiler", () => {
51
51
  expect(output).toBe(`h(Canvas)`);
52
52
  });
53
53
 
54
+ test("should compile component with dot notation", () => {
55
+ const input = `<MyComp.test />`;
56
+ const output = parser.parse(input);
57
+ expect(output).toBe(`h(MyComp.test)`);
58
+ });
59
+
54
60
  test("should compile component with dynamic attribute", () => {
55
61
  const input = `<Canvas width={x} />`;
56
62
  const output = parser.parse(input);
57
63
  expect(output).toBe(`h(Canvas, { width: x })`);
58
64
  });
59
65
 
66
+ test("should compile component with spread operator", () => {
67
+ const input = `<Canvas ...obj />`;
68
+ const output = parser.parse(input);
69
+ expect(output).toBe(`h(Canvas, obj)`);
70
+ });
71
+
60
72
  test("should compile component with dynamic attribute but is not a signal", () => {
61
73
  const input = `<Canvas width={20} />`;
62
74
  const output = parser.parse(input);