Finding the active element in a shadow root

You can get the focused element with document.activeElement but, if it's inside a shadow root, this will be the host element. This happens because of retargeting, but sometimes you might need access to the internal element that actually has focus.

Here's a recursive function that will return the internal element that has focus, even if it's inside a shadow root.

function getActiveElement(root: Document | ShadowRoot = document): Element | null {
  const activeEl = root.activeElement;

  if (!activeEl) {
    return null;
  }

  if (activeEl.shadowRoot) {
    return getActiveElement(activeEl.shadowRoot);
  } else {
    return activeEl;
  }
}

Usage:

const activeEl = getActiveElement();