@ichigo_san/graphing
Version:
A lightweight UML-style diagram editor built with React Flow and Tailwind CSS
682 lines (670 loc) โข 37.5 kB
JavaScript
"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;