resizable panels
This commit is contained in:
@@ -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;
|
||||||
|
}
|
||||||
|
|||||||
+26
-100
@@ -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,38 +106,31 @@ 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>
|
<div ref={introductionPanelRef} className="introduction-panel">
|
||||||
</DrawerHeader>
|
<Markdown>{level?.data?.introduction}</Markdown>
|
||||||
<Divider />
|
</div>
|
||||||
<IconButton onClick={toggleSidePanel}>
|
<div className="exercise">
|
||||||
<FontAwesomeIcon icon={showSidePanel ? faChevronLeft : faChevronRight}></FontAwesomeIcon>
|
<h4>Aufgabe:</h4>
|
||||||
</IconButton>
|
<Markdown>{level?.data?.descrText}</Markdown>
|
||||||
<LeftPanel spells={level?.data?.tactics} inventory={level?.data?.lemmas} showSidePanel={showSidePanel} setShowSidePanel={setShowSidePanel} />
|
<div className="statement"><code>{level?.data?.descrFormat}</code></div>
|
||||||
</Drawer>
|
<div ref={codeviewRef} className="codeview"></div>
|
||||||
<Grid container columnSpacing={{ xs: 1, sm: 2, md: 3 }} sx={{ flexGrow: 1, p: 3 }} className="main-grid">
|
</div>
|
||||||
<Grid xs={8} className="main-panel">
|
</div>
|
||||||
<div ref={introductionPanelRef} className="introduction-panel">
|
<div className="info-panel">
|
||||||
<Markdown>{level?.data?.introduction}</Markdown>
|
<EditorContext.Provider value={editorConnection}>
|
||||||
</div>
|
<MonacoEditorContext.Provider value={editor}>
|
||||||
<div className="exercise">
|
{editorConnection && <Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} />}
|
||||||
<h4>Aufgabe:</h4>
|
</MonacoEditorContext.Provider>
|
||||||
<Markdown>{level?.data?.descrText}</Markdown>
|
</EditorContext.Provider>
|
||||||
<div className="statement"><code>{level?.data?.descrFormat}</code></div>
|
</div>
|
||||||
<div ref={codeviewRef} className="codeview"></div>
|
<div className="doc-panel">
|
||||||
</div>
|
<LeftPanel spells={level?.data?.tactics} inventory={level?.data?.lemmas}
|
||||||
</Grid>
|
showSidePanel={showSidePanel} setShowSidePanel={setShowSidePanel} />
|
||||||
<Grid xs={4} className="info-panel">
|
</div>
|
||||||
<EditorContext.Provider value={editorConnection}>
|
</Split>
|
||||||
<MonacoEditorContext.Provider value={editor}>
|
</>
|
||||||
{editorConnection && <Main key={`${worldId}/${levelId}`} world={worldId} level={levelId} />}
|
|
||||||
</MonacoEditorContext.Provider>
|
|
||||||
</EditorContext.Provider>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Level
|
export default Level
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Generated
+1
@@ -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",
|
||||||
|
|||||||
+2
-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",
|
||||||
|
|||||||
Reference in New Issue
Block a user