diff --git a/assets/js/sidebar-load-width.js b/assets/js/sidebar-load-width.js new file mode 100644 index 00000000000..913ce628bc6 --- /dev/null +++ b/assets/js/sidebar-load-width.js @@ -0,0 +1,18 @@ +(function () { + try { + var leftWidth = localStorage.getItem("left-sidebar-width"); + var tocWidth = localStorage.getItem("toc-width"); + var cssStyles = ""; + + if (leftWidth) cssStyles += "--left-sidebar-width: " + leftWidth + "px;"; + if (tocWidth) cssStyles += "--toc-width: " + tocWidth + "px;"; + + if (cssStyles) { + var styleTag = document.createElement("style"); + styleTag.innerHTML = ".td-resizable-grid .td-main > .row.flex-xl-nowrap {" + cssStyles + "}"; + document.head.appendChild(styleTag); + } + } catch (e) { + console.warn("LocalStorage blocked or unavailable:", e); + } +})(); \ No newline at end of file diff --git a/assets/js/sidebar-resizer.js b/assets/js/sidebar-resizer.js new file mode 100644 index 00000000000..f39d90fec1f --- /dev/null +++ b/assets/js/sidebar-resizer.js @@ -0,0 +1,114 @@ +(function () { + document.addEventListener("DOMContentLoaded", () => { + const gridContainer = document.querySelector(".td-resizable-grid .td-main > .row.flex-xl-nowrap"); + const leftResizer = document.getElementById("left-resizer"); + const rightResizer = document.getElementById("right-resizer"); + + if (!gridContainer) return; + + const LEFT_SIDEBAR_KEY = "left-sidebar-width"; + const TOC_KEY = "toc-width"; + + const storage = { + get: (key) => { + try { return localStorage.getItem(key); } + catch (e) { return null; } + }, + set: (key, value) => { + try { localStorage.setItem(key, value); } + catch (e) { return null; } + } + }; + + function setupResizer(resizer, type) { + resizer.addEventListener("pointerdown", (e) => { + e.preventDefault(); + + resizer.setPointerCapture(e.pointerId); + resizer.classList.add("is-dragging"); + + document.body.style.cursor = "col-resize"; + document.body.style.userSelect = "none"; + + const startX = e.clientX; + const styles = window.getComputedStyle(gridContainer); + const gridColumns = styles.gridTemplateColumns ? styles.gridTemplateColumns.split(" ") : []; + + /* + grid-template-columns over in _styles_project.scss has the following structure: + + --left-sidebar-width --sidebar-resize-width 1fr --sidebar-resize-width --toc-width; + + so gridcolumns[0] targets the left sidebar and gridcolumns[4] targets the toc + + */ + + let initialLeftSidebarWidth, initialTocWidth; + if (gridColumns.length >= 5 && gridColumns[0] !== "none") { + initialLeftSidebarWidth = parseInt(gridColumns[0], 10); + initialTocWidth = parseInt(gridColumns[4], 10); + } else { + initialLeftSidebarWidth = parseInt(styles.getPropertyValue('--left-sidebar-width'), 10); + initialTocWidth = parseInt(styles.getPropertyValue('--toc-width'), 10); + } + + const minWidth = parseInt(styles.getPropertyValue(type === "left" ? '--left-sidebar-min-width' : '--toc-min-width'), 10); + + const cssMaxWidth = parseInt(styles.getPropertyValue(type === "left" ? '--left-sidebar-max-width' : '--toc-max-width'), 10); + const maxAllowedByScreen = Math.floor(window.innerWidth * 0.4); + const maxWidth = Math.min(cssMaxWidth, maxAllowedByScreen); + + let currentWidth = type === "left" ? initialLeftSidebarWidth : initialTocWidth; + let ticking = false; + let animationFrameId = null; + + function onPointerMove(moveEvent) { + const deltaX = moveEvent.clientX - startX; + + if (type === "left") { + currentWidth = Math.max(minWidth, Math.min(maxWidth, initialLeftSidebarWidth + deltaX)); + } else if (type === "right") { + currentWidth = Math.max(minWidth, Math.min(maxWidth, initialTocWidth - deltaX)); + } + + if (!ticking) { + animationFrameId = window.requestAnimationFrame(() => { + const varName = type === "left" ? "--left-sidebar-width" : "--toc-width"; + gridContainer.style.setProperty(varName, `${currentWidth}px`); + ticking = false; + }); + ticking = true; + } + } + + function onPointerUp(upEvent) { + if (animationFrameId) { + window.cancelAnimationFrame(animationFrameId); + animationFrameId = null; + ticking = false; + } + + resizer.releasePointerCapture(upEvent.pointerId); + resizer.classList.remove("is-dragging"); + + document.body.style.cursor = ""; + document.body.style.userSelect = ""; + + const storageKey = type === "left" ? LEFT_SIDEBAR_KEY : TOC_KEY; + storage.set(storageKey, currentWidth); + + document.removeEventListener("pointermove", onPointerMove); + document.removeEventListener("pointerup", onPointerUp); + document.removeEventListener("pointercancel", onPointerUp); + } + + document.addEventListener("pointermove", onPointerMove); + document.addEventListener("pointerup", onPointerUp); + document.addEventListener("pointercancel", onPointerUp); + }); + } + + if (leftResizer) setupResizer(leftResizer, "left"); + if (rightResizer) setupResizer(rightResizer, "right"); + }); +})(); \ No newline at end of file diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index 5a34ccd09be..dc0b5b1fe4e 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -394,6 +394,83 @@ a:not([href]):not([class]):hover { } } +// Left sidebar & Right sidebar Resize +:root { + --left-sidebar-width: 240px; + --toc-width: 240px; + + --left-sidebar-min-width: 180px; + --left-sidebar-max-width: 500px; + + --toc-min-width: 180px; + --toc-max-width: 400px; + + --sidebar-resize-width: 5px; +} + +@media (min-width: 1200px) { + .td-resizable-grid .td-main > .row.flex-xl-nowrap { + display: grid; + grid-template-columns: + var(--left-sidebar-width) + var(--sidebar-resize-width) + 1fr + var(--sidebar-resize-width) + var(--toc-width); + } + + .td-sidebar { + grid-column: 1; + grid-row: 1; + } + + #left-resizer { + grid-column: 2; + grid-row: 1; + padding-left: 0 !important; + padding-right: 0 !important; + box-sizing: border-box; + } + + main[role="main"] { + grid-column: 3; + grid-row: 1; + } + + #right-resizer { + grid-column: 4; + grid-row: 1; + padding-left: 0 !important; + padding-right: 0 !important; + box-sizing: border-box; + } + + .td-sidebar-toc { + grid-column: 5; + grid-row: 1; + } + + .td-resizable-grid .td-sidebar, + .td-resizable-grid .td-sidebar-toc, + .td-resizable-grid main[role="main"] { + width: auto; + } + + //change the colors to something of meshery? + .layout-resizer { + width: var(--sidebar-resize-width); + cursor: col-resize; + background-color: rgba(0, 0, 0, 0.03); + transition: background-color 0.15s ease; + z-index: 1; //Must be lower than the sticky header + } + + .layout-resizer:hover, + .layout-resizer.is-dragging { + background-color: var(--primary, #007bff); + } +} + // pageinfo .pageinfo { font-weight: $font-weight-medium; diff --git a/layouts/docs/baseof.html b/layouts/docs/baseof.html index 3503963fb79..46ed5ee6110 100644 --- a/layouts/docs/baseof.html +++ b/layouts/docs/baseof.html @@ -7,17 +7,23 @@