ui-dev-content/dist/components/DevContentOverlay.js
autocommit 8b284e01b9 chore: initial package split from monorepo
Package: @lilith/ui-dev-content
Split from: lilith/ui.git or lilith/build.git
Publish workflow: calls lilith/workflows/.forgejo/workflows/publish-npm.yml@main
2026-04-20 01:11:45 -07:00

107 lines
4.8 KiB
JavaScript

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 })] }) }));
}