Initial attempt at accessibly announcing route updates.

* Add handler for `phx:page-loading-stop` that focuses either the first `<h1>` child of `<main>`, or `<main>` directly if no child `<h1>` is present. Make this our focus target.
* Cache original `tabindex` of target, if any, and assign it a temporary `tabindex1 of -1.
* Focus the target.
* After a long timeout, either restore the target's original `tabindex` or remove the temporary -1 value. Short timeouts didn't seem to perform the focus step. Neither did nested `requestAnimationFrame` calls.
This commit is contained in:
Nolan Darilek 2021-11-22 15:25:41 -06:00
parent 7096b98cc2
commit 566a574c0a

View file

@ -177,11 +177,30 @@ let liveSocket = new LiveSocket("/live", Socket, {
params: {_csrf_token: csrfToken}
})
let routeUpdated = () => {
let target = document.querySelector("main h1") || document.querySelector("main")
if (target) {
let origTabIndex = target.getAttribute("tabindex")
target.setAttribute("tabindex", "-1")
target.focus()
window.setTimeout(() => {
if (origTabIndex) {
target.setAttribute("tabindex", origTabIndex)
} else {
target.removeAttribute("tabindex")
}
}, 1000)
}
}
// Show progress bar on live navigation and form submits
topbar.config({barColors: {0: "#29d"}, shadowColor: "rgba(0, 0, 0, .3)"})
window.addEventListener("phx:page-loading-start", info => topbar.show())
window.addEventListener("phx:page-loading-stop", info => topbar.hide())
// Accessible routing
window.addEventListener("phx:page-loading-stop", () => window.requestAnimationFrame(routeUpdated))
window.addEventListener("js:exec", e => e.target[e.detail.call](...e.detail.args))
// connect if there are any LiveViews on the page