diff --git a/packages/babel-plugin-jsx-dom-expressions/src/shared/component.js b/packages/babel-plugin-jsx-dom-expressions/src/shared/component.js
index 3762b868..df813d94 100644
--- a/packages/babel-plugin-jsx-dom-expressions/src/shared/component.js
+++ b/packages/babel-plugin-jsx-dom-expressions/src/shared/component.js
@@ -7,7 +7,8 @@ import {
filterChildren,
trimWhitespace,
transformCondition,
- convertJSXIdentifier
+ convertJSXIdentifier,
+ hasStaticMarker
} from "./utils";
import { transformNode, getCreateTemplate } from "./transform";
@@ -172,13 +173,7 @@ export default function transformComponent(path) {
runningObject.push(t.objectMethod("get", id, [], body, !t.isValidIdentifier(key)));
} else {
runningObject.push(
- t.objectMethod(
- "get",
- id,
- [],
- t.blockStatement([t.returnStatement(value.expression)]),
- !t.isValidIdentifier(key)
- )
+ transformObjectGetter(id, !t.isValidIdentifier(key), value.expression, path)
);
}
} else runningObject.push(t.objectProperty(id, value.expression));
@@ -279,3 +274,62 @@ function transformComponentChildren(children, config) {
}
return [transformedChildren, dynamic];
}
+
+function transformObjectGetter(key, isComputed, value, path) {
+ if (t.isObjectExpression(value)) {
+ // is object recurse
+
+ if (
+ !hasStaticMarker(value, path) &&
+ value.properties.some(
+ prop =>
+ (t.isSpreadElement(prop) || (prop.computed && t.isMemberExpression(prop.key))) &&
+ !hasStaticMarker(prop, path) &&
+ !hasStaticMarker(prop.value, path)
+ )
+ ) {
+ return t.objectMethod(
+ "get",
+ key,
+ [],
+ t.blockStatement([t.returnStatement(transformObjectGetterRecurse(value, path))]),
+ isComputed
+ );
+ }
+
+ return t.objectProperty(key, transformObjectGetterRecurse(value, path), isComputed);
+ }
+
+ // is not object, do not recurse
+
+ if (hasStaticMarker(value, path)) {
+ return t.objectProperty(key, value, isComputed);
+ }
+
+ return t.objectMethod("get", key, [], t.blockStatement([t.returnStatement(value)]), isComputed);
+}
+
+function transformObjectGetterRecurse(object, path) {
+ const properties = object.properties.map(prop => {
+ const key = prop.key;
+ const value = prop.value;
+
+ if (!t.isObjectProperty(prop)) {
+ return prop;
+ }
+
+ if (
+ t.isStringLiteral(value) ||
+ t.isNumericLiteral(value) ||
+ t.isBooleanLiteral(value) ||
+ t.isNullLiteral(value) ||
+ t.isIdentifier(value)
+ ) {
+ return prop;
+ }
+
+ return transformObjectGetter(key, !t.isValidIdentifier(key.name), value, path);
+ });
+
+ return t.objectExpression(properties);
+}
diff --git a/packages/babel-plugin-jsx-dom-expressions/src/shared/utils.js b/packages/babel-plugin-jsx-dom-expressions/src/shared/utils.js
index 2bde30ef..e4f551b9 100644
--- a/packages/babel-plugin-jsx-dom-expressions/src/shared/utils.js
+++ b/packages/babel-plugin-jsx-dom-expressions/src/shared/utils.js
@@ -77,6 +77,17 @@ export function isComponent(tagName) {
);
}
+export function hasStaticMarker(object, path) {
+ if (!object) return false;
+ if (
+ object.leadingComments &&
+ object.leadingComments[0] &&
+ object.leadingComments[0].value.trim() === getConfig(path).staticMarker
+ )
+ return true;
+ if (object.expression) return hasStaticMarker(object.expression, path);
+}
+
export function isDynamic(path, { checkMember, checkTags, checkCallExpressions = true, native }) {
const config = getConfig(path);
if (config.generate === "ssr" && native) {
diff --git a/packages/babel-plugin-jsx-dom-expressions/test/__dom_fixtures__/attributeExpressions/code.js b/packages/babel-plugin-jsx-dom-expressions/test/__dom_fixtures__/attributeExpressions/code.js
index fcd9b249..cb435ce2 100644
--- a/packages/babel-plugin-jsx-dom-expressions/test/__dom_fixtures__/attributeExpressions/code.js
+++ b/packages/babel-plugin-jsx-dom-expressions/test/__dom_fixtures__/attributeExpressions/code.js
@@ -264,3 +264,130 @@ const template80 =
const template81 =
const template82 = x=
+const template84 =
+
+const template85 =
+
+
+
+const template86 =
+
+const template87 =
+const template87a1 =
+const template87a2 =
+
+const template88 =
+
+const template89 =
+
+const template90 =
\ No newline at end of file
diff --git a/packages/babel-plugin-jsx-dom-expressions/test/__dom_fixtures__/attributeExpressions/output.js b/packages/babel-plugin-jsx-dom-expressions/test/__dom_fixtures__/attributeExpressions/output.js
index f7165362..941a10bc 100644
--- a/packages/babel-plugin-jsx-dom-expressions/test/__dom_fixtures__/attributeExpressions/output.js
+++ b/packages/babel-plugin-jsx-dom-expressions/test/__dom_fixtures__/attributeExpressions/output.js
@@ -1,5 +1,6 @@
import { template as _$template } from "r-dom";
import { delegateEvents as _$delegateEvents } from "r-dom";
+import { createComponent as _$createComponent } from "r-dom";
import { setBoolAttribute as _$setBoolAttribute } from "r-dom";
import { insert as _$insert } from "r-dom";
import { memo as _$memo } from "r-dom";
@@ -575,4 +576,179 @@ const template80 = (() => {
})();
const template81 = _tmpl$52();
const template82 = _tmpl$53();
+const template84 = _$createComponent(Comp, {
+ inputProps: {
+ quack,
+ get title() {
+ return title();
+ },
+ get name() {
+ return name();
+ },
+ quack: "best cat",
+ get store() {
+ return store.access;
+ },
+ static_: {
+ get store() {
+ return store.access;
+ },
+ quack: "best cat",
+ get team() {
+ return uy();
+ },
+ store
+ },
+ get spread() {
+ return {
+ ...store
+ };
+ }
+ }
+});
+const template85 = _$createComponent(Comp, {
+ get inputProps() {
+ return {
+ quack,
+ get title() {
+ return title();
+ },
+ get name() {
+ return name();
+ },
+ quack: "best cat",
+ get store() {
+ return store.access;
+ },
+ static_: {
+ get store() {
+ return store.access;
+ },
+ quack: "best cat",
+ get team() {
+ return uy();
+ },
+ store
+ },
+ ...store
+ };
+ }
+});
+const template86 = _$createComponent(Comp, {
+ get inputProps() {
+ return {
+ [quack]: "meaw",
+ get title() {
+ return title();
+ },
+ get name() {
+ return name();
+ },
+ quack: "best cat",
+ get store() {
+ return store.access;
+ },
+ static_: {
+ get store() {
+ return store.access;
+ },
+ quack: "best cat",
+ get team() {
+ return uy();
+ },
+ store
+ },
+ ...store
+ };
+ }
+});
+const template87 = _$createComponent(Comp, {
+ get inputProps() {
+ return {
+ [quack]: "meaw",
+ [store.key]: "ha"
+ };
+ }
+});
+const template87a1 = _$createComponent(Comp, {
+ inputProps: {
+ [quack]: "meaw",
+ [store]: "ha"
+ }
+});
+const template87a2 = _$createComponent(Comp, {
+ get inputProps() {
+ return {
+ [quack.key]: "meaw",
+ [store.key]: "ha"
+ };
+ }
+});
+const template88 = _$createComponent(Comp, {
+ inputProps: {
+ [quack]: /* @once */ "meaw",
+ get title() {
+ return title();
+ },
+ name: /* @once */ name(),
+ quack: "best cat",
+ get store() {
+ return store.access;
+ },
+ static_: {
+ store: /* @once */ store.access,
+ quack: "best cat",
+ team: /* @once */ uy(),
+ /* @once */ store
+ },
+ /* @once */ ...store
+ }
+});
+const template89 = _$createComponent(Comp, {
+ get inputProps() {
+ return {
+ [quack]: /* @once */ "meaw",
+ get title() {
+ return title();
+ },
+ name: /* @once */ name(),
+ quack: "best cat",
+ get store() {
+ return store.access;
+ },
+ static_: {
+ store: /* @once */ store.access,
+ quack: "best cat",
+ team: /* @once */ uy(),
+ /* @once */ store
+ },
+ /* @once */ ...store,
+ ...store
+ };
+ }
+});
+const template90 = _$createComponent(Comp, {
+ get inputProps() {
+ return {
+ [quack]: /* @once */ "meaw",
+ get title() {
+ return title();
+ },
+ name: /* @once */ name(),
+ quack: "best cat",
+ get store() {
+ return store.access;
+ },
+ static_: {
+ store: /* @once */ store.access,
+ quack: "best cat",
+ team: /* @once */ uy(),
+ /* @once */ store,
+ ...store
+ },
+ /* @once */ ...store,
+ ...store
+ };
+ }
+});
_$delegateEvents(["click", "input"]);