Skip to content

🐛 fix(disclosure): corrige le retour du focus - #1543

Open
keryanS wants to merge 1 commit into
mainfrom
fix/accordion-focus
Open

keryanS wants to merge 1 commit into
mainfrom
fix/accordion-focus

Conversation

@keryanS

@keryanS keryanS commented Sep 30, 2026

Copy link
Copy Markdown
Contributor

#1505
Corrige la gestion du focus à la fermeture des disclosures, notamment lorsqu’un accordéon est ouvert au chargement. Sa fermeture pouvait renvoyer le focus au logo et provoquer une erreur si le JavaScript du header n’était pas chargé.

  • Mutualise la focalisation explicite du bouton activé et la mémorisation des déclencheurs extérieurs dans DisclosureButton, y compris pour les navigateurs qui ne focalisent pas les boutons au clic.
  • Les collapses conservent le focus extérieur, notamment sur un bouton « fermer tous ». Si le focus est dans le contenu masqué, il revient au bouton principal ; sans focus actif, il revient à la cible mémorisée ou au logo.
  • Les modales conservent la restauration du focus précédant leur ouverture. Leur bouton de fermeture interne ne remplace pas cette cible.
  • Protège le retour au logo lorsque le composant header n’est pas chargé et supprime la gestion du clic devenue redondante dans les onglets.

@keryanS keryanS self-assigned this Sep 30, 2026
@keryanS
keryanS requested a balanced review from Copilot September 30, 2026 13:08
@keryanS keryanS added correctif Quelque chose ne fonctionne pas à valider maj 1.15.0 labels Sep 30, 2026
@keryanS keryanS added this to the 1.15.4 milestone Sep 30, 2026

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🔵 Needs a closer look

It refactors core focus handling across disclosure, collapse, modal, tab, and navigation components with cross-component side effects and no JS unit tests, plus a flagged preventFocus behavior divergence, so it warrants human verification.

Review effort: Balanced
Findings: 1 Medium severity

Open (1)
What changed in this PR

This PR fixes focus management when disclosures (accordions/collapses, modals, tabs) are closed, addressing issue #1505 where opening an accordion that is initially expanded (aria-expanded="true") and then closing it could lose focus or send it to the header logo — and could throw when the header JS was not loaded. It centralizes the "focus the activated button + memorize the outside trigger" logic in DisclosureButton, and lets each component decide where focus should return on close.

Changes:

  • Move explicit button focus + trigger memorization (retainFocus) into DisclosureButton.handleClick, and add a default focus() that focuses the primary button; remove the now-redundant retainFocus from base disclose and the redundant handleClick/focus in TabButton.
  • Rework Collapse.conceal to return focus to the main button when focus was inside the hidden content, or to the memorized trigger/logo when there is no active focus.
  • Make modals memorize/restore the pre-open focus (their internal close button no longer overwrites the target), and guard FocusManager.focusOnLogo when the header component is not loaded; fix a doc typo in fieldset.ejs.
File Description
src/​dsfr/​core/​script/​disclosure/​disclosure.js Adds _focusIndex default, removes retainFocus from disclose, and makes focus() target the primary button.
src/​dsfr/​core/​script/​disclosure/​disclosure-button.js handleClick now focuses the button, memorizes external triggers, then toggles.
src/​dsfr/​core/​script/​collapse/​collapse.js conceal restores focus based on where focus currently is; potential preventFocus default divergence flagged.
src/​dsfr/​core/​script/​api/​modules/​register/​focus-manager.js Guards focusOnLogo when api.header is unavailable.
src/​dsfr/​component/​tab/​script/​tab/​tab-button.js Removes redundant handleClick override now handled by the base class.
src/​dsfr/​component/​modal/​script/​modal/​modal.js Memorizes focus on disclose and overrides focus() to restore it.
src/​dsfr/​component/​form/​template/​ejs/​fieldset/​fieldset.ejs Fixes doc typo massages → messages.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

const activeElement = document.activeElement;
const shouldFocus = this.node.contains(activeElement);
const hasNoFocus = !activeElement || activeElement === document.body || activeElement === document.documentElement;
if (!super.conceal(withhold, true) || preventFocus === true) return;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

correctif Quelque chose ne fonctionne pas maj 1.15.0 à valider

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Accessibilité] Perte de focus lors du premier clic sur l'accordeon lorsque isExpanded = true

2 participants