Skip to content
This repository was archived by the owner on Sep 22, 2022. It is now read-only.

Commit a2b9ecc

Browse files
authored
Merge pull request #49 from github/shiftTab
Fix shift tab when currentIndex is 0 or -1
2 parents 6a07747 + 66c9d4a commit a2b9ecc

File tree

2 files changed

+35
-24
lines changed

2 files changed

+35
-24
lines changed

index.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,22 @@ function restrictTabBehavior(event: KeyboardEvent): void {
4949
if (elements.length === 0) return
5050

5151
const movement = event.shiftKey ? -1 : 1
52-
const currentFocus = elements.filter(el => el.matches(':focus'))[0]
53-
let targetIndex = 0
52+
const currentFocus = dialog.contains(document.activeElement) ? document.activeElement : null
53+
let targetIndex = movement === -1 ? -1 : 0
5454

5555
if (currentFocus) {
5656
const currentIndex = elements.indexOf(currentFocus)
5757
if (currentIndex !== -1) {
58-
const newIndex = currentIndex + movement
59-
if (newIndex >= 0) targetIndex = newIndex % elements.length
58+
targetIndex = currentIndex + movement
6059
}
6160
}
6261

62+
if (targetIndex < 0) {
63+
targetIndex = elements.length - 1
64+
} else {
65+
targetIndex = targetIndex % elements.length
66+
}
67+
6368
elements[targetIndex].focus()
6469
}
6570

test/test.js

+26-20
Original file line numberDiff line numberDiff line change
@@ -81,17 +81,19 @@ describe('details-dialog-element', function() {
8181
dialog.toggle(true)
8282
await waitForToggleEvent(details)
8383
assert(details.open)
84-
pressEscape(details)
84+
triggerKeydownEvent(details, 'Escape')
8585
assert(!details.open)
8686
})
8787

8888
it('manages focus', async function() {
8989
summary.click()
9090
await waitForToggleEvent(details)
9191
assert.equal(document.activeElement, dialog)
92-
pressTab(details)
92+
triggerKeydownEvent(details, 'Tab', true)
93+
assert.equal(document.activeElement, document.querySelector(`[${CLOSE_ATTR}]`))
94+
triggerKeydownEvent(details, 'Tab')
9395
assert.equal(document.activeElement, document.querySelector(`[data-button]`))
94-
pressTab(details)
96+
triggerKeydownEvent(details, 'Tab')
9597
assert.equal(document.activeElement, document.querySelector(`[${CLOSE_ATTR}]`))
9698
})
9799

@@ -122,7 +124,7 @@ describe('details-dialog-element', function() {
122124
assert(details.open)
123125
assert.equal(closeRequestCount, 2)
124126

125-
pressEscape(details)
127+
triggerKeydownEvent(details, 'Escape')
126128
assert(details.open)
127129
assert.equal(closeRequestCount, 3)
128130

@@ -163,7 +165,7 @@ describe('details-dialog-element', function() {
163165
assert(details.open)
164166
assert.equal(closeRequestCount, 1)
165167

166-
pressEscape(details)
168+
triggerKeydownEvent(details, 'Escape')
167169
assert(details.open)
168170
assert.equal(closeRequestCount, 2)
169171

@@ -197,7 +199,7 @@ describe('details-dialog-element', function() {
197199
dialog.toggle(true)
198200
await waitForToggleEvent(details)
199201
assert(details.open)
200-
pressEscape(details)
202+
triggerKeydownEvent(details, 'Escape')
201203
assert(!details.open)
202204
})
203205
})
@@ -230,7 +232,7 @@ describe('details-dialog-element', function() {
230232
dialog.preload = true
231233
assert(dialog.hasAttribute('preload'))
232234
assert.notOk(includeFragment.getAttribute('src'))
233-
triggerEvent(details, 'mouseover')
235+
triggerMouseoverEvent(details)
234236
assert.equal(includeFragment.getAttribute('src'), '/404')
235237
})
236238
})
@@ -260,7 +262,7 @@ describe('details-dialog-element', function() {
260262
it('transfers src on mouseover', async function() {
261263
assert(!details.open)
262264
assert.notOk(includeFragment.getAttribute('src'))
263-
triggerEvent(details, 'mouseover')
265+
triggerMouseoverEvent(details)
264266
assert.equal(includeFragment.getAttribute('src'), '/404')
265267
})
266268
})
@@ -279,17 +281,21 @@ function waitForToggleEvent(details) {
279281
})
280282
}
281283

282-
function triggerEvent(element, name, key) {
283-
const event = document.createEvent('Event')
284-
event.initEvent(name, true, true)
285-
if (key) event.key = key
286-
element.dispatchEvent(event)
287-
}
288-
289-
function pressEscape(details) {
290-
triggerEvent(details, 'keydown', 'Escape')
284+
function triggerMouseoverEvent(element) {
285+
element.dispatchEvent(
286+
new MouseEvent('mouseover', {
287+
bubbles: true,
288+
cancelable: true
289+
})
290+
)
291291
}
292-
293-
function pressTab(details) {
294-
triggerEvent(details, 'keydown', 'Tab')
292+
function triggerKeydownEvent(element, key, shiftKey) {
293+
element.dispatchEvent(
294+
new KeyboardEvent('keydown', {
295+
bubbles: true,
296+
cancelable: true,
297+
key,
298+
shiftKey
299+
})
300+
)
295301
}

0 commit comments

Comments
 (0)