UNPKG

asimex-visual-editor

Version:

A powerful visual page editor component for React applications

1,749 lines 120 kB
'use client';
'use strict';

var jsxRuntime = require('react/jsx-runtime');
var React = require('react');

/******************************************************************************
Copyright (c) Microsoft Corporation.

Permission to use, copy, modify, and/or distribute this software for any
purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
***************************************************************************** */
/* global Reflect, Promise, SuppressedError, Symbol, Iterator */


var __assign = function() {
    __assign = Object.assign || function __assign(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};

function __spreadArray(to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
}

typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
    var e = new Error(message);
    return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
};

// src/hooks/useEditor.ts
var useEditor = function () {
    var iframeRef = React.useRef(null);
    var _a = React.useState(null), selectedElement = _a[0], setSelectedElement = _a[1];
    var _b = React.useState({}), currentStyles = _b[0], setCurrentStyles = _b[1];
    var _c = React.useState(false), showAssetManager = _c[0], setShowAssetManager = _c[1];
    var _d = React.useState(false), isLoading = _d[0], setIsLoading = _d[1];
    var _e = React.useState(false), hasContent = _e[0], setHasContent = _e[1];
    var sendMessage = React.useCallback(function (message) {
        var _a, _b;
        (_b = (_a = iframeRef.current) === null || _a === void 0 ? void 0 : _a.contentWindow) === null || _b === void 0 ? void 0 : _b.postMessage(message, '*');
    }, []);
    // Inject editor script into HTML
    var injectEditorScript = React.useCallback(function (html) {
        var editorScript = "\n    <script data-editor-script=\"true\">\n      class IframeHelper {\n        constructor() {\n          this.selectedElement = null;\n          this.init();\n        }\n\n        init() {\n          document.addEventListener('mouseover', this.handleMouseOver.bind(this));\n          document.addEventListener('mouseout', this.handleMouseOut.bind(this));\n          document.addEventListener('click', this.handleClick.bind(this));\n          document.addEventListener('dblclick', this.handleDoubleClick.bind(this));\n          window.addEventListener('message', this.handleMessage.bind(this));\n        }\n\n        handleMouseOver(e) {\n  if (this.previewMode) return; // ADD THIS LINE\n  \n  if (e.target !== this.selectedElement && e.target !== document.body && e.target !== document.documentElement) {\n    e.target.style.outline = '2px dashed #007bff';\n  }\n}\n\nhandleMouseOut(e) {\n  if (this.previewMode) return; // ADD THIS LINE\n  \n  if (e.target !== this.selectedElement && e.target !== document.body && e.target !== document.documentElement) {\n    e.target.style.outline = '';\n  }\n}\n\n\n       \n\n     handleClick(e) {\n  if (this.previewMode) return;\n  \n  e.preventDefault();\n  e.stopPropagation();\n\n  if (this.selectedElement) {\n    this.selectedElement.style.outline = '';\n    this.selectedElement.removeAttribute('contenteditable');\n  }\n\n  if (e.target === document.body || e.target === document.documentElement) {\n    return;\n  }\n\n  this.selectedElement = e.target;\n  this.selectedElement.style.outline = '2px solid #007bff';\n\n  // Make element editable immediately\n  const editableTags = ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'SPAN', 'DIV', 'A', 'BUTTON'];\n  if (editableTags.includes(this.selectedElement.tagName)) {\n    this.selectedElement.setAttribute('contenteditable', 'true');\n    this.selectedElement.focus();\n  }\n\n  const elementData = this.getElementData(this.selectedElement);\n  window.parent.postMessage({\n    type: 'ELEMENT_SELECTED',\n    payload: elementData,\n  }, '*');\n}\n        handleDoubleClick(e) {\n          e.preventDefault();\n          e.stopPropagation();\n\n          if (e.target.tagName === 'IMG') {\n            window.parent.postMessage({\n              type: 'OPEN_ASSET_MANAGER',\n              payload: {}\n            }, '*');\n          }\n        }\n\n       handleMessage(e) {\n  const { type, payload } = e.data;\n  \n  switch (type) {\n    case 'APPLY_STYLE':\n      this.applyStyle(payload.selector, payload.styles);\n      break;\n    case 'UPDATE_CLASSES':\n      this.updateClasses(payload.selector, payload.classes);\n      break;\n    case 'DELETE_ELEMENT':\n      this.deleteElement(payload.selector);\n      break;\n    case 'DUPLICATE_ELEMENT':\n      this.duplicateElement(payload.selector);\n      break;\n    case 'GET_HTML':\n      this.exportHTML();\n      break;\n    case 'ADD_BLOCK':\n      this.addBlock(payload.content, payload.targetSelector);\n      break;\n    case 'TOGGLE_PREVIEW_MODE':  // ADD THIS NEW CASE\n      this.togglePreviewMode(payload.preview);\n      break;\n      case 'CLEAR_CANVAS':\n  this.clearCanvas();\n  break;\n  }\n}\n\nclearCanvas() {\n  try {\n    // Clear the body content but keep the script\n    const scripts = document.querySelectorAll('script[data-editor-script=\"true\"]');\n    document.body.innerHTML = '';\n    \n    // Re-add the editor script\n    scripts.forEach(script => {\n      document.body.appendChild(script);\n    });\n    \n    // Reset selected element\n    this.selectedElement = null;\n    \n    // Notify parent\n    window.parent.postMessage({\n      type: 'CANVAS_CLEARED',\n      payload: {}\n    }, '*');\n  } catch (error) {\n    console.error('Error clearing canvas:', error);\n  }\n}\n      // IMPROVED: Better block addition to prevent duplicates\naddBlock(content, targetSelector) {\n  const target = document.querySelector(targetSelector || 'body');\n  if (target && content) {\n    // Create unique ID for this addition\n    const additionId = 'block-' + Date.now() + '-' + Math.random().toString(36).substr(2, 9);\n    \n    // Check if this exact content was just added (prevent duplicates)\n    const recentAdditions = this.recentAdditions || [];\n    const now = Date.now();\n    \n    // Clean old additions (older than 1 second)\n    this.recentAdditions = recentAdditions.filter(a => now - a.timestamp < 1000);\n    \n    // Check for recent duplicate\n    const isDuplicate = this.recentAdditions.some(a => a.content === content);\n    if (isDuplicate) {\n      console.log('Duplicate block addition prevented');\n      return;\n    }\n    \n    // Add to recent additions\n    this.recentAdditions.push({ content, timestamp: now, id: additionId });\n    \n    const tempDiv = document.createElement('div');\n    tempDiv.innerHTML = content;\n    \n    // Add data attribute to track\n    while (tempDiv.firstChild) {\n      const element = tempDiv.firstChild;\n      if (element.nodeType === Node.ELEMENT_NODE) {\n        element.setAttribute('data-block-id', additionId);\n      }\n      target.appendChild(element);\n    }\n    \n    // Notify parent that block was added\n    window.parent.postMessage({\n      type: 'BLOCK_ADDED_SUCCESS',\n      payload: { \n        target: target.tagName,\n        additionId: additionId\n      }\n    }, '*');\n  }\n}\n\ntogglePreviewMode(isPreview) {\n  if (isPreview) {\n    // Hide all editor outlines and make non-editable\n    document.querySelectorAll('[style*=\"outline\"]').forEach(el => {\n      el.style.outline = '';\n    });\n    document.querySelectorAll('[contenteditable]').forEach(el => {\n      el.removeAttribute('contenteditable');\n    });\n    // Disable all editor event listeners\n    this.previewMode = true;\n  } else {\n    // Re-enable editor functionality\n    this.previewMode = false;\n  }\n}\n\n\n        duplicateElement(selector) {\n          const el = document.querySelector(selector);\n          if (el && el !== document.body && el !== document.documentElement) {\n            const clone = el.cloneNode(true);\n            \n            clone.removeAttribute('id');\n            const allElements = clone.querySelectorAll('*');\n            allElements.forEach(child => child.removeAttribute('id'));\n            \n            el.parentNode.insertBefore(clone, el.nextSibling);\n            \n            setTimeout(() => {\n              if (this.selectedElement) {\n                this.selectedElement.style.outline = '';\n              }\n              this.selectedElement = clone;\n              clone.style.outline = '2px solid #007bff';\n              \n              const elementData = this.getElementData(clone);\n              window.parent.postMessage({\n                type: 'ELEMENT_SELECTED',\n                payload: elementData,\n              }, '*');\n            }, 100);\n          }\n        }\n\n        exportHTML() {\n          try {\n            this.cleanupTempStyles();\n            let htmlContent = document.documentElement.outerHTML;\n            htmlContent = this.removeInjectedScript(htmlContent);\n            const styles = this.extractStyles();\n            \n            window.parent.postMessage({\n              type: 'EXPORT_DATA',\n              payload: {\n                html: htmlContent,\n                css: styles\n              }\n            }, '*');\n          } catch (error) {\n            console.error('Export error:', error);\n          }\n        }\n\n        cleanupTempStyles() {\n          document.querySelectorAll('[style*=\"outline\"]').forEach(el => {\n            const style = el.getAttribute('style');\n            if (style) {\n              const cleanedStyle = style\n                .split(';')\n                .filter(s => s.trim() && !s.toLowerCase().includes('outline'))\n                .join(';');\n              \n              if (cleanedStyle.trim()) {\n                el.setAttribute('style', cleanedStyle);\n              } else {\n                el.removeAttribute('style');\n              }\n            }\n          });\n\n          document.querySelectorAll('[contenteditable]').forEach(el => {\n            el.removeAttribute('contenteditable');\n          });\n        }\n\n        removeInjectedScript(html) {\n          return html.replace(/<script[^>]*data-editor-script=[\"']true[\"'][^>]*>[\\s\\S]*?<\\/script>/gi, '').trim();\n        }\n\n        extractStyles() {\n          let styles = '';\n          \n          const elementsWithStyles = document.querySelectorAll('[style]');\n          elementsWithStyles.forEach(el => {\n            const style = el.getAttribute('style');\n            if (style && !style.toLowerCase().includes('outline')) {\n              const selector = this.getUniqueSelector(el);\n              if (selector) {\n                styles += `${selector} { ${style} }\\n`;\n              }\n            }\n          });\n\n          return styles;\n        }\n\n        getUniqueSelector(el) {\n          if (!el) return '';\n          const path = [];\n          \n          while (el && el.nodeType === Node.ELEMENT_NODE) {\n            let selector = el.nodeName.toLowerCase();\n            \n            if (el.id) {\n              selector += '#' + el.id;\n              path.unshift(selector);\n              break;\n            } else {\n              let sibling = el;\n              let nth = 1;\n              while ((sibling = sibling.previousElementSibling)) {\n                if (sibling.nodeName === el.nodeName) nth++;\n              }\n              if (nth > 1) {\n                selector += ':nth-of-type(' + nth + ')';\n              }\n            }\n            \n            path.unshift(selector);\n            el = el.parentElement;\n          }\n          \n          return path.join(' > ');\n        }\n\n        getComputedStyles(el) {\n          const computed = window.getComputedStyle(el);\n          const relevantStyles = {};\n          \n          const styleProps = [\n            'display', 'position', 'top', 'bottom', 'left', 'right', 'z-index',\n            'width', 'height', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left',\n            'padding-top', 'padding-right', 'padding-bottom', 'padding-left',\n            'font-size', 'font-weight', 'color', 'background-color', 'border-width',\n            'border-style', 'border-color', 'border-radius', 'opacity'\n          ];\n          \n          styleProps.forEach(prop => {\n            relevantStyles[prop] = computed.getPropertyValue(prop);\n          });\n          \n          return relevantStyles;\n        }\n\n        getElementData(el) {\n          return {\n            selector: this.getUniqueSelector(el),\n            tagName: el.tagName,\n            id: el.id || '',\n            classes: Array.from(el.classList),\n            textContent: el.textContent?.trim().substring(0, 50) || '',\n            computedStyles: this.getComputedStyles(el)\n          };\n        }\n\n        applyStyle(selector, styles) {\n          const el = document.querySelector(selector);\n          if (el) {\n            if (styles.src && el.tagName === 'IMG') {\n              el.src = styles.src;\n              delete styles.src;\n            }\n            \n            Object.assign(el.style, styles);\n          }\n        }\n\n        updateClasses(selector, classes) {\n          const el = document.querySelector(selector);\n          if (el) {\n            el.className = classes.join(' ');\n          }\n        }\n\n        deleteElement(selector) {\n          const el = document.querySelector(selector);\n          if (el && el !== document.body && el !== document.documentElement) {\n            el.remove();\n          }\n        }\n      }\n\n      new IframeHelper();\n    </script>\n    ";
        // Clean HTML input
        var cleanHtml = html.trim();
        // If it's not a complete document, wrap it
        if (!cleanHtml.toLowerCase().includes('<!doctype') && !cleanHtml.toLowerCase().includes('<html')) {
            cleanHtml = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Visual Editor</title>\n</head>\n<body>\n".concat(cleanHtml, "\n</body>\n</html>");
        }
        // Inject script before closing body tag
        if (cleanHtml.includes('</body>')) {
            return cleanHtml.replace('</body>', "".concat(editorScript, "</body>"));
        }
        else {
            return cleanHtml + editorScript;
        }
    }, []);
    // Load HTML content and inject editor script
    var loadHTMLContent = React.useCallback(function (htmlContent) {
        if (!htmlContent.trim())
            return;
        setIsLoading(true);
        try {
            var modifiedHTML = injectEditorScript(htmlContent);
            var blob = new Blob([modifiedHTML], { type: 'text/html; charset=utf-8' });
            var blobUrl = URL.createObjectURL(blob);
            if (iframeRef.current) {
                iframeRef.current.src = blobUrl;
                setHasContent(true);
            }
        }
        catch (error) {
            console.error('Error loading HTML content:', error);
        }
        finally {
            setIsLoading(false);
        }
    }, [injectEditorScript]);
    // Add block functionality
    var addBlock = React.useCallback(function (content, targetSelector) {
        sendMessage({
            type: 'ADD_BLOCK',
            payload: {
                content: content,
                targetSelector: targetSelector || 'body'
            }
        });
    }, [sendMessage]);
    // Export functionality
    var exportHTML = React.useCallback(function () {
        if (!hasContent)
            return;
        sendMessage({
            type: 'GET_HTML',
            payload: {}
        });
    }, [sendMessage, hasContent]);
    // Handle element selection
    var handleElementSelected = React.useCallback(function (payload) {
        setSelectedElement(payload || null);
        setCurrentStyles((payload === null || payload === void 0 ? void 0 : payload.computedStyles) || {});
    }, []);
    // Handle asset manager
    var handleOpenAssetManager = React.useCallback(function () {
        setShowAssetManager(true);
    }, []);
    // Update style
    var updateStyle = React.useCallback(function (property, value) {
        var _a;
        setCurrentStyles(function (prev) {
            var _a;
            return (__assign(__assign({}, prev), (_a = {}, _a[property] = value, _a)));
        });
        if (selectedElement) {
            sendMessage({
                type: 'APPLY_STYLE',
                payload: {
                    selector: selectedElement.selector,
                    styles: (_a = {}, _a[property] = value, _a),
                },
            });
        }
    }, [selectedElement, sendMessage]);
    // Update classes
    var updateClasses = React.useCallback(function (classes) {
        if (selectedElement) {
            var updatedElement = __assign(__assign({}, selectedElement), { classes: classes });
            setSelectedElement(updatedElement);
            sendMessage({
                type: 'UPDATE_CLASSES',
                payload: {
                    selector: selectedElement.selector,
                    classes: classes,
                },
            });
        }
    }, [selectedElement, sendMessage]);
    // Delete element
    var deleteElement = React.useCallback(function () {
        if (selectedElement) {
            sendMessage({
                type: 'DELETE_ELEMENT',
                payload: { selector: selectedElement.selector },
            });
            setSelectedElement(null);
        }
    }, [selectedElement, sendMessage]);
    // Copy element
    var copyElement = React.useCallback(function () {
        if (selectedElement) {
            sendMessage({
                type: 'DUPLICATE_ELEMENT',
                payload: { selector: selectedElement.selector },
            });
        }
    }, [selectedElement, sendMessage]);
    // Handle asset selection
    var handleAssetSelect = React.useCallback(function (assetUrl) {
        if (selectedElement && selectedElement.tagName === 'IMG') {
            sendMessage({
                type: 'APPLY_STYLE',
                payload: {
                    selector: selectedElement.selector,
                    styles: { src: assetUrl },
                },
            });
        }
    }, [selectedElement, sendMessage]);
    // Return all methods
    return {
        iframeRef: iframeRef,
        selectedElement: selectedElement,
        currentStyles: currentStyles,
        showAssetManager: showAssetManager,
        isLoading: isLoading,
        hasContent: hasContent,
        setShowAssetManager: setShowAssetManager,
        handleAssetSelect: handleAssetSelect,
        handleElementSelected: handleElementSelected,
        handleOpenAssetManager: handleOpenAssetManager,
        updateStyle: updateStyle,
        updateClasses: updateClasses,
        deleteElement: deleteElement,
        copyElement: copyElement,
        loadHTMLContent: loadHTMLContent,
        exportHTML: exportHTML,
        addBlock: addBlock,
    };
};

