diff --git a/cypress/fixtures/pointer/removable.html b/cypress/fixtures/pointer/removable.html new file mode 100644 index 00000000..68d866b4 --- /dev/null +++ b/cypress/fixtures/pointer/removable.html @@ -0,0 +1,50 @@ + + + + + + + + + + +
+ + + + diff --git a/cypress/integration/behavior/pointer.spec.js b/cypress/integration/behavior/pointer.spec.js index 883d6f56..08dfe008 100644 --- a/cypress/integration/behavior/pointer.spec.js +++ b/cypress/integration/behavior/pointer.spec.js @@ -88,4 +88,23 @@ context('pointer', () => { cy.get('.vue-dropdown-item').first().should('have.class', 'highlighted') cy.get('.vue-dropdown-item.disabled').should('not.have.class', 'highlighted') }) + + it('should highlight closest option if original one is unavailable', () => { + cy.visit('/cypress/fixtures/pointer/removable.html') + + cy.get('.vue-select').click() + cy.get('.vue-dropdown-item').first().next().trigger('mousemove') + cy.get('.vue-dropdown-item').first().next().trigger('click') + cy.get('.vue-dropdown-item').first().next().trigger('click') + + cy.get('.vue-dropdown-item').first().next().should('have.class', 'highlighted') + + cy.get('.vue-dropdown-item').first().next().trigger('click') + cy.get('.vue-dropdown-item').first().next().trigger('click') + + cy.get('.vue-dropdown-item').first().should('have.class', 'highlighted') + + cy.get('.vue-dropdown-item').first().trigger('click') + cy.get('.vue-dropdown-item').first().trigger('click') + }) }) diff --git a/src/hooks.ts b/src/hooks.ts index a640f041..15f86d41 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -55,6 +55,11 @@ export const usePointer = (options: Ref, highlightedOriginalIndex: Ref watchEffect(() => { if (isSomeSelectable.value === false) highlightedOriginalIndex.value = null + if (options.value.length <= highlightedOriginalIndex.value) { + for (const option of options.value.reverse()) { + if (pointerSet(option.originalIndex)) break + } + } if ( highlightedOriginalIndex.value === null || isSelectable(options.value[highlightedOriginalIndex.value]) === false