Repository: wagtail/wagtail
File: client/src/controllers/KeyboardController.ts (TypeScript)

Code before:
  /**
   * Handle the key event by preventing the default action and performng the specified action.
   */
  handleKey(event: Event) {
    if (event.preventDefault) event.preventDefault();
    const targetElement =
      this.elementTargets.length > 0 ? this.elementTargets[0] : this.element;
    if (this.actionValue === 'focus') {
      this.handleFocus(targetElement as HTMLInputElement);
    } else {
      this.handleClick(targetElement);
    }
  }

  /**
   * Handle the click action on target element
   */
  handleClick(target: HTMLElement) {
    target.click();
  }

  /**
   * Handle the focus action on target element (focusing on searchbar)
   */
  handleFocus(target: HTMLInputElement) {
    if (this.slimValue) {
      const form = target.closest('form');

      const searchButton = form?.querySelector(
        'button[type="submit"]',
      ) as HTMLButtonElement;

      if (searchButton) {
        searchButton.click();
        setTimeout(() => {
          this.performFocus(target);
        }, this.delayValue || 300);
      }
    } else {
      // Sidebar is already expanded, focus immediately
      this.performFocus(target);
    }
  }

  /**
   * Perform the focus on input elements
   */
  performFocus(target: HTMLInputElement) {
    if (target) {
      target.focus();


Review comment (suggestion):
Is there any way to avoid this specific sidebar handling here? It feels like we are making this controller have to do very specific work for this use case, instead of keeping it generic.

Also, a reminder that we have a `forceFocus` util that's better at handling forcing focus as it smooths over a few nuances.

Ideas

1. What if we dispatch an event? Then the sidebar code listens for that event to focus on it? Then the KeybardController just gets changed to dispatch a custom event.
2. We change to a `select` method (see https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select ), which should emit a `select` event, which the sidebar can listen to and then ensure the sidebar opens itself. https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement/select_event
3. Get the sidebar to listen to `click` events on the search input and open itself AND focus on the input if they fire.
4. Maybe we enhance `forceFocus` to check if the element is visible, if not, it will dispatch an event to it saying 'about to focus', we actually did this already in the `FocusController` to achieve a similar goal for focusing on tabs.




Code after:
        this.keyValue = ariaKeyShortcuts;
      }
    }
  }

  /**
   * Handle the key event by preventing the default action and performing the specified action.
   */
  handleKey(event: Event) {
    if (event.preventDefault) event.preventDefault();
    const targetElement =
      this.elementTargets.length > 0 ? this.elementTargets[0] : this.element;
    if (this.actionValue === KeyboardAction.FOCUS) {
      this.handleFocus(targetElement);
    } else {
      this.handleClick(targetElement);
    }
  }

  /**
   * Handle the click action on target element.
   */
  handleClick(target: HTMLElement) {
    target.click();
  }

  /**
   * Handle the focus action on target element. If it is an input element containing text,
   * also selects the existing text inside the field.
   */
  handleFocus(target: HTMLElement) {
    forceFocus(target);

    if (target instanceof HTMLInputElement && target.value && target.select) {
      target.select();
    }
  }

  /**
   * When a key is set or changed, bind the handler to the keyboard shortcut.
   * This will override the shortcut, if already set.
   * Allow key to be empty, so it can be removed from the attributes to unbind the shortcuts
   */
  keyValueChanged(key: string, previousKey: string) {
    if (previousKey && previousKey !== key) {
      Mousetrap.unbind(previousKey);
    }

    if (!key) return;

    if (this.scopeValue === 'global') {