// src/components/Editor/EditorCanvas.tsx (Complete Fix)
var EditorCanvas = React.forwardRef(function (_a, ref) {
    var src = _a.src, style = _a.style, className = _a.className;
    return (jsxRuntime.jsx("iframe", { ref: ref, src: src || "about:blank", className: className, style: __assign({ border: 'none', backgroundColor: '#fff' }, style), title: "Visual Editor Canvas" }));
});
EditorCanvas.displayName = 'EditorCanvas';

var AssetManager = function (_a) {
    var isOpen = _a.isOpen, onClose = _a.onClose, onSelectAsset = _a.onSelectAsset; _a.selectedElement;
    var _b = React.useState(''), searchTerm = _b[0], setSearchTerm = _b[1];
    var _c = React.useState([]), uploadedAssets = _c[0], setUploadedAssets = _c[1];
    var stockImages = [
        'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=400&h=300&fit=crop',
        'https://images.unsplash.com/photo-1441974231531-c6227db76b6e?w=400&h=300&fit=crop',
        'https://images.unsplash.com/photo-1470071459604-3b5ec3a7fe05?w=400&h=300&fit=crop',
        'https://images.unsplash.com/photo-1508193638397-1c4234db14d8?w=400&h=300&fit=crop',
        'https://images.unsplash.com/photo-1469474968028-56623f02e42e?w=400&h=300&fit=crop',
        'https://images.unsplash.com/photo-1501594907352-04cda38ebc29?w=400&h=300&fit=crop',
        'https://images.unsplash.com/photo-1472214103451-9374bd1c798e?w=400&h=300&fit=crop',
        'https://images.unsplash.com/photo-1518837695005-2083093ee35b?w=400&h=300&fit=crop',
    ];
    var handleFileUpload = function (e) {
        var files = e.target.files;
        if (files) {
            Array.from(files).forEach(function (file) {
                var reader = new FileReader();
                reader.onload = function (event) {
                    var _a;
                    if ((_a = event.target) === null || _a === void 0 ? void 0 : _a.result) {
                        setUploadedAssets(function (prev) { return __spreadArray(__spreadArray([], prev, true), [event.target.result], false); });
                    }
                };
                reader.readAsDataURL(file);
            });
        }
    };
    var allImages = __spreadArray(__spreadArray([], uploadedAssets, true), stockImages, true);
    var filteredImages = searchTerm
        ? allImages.filter(function (_, index) { return index.toString().includes(searchTerm); })
        : allImages;
    if (!isOpen)
        return null;
    return (jsxRuntime.jsx("div", { style: {
            position: 'fixed',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            backgroundColor: 'rgba(0, 0, 0, 0.8)',
            zIndex: 10000,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center'
        }, children: jsxRuntime.jsxs("div", { style: {
                backgroundColor: '#333',
                borderRadius: '8px',
                padding: '24px',
                width: '90%',
                maxWidth: '800px',
                maxHeight: '80%',
                overflow: 'hidden',
                display: 'flex',
                flexDirection: 'column'
            }, children: [jsxRuntime.jsxs("div", { style: {
                        display: 'flex',
                        justifyContent: 'space-between',
                        alignItems: 'center',
                        marginBottom: '20px',
                        color: '#fff'
                    }, children: [jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: '20px' }, children: "Asset Manager" }), jsxRuntime.jsx("button", { onClick: onClose, style: {
                                background: 'none',
                                border: 'none',
                                color: '#fff',
                                fontSize: '24px',
                                cursor: 'pointer'
                            }, children: "\u2715" })] }), jsxRuntime.jsxs("div", { style: {
                        marginBottom: '20px',
                        padding: '16px',
                        backgroundColor: '#444',
                        borderRadius: '6px',
                        border: '2px dashed #666'
                    }, children: [jsxRuntime.jsx("input", { type: "file", multiple: true, accept: "image/*", onChange: handleFileUpload, style: { display: 'none' }, id: "file-upload" }), jsxRuntime.jsx("label", { htmlFor: "file-upload", style: {
                                display: 'block',
                                textAlign: 'center',
                                color: '#ccc',
                                cursor: 'pointer',
                                padding: '12px'
                            }, children: "\uD83D\uDCC1 Click to upload images or drag and drop" })] }), jsxRuntime.jsx("div", { style: { marginBottom: '20px' }, children: jsxRuntime.jsx("input", { type: "text", placeholder: "Search images...", value: searchTerm, onChange: function (e) { return setSearchTerm(e.target.value); }, style: {
                            width: '100%',
                            padding: '10px',
                            backgroundColor: '#555',
                            border: '1px solid #666',
                            borderRadius: '4px',
                            color: '#fff',
                            fontSize: '14px'
                        } }) }), jsxRuntime.jsx("div", { style: {
                        flex: 1,
                        overflowY: 'auto',
                        display: 'grid',
                        gridTemplateColumns: 'repeat(auto-fill, minmax(120px, 1fr))',
                        gap: '12px',
                        padding: '4px'
                    }, children: filteredImages.map(function (imageUrl, index) { return (jsxRuntime.jsx("div", { onClick: function () {
                            onSelectAsset(imageUrl);
                            onClose();
                        }, style: {
                            aspectRatio: '1',
                            backgroundImage: "url(".concat(imageUrl, ")"),
                            backgroundSize: 'cover',
                            backgroundPosition: 'center',
                            borderRadius: '6px',
                            cursor: 'pointer',
                            border: '2px solid transparent',
                            transition: 'all 0.2s ease'
                        }, onMouseEnter: function (e) {
                            e.currentTarget.style.borderColor = '#007bff';
                            e.currentTarget.style.transform = 'scale(1.05)';
                        }, onMouseLeave: function (e) {
                            e.currentTarget.style.borderColor = 'transparent';
                            e.currentTarget.style.transform = 'scale(1)';
                        } }, index)); }) }), jsxRuntime.jsxs("div", { style: {
                        marginTop: '20px',
                        display: 'flex',
                        justifyContent: 'space-between',
                        alignItems: 'center',
                        color: '#ccc',
                        fontSize: '12px'
                    }, children: [jsxRuntime.jsxs("span", { children: [filteredImages.length, " images available"] }), jsxRuntime.jsx("button", { onClick: onClose, style: {
                                padding: '8px 16px',
                                backgroundColor: '#666',
                                border: '1px solid #777',
                                borderRadius: '4px',
                                color: '#fff',
                                cursor: 'pointer'
                            }, children: "Cancel" })] })] }) }));
};

