Move header into Mainframe and controls to header
This commit is contained in:
parent
0befc7369a
commit
2db1e77a83
@ -2,7 +2,6 @@ import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import { Mainframe } from "../../ui/Mainframe";
|
||||
import { Header } from "../../ui/header";
|
||||
import LangProvider from "../../languages/befunge93";
|
||||
const LANG_ID = "befunge93";
|
||||
const LANG_NAME = "Befunge-93";
|
||||
@ -13,12 +12,11 @@ const IDE: NextPage = () => {
|
||||
<Head>
|
||||
<title>{LANG_NAME} | Esolang Park</title>
|
||||
</Head>
|
||||
<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
|
||||
<Header langId={LANG_ID} langName={LANG_NAME} />
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
<Mainframe langName={LANG_ID} provider={LangProvider} />
|
||||
</div>
|
||||
</div>
|
||||
<Mainframe
|
||||
langId={LANG_ID}
|
||||
langName={LANG_NAME}
|
||||
provider={LangProvider}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -2,7 +2,6 @@ import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import { Mainframe } from "../../ui/Mainframe";
|
||||
import { Header } from "../../ui/header";
|
||||
import LangProvider from "../../languages/brainfuck";
|
||||
const LANG_ID = "brainfuck";
|
||||
const LANG_NAME = "Brainfuck";
|
||||
@ -13,12 +12,11 @@ const IDE: NextPage = () => {
|
||||
<Head>
|
||||
<title>{LANG_NAME} | Esolang Park</title>
|
||||
</Head>
|
||||
<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
|
||||
<Header langId={LANG_ID} langName={LANG_NAME} />
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
<Mainframe langName={LANG_ID} provider={LangProvider} />
|
||||
</div>
|
||||
</div>
|
||||
<Mainframe
|
||||
langId={LANG_ID}
|
||||
langName={LANG_NAME}
|
||||
provider={LangProvider}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -2,7 +2,6 @@ import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import { Mainframe } from "../../ui/Mainframe";
|
||||
import { Header } from "../../ui/header";
|
||||
import LangProvider from "../../languages/chef";
|
||||
const LANG_ID = "chef";
|
||||
const LANG_NAME = "Chef";
|
||||
@ -13,12 +12,11 @@ const IDE: NextPage = () => {
|
||||
<Head>
|
||||
<title>{LANG_NAME} | Esolang Park</title>
|
||||
</Head>
|
||||
<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
|
||||
<Header langId={LANG_ID} langName={LANG_NAME} />
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
<Mainframe langName={LANG_ID} provider={LangProvider} />
|
||||
</div>
|
||||
</div>
|
||||
<Mainframe
|
||||
langId={LANG_ID}
|
||||
langName={LANG_NAME}
|
||||
provider={LangProvider}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -2,7 +2,6 @@ import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import { Mainframe } from "../../ui/Mainframe";
|
||||
import { Header } from "../../ui/header";
|
||||
import LangProvider from "../../languages/deadfish";
|
||||
const LANG_ID = "deadfish";
|
||||
const LANG_NAME = "Deadfish";
|
||||
@ -13,12 +12,11 @@ const IDE: NextPage = () => {
|
||||
<Head>
|
||||
<title>{LANG_NAME} | Esolang Park</title>
|
||||
</Head>
|
||||
<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
|
||||
<Header langId={LANG_ID} langName={LANG_NAME} />
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
<Mainframe langName={LANG_ID} provider={LangProvider} />
|
||||
</div>
|
||||
</div>
|
||||
<Mainframe
|
||||
langId={LANG_ID}
|
||||
langName={LANG_NAME}
|
||||
provider={LangProvider}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -3,7 +3,6 @@ import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import { Mainframe } from "../../ui/Mainframe";
|
||||
import { Header } from "../../ui/header";
|
||||
import LangProvider from "../../languages/rockstar";
|
||||
const LANG_ID = "$LANG_ID";
|
||||
const LANG_NAME = "Rockstar";
|
||||
@ -14,12 +13,11 @@ const IDE: NextPage = () => {
|
||||
<Head>
|
||||
<title>{LANG_NAME} | Esolang Park</title>
|
||||
</Head>
|
||||
<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
|
||||
<Header langId={LANG_ID} langName={LANG_NAME} />
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
<Mainframe langName={LANG_ID} provider={LangProvider} />
|
||||
</div>
|
||||
</div>
|
||||
<Mainframe
|
||||
langId={LANG_ID}
|
||||
langName={LANG_NAME}
|
||||
provider={LangProvider}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -3,7 +3,6 @@ import React from "react";
|
||||
import { NextPage } from "next";
|
||||
import Head from "next/head";
|
||||
import { Mainframe } from "../../ui/Mainframe";
|
||||
import { Header } from "../../ui/header";
|
||||
import LangProvider from "../../languages/$LANG_ID";
|
||||
const LANG_ID = "$LANG_ID";
|
||||
const LANG_NAME = "$LANG_NAME";
|
||||
@ -14,12 +13,11 @@ const IDE: NextPage = () => {
|
||||
<Head>
|
||||
<title>{LANG_NAME} | Esolang Park</title>
|
||||
</Head>
|
||||
<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
|
||||
<Header langId={LANG_ID} langName={LANG_NAME} />
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
<Mainframe langName={LANG_ID} provider={LangProvider} />
|
||||
</div>
|
||||
</div>
|
||||
<Mainframe
|
||||
langId={LANG_ID}
|
||||
langName={LANG_NAME}
|
||||
provider={LangProvider}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
import React from "react";
|
||||
import { Mosaic, MosaicNode, MosaicWindow } from "react-mosaic-component";
|
||||
import { Header } from "./header";
|
||||
import { useDarkMode } from "./providers/dark-mode-provider";
|
||||
|
||||
// IDs of windows in the mosaic layout
|
||||
@ -13,6 +14,8 @@ const WindowTitles = {
|
||||
};
|
||||
|
||||
type Props = {
|
||||
langId: string;
|
||||
langName: string;
|
||||
renderEditor: () => React.ReactNode;
|
||||
renderRenderer: () => React.ReactNode;
|
||||
renderInput: () => React.ReactNode;
|
||||
@ -46,20 +49,27 @@ export const MainLayout = (props: Props) => {
|
||||
};
|
||||
|
||||
return (
|
||||
<Mosaic<keyof typeof MOSAIC_MAP>
|
||||
className={mosaicClass}
|
||||
initialValue={INITIAL_LAYOUT}
|
||||
renderTile={(windowId, path) => (
|
||||
<MosaicWindow<number>
|
||||
path={path}
|
||||
title={WindowTitles[windowId]}
|
||||
toolbarControls={
|
||||
windowId === "editor" ? props.renderExecControls() : <span />
|
||||
}
|
||||
>
|
||||
{MOSAIC_MAP[windowId]()}
|
||||
</MosaicWindow>
|
||||
)}
|
||||
/>
|
||||
<div style={{ height: "100%", display: "flex", flexDirection: "column" }}>
|
||||
<Header
|
||||
langId={props.langId}
|
||||
langName={props.langName}
|
||||
renderExecControls={props.renderExecControls}
|
||||
/>
|
||||
<div style={{ flexGrow: 1 }}>
|
||||
<Mosaic<keyof typeof MOSAIC_MAP>
|
||||
className={mosaicClass}
|
||||
initialValue={INITIAL_LAYOUT}
|
||||
renderTile={(windowId, path) => (
|
||||
<MosaicWindow<number>
|
||||
path={path}
|
||||
title={WindowTitles[windowId]}
|
||||
toolbarControls={<span />}
|
||||
>
|
||||
{MOSAIC_MAP[windowId]()}
|
||||
</MosaicWindow>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -10,6 +10,7 @@ import { RendererRef, RendererWrapper } from "./renderer-wrapper";
|
||||
import { WorkerRuntimeError } from "../languages/worker-errors";
|
||||
|
||||
type Props<RS> = {
|
||||
langId: string;
|
||||
langName: string;
|
||||
provider: LanguageProvider<RS>;
|
||||
};
|
||||
@ -22,10 +23,10 @@ type Props<RS> = {
|
||||
* small execution intervals if rendered on every execution. All state management
|
||||
* is delegated to imperatively controlled child components.
|
||||
*/
|
||||
export const Mainframe = <RS extends {}>({ langName, provider }: Props<RS>) => {
|
||||
export const Mainframe = <RS extends {}>(props: Props<RS>) => {
|
||||
// Language provider and engine
|
||||
const providerRef = React.useRef(provider);
|
||||
const execController = useExecController(langName);
|
||||
const providerRef = React.useRef(props.provider);
|
||||
const execController = useExecController(props.langId);
|
||||
|
||||
// Refs for controlling UI components
|
||||
const codeEditorRef = React.useRef<CodeEditorRef>(null);
|
||||
@ -146,10 +147,12 @@ export const Mainframe = <RS extends {}>({ langName, provider }: Props<RS>) => {
|
||||
|
||||
return (
|
||||
<MainLayout
|
||||
langId={props.langId}
|
||||
langName={props.langName}
|
||||
renderEditor={() => (
|
||||
<CodeEditor
|
||||
ref={codeEditorRef}
|
||||
languageId={langName}
|
||||
languageId={props.langName}
|
||||
defaultValue={providerRef.current.sampleProgram}
|
||||
tokensProvider={providerRef.current.editorTokensProvider}
|
||||
onValidateCode={execController.validateCode}
|
||||
|
@ -15,10 +15,11 @@ const styles = {
|
||||
},
|
||||
inputWrapper: {
|
||||
/**
|
||||
* As of Dec'21, NumericInput doesn't have `small` prop yet,
|
||||
* so we instead use `transform` to hack up a smaller input.
|
||||
* As of Feb'22, NumericInput doesn't have `small` prop yet,
|
||||
* so we instead use `transform` to hack up a slightly smaller input.
|
||||
*/
|
||||
transform: "scale(0.8)",
|
||||
transform: "scale(0.9)",
|
||||
marginLeft: 10,
|
||||
},
|
||||
input: {
|
||||
width: 125,
|
||||
@ -44,6 +45,7 @@ const IntervalInput = (props: {
|
||||
clampValueOnBlur
|
||||
style={styles.input}
|
||||
disabled={props.disabled}
|
||||
title="Adjust the execution interval"
|
||||
onValueChange={(v) => props.onChange(v)}
|
||||
rightElement={<Tag minimal>ms</Tag>}
|
||||
allowNumericCharactersOnly
|
||||
@ -55,9 +57,11 @@ const IntervalInput = (props: {
|
||||
/** Button for starting code execution */
|
||||
const RunButton = ({ onClick }: { onClick: () => void }) => (
|
||||
<Button
|
||||
small
|
||||
outlined
|
||||
intent="success"
|
||||
onClick={onClick}
|
||||
rightIcon={<Icon icon="play" intent="success" />}
|
||||
title="Run your code"
|
||||
>
|
||||
Run code
|
||||
</Button>
|
||||
@ -78,21 +82,24 @@ const DebugControls = (props: {
|
||||
return (
|
||||
<ButtonGroup>
|
||||
<Button
|
||||
small
|
||||
title={paused ? "Pause" : "Resume"}
|
||||
outlined
|
||||
intent="primary"
|
||||
title={paused ? "Resume" : "Pause"}
|
||||
disabled={pauseDisabled}
|
||||
onClick={paused ? props.onResume : props.onPause}
|
||||
icon={<Icon icon={paused ? "play" : "pause"} intent="primary" />}
|
||||
/>
|
||||
<Button
|
||||
small
|
||||
outlined
|
||||
intent="warning"
|
||||
title="Step"
|
||||
onClick={props.onStep}
|
||||
disabled={stepDisabled}
|
||||
icon={<Icon icon="step-forward" intent="warning" />}
|
||||
/>
|
||||
<Button
|
||||
small
|
||||
outlined
|
||||
intent="danger"
|
||||
title="Stop"
|
||||
onClick={props.onStop}
|
||||
icon={<Icon icon="stop" intent="danger" />}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { Button, Card, Icon } from "@blueprintjs/core";
|
||||
import Image from "next/image";
|
||||
import logoImg from "./assets/logo.png";
|
||||
import { GitHubIcon } from "./custom-icons";
|
||||
import { useDarkMode } from "./providers/dark-mode-provider";
|
||||
import { Button, Card, Icon, Tag } from "@blueprintjs/core";
|
||||
|
||||
/** Link to the project's GitHub repository */
|
||||
const REPO_LINK = "https://github.com/nilaymaj/esolang-park";
|
||||
@ -11,22 +11,38 @@ const REPO_LINK = "https://github.com/nilaymaj/esolang-park";
|
||||
const NOTES_LINK = (id: string) =>
|
||||
`https://github.com/nilaymaj/esolang-park/blob/main/languages/${id}/README.md`;
|
||||
|
||||
export const Header = (props: { langId: string; langName: string }) => {
|
||||
type Props = {
|
||||
langId: string;
|
||||
langName: string;
|
||||
renderExecControls: () => React.ReactNode;
|
||||
};
|
||||
|
||||
export const Header = (props: Props) => {
|
||||
const DarkMode = useDarkMode();
|
||||
|
||||
const brandSection = (
|
||||
<div style={{ flex: 1, textAlign: "left" }}>
|
||||
<div
|
||||
style={{
|
||||
flex: 1,
|
||||
textAlign: "left",
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
}}
|
||||
>
|
||||
<Button minimal large>
|
||||
<div style={{ display: "flex", alignItems: "center" }}>
|
||||
<Image src={logoImg} alt="logo" width={20} height={20} />
|
||||
<span style={{ marginLeft: 10 }}>Esolang Park</span>
|
||||
</div>
|
||||
</Button>
|
||||
<Tag large minimal style={{ marginLeft: 10 }}>
|
||||
{props.langName}
|
||||
</Tag>
|
||||
</div>
|
||||
);
|
||||
|
||||
const langSection = (
|
||||
<div style={{ flex: 0, textAlign: "center" }}>{props.langName}</div>
|
||||
const controlsSection = (
|
||||
<div style={{ textAlign: "center" }}>{props.renderExecControls()}</div>
|
||||
);
|
||||
|
||||
const infoSection = (
|
||||
@ -60,7 +76,7 @@ export const Header = (props: { langId: string; langName: string }) => {
|
||||
}}
|
||||
>
|
||||
{brandSection}
|
||||
{langSection}
|
||||
{controlsSection}
|
||||
{infoSection}
|
||||
</Card>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user