takeInitialFocus()

in packages/eui/src/components/context_menu/context_menu_panel.tsx [240:301]


  takeInitialFocus() {
    // Give positioning time to render before focus is applied. Otherwise page jumps.
    requestAnimationFrame(() => {
      if (!this._isMounted) {
        return;
      }

      // Don't take focus yet if EuiContextMenu is in a popover
      // and the popover is initially opening/transitioning in
      if (this.initialPopoverParent && this.state.waitingForInitialPopover) {
        return;
      }

      // Setting focus while transitioning causes the animation to glitch, so we have to wait
      // until it's finished before we focus anything.
      if (this.props.transitionType) {
        // If the panel is transitioning, set focus to the panel so that users using
        // arrow keys that are fast clickers don't accidentally get stranded focus
        // or trigger keystrokes when it shouldn't
        this.panel?.focus({ preventScroll: true });
        return;
      }

      // Initial focus has already been handled, no need to continue and potentially hijack/focus fight
      if (this.state.tookInitialFocus) {
        return;
      }

      // `initialFocusedItemIndex={-1}` should only be used when preventing initial item focus is desired
      if (this.state.focusedItemIndex === -1) {
        // Resetting the focusedItemIndex to 0 allows keyboard up/down behavior to
        // still work correctly later if the panel is manually tabbed into
        return this.setState({ tookInitialFocus: true, focusedItemIndex: 0 });
      }

      // If an item should be focused, focus it (if it exists)
      if (this.state.focusedItemIndex != null && this.state.menuItems.length) {
        const focusedItem = this.state.menuItems[this.state.focusedItemIndex];
        if (focusedItem) {
          focusedItem.focus();
          return this.setState({ tookInitialFocus: true });
        }
      }

      // Otherwise, if the back button panel title is present, focus it
      if (this.backButton) {
        // Focus the back button for both `items` and `children` APIs
        this.backButton.focus();
        // If `items`, ensure our focused item index is correct
        if (this.state.menuItems.length) {
          this.setState({ focusedItemIndex: 0 });
        }
        return this.setState({ tookInitialFocus: true });
      }

      // Focus on the panel as a last resort.
      if (this.panel && !this.panel.contains(document.activeElement)) {
        this.panel.focus();
        this.setState({ tookInitialFocus: true });
      }
    });
  }