// src/components/Editor/HTMLLoader.tsx
var HTMLLoader = function (_a) {
    var isOpen = _a.isOpen, onClose = _a.onClose, onSubmit = _a.onSubmit;
    var _b = React.useState(''), htmlContent = _b[0], setHtmlContent = _b[1];
    var _c = React.useState('paste'), activeTab = _c[0], setActiveTab = _c[1];
    if (!isOpen)
        return null;
    var handleSubmit = function (e) {
        e.preventDefault();
        if (!htmlContent.trim()) {
            alert('Please enter HTML content');
            return;
        }
        onSubmit(htmlContent);
        setHtmlContent('');
        onClose();
    };
    var handleFileUpload = function (e) {
        var _a;
        var file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
        if (file && file.type === 'text/html') {
            var reader = new FileReader();
            reader.onload = function (event) {
                var _a;
                if ((_a = event.target) === null || _a === void 0 ? void 0 : _a.result) {
                    setHtmlContent(event.target.result);
                }
            };
            reader.readAsText(file);
        }
    };
    var sampleHTML = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n    <title>Sample Page</title>\n    <style>\n        body { font-family: Arial, sans-serif; margin: 40px; }\n        .container { max-width: 800px; margin: 0 auto; }\n        .hero { background: #f0f0f0; padding: 30px; border-radius: 8px; }\n    </style>\n</head>\n<body>\n    <div class=\"container\">\n        <div class=\"hero\">\n            <h1>Welcome to Visual Editor</h1>\n            <p>This is a sample HTML page. Click on any element to start editing!</p>\n            <img src=\"https://via.placeholder.com/400x200\" alt=\"Sample Image\" />\n            <button style=\"padding: 10px 20px; margin: 10px 0;\">Click Me</button>\n        </div>\n    </div>\n</body>\n</html>";
    return (jsxRuntime.jsx("div", { style: {
            position: 'fixed',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            backgroundColor: 'rgba(0, 0, 0, 0.8)',
            zIndex: 10000,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center'
        }, children: jsxRuntime.jsxs("div", { style: {
                backgroundColor: '#333',
                borderRadius: '8px',
                padding: '24px',
                width: '90%',
                maxWidth: '700px',
                maxHeight: '80%',
                color: '#fff',
                display: 'flex',
                flexDirection: 'column'
            }, children: [jsxRuntime.jsxs("div", { style: {
                        display: 'flex',
                        justifyContent: 'space-between',
                        alignItems: 'center',
                        marginBottom: '20px'
                    }, children: [jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: '18px' }, children: "Load HTML Content" }), jsxRuntime.jsx("button", { onClick: onClose, style: {
                                background: 'none',
                                border: 'none',
                                color: '#fff',
                                fontSize: '24px',
                                cursor: 'pointer'
                            }, children: "\u2715" })] }), jsxRuntime.jsxs("div", { style: { display: 'flex', marginBottom: '20px', gap: '4px' }, children: [jsxRuntime.jsx("button", { onClick: function () { return setActiveTab('paste'); }, style: {
                                padding: '8px 16px',
                                backgroundColor: activeTab === 'paste' ? '#007bff' : '#555',
                                border: '1px solid #666',
                                borderRadius: '4px 4px 0 0',
                                color: '#fff',
                                cursor: 'pointer'
                            }, children: "Paste HTML" }), jsxRuntime.jsx("button", { onClick: function () { return setActiveTab('upload'); }, style: {
                                padding: '8px 16px',
                                backgroundColor: activeTab === 'upload' ? '#007bff' : '#555',
                                border: '1px solid #666',
                                borderRadius: '4px 4px 0 0',
                                color: '#fff',
                                cursor: 'pointer'
                            }, children: "Upload File" })] }), jsxRuntime.jsxs("form", { onSubmit: handleSubmit, style: { flex: 1, display: 'flex', flexDirection: 'column' }, children: [activeTab === 'paste' ? (jsxRuntime.jsxs("div", { style: { flex: 1, display: 'flex', flexDirection: 'column' }, children: [jsxRuntime.jsxs("div", { style: { marginBottom: '12px', display: 'flex', gap: '8px' }, children: [jsxRuntime.jsx("button", { type: "button", onClick: function () { return setHtmlContent(sampleHTML); }, style: {
                                                padding: '6px 12px',
                                                backgroundColor: '#666',
                                                border: '1px solid #777',
                                                borderRadius: '4px',
                                                color: '#fff',
                                                cursor: 'pointer',
                                                fontSize: '12px'
                                            }, children: "Load Sample HTML" }), jsxRuntime.jsx("button", { type: "button", onClick: function () { return setHtmlContent(''); }, style: {
                                                padding: '6px 12px',
                                                backgroundColor: '#666',
                                                border: '1px solid #777',
                                                borderRadius: '4px',
                                                color: '#fff',
                                                cursor: 'pointer',
                                                fontSize: '12px'
                                            }, children: "Clear" })] }), jsxRuntime.jsx("textarea", { value: htmlContent, onChange: function (e) { return setHtmlContent(e.target.value); }, placeholder: "Paste your HTML content here...", style: {
                                        flex: 1,
                                        minHeight: '300px',
                                        padding: '12px',
                                        backgroundColor: '#444',
                                        border: '1px solid #666',
                                        borderRadius: '4px',
                                        color: '#fff',
                                        fontSize: '14px',
                                        fontFamily: 'monospace',
                                        resize: 'vertical'
                                    } })] })) : (jsxRuntime.jsxs("div", { style: { marginBottom: '16px' }, children: [jsxRuntime.jsx("label", { style: {
                                        display: 'block',
                                        marginBottom: '8px',
                                        fontSize: '14px',
                                        color: '#ccc'
                                    }, children: "Upload HTML File:" }), jsxRuntime.jsx("input", { type: "file", accept: ".html,.htm", onChange: handleFileUpload, style: {
                                        width: '100%',
                                        padding: '12px',
                                        backgroundColor: '#444',
                                        border: '1px solid #666',
                                        borderRadius: '4px',
                                        color: '#fff',
                                        fontSize: '14px'
                                    } })] })), jsxRuntime.jsxs("div", { style: {
                                display: 'flex',
                                gap: '12px',
                                justifyContent: 'flex-end',
                                marginTop: '16px'
                            }, children: [jsxRuntime.jsx("button", { type: "button", onClick: onClose, style: {
                                        padding: '10px 20px',
                                        backgroundColor: '#666',
                                        border: '1px solid #777',
                                        borderRadius: '4px',
                                        color: '#fff',
                                        cursor: 'pointer'
                                    }, children: "Cancel" }), jsxRuntime.jsx("button", { type: "submit", style: {
                                        padding: '10px 20px',
                                        backgroundColor: '#007bff',
                                        border: '1px solid #0066cc',
                                        borderRadius: '4px',
                                        color: '#fff',
                                        cursor: 'pointer'
                                    }, children: "Load HTML" })] })] })] }) }));
};

var ExportModal = function (_a) {
    var isOpen = _a.isOpen, onClose = _a.onClose, data = _a.data;
    if (!isOpen || !data)
        return null;
    var downloadFile = function (content, filename, type) {
        var blob = new Blob([content], { type: type });
        var url = URL.createObjectURL(blob);
        var a = document.createElement('a');
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
    };
    var handleDownloadHTML = function () {
        downloadFile(data.html, 'edited-page.html', 'text/html');
    };
    var handleDownloadCSS = function () {
        downloadFile(data.css, 'styles.css', 'text/css');
    };
    var handleDownloadBoth = function () {
        // Create a combined HTML file with embedded styles
        var combinedHTML = data.html.replace('</head>', "<style>\n".concat(data.css, "\n</style>\n</head>"));
        downloadFile(combinedHTML, 'edited-page-with-styles.html', 'text/html');
    };
    return (jsxRuntime.jsx("div", { style: {
            position: 'fixed',
            top: 0,
            left: 0,
            right: 0,
            bottom: 0,
            backgroundColor: 'rgba(0, 0, 0, 0.8)',
            zIndex: 10000,
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center'
        }, children: jsxRuntime.jsxs("div", { style: {
                backgroundColor: '#333',
                borderRadius: '8px',
                padding: '24px',
                width: '90%',
                maxWidth: '800px',
                maxHeight: '80%',
                color: '#fff',
                display: 'flex',
                flexDirection: 'column'
            }, children: [jsxRuntime.jsxs("div", { style: {
                        display: 'flex',
                        justifyContent: 'space-between',
                        alignItems: 'center',
                        marginBottom: '20px'
                    }, children: [jsxRuntime.jsx("h2", { style: { margin: 0, fontSize: '20px' }, children: "Export HTML & CSS" }), jsxRuntime.jsx("button", { onClick: onClose, style: {
                                background: 'none',
                                border: 'none',
                                color: '#fff',
                                fontSize: '24px',
                                cursor: 'pointer'
                            }, children: "\u2715" })] }), jsxRuntime.jsxs("div", { style: {
                        display: 'flex',
                        gap: '16px',
                        marginBottom: '20px'
                    }, children: [jsxRuntime.jsx("button", { onClick: handleDownloadHTML, style: {
                                padding: '12px 20px',
                                backgroundColor: '#4CAF50',
                                border: 'none',
                                borderRadius: '4px',
                                color: '#fff',
                                cursor: 'pointer',
                                fontSize: '14px'
                            }, children: "\uD83D\uDCC4 Download HTML" }), jsxRuntime.jsx("button", { onClick: handleDownloadCSS, style: {
                                padding: '12px 20px',
                                backgroundColor: '#2196F3',
                                border: 'none',
                                borderRadius: '4px',
                                color: '#fff',
                                cursor: 'pointer',
                                fontSize: '14px'
                            }, children: "\uD83C\uDFA8 Download CSS" }), jsxRuntime.jsx("button", { onClick: handleDownloadBoth, style: {
                                padding: '12px 20px',
                                backgroundColor: '#FF9800',
                                border: 'none',
                                borderRadius: '4px',
                                color: '#fff',
                                cursor: 'pointer',
                                fontSize: '14px'
                            }, children: "\uD83D\uDCE6 Download Combined" })] }), jsxRuntime.jsxs("div", { style: { flex: 1, display: 'flex', gap: '16px' }, children: [jsxRuntime.jsxs("div", { style: { flex: 1 }, children: [jsxRuntime.jsx("h3", { style: { fontSize: '16px', marginBottom: '8px' }, children: "HTML Content" }), jsxRuntime.jsx("textarea", { value: data.html, readOnly: true, style: {
                                        width: '100%',
                                        height: '300px',
                                        backgroundColor: '#2a2a2a',
                                        color: '#f8f8f2',
                                        border: '1px solid #555',
                                        borderRadius: '4px',
                                        padding: '12px',
                                        fontSize: '12px',
                                        fontFamily: 'monospace',
                                        resize: 'none'
                                    } })] }), jsxRuntime.jsxs("div", { style: { flex: 1 }, children: [jsxRuntime.jsx("h3", { style: { fontSize: '16px', marginBottom: '8px' }, children: "CSS Styles" }), jsxRuntime.jsx("textarea", { value: data.css, readOnly: true, style: {
                                        width: '100%',
                                        height: '300px',
                                        backgroundColor: '#2a2a2a',
                                        color: '#f8f8f2',
                                        border: '1px solid #555',
                                        borderRadius: '4px',
                                        padding: '12px',
                                        fontSize: '12px',
                                        fontFamily: 'monospace',
                                        resize: 'none'
                                    } })] })] })] }) }));
};

// src/components/DeviceManager/index.tsx
// Update your defaultDevices in DeviceManager:
var defaultDevices = [
    {
        id: 'desktop',
        name: 'Desktop',
        width: '100%',
        height: '100%',
        icon: '🖥️'
    },
    {
        id: 'tablet',
        name: 'Tablet',
        width: 768,
        height: 1024,
        icon: '📱'
    },
    {
        id: 'mobile',
        name: 'Mobile',
        width: 375,
        height: 667,
        icon: '📱'
    },
];
var DeviceManager = function (_a) {
    var _b;
    var _c = _a.devices, devices = _c === void 0 ? defaultDevices : _c, selectedDeviceId = _a.selectedDeviceId, onDeviceChange = _a.onDeviceChange, style = _a.style;
    var _d = React.useState(selectedDeviceId || ((_b = devices[0]) === null || _b === void 0 ? void 0 : _b.id)), currentDeviceId = _d[0], setCurrentDeviceId = _d[1];
    React.useEffect(function () {
        var device = devices.find(function (d) { return d.id === currentDeviceId; });
        if (device) {
            onDeviceChange(device);
        }
    }, [currentDeviceId, devices, onDeviceChange]);
    return (jsxRuntime.jsxs("div", { style: __assign({ display: 'flex', gap: '8px', padding: '8px 16px', backgroundColor: '#333', borderBottom: '1px solid #555', alignItems: 'center' }, style), children: [jsxRuntime.jsx("span", { style: { color: '#ccc', fontSize: '12px', marginRight: '8px' }, children: "Device:" }), devices.map(function (device) { return (jsxRuntime.jsxs("button", { onClick: function () { return setCurrentDeviceId(device.id); }, style: {
                    backgroundColor: currentDeviceId === device.id ? '#007bff' : '#555',
                    color: 'white',
                    border: 'none',
                    borderRadius: '4px',
                    padding: '6px 12px',
                    cursor: 'pointer',
                    fontSize: '12px',
                    display: 'flex',
                    alignItems: 'center',
                    gap: '4px',
                    transition: 'background-color 0.2s'
                }, title: "".concat(device.name, " (").concat(device.width, " \u00D7 ").concat(device.height, ")"), children: [device.icon && jsxRuntime.jsx("span", { children: device.icon }), jsxRuntime.jsx("span", { children: device.name })] }, device.id)); })] }));
};

