Sha256: ec0ff18e0c94c52f527cd97025a08650cd0a19afc2f6b150d641b6741af48867

Contents?: true

Size: 1.54 KB

Versions: 1

Compression:

Stored size: 1.54 KB

Contents

import { Controller } from "@hotwired/stimulus"

export default class extends Controller {
  static targets = [ "list", "option" ]
  static values  = { index: Number }

  connect() {
    this.#removeTabstops()
    this.#selectFirstItem()
  }

  navigate(event) {
    switch (event.key) {
      case "ArrowUp":
        event.preventDefault()
        this.#prev()
        break
      case "ArrowDown":
        event.preventDefault()
        this.#next()
        break
      case "Enter":
        event.preventDefault()
        this.#clickSelected()
        break
    }
  }

  reset() {
    this.indexValue = 0
    this.#selectCurrentItem()
  }

  #prev() {
    if (this.indexValue > 0) {
      this.indexValue--
      this.#selectCurrentItem()
    }
  }

  #next() {
    if (this.indexValue < this.#lastIndex) {
      this.indexValue++
      this.#selectCurrentItem()
    }
  }

  #clickSelected() {
    this.#visibleOptions[this.indexValue]?.click()
  }

  #removeTabstops() {
    this.optionTargets.forEach(e => e.tabIndex = -1)
  }

  #selectFirstItem() {
    this.optionTargets.forEach((element, index) => {
      element.ariaSelected = index === 0
    })
  }

  #selectCurrentItem() {
    this.optionTargets.forEach((element, index) => {
      element.ariaSelected = false
    })

    this.#visibleOptions.forEach((element, index) => {
      element.ariaSelected = index === this.indexValue
    })
  }

  get #lastIndex() {
    return this.#visibleOptions.length -1
  }

  get #visibleOptions() {
    return this.optionTargets.filter(e => e.offsetParent != null)
  }
}

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
css-zero-0.0.50 lib/generators/css_zero/add/templates/app/javascript/controllers/list_controller.js