refactor: literal handles its typing

This commit is contained in:
cha0s 2021-01-31 14:12:48 -06:00
parent 67a6caa62d
commit fc25cbe3f5
3 changed files with 169 additions and 130 deletions

View File

@ -3,9 +3,6 @@ import {join} from 'path';
import { import {
PropTypes, PropTypes,
React, React,
useEffect,
useRef,
useState,
} from '@latus/react'; } from '@latus/react';
import {useJsonPatcher} from '@persea/json'; import {useJsonPatcher} from '@persea/json';
@ -19,43 +16,11 @@ const Invocation = ({
op, op,
path, path,
}) => { }) => {
const literalTypeRef = useRef();
const [literalType, setLiteralType] = useState(false);
useEffect(() => {
literalTypeRef.current?.focus();
});
const patch = useJsonPatcher(); const patch = useJsonPatcher();
const argComponent = (arg, i) => { const argComponent = (arg, i) => {
const argPath = join(path, 'args', i.toString()); const argPath = join(path, 'args', i.toString());
if ('undefined' === arg.type) { if ('undefined' === arg.type) {
const confirmLiteralType = () => { return (
let value = null;
switch (literalType) {
case 'expressions':
value = {
type: 'expressions',
expressions: [],
};
break;
case 'number': value = 0; break;
case 'string': value = ''; break;
case 'array': value = []; break;
case 'object': value = {}; break;
case 'vector': value = [0, 0]; break;
default:
}
patch({
op: 'replace',
path: argPath,
value: {
type: 'literal',
value,
},
});
setLiteralType(false);
};
return false === literalType
? (
<Key <Key
childrenDescription={{ childrenDescription={{
'...': {label: '', type: 'undefined'}, '...': {label: '', type: 'undefined'},
@ -66,9 +31,15 @@ const Invocation = ({
key={path} key={path}
onChange={(event, value) => { onChange={(event, value) => {
if ('[literal]' === value) { if ('[literal]' === value) {
setLiteralType(''); patch({
type: 'add',
path: argPath,
value: {
type: 'literal',
},
});
return;
} }
else {
patch({ patch({
type: 'add', type: 'add',
path: argPath, path: argPath,
@ -82,27 +53,10 @@ const Invocation = ({
}, },
}); });
onChange(false, value, join(argPath, 'ops/0/key')); onChange(false, value, join(argPath, 'ops/0/key'));
}
}} }}
path={argPath} path={argPath}
value="..." value="..."
/> />
)
: (
<input
type="text"
onBlur={confirmLiteralType}
onChange={({target: {value}}) => {
setLiteralType(value);
}}
onKeyPress={(event) => {
if ('Enter' === event.key) {
confirmLiteralType(event);
}
}}
ref={literalTypeRef}
value={literalType}
/>
); );
} }
const j = description.vararg ? Math.min(description?.args?.length - 1, i) : i; const j = description.vararg ? Math.min(description?.args?.length - 1, i) : i;

View File

@ -1,7 +1,13 @@
import {join} from 'path'; import {join} from 'path';
import {Context} from '@avocado/behavior'; import {Context} from '@avocado/behavior';
import {PropTypes, React} from '@latus/react'; import {
PropTypes,
React,
useEffect,
useRef,
useState,
} from '@latus/react';
import { import {
Number, Number,
Vector, Vector,
@ -23,9 +29,42 @@ const Literal = ({
value, value,
vararg, vararg,
}) => { }) => {
const literalTypeRef = useRef();
const patch = useJsonPatcher();
const [literalType, setLiteralType] = useState(false);
useEffect(() => {
literalTypeRef.current?.focus();
});
const confirmLiteralType = () => {
if (literalType) {
let value = null;
switch (literalType) {
case 'expressions':
value = {
type: 'expressions',
expressions: [],
};
break;
case 'number': value = 0; break;
case 'string': value = ''; break;
case 'array': value = []; break;
case 'object': value = {}; break;
case 'vector': value = [0, 0]; break;
default:
}
patch({
op: 'replace',
path,
value: {
type: 'literal',
value,
},
});
}
setLiteralType(false);
};
// eslint-disable-next-line react/destructuring-assignment // eslint-disable-next-line react/destructuring-assignment
const contextDescription = context.describe(); const contextDescription = context.describe();
const patch = useJsonPatcher();
const valueComponent = (path, type, {value}) => { const valueComponent = (path, type, {value}) => {
switch (type) { switch (type) {
case 'bool': { case 'bool': {
@ -97,14 +136,56 @@ const Literal = ({
case 'null': case 'null':
case 'array': case 'array':
return null; return null;
default: default: {
return 'undefined' !== typeof value const elements = [];
? valueComponent(path, Context.inferTypeOf(value), {value}) if ('undefined' === type || 'any' === type) {
: null; elements.push(
<select
key={join(path, 'equality')}
onChange={({target: {value}}) => {
if ('≟' === value) {
setLiteralType('');
}
}}
value={false === literalType ? '=' : '≟'}
>
<option>=</option>
<option></option>
</select>,
);
}
if ('undefined' !== typeof value) {
elements.push(
<div className="component" key={join(path, 'component')}>
{valueComponent(path, Context.inferTypeOf(value), {value})}
</div>,
);
}
return <>{elements}</>;
}
} }
}; };
return ( return (
<> <>
{
false !== literalType
? (
<input
type="text"
onBlur={confirmLiteralType}
onChange={({target: {value}}) => {
setLiteralType(value);
}}
onKeyPress={(event) => {
if ('Enter' === event.key) {
confirmLiteralType(event);
}
}}
ref={literalTypeRef}
value={literalType}
/>
)
: (
<Key <Key
childrenDescription={{ childrenDescription={{
...( ...(
@ -146,6 +227,8 @@ const Literal = ({
path={path} path={path}
value="[literal]" value="[literal]"
/> />
)
}
<div className="literal"> <div className="literal">
{ {
options.length > 0 options.length > 0

View File

@ -1,3 +1,5 @@
.literal { .literal {
align-items: center;
display: flex;
pointer-events: auto; pointer-events: auto;
} }