gaufre: follow disclosure aria pattern
- add aria attributes on load with the gaufre api script so that people already using la gaufre don't necessarely *have* to update their code - add the aria patterns in given code examples/react components. In some cases, our small page load JS code isn't enough: for example on SPAs where gaufre buttons might be loaded after page load. thanks @inseo
This commit is contained in:
@@ -23,6 +23,8 @@ export const Gaufre = ({ variant }: Props) => {
|
|||||||
type="button"
|
type="button"
|
||||||
className={`lasuite-gaufre-btn ${variantClass} lasuite-gaufre-btn--vanilla js-lasuite-gaufre-btn`}
|
className={`lasuite-gaufre-btn ${variantClass} lasuite-gaufre-btn--vanilla js-lasuite-gaufre-btn`}
|
||||||
title={t("gaufre.label")}
|
title={t("gaufre.label")}
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls="lasuite-gaufre-popup"
|
||||||
>
|
>
|
||||||
{t("gaufre.label")}
|
{t("gaufre.label")}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
;(function () {
|
;(function () {
|
||||||
const BUTTON_CLASS = "js-lasuite-gaufre-btn"
|
const BUTTON_CLASS = "js-lasuite-gaufre-btn"
|
||||||
|
const POPUP_ID = "lasuite-gaufre-popup"
|
||||||
const DIMENSIONS = { width: 304, height: 352, margin: 8 }
|
const DIMENSIONS = { width: 304, height: 352, margin: 8 }
|
||||||
|
|
||||||
let lastFocusedButton = null
|
let lastFocusedButton = null
|
||||||
@@ -9,13 +10,20 @@
|
|||||||
if ("requestIdleCallback" in window) {
|
if ("requestIdleCallback" in window) {
|
||||||
requestIdleCallback(() => {
|
requestIdleCallback(() => {
|
||||||
appendPopup()
|
appendPopup()
|
||||||
|
enhanceButtonsA11y()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const enhanceButtonsA11y = () => {
|
||||||
|
const buttons = document.querySelectorAll(`.${BUTTON_CLASS}`)
|
||||||
|
buttons.forEach((b) => {
|
||||||
|
b.setAttribute("aria-controls", POPUP_ID)
|
||||||
|
b.setAttribute("aria-expanded", "false")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
document.body.addEventListener("click", (event) => {
|
document.body.addEventListener("click", (event) => {
|
||||||
if (!event.target.classList || !event.target.classList.contains(BUTTON_CLASS)) {
|
if (!event.target.classList || !event.target.classList.contains(BUTTON_CLASS)) {
|
||||||
const buttons = document.querySelectorAll(`.${BUTTON_CLASS}`)
|
|
||||||
buttons.forEach((b) => b.classList.remove("lasuite--gaufre-opened"))
|
|
||||||
hidePopup()
|
hidePopup()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -36,7 +44,7 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
window.addEventListener("resize", () => {
|
window.addEventListener("resize", () => {
|
||||||
const popup = document.querySelector(`#lasuite-gaufre-popup.lasuite--gaufre-opened`)
|
const popup = document.querySelector(`#${POPUP_ID}.lasuite--gaufre-opened`)
|
||||||
if (!popup) {
|
if (!popup) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -48,8 +56,8 @@
|
|||||||
})
|
})
|
||||||
|
|
||||||
const appendPopup = () => {
|
const appendPopup = () => {
|
||||||
if (document.querySelector(`#lasuite-gaufre-popup`)) {
|
if (document.getElementById(POPUP_ID)) {
|
||||||
return Promise.resolve(document.querySelector(`#lasuite-gaufre-popup`))
|
return Promise.resolve(document.getElementById(POPUP_ID))
|
||||||
}
|
}
|
||||||
const scriptTag = document.querySelector(`#lasuite-gaufre-script`)
|
const scriptTag = document.querySelector(`#lasuite-gaufre-script`)
|
||||||
if (!scriptTag) {
|
if (!scriptTag) {
|
||||||
@@ -59,7 +67,7 @@
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
const popup = document.createElement("div")
|
const popup = document.createElement("div")
|
||||||
popup.id = "lasuite-gaufre-popup"
|
popup.id = POPUP_ID
|
||||||
popup.style.cssText = "display: none !important"
|
popup.style.cssText = "display: none !important"
|
||||||
|
|
||||||
const { host, protocol, searchParams, origin } = new URL(scriptTag.src)
|
const { host, protocol, searchParams, origin } = new URL(scriptTag.src)
|
||||||
@@ -183,10 +191,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const showPopup = (button) => {
|
const showPopup = (button) => {
|
||||||
let popup = document.querySelector(`#lasuite-gaufre-popup`)
|
let popup = document.getElementById(POPUP_ID)
|
||||||
const show = (el) => {
|
const show = (el) => {
|
||||||
updatePopupStyle(el, button)
|
updatePopupStyle(el, button)
|
||||||
el.classList.add("lasuite--gaufre-opened")
|
el.classList.add("lasuite--gaufre-opened")
|
||||||
|
button.setAttribute("aria-expanded", "true")
|
||||||
lastFocusedButton = button
|
lastFocusedButton = button
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
el.querySelector(".js-lagaufre-keyboard-anchor").focus()
|
el.querySelector(".js-lagaufre-keyboard-anchor").focus()
|
||||||
@@ -200,13 +209,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
const hidePopup = () => {
|
const hidePopup = () => {
|
||||||
const popup = document.querySelector(`#lasuite-gaufre-popup`)
|
const popup = document.getElementById(POPUP_ID)
|
||||||
if (popup) {
|
if (popup) {
|
||||||
popup.style.cssText = "display: none !important"
|
popup.style.cssText = "display: none !important"
|
||||||
popup.classList.remove("lasuite--gaufre-opened")
|
popup.classList.remove("lasuite--gaufre-opened")
|
||||||
}
|
}
|
||||||
|
document.querySelectorAll(`.${BUTTON_CLASS}`).forEach((b) => {
|
||||||
|
b.classList.remove("lasuite--gaufre-opened")
|
||||||
|
b.setAttribute("aria-expanded", "false")
|
||||||
|
})
|
||||||
if (lastFocusedButton) {
|
if (lastFocusedButton) {
|
||||||
lastFocusedButton.classList.remove("lasuite--gaufre-opened")
|
|
||||||
lastFocusedButton.focus()
|
lastFocusedButton.focus()
|
||||||
lastFocusedButton = null
|
lastFocusedButton = null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,6 +62,8 @@ import gaufreCssUrl from "@gouvfr-lasuite/integration/dist/css/gaufre.css?url"
|
|||||||
type="button"
|
type="button"
|
||||||
class="lasuite-gaufre-btn lasuite-gaufre-btn--vanilla js-lasuite-gaufre-btn"
|
class="lasuite-gaufre-btn lasuite-gaufre-btn--vanilla js-lasuite-gaufre-btn"
|
||||||
title="Les services de La Suite numérique"
|
title="Les services de La Suite numérique"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls="lasuite-gaufre-popup"
|
||||||
>
|
>
|
||||||
Les services de La Suite numérique
|
Les services de La Suite numérique
|
||||||
</button>
|
</button>
|
||||||
@@ -71,6 +73,8 @@ import gaufreCssUrl from "@gouvfr-lasuite/integration/dist/css/gaufre.css?url"
|
|||||||
type="button"
|
type="button"
|
||||||
class="lasuite-gaufre-btn lasuite-gaufre-btn--vanilla js-lasuite-gaufre-btn"
|
class="lasuite-gaufre-btn lasuite-gaufre-btn--vanilla js-lasuite-gaufre-btn"
|
||||||
title="Les services de La Suite numérique"
|
title="Les services de La Suite numérique"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls="lasuite-gaufre-popup"
|
||||||
>
|
>
|
||||||
Les services de La Suite numérique
|
Les services de La Suite numérique
|
||||||
</button>
|
</button>
|
||||||
@@ -108,6 +112,8 @@ import gaufreCssUrl from "@gouvfr-lasuite/integration/dist/css/gaufre.css?url"
|
|||||||
type="button"
|
type="button"
|
||||||
class="lasuite-gaufre-btn lasuite-gaufre-btn--vanilla js-lasuite-gaufre-btn"
|
class="lasuite-gaufre-btn lasuite-gaufre-btn--vanilla js-lasuite-gaufre-btn"
|
||||||
title="Les services de La Suite numérique"
|
title="Les services de La Suite numérique"
|
||||||
|
aria-expanded="false"
|
||||||
|
aria-controls="lasuite-gaufre-popup"
|
||||||
>
|
>
|
||||||
Les services de La Suite numérique
|
Les services de La Suite numérique
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user