Skip to content

Commit

Permalink
A11y: set aria-expanded to the toggle button. (#61)
Browse files Browse the repository at this point in the history
* A11y: set aria-expanded to the toggle button.

Closes Quansight-Labs/czi-scientific-python-mgmt#77

* run linter/prettify
  • Loading branch information
Carreau authored Sep 12, 2024
1 parent f468ca6 commit 9a8272d
Showing 1 changed file with 59 additions and 42 deletions.
101 changes: 59 additions & 42 deletions sphinx_togglebutton/_static/togglebutton.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ let toggleChevron = `

var initToggleItems = () => {
var itemsToToggle = document.querySelectorAll(togglebuttonSelector);
console.log(`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`)
console.log(
`[togglebutton]: Adding toggle buttons to ${itemsToToggle.length} items`
);
// Add the button to each admonition and hook up a callback to toggle visibility
itemsToToggle.forEach((item, index) => {
if (item.classList.contains("admonition")) {
Expand All @@ -19,30 +21,40 @@ var initToggleItems = () => {
var toggleID = `toggle-${index}`;
var buttonID = `button-${toggleID}`;

item.setAttribute('id', toggleID);
if (!item.classList.contains("toggle")){
item.setAttribute("id", toggleID);
if (!item.classList.contains("toggle")) {
item.classList.add("toggle");
}
// This is the button that will be added to each item to trigger the toggle
var collapseButton = `
<button type="button" id="${buttonID}" class="toggle-button" data-target="${toggleID}" data-button="${buttonID}" data-toggle-hint="${toggleHintShow}" aria-label="Toggle hidden content">
<button type="button"
id="${buttonID}"
class="toggle-button"
data-target="${toggleID}"
data-button="${buttonID}"
data-toggle-hint="${toggleHintShow}"
aria-label="Toggle hidden content"
aria-expanded="false"
>
${toggleChevron}
</button>`;

title = item.querySelector(".admonition-title")
title = item.querySelector(".admonition-title");
title.insertAdjacentHTML("beforeend", collapseButton);
thisButton = document.getElementById(buttonID);

// Add click handlers for the button + admonition title (if admonition)
admonitionTitle = document.querySelector(`#${toggleID} > .admonition-title`)
admonitionTitle = document.querySelector(
`#${toggleID} > .admonition-title`
);
if (admonitionTitle) {
// If an admonition, then make the whole title block clickable
admonitionTitle.addEventListener('click', toggleClickHandler);
admonitionTitle.dataset.target = toggleID
admonitionTitle.dataset.button = buttonID
admonitionTitle.addEventListener("click", toggleClickHandler);
admonitionTitle.dataset.target = toggleID;
admonitionTitle.dataset.button = buttonID;
} else {
// If not an admonition then we'll listen for the button click
thisButton.addEventListener('click', toggleClickHandler);
thisButton.addEventListener("click", toggleClickHandler);
}

// Now hide the item for this toggle button unless explicitly noted to show
Expand All @@ -62,12 +74,12 @@ var initToggleItems = () => {
item.insertAdjacentHTML("beforebegin", detailsBlock);

// Now move the toggle-able content inside of the details block
details = item.previousElementSibling
details.appendChild(item)
item.classList.add("toggle-details__container")
details = item.previousElementSibling;
details.appendChild(item);
item.classList.add("toggle-details__container");

// Set up a click trigger to change the text as needed
details.addEventListener('click', (click) => {
details.addEventListener("click", (click) => {
let parent = click.target.parentElement;
if (parent.tagName.toLowerCase() == "details") {
summary = parent.querySelector("summary");
Expand All @@ -78,35 +90,38 @@ var initToggleItems = () => {
}
// Update the inner text for the proper hint
if (details.open) {
summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintShow;
summary.querySelector("span.toggle-details__summary-text").innerText =
toggleHintShow;
} else {
summary.querySelector("span.toggle-details__summary-text").innerText = toggleHintHide;
summary.querySelector("span.toggle-details__summary-text").innerText =
toggleHintHide;
}

});

// If we have a toggle-shown class, open details block should be open
if (item.classList.contains("toggle-shown")) {
details.click();
}
}
})
});
};

