nathanreyes / v-calendar

An elegant calendar and datepicker plugin for Vue.
https://vcalendar.io
MIT License
4.32k stars 840 forks source link

"Space" or "Enter" key on header nav arrows results in duplicate nav action #1459

Open choshin314 opened 3 months ago

choshin314 commented 3 months ago

When the left/right navigation arrow is focused, using the Space or Enter key to trigger navigation results in the click handler firing twice (which causes the navigation to double the steps).

My best guess is that the issue lies here and here – since a keydown event w/ Space/Enter keys will trigger the native click event on the button as well, we're seeing the click handler fire twice.

ScreenRecording2024-03-12at10 35 13AM-ezgif com-video-to-gif-converter

jeremymdoan commented 3 weeks ago

have you found a workaround for this issue?

choshin314 commented 3 weeks ago

have you found a workaround for this issue?

our workaround for now: we ended up writing a composable - hope this helps. Maybe also worth noting that it could break if something changes w/ the nav button css classes.

import { onBeforeUnmount, onMounted } from 'vue'

/** @param {import('vue').Ref<HTMLElement>} containerRef template ref on el wrapping VDatePicker */
export function useCalendarWorkaround(containerRef) {
  /**
   * @param {HTMLElement} el
   * @returns {boolean}
   */
  function isNavBtn(el) {
    return (
      el?.classList?.contains?.('vc-arrow') &&
      (el.classList.contains('vc-prev') || el.classList.contains('vc-next'))
    )
  }

  /**
   * @param {KeyboardEvent["key"]} key
   * @returns {boolean}
   */
  function isSpaceOrEnter(key) {
    return key === ' ' || key === 'Spacebar' || key === 'Enter'
  }

  /** @param {KeyboardEvent} e */
  function keydownWorkaround(e) {
    if (isNavBtn(e?.target) && isSpaceOrEnter(e?.key)) {
      e.preventDefault()
    }
  }

  onMounted(() => {
    containerRef.value?.addEventListener?.('keydown', keydownWorkaround)
  })

  onBeforeUnmount(() => {
    containerRef.value?.removeEventListener?.('keydown', keydownWorkaround)
  })
}
jeremymdoan commented 3 weeks ago

thanks