From c6b6ff4050b7dd15e9b1dd6d88a0d1733f1e6bc9 Mon Sep 17 00:00:00 2001 From: "oumaima.naoui.e" Date: Tue, 18 Nov 2025 14:48:57 +0100 Subject: [PATCH] Add onkeydown event handler to DsfrSearchCmp , DsfrHeaderCmp and DsfrCardTileListCmp --- .../lwc/dsfrHeaderCmp/dsfrHeaderCmp.js | 33 ++++++++++++++- .../dsfrCardTileListCmp.js | 27 +++++++++++- .../lwc/dsfrSearchCmp/dsfrSearchCmp.js | 42 +++++++++++++++---- 3 files changed, 91 insertions(+), 11 deletions(-) diff --git a/force-app/main/default/lwc/dsfrHeaderCmp/dsfrHeaderCmp.js b/force-app/main/default/lwc/dsfrHeaderCmp/dsfrHeaderCmp.js index 52ace12..ca01f80 100644 --- a/force-app/main/default/lwc/dsfrHeaderCmp/dsfrHeaderCmp.js +++ b/force-app/main/default/lwc/dsfrHeaderCmp/dsfrHeaderCmp.js @@ -74,6 +74,7 @@ export default class DsfrHeaderCmp extends NavigationMixin(LightningElement) { mainMenuItems; complexMenuItems; currentIndex = -1; + openAccordion = null; // Track the currently open accordion //----------------------------------- // Custom Labels @@ -682,8 +683,7 @@ export default class DsfrHeaderCmp extends NavigationMixin(LightningElement) { if (currentStatus == "true") { if (this.isDebug) console.log('toggleMenu: collapsing menu'); - currentMenu.classList?.remove("fr-collapse--expanded"); - event.target.ariaExpanded = "false"; + this.closeList(currentTargetId); } else { if (this.isDebug) console.log('toggleMenu: collapsing previous menu (if any)'); @@ -691,11 +691,40 @@ export default class DsfrHeaderCmp extends NavigationMixin(LightningElement) { if (this.isDebug) console.log('toggleMenu: expanding new menu'); currentMenu.classList.add("fr-collapse--expanded"); event.target.ariaExpanded = "true"; + this.openAccordion = currentTargetId; + document.addEventListener('keydown',this.handleEscape, false); } if (this.isDebug) console.log('toggleMenu: END for Header'); } + handleEscape = event => { + if (this.isDebug) console.log('handleEscape: START'); + if (event?.key === 'Escape') { + this.closeList(this.openAccordion); + } + else { + if (this.isDebug) console.log('handleEscape: END / ignoring key ',event.key); + } + } + + closeList(currentTarget){ + const currentMenu = this.template.querySelector("div.fr-collapse[id='" + currentTarget + "']") + || this.template.querySelector("div.fr-collapse[data-name='" + currentTarget + "']"); + const buttonTarget = this.template.querySelector("button[value='" + currentTarget + "']"); + + if (this.isDebug) console.log('closeList: currentMenu ',currentMenu); + if (this.isDebug) console.log('closeList: currentTarget ',buttonTarget); + + if (this.isDebug) console.log('closeList: collapsing menu'); + currentMenu.classList?.remove("fr-collapse--expanded"); + if (buttonTarget) { + buttonTarget.ariaExpanded = "false"; + } + this.openAccordion = null; + document.removeEventListener('keydown',this.handleEscape); + } + //---------------------------------------------------------------- // Utilities //---------------------------------------------------------------- diff --git a/force-app/main/extensions/lwc/dsfrCardTileListCmp/dsfrCardTileListCmp.js b/force-app/main/extensions/lwc/dsfrCardTileListCmp/dsfrCardTileListCmp.js index d6d9fdf..95699d0 100644 --- a/force-app/main/extensions/lwc/dsfrCardTileListCmp/dsfrCardTileListCmp.js +++ b/force-app/main/extensions/lwc/dsfrCardTileListCmp/dsfrCardTileListCmp.js @@ -529,13 +529,13 @@ export default class DsfrCardTileListCmp extends LightningElement { if (this.isDebug) console.log('toggleSort: current Menu classList ',sortMenu.classList); if (sortMenu.classList.contains('fr-collapse--expanded')) { if (this.isDebug) console.log('toggleSort: closing menu'); - sortMenu.classList.remove('fr-collapse--expanded'); - sortButton.setAttribute('aria-expanded',false); + this.closeList(); } else { if (this.isDebug) console.log('toggleSort: opening menu'); sortMenu.classList.add('fr-collapse--expanded'); sortButton.setAttribute('aria-expanded',true); + document.addEventListener('keydown',this.handleEscape, false); } if (this.isDebug) console.log('toggleSort: Menu classList updated ',sortMenu.classList); } @@ -543,6 +543,29 @@ export default class DsfrCardTileListCmp extends LightningElement { if (this.isDebug) console.log('toggleSort: END for card/tile list'); } + handleEscape = event => { + if (this.isDebug) console.log('handleEscape: START'); + if (event?.key === 'Escape') { + this.closeList(); + } + else { + if (this.isDebug) console.log('handleEscape: END / ignoring key ',event.key); + } + } + + closeList(){ + const sortMenu = this.refs.sortMenu; + if (this.isDebug) console.log('closeList: sortMenu found ',sortMenu); + const sortButton = this.refs.sortButton; + if (this.isDebug) console.log('closeList: sortButton found ',sortButton); + + if (this.isDebug) console.log('closeList: closing menu'); + sortMenu.classList.remove('fr-collapse--expanded'); + sortButton.setAttribute('aria-expanded',false); + + document.removeEventListener('keydown',this.handleEscape); + } + selectSort(event){ if (this.isDebug) console.log('selectSort: START for card/tile list',event); event.stopPropagation(); diff --git a/force-app/main/extensions/lwc/dsfrSearchCmp/dsfrSearchCmp.js b/force-app/main/extensions/lwc/dsfrSearchCmp/dsfrSearchCmp.js index 2c1ad10..ca0a2a2 100644 --- a/force-app/main/extensions/lwc/dsfrSearchCmp/dsfrSearchCmp.js +++ b/force-app/main/extensions/lwc/dsfrSearchCmp/dsfrSearchCmp.js @@ -45,6 +45,8 @@ export default class DsfrSearchCmp extends NavigationMixin(LightningElement) { criteriaList; // additional criteria values criteriaSelected; // list of selected additional criteria + openAccordion = null; // Track the currently open accordion + isReady = false; //----------------------------------------------------- @@ -259,23 +261,49 @@ export default class DsfrSearchCmp extends NavigationMixin(LightningElement) { let currentStatus = event.target?.ariaExpanded; if (this.isDebug) console.log('expandCollapse: current status fetched ', currentStatus); - let currentSection = this.template.querySelector("div.fr-collapse[data-name='" + currentTarget + "']"); - if (this.isDebug) console.log('expandCollapse: current section fetched ', currentSection); - - if (currentStatus == "true") { - if (this.isDebug) console.log('expandCollapse: collapsing section'); - currentSection.classList?.remove("fr-collapse--expanded"); - event.target.ariaExpanded = "false"; + if (currentStatus == "true" && currentTarget) { + this.closeList(currentTarget); } else { + let currentSection = this.template.querySelector("div.fr-collapse[data-name='" + currentTarget + "']"); + if (this.isDebug) console.log('expandCollapse: current section fetched ', currentSection); if (this.isDebug) console.log('expandCollapse: expanding section'); currentSection.classList.add("fr-collapse--expanded"); event.target.ariaExpanded = "true"; + this.openAccordion = currentTarget; + + document.addEventListener('keydown',this.handleEscape, false); } if (this.isDebug) console.log('expandCollapse: END'); } + handleEscape = event => { + if (this.isDebug) console.log('handleEscape: START'); + if (event?.key === 'Escape' && this.openAccordion) { + this.closeList(this.openAccordion); + } + else { + if (this.isDebug) console.log('handleEscape: END / ignoring key ',event.key); + } + } + + closeList(currentTarget){ + const currentSection = this.template.querySelector("div.fr-collapse[data-name='" + currentTarget + "']"); + const buttonTarget = this.template.querySelector("button[value='" + currentTarget + "']"); + + if (this.isDebug) console.log('closeList: currentSection ',currentSection); + if (this.isDebug) console.log('closeList: currentTarget ',buttonTarget); + + if (this.isDebug) console.log('closeList: collapsing section'); + currentSection.classList?.remove("fr-collapse--expanded"); + if (buttonTarget) { + buttonTarget.ariaExpanded = "false"; + } + this.openAccordion = null; + document.removeEventListener('keydown',this.handleEscape); + } + // Search term input events handleInputLeave(event){ if (this.isDebug) console.log('handleInputLeave: START for search with term ',this.searchTerm);