// src/components/BlockManager/DraggableBlockManager.tsx (Fixed duplicates)
var DraggableBlockManager = function (_a) {
    var blocks = _a.blocks, onAddBlock = _a.onAddBlock, iframeRef = _a.iframeRef, style = _a.style;
    var _b = React.useState('all'), selectedCategory = _b[0], setSelectedCategory = _b[1];
    var _c = React.useState(false), isDragging = _c[0], setIsDragging = _c[1];
    var filteredBlocks = selectedCategory === 'all'
        ? blocks
        : blocks.filter(function (block) { return block.category === selectedCategory; });
    var uniqueCategories = __spreadArray(['all'], Array.from(new Set(blocks.map(function (b) { return b.category; }).filter(Boolean))), true);
    // FIXED: Single drag handler to prevent duplicates
    var handleDragStart = React.useCallback(function (e, block) {
        console.log('Drag start:', block.label);
        setIsDragging(true);
        e.dataTransfer.setData('text/html', block.content);
        e.dataTransfer.setData('application/json', JSON.stringify(block));
        e.dataTransfer.effectAllowed = 'copy';
        // Visual feedback
        e.currentTarget.style.opacity = '0.5';
        e.currentTarget.style.transform = 'scale(0.95)';
    }, []);
    var handleDragEnd = React.useCallback(function (e) {
        console.log('Drag end');
        setIsDragging(false);
        // Reset visual feedback
        e.currentTarget.style.opacity = '1';
        e.currentTarget.style.transform = 'scale(1)';
    }, []);
    // FIXED: Separate click handler with drag state check
    var handleBlockClick = React.useCallback(function (block, e) {
        e.preventDefault();
        e.stopPropagation();
        // Don't trigger click if we just finished dragging
        if (isDragging) {
            return;
        }
        console.log('Block clicked:', block.label);
        onAddBlock(block.content, block);
    }, [onAddBlock, isDragging]);
    // Setup drop zone on iframe
    React.useEffect(function () {
        if (!(iframeRef === null || iframeRef === void 0 ? void 0 : iframeRef.current))
            return;
        var iframe = iframeRef.current;
        var dragCounter = 0; // Track drag enter/leave
        var setupDropZone = function () {
            var _a;
            try {
                var iframeDoc_1 = iframe.contentDocument || ((_a = iframe.contentWindow) === null || _a === void 0 ? void 0 : _a.document);
                if (!iframeDoc_1)
                    return;
                var handleDragEnter = function (e) {
                    e.preventDefault();
                    dragCounter++;
                    // Add visual feedback to iframe
                    if (dragCounter === 1) {
                        iframeDoc_1.body.style.backgroundColor = 'rgba(0, 123, 255, 0.1)';
                        iframeDoc_1.body.style.outline = '2px dashed #007bff';
                    }
                };
                var handleDragLeave = function (e) {
                    e.preventDefault();
                    dragCounter--;
                    // Remove visual feedback when completely leaving
                    if (dragCounter === 0) {
                        iframeDoc_1.body.style.backgroundColor = '';
                        iframeDoc_1.body.style.outline = '';
                    }
                };
                var handleDragOver = function (e) {
                    e.preventDefault();
                    e.dataTransfer.dropEffect = 'copy';
                };
                var handleDrop = function (e) {
                    e.preventDefault();
                    dragCounter = 0;
                    // Reset visual feedback
                    iframeDoc_1.body.style.backgroundColor = '';
                    iframeDoc_1.body.style.outline = '';
                    var htmlContent = e.dataTransfer.getData('text/html');
                    var blockData = e.dataTransfer.getData('application/json');
                    if (htmlContent && blockData) {
                        try {
                            var block = JSON.parse(blockData);
                            console.log('Block dropped:', block.label);
                            // Find the appropriate drop target
                            var targetElement = e.target;
                            // Navigate up to find a suitable container
                            while (targetElement && targetElement !== iframeDoc_1.body) {
                                if (['DIV', 'SECTION', 'MAIN', 'ARTICLE', 'HEADER', 'FOOTER'].includes(targetElement.tagName)) {
                                    break;
                                }
                                targetElement = targetElement.parentElement;
                            }
                            if (!targetElement) {
                                targetElement = iframeDoc_1.body;
                            }
                            // Create and insert the new element
                            var tempDiv = document.createElement('div');
                            tempDiv.innerHTML = htmlContent;
                            // Add each element from the block
                            while (tempDiv.firstChild) {
                                targetElement.appendChild(tempDiv.firstChild);
                            }
                            // Notify parent
                            window.parent.postMessage({
                                type: 'BLOCK_ADDED_SUCCESS',
                                payload: { block: block, target: targetElement.tagName }
                            }, '*');
                        }
                        catch (error) {
                            console.error('Error adding block via drop:', error);
                        }
                    }
                };
                // Clean up existing listeners
                iframeDoc_1.removeEventListener('dragenter', handleDragEnter);
                iframeDoc_1.removeEventListener('dragleave', handleDragLeave);
                iframeDoc_1.removeEventListener('dragover', handleDragOver);
                iframeDoc_1.removeEventListener('drop', handleDrop);
                // Add new listeners
                iframeDoc_1.addEventListener('dragenter', handleDragEnter);
                iframeDoc_1.addEventListener('dragleave', handleDragLeave);
                iframeDoc_1.addEventListener('dragover', handleDragOver);
                iframeDoc_1.addEventListener('drop', handleDrop);
            }
            catch (error) {
                console.warn('Cannot setup drop zone:', error);
            }
        };
        iframe.addEventListener('load', setupDropZone);
        if (iframe.contentDocument) {
            setupDropZone();
        }
        return function () {
            iframe.removeEventListener('load', setupDropZone);
        };
    }, [iframeRef, onAddBlock]);
    return (jsxRuntime.jsxs("div", { style: __assign({ display: 'flex', flexDirection: 'column', height: '100%', backgroundColor: '#444', color: '#fff' }, style), children: [jsxRuntime.jsx("div", { style: {
                    padding: '12px 16px',
                    borderBottom: '1px solid #555',
                    backgroundColor: '#333'
                }, children: jsxRuntime.jsx("h3", { style: { margin: 0, fontSize: '14px', fontWeight: 'bold' }, children: "\uD83D\uDCE6 Blocks" }) }), uniqueCategories.length > 1 && (jsxRuntime.jsx("div", { style: {
                    padding: '8px 16px',
                    borderBottom: '1px solid #555'
                }, children: jsxRuntime.jsx("select", { value: selectedCategory, onChange: function (e) { return setSelectedCategory(e.target.value); }, style: {
                        width: '100%',
                        padding: '6px',
                        backgroundColor: '#555',
                        color: '#fff',
                        border: '1px solid #666',
                        borderRadius: '4px',
                        fontSize: '12px'
                    }, children: uniqueCategories.map(function (category) { return (jsxRuntime.jsx("option", { value: category, children: category ? category.charAt(0).toUpperCase() + category.slice(1) : 'All' }, category)); }) }) })), jsxRuntime.jsxs("div", { style: {
                    flex: 1,
                    overflowY: 'auto',
                    padding: '8px'
                }, children: [jsxRuntime.jsx("div", { style: {
                            display: 'grid',
                            gridTemplateColumns: 'repeat(auto-fill, minmax(80px, 1fr))',
                            gap: '8px'
                        }, children: filteredBlocks.map(function (block) { return (jsxRuntime.jsxs("div", { draggable: true, onDragStart: function (e) { return handleDragStart(e, block); }, onDragEnd: handleDragEnd, onClick: function (e) { return handleBlockClick(block, e); }, style: {
                                backgroundColor: '#555',
                                borderRadius: '6px',
                                padding: '8px',
                                cursor: 'grab',
                                textAlign: 'center',
                                transition: 'all 0.2s ease',
                                border: '2px solid transparent',
                                position: 'relative',
                                userSelect: 'none'
                            }, onMouseEnter: function (e) {
                                if (!isDragging) {
                                    e.currentTarget.style.backgroundColor = '#666';
                                    e.currentTarget.style.borderColor = '#007bff';
                                    e.currentTarget.style.transform = 'scale(1.02)';
                                }
                            }, onMouseLeave: function (e) {
                                if (!isDragging) {
                                    e.currentTarget.style.backgroundColor = '#555';
                                    e.currentTarget.style.borderColor = 'transparent';
                                    e.currentTarget.style.transform = 'scale(1)';
                                }
                            }, title: "".concat(block.label, " - Drag to canvas or click to add to body"), children: [jsxRuntime.jsx("div", { style: {
                                        position: 'absolute',
                                        top: '4px',
                                        right: '4px',
                                        fontSize: '8px',
                                        color: '#aaa',
                                        lineHeight: 1
                                    }, children: "\u22EE\u22EE" }), block.thumbnailUrl ? (jsxRuntime.jsx("img", { src: block.thumbnailUrl, alt: block.label, style: {
                                        width: '100%',
                                        height: '50px',
                                        objectFit: 'cover',
                                        borderRadius: '4px',
                                        marginBottom: '4px',
                                        pointerEvents: 'none'
                                    } })) : (jsxRuntime.jsx("div", { style: {
                                        width: '100%',
                                        height: '50px',
                                        backgroundColor: '#666',
                                        borderRadius: '4px',
                                        display: 'flex',
                                        alignItems: 'center',
                                        justifyContent: 'center',
                                        fontSize: '20px',
                                        marginBottom: '4px'
                                    }, children: block.icon || '📄' })), jsxRuntime.jsx("div", { style: { fontSize: '10px', color: '#ccc', lineHeight: 1.2 }, children: block.label })] }, block.id)); }) }), filteredBlocks.length === 0 && (jsxRuntime.jsx("div", { style: {
                            textAlign: 'center',
                            color: '#666',
                            padding: '40px 20px',
                            fontSize: '14px'
                        }, children: "No blocks available" }))] }), jsxRuntime.jsx("div", { style: {
                    padding: '8px 12px',
                    borderTop: '1px solid #555',
                    backgroundColor: '#333',
                    fontSize: '11px',
                    color: '#aaa',
                    textAlign: 'center'
                }, children: "\uD83D\uDCA1 Drag to canvas or click to add to body" })] }));
};

var ClassTag = function (_a) {
    var className = _a.className, onRemove = _a.onRemove;
    return (jsxRuntime.jsxs("div", { style: {
            display: 'flex',
            alignItems: 'center',
            backgroundColor: '#8e44ad',
            padding: '4px 8px',
            borderRadius: '4px',
            fontSize: '12px',
            margin: '2px'
        }, children: [jsxRuntime.jsx("span", { children: className }), jsxRuntime.jsx("button", { onClick: function () { return onRemove(className); }, style: {
                    marginLeft: '6px',
                    background: 'none',
                    border: 'none',
                    color: '#fff',
                    cursor: 'pointer',
                    fontSize: '14px',
                    padding: '0'
                }, children: "\u2715" })] }));
};

var STYLE_SECTIONS = [
    {
        name: 'General',
        icon: '⚙️',
        props: [
            { name: 'display', label: 'Display', type: 'select', options: ['block', 'inline', 'inline-block', 'flex', 'grid', 'none'] },
            { name: 'position', label: 'Position', type: 'select', options: ['static', 'relative', 'absolute', 'fixed', 'sticky'] },
            { name: 'top', label: 'Top', type: 'dimension' },
            { name: 'bottom', label: 'Bottom', type: 'dimension' },
            { name: 'left', label: 'Left', type: 'dimension' },
            { name: 'right', label: 'Right', type: 'dimension' },
            { name: 'z-index', label: 'Z Index', type: 'number' },
            { name: 'float', label: 'Float', type: 'select', options: ['none', 'left', 'right'] },
            { name: 'clear', label: 'Clear', type: 'select', options: ['none', 'left', 'right', 'both'] },
            { name: 'overflow', label: 'Overflow', type: 'select', options: ['visible', 'hidden', 'scroll', 'auto'] },
            { name: 'opacity', label: 'Opacity', type: 'slider', min: 0, max: 1, step: 0.1 },
            { name: 'visibility', label: 'Visibility', type: 'select', options: ['visible', 'hidden', 'collapse'] },
        ],
    },
    {
        name: 'Dimension',
        icon: '📏',
        props: [
            { name: 'width', label: 'Width', type: 'dimension' },
            { name: 'height', label: 'Height', type: 'dimension' },
            { name: 'min-width', label: 'Min Width', type: 'dimension' },
            { name: 'min-height', label: 'Min Height', type: 'dimension' },
            { name: 'max-width', label: 'Max Width', type: 'dimension' },
            { name: 'max-height', label: 'Max Height', type: 'dimension' },
        ],
    },
    {
        name: 'Spacing',
        icon: '📐',
        props: [
            { name: 'margin-top', label: 'Margin Top', type: 'dimension' },
            { name: 'margin-right', label: 'Margin Right', type: 'dimension' },
            { name: 'margin-bottom', label: 'Margin Bottom', type: 'dimension' },
            { name: 'margin-left', label: 'Margin Left', type: 'dimension' },
            { name: 'padding-top', label: 'Padding Top', type: 'dimension' },
            { name: 'padding-right', label: 'Padding Right', type: 'dimension' },
            { name: 'padding-bottom', label: 'Padding Bottom', type: 'dimension' },
            { name: 'padding-left', label: 'Padding Left', type: 'dimension' },
        ],
    },
    {
        name: 'Typography',
        icon: '🔤',
        props: [
            { name: 'font-size', label: 'Font Size', type: 'dimension' },
            { name: 'font-weight', label: 'Font Weight', type: 'select', options: ['100', '200', '300', '400', '500', '600', '700', '800', '900'] },
            { name: 'font-style', label: 'Font Style', type: 'select', options: ['normal', 'italic', 'oblique'] },
            { name: 'line-height', label: 'Line Height', type: 'dimension' },
            { name: 'letter-spacing', label: 'Letter Spacing', type: 'dimension' },
            { name: 'word-spacing', label: 'Word Spacing', type: 'dimension' },
            { name: 'text-align', label: 'Text Align', type: 'select', options: ['left', 'center', 'right', 'justify'] },
            { name: 'text-transform', label: 'Text Transform', type: 'select', options: ['none', 'capitalize', 'uppercase', 'lowercase'] },
            { name: 'text-decoration', label: 'Text Decoration', type: 'select', options: ['none', 'underline', 'line-through', 'overline'] },
            { name: 'white-space', label: 'White Space', type: 'select', options: ['normal', 'nowrap', 'pre', 'pre-line', 'pre-wrap'] },
            { name: 'color', label: 'Color', type: 'color' },
        ],
    },
    {
        name: 'Background',
        icon: '🎨',
        props: [
            { name: 'background-color', label: 'Background Color', type: 'color' },
            { name: 'background-repeat', label: 'Background Repeat', type: 'select', options: ['repeat', 'no-repeat', 'repeat-x', 'repeat-y'] },
            { name: 'background-position', label: 'Background Position', type: 'select', options: ['left top', 'center', 'right bottom'] },
            { name: 'background-size', label: 'Background Size', type: 'select', options: ['auto', 'cover', 'contain'] },
            { name: 'background-attachment', label: 'Background Attachment', type: 'select', options: ['scroll', 'fixed', 'local'] },
        ],
    },
    {
        name: 'Border',
        icon: '⬜',
        props: [
            { name: 'border-width', label: 'Border Width', type: 'dimension' },
            { name: 'border-style', label: 'Border Style', type: 'select', options: ['none', 'solid', 'dashed', 'dotted', 'double'] },
            { name: 'border-color', label: 'Border Color', type: 'color' },
            { name: 'border-radius', label: 'Border Radius', type: 'dimension' },
            { name: 'border-top-left-radius', label: 'Top Left Radius', type: 'dimension' },
            { name: 'border-top-right-radius', label: 'Top Right Radius', type: 'dimension' },
            { name: 'border-bottom-left-radius', label: 'Bottom Left Radius', type: 'dimension' },
            { name: 'border-bottom-right-radius', label: 'Bottom Right Radius', type: 'dimension' },
        ],
    },
    {
        name: 'Flexbox',
        icon: '📦',
        props: [
            { name: 'flex-direction', label: 'Flex Direction', type: 'select', options: ['row', 'column', 'row-reverse', 'column-reverse'] },
            { name: 'flex-wrap', label: 'Flex Wrap', type: 'select', options: ['nowrap', 'wrap', 'wrap-reverse'] },
            { name: 'justify-content', label: 'Justify Content', type: 'select', options: ['flex-start', 'center', 'flex-end', 'space-between', 'space-around', 'space-evenly'] },
            { name: 'align-items', label: 'Align Items', type: 'select', options: ['stretch', 'flex-start', 'center', 'flex-end', 'baseline'] },
            { name: 'gap', label: 'Gap', type: 'dimension' },
        ],
    },
];
var DEFAULT_CLASSES = [
    'title', 'text-center', 'expert-css', 'btn', 'btn-primary',
    'container', 'row', 'col', 'header', 'footer', 'sidebar',
    'card', 'nav', 'section', 'article', 'aside'
];

