afcapel / stimulus-autocomplete

Stimulus autocomplete component
MIT License
478 stars 61 forks source link

Feature improve: When mouse move on an option item, it should become the current selected option item. #125

Open qichunren opened 1 year ago

qichunren commented 1 year ago

See github top left search box for example.

cmer commented 1 year ago

Isn't that just changing the background with CSS on hover?

ACPK commented 1 year ago

@cmer @afcapel The stimulus-autocomplete example keeps the wrong aria-activedescendant value on the input field when the user uses the mouse. Any results that stimulus-autocomplete gave the class of "active" to would need the "active" removed when using the mouse. Additionally, the aria-activedescendant value needs to be set to the value of the result that the user is hovering over.

Solution

Add data-action="mouseenter->autocomplete#show" to results.

<li role="option" data-autocomplete-value="1" 
  data-action="mouseenter->autocomplete#show">
  Mockingbird
</li>

Add show to autocomplete.js

show(event)
  {
    if (event.target) this.select(event.target)
  }
tmaier commented 1 year ago

I think I was able to solve this with the following custom stimulus controller, which inherits stimulus-autocomplete:

import { Autocomplete } from 'stimulus-autocomplete'

const optionSelector = "[role='option']:not([aria-disabled])"

export default class extends Autocomplete {
  connect() {
    super.connect()
    this.resultsTarget.addEventListener('mouseover', this.onResultsMouseOver)
  }

  disconnect() {
    super.disconnect()
    if (this.hasResultsTarget) {
      this.resultsTarget.removeEventListener('mouseover', this.onResultsMouseOver)
    }
  }

  onResultsMouseOver = (event) => {
    if (!(event.target instanceof Element)) return
    const selected = event.target.closest(optionSelector)
    if (selected) this.select(selected)
  }
}
Mecanik commented 10 months ago

data-action="mouseenter->autocomplete#show"

This does not work for me. What exactly should change? Nothing changes. Could you share your HTML?