resizable panels
This commit is contained in:
@@ -83,3 +83,11 @@ code {
|
||||
.app-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.markdown li ul, .markdown li ol {
|
||||
margin:0 1.5em;
|
||||
}
|
||||
|
||||
.markdown ul, .markdown ol {
|
||||
margin:0 1.5em 1.5em 1.5em;
|
||||
}
|
||||
|
||||
+26
-100
@@ -41,64 +41,7 @@ import Divider from '@mui/material/Divider';
|
||||
import Markdown from './Markdown';
|
||||
import { SetTitleContext } from '../App';
|
||||
|
||||
|
||||
|
||||
/** 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 */
|
||||
|
||||
import Split from 'react-split'
|
||||
|
||||
export const MonacoEditorContext = React.createContext<monaco.editor.IStandaloneCodeEditor>(null as any);
|
||||
|
||||
@@ -141,16 +84,6 @@ function Level() {
|
||||
const {editor, infoProvider, editorConnection} =
|
||||
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 <>
|
||||
<div style={level.isLoading ? null : {display: "none"}} className="app-content loading"><CircularProgress /></div>
|
||||
<div style={level.isLoading ? {display: "none"} : null} className="app-bar">
|
||||
@@ -173,38 +106,31 @@ function Level() {
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div style={level.isLoading ? {display: "none"} : null} className="app-content level">
|
||||
<Drawer variant="permanent" open={showSidePanel} className="doc-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">
|
||||
<Markdown>{level?.data?.introduction}</Markdown>
|
||||
</div>
|
||||
<div className="exercise">
|
||||
<h4>Aufgabe:</h4>
|
||||
<Markdown>{level?.data?.descrText}</Markdown>
|
||||
<div className="statement"><code>{level?.data?.descrFormat}</code></div>
|
||||
<div ref={codeviewRef} className="codeview"></div>
|
||||
</div>
|
||||
</Grid>
|
||||
<Grid xs={4} className="info-panel">
|
||||
<EditorContext.Provider value={editorConnection}>
|
||||
<MonacoEditorContext.Provider value={editor}>
|
||||
{editorConnection && <Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} />}
|
||||
</MonacoEditorContext.Provider>
|
||||
</EditorContext.Provider>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</div>
|
||||
</>
|
||||
<Split minSize={200} className={`app-content level ${level.isLoading ? 'hidden' : ''}}`}>
|
||||
<div className="main-panel">
|
||||
<div ref={introductionPanelRef} className="introduction-panel">
|
||||
<Markdown>{level?.data?.introduction}</Markdown>
|
||||
</div>
|
||||
<div className="exercise">
|
||||
<h4>Aufgabe:</h4>
|
||||
<Markdown>{level?.data?.descrText}</Markdown>
|
||||
<div className="statement"><code>{level?.data?.descrFormat}</code></div>
|
||||
<div ref={codeviewRef} className="codeview"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="info-panel">
|
||||
<EditorContext.Provider value={editorConnection}>
|
||||
<MonacoEditorContext.Provider value={editor}>
|
||||
{editorConnection && <Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} />}
|
||||
</MonacoEditorContext.Provider>
|
||||
</EditorContext.Provider>
|
||||
</div>
|
||||
<div className="doc-panel">
|
||||
<LeftPanel spells={level?.data?.tactics} inventory={level?.data?.lemmas}
|
||||
showSidePanel={showSidePanel} setShowSidePanel={setShowSidePanel} />
|
||||
</div>
|
||||
</Split>
|
||||
</>
|
||||
}
|
||||
|
||||
export default Level
|
||||
|
||||
@@ -12,7 +12,7 @@ function Markdown(props) {
|
||||
rehypePlugins: [...props.remarkPlugins ?? [], rehypeKatex],
|
||||
};
|
||||
return (
|
||||
<ReactMarkdown {...newProps} />
|
||||
<ReactMarkdown {...newProps} className="markdown" />
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,25 @@
|
||||
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 {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
@@ -16,7 +35,11 @@
|
||||
}
|
||||
|
||||
.introduction-panel {
|
||||
width: 100%;
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.exercise {
|
||||
padding: 1em;
|
||||
}
|
||||
|
||||
.exercise {
|
||||
|
||||
Generated
+1
@@ -29,6 +29,7 @@
|
||||
"react-markdown": "^8.0.4",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-router-dom": "^6.5.0",
|
||||
"react-split": "^2.0.14",
|
||||
"rehype-katex": "^6.0.2",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-math": "^5.1.1",
|
||||
|
||||
+2
-1
@@ -8,7 +8,6 @@
|
||||
"@emotion/styled": "^11.10.5",
|
||||
"@fontsource/roboto": "^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/material": "^5.11.1",
|
||||
"@reduxjs/toolkit": "^1.9.1",
|
||||
@@ -18,6 +17,7 @@
|
||||
"cytoscape-klay": "^3.1.4",
|
||||
"debounce": "^1.2.1",
|
||||
"express": "^4.18.2",
|
||||
"lean4-infoview": "https://gitpkg.now.sh/leanprover/vscode-lean4/lean4-infoview?master",
|
||||
"lean4web": "github:hhu-adam/lean4web",
|
||||
"path-browserify": "^1.0.1",
|
||||
"react": "^18.2.0",
|
||||
@@ -25,6 +25,7 @@
|
||||
"react-markdown": "^8.0.4",
|
||||
"react-redux": "^8.0.5",
|
||||
"react-router-dom": "^6.5.0",
|
||||
"react-split": "^2.0.14",
|
||||
"rehype-katex": "^6.0.2",
|
||||
"remark-gfm": "^3.0.1",
|
||||
"remark-math": "^5.1.1",
|
||||
|
||||
Reference in New Issue
Block a user