Wrap JSXElement in expr container (for JSXAttribute)
Joe Savona committed
Sep 14, 2023 at 21:48 UTC
c70e87f53501f329b25c4e78e2eafc0aab270292
3 files changed
+148
-2
compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts
+1
-2
@@ -1279,8 +1279,7 @@ function codegenJsxAttribute(
1279
const innerValue = codegenPlace(cx, attribute.place);
1280
let value;
1281
switch (innerValue.type) {
1282
- case "StringLiteral":
1283
- case "JSXElement": {
1282
+ case "StringLiteral": {
1283
value = innerValue;
1284
break;
1285
}
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-element-value.expect.md
new
+113
@@ -0,0 +1,113 @@
1
+
2
+## Input
3
+
4
+```javascript
5
+// @flow
6
+function Component({ items }) {
7
+ // Per the spec, <Foo value=<>{...}</> /> is valid.
8
+ // But many tools don't allow fragments as jsx attribute values,
9
+ // so we ensure not to emit them wrapped in an expression container
10
+ return items.length > 0 ? (
11
+ <Foo
12
+ value={
13
+ <Bar>
14
+ {items.map((item) => (
15
+ <Item key={item.id} item={item} />
16
+ ))}
17
+ </Bar>
18
+ }
19
+ ></Foo>
20
+ ) : null;
21
+}
22
+
23
+function Foo({ value }) {
24
+ return value;
25
+}
26
+
27
+function Bar({ children }) {
28
+ return <div>{children}</div>;
29
+}
30
+
31
+function Item({ item }) {
32
+ return <div>{item.name}</div>;
33
+}
34
+
35
+export const FIXTURE_ENTRYPOINT = {
36
+ fn: Component,
37
+ params: [{ items: [{ id: 1, name: "One!" }] }],
38
+};
39
+
40
+```
41
+
42
+## Code
43
+
44
+```javascript
45
+import { unstable_useMemoCache as useMemoCache } from "react";
46
+function Component(t29) {
47
+ const $ = useMemoCache(2);
48
+ const { items } = t29;
49
+ const c_0 = $[0] !== items;
50
+ let t0;
51
+ if (c_0) {
52
+ t0 =
53
+ items.length > 0 ? (
54
+ <Foo
55
+ value={
56
+ <Bar>
57
+ {items.map((item) => (
58
+ <Item key={item.id} item={item} />
59
+ ))}
60
+ </Bar>
61
+ }
62
+ />
63
+ ) : null;
64
+ $[0] = items;
65
+ $[1] = t0;
66
+ } else {
67
+ t0 = $[1];
68
+ }
69
+ return t0;
70
+}
71
+
72
+function Foo(t5) {
73
+ const { value } = t5;
74
+ return value;
75
+}
76
+
77
+function Bar(t6) {
78
+ const $ = useMemoCache(2);
79
+ const { children } = t6;
80
+ const c_0 = $[0] !== children;
81
+ let t0;
82
+ if (c_0) {
83
+ t0 = <div>{children}</div>;
84
+ $[0] = children;
85
+ $[1] = t0;
86
+ } else {
87
+ t0 = $[1];
88
+ }
89
+ return t0;
90
+}
91
+
92
+function Item(t7) {
93
+ const $ = useMemoCache(2);
94
+ const { item } = t7;
95
+ const c_0 = $[0] !== item.name;
96
+ let t0;
97
+ if (c_0) {
98
+ t0 = <div>{item.name}</div>;
99
+ $[0] = item.name;
100
+ $[1] = t0;
101
+ } else {
102
+ t0 = $[1];
103
+ }
104
+ return t0;
105
+}
106
+
107
+export const FIXTURE_ENTRYPOINT = {
108
+ fn: Component,
109
+ params: [{ items: [{ id: 1, name: "One!" }] }],
110
+};
111
+
112
+```
113
+
\ No newline at end of file
compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/jsx-attribute-with-jsx-element-value.js
new
+34
@@ -0,0 +1,34 @@
1
+// @flow
2
+function Component({ items }) {
3
+ // Per the spec, <Foo value=<>{...}</> /> is valid.
4
+ // But many tools don't allow fragments as jsx attribute values,
5
+ // so we ensure not to emit them wrapped in an expression container
6
+ return items.length > 0 ? (
7
+ <Foo
8
+ value={
9
+ <Bar>
10
+ {items.map((item) => (
11
+ <Item key={item.id} item={item} />
12
+ ))}
13
+ </Bar>
14
+ }
15
+ ></Foo>
16
+ ) : null;
17
+}
18
+
19
+function Foo({ value }) {
20
+ return value;
21
+}
22
+
23
+function Bar({ children }) {
24
+ return <div>{children}</div>;
25
+}
26
+
27
+function Item({ item }) {
28
+ return <div>{item.name}</div>;
29
+}
30
+
31
+export const FIXTURE_ENTRYPOINT = {
32
+ fn: Component,
33
+ params: [{ items: [{ id: 1, name: "One!" }] }],
34
+};