Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8faf636

Browse files
committed
Split out tree for better UX
1 parent 260aa43 commit 8faf636

File tree

5 files changed

+75
-73
lines changed

5 files changed

+75
-73
lines changed

.gitignore

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
/docs/index.js*
1+
# Ignore everything in the output docs directory controlled by the build system.
2+
/docs/
3+
!/docs/index.css
4+
!/docs/index.html
5+
6+
# Ignore everything to do with building the app.wasm file.
27
/head-wasm32-unknown-wasi-full-js/
38
/lib/
4-
/node_modules/
59
/ruby.wasm
610
/src/app.wasm
7-
/vendor/
811
/wasi-vfs
12+
13+
# Ignore all of the node dependencies and related files.
14+
/node_modules/
915
/yarn-error.log

src/Editor.tsx

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import React from "react";
2+
3+
type EditorProps = {
4+
cols: number,
5+
value: string,
6+
onChange: (value: string) => void
7+
};
8+
9+
const Editor: React.FC<EditorProps> = ({ cols, value, onChange }) => {
10+
const onSourceChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
11+
onChange(event.target.value);
12+
};
13+
14+
return <textarea cols={cols} value={value} onChange={onSourceChange} />;
15+
};
16+
17+
export default Editor;

src/Tree.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import React, { useEffect, useMemo, useState } from "react";
2+
3+
import createRuby, { Ruby } from "./createRuby";
4+
5+
function prettyPrint(ruby: Ruby, value: string) {
6+
try {
7+
return ruby.prettyPrint(value);
8+
} catch (error) {
9+
// For now, just ignoring the error. Eventually I'd like to make this mark
10+
// an error state on the editor to give feedback to the user.
11+
}
12+
}
13+
14+
type TreeProps = {
15+
cols: number,
16+
value: string
17+
};
18+
19+
const Tree: React.FC<TreeProps> = ({ cols, value }) => {
20+
const [ruby, setRuby] = useState<Ruby>(null);
21+
const [output, setOutput] = useState<string>("");
22+
23+
useEffect(() => {
24+
createRuby().then((ruby) => {
25+
setRuby(ruby);
26+
setOutput(prettyPrint(ruby, value));
27+
});
28+
}, []);
29+
30+
useMemo(() => {
31+
if (ruby) {
32+
setOutput(prettyPrint(ruby, value));
33+
}
34+
}, [ruby, value]);
35+
36+
return <textarea cols={cols} value={output} readOnly />;
37+
};
38+
39+
export default Tree;

src/index.tsx

Lines changed: 9 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,19 @@
1-
import React, { useEffect, useReducer } from "react";
1+
import React, { Suspense, useState } from "react";
22
import { createRoot } from "react-dom/client";
33

4-
import createRuby, { Ruby } from "./createRuby";
5-
6-
type State = {
7-
state: "initializing" | "ready" | "evaluating",
8-
source: string,
9-
output: string,
10-
ruby: null | Ruby
11-
};
12-
13-
const initialState: State = {
14-
state: "initializing",
15-
source: "1 + 2",
16-
output: "",
17-
ruby: null
18-
};
19-
20-
type Action = (
21-
| { type: "changeSource", source: string }
22-
| { type: "createRuby", ruby: Ruby, output: string }
23-
| { type: "evaluateSource", output: string }
24-
| { type: "syntaxErrorSource" }
25-
);
26-
27-
function reducer(state: State, action: Action): State {
28-
switch (action.type) {
29-
case "changeSource":
30-
return { ...state, state: "evaluating", source: action.source };
31-
case "createRuby":
32-
return { ...state, state: "ready", ruby: action.ruby, output: action.output };
33-
case "evaluateSource":
34-
return { ...state, state: "ready", output: action.output };
35-
case "syntaxErrorSource":
36-
return { ...state, state: "ready" };
37-
}
38-
}
4+
import Editor from "./Editor";
5+
const Tree = React.lazy(() => import("./Tree"));
396

407
const App: React.FC = () => {
41-
const [state, dispatch] = useReducer(reducer, initialState);
42-
43-
const onSourceChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
44-
dispatch({ type: "changeSource", source: event.target.value });
45-
};
46-
47-
useEffect(() => {
48-
switch (state.state) {
49-
case "initializing":
50-
createRuby().then((ruby) => {
51-
dispatch({ type: "createRuby", ruby, output: ruby.prettyPrint(state.source) });
52-
});
53-
return;
54-
case "evaluating":
55-
try {
56-
dispatch({ type: "evaluateSource", output: state.ruby.prettyPrint(state.source) });
57-
} catch (error) {
58-
dispatch({ type: "syntaxErrorSource" });
59-
}
60-
return;
61-
}
62-
}, [state.state]);
8+
const [source, setSource] = useState<string>("1 + 2");
9+
const cols = 80;
6310

6411
return (
6512
<>
66-
<textarea
67-
cols={80}
68-
value={state.source}
69-
onChange={onSourceChange}
70-
readOnly={state.state !== "ready"}
71-
/>
72-
<textarea
73-
cols={80}
74-
value={state.output}
75-
readOnly
76-
/>
13+
<Editor cols={cols} value={source} onChange={setSource} />
14+
<Suspense fallback={<textarea cols={cols} readOnly />}>
15+
<Tree cols={cols} value={source} />
16+
</Suspense>
7717
</>
7818
);
7919
};

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"allowSyntheticDefaultImports": true,
55
"downlevelIteration": true,
66
"jsx": "react",
7-
"module": "es6",
7+
"module": "es2020",
88
"moduleResolution": "node",
99
"noImplicitAny": true,
1010
"target": "es5"

0 commit comments

Comments
 (0)