diff --git a/src/components/Select.vue b/src/components/Select.vue index e290ede..18a0edb 100644 --- a/src/components/Select.vue +++ b/src/components/Select.vue @@ -302,6 +302,7 @@ /** * Select the current value if selectOnTab is enabled + * @deprecated */ onTab: { type: Function, @@ -449,12 +450,22 @@ /** * When true, hitting the 'tab' key will select the current select value * @type {Boolean} + * @deprecated */ selectOnTab: { type: Boolean, default: false }, + /** + * Keycodes that will select the current option. + * @type Array + */ + selectOnKeyCodes: { + type: Array, + default: () => [13], + }, + /** * Query Selector used to find the search input * when the 'search' scoped slot is used. @@ -860,16 +871,16 @@ * @return {Function} */ onSearchKeyDown (e) { - const handlers = this.mapKeydown({ + const preventAndSelect = e => { + e.preventDefault(); + return this.typeAheadSelect(); + }; + + const defaults = { // delete 8: e => this.maybeDeleteValue(), // tab 9: e => this.onTab(), - // enter.prevent - 13: e => { - e.preventDefault(); - return this.typeAheadSelect(); - }, // esc 27: e => this.onEscape(), // up.prevent @@ -882,7 +893,11 @@ e.preventDefault(); return this.typeAheadDown(); }, - }, this); + }; + + this.selectOnKeyCodes.forEach(keyCode => defaults[keyCode] = preventAndSelect); + + const handlers = this.mapKeydown(defaults, this); if (typeof handlers[e.keyCode] === 'function') { return handlers[e.keyCode](e); diff --git a/src/handlers/searchKeyDown.js b/src/handlers/searchKeyDown.js index e69de29..bd9db89 100644 --- a/src/handlers/searchKeyDown.js +++ b/src/handlers/searchKeyDown.js @@ -0,0 +1,28 @@ +export default { + // delete + 8: e => this.maybeDeleteValue(), + + // tab + 9: e => this.onTab(), + + // enter.prevent + 13: e => { + e.preventDefault(); + return this.typeAheadSelect(); + }, + + // esc + 27: e => this.onEscape(), + + // up.prevent + 38: e => { + e.preventDefault(); + return this.typeAheadUp(); + }, + + // down.prevent + 40: e => { + e.preventDefault(); + return this.typeAheadDown(); + }, +}; diff --git a/tests/unit/Keydown.spec.js b/tests/unit/Keydown.spec.js new file mode 100644 index 0000000..56d390b --- /dev/null +++ b/tests/unit/Keydown.spec.js @@ -0,0 +1,44 @@ +import { mountDefault } from '../helpers'; + +describe('Custom Keydown Handlers', () => { + + it('can use the map-keydown prop to trigger custom behaviour', () => { + const onKeyDown = jest.fn(); + const Select = mountDefault({ + mapKeydown: (defaults, vm) => ({...defaults, 32: onKeyDown}), + }); + + Select.find({ref: 'search'}).trigger('keydown.space'); + + expect(onKeyDown.mock.calls.length).toBe(1); + }); + + it('selectOnKeyCodes should trigger a selection for custom keycodes', () => { + const Select = mountDefault({ + selectOnKeyCodes: [32], + }); + + const spy = jest.spyOn(Select.vm, 'typeAheadSelect'); + + Select.find({ref: 'search'}).trigger('keydown.space'); + + expect(spy).toHaveBeenCalledTimes(1); + }); + + it('even works when combining selectOnKeyCodes with map-keydown', () => { + const onKeyDown = jest.fn(); + const Select = mountDefault({ + mapKeydown: (defaults, vm) => ({...defaults, 32: onKeyDown}), + selectOnKeyCodes: [9], + }); + + const spy = jest.spyOn(Select.vm, 'typeAheadSelect'); + + Select.find({ref: 'search'}).trigger('keydown.space'); + expect(onKeyDown.mock.calls.length).toBe(1); + + Select.find({ref: 'search'}).trigger('keydown.tab'); + expect(spy).toHaveBeenCalledTimes(1); + }); + +});