UNPKG

@ichigo_san/graphing

Version:

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

263 lines (250 loc) 12.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _lucideReact = require("lucide-react"); var _gradientUtils = require("../utils/gradientUtils"); 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); } // Advanced gradient picker component for the Properties Editor // Provides both simple and advanced gradient controls const GradientPicker = ({ value, onChange, label = "Background", disabled = false, showPresets = true, allowPatterns = false }) => { var _gradientDef$colors$, _gradientDef$colors$2; const [isAdvancedMode, setIsAdvancedMode] = (0, _react.useState)(false); const [gradientDef, setGradientDef] = (0, _react.useState)(() => { // Initialize from value - could be color string or gradient object if (typeof value === 'string') { return (0, _gradientUtils.cssToGradient)(value); } return value || (0, _gradientUtils.createGradient)(_gradientUtils.GRADIENT_TYPES.SOLID, [{ color: '#ffffff', position: 0 }]); }); // Update gradient definition when value changes externally (0, _react.useEffect)(() => { if (typeof value === 'string') { setGradientDef((0, _gradientUtils.cssToGradient)(value)); } else if (value) { setGradientDef(value); } }, [value]); // Handle gradient changes const handleGradientChange = (0, _react.useCallback)(newGradientDef => { setGradientDef(newGradientDef); const cssValue = (0, _gradientUtils.gradientToCss)(newGradientDef); onChange(cssValue); }, [onChange]); // Handle type change const handleTypeChange = (0, _react.useCallback)(newType => { const newGradient = { ...gradientDef, type: newType }; // Ensure we have at least 2 colors for gradients if (newType !== _gradientUtils.GRADIENT_TYPES.SOLID && newGradient.colors.length < 2) { var _newGradient$colors$; newGradient.colors = [{ color: ((_newGradient$colors$ = newGradient.colors[0]) === null || _newGradient$colors$ === void 0 ? void 0 : _newGradient$colors$.color) || '#3b82f6', position: 0 }, { color: '#6366f1', position: 100 }]; } handleGradientChange(newGradient); }, [gradientDef, handleGradientChange]); // Handle direction change const handleDirectionChange = (0, _react.useCallback)(newDirection => { handleGradientChange({ ...gradientDef, direction: newDirection }); }, [gradientDef, handleGradientChange]); // Add color stop const addColorStop = (0, _react.useCallback)(() => { const colors = [...gradientDef.colors]; const newPosition = colors.length > 0 ? Math.min(100, Math.max(...colors.map(c => c.position)) + 25) : 50; colors.push({ color: '#6366f1', position: newPosition }); handleGradientChange({ ...gradientDef, colors }); }, [gradientDef, handleGradientChange]); // Remove color stop const removeColorStop = (0, _react.useCallback)(index => { if (gradientDef.colors.length <= 1) return; // Keep at least one color const colors = gradientDef.colors.filter((_, i) => i !== index); handleGradientChange({ ...gradientDef, colors }); }, [gradientDef, handleGradientChange]); // Update color stop const updateColorStop = (0, _react.useCallback)((index, updates) => { const colors = [...gradientDef.colors]; colors[index] = { ...colors[index], ...updates }; handleGradientChange({ ...gradientDef, colors }); }, [gradientDef, handleGradientChange]); // Apply preset const applyPreset = (0, _react.useCallback)(presetGradient => { handleGradientChange(presetGradient); }, [handleGradientChange]); // Render color stop editor const renderColorStop = (colorStop, index) => /*#__PURE__*/_react.default.createElement("div", { key: index, className: "flex items-center gap-2 mb-2 p-2 bg-gray-50 dark:bg-gray-700 rounded" }, /*#__PURE__*/_react.default.createElement("input", { type: "color", value: colorStop.color, onChange: e => updateColorStop(index, { color: e.target.value }), className: "w-8 h-8 p-0 border border-gray-300 dark:border-gray-600 rounded cursor-pointer", disabled: disabled }), /*#__PURE__*/_react.default.createElement("input", { type: "text", value: colorStop.color, onChange: e => updateColorStop(index, { color: e.target.value }), className: "flex-1 px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded font-mono", disabled: disabled }), /*#__PURE__*/_react.default.createElement("input", { type: "number", value: colorStop.position, onChange: e => updateColorStop(index, { position: Math.max(0, Math.min(100, parseFloat(e.target.value) || 0)) }), min: "0", max: "100", className: "w-16 px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded", disabled: disabled }), /*#__PURE__*/_react.default.createElement("span", { className: "text-xs text-gray-500" }, "%"), gradientDef.colors.length > 1 && /*#__PURE__*/_react.default.createElement("button", { onClick: () => removeColorStop(index), className: "p-1 text-red-500 hover:bg-red-100 dark:hover:bg-red-900/20 rounded", disabled: disabled }, /*#__PURE__*/_react.default.createElement(_lucideReact.X, { size: 12 }))); // Get current CSS value for preview const previewStyle = { background: (0, _gradientUtils.ensureBackwardCompatibility)(gradientDef), width: '100%', height: '40px', borderRadius: '4px', border: '1px solid #e5e7eb' }; const presets = (0, _gradientUtils.getGradientPresets)(); return /*#__PURE__*/_react.default.createElement("div", { className: "mb-4" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-2 text-sm font-medium text-gray-700 dark:text-gray-300" }, label, ":"), /*#__PURE__*/_react.default.createElement("div", { className: "mb-3" }, /*#__PURE__*/_react.default.createElement("div", { style: previewStyle })), /*#__PURE__*/_react.default.createElement("div", { className: "mb-3" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-xs font-medium text-gray-600 dark:text-gray-400" }, "Type:"), /*#__PURE__*/_react.default.createElement("select", { value: gradientDef.type, onChange: e => handleTypeChange(e.target.value), className: "w-full px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500", disabled: disabled }, /*#__PURE__*/_react.default.createElement("option", { value: _gradientUtils.GRADIENT_TYPES.SOLID }, "Solid Color"), /*#__PURE__*/_react.default.createElement("option", { value: _gradientUtils.GRADIENT_TYPES.LINEAR }, "Linear Gradient"), /*#__PURE__*/_react.default.createElement("option", { value: _gradientUtils.GRADIENT_TYPES.RADIAL }, "Radial Gradient"), /*#__PURE__*/_react.default.createElement("option", { value: _gradientUtils.GRADIENT_TYPES.CONIC }, "Conic Gradient"))), gradientDef.type === _gradientUtils.GRADIENT_TYPES.SOLID && /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center gap-2" }, /*#__PURE__*/_react.default.createElement("input", { type: "color", value: ((_gradientDef$colors$ = gradientDef.colors[0]) === null || _gradientDef$colors$ === void 0 ? void 0 : _gradientDef$colors$.color) || '#ffffff', onChange: e => updateColorStop(0, { color: e.target.value }), className: "w-12 h-10 p-0 border border-gray-300 dark:border-gray-600 rounded cursor-pointer", disabled: disabled }), /*#__PURE__*/_react.default.createElement("input", { type: "text", value: ((_gradientDef$colors$2 = gradientDef.colors[0]) === null || _gradientDef$colors$2 === void 0 ? void 0 : _gradientDef$colors$2.color) || '#ffffff', onChange: e => updateColorStop(0, { color: e.target.value }), className: "flex-1 px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500 font-mono", disabled: disabled })), gradientDef.type !== _gradientUtils.GRADIENT_TYPES.SOLID && /*#__PURE__*/_react.default.createElement("div", null, gradientDef.type === _gradientUtils.GRADIENT_TYPES.LINEAR && /*#__PURE__*/_react.default.createElement("div", { className: "mb-3" }, /*#__PURE__*/_react.default.createElement("label", { className: "block mb-1 text-xs font-medium text-gray-600 dark:text-gray-400" }, "Direction:"), /*#__PURE__*/_react.default.createElement("select", { value: gradientDef.direction, onChange: e => handleDirectionChange(e.target.value), className: "w-full px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500", disabled: disabled }, Object.entries(_gradientUtils.GRADIENT_DIRECTIONS).map(([key, value]) => /*#__PURE__*/_react.default.createElement("option", { key: key, value: value }, value.replace('to ', '').replace(/\b\w/g, l => l.toUpperCase()))))), /*#__PURE__*/_react.default.createElement("div", { className: "mb-3" }, /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /*#__PURE__*/_react.default.createElement("label", { className: "text-xs font-medium text-gray-600 dark:text-gray-400" }, "Colors:"), /*#__PURE__*/_react.default.createElement("button", { onClick: addColorStop, className: "flex items-center gap-1 px-2 py-1 text-xs bg-indigo-500 text-white rounded hover:bg-indigo-600", disabled: disabled }, /*#__PURE__*/_react.default.createElement(_lucideReact.Plus, { size: 12 }), "Add")), gradientDef.colors.map((colorStop, index) => renderColorStop(colorStop, index)))), showPresets && /*#__PURE__*/_react.default.createElement("div", { className: "mb-3" }, /*#__PURE__*/_react.default.createElement("button", { onClick: () => setIsAdvancedMode(!isAdvancedMode), className: "flex items-center gap-1 text-xs text-gray-600 dark:text-gray-400 hover:text-gray-800 dark:hover:text-gray-200" }, /*#__PURE__*/_react.default.createElement(_lucideReact.ChevronRight, { className: `transition-transform ${isAdvancedMode ? 'rotate-90' : ''}`, size: 12 }), "Presets"), isAdvancedMode && /*#__PURE__*/_react.default.createElement("div", { className: "mt-2 grid grid-cols-3 gap-2" }, Object.entries(presets).map(([name, preset]) => /*#__PURE__*/_react.default.createElement("button", { key: name, onClick: () => applyPreset(preset), className: "relative h-8 rounded border border-gray-300 dark:border-gray-600 hover:border-indigo-500 overflow-hidden group", style: { background: (0, _gradientUtils.gradientToCss)(preset) }, disabled: disabled, title: name.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()) }, /*#__PURE__*/_react.default.createElement("div", { className: "absolute inset-0 bg-black bg-opacity-0 group-hover:bg-opacity-10 flex items-center justify-center" }, /*#__PURE__*/_react.default.createElement("span", { className: "text-xs text-white opacity-0 group-hover:opacity-100 drop-shadow" }, name.charAt(0).toUpperCase()))))))); }; var _default = exports.default = GradientPicker;