Skip to content

Commit

Permalink
Improve website layout (#69)
Browse files Browse the repository at this point in the history
* Adopt horizontal layout
* Display MemoryViz logo
* Change sample input and rendering options sections into dropdown menus
  • Loading branch information
yoonieaj authored Aug 19, 2024
1 parent a9f9d96 commit d971290
Show file tree
Hide file tree
Showing 20 changed files with 318 additions and 236 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ and adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

### 📚 Documentation and demo website changes

- Reformatted demo website to horizontal layout.

### 🔧 Internal changes

## [0.3.0] - 2024-08-02
Expand Down
3 changes: 3 additions & 0 deletions demo/jest.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ const config: Config = {
// Force module roughjs to resolve with the CJS entry point, because Jest does not support package.json.exports. Elaborated in PR#15.
roughjs: require.resolve("roughjs"),
"memory-viz": require.resolve("../memory-viz/src"),
// Mocks a file (see fileMock.js) each time any of the below file types are imported.
"\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga|css|less|sass|scss)$":
"./mocks/fileMock.js",
},

// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
Expand Down
70 changes: 36 additions & 34 deletions demo/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, { useState } from "react";
import { Box, Stack } from "@mui/material";
import SvgDisplay from "./SvgDisplay";
import MemoryModelsUserInput from "./MemoryModelsUserInput";
import { ErrorBoundary } from "react-error-boundary";
import DownloadSVGButton from "./DownloadSVGButton";
import { Alert } from "@mui/material";
import { configDataPropTypes } from "./MemoryModelsUserInput";
import MemoryModelsSample from "./MemoryModelsSample";
import Header from "./Header";

export default function App() {
const [textData, setTextData] = useState("");
Expand Down Expand Up @@ -33,45 +34,46 @@ export default function App() {
};

return (
<>
<main className="container">
<Header />
{failureBanner && (
<Alert severity="error" data-testid="json-parse-alert">
{failureBanner}
</Alert>
)}
<MemoryModelsSample
setTextData={setTextData}
setConfigData={setConfigData}
onTextDataSubmit={onTextDataSubmit}
/>
<MemoryModelsUserInput
textData={textData}
setTextData={setTextData}
configData={configData}
setConfigData={setConfigData}
onTextDataSubmit={onTextDataSubmit}
setFailureBanner={setFailureBanner}
jsonResult={jsonResult}
/>
<section>
<h2>Output</h2>
<DownloadSVGButton svgResult={svgResult} />
<ErrorBoundary
fallback={
<p data-testid="svg-display-error-boundary">
This is valid JSON but not valid Memory Models JSON.
Please refer to the repo for more details.
</p>
}
key={jsonResult}
>
<SvgDisplay
jsonResult={jsonResult}
<Stack direction="row" spacing={2}>
<Box sx={{ width: "40%" }}>
<h2>Input</h2>
<MemoryModelsUserInput
textData={textData}
setTextData={setTextData}
configData={configData}
setSvgResult={setSvgResult}
setConfigData={setConfigData}
onTextDataSubmit={onTextDataSubmit}
setFailureBanner={setFailureBanner}
jsonResult={jsonResult}
/>
</ErrorBoundary>
</section>
</>
</Box>
<Box sx={{ width: "60%" }}>
<h2>Output</h2>
<ErrorBoundary
fallback={
<p data-testid="svg-display-error-boundary">
This is valid JSON but not valid Memory Models
JSON. Please refer to the repo for more details.
</p>
}
key={jsonResult}
>
<SvgDisplay
jsonResult={jsonResult}
configData={configData}
setSvgResult={setSvgResult}
/>
</ErrorBoundary>
<DownloadSVGButton svgResult={svgResult} />
</Box>
</Stack>
</main>
);
}
7 changes: 3 additions & 4 deletions demo/src/DownloadJSONButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Button } from "@mui/material";

type DownloadJSONButtonPropTypes = {
jsonResult: string;
sx: object;
};
export default function DownloadJSONButton(props: DownloadJSONButtonPropTypes) {
const file = new Blob([JSON.stringify(props.jsonResult, null, 2)], {
Expand All @@ -12,17 +11,17 @@ export default function DownloadJSONButton(props: DownloadJSONButtonPropTypes) {

return (
<Button
variant="contained"
variant="text"
color="primary"
data-testid="download-json-btn"
disabled={!props.jsonResult}
download="memory_model.json"
target="_blank"
rel="noreferrer"
href={window.URL.createObjectURL(file)}
sx={{ ...props.sx, textTransform: "none" }}
sx={{ textTransform: "none" }}
>
Download This JSON
Download JSON
</Button>
);
}
4 changes: 2 additions & 2 deletions demo/src/DownloadSVGButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ export default function DownloadSVGButton(props: DownloadSVGButtonPropTypes) {

return (
<Button
variant="contained"
color="primary"
variant="text"
data-testid="download-svg-btn"
disabled={!props.svgResult}
href={URL.createObjectURL(file)}
Expand All @@ -19,7 +19,7 @@ export default function DownloadSVGButton(props: DownloadSVGButtonPropTypes) {
download="output.svg"
sx={{ textTransform: "none" }}
>
Download This SVG
Download SVG
</Button>
);
}
42 changes: 42 additions & 0 deletions demo/src/Header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import React from "react";
import { Box, Link, Stack, Typography } from "@mui/material";
import image from "../../assets/logo_square.png";

export default function Header() {
return (
<header className="container">
<Stack direction={"row"} justifyContent={"space-between"}>
<Box>
<h1 style={{ marginBottom: 0 }}>MemoryViz Demo</h1>
<Typography variant="subtitle1">
Demos of the{" "}
<Link
href="https://github.com/david-yz-liu/memory-viz"
target="_blank"
rel="noopener noreferrer"
>
MemoryViz
</Link>{" "}
Javascript library for visualizing Python memory. Click{" "}
<Link
href="https://www.cs.toronto.edu/~david/memory-viz/docs/api/"
target="_blank"
rel="noopener noreferrer"
>
here
</Link>{" "}
for documentation.
</Typography>
</Box>
<img
src={image}
alt="MemoryViz Logo"
style={{
width: "100px",
objectFit: "contain",
}}
/>
</Stack>
</header>
);
}
37 changes: 37 additions & 0 deletions demo/src/MemoryModelsMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React, { ReactNode, useState } from "react";
import { Box, Button, Menu } from "@mui/material";
import ExpandMoreRoundedIcon from "@mui/icons-material/ExpandMoreRounded";
import "./css/styles.css";

type MemoryModelsMenuPropTypes = {
menuName: string;
testId: string;
menuItems: ReactNode;
};

export default function MemoryModelsMenu(props: MemoryModelsMenuPropTypes) {
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null);
const open = Boolean(anchorEl);
const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
setAnchorEl(event.currentTarget);
};
const handleClose = () => {
setAnchorEl(null);
};

return (
<>
<Button
onClick={handleClick}
data-testid={props.testId}
className={`menu-button ${open ? "open" : ""}`}
>
{props.menuName}
<ExpandMoreRoundedIcon />
</Button>
<Menu anchorEl={anchorEl} open={open} onClose={handleClose}>
<Box>{props.menuItems}</Box>
</Menu>
</>
);
}
58 changes: 14 additions & 44 deletions demo/src/MemoryModelsSample.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
import React, { useEffect, useState } from "react";
import {
Accordion,
AccordionDetails,
AccordionSummary,
Button,
Card,
CardContent,
Grid,
} from "@mui/material";
import { ExpandMore } from "@mui/icons-material";
import { Box, MenuItem } from "@mui/material";
import MemoryModelsMenu from "./MemoryModelsMenu";

import { SAMPLES } from "./sample";

Expand Down Expand Up @@ -40,39 +32,17 @@ export default function MemoryModelsSample(props: MemoryModelsSamplePropTypes) {
};

return (
<Accordion>
<AccordionSummary
expandIcon={<ExpandMore />}
data-testid="sample-inputs-accordion"
>
Sample Inputs
</AccordionSummary>
<AccordionDetails>
<Card color="neutral">
<CardContent>
<Grid container spacing={2}>
{SAMPLES.map((sample, index) => (
<Grid item xs={12} sm={6} md={4} key={index}>
<Button
variant="contained"
onClick={() =>
handleButtonClick(index, sample)
}
color={
index === clickedBtnIndex
? "success"
: "primary"
}
sx={{ textTransform: "capitalize" }}
>
{sample["name"]}
</Button>
</Grid>
))}
</Grid>
</CardContent>
</Card>
</AccordionDetails>
</Accordion>
<MemoryModelsMenu
menuName="Sample Inputs"
testId="sample-inputs-menu"
menuItems={SAMPLES.map((sample, index) => (
<MenuItem
key={index}
onClick={() => handleButtonClick(index, sample)}
>
{sample["name"]}
</MenuItem>
))}
/>
);
}
Loading

0 comments on commit d971290

Please sign in to comment.