var ClassManager = function (_a) {
    var elementClasses = _a.elementClasses, onUpdateClasses = _a.onUpdateClasses;
    var _b = React.useState(false), showAddModal = _b[0], setShowAddModal = _b[1];
    var _c = React.useState(''), newClassName = _c[0], setNewClassName = _c[1];
    var removeClass = function (className) {
        var newClasses = elementClasses.filter(function (c) { return c !== className; });
        onUpdateClasses(newClasses);
    };
    var addClass = function (className) {
        if (className && !elementClasses.includes(className)) {
            var newClasses = __spreadArray(__spreadArray([], elementClasses, true), [className], false);
            onUpdateClasses(newClasses);
        }
    };
    var handleAddCustomClass = function () {
        if (newClassName.trim()) {
            addClass(newClassName.trim());
            setNewClassName('');
            setShowAddModal(false);
        }
    };
    return (jsxRuntime.jsxs("div", { style: { padding: '16px', borderBottom: '1px solid #555' }, children: [jsxRuntime.jsxs("div", { style: {
                    display: 'flex',
                    justifyContent: 'space-between',
                    alignItems: 'center',
                    marginBottom: '12px'
                }, children: [jsxRuntime.jsx("h3", { style: { margin: 0, fontSize: '14px', fontWeight: 'bold' }, children: "Classes" }), jsxRuntime.jsxs("select", { style: {
                            padding: '4px 8px',
                            backgroundColor: '#555',
                            color: '#fff',
                            border: '1px solid #666',
                            borderRadius: '4px',
                            fontSize: '12px'
                        }, children: [jsxRuntime.jsx("option", { value: "", children: "- State -" }), jsxRuntime.jsx("option", { value: "hover", children: ":hover" }), jsxRuntime.jsx("option", { value: "focus", children: ":focus" }), jsxRuntime.jsx("option", { value: "active", children: ":active" })] })] }), jsxRuntime.jsx("div", { style: {
                    display: 'flex',
                    flexWrap: 'wrap',
                    gap: '6px',
                    marginBottom: '12px',
                    minHeight: '40px'
                }, children: elementClasses.map(function (className) { return (jsxRuntime.jsx(ClassTag, { className: className, onRemove: removeClass }, className)); }) }), jsxRuntime.jsxs("div", { style: { display: 'flex', gap: '8px', alignItems: 'center' }, children: [jsxRuntime.jsx("button", { onClick: function () { return setShowAddModal(!showAddModal); }, style: {
                            width: '40px',
                            height: '40px',
                            backgroundColor: '#555',
                            border: '1px solid #666',
                            borderRadius: '4px',
                            color: '#fff',
                            fontSize: '18px',
                            cursor: 'pointer',
                            display: 'flex',
                            alignItems: 'center',
                            justifyContent: 'center'
                        }, children: "+" }), showAddModal && (jsxRuntime.jsx("div", { style: { flex: 1 }, children: jsxRuntime.jsx("input", { type: "text", value: newClassName, onChange: function (e) { return setNewClassName(e.target.value); }, placeholder: "Enter class name", style: {
                                width: '100%',
                                padding: '6px 8px',
                                backgroundColor: '#555',
                                border: '1px solid #666',
                                borderRadius: '4px',
                                color: '#fff',
                                fontSize: '12px'
                            }, onKeyPress: function (e) {
                                if (e.key === 'Enter') {
                                    handleAddCustomClass();
                                }
                            } }) }))] }), showAddModal && (jsxRuntime.jsxs("div", { style: { marginTop: '8px' }, children: [jsxRuntime.jsx("div", { style: { fontSize: '12px', color: '#ccc', marginBottom: '4px' }, children: "Quick Add:" }), jsxRuntime.jsx("div", { style: { display: 'flex', flexWrap: 'wrap', gap: '4px' }, children: DEFAULT_CLASSES.map(function (className) { return (jsxRuntime.jsx("button", { onClick: function () { return addClass(className); }, style: {
                                padding: '2px 6px',
                                backgroundColor: '#666',
                                border: '1px solid #777',
                                borderRadius: '3px',
                                color: '#fff',
                                fontSize: '10px',
                                cursor: 'pointer'
                            }, disabled: elementClasses.includes(className), children: className }, className)); }) })] }))] }));
};

var ElementInfo = function (_a) {
    var selectedElement = _a.selectedElement, onCopy = _a.onCopy, onDelete = _a.onDelete, onOpenAssets = _a.onOpenAssets;
    return (jsxRuntime.jsx("div", { style: { padding: '16px', borderBottom: '1px solid #555' }, children: jsxRuntime.jsxs("div", { style: {
                display: 'flex',
                justifyContent: 'space-between',
                alignItems: 'flex-start',
                gap: '12px'
            }, children: [jsxRuntime.jsxs("div", { style: { flex: 1 }, children: [jsxRuntime.jsx("div", { style: { fontSize: '12px', color: '#ccc', marginBottom: '4px' }, children: "Selected:" }), jsxRuntime.jsxs("div", { style: {
                                fontSize: '16px',
                                fontWeight: 'bold',
                                marginBottom: '4px'
                            }, children: [selectedElement.tagName.toLowerCase(), selectedElement.id && (jsxRuntime.jsxs("span", { style: { color: '#4CAF50' }, children: ["#", selectedElement.id] }))] }), jsxRuntime.jsx("div", { style: {
                                fontSize: '11px',
                                color: '#888',
                                wordBreak: 'break-all',
                                marginBottom: '8px'
                            }, children: selectedElement.selector }), selectedElement.textContent && (jsxRuntime.jsxs("div", { style: {
                                fontSize: '11px',
                                color: '#999',
                                fontStyle: 'italic',
                                overflow: 'hidden',
                                textOverflow: 'ellipsis'
                            }, children: ["\"", selectedElement.textContent, "...\""] }))] }), jsxRuntime.jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: '4px' }, children: [selectedElement.tagName === 'IMG' && onOpenAssets && (jsxRuntime.jsx("button", { onClick: onOpenAssets, title: "Change image", style: {
                                padding: '8px',
                                backgroundColor: '#4CAF50',
                                border: '1px solid #666',
                                borderRadius: '4px',
                                color: '#fff',
                                cursor: 'pointer',
                                fontSize: '12px',
                                minWidth: '36px',
                                display: 'flex',
                                alignItems: 'center',
                                justifyContent: 'center'
                            }, children: "\uD83D\uDDBC\uFE0F" })), jsxRuntime.jsx("button", { onClick: onCopy, title: "Duplicate element", style: {
                                padding: '8px',
                                backgroundColor: '#555',
                                border: '1px solid #666',
                                borderRadius: '4px',
                                color: '#fff',
                                cursor: 'pointer',
                                fontSize: '12px',
                                minWidth: '36px',
                                display: 'flex',
                                alignItems: 'center',
                                justifyContent: 'center'
                            }, children: "\uD83D\uDCD1" }), jsxRuntime.jsx("button", { onClick: onDelete, title: "Delete element", style: {
                                padding: '8px',
                                backgroundColor: '#d32f2f',
                                border: '1px solid #666',
                                borderRadius: '4px',
                                color: '#fff',
                                cursor: 'pointer',
                                fontSize: '12px',
                                minWidth: '36px',
                                display: 'flex',
                                alignItems: 'center',
                                justifyContent: 'center'
                            }, children: "\uD83D\uDDD1\uFE0F" })] })] }) }));
};

// src/components/StyleManager/SearchBar.tsx (Compact version)
var SearchBar = function (_a) {
    var searchTerm = _a.searchTerm, onSearchChange = _a.onSearchChange;
    return (jsxRuntime.jsx("div", { style: {
            padding: '8px 12px', // Reduced padding
            borderBottom: '1px solid #555',
            backgroundColor: '#333'
        }, children: jsxRuntime.jsx("input", { type: "text", value: searchTerm, onChange: function (e) { return onSearchChange(e.target.value); }, placeholder: "Search styles...", style: {
                width: '100%',
                padding: '6px 8px', // Reduced padding
                backgroundColor: '#555',
                border: '1px solid #666',
                borderRadius: '3px',
                color: '#fff',
                fontSize: '11px', // Smaller font
                outline: 'none'
            } }) }));
};

