diff --git a/gui/src/app/SPAnalysis/SPAnalysisContextProvider.tsx b/gui/src/app/SPAnalysis/SPAnalysisContextProvider.tsx index ddad1ed7..d044ee7e 100644 --- a/gui/src/app/SPAnalysis/SPAnalysisContextProvider.tsx +++ b/gui/src/app/SPAnalysis/SPAnalysisContextProvider.tsx @@ -11,6 +11,7 @@ type SPAnalysisContextType = { } type SPAnalysisContextProviderProps = { + // } export const SPAnalysisContext = createContext({ diff --git a/gui/src/app/pages/HomePage/HomePage.tsx b/gui/src/app/pages/HomePage/HomePage.tsx index 4ba0e1c2..cbb57fb5 100644 --- a/gui/src/app/pages/HomePage/HomePage.tsx +++ b/gui/src/app/pages/HomePage/HomePage.tsx @@ -1,5 +1,5 @@ import { Splitter } from "@fi-sci/splitter"; -import { FunctionComponent, useCallback, useContext, useEffect, useMemo, useState } from "react"; +import { FunctionComponent, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react"; import DataFileEditor from "../../FileEditor/DataFileEditor"; import StanFileEditor from "../../FileEditor/StanFileEditor"; import RunPanel from "../../RunPanel/RunPanel"; @@ -30,8 +30,6 @@ const HomePage: FunctionComponent = ({ width, height }) => { } const HomePageChild: FunctionComponent = ({ width, height }) => { - - const { data, update } = useContext(SPAnalysisContext) const setSamplingOpts = useCallback((opts: SamplingOpts) => { update({ type: 'setSamplingOpts', opts }) @@ -39,14 +37,29 @@ const HomePageChild: FunctionComponent = ({ width, height }) => { const [compiledMainJsUrl, setCompiledMainJsUrl] = useState('') - const leftPanelWidth = Math.max(250, Math.min(340, width * 0.2)) + const [leftPanelCollapsed, setLeftPanelCollapsed] = useState(determineShouldBeInitiallyCollapsed(width)) + const expandedLeftPanelWidth = determineLeftPanelWidth(width) // what the width would be if expanded + const leftPanelWidth = leftPanelCollapsed ? 20 : expandedLeftPanelWidth // the actual width + + // We automatically collapse the panel if user has resized the window to be + // too small but we only want to do this right when we cross the threshold, + // not every time we resize by a pixel. Similar for expanding the panel when + // we cross the threshold in the other direction. + const lastShouldBeCollapsed = useRef(determineShouldBeInitiallyCollapsed(width)) + useEffect(() => { + const shouldBeCollapsed = determineShouldBeInitiallyCollapsed(width) + if (shouldBeCollapsed !== lastShouldBeCollapsed.current) { + lastShouldBeCollapsed.current = shouldBeCollapsed + setLeftPanelCollapsed(shouldBeCollapsed) + } + }, [width]) + const topBarHeight = 25 useEffect(() => { document.title = "Stan Playground - " + data.meta.title; }, [data.meta.title]) - return (
@@ -58,6 +71,8 @@ const HomePageChild: FunctionComponent = ({ width, height }) => {
= ({ width, height }) => { ) } +// the width of the left panel when it is expanded based on the overall width +const determineLeftPanelWidth = (width: number) => { + const minWidth = 250 + const maxWidth = 400 + return Math.min(maxWidth, Math.max(minWidth, width / 4)) +} + +// whether the left panel should be collapsed initially based on the overall +// width +const determineShouldBeInitiallyCollapsed = (width: number) => { + return width < 800 +} + type RightViewProps = { width: number height: number diff --git a/gui/src/app/pages/HomePage/LeftPanel.tsx b/gui/src/app/pages/HomePage/LeftPanel.tsx index 554758ce..30c7a362 100644 --- a/gui/src/app/pages/HomePage/LeftPanel.tsx +++ b/gui/src/app/pages/HomePage/LeftPanel.tsx @@ -1,18 +1,21 @@ -import { Hyperlink } from "@fi-sci/misc" +import { Hyperlink, SmallIconButton } from "@fi-sci/misc" import ModalWindow, { useModalWindow } from "@fi-sci/modal-window" import { FunctionComponent, useCallback, useContext } from "react" import examplesStanies, { Stanie } from "../../exampleStanies/exampleStanies" import { SPAnalysisContext } from "../../SPAnalysis/SPAnalysisContextProvider" import ExportWindow from "./ExportWindow" import ImportWindow from "./ImportWindow" +import { ChevronLeft, ChevronRight } from "@mui/icons-material" type LeftPanelProps = { width: number height: number hasUnsavedChanges: boolean + collapsed: boolean + onSetCollapsed: (collapsed: boolean) => void } -const LeftPanel: FunctionComponent = ({ width, height, hasUnsavedChanges }) => { +const LeftPanel: FunctionComponent = ({ width, height, hasUnsavedChanges, collapsed, onSetCollapsed }) => { // note: this is close enough to pass in directly if we wish const { update } = useContext(SPAnalysisContext) @@ -22,9 +25,21 @@ const LeftPanel: FunctionComponent = ({ width, height, hasUnsave const { visible: exportVisible, handleOpen: exportOpen, handleClose: exportClose } = useModalWindow() const { visible: importVisible, handleOpen: importOpen, handleClose: importClose } = useModalWindow() + + if (collapsed) { + return ( +
+
+ onSetCollapsed(false)} /> +
+
+ ) + } + return (
+ onSetCollapsed(true)} />

Examples

{ examplesStanies.map((stanie, i) => ( @@ -85,4 +100,24 @@ const LeftPanel: FunctionComponent = ({ width, height, hasUnsave ) } +const ExpandButton: FunctionComponent<{ onClick: () => void }> = ({ onClick }) => { + return ( + } + onClick={onClick} + title="Expand" + /> + ) +} + +const CollapseButton: FunctionComponent<{ onClick: () => void }> = ({ onClick }) => { + return ( + } + onClick={onClick} + title="Collapse" + /> + ) +} + export default LeftPanel \ No newline at end of file