implement nested handlers in call block
This commit is contained in:
parent
1f831b0517
commit
9afaa41fbb
2 changed files with 39 additions and 18 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
// import { useState } from 'react'
|
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import './App.css'
|
import './App.css'
|
||||||
import { Editor, initialEditorState, type EditorState } from './Editor'
|
import { Editor, initialEditorState, type EditorState } from './Editor'
|
||||||
|
|
@ -82,9 +81,9 @@ const tripleFunctionCallEditorState: EditorState = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function App() {
|
export function App() {
|
||||||
const [history, setHistory] = useState([initialEditorState]);
|
// const [history, setHistory] = useState([initialEditorState]);
|
||||||
// const [history, setHistory] = useState([nonEmptyEditorState]);
|
// const [history, setHistory] = useState([nonEmptyEditorState]);
|
||||||
// const [history, setHistory] = useState([tripleFunctionCallEditorState]);
|
const [history, setHistory] = useState([tripleFunctionCallEditorState]);
|
||||||
|
|
||||||
const [future, setFuture] = useState<EditorState[]>([]);
|
const [future, setFuture] = useState<EditorState[]>([]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import { apply, getType, getInst, assignFn, UnifyError } from "dope2";
|
import { useState } from "react";
|
||||||
import type { Dynamic, State2Props } from "./util/extra";
|
|
||||||
|
import { apply, UnifyError } from "dope2";
|
||||||
|
|
||||||
import { Editor, type EditorState } from "./Editor";
|
import { Editor, type EditorState } from "./Editor";
|
||||||
|
import { Value } from "./Value";
|
||||||
|
import type { Dynamic, State2Props } from "./util/extra";
|
||||||
|
|
||||||
import "./CallBlock.css";
|
import "./CallBlock.css";
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { Type } from "./Type";
|
|
||||||
import { Value } from "./Value";
|
|
||||||
import { focusPrevElement } from "./util/dom_trickery";
|
|
||||||
|
|
||||||
export interface CallBlockState<
|
export interface CallBlockState<
|
||||||
FnState=EditorState,
|
FnState=EditorState,
|
||||||
|
|
@ -110,11 +110,17 @@ export function CallBlock({ state, setState, onResolve }: CallBlockProps) {
|
||||||
const {unifyError, setFn, setInput, onFnResolve, onInputResolve, onFnCancel, onInputCancel}
|
const {unifyError, setFn, setInput, onFnResolve, onInputResolve, onFnCancel, onInputCancel}
|
||||||
= headlessCallBlock({ state, setState, onResolve });
|
= headlessCallBlock({ state, setState, onResolve });
|
||||||
return <span className={"functionBlock" + (unifyError ? " unifyError" : "")}>
|
return <span className={"functionBlock" + (unifyError ? " unifyError" : "")}>
|
||||||
<FunctionHeader fn={state.fn}/>
|
<FunctionHeader
|
||||||
|
fn={state.fn}
|
||||||
|
setFn={setFn}
|
||||||
|
onFnResolve={onFnResolve} />
|
||||||
<div className="functionParams">
|
<div className="functionParams">
|
||||||
<div className="outputParam">
|
<div className="outputParam">
|
||||||
{/* Sequence of input parameters */}
|
{/* Sequence of input parameters */}
|
||||||
<InputParams fn={state.fn} input={state.input} setInput={setInput}
|
<InputParams
|
||||||
|
fn={state.fn} setFn={setFn}
|
||||||
|
input={state.input} setInput={setInput}
|
||||||
|
onFnResolve={onFnResolve}
|
||||||
onInputResolve={onInputResolve} onInputCancel={onInputCancel} />
|
onInputResolve={onInputResolve} onInputCancel={onInputCancel} />
|
||||||
|
|
||||||
{/* Output (or Error) */}
|
{/* Output (or Error) */}
|
||||||
|
|
@ -125,25 +131,39 @@ export function CallBlock({ state, setState, onResolve }: CallBlockProps) {
|
||||||
</span>;
|
</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
function FunctionHeader({ fn }) {
|
function FunctionHeader({ fn, setFn, onFnResolve }) {
|
||||||
if (fn.kind === "call") {
|
if (fn.kind === "call") {
|
||||||
// if the function we're calling is itself the result of a function call,
|
// if the function we're calling is itself the result of a function call,
|
||||||
// then we are anonymous, and so we don't draw a function name
|
// then we are anonymous, and so we don't draw a function name
|
||||||
|
|
||||||
// recurse:
|
// recurse:
|
||||||
return <FunctionHeader fn={fn.fn} />;
|
const {
|
||||||
|
onFnResolve : onFnFnResolve
|
||||||
|
} = headlessCallBlock({state: fn, setState: setFn, onResolve: onFnResolve});
|
||||||
|
|
||||||
|
return <FunctionHeader
|
||||||
|
fn={fn.fn}
|
||||||
|
setFn={fnFn => setFn({...fn, fn: fnFn})}
|
||||||
|
onFnResolve={onFnFnResolve} />;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// end of recursion - draw function name
|
// end of recursion - draw function name
|
||||||
return <div className="functionName">
|
return <div className="functionName">
|
||||||
𝑓𝑛
|
𝑓𝑛
|
||||||
<Editor state={fn} setState={() => {/*todo*/}}
|
<Editor
|
||||||
onResolve={() => {}} onCancel={() => {/*todo*/}}/>
|
state={fn}
|
||||||
|
setState={setFn}
|
||||||
|
onResolve={onFnResolve}
|
||||||
|
onCancel={() => {/*todo*/}}/>
|
||||||
</div>;
|
</div>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function InputParams({ fn, input, setInput, onInputResolve, onInputCancel }) {
|
function InputParams({ fn, setFn, input, setInput, onFnResolve, onInputResolve, onInputCancel }) {
|
||||||
|
const {
|
||||||
|
onInputResolve: onFnInputResolve,
|
||||||
|
onFnResolve : onFnFnResolve
|
||||||
|
} = headlessCallBlock({state: fn, setState: setFn, onResolve: onFnResolve});
|
||||||
return <div className="inputParam">
|
return <div className="inputParam">
|
||||||
{(fn.kind === "call") &&
|
{(fn.kind === "call") &&
|
||||||
// if the function we're calling is itself the result of a function call,
|
// if the function we're calling is itself the result of a function call,
|
||||||
|
|
@ -152,9 +172,11 @@ function InputParams({ fn, input, setInput, onInputResolve, onInputCancel }) {
|
||||||
// Input(s) of the function we're calling:
|
// Input(s) of the function we're calling:
|
||||||
<InputParams
|
<InputParams
|
||||||
fn={fn.fn}
|
fn={fn.fn}
|
||||||
|
setFn={fnFn => setFn({...fn, fn: fnFn})}
|
||||||
input={fn.input}
|
input={fn.input}
|
||||||
setInput={() => {/*todo*/}}
|
setInput={fnInput => setFn({...fn, input: fnInput})}
|
||||||
onInputResolve={() => {/*todo*/}}
|
onFnResolve={onFnFnResolve}
|
||||||
|
onInputResolve={onFnInputResolve}
|
||||||
onInputCancel={() => {/*todo*/}}/>
|
onInputCancel={() => {/*todo*/}}/>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue