Skip to content

Commit 4e76b4d

Browse files
committed
Configure: Home and End navigation
By default, continue to ignore `Home` and `End` navigation keys. When `optionalNavigationKeys: ["Home", "End"]` is passed as a configuration object, treat them as valid navigation keys.
1 parent 02edd77 commit 4e76b4d

File tree

2 files changed

+72
-9
lines changed

2 files changed

+72
-9
lines changed

src/index.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
const ctrlBindings = !!navigator.userAgent.match(/Macintosh/)
2+
type OptionalNavigationKeys = 'Home' | 'End'
23

34
export default class Combobox {
45
isComposing: boolean
@@ -7,11 +8,17 @@ export default class Combobox {
78
keyboardEventHandler: (event: KeyboardEvent) => void
89
compositionEventHandler: (event: Event) => void
910
inputHandler: (event: Event) => void
11+
optionalNavigationKeys: OptionalNavigationKeys[]
1012

11-
constructor(input: HTMLTextAreaElement | HTMLInputElement, list: HTMLElement) {
13+
constructor(
14+
input: HTMLTextAreaElement | HTMLInputElement,
15+
list: HTMLElement,
16+
options: {optionalNavigationKeys: OptionalNavigationKeys[]} = {optionalNavigationKeys: []}
17+
) {
1218
this.input = input
1319
this.list = list
1420
this.isComposing = false
21+
this.optionalNavigationKeys = options.optionalNavigationKeys
1522

1623
if (!list.id) {
1724
list.id = `combobox-${Math.random()

test/test.js

+64-8
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,6 @@ describe('combobox-nav', function() {
138138
assert.equal(options[5].getAttribute('aria-selected'), 'true')
139139
assert.equal(input.getAttribute('aria-activedescendant'), 'link')
140140

141-
press(input, 'Home')
142-
assert.equal(options[0].getAttribute('aria-selected'), 'true')
143-
assert.equal(input.getAttribute('aria-activedescendant'), 'baymax')
144-
145-
press(input, 'End')
146-
assert.equal(options[5].getAttribute('aria-selected'), 'true')
147-
assert.equal(input.getAttribute('aria-activedescendant'), 'link')
148-
149141
press(input, 'Enter')
150142
assert.equal(expectedTargets.length, 2)
151143
assert.equal(expectedTargets[0], 'hubot')
@@ -230,4 +222,68 @@ describe('combobox-nav', function() {
230222
assert.equal(list.scrollTop, 36)
231223
})
232224
})
225+
226+
describe('with Home key navigation enabled', function() {
227+
let input, list, options, combobox
228+
beforeEach(function() {
229+
document.body.innerHTML = `
230+
<input type="text">
231+
<ul role="listbox" id="list-id">
232+
<li id="baymax" role="option">Baymax</li>
233+
<li><del>BB-8</del></li>
234+
<li id="hubot" role="option">Hubot</li>
235+
<li id="r2-d2" role="option">R2-D2</li>
236+
<li id="johnny-5" hidden role="option">Johnny 5</li>
237+
<li id="wall-e" role="option" aria-disabled="true">Wall-E</li>
238+
<li><a href="#link" role="option" id="link">Link</a></li>
239+
</ul>
240+
`
241+
input = document.querySelector('input')
242+
list = document.querySelector('ul')
243+
options = document.querySelectorAll('[role=option]')
244+
combobox = new Combobox(input, list, {optionalNavigationKeys: ['Home']})
245+
combobox.start()
246+
})
247+
248+
it('updates attributes on keyboard events', function() {
249+
press(input, 'ArrowDown')
250+
press(input, 'ArrowDown')
251+
252+
assert.equal(options[1].getAttribute('aria-selected'), 'true')
253+
assert.equal(input.getAttribute('aria-activedescendant'), 'hubot')
254+
255+
press(input, 'Home')
256+
assert.equal(options[0].getAttribute('aria-selected'), 'true')
257+
assert.equal(input.getAttribute('aria-activedescendant'), 'baymax')
258+
})
259+
})
260+
261+
describe('with End key navigation enabled', function() {
262+
let input, list, options, combobox
263+
beforeEach(function() {
264+
document.body.innerHTML = `
265+
<input type="text">
266+
<ul role="listbox" id="list-id">
267+
<li id="baymax" role="option">Baymax</li>
268+
<li><del>BB-8</del></li>
269+
<li id="hubot" role="option">Hubot</li>
270+
<li id="r2-d2" role="option">R2-D2</li>
271+
<li id="johnny-5" hidden role="option">Johnny 5</li>
272+
<li id="wall-e" role="option" aria-disabled="true">Wall-E</li>
273+
<li><a href="#link" role="option" id="link">Link</a></li>
274+
</ul>
275+
`
276+
input = document.querySelector('input')
277+
list = document.querySelector('ul')
278+
options = document.querySelectorAll('[role=option]')
279+
combobox = new Combobox(input, list, {optionalNavigationKeys: ['End']})
280+
combobox.start()
281+
})
282+
283+
it('updates attributes on keyboard events', function() {
284+
press(input, 'End')
285+
assert.equal(options[5].getAttribute('aria-selected'), 'true')
286+
assert.equal(input.getAttribute('aria-activedescendant'), 'link')
287+
})
288+
})
233289
})

0 commit comments

Comments
 (0)