Skip to content

Commit

Permalink
fix: handle focusout correctly, so the dropdown doesn't close uninten…
Browse files Browse the repository at this point in the history
…tionally
  • Loading branch information
Merlin committed Sep 17, 2024
1 parent 229ecac commit 71f71cf
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 8 deletions.
11 changes: 8 additions & 3 deletions src/Multiselect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
:tabindex="tabindex"
data-cy="multiselect"
@focusin="activate"
@focusout="deactivate"
@focusout="handleFocusOut"
@focus="handleFocus"
@mousedown.self="handleMousedown"
>
Expand Down Expand Up @@ -65,7 +65,8 @@
<span
:class="classList.clear"
data-cy="clear"
@mousedown="clear"
@mousedown.prevent
@click="clear"
><span
:class="classList.clearIcon"
><!-- clear icon? --> x</span></span>
Expand All @@ -78,8 +79,9 @@
/>
</div>
</v-target>
<!-- always show but hide content to avoid weird dropdown ref behaviour -->
<v-follower
:show="multiselectContainer && dropdownOpen"
:show="true"
:placement="dropdownPlacement"
>
<!--option dropdown-->
Expand All @@ -88,7 +90,9 @@
:class="classList.dropdown"
data-cy="dropdown"
:style="dropdownStyle"
tabindex="0"
@scroll="handleScroll"
@focusout="handleFocusOut"
>
<ul
v-if="shownOptions.length > 0 && (!loadingOptions || infinite)"
Expand Down Expand Up @@ -433,6 +437,7 @@ export default defineComponent({
searchable,
disabled,
context,
dropdown.dropdown,
dropdown.openDropdown,
dropdown.closeDropdown,
search.clearSearch,
Expand Down
10 changes: 5 additions & 5 deletions src/tests/MultiselectTester.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
:loading-options="loadingOptions"
:max-options="maxOptions"
:infinite="infinite"
:teleport="teleport"
:position="position"
/>
<Multiselect
v-else
Expand All @@ -46,7 +46,7 @@
:loading-options="loadingOptions"
:max-options="maxOptions"
:infinite="infinite"
:teleport="teleport"
:position="position"
/>
<div v-if="vModel">
<button
Expand Down Expand Up @@ -268,10 +268,10 @@ export default defineComponent({
required: false,
default: false,
},
teleport: {
type: Boolean,
position: {
type: String as PropType<'auto' | 'bottom' | 'top'>,
required: false,
default: false,
default: 'auto',
},
},
setup(props) {
Expand Down
11 changes: 11 additions & 0 deletions src/utils/useMultiselect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default function useMultiselect(
searchable: Ref<boolean>,
disabled: Ref<boolean>,
context: SetupContext,
dropdown: Ref<HTMLDivElement | undefined>,
openDropdown: () => void,
closeDropdown: () => void,
clearSearch: () => void,
Expand Down Expand Up @@ -37,6 +38,15 @@ export default function useMultiselect(
}
}

// don't deactivate when focusing option dropdown
function handleFocusOut(e: FocusEvent) {
const relatedTarget = e.relatedTarget as Node
if (dropdown.value && relatedTarget && dropdown.value.contains(relatedTarget))
e.preventDefault()
else
deactivate()
}

function handleFocus() {
input.value?.focus()
}
Expand Down Expand Up @@ -71,5 +81,6 @@ export default function useMultiselect(
deactivate,
handleMousedown,
handleFocus,
handleFocusOut,
}
}

0 comments on commit 71f71cf

Please sign in to comment.