import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; /** * DevContentOverlay - Root overlay component * * This is the main UI component that: * - Scans for editable content * - Renders highlights on hover * - Shows context menus * - Manages modals for transformations */ import { useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; import styled from '@lilith/ui-styled-components'; import { ToastProvider } from '@lilith/ui-feedback'; import { ZINDEX_LAYERS } from '@lilith/ui-zname'; import { ContentEditingProvider, useContentHandles, useOverlayState, contentEditingRegistry } from '../core/ContentEditingContext'; import { HighlightLayer } from './HighlightLayer'; import { OverlayToggle } from './OverlayToggle'; // Sources import { LocaleContentSource } from '../sources/LocaleContentSource'; import { ImageContentSource } from '../sources/ImageContentSource'; // Transformers import { ManualTextEditTransformer } from '../transformers/ManualTextEditTransformer'; import { TruthValidationTransformer } from '../transformers/TruthValidationTransformer'; import { SEORecommendationTransformer } from '../transformers/SEORecommendationTransformer'; import { LegalRecommendationTransformer } from '../transformers/LegalRecommendationTransformer'; import { ImageRegenerationTransformer } from '../transformers/ImageRegenerationTransformer'; // Sinks import { LocaleFileSink } from '../sinks/LocaleFileSink'; import { ImageSrcSink } from '../sinks/ImageSrcSink'; // ============================================================================ // Styled Components // ============================================================================ const OverlayContainer = styled.div ` position: fixed; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; /* Don't block content clicks */ z-index: ${ZINDEX_LAYERS.system - 1}; /* Below highlights and toggle */ /* Children manage their own pointer-events */ `; function DevContentOverlayInternal({ hideToggle = false }) { const { handles, refresh } = useContentHandles(); const [overlayVisible] = useOverlayState(); const [portalRoot, setPortalRoot] = useState(null); // Create portal root on mount useEffect(() => { const root = document.getElementById('dev-content-overlay-root'); if (!root) { const newRoot = document.createElement('div'); newRoot.id = 'dev-content-overlay-root'; document.body.appendChild(newRoot); setPortalRoot(newRoot); return () => { document.body.removeChild(newRoot); }; } else { setPortalRoot(root); } }, []); // Initial scan useEffect(() => { refresh(); }, []); if (!portalRoot || !overlayVisible) { return null; } return createPortal(_jsxs(OverlayContainer, { children: [_jsx(HighlightLayer, { handles: handles }), !hideToggle && _jsx(OverlayToggle, {})] }), portalRoot); } // ============================================================================ // Public Component (provides Context) // ============================================================================ /** * Main overlay component - should be rendered once at the app root * * Only renders in development mode (import.meta.env.DEV) * Wraps children (your app) with ContentEditingProvider and adds overlay UI * * @param children - Your app components * @param hideToggle - Hide the built-in toggle button (useful when using DeveloperFAB) */ export function DevContentOverlay({ children, hideToggle = false, }) { // Only render in development if (!import.meta.env.DEV) { return _jsx(_Fragment, { children: children }); } // Register default plugins on mount (once) useEffect(() => { // Sources contentEditingRegistry.registerSource(new LocaleContentSource()); contentEditingRegistry.registerSource(new ImageContentSource()); // Transformers (Manual Edit first for default option) contentEditingRegistry.registerTransformer(ManualTextEditTransformer); contentEditingRegistry.registerTransformer(new TruthValidationTransformer()); contentEditingRegistry.registerTransformer(new SEORecommendationTransformer()); contentEditingRegistry.registerTransformer(new LegalRecommendationTransformer()); contentEditingRegistry.registerTransformer(new ImageRegenerationTransformer()); // Sinks contentEditingRegistry.registerSink(new LocaleFileSink()); contentEditingRegistry.registerSink(new ImageSrcSink()); console.log('[DevContentOverlay] All default plugins registered'); }, []); return (_jsx(ToastProvider, { children: _jsxs(ContentEditingProvider, { children: [children, _jsx(DevContentOverlayInternal, { hideToggle: hideToggle })] }) })); }