UNPKG

@ichigo_san/graphing

Version:

A lightweight UML-style diagram editor built with React Flow and Tailwind CSS

280 lines (278 loc) 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _lucideReact = require("lucide-react"); function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); } const EnhancedMenuBar = _ref => { let { onNew, onOpen, onSave, onSaveAs, onImportJSON, onImportJSONText, onImportDrawio, onExportJSON, onExportDrawio, onExportPNG, onExportJPG, onExportSVG, onUndo, onRedo, onCut, onCopy, onPaste, onDelete, onSelectAll, onDeselectAll, onAddContainer, onAddComponent, onAddShape, onLinkNodes, onUnlinkNodes, onValidateJSON, onAutoLayout, onTogglePropertiesPanel, onToggleStatsPanel, onToggleTheme, showThemeToggle = false, onToggleMini, showMiniToggle = false, canUndo = false, canRedo = false, hasSelection = false, hasClipboard = false, canLink = false } = _ref; const [activeMenu, setActiveMenu] = (0, _react.useState)(null); const menuRef = (0, _react.useRef)(null); // Close menu when clicking outside (0, _react.useEffect)(() => { const handleClickOutside = event => { if (menuRef.current && !menuRef.current.contains(event.target)) { setActiveMenu(null); } }; document.addEventListener('mousedown', handleClickOutside); return () => document.removeEventListener('mousedown', handleClickOutside); }, []); const handleMenuClick = (0, _react.useCallback)(menuName => { setActiveMenu(activeMenu === menuName ? null : menuName); }, [activeMenu]); const handleMenuItemClick = (0, _react.useCallback)(action => { if (action) { action(); } setActiveMenu(null); }, []); const MenuButton = _ref2 => { let { name, icon: Icon, children } = _ref2; return /*#__PURE__*/_react.default.createElement("div", { className: "relative" }, /*#__PURE__*/_react.default.createElement("button", { className: "flex items-center gap-2 px-3 py-1.5 text-gray-800 dark:text-gray-100 bg-white dark:bg-gray-900 text-sm font-medium rounded-md transition-colors ".concat(activeMenu === name ? 'bg-gray-200 dark:bg-gray-700 shadow-sm' : 'hover:bg-gray-100 dark:hover:bg-gray-700'), onClick: () => handleMenuClick(name) }, /*#__PURE__*/_react.default.createElement(Icon, { size: 16 }), /*#__PURE__*/_react.default.createElement("span", null, name), /*#__PURE__*/_react.default.createElement(_lucideReact.ChevronDown, { size: 12 })), activeMenu === name && /*#__PURE__*/_react.default.createElement("div", { className: "absolute top-full left-0 mt-1 bg-white dark:bg-gray-800 shadow-lg rounded-lg min-w-[200px] z-50 animate-fadeIn" }, children)); }; const MenuItem = _ref3 => { let { onClick, disabled = false, children, shortcut = null, separator = false, icon: Icon = null } = _ref3; if (separator) { return /*#__PURE__*/_react.default.createElement("div", { className: "h-px my-1 bg-gray-200 dark:bg-gray-700" }); } return /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center justify-between px-4 py-2.5 text-gray-700 dark:text-gray-200 text-sm cursor-pointer transition-all ".concat(disabled ? 'opacity-50 cursor-not-allowed' : 'hover:bg-gray-100 dark:hover:bg-gray-700 hover:translate-x-0.5'), onClick: disabled ? undefined : () => handleMenuItemClick(onClick) }, /*#__PURE__*/_react.default.createElement("span", { className: "flex items-center gap-2" }, Icon && /*#__PURE__*/_react.default.createElement(Icon, { size: 14 }), children), shortcut && /*#__PURE__*/_react.default.createElement("span", { className: "text-xs bg-gray-100 dark:bg-gray-700 text-gray-500 dark:text-gray-400 px-1.5 py-0.5 rounded font-mono border border-gray-200 dark:border-gray-600" }, shortcut)); }; return /*#__PURE__*/_react.default.createElement("div", { ref: menuRef, className: "flex items-center bg-white dark:bg-gray-900 p-0 relative z-10 border-b border-gray-200 dark:border-gray-700" }, /*#__PURE__*/_react.default.createElement(MenuButton, { name: "File", icon: _lucideReact.File }, /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onNew, shortcut: "Ctrl+N" }, "New Diagram"), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onOpen, shortcut: "Ctrl+O" }, "Open..."), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onSave, shortcut: "Ctrl+S" }, "Save"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onSaveAs, shortcut: "Ctrl+Shift+S" }, "Save As..."), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onImportJSON }, "Import JSON..."), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onImportJSONText }, "Paste JSON..."), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onImportDrawio }, "Import Draw.io XML..."), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onExportJSON }, "Export as JSON"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onExportDrawio }, "Export as Draw.io XML"), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onExportPNG }, "Export as PNG"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onExportJPG }, "Export as JPG"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onExportSVG }, "Export as SVG")), /*#__PURE__*/_react.default.createElement(MenuButton, { name: "Edit", icon: _lucideReact.Edit }, /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onUndo, disabled: !canUndo, shortcut: "Ctrl+Z", icon: _lucideReact.ChevronDown }, "Undo"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onRedo, disabled: !canRedo, shortcut: "Ctrl+Y" }, "Redo"), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onCut, disabled: !hasSelection, shortcut: "Ctrl+X" }, "Cut"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onCopy, disabled: !hasSelection, shortcut: "Ctrl+C", icon: _lucideReact.Copy }, "Copy"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onPaste, disabled: !hasClipboard, shortcut: "Ctrl+V" }, "Paste"), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onDelete, disabled: !hasSelection, shortcut: "Delete", icon: _lucideReact.Trash }, "Delete"), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onSelectAll, shortcut: "Ctrl+A" }, "Select All"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onDeselectAll, disabled: !hasSelection }, "Deselect All"), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onAddContainer, icon: _lucideReact.Plus }, "Add Container"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onAddComponent }, "Add Component"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onAddShape }, "Add Shape")), /*#__PURE__*/_react.default.createElement(MenuButton, { name: "Connect", icon: _lucideReact.Link }, /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onLinkNodes, disabled: !canLink, icon: _lucideReact.Link }, "Link Selected Nodes"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onUnlinkNodes, disabled: !hasSelection, icon: _lucideReact.Unlink }, "Unlink Selected")), /*#__PURE__*/_react.default.createElement(MenuButton, { name: "View", icon: _lucideReact.Eye }, /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "Zoom In"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "Zoom Out"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "Fit to Screen"), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "Show Grid"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "Show Rulers"), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "Toggle Minimap"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onTogglePropertiesPanel }, "Toggle Properties Panel"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onToggleStatsPanel }, "Toggle Diagram Stats"), showMiniToggle && /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onToggleMini }, "Toggle Mini Editor"), showThemeToggle && /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onToggleTheme }, "Toggle Dark Mode")), /*#__PURE__*/_react.default.createElement(MenuButton, { name: "Settings", icon: _lucideReact.Settings }, /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "Diagram Templates..."), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onValidateJSON }, "JSON Schema Validator"), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: onAutoLayout }, "Auto-Layout"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "Align Elements"), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "Preferences...")), /*#__PURE__*/_react.default.createElement(MenuButton, { name: "Help", icon: _lucideReact.HelpCircle }, /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "Keyboard Shortcuts"), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "User Guide"), /*#__PURE__*/_react.default.createElement(MenuItem, { separator: true }), /*#__PURE__*/_react.default.createElement(MenuItem, { onClick: () => {} }, "About"))); }; var _default = exports.default = EnhancedMenuBar;