diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/App.module.css | 19 | ||||
| -rw-r--r-- | src/App.tsx | 19 | ||||
| -rw-r--r-- | src/Editor.tsx | 61 | ||||
| -rw-r--r-- | src/Tutorial.tsx | 2 | ||||
| -rw-r--r-- | src/index.css | 4 |
5 files changed, 87 insertions, 18 deletions
diff --git a/src/App.module.css b/src/App.module.css index a051663..06f0da6 100644 --- a/src/App.module.css +++ b/src/App.module.css @@ -19,6 +19,11 @@ margin-bottom: -10px; } +.iconRow h1 { + font-size: var(--font-xxl); + margin: 0; +} + .iconRow img { width: auto; height: 40px; @@ -40,3 +45,17 @@ } .tutorial {} + +.author .githubLink, +.author p { + display: flex; + flex-flow: row nowrap; + align-items: center; + margin: 5px 0; +} + +.author svg { + height: 20px; + width: 20px; + margin-right: 10px; +}
\ No newline at end of file diff --git a/src/App.tsx b/src/App.tsx index 9e78af3..5d33a38 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3,13 +3,19 @@ import Editor from "./Editor" import Tutorial from "./Tutorial" import icon from "./favicon.png" +const GithubIcon = () => ( + <svg height="32" aria-hidden="true" viewBox="0 0 16 16" version="1.1" width="32" data-view-component="true" className="octicon octicon-mark-github"> + <path fill="#fff" fillRule="evenodd" d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path> + </svg> +) + const App = () => { return ( <div className={styles.app}> <header className={styles.header}> <div className={styles.iconRow}> <img src={icon} /> - <strong>SLAM</strong> + <h1>SLAM</h1> </div> <div className={styles.sloganRow}> <small>A Mere Stack Language</small> @@ -17,6 +23,17 @@ const App = () => { </header> <div className={styles.editor}><Editor /></div> <div className={styles.tutorial}><Tutorial /></div> + <div className={styles.author}> + <h3>Author</h3> + <p> + Jan Tuomi <<a href="mailto:jans.tuomi@gmail.com">jans.tuomi@gmail.com</a>> + </p> + + <a className={styles.githubLink} href="https://github.com/jantuomi"> + <GithubIcon /> + <div>Github</div> + </a> + </div> </div> ) } diff --git a/src/Editor.tsx b/src/Editor.tsx index 5548586..1d4b45a 100644 --- a/src/Editor.tsx +++ b/src/Editor.tsx @@ -1,7 +1,7 @@ import AceEditor from "react-ace" import "ace-builds/src-noconflict/mode-java" import "ace-builds/src-noconflict/theme-github" -import { useState } from "react" +import { useEffect, useState } from "react" import styles from "./Editor.module.css" import { SubmitResult, submitSource, useExamples } from "./api" import Select from "react-select" @@ -18,7 +18,11 @@ const Editor = () => { const examples = useExamples() const [sourceText, setSourceText] = useState(defaultSourceText) const [result, setResult] = useState<SubmitResult>({ type: "not_yet_requested" }) - const onChange = setSourceText + const [sourceDirty, setSourceDirty] = useState(false) + const onChange = (text: string) => { + setSourceText(text) + setSourceDirty(true) + } const executeCode = async (text: string) => { const result = await submitSource(text) @@ -29,7 +33,7 @@ const Editor = () => { switch (examples.type) { case "not_yet_requested": case "loading": - return <div>Loading examples...</div> + return <div id="examples-loading">Loading examples...</div> case "failed": return <div className={styles.error}> An unexpected error occurred while loading examples. See console for details. @@ -51,9 +55,19 @@ const Editor = () => { } return ( <Select + id="example-select" placeholder="Pick an example code snippet..." options={options} - onChange={(val) => { setSourceText(val?.value as string) }} + onChange={(val) => { + let ok = true + if (sourceDirty) { + ok = window.confirm("Loading an example will discard your changes. Proceed?") + } + if (ok) { + setSourceText(val?.value as string) + setSourceDirty(false) + } + }} styles={customStyles} /> ) @@ -93,25 +107,40 @@ const Editor = () => { } } + const resetSourceEditor = () => { + setSourceText("") + } + + // reset source editor content, used in e2e tests + useEffect(() => { + window.addEventListener("resetSourceEditor", resetSourceEditor) + + return () => { + window.removeEventListener("resetSourceEditor", resetSourceEditor) + } + }, []) + return ( <> <div className={styles.examples}> {renderExamples()} </div> - <AceEditor - mode="" - theme="github" - onChange={onChange} - value={sourceText} - name="editor" - editorProps={{ $blockScrolling: true }} - width="100%" - fontSize={16} - /> - <button className={styles.runButton} onClick={() => executeCode(sourceText)}> + <div id="source-editor"> + <AceEditor + mode="" + theme="github" + onChange={onChange} + value={sourceText} + name="editor" + editorProps={{ $blockScrolling: true }} + width="100%" + fontSize={16} + /> + </div> + <button id="run-button" className={styles.runButton} onClick={() => executeCode(sourceText)}> ▶️ Run code on server </button> - <div className={styles.results}> + <div id="results-editor" className={styles.results}> {renderResults()} </div> </> diff --git a/src/Tutorial.tsx b/src/Tutorial.tsx index 0fcdb12..a511ec3 100644 --- a/src/Tutorial.tsx +++ b/src/Tutorial.tsx @@ -22,7 +22,7 @@ const Tutorial = () => ( <p> <i>Phrases</i>, roughly equal to Lisp's quoted S-expressions, are a sequence of words that are not immediately evaluated when encountered, but instead put on - the stack for later manipulation. Phrases can be used to implement strings or homogenous + the stack for later manipulation. Phrases can be used to implement strings or heterogenous list structures. Phrases are also the core of conditional expressions, where branches of code are only evaluated when a condition is met. </p> diff --git a/src/index.css b/src/index.css index 6f181ab..86f5d57 100644 --- a/src/index.css +++ b/src/index.css @@ -43,4 +43,8 @@ button { button:hover { text-decoration: underline; +} + +a { + color: var(--white); }
\ No newline at end of file |
