+ {steps.map((step, i) => {
+ switch (step.type) {
+ case 'key':
+ const tierOptions = Object.keys(stepsList.reduce((r, optionSteps) => {
+ if (!optionSteps[i] || !optionSteps[i].key) {
+ return r;
+ }
+ for (let j = 0; j < i; ++j) {
+ if (steps[j].key !== optionSteps[j].key) {
+ return r;
+ }
+ }
+ return {...r, [optionSteps[i].key]: true};
+ }, {}));
+ if (0 === i) {
+ const index = tierOptions.indexOf('context');
+ if (-1 !== index) {
+ tierOptions.splice(index, 1);
+ }
+ tierOptions.push('Literal');
+ }
+ return (
+
+
+
+ );
+ case 'invoke':
+ return (
+
+
(
+ {step.args.map((arg) => (
+
+
+
+ ))}
+
)
+
+ );
+ default:
+ return null;
+ }
+ })}
+ {
+ value && (
+
+ =
+
+
+ )
+ }
+
+ );
+};
+
+export default decorate(Steps);
diff --git a/src/client/components/types/steps.raw.scss b/src/client/components/types/steps.raw.scss
new file mode 100644
index 0000000..33e910a
--- /dev/null
+++ b/src/client/components/types/steps.raw.scss
@@ -0,0 +1,53 @@
+:scope {
+ display: flex;
+ flex-wrap: wrap;
+}
+
+.key + .key {
+ select {
+ border-left: none;
+ }
+}
+
+.args {
+ margin-left: 2em;
+}
+
+.arg {
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ display: flex;
+ margin-left: 2em;
+ padding: 0.5em;
+ &:not(:last-of-type) {
+ border-bottom: none;
+ }
+ &:nth-of-type(2n) {
+ background-color: rgba(0, 0, 0, 0.025);
+ }
+ &:nth-of-type(2n+1) {
+ background-color: rgba(255, 255, 255, 0.025);
+ }
+}
+
+.arg .steps {
+ display: flex;
+}
+
+.bracket, .paren {
+ color: #999999;
+}
+
+.invoke {
+ // border-left: 1px dotted rgba(255, 255, 255, 0.1);
+ padding-left: 1em;
+}
+
+.assign {
+ display: flex;
+ align-items: center;
+}
+
+.op {
+ align-self: flex-start;
+ margin: 0.5em 1em;
+}
diff --git a/src/client/components/types/typing.js b/src/client/components/types/typing.js
new file mode 100644
index 0000000..d44ebdd
--- /dev/null
+++ b/src/client/components/types/typing.js
@@ -0,0 +1,61 @@
+export function typeFromV(v) {
+ if ('undefined' === typeof v) {
+ return 'undefined';
+ }
+ if (null === v) {
+ return 'null';
+ }
+ if ('number' === typeof v) {
+ return 'number';
+ }
+ if ('string' === typeof v) {
+ return 'string';
+ }
+ if ('boolean' === typeof v) {
+ return 'bool';
+ }
+ if (v.length && 2 === v.length && v instanceof Array) {
+ return 'vector';
+ }
+ if (!v.contextDescription) {
+ return 'object';
+ }
+ const {type} = v.contextDescription();
+ return type;
+}
+
+export function typeFromSteps(context, steps) {
+ if (!steps || 0 === steps.length) {
+ return 'undefined';
+ }
+ const first = context.map.get(steps[0].key);
+ const [, type] = steps.slice(1).reduce(
+ ([v, type], step, i) => {
+ if (i === steps.length - 2) {
+ if (v.contextDescription) {
+ const {children} = v.contextDescription();
+ return [undefined, step.key ? children[step.key].type : type];
+ }
+ else {
+ return [undefined, type];
+ }
+ }
+ else {
+ if (step.key) {
+ const {children} = v.contextDescription();
+ return [v[step.key], children[step.key].type];
+ }
+ else {
+ return [v, type];
+ }
+ }
+ step
+ },
+ [first, typeFromV(first)],
+ );
+ return type;
+}
+
+export function typeFits(reference, candidate) {
+ return 'any' === reference || -1 !== (reference.split('|') || []).indexOf(candidate);
+}
diff --git a/src/client/components/types/value.raw.scss b/src/client/components/types/value.raw.scss
index e69de29..3dec98d 100644
--- a/src/client/components/types/value.raw.scss
+++ b/src/client/components/types/value.raw.scss
@@ -0,0 +1,22 @@
+.fn {
+ text-align-last: right;
+}
+
+:scope {
+ display: flex;
+ align-items: center;
+}
+
+.object {
+ background-color: #333333;
+ border: 1px solid rgba(255, 255, 255, 0.1);
+ padding: 0.25em;
+}
+
+.object, input {
+ // border-left: none;
+}
+
+select {
+ margin-right: 0.25em;
+}
diff --git a/src/client/components/types/value.type-renderer.jsx b/src/client/components/types/value.type-renderer.jsx
index db85dd3..b828974 100644
--- a/src/client/components/types/value.type-renderer.jsx
+++ b/src/client/components/types/value.type-renderer.jsx
@@ -4,77 +4,63 @@ import contempo from 'contempo';
import PropTypes from 'prop-types';
import React from 'react';
+import Bool from './bool.type-renderer';
import propertyPropTypes from './property-prop-types';
+import Steps from './steps';
+import {contextStepsList} from './steps-lists';
+import {typeFits, typeFromSteps, typeFromV} from './typing';
-const reduceStep = (r, step) => {
- switch (step.type) {
- case 'key':
- return `${r}.${step.key}`;
- case 'invoke':
- return (
-
-
{'{'}
-
-
- {' '}
- {JSON.stringify(value.value, null, 2).slice(1).slice(0, -1).trim('\n')}
-
-
-
{'}'}
+
+
+ {
+ (() => {
+ switch (type) {
+ case 'bool':
+ return
;
+ case 'number':
+ case 'string':
+ return
;
+ case 'object':
+ return (
+
+
{'{'}
+
+
+ {' '}
+ {JSON.stringify(value.value, null, 2).slice(1).slice(0, -1).trim('\n')}
+
+
+
{'}'}
+
+ );
+ default:
+ return null;
+ }
+ })()
+ }
);
default:
@@ -87,11 +73,13 @@ const decorate = compose(
);
const Value = ({
+ context,
name,
label,
options,
+ type,
value,
-}) => renderValue(value);
+}) => renderValue(context, type || 'any', value);
Value.propTypes = {
...propertyPropTypes,
diff --git a/src/client/index.scss b/src/client/index.scss
index eae2426..787ad04 100644
--- a/src/client/index.scss
+++ b/src/client/index.scss
@@ -72,7 +72,7 @@ code {
label {
align-items: left;
- background-color: #272727;
+ background-color: rgba(255, 255, 255, 0.025);
color: #ffffff;
display: flex;
flex-direction: column;
@@ -93,12 +93,16 @@ label {
}
label:nth-of-type(2n+1) {
- background-color: #1d1d1d
+ background-color: rgba(0, 0, 0, 0.025);
+}
+
+[contenteditable] {
+ cursor: text;
}
input {
background: #333;
- border: 1px solid black;
+ border: 1px solid rgba(255, 255, 255, 0.1);
color: #ffffff;
font-size: 0.75em;
padding: 0.5em;
@@ -106,7 +110,7 @@ input {
fieldset {
background-color: #151515;
- border: 1px solid #000000;
+ border: 1px solid rgba(255, 255, 255, 0.1);
display: inline-block;
margin: 0 0 1em 0;
padding: 0.5em;
@@ -121,16 +125,19 @@ button, input[type="checkbox"], input[type="checkbox"] + label {
select {
background: #222222;
- border: 1px solid #000000;
+ border: 1px solid rgba(255, 255, 255, 0.1);
color: #ffffff;
+ cursor: pointer;
font-size: 0.75em;
- line-height: 1em;
+ margin: 0.25em 0;
-moz-appearance: none;
-webkit-appearance: none;
padding: 0.5em;
}
*:focus {
+ position: relative;
box-shadow: 0 0 2px 0 #d68030ff;
outline: none;
+ z-index: 1;
}