Skip to content

Commit

Permalink
Add patch to fix sidebar toggle (#7330)
Browse files Browse the repository at this point in the history
Co-authored-by: Simon Høxbro Hansen <simon.hansen@me.com>
  • Loading branch information
philippjfr and hoxbro authored Sep 27, 2024
1 parent e3514e4 commit c525206
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 2 deletions.
101 changes: 101 additions & 0 deletions doc/_static/toggle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
export function documentReady(callback) {
if (document.readyState != "loading") callback();
else document.addEventListener("DOMContentLoaded", callback);
}

function clone(node) {
var new_element = node.cloneNode(true);
node.parentNode.replaceChild(new_element, node);
}

export function documentReady(callback) {
if (document.readyState != "loading") callback();
else document.addEventListener("DOMContentLoaded", callback);
}

let loaded = false

function setupMobileSidebarKeyboardHandlers() {
if (loaded) {
return
}
loaded = true

// These are hidden checkboxes at the top of the page whose :checked property
// allows the mobile sidebars to be hidden or revealed via CSS.
const primaryToggle = document.getElementById("pst-primary-sidebar-checkbox");
const secondaryToggle = document.getElementById(
"pst-secondary-sidebar-checkbox",
);
const primarySidebar = document.querySelector(".bd-sidebar-primary");
const secondarySidebar = document.querySelector(".bd-sidebar-secondary");

// Toggle buttons -
//
// These are the hamburger-style buttons in the header nav bar. When the user
// clicks, the button transmits the click to the hidden checkboxes used by the
// CSS to control whether the sidebar is open or closed.
const primaryClickTransmitter = document.querySelector(".primary-toggle");
const secondaryClickTransmitter = document.querySelector(".secondary-toggle");
[
[primaryClickTransmitter, primaryToggle, primarySidebar],
[secondaryClickTransmitter, secondaryToggle, secondarySidebar],
].forEach(([clickTransmitter, toggle, sidebar]) => {
if (!clickTransmitter) {
return;
}
clone(clickTransmitter)
clickTransmitter.addEventListener("click", (event) => {
event.preventDefault();
event.stopPropagation();
toggle.checked = !toggle.checked;

// If we are opening the sidebar, move focus to the first focusable item
// in the sidebar
if (toggle.checked) {
// Note: this selector is not exhaustive, and we may need to update it
// in the future
const tabStop = sidebar.querySelector("a, button");
// use setTimeout because you cannot move focus synchronously during a
// click in the handler for the click event
setTimeout(() => tabStop.focus(), 100);
}
});
});

// Escape key -
//
// When sidebar is open, user should be able to press escape key to close the
// sidebar.
[
[primarySidebar, primaryToggle, primaryClickTransmitter],
[secondarySidebar, secondaryToggle, secondaryClickTransmitter],
].forEach(([sidebar, toggle, transmitter]) => {
if (!sidebar) {
return;
}
sidebar.addEventListener("keydown", (event) => {
if (event.key === "Escape") {
event.preventDefault();
event.stopPropagation();
toggle.checked = false;
transmitter.focus();
}
});
});

// When the <label> overlay is clicked to close the sidebar, return focus to
// the opener button in the nav bar.
[
[primaryToggle, primaryClickTransmitter],
[secondaryToggle, secondaryClickTransmitter],
].forEach(([toggle, transmitter]) => {
toggle.addEventListener("change", (event) => {
if (!event.currentTarget.checked) {
transmitter.focus();
}
});
});
}

documentReady(setupMobileSidebarKeyboardHandlers)
3 changes: 2 additions & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ def get_requirements():

html_js_files = [
(None, {'body': '{"shimMode": true}', 'type': 'esms-options'}),
f'https://cdn.holoviz.org/panel/{js_version}/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js'
f'https://cdn.holoviz.org/panel/{js_version}/dist/bundled/reactiveesm/es-module-shims@^1.10.0/dist/es-module-shims.min.js',
'_static/toggle.js'
]

nbsite_pyodide_conf = {
Expand Down
2 changes: 1 addition & 1 deletion panel/.eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ module.exports = {
},
"plugins": ["@typescript-eslint", "@stylistic/eslint-plugin"],
"extends": [],
"ignorePatterns": ["*/dist", "*/theme/**/*.js", ".eslintrc.js", "*/_templates/*.js", "*/template/**/*.js", "examples/*", "scripts/*"],
"ignorePatterns": ["*/dist", "*/theme/**/*.js", ".eslintrc.js", "*/_templates/*.js", "*/template/**/*.js", "examples/*", "scripts/*", "doc/_static/*.js"],
"rules": {
"@typescript-eslint/ban-types": ["error", {
"types": {
Expand Down

0 comments on commit c525206

Please sign in to comment.