waitForReactSelectMenu function infrastructure ~ 75.0%

Last updated: 2026-03-04T23:21:38.391Z

Metrics

LOC: 49 Complexity: 11 Params: 3 Coverage: 75.0% (12/16 lines, 0x executed)

Signature

waitForReactSelectMenu( wrapper: HTMLElement, timeoutMs: number, ): : Promise<HTMLElement | null>

Summary

Waits for react-select's dropdown menu to appear. react-select renders the menu either: a) inline — directly inside the container wrapper, OR b) portaled — appended to document.body (menuPortalTarget). Portal detection: react-select sets aria-controls on the search input ONLY while the menu is open, so we must read it dynamically (each check), not once at call time. Fallback: scan document.body for .react-select__menu elements not contained within this wrapper — handles the portal case even without aria-controls.

Architecture violations

View all

  • [warning] max-cyclomatic-complexity: 'waitForReactSelectMenu' has cyclomatic complexity 11 (max 10)

Source Code

function waitForReactSelectMenu(
  wrapper: HTMLElement,
  timeoutMs: number,
): Promise<HTMLElement | null> {
  const findInline = () =>
    wrapper.querySelector<HTMLElement>(".react-select__menu");

  // Re-read aria-controls on every check because react-select only sets it
  // while the menu is open (aria-expanded="true").
  const findPortaled = (): HTMLElement | null => {
    const input = wrapper.querySelector<HTMLInputElement>(
      "input[aria-controls]",
    );
    const listboxId = input?.getAttribute("aria-controls") ?? null;
    if (listboxId) {
      const listbox = document.getElementById(listboxId);
      const byAriaControls =
        listbox?.closest<HTMLElement>(".react-select__menu") ?? null;
      if (byAriaControls) return byAriaControls;
    }

    // Broader fallback: any .react-select__menu in the document that is NOT
    // a child of this wrapper (i.e. a portaled one).
    const allMenus = Array.from(
      document.querySelectorAll<HTMLElement>(".react-select__menu"),
    );
    return allMenus.find((m) => !wrapper.contains(m)) ?? null;
  };

  const existing = findInline() ?? findPortaled();
  if (existing) return Promise.resolve(existing);

  return new Promise((resolve) => {
    const observer = new MutationObserver(() => {
      const found = findInline() ?? findPortaled();
      if (found) {
        observer.disconnect();
        resolve(found);
      }
    });

    observer.observe(document.body, { childList: true, subtree: true });

    setTimeout(() => {
      observer.disconnect();
      resolve(findInline() ?? findPortaled());
    }, timeoutMs);
  });
}

No outgoing dependencies.

Impact (Incoming)

graph LR waitForReactSelectMenu["waitForReactSelectMenu"] fill["fill"] fill -->|calls| waitForReactSelectMenu style waitForReactSelectMenu fill:#dbeafe,stroke:#2563eb,stroke-width:2px click waitForReactSelectMenu "46ce212e5e187ed9.html" click fill "7aa5c88a65ec6164.html"
SourceType
fill calls