diff --git a/packages/entity/src/behavior-components/expression.jsx b/packages/entity/src/behavior-components/expression.jsx
index 20f4f63..70835f5 100644
--- a/packages/entity/src/behavior-components/expression.jsx
+++ b/packages/entity/src/behavior-components/expression.jsx
@@ -1,7 +1,11 @@
import {join, relative} from 'path';
-import {isInvocation, isKey} from '@avocado/behavior';
-import {PropTypes, React} from '@latus/react';
+import {compile, isInvocation, isKey} from '@avocado/behavior';
+import {
+ PropTypes,
+ React,
+ useLatus,
+} from '@latus/react';
import {useJsonPatcher} from '@persea/json';
import classnames from 'classnames';
@@ -10,18 +14,18 @@ import Key from './expression/key';
const Expression = ({
context,
- expression,
+ value,
path,
type,
}) => {
+ const latus = useLatus();
const patch = useJsonPatcher();
let i = 0;
- const {ops} = expression;
+ const {ops} = value;
const Renderables = [];
let opsCount = 0;
- let walk = context;
// eslint-disable-next-line react/destructuring-assignment
- let description = context.constructor.descriptionFor(walk);
+ let description = context.constructor.descriptionFor(context);
const onChange = (event, value, localPath) => {
const patches = [];
const j = parseInt(relative(path, localPath).split('/')[1], 10);
@@ -100,8 +104,8 @@ const Expression = ({
onChange(event, value, localPath);
}
}}
- op={op}
path={opPath}
+ value={op.key}
/>,
);
opsCount += 1;
@@ -136,15 +140,10 @@ const Expression = ({
opsCount += 1;
}
if (isKey(op)) {
- if (context === walk) {
- [walk] = context.get(op.key);
- }
- else {
- walk = walk[op.key];
- }
+ const current = compile({type: 'expression', ops: ops.slice(0, i + 1)}, latus)(context);
description = {
- ...context.constructor.descriptionFor(walk),
- ...description.children[op.key],
+ ...context.constructor.descriptionFor(current),
+ ...description?.children?.[op.key] || {},
};
if (description.args && (!nextOp || !isInvocation(nextOp))) {
Renderables.push(
@@ -154,17 +153,16 @@ const Expression = ({
onClick={((description, opPath) => () => {
const parts = opPath.split('/');
parts.push(parseInt(parts.pop(), 10) + 1);
- const invocation = {
- type: 'invoke',
- args: description.args.map(() => ({
- type: 'literal',
- value: null,
- })),
- };
patch({
op: 'add',
path: parts.join('/'),
- value: invocation,
+ value: {
+ type: 'invoke',
+ args: description.args.map(() => ({
+ type: 'literal',
+ value: null,
+ })),
+ },
});
})(description, opPath)}
type="button"
@@ -218,7 +216,7 @@ Expression.propTypes = {
describe: PropTypes.func,
get: PropTypes.func,
}).isRequired,
- expression: PropTypes.shape({
+ value: PropTypes.shape({
ops: PropTypes.arrayOf(
PropTypes.shape({
key: PropTypes.string,
diff --git a/packages/entity/src/behavior-components/expression/invocation.jsx b/packages/entity/src/behavior-components/expression/invocation.jsx
index 010c087..808de71 100644
--- a/packages/entity/src/behavior-components/expression/invocation.jsx
+++ b/packages/entity/src/behavior-components/expression/invocation.jsx
@@ -1,22 +1,33 @@
import {join} from 'path';
import {PropTypes, React} from '@latus/react';
-import {useJsonPatcher} from '@persea/json';
-import Literal from '../literal';
-import Key from './key';
+import Variant from '../variant';
const Invocation = ({
context,
description,
- Expression,
onChange,
op,
path,
}) => {
// eslint-disable-next-line react/destructuring-assignment
- const contextDescription = context.describe();
- const patch = useJsonPatcher();
+ const argComponent = (arg, i) => {
+ const argPath = join(path, 'args', i.toString());
+ const options = description?.args?.[i].options;
+ const type = description?.args?.[i].type || 'undefined';
+ return (
+
+ );
+ };
return (
(
@@ -26,55 +37,7 @@ const Invocation = ({
key={join(path, 'args', i.toString())}
className="invocation__arg"
>
- {
- 'literal' === arg.type
- ? (
- <>
- ': {
- label: '',
- type: arg.type,
- },
- ...contextDescription.children,
- }}
- onChange={(event, value) => {
- patch({
- op: 'replace',
- path: join(path, 'args', i.toString()),
- value: {
- type: 'expression',
- ops: [
- {
- type: 'key',
- key: value,
- },
- ],
- },
- });
- }}
- op={op}
- path={path}
- />
-
- >
- )
- : (
-
- )
- }
+ {argComponent(arg, i)}
{i < op.args.length - 1 && , }
))
@@ -85,9 +48,7 @@ const Invocation = ({
};
Invocation.propTypes = {
- context: PropTypes.shape({
- describe: PropTypes.func,
- }).isRequired,
+ context: PropTypes.shape({}).isRequired,
description: PropTypes.shape({
args: PropTypes.arrayOf(
PropTypes.shape({
@@ -96,7 +57,6 @@ Invocation.propTypes = {
}),
),
}).isRequired,
- Expression: PropTypes.func.isRequired,
onChange: PropTypes.func.isRequired,
op: PropTypes.shape({
args: PropTypes.arrayOf(PropTypes.any),
diff --git a/packages/entity/src/behavior-components/expression/key.jsx b/packages/entity/src/behavior-components/expression/key.jsx
index 9da4b9d..739025f 100644
--- a/packages/entity/src/behavior-components/expression/key.jsx
+++ b/packages/entity/src/behavior-components/expression/key.jsx
@@ -5,8 +5,8 @@ import {PropTypes, React} from '@latus/react';
const Key = ({
childrenDescription,
onChange,
- op,
path,
+ value,
}) => {
const options = Object.entries(childrenDescription)
.map(([key]) => (
@@ -18,7 +18,7 @@ const Key = ({
onChange={(event) => {
onChange(event, event.target.value, join(path, 'key'));
}}
- value={op.key}
+ value={value}
>
{options}
@@ -29,10 +29,8 @@ const Key = ({
Key.propTypes = {
childrenDescription: PropTypes.shape({}).isRequired,
onChange: PropTypes.func.isRequired,
- op: PropTypes.shape({
- key: PropTypes.string,
- }).isRequired,
path: PropTypes.string.isRequired,
+ value: PropTypes.string.isRequired,
};
export default Key;
diff --git a/packages/entity/src/behavior-components/expressions.jsx b/packages/entity/src/behavior-components/expressions.jsx
index 4030561..4bdf955 100644
--- a/packages/entity/src/behavior-components/expressions.jsx
+++ b/packages/entity/src/behavior-components/expressions.jsx
@@ -6,7 +6,7 @@ import Expression from './expression';
const Expressions = ({
context,
- expressions: {expressions},
+ value: {expressions},
path,
}) => (
@@ -14,7 +14,7 @@ const Expressions = ({
expressions.map((expression, i) => (
{
- const valueComponent = (path, type, value) => {
+ // eslint-disable-next-line react/destructuring-assignment
+ const contextDescription = context.describe();
+ const patch = useJsonPatcher();
+ const valueComponent = (path, type, {value}) => {
switch (type) {
case 'number':
return (
@@ -19,7 +31,7 @@ const Literal = ({
onChange={(event, value) => {
onChange(event, value, path);
}}
- value={value}
+ value={null === value ? 0 : value}
/>
);
case 'string':
@@ -29,7 +41,7 @@ const Literal = ({
onChange={(event) => {
onChange(event, value, path);
}}
- value={value || ''}
+ value={null === value ? '' : value}
/>
);
case 'object':
@@ -38,7 +50,7 @@ const Literal = ({
onChange={(event, value) => {
onChange(event, value, path);
}}
- json={value}
+ json={null === value ? {} : value}
/>
);
default:
@@ -46,32 +58,58 @@ const Literal = ({
}
};
return (
-
- {
- options.length > 0
- ? (
-
- )
- : valueComponent(path, type, value)
- }
-
+ <>
+ ': {
+ label: '',
+ type: value.type,
+ },
+ ...contextDescription.children,
+ }}
+ onChange={(event, value) => {
+ patch({
+ op: 'replace',
+ path,
+ value: {
+ type: 'expression',
+ ops: [
+ {
+ type: 'key',
+ key: value,
+ },
+ ],
+ },
+ });
+ }}
+ op={op}
+ path={path}
+ />
+
+ {
+ options.length > 0
+ ? (
+
+ )
+ : valueComponent(join(path, 'value'), type, value)
+ }
+
+ >
);
};
@@ -80,8 +118,14 @@ Literal.defaultProps = {
};
Literal.propTypes = {
+ context: PropTypes.shape({
+ describe: PropTypes.func,
+ }).isRequired,
type: PropTypes.string.isRequired,
onChange: PropTypes.func.isRequired,
+ op: PropTypes.shape({
+ key: PropTypes.string,
+ }).isRequired,
options: PropTypes.arrayOf(PropTypes.any),
path: PropTypes.string.isRequired,
// eslint-disable-next-line react/forbid-prop-types
diff --git a/packages/entity/src/behavior-components/variant.jsx b/packages/entity/src/behavior-components/variant.jsx
new file mode 100644
index 0000000..40961d1
--- /dev/null
+++ b/packages/entity/src/behavior-components/variant.jsx
@@ -0,0 +1,30 @@
+import {
+ PropTypes,
+ React,
+ useLatus,
+} from '@latus/react';
+
+const Variant = (props) => {
+ const {value} = props;
+ const {type} = value;
+ const latus = useLatus();
+ const BehaviorControllers = latus.get('%behavior-controllers');
+ const Controller = BehaviorControllers[type];
+ return (
+
+ );
+};
+
+Variant.propTypes = {
+ onChange: PropTypes.func.isRequired,
+ path: PropTypes.string.isRequired,
+ value: PropTypes.shape({
+ type: PropTypes.string,
+ }).isRequired,
+};
+
+export default Variant;
diff --git a/packages/entity/src/index.js b/packages/entity/src/index.js
index d5a1f41..b4f1153 100644
--- a/packages/entity/src/index.js
+++ b/packages/entity/src/index.js
@@ -2,6 +2,9 @@ import {basename, extname} from 'path';
import {camelCase} from '@latus/core';
+import Expression from './behavior-components/expression';
+import Expressions from './behavior-components/expressions';
+import Literal from './behavior-components/literal';
import EntityResourceController from './resource-controllers/entity';
export {EntityResourceController};
@@ -11,6 +14,11 @@ export default {
'@latus/core/starting': async (latus) => {
const TraitRenderers = latus.invokeReduce('@persea/entity/trait-components');
latus.set('%trait-components', TraitRenderers);
+ latus.set('%behavior-controllers', {
+ expression: Expression,
+ expressions: Expressions,
+ literal: Literal,
+ });
},
'@persea/core/resource-controllers': () => [
EntityResourceController,
diff --git a/packages/entity/src/trait-components/alive.jsx b/packages/entity/src/trait-components/alive.jsx
index 7a18aaf..0937e05 100644
--- a/packages/entity/src/trait-components/alive.jsx
+++ b/packages/entity/src/trait-components/alive.jsx
@@ -14,7 +14,7 @@ const Alive = ({
Death actions