_listboxOnKeyDown(ev) {
      if (this.disabled) {
        return;
      }

      this._isHandlingUserInput = true;
      setTimeout(() => {
        // Since we can't control when subclasses are done handling keyboard input, we
        // schedule a timeout to reset _isHandlingUserInput
        this._isHandlingUserInput = false;
      });

      const { key } = ev;

      switch (key) {
        case ' ':
        case 'Enter': {
          if (key === ' ' && this._listboxReceivesNoFocus) {
            return;
          }
          if (key === ' ') {
            ev.preventDefault();
          }
          if (!this.formElements[this.activeIndex]) {
            return;
          }

          if (this.formElements[this.activeIndex].disabled) {
            return;
          }

          if (this.formElements[this.activeIndex].href) {
            this.formElements[this.activeIndex].click();
          }

          this.setCheckedIndex(this.activeIndex);
          break;
        }
        case 'ArrowUp':
          ev.preventDefault();
          if (this.orientation === 'vertical') {
            this.activeIndex = this._getPreviousEnabledOption(this.activeIndex);
          }
          break;
        case 'ArrowLeft':
          if (this._listboxReceivesNoFocus) {
            return;
          }
          ev.preventDefault();
          if (this.orientation === 'horizontal') {
            this.activeIndex = this._getPreviousEnabledOption(this.activeIndex);
          }
          break;
        case 'ArrowDown':
          ev.preventDefault();
          if (this.orientation === 'vertical') {
            this.activeIndex = this._getNextEnabledOption(this.activeIndex);
          }
          break;
        case 'ArrowRight':
          if (this._listboxReceivesNoFocus) {
            return;
          }
          ev.preventDefault();
          if (this.orientation === 'horizontal') {
            this.activeIndex = this._getNextEnabledOption(this.activeIndex);
          }
          break;
        case 'Home':
          if (this._listboxReceivesNoFocus) {
            return;
          }
          ev.preventDefault();
          this.activeIndex = this._getNextEnabledOption(0, 0);
          break;
        case 'End':
          if (this._listboxReceivesNoFocus) {
            return;
          }
          ev.preventDefault();
          this.activeIndex = this._getPreviousEnabledOption(this.formElements.length - 1, 0);
          break;
        default:
          if (!this._noTypeAhead) {
            this._handleTypeAhead(ev, {
              setAsChecked: this.selectionFollowsFocus && !this.multipleChoice,
            });
          }
      }

      const keys = ['ArrowUp', 'ArrowDown', 'ArrowLeft', 'ArrowRight', 'Home', 'End'];
      if (keys.includes(key) && this.selectionFollowsFocus && !this.multipleChoice) {
        this.setCheckedIndex(this.activeIndex);
      }
    }
@desc
Handle various keyboard controls; UP/DOWN will shift focus; SPACE selects
an item.

@param {KeyboardEvent} ev - the keydown event object
@protected