UNPKG

aura-glass

Version:

A comprehensive glassmorphism design system for React applications with 142+ production-ready components

302 lines (299 loc) 12.2 kB
'use client'; import { jsx, jsxs } from 'react/jsx-runtime'; import { useState, useEffect, useCallback } from 'react'; import { cn } from '../../lib/utilsComprehensive.js'; import { DragDropProvider, useDragDrop } from './GlassDragDropProvider.js'; import { GlassComponentPalette } from './GlassComponentPalette.js'; import { GlassCanvas } from './GlassCanvas.js'; import { GlassPropertyPanel } from './GlassPropertyPanel.js'; import { GlassPageStructure } from './GlassPageStructure.js'; const Toolbar = () => { const { pageState, undo, redo, canUndo, canRedo, togglePreviewMode, setActiveBreakpoint, toggleGrid, toggleSnapToGrid, clearPage, exportPage, importPage } = useDragDrop(); const handleSave = useCallback(() => { const data = exportPage(); localStorage.setItem("glass-page-builder-autosave", JSON.stringify(data)); // You could also call an onSave prop here }, [exportPage]); const handleLoad = useCallback(() => { const saved = localStorage.getItem("glass-page-builder-autosave"); if (saved) { try { const data = JSON.parse(saved); importPage(data); } catch (error) { console.error("Error loading saved data:", error); } } }, [importPage]); // Auto-save every 30 seconds useEffect(() => { const interval = setInterval(() => { if (pageState.components.length > 0) { handleSave(); } }, 30000); return () => clearInterval(interval); }, [pageState.components.length, handleSave]); return jsxs("div", { "data-glass-component": true, className: "glass-flex glass-items-center glass-justify-between glass-p-4 glass-surface-subtle glass-border-b glass-border-subtle", children: [jsxs("div", { className: "glass-flex glass-items-center glass-gap-4", children: [jsxs("div", { className: "glass-flex glass-items-center glass-gap-2", children: [jsx("h1", { className: 'glass-text-xl font-bold glass-text-secondary', children: "Page Builder" }), jsx("span", { className: "glass-text-xs glass-text-secondary glass-surface-subtle glass-px-2 glass-py-1 glass-radius", children: "v1.0" })] }), jsx("div", { className: 'w-px h-6 glass-surface-subtle' }), jsxs("div", { className: "glass-flex glass-items-center glass-gap-2", children: [jsxs("button", { onClick: clearPage, className: 'glass-flex glass-items-center glass-gap-2 glass-px-3 glass-py-2 glass-text-sm glass-text-secondary hover:glass-surface-subtle glass-radius-md transition-colors glass-focus glass-touch-target glass-contrast-guard glass-focus glass-touch-target glass-contrast-guard', children: [jsx("span", { children: "\uD83D\uDDD1\uFE0F" }), "New"] }), jsxs("button", { onClick: handleSave, className: 'glass-flex glass-items-center glass-gap-2 glass-px-3 glass-py-2 glass-text-sm glass-text-secondary hover:glass-surface-subtle glass-radius-md transition-colors glass-focus glass-touch-target glass-contrast-guard glass-focus glass-touch-target glass-contrast-guard', children: [jsx("span", { children: "\uD83D\uDCBE" }), "Save"] }), jsxs("button", { onClick: handleLoad, className: 'glass-flex glass-items-center glass-gap-2 glass-px-3 glass-py-2 glass-text-sm glass-text-secondary hover:glass-surface-subtle glass-radius-md transition-colors glass-focus glass-touch-target glass-contrast-guard glass-focus glass-touch-target glass-contrast-guard', children: [jsx("span", { children: "\uD83D\uDCC1" }), "Load"] })] }), jsx("div", { className: 'w-px h-6 glass-surface-subtle' }), jsxs("div", { className: "glass-flex glass-items-center glass-gap-1", children: [jsx("button", { onClick: undo, disabled: !canUndo(), className: cn("p-2 rounded-md transition-colors", canUndo() ? "text-gray-700 hover:bg-gray-100" : "text-gray-400 cursor-not-allowed"), title: "Undo (Ctrl+Z)", children: "\u21B6" }), jsx("button", { onClick: redo, disabled: !canRedo(), className: cn("p-2 rounded-md transition-colors", canRedo() ? "text-gray-700 hover:bg-gray-100" : "text-gray-400 cursor-not-allowed"), title: "Redo (Ctrl+Y)", children: "\u21B7" })] })] }), jsx("div", { className: "glass-flex glass-items-center glass-gap-2 glass-surface-subtle glass-radius-lg glass-p-1", children: [{ key: "desktop", icon: "🖥️", label: "Desktop" }, { key: "tablet", icon: "📱", label: "Tablet" }, { key: "mobile", icon: "📱", label: "Mobile" }].map(breakpoint => jsxs("button", { onClick: () => setActiveBreakpoint(breakpoint.key), className: cn("flex items-center gap-2 px-3 py-2 text-sm rounded-md transition-colors", pageState.activeBreakpoint === breakpoint.key ? "bg-white text-gray-900 shadow-sm" : "text-gray-600 hover:text-gray-900"), title: breakpoint.label, children: [jsx("span", { children: breakpoint.icon }), breakpoint.label] }, breakpoint.key)) }), jsxs("div", { className: "glass-flex glass-items-center glass-gap-4", children: [jsxs("div", { className: "glass-flex glass-items-center glass-gap-2", children: [jsxs("button", { onClick: toggleGrid, className: cn("flex items-center gap-2 px-3 py-2 text-sm rounded-md transition-colors", pageState.showGrid ? "bg-blue-100 text-blue-700" : "text-gray-700 hover:bg-gray-100"), children: [jsx("span", { children: "\u229E" }), "Grid"] }), jsxs("button", { onClick: toggleSnapToGrid, className: cn("flex items-center gap-2 px-3 py-2 text-sm rounded-md transition-colors", pageState.snapToGrid ? "bg-blue-100 text-blue-700" : "text-gray-700 hover:bg-gray-100"), children: [jsx("span", { children: "\uD83E\uDDF2" }), "Snap"] })] }), jsx("div", { className: 'w-px h-6 glass-surface-subtle' }), jsxs("div", { className: "glass-flex glass-items-center glass-gap-2", children: [jsxs("button", { onClick: togglePreviewMode, className: cn("flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-md transition-colors", pageState.previewMode ? "bg-green-600 text-white hover:bg-green-700" : "bg-gray-100 text-gray-700 hover:bg-gray-200"), children: [jsx("span", { children: pageState.previewMode ? "👁️" : "✏️" }), pageState.previewMode ? "Exit Preview" : "Preview"] }), jsxs("button", { onClick: () => { const data = exportPage(); console.log("Publishing:", data); alert("Page published! (Demo - check console for data)"); }, className: 'glass-flex glass-items-center glass-gap-2 glass-px-4 glass-py-2 glass-text-sm font-medium glass-surface-blue text-primary hover:glass-surface-blue glass-radius-md transition-colors', children: [jsx("span", { children: "\uD83D\uDE80" }), "Publish"] })] })] })] }); }; const PageBuilderCore = ({ className, initialData, onSave, onPreview, onPublish }) => { const { importPage } = useDragDrop(); const [leftPanelCollapsed, setLeftPanelCollapsed] = useState(false); const [rightPanelCollapsed, setRightPanelCollapsed] = useState(false); const [activeLeftPanel, setActiveLeftPanel] = useState("components"); // Load initial data useEffect(() => { if (initialData) { importPage(initialData); } else { // Try to load from localStorage const saved = localStorage.getItem("glass-page-builder-autosave"); if (saved) { try { const data = JSON.parse(saved); importPage(data); } catch (error) { console.error("Error loading saved data:", error); } } } }, [initialData, importPage]); // Keyboard shortcuts useEffect(() => { const handleKeyDown = e => { if ((e.metaKey || e.ctrlKey) && !e.shiftKey && !e.altKey) { switch (e.key) { case "z": e.preventDefault(); // undo() would be called here if we had access to it break; case "y": e.preventDefault(); // redo() would be called here if we had access to it break; case "s": e.preventDefault(); break; case "p": e.preventDefault(); break; } } }; document.addEventListener("keydown", handleKeyDown); return () => document.removeEventListener("keydown", handleKeyDown); }, [onSave, onPreview]); return jsxs("div", { className: cn("h-screen flex flex-col overflow-hidden bg-gray-100", className), children: [jsx(Toolbar, {}), jsxs("div", { className: 'glass-flex-1 glass-flex overflow-hidden', children: [jsxs("div", { className: "glass-flex", children: [!leftPanelCollapsed && jsxs("div", { className: 'w-12 glass-surface-subtle glass-border-r glass-border-subtle glass-flex glass-flex-col', children: [jsxs("button", { onClick: () => setActiveLeftPanel("components"), className: cn("flex flex-col items-center gap-1 p-3 text-xs transition-colors", activeLeftPanel === "components" ? "bg-blue-50 text-blue-600" : "text-gray-600 hover:bg-gray-50"), title: "Components", children: [jsx("span", { className: "glass-text-lg", children: "\uD83D\uDCE6" }), "Comp"] }), jsxs("button", { onClick: () => setActiveLeftPanel("structure"), className: cn("flex flex-col items-center gap-1 p-3 text-xs transition-colors", activeLeftPanel === "structure" ? "bg-blue-50 text-blue-600" : "text-gray-600 hover:bg-gray-50"), title: "Structure", children: [jsx("span", { className: "glass-text-lg", children: "\uD83C\uDF33" }), "Tree"] })] }), jsx("div", { className: "glass-border-r glass-border-subtle", children: activeLeftPanel === "components" ? jsx(GlassComponentPalette, { collapsed: leftPanelCollapsed, onToggleCollapse: () => setLeftPanelCollapsed(!leftPanelCollapsed) }) : jsx(GlassPageStructure, { collapsed: leftPanelCollapsed, onToggleCollapse: () => setLeftPanelCollapsed(!leftPanelCollapsed) }) })] }), jsx(GlassCanvas, {}), jsx("div", { className: "glass-border-l glass-border-subtle", children: jsx(GlassPropertyPanel, { collapsed: rightPanelCollapsed, onToggleCollapse: () => setRightPanelCollapsed(!rightPanelCollapsed) }) })] }), jsxs("div", { className: 'h-6 glass-surface-primary text-gray-300 glass-text-xs glass-flex glass-items-center glass-justify-between glass-px-4', children: [jsxs("div", { className: "glass-flex glass-items-center glass-gap-4", children: [jsx("span", { children: "\uD83D\uDFE2 Ready" }), jsx("span", { children: "Auto-save: ON" })] }), jsxs("div", { className: "glass-flex glass-items-center glass-gap-4", children: [jsx("span", { children: "Zoom: 100%" }), jsxs("span", { children: ["Grid: ", `${"OFF"}`] })] })] })] }); }; const GlassPageBuilder = ({ className, ...restProps }) => { return jsx(DragDropProvider, { className: className, children: jsx(PageBuilderCore, { ...restProps, className: className }) }); }; export { GlassPageBuilder }; //# sourceMappingURL=GlassPageBuilder.js.map