Skip to content

Commit e6f45b2

Browse files
committed
Focus blijft met tabben nu binnen feature modal totdat deze wordt gesloten
1 parent cb7f7af commit e6f45b2

2 files changed

Lines changed: 33 additions & 4 deletions

File tree

plugins/gh-datainmap/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
- Focus blijft met tabben nu binnen feature modal totdat deze wordt gesloten.
12
- Zoomknoppen zijn nu voorzien van een `aria-label`.
23
- Het overzicht met layers geeft nu ook het type en de transparantie aan.
34
- Opmaak standaard stylesheet aangepast, deze voldeed niet en liet niet alle elementen goed zien. Door nu een goede basis te bieden moet het eenvoudiger zijn om in een eigen stylesheet enkel aanpassingen door te voeren. Al wordt het nog steeds aangeraden om een eigen stylesheet te gebruiken. Zie de broncode voor een voorbeeld.

src/components/feature.js

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ class KMLFeatureComponent extends Component {
4242
<h1>{feature.name}</h1>
4343
<CloseModal onClick={() => this.props.closeModal()} />
4444
</header>
45-
<section className="gh-dim-feature-content" dangerouslySetInnerHTML={{__html: feature.description}} />
45+
<section className="gh-dim-feature-content" dangerouslySetInnerHTML={{__html: feature.description}} tabIndex="0" />
4646
</>
4747
)
4848
}
@@ -61,7 +61,7 @@ class WMSFeatureComponent extends Component {
6161
<h1>Informatie</h1>
6262
<CloseModal onClick={() => this.props.closeModal()} />
6363
</header>
64-
<section className="gh-dim-feature-content" dangerouslySetInnerHTML={{__html: feature}} />
64+
<section className="gh-dim-feature-content" dangerouslySetInnerHTML={{__html: feature}} tabIndex="0" />
6565
</>
6666
)
6767
}
@@ -86,7 +86,7 @@ class DIMFeatureComponent extends Component {
8686
<h1 dangerouslySetInnerHTML={{__html: title}}></h1>
8787
<CloseModal onClick={() => this.props.closeModal()} />
8888
</header>
89-
<section className="gh-dim-feature-content" dangerouslySetInnerHTML={{__html: feature.content}} />
89+
<section className="gh-dim-feature-content" dangerouslySetInnerHTML={{__html: feature.content}} tabIndex="0" />
9090
</>
9191
);
9292
}
@@ -95,11 +95,37 @@ class DIMFeatureComponent extends Component {
9595
export default class FeatureComponent extends Component {
9696
constructor(props) {
9797
super(props);
98+
this.refModal = React.createRef();
9899
this.closeModalWithEscape = (e) => {
99100
if(e.key === 'Escape') {
100101
this.closeModal();
101102
}
102103
};
104+
this.trapFocusInsideModal = (e) => {
105+
// Based on https://gist.github.com/myogeshchavan97/d50d42aa9205573b811587d57c2e58a6#file-trap_focus-js
106+
const focusableElements = 'button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])';
107+
const modal = this.refModal.current;
108+
const firstFocusableElement = modal.querySelectorAll(focusableElements)[0]; // get first element to be focused inside modal
109+
const focusableContent = modal.querySelectorAll(focusableElements);
110+
const lastFocusableElement = focusableContent[focusableContent.length - 1]; // get last element to be focused inside modal
111+
const isTabPressed = e.key === 'Tab' || e.keyCode === 9;
112+
if(!isTabPressed) {
113+
return;
114+
}
115+
116+
if(e.shiftKey) { // if shift key pressed for shift + tab combination
117+
if(document.activeElement === firstFocusableElement) {
118+
lastFocusableElement.focus(); // add focus for the last focusable element
119+
e.preventDefault();
120+
}
121+
}
122+
else { // if tab key is pressed
123+
if(document.activeElement === lastFocusableElement) { // if focused has reached to last focusable element then focus first focusable element after pressing tab
124+
firstFocusableElement.focus(); // add focus for the first focusable element
125+
e.preventDefault();
126+
}
127+
}
128+
};
103129
}
104130

105131
closeModal() {
@@ -120,9 +146,11 @@ export default class FeatureComponent extends Component {
120146
// Close modal when Escape is pressed
121147
if(this.props.feature !== null) {
122148
document.addEventListener('keydown', this.closeModalWithEscape);
149+
document.addEventListener('keydown', this.trapFocusInsideModal);
123150
}
124151
else {
125152
document.removeEventListener('keydown', this.closeModalWithEscape);
153+
document.removeEventListener('keydown', this.trapFocusInsideModal);
126154
}
127155
}
128156

@@ -152,7 +180,7 @@ export default class FeatureComponent extends Component {
152180
timeout={400}
153181
unmountOnExit
154182
classNames="transition">
155-
<div className="gh-dim-feature-modal" onClick={(e) => this.closeModal()}>
183+
<div className="gh-dim-feature-modal" onClick={(e) => this.closeModal()} ref={this.refModal} tabIndex="0">
156184
{ /* Prevent a click event on the article element to close the modal */ }
157185
<article className="gh-dim-feature" onClick={e => e.stopPropagation() }>
158186
{content}

0 commit comments

Comments
 (0)