var StyleInput = function (_a) {
    var property = _a.property, value = _a.value, onChange = _a.onChange;
    var inputStyles = {
        base: {
            padding: '6px 8px',
            border: '1px solid #555',
            backgroundColor: '#444',
            color: '#fff',
            borderRadius: '4px',
            fontSize: '12px',
        }
    };
    var getNumericValue = function (val) {
        if (!val)
            return property.max || 1;
        var match = val.match(/^(\d*\.?\d+)/);
        return match ? parseFloat(match[1]) : (property.max || 1);
    };
    var adjustValue = function (increment) {
        var current = getNumericValue(value);
        var step = property.step || 1;
        var newVal = increment ? current + step : current - step;
        var constrainedVal = newVal;
        if (property.min !== undefined)
            constrainedVal = Math.max(property.min, constrainedVal);
        if (property.max !== undefined)
            constrainedVal = Math.min(property.max, constrainedVal);
        var unit = value ? value.replace(/^[\d.]+/, '') : 'px';
        onChange("".concat(constrainedVal).concat(unit || 'px'));
    };
    var renderInput = function () {
        var _a;
        switch (property.type) {
            case 'select':
                return (jsxRuntime.jsxs("select", { value: value, onChange: function (e) { return onChange(e.target.value); }, style: __assign(__assign({}, inputStyles.base), { flex: 1 }), children: [jsxRuntime.jsx("option", { value: "", children: "auto" }), (_a = property.options) === null || _a === void 0 ? void 0 : _a.map(function (option) { return (jsxRuntime.jsx("option", { value: option, children: option }, option)); })] }));
            case 'color':
                return (jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [jsxRuntime.jsx("input", { type: "color", value: value || '#000000', onChange: function (e) { return onChange(e.target.value); }, style: { width: '30px', height: '30px', border: 'none', borderRadius: '4px' } }), jsxRuntime.jsx("input", { type: "text", value: value, onChange: function (e) { return onChange(e.target.value); }, placeholder: "auto", style: __assign(__assign({}, inputStyles.base), { flex: 1 }) })] }));
            case 'dimension':
                return (jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '4px' }, children: [jsxRuntime.jsx("input", { type: "text", value: value, onChange: function (e) { return onChange(e.target.value); }, placeholder: "auto", style: __assign(__assign({}, inputStyles.base), { flex: 1, textAlign: 'center' }) }), jsxRuntime.jsxs("div", { style: { display: 'flex', flexDirection: 'column' }, children: [jsxRuntime.jsx("button", { onClick: function () { return adjustValue(true); }, style: {
                                        padding: '1px 3px',
                                        border: '1px solid #555',
                                        backgroundColor: '#555',
                                        color: '#fff',
                                        borderRadius: '2px',
                                        fontSize: '8px',
                                        cursor: 'pointer',
                                        lineHeight: '10px',
                                        width: '16px',
                                        height: '12px'
                                    }, children: "\u25B2" }), jsxRuntime.jsx("button", { onClick: function () { return adjustValue(false); }, style: {
                                        padding: '1px 3px',
                                        border: '1px solid #555',
                                        backgroundColor: '#555',
                                        color: '#fff',
                                        borderRadius: '2px',
                                        fontSize: '8px',
                                        cursor: 'pointer',
                                        lineHeight: '10px',
                                        width: '16px',
                                        height: '12px',
                                        marginTop: '1px'
                                    }, children: "\u25BC" })] })] }));
            case 'slider':
                var numValue = getNumericValue(value);
                var min = property.min || 0;
                var max = property.max || 1;
                var step = property.step || 0.1;
                return (jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [jsxRuntime.jsx("input", { type: "range", min: min, max: max, step: step, value: numValue, onChange: function (e) { return onChange(e.target.value); }, style: { flex: 1 } }), jsxRuntime.jsx("span", { style: { color: '#ccc', fontSize: '12px', minWidth: '30px' }, children: numValue.toFixed(1) })] }));
            default:
                return (jsxRuntime.jsx("input", { type: "text", value: value, onChange: function (e) { return onChange(e.target.value); }, placeholder: "auto", style: __assign(__assign({}, inputStyles.base), { width: '100%' }) }));
        }
    };
    return (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { style: {
                    display: 'block',
                    fontSize: '12px',
                    color: '#ccc',
                    marginBottom: '4px',
                    fontWeight: 'normal'
                }, children: property.label }), renderInput()] }));
};

var StyleSection = function (_a) {
    var section = _a.section, isOpen = _a.isOpen, currentStyles = _a.currentStyles, onToggle = _a.onToggle, onStyleChange = _a.onStyleChange;
    return (jsxRuntime.jsxs("div", { style: { borderBottom: '1px solid #555' }, children: [jsxRuntime.jsxs("div", { onClick: onToggle, style: {
                    padding: '8px 12px', // Reduced from whatever you had
                    backgroundColor: '#333',
                    borderBottom: '1px solid #555',
                    cursor: 'pointer',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'space-between',
                    fontSize: '12px', // Smaller font
                    fontWeight: 'bold',
                    minHeight: '32px' // Fixed smaller height
                }, children: [jsxRuntime.jsx("span", { children: section.name }), jsxRuntime.jsx("span", { style: { fontSize: '10px', color: '#aaa' }, children: isOpen ? '▼' : '▶' })] }), isOpen && (jsxRuntime.jsx("div", { style: { padding: '16px' }, children: jsxRuntime.jsx("div", { style: {
                        display: 'grid',
                        gridTemplateColumns: '1fr 1fr',
                        gap: '12px',
                        alignItems: 'start'
                    }, children: section.props.map(function (prop) { return (jsxRuntime.jsx(StyleInput, { property: prop, value: currentStyles[prop.name] || '', onChange: function (value) { return onStyleChange(prop.name, value); } }, prop.name)); }) }) }))] }));
};

// src/components/StyleManager/index.tsx (Improved scrolling)
var StyleManager = function (_a) {
    var currentStyles = _a.currentStyles, onStyleChange = _a.onStyleChange;
    var _b = React.useState(''), searchTerm = _b[0], setSearchTerm = _b[1];
    var _c = React.useState({
        General: true,
        Dimension: false,
        Spacing: false,
        Typography: false,
        Background: false,
        Border: false,
    }), openSections = _c[0], setOpenSections = _c[1];
    var filteredSections = React.useMemo(function () {
        if (!searchTerm)
            return STYLE_SECTIONS;
        return STYLE_SECTIONS.map(function (section) { return (__assign(__assign({}, section), { props: section.props.filter(function (prop) {
                return prop.label.toLowerCase().includes(searchTerm.toLowerCase()) ||
                    prop.name.toLowerCase().includes(searchTerm.toLowerCase());
            }) })); }).filter(function (section) { return section.props.length > 0; });
    }, [searchTerm]);
    var toggleSection = function (sectionName) {
        setOpenSections(function (prev) {
            var _a;
            return (__assign(__assign({}, prev), (_a = {}, _a[sectionName] = !prev[sectionName], _a)));
        });
    };
    return (jsxRuntime.jsxs("div", { style: {
            height: '100%',
            display: 'flex',
            flexDirection: 'column'
        }, children: [jsxRuntime.jsx("div", { style: { flexShrink: 0 }, children: jsxRuntime.jsx(SearchBar, { searchTerm: searchTerm, onSearchChange: setSearchTerm }) }), jsxRuntime.jsx("div", { style: {
                    flex: 1,
                    overflowY: 'auto',
                    overflowX: 'hidden'
                }, children: filteredSections.map(function (section) { return (jsxRuntime.jsx(StyleSection, { section: section, isOpen: openSections[section.name] || false, currentStyles: currentStyles, onToggle: function () { return toggleSection(section.name); }, onStyleChange: onStyleChange }, section.name)); }) })] }));
};

// src/components/Editor/EditorSidebar.tsx (Fixed scrolling)
var EditorSidebar = function (_a) {
    var _b;
    var editor = _a.editor;
    return (jsxRuntime.jsxs("div", { style: {
            height: '100%',
            backgroundColor: '#444',
            color: '#fff',
            display: 'flex',
            flexDirection: 'column',
            borderLeft: '1px solid #555'
        }, children: [jsxRuntime.jsxs("div", { style: {
                    flexShrink: 0, // Don't shrink
                    backgroundColor: '#333',
                    borderBottom: '1px solid #555'
                }, children: [jsxRuntime.jsx(ClassManager, { elementClasses: ((_b = editor.selectedElement) === null || _b === void 0 ? void 0 : _b.classes) || [], onUpdateClasses: editor.updateClasses }), editor.selectedElement && (jsxRuntime.jsx(ElementInfo, { selectedElement: editor.selectedElement, onCopy: editor.copyElement, onDelete: editor.deleteElement, onOpenAssets: function () { return editor.setShowAssetManager(true); } }))] }), jsxRuntime.jsx("div", { style: {
                    flex: 1,
                    overflow: 'hidden', // This container should not scroll
                    display: 'flex',
                    flexDirection: 'column'
                }, children: jsxRuntime.jsx("div", { style: {
                        flex: 1,
                        overflowY: 'auto', // Only this inner div scrolls
                        overflowX: 'hidden'
                    }, children: jsxRuntime.jsx(StyleManager, { currentStyles: editor.currentStyles, onStyleChange: editor.updateStyle }) }) })] }));
};

// src/components/TabbedRightPanel/index.tsx (Auto-switch functionality)
var TabbedRightPanel = function (_a) {
    var blocks = _a.blocks, showBlockManager = _a.showBlockManager, onAddBlock = _a.onAddBlock, editor = _a.editor, iframeRef = _a.iframeRef;
    var _b = React.useState('blocks'), activeTab = _b[0], setActiveTab = _b[1];
    // AUTO-SWITCH: Switch to styles when element is selected
    React.useEffect(function () {
        if (editor === null || editor === void 0 ? void 0 : editor.selectedElement) {
            setActiveTab('styles');
        }
    }, [editor === null || editor === void 0 ? void 0 : editor.selectedElement]);
    var tabs = [
        {
            id: 'blocks',
            label: 'Blocks',
            icon: '📦',
            show: showBlockManager && blocks.length > 0
        },
        {
            id: 'styles',
            label: 'Styles',
            icon: '🎨',
            show: true
        }
    ].filter(function (tab) { return tab.show; });
    return (jsxRuntime.jsxs("div", { style: {
            width: '350px',
            height: '100%',
            backgroundColor: '#444',
            color: '#fff',
            display: 'flex',
            flexDirection: 'column',
            borderLeft: '1px solid #555'
        }, children: [jsxRuntime.jsx("div", { style: {
                    display: 'flex',
                    borderBottom: '1px solid #555',
                    backgroundColor: '#333'
                }, children: tabs.map(function (tab) { return (jsxRuntime.jsxs("button", { onClick: function () { return setActiveTab(tab.id); }, style: {
                        flex: 1,
                        padding: '12px 8px',
                        backgroundColor: activeTab === tab.id ? '#555' : 'transparent',
                        color: activeTab === tab.id ? '#fff' : '#aaa',
                        border: 'none',
                        borderBottom: activeTab === tab.id ? '2px solid #007bff' : '2px solid transparent',
                        cursor: 'pointer',
                        fontSize: '12px',
                        fontWeight: activeTab === tab.id ? 'bold' : 'normal',
                        display: 'flex',
                        alignItems: 'center',
                        justifyContent: 'center',
                        gap: '4px',
                        transition: 'all 0.2s ease'
                    }, onMouseEnter: function (e) {
                        if (activeTab !== tab.id) {
                            e.currentTarget.style.backgroundColor = '#555';
                            e.currentTarget.style.color = '#fff';
                        }
                    }, onMouseLeave: function (e) {
                        if (activeTab !== tab.id) {
                            e.currentTarget.style.backgroundColor = 'transparent';
                            e.currentTarget.style.color = '#aaa';
                        }
                    }, children: [jsxRuntime.jsx("span", { style: { fontSize: '14px' }, children: tab.icon }), jsxRuntime.jsx("span", { children: tab.label })] }, tab.id)); }) }), jsxRuntime.jsxs("div", { style: { flex: 1, overflow: 'hidden' }, children: [activeTab === 'blocks' && showBlockManager && (jsxRuntime.jsx(DraggableBlockManager, { blocks: blocks, onAddBlock: onAddBlock, iframeRef: iframeRef })), activeTab === 'styles' && (jsxRuntime.jsx(EditorSidebar, { editor: editor }))] }), jsxRuntime.jsxs("div", { style: {
                    height: '30px',
                    backgroundColor: '#333',
                    borderTop: '1px solid #555',
                    display: 'flex',
                    alignItems: 'center',
                    justifyContent: 'center',
                    fontSize: '11px',
                    color: '#666'
                }, children: [activeTab === 'blocks' && "".concat(blocks.length, " blocks available"), activeTab === 'styles' && ((editor === null || editor === void 0 ? void 0 : editor.selectedElement) ? "".concat(editor.selectedElement.tagName, " selected") : 'No element selected')] })] }));
};

// src/components/PreviewButton/index.tsx
var PreviewButton = function (_a) {
    var isPreview = _a.isPreview, onTogglePreview = _a.onTogglePreview, style = _a.style;
    return (jsxRuntime.jsxs("button", { onClick: onTogglePreview, style: __assign({ display: 'flex', alignItems: 'center', gap: '6px', padding: '8px 12px', backgroundColor: isPreview ? '#4CAF50' : '#555', border: '1px solid #666', borderRadius: '4px', color: '#fff', fontSize: '12px', cursor: 'pointer', transition: 'background-color 0.2s' }, style), title: isPreview ? 'Exit Preview Mode' : 'Enter Preview Mode', children: [jsxRuntime.jsx("span", { style: { fontSize: '14px' }, children: isPreview ? '🚫' : '👁️' }), jsxRuntime.jsx("span", { children: isPreview ? 'Exit Preview' : 'Preview' })] }));
};

