The closestAcrossShadow utility works like the native
Element.closest(), but it does not stop at shadow-DOM boundaries.
When the current tree yields no match it continues from the host of the enclosing
shadow root and keeps walking up toward the document, returning the nearest matching
ancestor (or the element itself), or null if there is none.
This is useful when a component nested inside another component's shadow root needs
to locate a shared ancestor — for example a k-context —
which native closest() cannot reach because it never crosses shadow boundaries.
import closestAcrossShadow from './utils/closestAcrossShadow.js';
// From inside a deeply nested component, reach a shared k-context:
const ctx = closestAcrossShadow(this, 'k-context');
const settings = ctx?.get('settings');
element: ElementThe element to start searching from. The element itself is included in the match, just like closest().
selector: stringA CSS selector to match ancestors against.
returns: Element | nullThe nearest matching ancestor across shadow boundaries, or null if none match.
import closestAcrossShadow from './utils/closestAcrossShadow.js';
connectedCallback() {
super.connectedCallback();
const ctx = closestAcrossShadow(this, 'k-context');
ctx?.addEventListener('context:set', () => this.requestUpdate());
}
// No matching ancestor in any tree:
closestAcrossShadow(someDetachedNode, '.missing'); // => null