// This should simply add / remove the collapsed class and change the button text
var toggleHidden = (button) => {
target = button.dataset['target']
target = button.dataset["target"];
var itemToToggle = document.getElementById(target);
if (itemToToggle.classList.contains("toggle-hidden")) {
itemToToggle.classList.remove("toggle-hidden");
button.classList.remove("toggle-button-hidden");
button.dataset.toggleHint = toggleHintHide;
button.setAttribute("aria-expanded", true);
} else {
itemToToggle.classList.add("toggle-hidden");
button.classList.add("toggle-button-hidden");
button.dataset.toggleHint = toggleHintShow;
button.setAttribute("aria-expanded", false);
}
}
};

var toggleClickHandler = (click) => {
// Be cause the admonition title is clickable and extends to the whole admonition
Expand All @@ -124,36 +139,36 @@ var toggleClickHandler = (click) => {
// We've clicked the button itself and so don't need to do anything
button = click.target;
} else {
console.log(`[togglebutton]: Couldn't find button for ${click.target}`)
console.log(`[togglebutton]: Couldn't find button for ${click.target}`);
}
target = document.getElementById(button.dataset['button']);
target = document.getElementById(button.dataset["button"]);
toggleHidden(target);
}
};

// If we want to blanket-add toggle classes to certain cells
var addToggleToSelector = () => {
const selector = "";
if (selector.length > 0) {
document.querySelectorAll(selector).forEach((item) => {
item.classList.add("toggle");
})
});
}
}
};

// Helper function to run when the DOM is finished
const sphinxToggleRunWhenDOMLoaded = cb => {
if (document.readyState != 'loading') {
cb()
const sphinxToggleRunWhenDOMLoaded = (cb) => {
if (document.readyState != "loading") {
cb();
} else if (document.addEventListener) {
document.addEventListener('DOMContentLoaded', cb)
document.addEventListener("DOMContentLoaded", cb);
} else {
document.attachEvent('onreadystatechange', function() {
if (document.readyState == 'complete') cb()
})
document.attachEvent("onreadystatechange", function () {
if (document.readyState == "complete") cb();
});
}
}
sphinxToggleRunWhenDOMLoaded(addToggleToSelector)
sphinxToggleRunWhenDOMLoaded(initToggleItems)
};
sphinxToggleRunWhenDOMLoaded(addToggleToSelector);
sphinxToggleRunWhenDOMLoaded(initToggleItems);

/** Toggle details blocks to be open when printing */
if (toggleOpenOnPrint == "true") {
Expand All @@ -163,21 +178,23 @@ if (toggleOpenOnPrint == "true") {
el.dataset["togglestatus"] = el.open;
el.open = true;
});

// Open the admonitions
document.querySelectorAll(".admonition.toggle.toggle-hidden").forEach((el) => {
console.log(el);
el.querySelector("button.toggle-button").click();
el.dataset["toggle_after_print"] = "true";
});
document
.querySelectorAll(".admonition.toggle.toggle-hidden")
.forEach((el) => {
console.log(el);
el.querySelector("button.toggle-button").click();
el.dataset["toggle_after_print"] = "true";
});
});
window.addEventListener("afterprint", () => {
// Re-close the details that were closed
document.querySelectorAll("details.toggle-details").forEach((el) => {
el.open = el.dataset["togglestatus"] == "true";
delete el.dataset["togglestatus"];
});

// Re-close the admonition toggle buttons
document.querySelectorAll(".admonition.toggle").forEach((el) => {
if (el.dataset["toggle_after_print"] == "true") {
Expand Down

0 comments on commit 9a8272d

Please sign in to comment.