From ca9a49545bf46ffdf797faa6d02c5978723940c6 Mon Sep 17 00:00:00 2001 From: Jeff Sagal Date: Sat, 17 Dec 2022 13:39:21 -0800 Subject: [PATCH] feat(1735): add mapKeyPress prop --- docs/guide/keydown.md | 82 ++++++++++++++++++++++++--------------- src/components/Select.vue | 44 +++++++++++++++------ 2 files changed, 83 insertions(+), 43 deletions(-) diff --git a/docs/guide/keydown.md b/docs/guide/keydown.md index b353960..dad8866 100644 --- a/docs/guide/keydown.md +++ b/docs/guide/keydown.md @@ -4,16 +4,17 @@ ## selectOnKeyCodes `selectOnKeyCodes {Array}` is an array of keyCodes that will trigger a typeAheadSelect. Any keyCodes - in this array will prevent the default event action and trigger a typeahead select. By default, - it's just `[13]` for return. For example, maybe you want to tag on a comma keystroke: - +in this array will prevent the default event action and trigger a typeahead select. By default, +it's just `[13]` for return. For example, maybe you want to tag on a comma keystroke: + - + <<< @/.vuepress/components/TagOnComma.vue ## mapKeyDown -Vue Select provides the `map-keydown` Function prop to allow for customizing the components response to +Vue Select provides the `mapKeyDown` Function prop to allow for customizing the components response +to keydown events while the search input has focus. ```js @@ -29,37 +30,37 @@ By default, the prop is a no–op returning the same object `map` object it rece maps keyCodes to handlers: `{ : }`. Modifying this object can override default functionality, or add handlers for different keys that the component doesn't normally listen for. -Note that any keyCodes you've added to `selectOnKeyCodes` will be passed to `map-keydown` as well, -so `map-keydown` will always take precedence. +Note that any keyCodes you've added to `selectOnKeyCodes` will be passed to `mapKeyDown` as well, +so `mapKeyDown` will always take precedence. **Default Handlers** ```js -// delete -8: e => this.maybeDeleteValue() - -// tab -9: e => this.onTab() - -// enter -13: e => { - e.preventDefault(); - return this.typeAheadSelect(); -} - -// esc -27: e => this.onEscape() - -// up -38: e => { - e.preventDefault(); - return this.typeAheadUp(); -} - -// down -40: e => { - e.preventDefault(); - return this.typeAheadDown(); +const defaults = { + // backspace + 8: (e) => this.maybeDeleteValue(), + // tab + 9: (e) => this.onTab(), + // esc + 27: (e) => this.onEscape(), + // up.prevent + 38: (e) => { + e.preventDefault() + if (!this.open) { + this.open = true + return + } + return this.typeAheadUp() + }, + // down.prevent + 40: (e) => { + e.preventDefault() + if (!this.open) { + this.open = true + return + } + return this.typeAheadDown() + }, } ``` @@ -71,3 +72,20 @@ This is example listens for the `@` key, and autocompletes an email address with <<< @/.vuepress/components/CustomHandlers.vue +## mapKeyPress + +`mapKeyPress` prop is identical in functionality to `mapKeyDown`, but it's called on `keypress` +events instead of `keydown`. The keypress event is used to detect space bar presses when the input +has focus, and the menu is closed. + +```js + const defaults = { + // space + 32: (e) => { + if (!this.open) { + e.preventDefault() + this.open = true + } + }, +} +``` diff --git a/src/components/Select.vue b/src/components/Select.vue index a4efc86..4dd538d 100644 --- a/src/components/Select.vue +++ b/src/components/Select.vue @@ -596,7 +596,6 @@ export default { * for the search input. Can be used to implement * custom behaviour for key presses. */ - mapKeydown: { type: Function, /** @@ -607,6 +606,21 @@ export default { default: (map, vm) => map, }, + /** + * Used to modify the default keypress events map + * for the search input. Can be used to implement + * custom behaviour for key presses. + */ + mapKeyPress: { + type: Function, + /** + * @param map {Object} + * @param vm {VueSelect} + * @return {Object} + */ + default: (map, vm) => map, + }, + /** * Append the dropdown element to the end of the body * and size/position it dynamically. Use it if you have @@ -1331,19 +1345,17 @@ export default { 38: (e) => { e.preventDefault() if (!this.open) { - this.open = true - return + return (this.open = true) } - return this.typeAheadUp() + this.typeAheadUp() }, // down.prevent 40: (e) => { e.preventDefault() if (!this.open) { - this.open = true - return + return (this.open = true) } - return this.typeAheadDown() + this.typeAheadDown() }, } @@ -1359,13 +1371,23 @@ export default { }, /** - * @todo: Probably want to add a mapKeyPress method just like we have for keydown. * @param {KeyboardEvent} e */ onSearchKeyPress(e) { - if (!this.open && e.keyCode === 32) { - e.preventDefault() - this.open = true + const defaults = { + // space + 32: (e) => { + if (!this.open) { + e.preventDefault() + this.open = true + } + }, + } + + const handlers = this.mapKeyPress(defaults, this) + + if (typeof handlers[e.keyCode] === 'function') { + return handlers[e.keyCode](e) } }, },