// src/components/Editor/index.tsx (Enhanced with single header + clear canvas)
var Editor = function (_a) {
    var canvasUrl = _a.canvasUrl, _b = _a.devices, devices = _b === void 0 ? defaultDevices : _b, _c = _a.blocks, blocks = _c === void 0 ? [] : _c, _d = _a.showDeviceManager, showDeviceManager = _d === void 0 ? true : _d, _e = _a.showBlockManager, showBlockManager = _e === void 0 ? true : _e, _f = _a.showPreview, showPreview = _f === void 0 ? true : _f;
    var editor = useEditor();
    var _g = React.useState(!canvasUrl && !(editor === null || editor === void 0 ? void 0 : editor.hasContent)), showHTMLLoader = _g[0], setShowHTMLLoader = _g[1];
    var _h = React.useState(false), showExportModal = _h[0], setShowExportModal = _h[1];
    var _j = React.useState(null), exportData = _j[0], setExportData = _j[1];
    var _k = React.useState(devices[0]), currentDevice = _k[0], setCurrentDevice = _k[1];
    var _l = React.useState(false), isPreviewMode = _l[0], setIsPreviewMode = _l[1];
    // Handle preview toggle
    var handlePreviewToggle = function () {
        var _a, _b, _c;
        if (!((_a = editor === null || editor === void 0 ? void 0 : editor.iframeRef) === null || _a === void 0 ? void 0 : _a.current))
            return;
        if (!isPreviewMode) {
            setIsPreviewMode(true);
            (_b = editor.iframeRef.current.contentWindow) === null || _b === void 0 ? void 0 : _b.postMessage({
                type: 'TOGGLE_PREVIEW_MODE',
                payload: { preview: true }
            }, '*');
        }
        else {
            setIsPreviewMode(false);
            (_c = editor.iframeRef.current.contentWindow) === null || _c === void 0 ? void 0 : _c.postMessage({
                type: 'TOGGLE_PREVIEW_MODE',
                payload: { preview: false }
            }, '*');
        }
    };
    // Clear canvas functionality
    var handleClearCanvas = function () {
        var _a, _b, _c, _d;
        if (window.confirm('Are you sure you want to clear the canvas? This action cannot be undone.')) {
            (_c = (_b = (_a = editor === null || editor === void 0 ? void 0 : editor.iframeRef) === null || _a === void 0 ? void 0 : _a.current) === null || _b === void 0 ? void 0 : _b.contentWindow) === null || _c === void 0 ? void 0 : _c.postMessage({
                type: 'CLEAR_CANVAS',
                payload: {}
            }, '*');
            // Reset editor state
            (_d = editor === null || editor === void 0 ? void 0 : editor.handleElementSelected) === null || _d === void 0 ? void 0 : _d.call(editor, undefined);
        }
    };
    React.useEffect(function () {
        var handleMessage = function (e) {
            var _a, _b;
            var _c = e.data, type = _c.type, payload = _c.payload;
            switch (type) {
                case 'ELEMENT_SELECTED':
                    if (!isPreviewMode) {
                        (_a = editor === null || editor === void 0 ? void 0 : editor.handleElementSelected) === null || _a === void 0 ? void 0 : _a.call(editor, payload);
                    }
                    break;
                case 'OPEN_ASSET_MANAGER':
                    if (!isPreviewMode) {
                        (_b = editor === null || editor === void 0 ? void 0 : editor.handleOpenAssetManager) === null || _b === void 0 ? void 0 : _b.call(editor);
                    }
                    break;
                case 'EXPORT_DATA':
                    setExportData(payload);
                    setShowExportModal(true);
                    break;
                case 'BLOCK_ADDED_SUCCESS':
                    console.log('Block successfully added');
                    break;
            }
        };
        window.addEventListener('message', handleMessage);
        return function () { return window.removeEventListener('message', handleMessage); };
    }, [editor, isPreviewMode]);
    React.useEffect(function () {
        var _a;
        if (canvasUrl && ((_a = editor === null || editor === void 0 ? void 0 : editor.iframeRef) === null || _a === void 0 ? void 0 : _a.current)) {
            editor.iframeRef.current.src = canvasUrl;
        }
    }, [canvasUrl, editor === null || editor === void 0 ? void 0 : editor.iframeRef]);
    var handleHTMLSubmit = function (html) {
        var _a;
        (_a = editor === null || editor === void 0 ? void 0 : editor.loadHTMLContent) === null || _a === void 0 ? void 0 : _a.call(editor, html);
        setShowHTMLLoader(false);
    };
    var handleAddBlock = function (content, block) {
        if (editor === null || editor === void 0 ? void 0 : editor.addBlock) {
            editor.addBlock(content);
        }
    };
    ({
        width: typeof currentDevice.width === 'number' ? "".concat(currentDevice.width, "px") : currentDevice.width,
        height: typeof currentDevice.height === 'number' ? "".concat(currentDevice.height, "px") : currentDevice.height});
    return (jsxRuntime.jsxs("div", { style: {
            display: 'flex',
            flexDirection: 'column',
            height: '100vh',
            backgroundColor: '#2d2d2d',
            overflow: 'hidden'
        }, children: [!isPreviewMode && (jsxRuntime.jsxs("div", { className: "editor-header", style: {
                    height: '60px',
                    backgroundColor: '#333',
                    borderBottom: '1px solid #555',
                    display: 'flex',
                    alignItems: 'center',
                    padding: '0 16px',
                    gap: '12px',
                    flexShrink: 0,
                    zIndex: 1000
                }, children: [jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '12px' }, children: [jsxRuntime.jsx("button", { onClick: function () { return setShowHTMLLoader(true); }, style: {
                                    padding: '8px 12px',
                                    backgroundColor: '#555',
                                    border: '1px solid #666',
                                    borderRadius: '4px',
                                    color: '#fff',
                                    cursor: 'pointer',
                                    fontSize: '12px'
                                }, children: "\uD83D\uDCDD Load HTML" }), jsxRuntime.jsx("button", { onClick: handleClearCanvas, disabled: !(editor === null || editor === void 0 ? void 0 : editor.hasContent), style: {
                                    padding: '8px 12px',
                                    backgroundColor: (editor === null || editor === void 0 ? void 0 : editor.hasContent) ? '#dc3545' : '#444',
                                    border: '1px solid #666',
                                    borderRadius: '4px',
                                    color: '#fff',
                                    cursor: (editor === null || editor === void 0 ? void 0 : editor.hasContent) ? 'pointer' : 'not-allowed',
                                    fontSize: '12px'
                                }, title: "Clear Canvas", children: "\uD83D\uDDD1\uFE0F Clear" }), jsxRuntime.jsx("button", { onClick: function () { var _a; return (_a = editor === null || editor === void 0 ? void 0 : editor.exportHTML) === null || _a === void 0 ? void 0 : _a.call(editor); }, disabled: !(editor === null || editor === void 0 ? void 0 : editor.hasContent), style: {
                                    padding: '8px 12px',
                                    backgroundColor: (editor === null || editor === void 0 ? void 0 : editor.hasContent) ? '#4CAF50' : '#444',
                                    border: '1px solid #666',
                                    borderRadius: '4px',
                                    color: '#fff',
                                    cursor: (editor === null || editor === void 0 ? void 0 : editor.hasContent) ? 'pointer' : 'not-allowed',
                                    fontSize: '12px'
                                }, children: "\uD83D\uDCE5 Export" })] }), showDeviceManager && (jsxRuntime.jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: '8px' }, children: [jsxRuntime.jsx("span", { style: { color: '#ccc', fontSize: '12px' }, children: "Device:" }), jsxRuntime.jsx("select", { value: currentDevice.id, onChange: function (e) {
                                    var device = devices.find(function (d) { return d.id === e.target.value; });
                                    if (device)
                                        setCurrentDevice(device);
                                }, style: {
                                    padding: '6px 12px',
                                    backgroundColor: '#555',
                                    color: '#fff',
                                    border: '1px solid #666',
                                    borderRadius: '4px',
                                    fontSize: '12px',
                                    minWidth: '120px'
                                }, children: devices.map(function (device) { return (jsxRuntime.jsxs("option", { value: device.id, children: [device.icon, " ", device.name] }, device.id)); }) })] })), jsxRuntime.jsxs("div", { style: { marginLeft: 'auto', display: 'flex', alignItems: 'center', gap: '12px' }, children: [showPreview && (jsxRuntime.jsx(PreviewButton, { isPreview: isPreviewMode, onTogglePreview: handlePreviewToggle })), (editor === null || editor === void 0 ? void 0 : editor.isLoading) && (jsxRuntime.jsx("div", { style: { color: '#fff', fontSize: '12px' }, children: "Loading..." })), !(editor === null || editor === void 0 ? void 0 : editor.hasContent) && (jsxRuntime.jsx("div", { style: { color: '#aaa', fontSize: '12px' }, children: "Load HTML to start editing" }))] })] })), isPreviewMode && (jsxRuntime.jsx("div", { style: {
                    position: 'fixed',
                    top: '20px',
                    right: '20px',
                    zIndex: 10000
                }, children: jsxRuntime.jsx(PreviewButton, { isPreview: isPreviewMode, onTogglePreview: handlePreviewToggle }) })), jsxRuntime.jsxs("div", { style: {
                    display: 'flex',
                    flex: 1,
                    overflow: 'hidden',
                    backgroundColor: isPreviewMode ? '#000' : '#2d2d2d'
                }, children: [jsxRuntime.jsx("div", { style: {
                            flex: 1,
                            display: 'flex',
                            justifyContent: 'center',
                            alignItems: 'flex-start',
                            backgroundColor: isPreviewMode ? '#000' : '#f5f5f5',
                            padding: isPreviewMode ? '0' : '20px',
                            overflow: 'auto',
                            minHeight: 0
                        }, children: jsxRuntime.jsx(EditorCanvas, { ref: editor === null || editor === void 0 ? void 0 : editor.iframeRef, src: "about:blank", style: isPreviewMode ? {
                                width: '100%',
                                height: '100%'
                            } : {
                                width: typeof currentDevice.width === 'number' ? "".concat(currentDevice.width, "px") : currentDevice.width,
                                height: typeof currentDevice.height === 'number' ? "".concat(currentDevice.height, "px") : currentDevice.height,
                                border: '1px solid #ddd',
                                borderRadius: '4px',
                                boxShadow: '0 2px 10px rgba(0,0,0,0.1)',
                                backgroundColor: '#fff',
                                minWidth: '300px',
                                minHeight: '200px'
                            } }) }), !isPreviewMode && (jsxRuntime.jsx(TabbedRightPanel, { blocks: blocks, showBlockManager: showBlockManager, onAddBlock: handleAddBlock, editor: editor, iframeRef: editor === null || editor === void 0 ? void 0 : editor.iframeRef }))] }), jsxRuntime.jsx(HTMLLoader, { isOpen: showHTMLLoader, onClose: function () { return setShowHTMLLoader(false); }, onSubmit: handleHTMLSubmit }), jsxRuntime.jsx(ExportModal, { isOpen: showExportModal, onClose: function () { return setShowExportModal(false); }, data: exportData }), jsxRuntime.jsx(AssetManager, { isOpen: !!(editor === null || editor === void 0 ? void 0 : editor.showAssetManager), onClose: function () { var _a; return (_a = editor === null || editor === void 0 ? void 0 : editor.setShowAssetManager) === null || _a === void 0 ? void 0 : _a.call(editor, false); }, onSelectAsset: (editor === null || editor === void 0 ? void 0 : editor.handleAssetSelect) || (function () { }), selectedElement: (editor === null || editor === void 0 ? void 0 : editor.selectedElement) || null })] }));
};

// src/components/BlockManager/index.tsx (Fixed)
var BlockManager = function (_a) {
    var blocks = _a.blocks, onAddBlock = _a.onAddBlock, style = _a.style, categories = _a.categories;
    var _b = React.useState('all'), selectedCategory = _b[0], setSelectedCategory = _b[1];
    var filteredBlocks = selectedCategory === 'all'
        ? blocks
        : blocks.filter(function (block) { return block.category === selectedCategory; });
    var uniqueCategories = categories || __spreadArray(['all'], Array.from(new Set(blocks.map(function (b) { return b.category; }).filter(Boolean))), true);
    return (jsxRuntime.jsxs("div", { style: __assign({ display: 'flex', flexDirection: 'column', height: '100%', backgroundColor: '#444', color: '#fff' }, style), children: [jsxRuntime.jsx("div", { style: {
                    padding: '12px 16px',
                    borderBottom: '1px solid #555',
                    backgroundColor: '#333'
                }, children: jsxRuntime.jsx("h3", { style: { margin: 0, fontSize: '14px', fontWeight: 'bold' }, children: "Blocks" }) }), uniqueCategories.length > 1 && (jsxRuntime.jsx("div", { style: {
                    padding: '8px 16px',
                    borderBottom: '1px solid #555'
                }, children: jsxRuntime.jsx("select", { value: selectedCategory, onChange: function (e) { return setSelectedCategory(e.target.value); }, style: {
                        width: '100%',
                        padding: '6px',
                        backgroundColor: '#555',
                        color: '#fff',
                        border: '1px solid #666',
                        borderRadius: '4px',
                        fontSize: '12px'
                    }, children: uniqueCategories.map(function (category) { return (jsxRuntime.jsx("option", { value: category, children: category ? category.charAt(0).toUpperCase() + category.slice(1) : 'Unknown' }, category)); }) }) })), jsxRuntime.jsx("div", { style: {
                    flex: 1,
                    overflowY: 'auto',
                    padding: '8px'
                }, children: jsxRuntime.jsx("div", { style: {
                        display: 'grid',
                        gridTemplateColumns: 'repeat(auto-fill, minmax(80px, 1fr))',
                        gap: '8px'
                    }, children: filteredBlocks.map(function (block) { return (jsxRuntime.jsxs("div", { onClick: function () { return onAddBlock(block.content, block); }, style: {
                            backgroundColor: '#555',
                            borderRadius: '6px',
                            padding: '8px',
                            cursor: 'pointer',
                            textAlign: 'center',
                            transition: 'background-color 0.2s',
                            border: '1px solid transparent'
                        }, onMouseEnter: function (e) {
                            e.currentTarget.style.backgroundColor = '#666';
                            e.currentTarget.style.borderColor = '#007bff';
                        }, onMouseLeave: function (e) {
                            e.currentTarget.style.backgroundColor = '#555';
                            e.currentTarget.style.borderColor = 'transparent';
                        }, title: block.label, children: [block.thumbnailUrl ? (jsxRuntime.jsx("img", { src: block.thumbnailUrl, alt: block.label, style: {
                                    width: '100%',
                                    height: '60px',
                                    objectFit: 'cover',
                                    borderRadius: '4px',
                                    marginBottom: '4px'
                                } })) : (jsxRuntime.jsx("div", { style: {
                                    width: '100%',
                                    height: '60px',
                                    backgroundColor: '#666',
                                    borderRadius: '4px',
                                    display: 'flex',
                                    alignItems: 'center',
                                    justifyContent: 'center',
                                    fontSize: '24px',
                                    marginBottom: '4px'
                                }, children: block.icon || '📄' })), jsxRuntime.jsx("div", { style: { fontSize: '10px', color: '#ccc' }, children: block.label })] }, block.id)); }) }) })] }));
};

