Skip to content

Commit

Permalink
Configure: Home and End navigation
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
seanpdoyle committed Aug 2, 2022
1 parent 02edd77 commit 4e76b4d
Show file tree
Hide file tree
Showing 2 changed files with 72 additions and 9 deletions.
9 changes: 8 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const ctrlBindings = !!navigator.userAgent.match(/Macintosh/)
type OptionalNavigationKeys = 'Home' | 'End'

export default class Combobox {
isComposing: boolean
Expand All @@ -7,11 +8,17 @@ export default class Combobox {
keyboardEventHandler: (event: KeyboardEvent) => void
compositionEventHandler: (event: Event) => void
inputHandler: (event: Event) => void
optionalNavigationKeys: OptionalNavigationKeys[]

constructor(input: HTMLTextAreaElement | HTMLInputElement, list: HTMLElement) {
constructor(
input: HTMLTextAreaElement | HTMLInputElement,
list: HTMLElement,
options: {optionalNavigationKeys: OptionalNavigationKeys[]} = {optionalNavigationKeys: []}
) {
this.input = input
this.list = list
this.isComposing = false
this.optionalNavigationKeys = options.optionalNavigationKeys

if (!list.id) {
list.id = `combobox-${Math.random()
Expand Down
72 changes: 64 additions & 8 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,14 +138,6 @@ describe('combobox-nav', function() {
assert.equal(options[5].getAttribute('aria-selected'), 'true')
assert.equal(input.getAttribute('aria-activedescendant'), 'link')

press(input, 'Home')
assert.equal(options[0].getAttribute('aria-selected'), 'true')
assert.equal(input.getAttribute('aria-activedescendant'), 'baymax')

press(input, 'End')
assert.equal(options[5].getAttribute('aria-selected'), 'true')
assert.equal(input.getAttribute('aria-activedescendant'), 'link')

press(input, 'Enter')
assert.equal(expectedTargets.length, 2)
assert.equal(expectedTargets[0], 'hubot')
Expand Down Expand Up @@ -230,4 +222,68 @@ describe('combobox-nav', function() {
assert.equal(list.scrollTop, 36)
})
})

describe('with Home key navigation enabled', function() {
let input, list, options, combobox
beforeEach(function() {
document.body.innerHTML = `
<input type="text">
<ul role="listbox" id="list-id">
<li id="baymax" role="option">Baymax</li>
<li><del>BB-8</del></li>
<li id="hubot" role="option">Hubot</li>
<li id="r2-d2" role="option">R2-D2</li>
<li id="johnny-5" hidden role="option">Johnny 5</li>
<li id="wall-e" role="option" aria-disabled="true">Wall-E</li>
<li><a href="#link" role="option" id="link">Link</a></li>
</ul>
`
input = document.querySelector('input')
list = document.querySelector('ul')
options = document.querySelectorAll('[role=option]')
combobox = new Combobox(input, list, {optionalNavigationKeys: ['Home']})
combobox.start()
})

it('updates attributes on keyboard events', function() {
press(input, 'ArrowDown')
press(input, 'ArrowDown')

assert.equal(options[1].getAttribute('aria-selected'), 'true')
assert.equal(input.getAttribute('aria-activedescendant'), 'hubot')

press(input, 'Home')
assert.equal(options[0].getAttribute('aria-selected'), 'true')
assert.equal(input.getAttribute('aria-activedescendant'), 'baymax')
})
})

describe('with End key navigation enabled', function() {
let input, list, options, combobox
beforeEach(function() {
document.body.innerHTML = `
<input type="text">
<ul role="listbox" id="list-id">
<li id="baymax" role="option">Baymax</li>
<li><del>BB-8</del></li>
<li id="hubot" role="option">Hubot</li>
<li id="r2-d2" role="option">R2-D2</li>
<li id="johnny-5" hidden role="option">Johnny 5</li>
<li id="wall-e" role="option" aria-disabled="true">Wall-E</li>
<li><a href="#link" role="option" id="link">Link</a></li>
</ul>
`
input = document.querySelector('input')
list = document.querySelector('ul')
options = document.querySelectorAll('[role=option]')
combobox = new Combobox(input, list, {optionalNavigationKeys: ['End']})
combobox.start()
})

it('updates attributes on keyboard events', function() {
press(input, 'End')
assert.equal(options[5].getAttribute('aria-selected'), 'true')
assert.equal(input.getAttribute('aria-activedescendant'), 'link')
})
})
})

0 comments on commit 4e76b4d

Please sign in to comment.