diff --git a/src/index.ts b/src/index.ts index 5164a8c..35efe6e 100644 --- a/src/index.ts +++ b/src/index.ts @@ -79,7 +79,7 @@ export default class Combobox { this.input.addEventListener('input', this.inputHandler) ;(this.input as HTMLElement).addEventListener('keydown', this.keyboardEventHandler) this.list.addEventListener('click', commitWithElement) - this.indicateDefaultOption() + this.resetSelection() } stop(): void { @@ -138,13 +138,15 @@ export default class Combobox { clearSelection(): void { this.input.removeAttribute('aria-activedescendant') - for (const el of this.list.querySelectorAll('[aria-selected="true"]')) { + for (const el of this.list.querySelectorAll('[aria-selected="true"], [data-combobox-option-default="true"]')) { el.removeAttribute('aria-selected') + el.removeAttribute('data-combobox-option-default') } + } - if (this.firstOptionSelectionMode === 'active') { - this.indicateDefaultOption() - } + resetSelection(): void { + this.clearSelection() + this.indicateDefaultOption() } } @@ -189,7 +191,7 @@ function keyboardBindings(event: KeyboardEvent, combobox: Combobox) { break default: if (event.ctrlKey) break - combobox.clearSelection() + combobox.resetSelection() } } diff --git a/test/test.js b/test/test.js index 3368cce..a39d783 100644 --- a/test/test.js +++ b/test/test.js @@ -285,6 +285,15 @@ describe('combobox-nav', function () { assert.equal(document.querySelector('[data-combobox-option-default]'), options[0]) }) + it('first item remains active when typing', () => { + const text = 'R2-D2' + for (let i = 0; i < text.length; i++) { + press(input, text[i]) + } + + assert.equal(document.querySelector('[data-combobox-option-default]'), options[0]) + }) + it('applies default option on Enter', () => { let commits = 0 document.addEventListener('combobox-commit', () => commits++) @@ -299,12 +308,18 @@ describe('combobox-nav', function () { assert.equal(document.querySelectorAll('[data-combobox-option-default]').length, 0) }) - it('resets default indication when selection cleared', () => { + it('resets default indication when selection reset', () => { combobox.navigate(1) - combobox.clearSelection() + combobox.resetSelection() assert.equal(document.querySelectorAll('[data-combobox-option-default]').length, 1) }) + it('removes default indication when selection cleared', () => { + combobox.navigate(1) + combobox.clearSelection() + assert.equal(document.querySelectorAll('[data-combobox-option-default]').length, 0) + }) + it('does not error when no options are visible', () => { assert.doesNotThrow(() => { document.getElementById('list-id').style.display = 'none' @@ -325,8 +340,6 @@ describe('combobox-nav', function () {
  • BB-8
  • Hubot
  • R2-D2
  • - -
  • Wall-E
  • Link
  • ` @@ -349,6 +362,32 @@ describe('combobox-nav', function () { assert.equal(list.children[0].getAttribute('aria-selected'), 'true') }) + it('first item remains selected when typing', () => { + const text = 'R2-D2' + for (let i = 0; i < text.length; i++) { + press(input, text[i]) + } + + assert.equal(list.children[0].getAttribute('aria-selected'), 'true') + }) + + it('pressing key down off the last item will have no items selected', () => { + // Get all visible options in the list + const options = document.querySelectorAll('[role=option]:not([aria-hidden=true])') + // Key press down for each item and ensure the next is selected + for (let i = 0; i < options.length; i++) { + if (i > 0) { + assert.equal(options[i - 1].getAttribute('aria-selected'), null) + } + + assert.equal(options[i].getAttribute('aria-selected'), 'true') + press(input, 'ArrowDown') + } + + const selected = document.querySelectorAll('[aria-selected]') + assert.equal(selected.length, 0) + }) + it('indicates first option when restarted', () => { combobox.stop() combobox.start()