From 12190e45fd2804d16ff988c03a162a770ee2c503 Mon Sep 17 00:00:00 2001 From: mertsincan Date: Thu, 1 Sep 2022 00:30:06 +0100 Subject: [PATCH] Fixed #2916 - Add autoFilterFocus property to Dropdown and MultiSelect --- api-generator/components/dropdown.js | 6 ++++++ api-generator/components/multiselect.js | 6 ++++++ src/components/dropdown/Dropdown.d.ts | 5 +++++ src/components/dropdown/Dropdown.vue | 20 ++++++++++++------- src/components/multiselect/MultiSelect.d.ts | 5 +++++ src/components/multiselect/MultiSelect.vue | 22 +++++++++++++-------- src/views/dropdown/DropdownDoc.vue | 6 ++++++ src/views/multiselect/MultiSelectDoc.vue | 6 ++++++ 8 files changed, 61 insertions(+), 15 deletions(-) diff --git a/api-generator/components/dropdown.js b/api-generator/components/dropdown.js index 31e0ad4f8..f4064690e 100644 --- a/api-generator/components/dropdown.js +++ b/api-generator/components/dropdown.js @@ -197,6 +197,12 @@ const DropdownProps = [ default: "true", description: "Whether to focus on the first visible or selected element when the overlay panel is shown." }, + { + name: "autoFilterFocus", + type: "boolean", + default: "false", + description: "Whether to focus on the filter element when the overlay panel is shown." + }, { name: "selectOnFocus", type: "boolean", diff --git a/api-generator/components/multiselect.js b/api-generator/components/multiselect.js index 82db603ff..e6eebd89f 100644 --- a/api-generator/components/multiselect.js +++ b/api-generator/components/multiselect.js @@ -209,6 +209,12 @@ const MultiSelectProps = [ default: "true", description: "Whether to focus on the first visible or selected element when the overlay panel is shown." }, + { + name: "autoFilterFocus", + type: "boolean", + default: "false", + description: "Whether to focus on the filter element when the overlay panel is shown." + }, { name: "filterMessage", type: "string", diff --git a/src/components/dropdown/Dropdown.d.ts b/src/components/dropdown/Dropdown.d.ts index fdf82e0ef..dbee05619 100755 --- a/src/components/dropdown/Dropdown.d.ts +++ b/src/components/dropdown/Dropdown.d.ts @@ -182,6 +182,11 @@ export interface DropdownProps { * Default value is true. */ autoOptionFocus?: boolean | undefined; + /** + * Whether to focus on the filter element when the overlay panel is shown. + * Default value is false. + */ + autoFilterFocus?: boolean | undefined; /** * When enabled, the focused option is selected. * Default value is false. diff --git a/src/components/dropdown/Dropdown.vue b/src/components/dropdown/Dropdown.vue index bb34971f8..575db3e70 100755 --- a/src/components/dropdown/Dropdown.vue +++ b/src/components/dropdown/Dropdown.vue @@ -21,7 +21,7 @@
- @@ -144,6 +144,10 @@ export default { type: Boolean, default: true }, + autoFilterFocus: { + type: Boolean, + default: false + }, selectOnFocus: { type: Boolean, default: false @@ -267,7 +271,7 @@ export default { this.overlayVisible = true; this.focusedOptionIndex = this.focusedOptionIndex !== -1 ? this.focusedOptionIndex : (this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1); - isFocus && this.$refs.focusInput.focus(); + isFocus && DomHandler.focus(this.$refs.focusInput); }, hide(isFocus) { const _hide = () => { @@ -277,7 +281,7 @@ export default { this.searchValue = ''; this.resetFilterOnHide && (this.filterValue = null); - isFocus && this.$refs.focusInput && this.$refs.focusInput.focus(); + isFocus && DomHandler.focus(this.$refs.focusInput); } setTimeout(() => { _hide() }, 0); // For ScreenReaders @@ -390,14 +394,14 @@ export default { if (relatedTarget === this.$refs.focusInput) { const firstFocusableEl = DomHandler.getFirstFocusableElement(this.overlay, ':not(.p-hidden-focusable)'); - firstFocusableEl && firstFocusableEl.focus(); + DomHandler.focus(firstFocusableEl); } else { - this.$refs.focusInput.focus(); + DomHandler.focus(this.$refs.focusInput); } }, onLastHiddenFocus() { - this.$refs.firstHiddenFocusableElementOnOverlay.focus(); + DomHandler.focus(this.$refs.firstHiddenFocusableElementOnOverlay); }, onOptionSelect(event, option, isHide = true) { const value = this.getOptionValue(option); @@ -571,7 +575,7 @@ export default { onTabKey(event, pressedInInputText = false) { if (!pressedInInputText) { if (this.overlayVisible && this.hasFocusableElements()) { - this.$refs.firstHiddenFocusableElementOnOverlay.focus(); + DomHandler.focus(this.$refs.firstHiddenFocusableElementOnOverlay); event.preventDefault(); } @@ -593,6 +597,8 @@ export default { ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay); this.alignOverlay(); this.scrollInView(); + + this.autoFilterFocus && DomHandler.focus(this.$refs.filterInput); }, onOverlayAfterEnter() { this.bindOutsideClickListener(); diff --git a/src/components/multiselect/MultiSelect.d.ts b/src/components/multiselect/MultiSelect.d.ts index 0ef65d612..e29506160 100755 --- a/src/components/multiselect/MultiSelect.d.ts +++ b/src/components/multiselect/MultiSelect.d.ts @@ -202,6 +202,11 @@ export interface MultiSelectProps { * Default value is true. */ autoOptionFocus?: boolean | undefined; + /** + * Whether to focus on the filter element when the overlay panel is shown. + * Default value is false. + */ + autoFilterFocus?: boolean | undefined; /** * Text to be displayed in hidden accessible field when filtering returns any results. Defaults to value from PrimeVue locale configuration. * Default value is '{0} results are available'. diff --git a/src/components/multiselect/MultiSelect.vue b/src/components/multiselect/MultiSelect.vue index d2c0b7245..c1be73b14 100755 --- a/src/components/multiselect/MultiSelect.vue +++ b/src/components/multiselect/MultiSelect.vue @@ -44,7 +44,7 @@
- @@ -197,6 +197,10 @@ export default { type: Boolean, default: true }, + autoFilterFocus: { + type: Boolean, + default: false + }, filterMessage: { type: String, default: null @@ -312,7 +316,7 @@ export default { this.overlayVisible = true; this.focusedOptionIndex = this.focusedOptionIndex !== -1 ? this.focusedOptionIndex : (this.autoOptionFocus ? this.findFirstFocusedOptionIndex() : -1); - isFocus && this.$refs.focusInput.focus(); + isFocus && DomHandler.focus(this.$refs.focusInput); }, hide(isFocus) { this.$emit('before-hide'); @@ -321,7 +325,7 @@ export default { this.searchValue = ''; this.resetFilterOnHide && (this.filterValue = null); - isFocus && this.$refs.focusInput.focus(); + isFocus && DomHandler.focus(this.$refs.focusInput); }, onFocus(event) { this.focused = true; @@ -413,14 +417,14 @@ export default { if (relatedTarget === this.$refs.focusInput) { const firstFocusableEl = DomHandler.getFirstFocusableElement(this.overlay, ':not(.p-hidden-focusable)'); - firstFocusableEl && firstFocusableEl.focus(); + DomHandler.focus(firstFocusableEl); } else { - this.$refs.focusInput.focus(); + DomHandler.focus(this.$refs.focusInput); } }, onLastHiddenFocus() { - this.$refs.firstHiddenFocusableElementOnOverlay.focus(); + DomHandler.focus(this.$refs.firstHiddenFocusableElementOnOverlay); }, onCloseClick() { this.hide(true); @@ -445,7 +449,7 @@ export default { value = [...(this.modelValue || []), this.getOptionValue(option)]; this.updateModel(event, value); - isFocus && this.$refs.focusInput.focus(); + isFocus && DomHandler.focus(this.$refs.focusInput); index !== -1 && (this.focusedOptionIndex = index); }, onOptionMouseMove(event, index) { @@ -646,7 +650,7 @@ export default { onTabKey(event, pressedInInputText = false) { if (!pressedInInputText) { if (this.overlayVisible && this.hasFocusableElements()) { - this.$refs.firstHiddenFocusableElementOnOverlay.focus(); + DomHandler.focus(this.$refs.firstHiddenFocusableElementOnOverlay); event.preventDefault(); } @@ -666,6 +670,8 @@ export default { ZIndexUtils.set('overlay', el, this.$primevue.config.zIndex.overlay); this.alignOverlay(); this.scrollInView(); + + this.autoFilterFocus && DomHandler.focus(this.$refs.filterInput); }, onOverlayAfterEnter() { this.bindOutsideClickListener(); diff --git a/src/views/dropdown/DropdownDoc.vue b/src/views/dropdown/DropdownDoc.vue index 843b6dd7f..fa3cc7eba 100755 --- a/src/views/dropdown/DropdownDoc.vue +++ b/src/views/dropdown/DropdownDoc.vue @@ -330,6 +330,12 @@ export default { true Whether to focus on the first visible or selected element when the overlay panel is shown. + + autoFilterFocus + boolean + false + Whether to focus on the filter element when the overlay panel is shown. + selectOnFocus boolean diff --git a/src/views/multiselect/MultiSelectDoc.vue b/src/views/multiselect/MultiSelectDoc.vue index 2088b0557..c269515bd 100755 --- a/src/views/multiselect/MultiSelectDoc.vue +++ b/src/views/multiselect/MultiSelectDoc.vue @@ -351,6 +351,12 @@ export default { true Whether to focus on the first visible or selected element when the overlay panel is shown. + + autoFilterFocus + boolean + false + Whether to focus on the filter element when the overlay panel is shown. + filterMessage string