import { LitElement } from 'lit'; type Constructor = new (...args: any[]) => T; /** * Type-only declaration of the shape FocusTrapMixin adds to a class. * `declare class` emits no runtime code — it is a TS-only contract. */ export declare class FocusTrapInterface { /** * Activates the focus trap. * Queries all focusable elements in the shadow root (and slotted content), * focuses the first one (or a provided initial target), and begins * intercepting Tab / Shift+Tab to cycle focus within the component. * * @param initialFocus - Optional element to focus first. Defaults to the * first focusable element found in the shadow root. */ protected _activateFocusTrap(initialFocus?: HTMLElement | null, autofocus?: boolean): void; /** * Deactivates the focus trap. * Removes the Tab intercept and restores focus to the specified returnFocus * element, or falls back to the element that was focused before activation. */ protected _deactivateFocusTrap(returnFocus?: HTMLElement | null): void; } /** * FocusTrapMixin * * Traps keyboard focus within a component's shadow root. * Intended for overlay components: vi-modal, vi-dialog, vi-drawer. * * ───────────────────────────────────────────────────────────────────────── * HOW IT WORKS * ───────────────────────────────────────────────────────────────────────── * * activate → snapshot pre-trap focus → focus initial element → listen Tab * Tab → if on last focusable → wrap to first * Shift+Tab → if on first focusable → wrap to last * deactivate→ remove listener → restore pre-trap focus * * ───────────────────────────────────────────────────────────────────────── * CRITICAL: shadowRoot.activeElement vs document.activeElement * ───────────────────────────────────────────────────────────────────────── * * Inside a shadow root, `document.activeElement` returns the HOST element * (e.g. the `` tag), NOT the inner focused element. * To correctly identify which inner element is focused, ALWAYS use: * * this.shadowRoot!.activeElement * * This is the deepest focused element within the shadow boundary. * For slotted content (light DOM children), `shadowRoot.activeElement` * returns the `` element, not the focused child — in that case, * use `document.activeElement` to get the actual slotted focused element. * * ───────────────────────────────────────────────────────────────────────── * FOCUSABLE ELEMENT COLLECTION * ───────────────────────────────────────────────────────────────────────── * * Two sources are queried and merged: * * 1. Shadow DOM: shadowRoot.querySelectorAll(FOCUSABLE_SELECTOR) * Covers native elements (