Let ... in ... block is working
This commit is contained in:
parent
f09261df93
commit
897824e07d
10 changed files with 28 additions and 24 deletions
|
|
@ -24,6 +24,7 @@ nav {
|
||||||
|
|
||||||
main {
|
main {
|
||||||
grid-area: content;
|
grid-area: content;
|
||||||
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
aside {
|
aside {
|
||||||
|
|
|
||||||
|
|
@ -52,9 +52,9 @@ export function App() {
|
||||||
|
|
||||||
const commands = [
|
const commands = [
|
||||||
["call" , "[c] call" ],
|
["call" , "[c] call" ],
|
||||||
["eval" , "[u] [Tab] [Enter] eval"],
|
["eval" , "[e] [Tab] [Enter] eval"],
|
||||||
["transform", "[t] [.] transform" ],
|
["transform", "[t] [.] transform" ],
|
||||||
["let" , "[=] let ... in ..." ],
|
["let" , "[l] [=] let ... in ..." ],
|
||||||
];
|
];
|
||||||
|
|
||||||
const [highlighted, setHighlighted] = useState(
|
const [highlighted, setHighlighted] = useState(
|
||||||
|
|
|
||||||
|
|
@ -5,20 +5,11 @@
|
||||||
color: black;
|
color: black;
|
||||||
}
|
}
|
||||||
|
|
||||||
.functionBlock.unifyError {
|
|
||||||
/* background-color: pink; */
|
|
||||||
/* color:white; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.functionName {
|
.functionName {
|
||||||
/* text-align: center; */
|
/* text-align: center; */
|
||||||
background-color: white;
|
background-color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.functionBlock.unifyError .functionName {
|
|
||||||
/* background-color: pink; */
|
|
||||||
}
|
|
||||||
|
|
||||||
.inputParam:after {
|
.inputParam:after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ function FunctionHeader({ fn, setFn, input, onFnResolve }) {
|
||||||
|
|
||||||
// end of recursion - draw function name
|
// end of recursion - draw function name
|
||||||
return <div className="functionName">
|
return <div className="functionName">
|
||||||
𝑓𝑛
|
𝑓𝑛
|
||||||
<Editor
|
<Editor
|
||||||
state={fn}
|
state={fn}
|
||||||
setState={setFn}
|
setState={setFn}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ interface EditorProps extends State2Props<EditorState> {
|
||||||
}
|
}
|
||||||
|
|
||||||
function getCommands(type) {
|
function getCommands(type) {
|
||||||
const commands = ['u', 't', 'Enter', 'Backspace', 'ArrowLeft', 'ArrowRight', 'Tab', 'l', '=', '.'];
|
const commands = ['e', 't', 'Enter', 'Backspace', 'ArrowLeft', 'ArrowRight', 'Tab', 'l', '=', '.'];
|
||||||
if (getSymbol(type) === symbolFunction) {
|
if (getSymbol(type) === symbolFunction) {
|
||||||
commands.push('c');
|
commands.push('c');
|
||||||
}
|
}
|
||||||
|
|
@ -82,7 +82,7 @@ export function Editor({state, setState, onResolve, onCancel, filter}: EditorPro
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
setNeedCommand(false);
|
setNeedCommand(false);
|
||||||
// u -> pass Up
|
// u -> pass Up
|
||||||
if (e.key === "u" || e.key === "Enter" || e.key === "Tab" && !e.shiftKey) {
|
if (e.key === "e" || e.key === "Enter" || e.key === "Tab" && !e.shiftKey) {
|
||||||
onResolve(state);
|
onResolve(state);
|
||||||
globalContext?.doHighlight.eval();
|
globalContext?.doHighlight.eval();
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -154,7 +154,7 @@ export function InputBlock({ state, setState, filter, onResolve, onCancel }: Inp
|
||||||
}
|
}
|
||||||
{/* Input box */}
|
{/* Input box */}
|
||||||
<input ref={inputRef}
|
<input ref={inputRef}
|
||||||
placeholder="start typing..."
|
placeholder="<name or literal>"
|
||||||
className="editable"
|
className="editable"
|
||||||
value={text}
|
value={text}
|
||||||
onInput={onInput}
|
onInput={onInput}
|
||||||
|
|
|
||||||
6
src/LetInBlock.css
Normal file
6
src/LetInBlock.css
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
.keyword {
|
||||||
|
color: blue;
|
||||||
|
margin: 0 2px 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -5,6 +5,8 @@ import type { Dynamic, State2Props } from "./util/extra";
|
||||||
import { growEnv } from "dope2";
|
import { growEnv } from "dope2";
|
||||||
import { autoInputWidth } from "./util/dom_trickery";
|
import { autoInputWidth } from "./util/dom_trickery";
|
||||||
|
|
||||||
|
import "./LetInBlock.css";
|
||||||
|
|
||||||
export interface LetInBlockState {
|
export interface LetInBlockState {
|
||||||
kind: "let";
|
kind: "let";
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -23,6 +25,9 @@ export function LetInBlock({state, setState, onResolve}: LetInBlockProps) {
|
||||||
const env = useContext(EnvContext);
|
const env = useContext(EnvContext);
|
||||||
const nameRef = useRef<HTMLInputElement>(null);
|
const nameRef = useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
|
const setInner = inner => setState({...state, inner});
|
||||||
|
const setValue = value => setState({...state, value});
|
||||||
|
|
||||||
const onChangeName = (e: React.ChangeEvent<HTMLInputElement>) => {
|
const onChangeName = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
setState({...state, name: e.target.value});
|
setState({...state, name: e.target.value});
|
||||||
}
|
}
|
||||||
|
|
@ -37,27 +42,29 @@ export function LetInBlock({state, setState, onResolve}: LetInBlockProps) {
|
||||||
&& growEnv(env)(name)(value.resolved) || env;
|
&& growEnv(env)(name)(value.resolved) || env;
|
||||||
return <span className="letIn">
|
return <span className="letIn">
|
||||||
<div className="decl">
|
<div className="decl">
|
||||||
let <input
|
<span className="keyword">let</span>
|
||||||
|
<input
|
||||||
ref={nameRef}
|
ref={nameRef}
|
||||||
className='editable'
|
className='editable'
|
||||||
value={name}
|
value={name}
|
||||||
placeholder="<variable name>"
|
placeholder="<variable name>"
|
||||||
onChange={onChangeName}
|
onChange={onChangeName}
|
||||||
/> =
|
/>
|
||||||
|
<span className="keyword">=</span>
|
||||||
<Editor
|
<Editor
|
||||||
state={value}
|
state={value}
|
||||||
|
setState={setValue}
|
||||||
filter={() => true}
|
filter={() => true}
|
||||||
onResolve={(state: EditorState) => {} }
|
onResolve={() => {}}
|
||||||
onCancel={() => {}}
|
onCancel={() => {}}
|
||||||
setState={(state: EditorState) => {} }
|
|
||||||
/>
|
/>
|
||||||
in
|
<span className="keyword">in</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="inner">
|
<div className="inner">
|
||||||
<EnvContext value={innerEnv}>
|
<EnvContext value={innerEnv}>
|
||||||
<Editor
|
<Editor
|
||||||
state={inner}
|
state={inner}
|
||||||
setState={innerState => setState({...state, inner})}
|
setState={setInner}
|
||||||
filter={() => true}
|
filter={() => true}
|
||||||
onResolve={onResolve}
|
onResolve={onResolve}
|
||||||
onCancel={() => {}}
|
onCancel={() => {}}
|
||||||
|
|
|
||||||
|
|
@ -9,4 +9,3 @@ body {
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-variation-settings: "wdth" 100;
|
font-variation-settings: "wdth" 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,6 @@ export function focusPrevElement() {
|
||||||
|
|
||||||
export const autoInputWidth = (inputRef: React.RefObject<HTMLInputElement| null>, text) => {
|
export const autoInputWidth = (inputRef: React.RefObject<HTMLInputElement| null>, text) => {
|
||||||
if (inputRef.current) {
|
if (inputRef.current) {
|
||||||
inputRef.current.style.width = `${text.length === 0 ? 140 : (text.length*8.7)}px`;
|
inputRef.current.style.width = `${text.length === 0 ? 150 : (text.length*8.7)}px`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue