resizable panels

pull/43/head
Alexander Bentkamp 3 years ago
parent 2774fab98c
commit e2ea6fa85e

@ -83,3 +83,11 @@ code {
.app-content { .app-content {
flex: 1; flex: 1;
} }
.markdown li ul, .markdown li ol {
margin:0 1.5em;
}
.markdown ul, .markdown ol {
margin:0 1.5em 1.5em 1.5em;
}

@ -41,64 +41,7 @@ import Divider from '@mui/material/Divider';
import Markdown from './Markdown'; import Markdown from './Markdown';
import { SetTitleContext } from '../App'; import { SetTitleContext } from '../App';
import Split from 'react-split'
/** Drawer Test */
const drawerWidth = 400; /* TODO: This width is hard-coded. Fix me. */
const openedMixin = (theme: Theme): CSSObject => ({
width: drawerWidth,
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.enteringScreen,
}),
overflowX: 'hidden',
});
const closedMixin = (theme: Theme): CSSObject => ({
transition: theme.transitions.create('width', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
overflowX: 'hidden',
width: `calc(${theme.spacing(7)} + 1px)`,
[theme.breakpoints.up('sm')]: {
width: `calc(${theme.spacing(8)} + 1px)`,
},
});
const DrawerHeader = styled('div')(({ theme }) => ({
display: 'flex',
alignItems: 'center',
justifyContent: 'flex-end',
padding: theme.spacing(0, 1),
// necessary for content to be below app bar
...theme.mixins.toolbar,
}));
interface AppBarProps extends MuiAppBarProps {
open?: boolean;
}
const Drawer = styled(MuiDrawer, { shouldForwardProp: (prop) => prop !== 'open' })(
({ theme, open }) => ({
width: drawerWidth,
flexShrink: 0,
whiteSpace: 'nowrap',
boxSizing: 'border-box',
...(open && {
...openedMixin(theme),
'& .MuiDrawer-paper': openedMixin(theme),
}),
...(!open && {
...closedMixin(theme),
'& .MuiDrawer-paper': closedMixin(theme),
}),
}),
);
/** End Drawer Test */
export const MonacoEditorContext = React.createContext<monaco.editor.IStandaloneCodeEditor>(null as any); export const MonacoEditorContext = React.createContext<monaco.editor.IStandaloneCodeEditor>(null as any);
@ -141,16 +84,6 @@ function Level() {
const {editor, infoProvider, editorConnection} = const {editor, infoProvider, editorConnection} =
useLevelEditor(worldId, levelId, codeviewRef, initialCode, onDidChangeContent) useLevelEditor(worldId, levelId, codeviewRef, initialCode, onDidChangeContent)
const {setTitle, setSubtitle} = React.useContext(SetTitleContext);
useEffect(() => {
if (level?.data?.title) {
setSubtitle(``)
} else {
setSubtitle(`Level ${levelId}`)
}
}, [levelId, level?.data?.title])
return <> return <>
<div style={level.isLoading ? null : {display: "none"}} className="app-content loading"><CircularProgress /></div> <div style={level.isLoading ? null : {display: "none"}} className="app-content loading"><CircularProgress /></div>
<div style={level.isLoading ? {display: "none"} : null} className="app-bar"> <div style={level.isLoading ? {display: "none"} : null} className="app-bar">
@ -173,18 +106,8 @@ function Level() {
</div> </div>
</div> </div>
<div style={level.isLoading ? {display: "none"} : null} className="app-content level"> <Split minSize={200} className={`app-content level ${level.isLoading ? 'hidden' : ''}}`}>
<Drawer variant="permanent" open={showSidePanel} className="doc-panel"> <div className="main-panel">
<DrawerHeader>
</DrawerHeader>
<Divider />
<IconButton onClick={toggleSidePanel}>
<FontAwesomeIcon icon={showSidePanel ? faChevronLeft : faChevronRight}></FontAwesomeIcon>
</IconButton>
<LeftPanel spells={level?.data?.tactics} inventory={level?.data?.lemmas} showSidePanel={showSidePanel} setShowSidePanel={setShowSidePanel} />
</Drawer>
<Grid container columnSpacing={{ xs: 1, sm: 2, md: 3 }} sx={{ flexGrow: 1, p: 3 }} className="main-grid">
<Grid xs={8} className="main-panel">
<div ref={introductionPanelRef} className="introduction-panel"> <div ref={introductionPanelRef} className="introduction-panel">
<Markdown>{level?.data?.introduction}</Markdown> <Markdown>{level?.data?.introduction}</Markdown>
</div> </div>
@ -194,16 +117,19 @@ function Level() {
<div className="statement"><code>{level?.data?.descrFormat}</code></div> <div className="statement"><code>{level?.data?.descrFormat}</code></div>
<div ref={codeviewRef} className="codeview"></div> <div ref={codeviewRef} className="codeview"></div>
</div> </div>
</Grid> </div>
<Grid xs={4} className="info-panel"> <div className="info-panel">
<EditorContext.Provider value={editorConnection}> <EditorContext.Provider value={editorConnection}>
<MonacoEditorContext.Provider value={editor}> <MonacoEditorContext.Provider value={editor}>
{editorConnection && <Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} />} {editorConnection && <Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} />}
</MonacoEditorContext.Provider> </MonacoEditorContext.Provider>
</EditorContext.Provider> </EditorContext.Provider>
</Grid>
</Grid>
</div> </div>
<div className="doc-panel">
<LeftPanel spells={level?.data?.tactics} inventory={level?.data?.lemmas}
showSidePanel={showSidePanel} setShowSidePanel={setShowSidePanel} />
</div>
</Split>
</> </>
} }

@ -12,7 +12,7 @@ function Markdown(props) {
rehypePlugins: [...props.remarkPlugins ?? [], rehypeKatex], rehypePlugins: [...props.remarkPlugins ?? [], rehypeKatex],
}; };
return ( return (
<ReactMarkdown {...newProps} /> <ReactMarkdown {...newProps} className="markdown" />
); );
} }

@ -5,6 +5,25 @@
display: flex; display: flex;
} }
.hidden {
display: none;
}
.gutter {
background-color: #eee;
background-repeat: no-repeat;
background-position: 50%;
}
.gutter.gutter-vertical {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB4AAAAFAQMAAABo7865AAAABlBMVEVHcEzMzMzyAv2sAAAAAXRSTlMAQObYZgAAABBJREFUeF5jOAMEEAIEEFwAn3kMwcB6I2AAAAAASUVORK5CYII=');
}
.gutter.gutter-horizontal {
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAeCAYAAADkftS9AAAAIklEQVQoU2M4c+bMfxAGAgYYmwGrIIiDjrELjpo5aiZeMwF+yNnOs5KSvgAAAABJRU5ErkJggg==');
}
.main-panel, .info-panel { .main-panel, .info-panel {
height: 100%; height: 100%;
overflow: auto; overflow: auto;
@ -16,7 +35,11 @@
} }
.introduction-panel { .introduction-panel {
width: 100%; padding: 1em;
}
.exercise {
padding: 1em;
} }
.exercise { .exercise {

1
package-lock.json generated

@ -29,6 +29,7 @@
"react-markdown": "^8.0.4", "react-markdown": "^8.0.4",
"react-redux": "^8.0.5", "react-redux": "^8.0.5",
"react-router-dom": "^6.5.0", "react-router-dom": "^6.5.0",
"react-split": "^2.0.14",
"rehype-katex": "^6.0.2", "rehype-katex": "^6.0.2",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"remark-math": "^5.1.1", "remark-math": "^5.1.1",

@ -8,7 +8,6 @@
"@emotion/styled": "^11.10.5", "@emotion/styled": "^11.10.5",
"@fontsource/roboto": "^4.5.8", "@fontsource/roboto": "^4.5.8",
"@fontsource/roboto-mono": "^4.5.8", "@fontsource/roboto-mono": "^4.5.8",
"lean4-infoview": "https://gitpkg.now.sh/leanprover/vscode-lean4/lean4-infoview?master",
"@mui/icons-material": "^5.11.0", "@mui/icons-material": "^5.11.0",
"@mui/material": "^5.11.1", "@mui/material": "^5.11.1",
"@reduxjs/toolkit": "^1.9.1", "@reduxjs/toolkit": "^1.9.1",
@ -18,6 +17,7 @@
"cytoscape-klay": "^3.1.4", "cytoscape-klay": "^3.1.4",
"debounce": "^1.2.1", "debounce": "^1.2.1",
"express": "^4.18.2", "express": "^4.18.2",
"lean4-infoview": "https://gitpkg.now.sh/leanprover/vscode-lean4/lean4-infoview?master",
"lean4web": "github:hhu-adam/lean4web", "lean4web": "github:hhu-adam/lean4web",
"path-browserify": "^1.0.1", "path-browserify": "^1.0.1",
"react": "^18.2.0", "react": "^18.2.0",
@ -25,6 +25,7 @@
"react-markdown": "^8.0.4", "react-markdown": "^8.0.4",
"react-redux": "^8.0.5", "react-redux": "^8.0.5",
"react-router-dom": "^6.5.0", "react-router-dom": "^6.5.0",
"react-split": "^2.0.14",
"rehype-katex": "^6.0.2", "rehype-katex": "^6.0.2",
"remark-gfm": "^3.0.1", "remark-gfm": "^3.0.1",
"remark-math": "^5.1.1", "remark-math": "^5.1.1",

Loading…
Cancel
Save