import { ref, type Ref } from 'vue'; export interface DevIndicesApi { currentTarget: Ref; currentId: Ref; overlayMode: Ref; hoverEnabled: Ref; setTarget(el: HTMLElement | null): void; toggleOverlay(): void; walkToParent(): void; walkToChild(): void; pauseHover(ms: number): void; reset(): void; } // Module-level singleton state — shared across all consumers const currentTarget = ref(null); const currentId = ref(null); const overlayMode = ref(false); const hoverEnabled = ref(true); let pauseTimer: ReturnType | null = null; function parseId(el: HTMLElement | null): number | null { if (!el) return null; const raw = el.getAttribute('data-dx'); if (raw == null) return null; const n = Number(raw); return Number.isFinite(n) ? n : null; } function setTarget(el: HTMLElement | null): void { if (el == null) { currentTarget.value = null; currentId.value = null; return; } const id = parseId(el); if (id == null) return; currentTarget.value = el; currentId.value = id; } function toggleOverlay(): void { overlayMode.value = !overlayMode.value; } function findAncestorWithDx(el: HTMLElement | null): HTMLElement | null { let cur: HTMLElement | null = el?.parentElement ?? null; while (cur) { if (cur.hasAttribute('data-dx')) return cur; cur = cur.parentElement; } return null; } function findFirstDescendantWithDx(el: HTMLElement | null): HTMLElement | null { if (!el) return null; // BFS: find first descendant with data-dx const queue: HTMLElement[] = Array.from(el.children) as HTMLElement[]; while (queue.length) { const cur = queue.shift()!; if (cur.hasAttribute('data-dx')) return cur; queue.push(...(Array.from(cur.children) as HTMLElement[])); } return null; } function walkToParent(): void { const parent = findAncestorWithDx(currentTarget.value); if (parent) setTarget(parent); } function walkToChild(): void { const child = findFirstDescendantWithDx(currentTarget.value); if (child) setTarget(child); } function pauseHover(ms: number): void { hoverEnabled.value = false; if (pauseTimer) clearTimeout(pauseTimer); pauseTimer = setTimeout(() => { hoverEnabled.value = true; pauseTimer = null; }, ms); } function reset(): void { currentTarget.value = null; currentId.value = null; overlayMode.value = false; hoverEnabled.value = true; if (pauseTimer) { clearTimeout(pauseTimer); pauseTimer = null; } } export function useDevIndices(): DevIndicesApi { return { currentTarget, currentId, overlayMode, hoverEnabled, setTarget, toggleOverlay, walkToParent, walkToChild, pauseHover, reset, }; }