From 5800923713b0485cab871bc248e66c59aec34dda Mon Sep 17 00:00:00 2001
From: Michael Daines <1383+mdaines@users.noreply.github.com>
Date: Mon, 4 Nov 2024 15:22:24 -0500
Subject: [PATCH] Add resizing handle for editor pane
---
packages/website/src/components/App.jsx | 14 +++++--
packages/website/src/components/Resize.jsx | 40 +++++++++++++++++++
packages/website/src/index.html | 2 +-
packages/website/src/index.jsx | 2 +-
packages/website/src/styles/app.css | 45 +++++++++++++++-------
5 files changed, 85 insertions(+), 18 deletions(-)
create mode 100644 packages/website/src/components/Resize.jsx
diff --git a/packages/website/src/components/App.jsx b/packages/website/src/components/App.jsx
index 8bc96d15..6380f0ee 100644
--- a/packages/website/src/components/App.jsx
+++ b/packages/website/src/components/App.jsx
@@ -7,6 +7,7 @@ import Editor from "./Editor.jsx";
import OutputToolbar from "./OutputToolbar.jsx";
import Output from "./Output.jsx";
import Errors from "./Errors.jsx";
+import Resize from "./Resize.jsx";
const worker = new ReloadablePromiseWorker(() => new Worker(new URL("../worker.js", import.meta.url), { type: "module" }));
@@ -28,8 +29,10 @@ export default function App({ initialSrc }) {
const [errors, setErrors] = useState([]);
const [zoom, setZoom] = useState("fit");
const [isValid, setValid] = useState(false);
- const imageZoomRef = useRef(null);
+
+ const appRef = useRef(null);
const editorRef = useRef(null);
+ const imageZoomRef = useRef(null);
function handleCopyLink() {
copyLink(src);
@@ -50,6 +53,10 @@ export default function App({ initialSrc }) {
setDebouncedSrc(example);
}
+ function handleResize(width) {
+ appRef.current.style.setProperty("--editor-width", width + "px");
+ }
+
const handleSrcChangeDebounced = useMemo(() => {
return debounce(setDebouncedSrc, 750);
}, []);
@@ -88,12 +95,13 @@ export default function App({ initialSrc }) {
const zoomEnabled = result?.format == "svg-image";
return (
- <>
+
+
imageZoomRef.current?.zoomIn()} onZoomOut={() => imageZoomRef.current?.zoomOut()} />
- >
+
);
}
diff --git a/packages/website/src/components/Resize.jsx b/packages/website/src/components/Resize.jsx
new file mode 100644
index 00000000..8a02a720
--- /dev/null
+++ b/packages/website/src/components/Resize.jsx
@@ -0,0 +1,40 @@
+import { useEffect, useRef } from "react";
+
+let dragging = false;
+let dragOffset;
+
+export default function Resize({ onResize }) {
+ function handleMouseDown(e) {
+ e.preventDefault();
+
+ const rect = e.target.getBoundingClientRect();
+
+ dragging = true;
+ dragOffset = Math.round(e.clientX - rect.left);
+ }
+
+ function handleMouseMove(e) {
+ if (dragging) {
+ let width = Math.max(0, e.clientX - dragOffset);
+ onResize(width);
+ }
+ }
+
+ function handleMouseUp() {
+ dragging = false;
+ }
+
+ useEffect(() => {
+ window.addEventListener("mousemove", handleMouseMove);
+ window.addEventListener("mouseup", handleMouseUp);
+ }, []);
+
+ let resizeRef = useRef(null);
+
+ return (
+
+ );
+}
diff --git a/packages/website/src/index.html b/packages/website/src/index.html
index 4e51596b..cdd4efdc 100644
--- a/packages/website/src/index.html
+++ b/packages/website/src/index.html
@@ -21,7 +21,7 @@
-
diff --git a/packages/website/src/index.jsx b/packages/website/src/index.jsx
index 91e73713..56dd6a2f 100644
--- a/packages/website/src/index.jsx
+++ b/packages/website/src/index.jsx
@@ -6,7 +6,7 @@ import { getExample, defaultExampleName } from "./examples.js";
const initialSrc = getInputFromSearch(window.location.search, getExample(defaultExampleName));
-const root = createRoot(document.getElementById("app"));
+const root = createRoot(document.getElementById("root"));
root.render(
diff --git a/packages/website/src/styles/app.css b/packages/website/src/styles/app.css
index c387b813..c02b89da 100644
--- a/packages/website/src/styles/app.css
+++ b/packages/website/src/styles/app.css
@@ -17,17 +17,22 @@ body {
grid-template-rows: max-content minmax(0, 1fr);
}
-#app {
+#root {
+ display: grid;
grid-area: app;
+}
+
+#app {
+ --editor-width: 50%;
+
display: grid;
- grid-template-areas: "editor-toolbar output-toolbar" "editor output" "editor errors";
- grid-template-columns: 50% 1fr;
+ grid-template-areas: "editor-toolbar resize output-toolbar" "editor resize output" "editor resize errors";
+ grid-template-columns: minmax(300px, var(--editor-width)) 1px minmax(450px, 1fr);
grid-template-rows: max-content 1fr fit-content(20%);
}
.editor {
grid-area: editor;
- border-right: 1px solid #ccc;
}
.cm-editor {
@@ -91,7 +96,6 @@ body {
.editor-toolbar {
grid-area: editor-toolbar;
- border-right: 1px solid #ccc;
justify-content: center;
}
@@ -160,17 +164,9 @@ body {
grid-template-rows: max-content 30% max-content 1fr fit-content(20%);
}
- .editor {
- border-right: none;
- }
-
.output-toolbar {
border-top: 1px solid #ccc;
}
-
- .editor-toolbar {
- border-right: none;
- }
}
@media (max-width: 450px) {
@@ -178,3 +174,26 @@ body {
font-size: 16px;
}
}
+
+
+.resize {
+ grid-area: resize;
+ background: #ccc;
+ position: relative;
+ z-index: 1;
+}
+
+.resize-handle {
+ width: 7px;
+ left: -3px;
+ position: absolute;
+ top: 0;
+ bottom: 0;
+ cursor: ew-resize;
+}
+
+@media (max-width: 750px) {
+ .resize {
+ display: none;
+ }
+}