diff --git a/src/app/components/generator/ProjectPanel.tsx b/src/app/components/generator/ProjectPanel.tsx index fa4d0dbb..3b76c59d 100644 --- a/src/app/components/generator/ProjectPanel.tsx +++ b/src/app/components/generator/ProjectPanel.tsx @@ -133,7 +133,7 @@ export function ProjectPanel() { }, [service, actions, projectRoot, projectUri]) - return <> + return
{projects.map(p => changeProject(p.name)} />)} @@ -152,5 +152,5 @@ export function ProjectPanel() { : path.split('/')} group={FolderEntry} leaf={FileEntry} />}
- +
} diff --git a/src/app/components/generator/SchemaGenerator.tsx b/src/app/components/generator/SchemaGenerator.tsx index a4cd64a5..bc9abd41 100644 --- a/src/app/components/generator/SchemaGenerator.tsx +++ b/src/app/components/generator/SchemaGenerator.tsx @@ -7,7 +7,7 @@ import config from '../../Config.js' import { DRAFT_PROJECT, useLocale, useProject, useVersion } from '../../contexts/index.js' import { useModal } from '../../contexts/Modal.jsx' import { useSpyglass, watchSpyglassUri } from '../../contexts/Spyglass.jsx' -import { AsyncCancel, useActiveTimeout, useAsync, useSearchParam } from '../../hooks/index.js' +import { AsyncCancel, useActiveTimeout, useAsync, useLocalStorage, useSearchParam } from '../../hooks/index.js' import type { VersionId } from '../../services/index.js' import { checkVersion, fetchDependencyMcdoc, fetchPreset, fetchRegistries, getSnippet, shareSnippet } from '../../services/index.js' import { DEPENDENCY_URI } from '../../services/Spyglass.js' @@ -17,6 +17,7 @@ import { Ad, Btn, BtnMenu, ErrorPanel, FileCreation, Footer, HasPreview, Octicon import { getRootDefault } from './McdocHelpers.js' export const SHARE_KEY = 'share' +const MIN_PROJECT_PANEL_WIDTH = 200 interface Props { gen: ConfigGenerator @@ -322,6 +323,38 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) { setProjectShown(!projectShown) }, [projectShown]) + const [panelWidth, setPanelWidth] = useLocalStorage('misode_project_panel_width', MIN_PROJECT_PANEL_WIDTH, (s) => Number(s), (v) => v.toString()) + const [realPanelWidth, setRealPanelWidth] = useState(panelWidth) + const [resizeStart, setResizeStart] = useState() + + useEffect(() => { + const onMouseMove = (e: MouseEvent) => { + if (resizeStart) { + const targetWidth = e.clientX - resizeStart + if (targetWidth < 50) { + setProjectShown(false) + } else { + setRealPanelWidth(Math.max(MIN_PROJECT_PANEL_WIDTH, targetWidth)) + } + } + } + window.addEventListener('mousemove', onMouseMove) + return () => window.removeEventListener('mousemove', onMouseMove) + }, [resizeStart]) + + useEffect(() => { + const onMouseUp = () => { + setResizeStart(undefined) + if (realPanelWidth < MIN_PROJECT_PANEL_WIDTH) { + setRealPanelWidth(panelWidth) + } else { + setPanelWidth(realPanelWidth) + } + } + window.addEventListener('mouseup', onMouseUp) + return () => window.removeEventListener('mouseup', onMouseUp) + }, [panelWidth, realPanelWidth]) + const newEmptyFile = useCallback(async () => { if (service) { const unsavedUri = service.getUnsavedFileUri(gen) @@ -333,7 +366,7 @@ export function SchemaGenerator({ gen, allowedVersions }: Props) { }, [gen, service, showModal]) return <> -
+
{!gen.tags?.includes('partners') && } -
- +
+ +
setResizeStart(e.clientX - panelWidth)}>
} diff --git a/src/styles/global.css b/src/styles/global.css index b6c9778c..196d9f01 100644 --- a/src/styles/global.css +++ b/src/styles/global.css @@ -330,6 +330,7 @@ main > .controls { .project-controls { margin: 8px; + margin-right: 0; display: flex; z-index: 2; } @@ -520,10 +521,8 @@ canvas.preview-details.visible { .popup-project { position: fixed; display: flex; - flex-direction: column; + flex-direction: row; height: calc(100% - 56px); - width: 200px; - width: max(200px, 20vw); right: 100%; bottom: 0; z-index: 3; @@ -538,8 +537,20 @@ canvas.preview-details.visible { } main.has-project { - padding-left: 200px; - padding-left: max(200px, 20vw); + padding-left: var(--project-panel-width, 200px); +} + +.popup-project .panel-content { + display: flex; + flex-direction: column; + width: calc(100% - 8px); +} + +.panel-resize { + width: 8px; + height: 100%; + cursor: ew-resize; + user-select: none; } .preview-overlay {