UNPKG

@ichigo_san/graphing

Version:

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

682 lines (670 loc) โ€ข 37.5 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); } function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } // src/components/editor/TailwindPropertyEditor.jsx // Simple preview for the different intersection styles const IntersectionStylePreview = _ref => { let { style, size = 40, className = '' } = _ref; const cx = size / 2; const cy = size / 2; const line = size * 0.7; const jump = 8; switch (style) { case 'arc': return /*#__PURE__*/_react.default.createElement("svg", { width: size, height: size, className: className, viewBox: "0 0 ".concat(size, " ").concat(size) }, /*#__PURE__*/_react.default.createElement("line", { x1: cx - line / 2, y1: cy, x2: cx + line / 2, y2: cy, stroke: "#94a3b8", strokeWidth: "2" }), /*#__PURE__*/_react.default.createElement("path", { d: "M ".concat(cx, " ").concat(cy - line / 2, " L ").concat(cx, " ").concat(cy - jump / 2, " Q ").concat(cx + jump / 2, " ").concat(cy, " ").concat(cx, " ").concat(cy + jump / 2, " L ").concat(cx, " ").concat(cy + line / 2), stroke: "#3b82f6", strokeWidth: "2", fill: "none" })); case 'sharp': return /*#__PURE__*/_react.default.createElement("svg", { width: size, height: size, className: className, viewBox: "0 0 ".concat(size, " ").concat(size) }, /*#__PURE__*/_react.default.createElement("line", { x1: cx - line / 2, y1: cy, x2: cx + line / 2, y2: cy, stroke: "#94a3b8", strokeWidth: "2" }), /*#__PURE__*/_react.default.createElement("path", { d: "M ".concat(cx, " ").concat(cy - line / 2, " L ").concat(cx, " ").concat(cy - jump / 2, " L ").concat(cx + jump / 2, " ").concat(cy - jump / 2, " L ").concat(cx + jump / 2, " ").concat(cy + jump / 2, " L ").concat(cx, " ").concat(cy + jump / 2, " L ").concat(cx, " ").concat(cy + line / 2), stroke: "#3b82f6", strokeWidth: "2", fill: "none" })); default: return /*#__PURE__*/_react.default.createElement("svg", { width: size, height: size, className: className, viewBox: "0 0 ".concat(size, " ").concat(size) }, /*#__PURE__*/_react.default.createElement("line", { x1: cx - line / 2, y1: cy, x2: cx + line / 2, y2: cy, stroke: "#94a3b8", strokeWidth: "2" }), /*#__PURE__*/_react.default.createElement("line", { x1: cx, y1: cy - line / 2, x2: cx, y2: cy + line / 2, stroke: "#3b82f6", strokeWidth: "2" })); } }; // Small selector embedded in this file to avoid extra components const IntersectionStyleSelector = _ref2 => { let { value, onChange, disabled = false } = _ref2; const options = [{ value: 'none', label: 'None' }, { value: 'arc', label: 'Arc' }, { value: 'sharp', label: 'Sharp' }]; const handleClick = val => { if (disabled) return; onChange({ target: { value: val } }); }; return /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Intersections:"), /*#__PURE__*/_react.default.createElement("div", { className: "flex gap-2" }, options.map(opt => /*#__PURE__*/_react.default.createElement("button", { type: "button", key: opt.value, onClick: () => handleClick(opt.value), className: "p-1 border rounded ".concat(value === opt.value ? 'border-indigo-500' : 'border-gray-200', " ").concat(disabled ? 'opacity-50 cursor-not-allowed' : 'hover:border-indigo-400') }, /*#__PURE__*/_react.default.createElement(IntersectionStylePreview, { style: opt.value, size: 32 }))))); }; const TailwindPropertyEditor = _ref3 => { let { selectedNode, selectedEdge, onElementPropertyChange, minimized = false, onToggleMinimized = () => {}, onClose = () => {} } = _ref3; // Node properties const [nodeLabel, setNodeLabel] = (0, _react.useState)(''); const [nodeIcon, setNodeIcon] = (0, _react.useState)(''); const [nodeTextColor, setNodeTextColor] = (0, _react.useState)('#000000'); const [nodeDescription, setNodeDescription] = (0, _react.useState)(''); const [nodeColor, setNodeColor] = (0, _react.useState)('#ffffff'); const [nodeBorderColor, setNodeBorderColor] = (0, _react.useState)('#dddddd'); const [nodeZIndex, setNodeZIndex] = (0, _react.useState)(1); // Edge properties const [edgeLabel, setEdgeLabel] = (0, _react.useState)(''); const [edgeDescription, setEdgeDescription] = (0, _react.useState)(''); const [edgeType, setEdgeType] = (0, _react.useState)('smoothstep'); const [edgeAnimated, setEdgeAnimated] = (0, _react.useState)(false); const [edgeStrokeWidth, setEdgeStrokeWidth] = (0, _react.useState)(2); const [edgeStrokeColor, setEdgeStrokeColor] = (0, _react.useState)('#999999'); const [edgeStrokeDasharray, setEdgeStrokeDasharray] = (0, _react.useState)(''); const [edgeZIndex, setEdgeZIndex] = (0, _react.useState)(5); const [edgeMarkerOption, setEdgeMarkerOption] = (0, _react.useState)('end'); const [edgeIntersection, setEdgeIntersection] = (0, _react.useState)('none'); // UI State const [expandedSections, setExpandedSections] = (0, _react.useState)({ basic: true, style: true, advanced: false }); // Common emojis with categories const emojiCategories = { 'Tech': ['๐Ÿ’ป', '๐Ÿ–ฅ๏ธ', '๐Ÿ“ฑ', 'โŒš', '๐Ÿ“ก', '๐Ÿ›ฐ๏ธ', '๐Ÿ’พ', '๐Ÿ’ฟ', '๐Ÿ“€', '๐Ÿ”Œ', '๐Ÿ”‹', '๐Ÿ–จ๏ธ', 'โŒจ๏ธ', '๐Ÿ–ฑ๏ธ', '๐Ÿ’ฝ'], 'Network': ['๐ŸŒ', '๐Ÿ“ถ', '๐Ÿ“ก', '๐Ÿ”—', 'โ›“๏ธ', '๐Ÿ”’', '๐Ÿ”“', '๐Ÿ”', '๐Ÿ”‘', '๐Ÿ—๏ธ', '๐Ÿ“Š', '๐Ÿ“ˆ', '๐Ÿ“‰', '๐Ÿ“‹', '๐Ÿ“Œ'], 'Data': ['๐Ÿ“', '๐Ÿ“‚', '๐Ÿ—‚๏ธ', '๐Ÿ“„', '๐Ÿ“ƒ', '๐Ÿ“‘', '๐Ÿ“Š', '๐Ÿ“ˆ', '๐Ÿ“‰', '๐Ÿ“', '๐Ÿ“”', '๐Ÿ“•', '๐Ÿ“—', '๐Ÿ“˜', '๐Ÿ“™'], 'Tools': ['๐Ÿ”ง', '๐Ÿ”จ', 'โš™๏ธ', '๐Ÿ› ๏ธ', '๐Ÿ—œ๏ธ', 'โš’๏ธ', '๐Ÿงฐ', '๐Ÿ”ฉ', 'โš–๏ธ', '๐Ÿงฒ', 'โš—๏ธ', '๐Ÿงช', '๐Ÿงฌ', '๐Ÿ”ฌ', '๐Ÿ”ญ'], 'Shapes': ['๐Ÿ”ท', '๐Ÿ”ถ', '๐Ÿ”ต', '๐ŸŸข', '๐ŸŸก', '๐ŸŸ ', '๐Ÿ”ด', '๐ŸŸฃ', 'โšซ', 'โšช', '๐ŸŸค', 'โญ', 'โœจ', '๐Ÿ’ซ', '๐ŸŒŸ'] }; // Update local state when selection changes (0, _react.useEffect)(() => { if (selectedNode !== null && selectedNode !== void 0 && selectedNode.data) { var _selectedNode$style; setNodeLabel(selectedNode.data.label || ''); setNodeIcon(selectedNode.data.icon || ''); setNodeTextColor(selectedNode.data.textColor || '#000000'); setNodeDescription(selectedNode.data.description || ''); setNodeColor(selectedNode.data.color || '#ffffff'); setNodeBorderColor(selectedNode.data.borderColor || '#dddddd'); setNodeZIndex(selectedNode.zIndex || ((_selectedNode$style = selectedNode.style) === null || _selectedNode$style === void 0 ? void 0 : _selectedNode$style.zIndex) || 1); } if (selectedEdge) { var _selectedEdge$data, _selectedEdge$data2, _selectedEdge$style, _selectedEdge$style2, _selectedEdge$style3, _selectedEdge$style4, _selectedEdge$markerS, _selectedEdge$markerE, _selectedEdge$data3; setEdgeLabel(((_selectedEdge$data = selectedEdge.data) === null || _selectedEdge$data === void 0 ? void 0 : _selectedEdge$data.label) || selectedEdge.label || ''); setEdgeDescription(((_selectedEdge$data2 = selectedEdge.data) === null || _selectedEdge$data2 === void 0 ? void 0 : _selectedEdge$data2.description) || ''); setEdgeType(selectedEdge.type || 'smoothstep'); setEdgeAnimated(selectedEdge.animated || false); setEdgeStrokeWidth(((_selectedEdge$style = selectedEdge.style) === null || _selectedEdge$style === void 0 ? void 0 : _selectedEdge$style.strokeWidth) || 2); setEdgeStrokeColor(((_selectedEdge$style2 = selectedEdge.style) === null || _selectedEdge$style2 === void 0 ? void 0 : _selectedEdge$style2.stroke) || '#999999'); setEdgeStrokeDasharray(((_selectedEdge$style3 = selectedEdge.style) === null || _selectedEdge$style3 === void 0 ? void 0 : _selectedEdge$style3.strokeDasharray) || ''); setEdgeZIndex(selectedEdge.zIndex || ((_selectedEdge$style4 = selectedEdge.style) === null || _selectedEdge$style4 === void 0 ? void 0 : _selectedEdge$style4.zIndex) || 5); const start = ((_selectedEdge$markerS = selectedEdge.markerStart) === null || _selectedEdge$markerS === void 0 ? void 0 : _selectedEdge$markerS.type) !== undefined ? selectedEdge.markerStart.type : 'none'; const end = ((_selectedEdge$markerE = selectedEdge.markerEnd) === null || _selectedEdge$markerE === void 0 ? void 0 : _selectedEdge$markerE.type) !== undefined ? selectedEdge.markerEnd.type : 'none'; if (start !== 'none' && end !== 'none') setEdgeMarkerOption('both');else if (start !== 'none') setEdgeMarkerOption('start');else if (end !== 'none') setEdgeMarkerOption('end');else setEdgeMarkerOption('none'); setEdgeIntersection(((_selectedEdge$data3 = selectedEdge.data) === null || _selectedEdge$data3 === void 0 ? void 0 : _selectedEdge$data3.intersection) || 'none'); } }, [selectedNode, selectedEdge]); // Toggle section expansion const toggleSection = (0, _react.useCallback)(section => { setExpandedSections(prev => _objectSpread(_objectSpread({}, prev), {}, { [section]: !prev[section] })); }, []); // Node property handlers const handleNodeLabelChange = (0, _react.useCallback)(e => { const value = e.target.value; setNodeLabel(value); onElementPropertyChange('node', 'label', value); }, [onElementPropertyChange]); const handleNodeIconChange = (0, _react.useCallback)(e => { const value = e.target.value; setNodeIcon(value); onElementPropertyChange('node', 'icon', value); }, [onElementPropertyChange]); const handleEmojiClick = (0, _react.useCallback)(emoji => { setNodeIcon(emoji); onElementPropertyChange('node', 'icon', emoji); }, [onElementPropertyChange]); // Quick style presets const applyEdgePreset = (0, _react.useCallback)(preset => { switch (preset) { case 'solid': setEdgeStrokeDasharray(''); setEdgeStrokeWidth(2); onElementPropertyChange('edge', 'style.strokeDasharray', undefined); onElementPropertyChange('edge', 'style.strokeWidth', 2); break; case 'dashed': setEdgeStrokeDasharray('5,5'); onElementPropertyChange('edge', 'style.strokeDasharray', '5,5'); break; case 'dotted': setEdgeStrokeDasharray('2,2'); onElementPropertyChange('edge', 'style.strokeDasharray', '2,2'); break; case 'thick': setEdgeStrokeWidth(4); onElementPropertyChange('edge', 'style.strokeWidth', 4); break; default: break; } }, [onElementPropertyChange]); // Node handlers const handleNodeDescriptionChange = (0, _react.useCallback)(e => { const value = e.target.value; setNodeDescription(value); onElementPropertyChange('node', 'description', value); }, [onElementPropertyChange]); const handleNodeZIndexChange = (0, _react.useCallback)(e => { const value = parseInt(e.target.value, 10) || 0; setNodeZIndex(value); onElementPropertyChange('node', 'zIndex', value); }, [onElementPropertyChange]); const handleNodeColorChange = (0, _react.useCallback)(e => { const value = e.target.value; setNodeColor(value); onElementPropertyChange('node', 'color', value); }, [onElementPropertyChange]); const handleNodeBorderColorChange = (0, _react.useCallback)(e => { const value = e.target.value; setNodeBorderColor(value); onElementPropertyChange('node', 'borderColor', value); }, [onElementPropertyChange]); const handleNodeTextColorChange = (0, _react.useCallback)(e => { const value = e.target.value; setNodeTextColor(value); onElementPropertyChange('node', 'textColor', value); }, [onElementPropertyChange]); // Edge handlers const handleEdgeLabel = (0, _react.useCallback)(e => { const value = e.target.value; setEdgeLabel(value); onElementPropertyChange('edge', 'label', value); }, [onElementPropertyChange]); const handleEdgeDescriptionChange = (0, _react.useCallback)(e => { const value = e.target.value; setEdgeDescription(value); onElementPropertyChange('edge', 'description', value); }, [onElementPropertyChange]); const handleEdgeZIndexChange = (0, _react.useCallback)(e => { const value = parseInt(e.target.value, 10) || 0; setEdgeZIndex(value); onElementPropertyChange('edge', 'zIndex', value); }, [onElementPropertyChange]); const handleEdgeTypeChange = (0, _react.useCallback)(e => { const value = e.target.value; setEdgeType(value); onElementPropertyChange('edge', 'type', value); }, [onElementPropertyChange]); const handleEdgeStrokeColorChange = (0, _react.useCallback)(e => { const value = e.target.value; setEdgeStrokeColor(value); onElementPropertyChange('edge', 'style.stroke', value); }, [onElementPropertyChange]); const handleEdgeStrokeWidthChange = (0, _react.useCallback)(e => { const value = parseInt(e.target.value, 10) || 1; setEdgeStrokeWidth(value); onElementPropertyChange('edge', 'style.strokeWidth', value); }, [onElementPropertyChange]); const handleEdgeStrokeDasharrayChange = (0, _react.useCallback)(e => { const value = e.target.value; setEdgeStrokeDasharray(value); onElementPropertyChange('edge', 'style.strokeDasharray', value); }, [onElementPropertyChange]); const handleEdgeAnimatedChange = (0, _react.useCallback)(e => { const checked = e.target.checked; setEdgeAnimated(checked); onElementPropertyChange('edge', 'animated', checked); }, [onElementPropertyChange]); const handleEdgeMarkerChange = (0, _react.useCallback)(e => { const value = e.target.value; setEdgeMarkerOption(value); switch (value) { case 'both': onElementPropertyChange('edge', 'markerStart', { type: 'arrow' }); onElementPropertyChange('edge', 'markerEnd', { type: 'arrow' }); break; case 'start': onElementPropertyChange('edge', 'markerStart', { type: 'arrow' }); onElementPropertyChange('edge', 'markerEnd', undefined); break; case 'end': onElementPropertyChange('edge', 'markerStart', undefined); onElementPropertyChange('edge', 'markerEnd', { type: 'arrow' }); break; default: onElementPropertyChange('edge', 'markerStart', undefined); onElementPropertyChange('edge', 'markerEnd', undefined); break; } }, [onElementPropertyChange]); // ๐Ÿ‘ˆ UPDATED: This handler now works with the new component const handleEdgeIntersectionChange = (0, _react.useCallback)(e => { const value = e.target.value; setEdgeIntersection(value); onElementPropertyChange('edge', 'intersection', value); }, [onElementPropertyChange]); if (!selectedNode && !selectedEdge) { return /*#__PURE__*/_react.default.createElement("div", { className: "w-72 max-w-[90vw] bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-100 rounded-lg shadow-lg ".concat(minimized ? 'overflow-hidden' : 'h-full overflow-y-auto') }, /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center justify-between py-3 px-4 bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-gray-100 font-semibold rounded-t-lg" }, /*#__PURE__*/_react.default.createElement("span", null, "Properties"), /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center space-x-1" }, /*#__PURE__*/_react.default.createElement("button", { className: "p-1 hover:bg-white/10 rounded", onClick: onToggleMinimized, title: minimized ? 'Expand' : 'Minimize' }, minimized ? /*#__PURE__*/_react.default.createElement(_lucideReact.ChevronUp, { size: 14 }) : /*#__PURE__*/_react.default.createElement(_lucideReact.ChevronDown, { size: 14 })), /*#__PURE__*/_react.default.createElement("button", { className: "p-1 hover:bg-white/10 rounded", onClick: onClose, title: "Close" }, /*#__PURE__*/_react.default.createElement(_lucideReact.X, { size: 14 })))), !minimized && /*#__PURE__*/_react.default.createElement("div", { className: "p-4" }, /*#__PURE__*/_react.default.createElement("div", { className: "text-center text-gray-500 dark:text-gray-400 py-6" }, /*#__PURE__*/_react.default.createElement("p", null, "Select an element to edit its properties"), /*#__PURE__*/_react.default.createElement("div", { className: "mt-4 text-left text-sm bg-gray-50 dark:bg-gray-700 p-3 rounded-lg" }, /*#__PURE__*/_react.default.createElement("strong", null, "Tips:"), /*#__PURE__*/_react.default.createElement("ul", { className: "mt-2 pl-5 list-disc" }, /*#__PURE__*/_react.default.createElement("li", { className: "mb-1" }, "Click nodes or edges to select them"), /*#__PURE__*/_react.default.createElement("li", { className: "mb-1" }, "Use Ctrl+C/V to copy/paste"), /*#__PURE__*/_react.default.createElement("li", { className: "mb-1" }, "Use Delete key to remove elements"), /*#__PURE__*/_react.default.createElement("li", { className: "mb-1" }, "Double-click to edit labels inline")))))); } return /*#__PURE__*/_react.default.createElement("div", { className: "w-72 max-w-[90vw] bg-white dark:bg-gray-800 text-gray-800 dark:text-gray-100 rounded-lg shadow-lg ".concat(minimized ? 'overflow-hidden' : 'h-full overflow-y-auto') }, /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center justify-between py-3 px-4 bg-gray-100 dark:bg-gray-900 text-gray-800 dark:text-gray-100 font-semibold rounded-t-lg" }, /*#__PURE__*/_react.default.createElement("span", null, selectedNode ? "".concat(selectedNode.type || 'Node', " Properties") : 'Edge Properties'), /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center space-x-1" }, /*#__PURE__*/_react.default.createElement("button", { className: "p-1 hover:bg-white/10 rounded", onClick: onToggleMinimized, title: minimized ? 'Expand' : 'Minimize' }, minimized ? /*#__PURE__*/_react.default.createElement(_lucideReact.ChevronUp, { size: 14 }) : /*#__PURE__*/_react.default.createElement(_lucideReact.ChevronDown, { size: 14 })), /*#__PURE__*/_react.default.createElement("button", { className: "p-1 hover:bg-white/10 rounded", onClick: onClose, title: "Close" }, /*#__PURE__*/_react.default.createElement(_lucideReact.X, { size: 14 })))), !minimized && /*#__PURE__*/_react.default.createElement("div", { className: "p-4" }, /*#__PURE__*/_react.default.createElement("div", { className: "mb-4 border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden" }, /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center px-4 py-3 bg-gray-50 dark:bg-gray-800 cursor-pointer", onClick: () => toggleSection('basic') }, /*#__PURE__*/_react.default.createElement(_lucideReact.ChevronRight, { className: "mr-2 text-gray-500 transition-transform ".concat(expandedSections.basic ? 'rotate-90' : ''), size: 16 }), /*#__PURE__*/_react.default.createElement("span", { className: "font-medium text-gray-700 dark:text-gray-200" }, "Basic Properties")), expandedSections.basic && /*#__PURE__*/_react.default.createElement("div", { className: "p-4" }, /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Name/Label:"), /*#__PURE__*/_react.default.createElement("input", { type: "text", value: selectedNode ? nodeLabel : edgeLabel, onChange: selectedNode ? handleNodeLabelChange : handleEdgeLabel, placeholder: selectedNode ? "Enter node name" : "Enter edge label", className: "w-full px-3 py-2 border-2 border-gray-200 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" })), /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Description:"), /*#__PURE__*/_react.default.createElement("textarea", { value: selectedNode ? nodeDescription : edgeDescription, onChange: selectedNode ? handleNodeDescriptionChange : handleEdgeDescriptionChange, placeholder: "Enter description", rows: 3, className: "w-full px-3 py-2 border-2 border-gray-200 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent resize-y" })), /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Layer (Z-Index):"), /*#__PURE__*/_react.default.createElement("div", { className: "flex flex-col" }, /*#__PURE__*/_react.default.createElement("input", { type: "number", value: selectedNode ? nodeZIndex : edgeZIndex, onChange: selectedNode ? handleNodeZIndexChange : handleEdgeZIndexChange, min: "0", max: "1000", className: "w-24 px-3 py-2 border-2 border-gray-200 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" }), /*#__PURE__*/_react.default.createElement("span", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400" }, "Higher numbers appear on top"))), selectedNode && /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Icon:"), /*#__PURE__*/_react.default.createElement("input", { type: "text", value: nodeIcon, onChange: handleNodeIconChange, placeholder: "Enter emoji or icon", className: "w-full px-3 py-2 border-2 border-gray-200 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" })), selectedEdge && /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Connection Type:"), /*#__PURE__*/_react.default.createElement("select", { value: edgeType, onChange: handleEdgeTypeChange, className: "w-full px-3 py-2 border-2 border-gray-200 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" }, /*#__PURE__*/_react.default.createElement("option", { value: "adjustable" }, "Adjustable"), /*#__PURE__*/_react.default.createElement("option", { value: "default" }, "Straight"), /*#__PURE__*/_react.default.createElement("option", { value: "step" }, "Step"), /*#__PURE__*/_react.default.createElement("option", { value: "smoothstep" }, "Smooth Step"), /*#__PURE__*/_react.default.createElement("option", { value: "straight" }, "Direct"))), selectedEdge && /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Arrowheads:"), /*#__PURE__*/_react.default.createElement("select", { value: edgeMarkerOption, onChange: handleEdgeMarkerChange, className: "w-full px-3 py-2 border-2 border-gray-200 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" }, /*#__PURE__*/_react.default.createElement("option", { value: "end" }, "Pointing to Target"), /*#__PURE__*/_react.default.createElement("option", { value: "start" }, "Pointing from Target"), /*#__PURE__*/_react.default.createElement("option", { value: "both" }, "Both Ends"), /*#__PURE__*/_react.default.createElement("option", { value: "none" }, "None"))), selectedEdge && /*#__PURE__*/_react.default.createElement(IntersectionStyleSelector, { value: edgeIntersection, onChange: handleEdgeIntersectionChange }))), /*#__PURE__*/_react.default.createElement("div", { className: "mb-4 border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden" }, /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center px-4 py-3 bg-gray-50 dark:bg-gray-800 cursor-pointer", onClick: () => toggleSection('style') }, /*#__PURE__*/_react.default.createElement(_lucideReact.ChevronRight, { className: "mr-2 text-gray-500 transition-transform ".concat(expandedSections.style ? 'rotate-90' : ''), size: 16 }), /*#__PURE__*/_react.default.createElement("span", { className: "font-medium text-gray-700 dark:text-gray-200" }, "Style Properties")), expandedSections.style && /*#__PURE__*/_react.default.createElement("div", { className: "p-4" }, selectedNode && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Background Color:"), /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center gap-2" }, /*#__PURE__*/_react.default.createElement("input", { type: "color", value: nodeColor, onChange: handleNodeColorChange, className: "w-12 h-10 p-0 border-2 border-gray-200 dark:border-gray-600 rounded cursor-pointer" }), /*#__PURE__*/_react.default.createElement("input", { type: "text", value: nodeColor, onChange: handleNodeColorChange, placeholder: "#ffffff", className: "flex-1 px-3 py-2 border-2 border-gray-200 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent font-mono" }))), /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Border Color:"), /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center gap-2" }, /*#__PURE__*/_react.default.createElement("input", { type: "color", value: nodeBorderColor, onChange: handleNodeBorderColorChange, className: "w-12 h-10 p-0 border-2 border-gray-200 dark:border-gray-600 rounded cursor-pointer" }), /*#__PURE__*/_react.default.createElement("input", { type: "text", value: nodeBorderColor, onChange: handleNodeBorderColorChange, placeholder: "#dddddd", className: "flex-1 px-3 py-2 border-2 border-gray-200 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent font-mono" }))), /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Text Color:"), /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center gap-2" }, /*#__PURE__*/_react.default.createElement("input", { type: "color", value: nodeTextColor, onChange: handleNodeTextColorChange, className: "w-12 h-10 p-0 border-2 border-gray-200 dark:border-gray-600 rounded cursor-pointer" }), /*#__PURE__*/_react.default.createElement("input", { type: "text", value: nodeTextColor, onChange: handleNodeTextColorChange, placeholder: "#000000", className: "flex-1 px-3 py-2 border-2 border-gray-200 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent font-mono" })))), selectedEdge && /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Line Color:"), /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center gap-2" }, /*#__PURE__*/_react.default.createElement("input", { type: "color", value: edgeStrokeColor, onChange: handleEdgeStrokeColorChange, className: "w-12 h-10 p-0 border-2 border-gray-200 dark:border-gray-600 rounded cursor-pointer" }), /*#__PURE__*/_react.default.createElement("input", { type: "text", value: edgeStrokeColor, onChange: handleEdgeStrokeColorChange, placeholder: "#999999", className: "flex-1 px-3 py-2 border-2 border-gray-200 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent font-mono" }))), /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Line Width:"), /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center gap-2" }, /*#__PURE__*/_react.default.createElement("input", { type: "range", min: "1", max: "10", value: edgeStrokeWidth, onChange: handleEdgeStrokeWidthChange, className: "flex-1 h-2 bg-gray-300 rounded-full appearance-none" }), /*#__PURE__*/_react.default.createElement("span", { className: "px-2 py-1 bg-gray-100 dark:bg-gray-700 text-sm font-medium text-gray-700 dark:text-gray-300 rounded" }, edgeStrokeWidth, "px"))), /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Line Style:"), /*#__PURE__*/_react.default.createElement("div", { className: "flex flex-wrap gap-2" }, /*#__PURE__*/_react.default.createElement("button", { onClick: () => applyEdgePreset('solid'), className: "px-3 py-1.5 text-sm border-2 rounded-md transition-all ".concat(!edgeStrokeDasharray ? 'bg-indigo-500 text-white border-indigo-600' : 'bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-200 border-gray-200 dark:border-gray-600 hover:border-indigo-500 hover:bg-indigo-50 dark:hover:bg-indigo-900/20') }, "Solid"), /*#__PURE__*/_react.default.createElement("button", { onClick: () => applyEdgePreset('dashed'), className: "px-3 py-1.5 text-sm border-2 rounded-md transition-all ".concat(edgeStrokeDasharray === '5,5' ? 'bg-indigo-500 text-white border-indigo-600' : 'bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-200 border-gray-200 dark:border-gray-600 hover:border-indigo-500 hover:bg-indigo-50 dark:hover:bg-indigo-900/20') }, "Dashed"), /*#__PURE__*/_react.default.createElement("button", { onClick: () => applyEdgePreset('dotted'), className: "px-3 py-1.5 text-sm border-2 rounded-md transition-all ".concat(edgeStrokeDasharray === '2,2' ? 'bg-indigo-500 text-white border-indigo-600' : 'bg-white dark:bg-gray-700 text-gray-700 dark:text-gray-200 border-gray-200 dark:border-gray-600 hover:border-indigo-500 hover:bg-indigo-50 dark:hover:bg-indigo-900/20') }, "Dotted"))), /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-sm font-medium text-gray-700 dark:text-gray-300" }, "Custom Dash Pattern:"), /*#__PURE__*/_react.default.createElement("input", { type: "text", value: edgeStrokeDasharray, onChange: handleEdgeStrokeDasharrayChange, placeholder: "e.g., 5,5 or 10,5,2,5", className: "w-full px-3 py-2 border-2 border-gray-200 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:border-transparent" }), /*#__PURE__*/_react.default.createElement("span", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400 italic" }, "Comma-separated values")), /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "flex items-center gap-2 cursor-pointer" }, /*#__PURE__*/_react.default.createElement("div", { className: "relative flex items-center" }, /*#__PURE__*/_react.default.createElement("input", { type: "checkbox", checked: edgeAnimated, onChange: handleEdgeAnimatedChange, className: "sr-only" }), /*#__PURE__*/_react.default.createElement("div", { className: "w-10 h-5 ".concat(edgeAnimated ? 'bg-indigo-500' : 'bg-gray-200 dark:bg-gray-700', " rounded-full transition-colors") }), /*#__PURE__*/_react.default.createElement("div", { className: "absolute left-0.5 top-0.5 bg-white w-4 h-4 rounded-full transition-transform ".concat(edgeAnimated ? 'transform translate-x-5' : '') })), /*#__PURE__*/_react.default.createElement("span", { className: "text-sm font-medium text-gray-700 dark:text-gray-300" }, "Animated")))))), selectedNode && /*#__PURE__*/_react.default.createElement("div", { className: "mb-4 border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden" }, /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center px-4 py-3 bg-gray-50 dark:bg-gray-800 cursor-pointer", onClick: () => toggleSection('advanced') }, /*#__PURE__*/_react.default.createElement(_lucideReact.ChevronRight, { className: "mr-2 text-gray-500 transition-transform ".concat(expandedSections.advanced ? 'rotate-90' : ''), size: 16 }), /*#__PURE__*/_react.default.createElement("span", { className: "font-medium text-gray-700 dark:text-gray-200" }, "Icon Library")), expandedSections.advanced && /*#__PURE__*/_react.default.createElement("div", { className: "p-4" }, Object.entries(emojiCategories).map(_ref4 => { let [category, emojis] = _ref4; return /*#__PURE__*/_react.default.createElement("div", { key: category, className: "mb-4" }, /*#__PURE__*/_react.default.createElement("div", { className: "text-xs font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-2" }, category), /*#__PURE__*/_react.default.createElement("div", { className: "grid grid-cols-8 gap-1" }, emojis.map((emoji, index) => /*#__PURE__*/_react.default.createElement("button", { key: index, className: "w-8 h-8 flex items-center justify-center text-lg border-2 rounded transition-all ".concat(nodeIcon === emoji ? 'bg-indigo-500 border-indigo-600 transform scale-110 shadow-md' : 'bg-white dark:bg-gray-700 border-gray-200 dark:border-gray-600 hover:border-indigo-500 hover:bg-indigo-50 dark:hover:bg-indigo-900/20 hover:scale-110'), onClick: () => handleEmojiClick(emoji), title: emoji }, emoji)))); }))))); }; var _default = exports.default = TailwindPropertyEditor;