diff --git a/python_docs_theme/static/pydoctheme.css b/python_docs_theme/static/pydoctheme.css index 0f6f8d3..8327941 100644 --- a/python_docs_theme/static/pydoctheme.css +++ b/python_docs_theme/static/pydoctheme.css @@ -139,7 +139,13 @@ span.pre { white-space: unset; } +div.bodywrapper { + margin-left: 250px; +} + div.sphinxsidebar { + display: flex; + width: 250px; float: none; position: sticky; top: 0; @@ -157,12 +163,12 @@ div.sphinxsidebar h4 { } div.sphinxsidebarwrapper { - width: 217px; box-sizing: border-box; height: 100%; overflow-x: hidden; overflow-y: auto; - float: left; + float: none; + flex-grow: 1; } div.sphinxsidebarwrapper > h3:first-child { @@ -197,12 +203,13 @@ div.sphinxsidebar input[type='text'] { margin-left: 0; color: #444444; font-size: 1.2em; - cursor: pointer; + cursor: default; /* cursor is set to 'col-resize' using JS */ padding-top: 1px; - float: right; + float: none; display: table; /* after Sphinx 4.x and earlier is dropped, only the below is needed */ width: 12px; + min-width: 12px; border-radius: 0 5px 5px 0; border-left: none; } @@ -468,7 +475,7 @@ div.genindex-jumpbox a { font-size: 0.875rem; } div.bodywrapper { - margin: 0; + margin: 0 !important; } /* Typography */ div.body h1 { @@ -490,7 +497,7 @@ div.genindex-jumpbox a { } /* Remove sidebar and top related bar */ div.related, .sphinxsidebar { - display: none; + display: none !important; } /* Anchorlinks are not hidden by fixed-positioned navbar when scrolled to */ html { diff --git a/python_docs_theme/static/sidebar.js_t b/python_docs_theme/static/sidebar.js_t index a08aa0f..63fe568 100644 --- a/python_docs_theme/static/sidebar.js_t +++ b/python_docs_theme/static/sidebar.js_t @@ -26,13 +26,14 @@ */ const initialiseSidebar = () => { + const ngettext = Documentation.ngettext // global elements used by the functions. - const bodyWrapper = document.getElementsByClassName("bodywrapper")[0] - const sidebar = document.getElementsByClassName("sphinxsidebar")[0] - const sidebarWrapper = document.getElementsByClassName("sphinxsidebarwrapper")[0] + const bodyWrapper = document.querySelector(".bodywrapper") + const sidebar = document.querySelector(".sphinxsidebar") + const sidebarWrapper = document.querySelector(".sphinxsidebarwrapper") // exit early if the document has no sidebar for some reason - if (typeof sidebar === "undefined") { + if (!sidebar) { return } @@ -44,46 +45,64 @@ const initialiseSidebar = () => { #} {% if sphinx_version_tuple is defined and sphinx_version_tuple[0] >= 5 %} const sidebarButton = document.getElementById("sidebarbutton") - const sidebarArrow = sidebarButton.querySelector('span') {% else %} // create the sidebar button element const sidebarButton = document.createElement("div") sidebarButton.id = "sidebarbutton" - // create the sidebar button arrow element - const sidebarArrow = document.createElement("span") - sidebarArrow.innerText = "«" - sidebarButton.appendChild(sidebarArrow) - sidebar.appendChild(sidebarButton) {% endif %} + const sidebarMinWidth = 200 + const sidebarMaxWidth = Math.round(0.5 * window.innerWidth) - const collapse_sidebar = () => { - bodyWrapper.style.marginLeft = ".8em" - sidebar.style.width = ".8em" - sidebarWrapper.style.display = "none" - sidebarArrow.innerText = "»" - sidebarButton.title = _("Expand sidebar") - window.localStorage.setItem("sidebar", "collapsed") - } + sidebarbutton.innerHTML = "" + sidebarbutton.tabindex = "0" // make it focusable + sidebarbutton.role = "slider" + sidebarbutton.title = _("Resize sidebar") + sidebarbutton.style.cursor = "col-resize" // Set the cursor only if JS is enabled + sidebarbutton.setAttribute("aria-label", _("Resize sidebar by dragging")) + sidebarbutton.setAttribute( + "aria-valuetext", + ngettext( + "Sidebar width {count} pixel", + "Sidebar width {count} pixels", + sidebar.offsetWidth + ).replace("{count}", sidebar.offsetWidth) + ) + let clientX; - const expand_sidebar = () => { - bodyWrapper.style.marginLeft = "" - sidebar.style.removeProperty("width") - sidebarWrapper.style.display = "" - sidebarArrow.innerText = "«" - sidebarButton.title = _("Collapse sidebar") - window.localStorage.setItem("sidebar", "expanded") + function onMouseMove(e) { + e.preventDefault() + const sidebarWidth = sidebar.offsetWidth + const newWidth = Math.max( + sidebarMinWidth, + Math.min(sidebarMaxWidth, sidebarWidth + e.clientX - clientX) + ) + clientX = e.clientX + sidebar.style.width = `${newWidth}px` + bodyWrapper.style.marginLeft = `${newWidth}px` + window.localStorage.setItem("sidebar-width", newWidth) } - sidebarButton.addEventListener("click", () => { - (sidebarWrapper.style.display === "none") ? expand_sidebar() : collapse_sidebar() + sidebarButton.addEventListener("mousedown", e => { + e.preventDefault() + clientX = e.clientX + document.addEventListener("mousemove", onMouseMove) + document.addEventListener("mouseup", () => { + document.removeEventListener("mousemove", onMouseMove) + sidebarbutton.setAttribute( + "aria-valuetext", + ngettext( + "Sidebar width {count} pixel", + "Sidebar width {count} pixels", + sidebar.offsetWidth + ).replace("{count}", sidebar.offsetWidth) + ) + }) }) - const sidebar_state = window.localStorage.getItem("sidebar") - if (sidebar_state === "collapsed") { - collapse_sidebar() - } - else if (sidebar_state === "expanded") { - expand_sidebar() + const sidebarWidth = parseInt(window.localStorage.getItem("sidebar-width"), 10) + if(Number.isFinite(sidebarWidth)) { + sidebar.style.width = `${sidebarWidth}px` + bodyWrapper.style.marginLeft = `${sidebarWidth}px` } }