// src/components/ResizablePanel/index.tsx
var ResizablePanel = function (_a) {
    var _b = _a.initialWidth, initialWidth = _b === void 0 ? 300 : _b, _c = _a.minWidth, minWidth = _c === void 0 ? 200 : _c, _d = _a.maxWidth, maxWidth = _d === void 0 ? 600 : _d, _e = _a.direction, direction = _e === void 0 ? 'right' : _e, children = _a.children, style = _a.style, onResize = _a.onResize;
    var _f = React.useState(initialWidth), width = _f[0], setWidth = _f[1];
    var _g = React.useState(false), isResizing = _g[0], setIsResizing = _g[1];
    var resizerRef = React.useRef(null);
    var panelRef = React.useRef(null);
    var handleMouseDown = React.useCallback(function (e) {
        e.preventDefault();
        setIsResizing(true);
        var startX = e.clientX;
        var startWidth = width;
        var handleMouseMove = function (e) {
            e.preventDefault();
            var newWidth;
            if (direction === 'right') {
                newWidth = startWidth + (e.clientX - startX);
            }
            else {
                newWidth = startWidth - (e.clientX - startX);
            }
            if (newWidth >= minWidth && newWidth <= maxWidth) {
                setWidth(newWidth);
                onResize === null || onResize === void 0 ? void 0 : onResize(newWidth);
            }
        };
        var handleMouseUp = function () {
            setIsResizing(false);
            document.removeEventListener('mousemove', handleMouseMove);
            document.removeEventListener('mouseup', handleMouseUp);
        };
        document.addEventListener('mousemove', handleMouseMove);
        document.addEventListener('mouseup', handleMouseUp);
    }, [width, minWidth, maxWidth, direction, onResize]);
    return (jsxRuntime.jsxs("div", { ref: panelRef, style: __assign({ width: width, height: '100%', position: 'relative', display: 'flex', flexDirection: 'column', backgroundColor: '#444', color: '#fff' }, style), children: [children, jsxRuntime.jsx("div", { ref: resizerRef, onMouseDown: handleMouseDown, style: {
                    width: '5px',
                    cursor: 'ew-resize',
                    position: 'absolute',
                    top: 0,
                    bottom: 0,
                    right: direction === 'right' ? 0 : undefined,
                    left: direction === 'left' ? 0 : undefined,
                    backgroundColor: isResizing ? '#007bff' : 'transparent',
                    transition: 'background-color 0.2s',
                    zIndex: 1000
                }, onMouseEnter: function (e) {
                    if (!isResizing) {
                        e.currentTarget.style.backgroundColor = '#666';
                    }
                }, onMouseLeave: function (e) {
                    if (!isResizing) {
                        e.currentTarget.style.backgroundColor = 'transparent';
                    }
                } })] }));
};

// src/components/PanelManager/index.tsx
var PanelManager = function (_a) {
    var panels = _a.panels, _b = _a.activePanelIds, activePanelIds = _b === void 0 ? [] : _b, onPanelToggle = _a.onPanelToggle, children = _a.children;
    var _c = React.useState(activePanelIds), localActivePanels = _c[0], setLocalActivePanels = _c[1];
    var togglePanel = function (panelId) {
        var isActive = localActivePanels.includes(panelId);
        var newActivePanels = isActive
            ? localActivePanels.filter(function (id) { return id !== panelId; })
            : __spreadArray(__spreadArray([], localActivePanels, true), [panelId], false);
        setLocalActivePanels(newActivePanels);
        onPanelToggle === null || onPanelToggle === void 0 ? void 0 : onPanelToggle(panelId, !isActive);
    };
    var leftPanels = panels.filter(function (p) { return p.position === 'left' && localActivePanels.includes(p.id); });
    var rightPanels = panels.filter(function (p) { return p.position === 'right' && localActivePanels.includes(p.id); });
    return (jsxRuntime.jsxs("div", { style: { display: 'flex', height: '100%' }, children: [leftPanels.map(function (panel) {
                var PanelComponent = panel.component;
                return (jsxRuntime.jsx("div", { style: { width: panel.defaultWidth || 300 }, children: jsxRuntime.jsx(PanelComponent, __assign({}, panel.props)) }, panel.id));
            }), jsxRuntime.jsx("div", { style: { flex: 1 }, children: children }), rightPanels.map(function (panel) {
                var PanelComponent = panel.component;
                return (jsxRuntime.jsx("div", { style: { width: panel.defaultWidth || 300 }, children: jsxRuntime.jsx(PanelComponent, __assign({}, panel.props)) }, panel.id));
            }), jsxRuntime.jsx("div", { style: {
                    position: 'absolute',
                    top: '10px',
                    right: '10px',
                    display: 'flex',
                    gap: '4px',
                    zIndex: 1000
                }, children: panels.map(function (panel) { return (jsxRuntime.jsx("button", { onClick: function () { return togglePanel(panel.id); }, style: {
                        padding: '6px',
                        backgroundColor: localActivePanels.includes(panel.id) ? '#007bff' : '#555',
                        border: 'none',
                        borderRadius: '4px',
                        color: '#fff',
                        cursor: 'pointer',
                        fontSize: '12px'
                    }, title: panel.title, children: panel.icon || panel.title.charAt(0) }, panel.id)); }) })] }));
};

var getIframeHelperScript = function () {
    return "\n<script>\n  class IframeHelper {\n    constructor() {\n      this.selectedElement = null;\n      this.init();\n    }\n\n    init() {\n      document.addEventListener('mouseover', this.handleMouseOver.bind(this));\n      document.addEventListener('mouseout', this.handleMouseOut.bind(this));\n      document.addEventListener('click', this.handleClick.bind(this));\n      document.addEventListener('dblclick', this.handleDoubleClick.bind(this));\n      window.addEventListener('message', this.handleMessage.bind(this));\n    }\n\n    handleMouseOver(e) {\n      if (e.target !== this.selectedElement) {\n        e.target.style.outline = '2px dashed #007bff';\n      }\n    }\n\n    handleMouseOut(e) {\n      if (e.target !== this.selectedElement) {\n        e.target.style.outline = '';\n      }\n    }\n\n    handleClick(e) {\n      e.stopPropagation();\n\n      if (this.selectedElement) {\n        this.selectedElement.style.outline = '';\n      }\n\n      this.selectedElement = e.target;\n      this.selectedElement.style.outline = '2px solid #007bff';\n\n      const editableTags = ['P', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'SPAN', 'DIV', 'A', 'BUTTON'];\n      if (editableTags.includes(this.selectedElement.tagName)) {\n        this.selectedElement.setAttribute('contenteditable', 'true');\n        this.selectedElement.focus();\n      }\n\n      const elementData = this.getElementData(this.selectedElement);\n      window.parent.postMessage({\n        type: 'ELEMENT_SELECTED',\n        payload: elementData,\n      }, '*');\n    }\n\n    handleDoubleClick(e) {\n      e.preventDefault();\n      e.stopPropagation();\n\n      if (e.target.tagName === 'IMG') {\n        window.parent.postMessage({\n          type: 'OPEN_ASSET_MANAGER',\n          payload: {}\n        }, '*');\n      }\n    }\n\n    handleMessage(e) {\n      const { type, payload } = e.data;\n      \n      switch (type) {\n        case 'APPLY_STYLE':\n          this.applyStyle(payload.selector, payload.styles);\n          break;\n        case 'UPDATE_CLASSES':\n          this.updateClasses(payload.selector, payload.classes);\n          break;\n        case 'DELETE_ELEMENT':\n          this.deleteElement(payload.selector);\n          break;\n        case 'DUPLICATE_ELEMENT':\n          this.duplicateElement(payload.selector);\n          break;\n      }\n    }\n\n    duplicateElement(selector) {\n      const el = document.querySelector(selector);\n      if (el && el !== document.body && el !== document.documentElement) {\n        const clone = el.cloneNode(true);\n        \n        clone.removeAttribute('id');\n        const allElements = clone.querySelectorAll('*');\n        allElements.forEach(child => child.removeAttribute('id'));\n        \n        el.parentNode.insertBefore(clone, el.nextSibling);\n        \n        setTimeout(() => {\n          if (this.selectedElement) {\n            this.selectedElement.style.outline = '';\n          }\n          this.selectedElement = clone;\n          clone.style.outline = '2px solid #007bff';\n          \n          const elementData = this.getElementData(clone);\n          window.parent.postMessage({\n            type: 'ELEMENT_SELECTED',\n            payload: elementData,\n          }, '*');\n        }, 100);\n      }\n    }\n\n    getUniqueSelector(el) {\n      if (!el) return '';\n      const path = [];\n      \n      while (el && el.nodeType === Node.ELEMENT_NODE) {\n        let selector = el.nodeName.toLowerCase();\n        \n        if (el.id) {\n          selector += '#' + el.id;\n          path.unshift(selector);\n          break;\n        } else {\n          let sibling = el;\n          let nth = 1;\n          while ((sibling = sibling.previousElementSibling)) {\n            if (sibling.nodeName === el.nodeName) nth++;\n          }\n          selector += ':nth-of-type(' + nth + ')';\n        }\n        \n        path.unshift(selector);\n        el = el.parentElement;\n      }\n      \n      return path.join(' > ');\n    }\n\n    getComputedStyles(el) {\n      const computed = window.getComputedStyle(el);\n      const relevantStyles = {};\n      \n      const styleProps = [\n        'display', 'position', 'top', 'bottom', 'left', 'right', 'z-index',\n        'width', 'height', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left',\n        'padding-top', 'padding-right', 'padding-bottom', 'padding-left',\n        'font-size', 'font-weight', 'color', 'background-color', 'border-width',\n        'border-style', 'border-color', 'border-radius', 'opacity'\n      ];\n      \n      styleProps.forEach(prop => {\n        relevantStyles[prop] = computed.getPropertyValue(prop);\n      });\n      \n      return relevantStyles;\n    }\n\n    getElementData(el) {\n      return {\n        selector: this.getUniqueSelector(el),\n        tagName: el.tagName,\n        id: el.id || '',\n        classes: Array.from(el.classList),\n        textContent: el.textContent?.trim().substring(0, 50) || '',\n        computedStyles: this.getComputedStyles(el)\n      };\n    }\n\n    applyStyle(selector, styles) {\n      const el = document.querySelector(selector);\n      if (el) {\n        if (styles.src && el.tagName === 'IMG') {\n          el.src = styles.src;\n          delete styles.src;\n        }\n        \n        Object.assign(el.style, styles);\n      }\n    }\n\n    updateClasses(selector, classes) {\n      const el = document.querySelector(selector);\n      if (el) {\n        el.className = classes.join(' ');\n      }\n    }\n\n    deleteElement(selector) {\n      const el = document.querySelector(selector);\n      if (el && el !== document.body && el !== document.documentElement) {\n        el.remove();\n      }\n    }\n  }\n\n  new IframeHelper();\n</script>\n";
};

exports.AssetManager = AssetManager;
exports.BlockManager = BlockManager;
exports.ClassManager = ClassManager;
exports.DEFAULT_CLASSES = DEFAULT_CLASSES;
exports.DeviceManager = DeviceManager;
exports.DraggableBlockManager = DraggableBlockManager;
exports.ElementInfo = ElementInfo;
exports.PanelManager = PanelManager;
exports.PreviewButton = PreviewButton;
exports.ResizablePanel = ResizablePanel;
exports.STYLE_SECTIONS = STYLE_SECTIONS;
exports.StyleManager = StyleManager;
exports.TabbedRightPanel = TabbedRightPanel;
exports.VisualEditor = Editor;
exports.defaultDevices = defaultDevices;
exports.getIframeHelperScript = getIframeHelperScript;
exports.useEditor = useEditor;
//# sourceMappingURL=index.js.map