UNPKG

@ichigo_san/graphing

Version:

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

277 lines (266 loc) 13.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = _interopRequireWildcard(require("react")); var _lucideReact = require("lucide-react"); var _shadowUtils = require("../utils/shadowUtils"); 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 shadow picker component for the Properties Editor // Provides professional shadow effects and visual controls const ShadowPicker = ({ value, onChange, label = "Shadow", disabled = false, showPresets = true }) => { const [isPresetsExpanded, setIsPresetsExpanded] = (0, _react.useState)(false); const [shadowDef, setShadowDef] = (0, _react.useState)(() => { // Initialize from value - could be CSS string or shadow object if (typeof value === 'string') { return (0, _shadowUtils.cssToShadow)(value); } return value || (0, _shadowUtils.createShadow)(_shadowUtils.SHADOW_TYPES.NONE); }); // Update shadow definition when value changes externally (0, _react.useEffect)(() => { if (typeof value === 'string') { setShadowDef((0, _shadowUtils.cssToShadow)(value)); } else if (value) { setShadowDef(value); } }, [value]); // Handle shadow changes const handleShadowChange = (0, _react.useCallback)(newShadowDef => { setShadowDef(newShadowDef); const cssValue = (0, _shadowUtils.shadowToCss)(newShadowDef); onChange(cssValue); }, [onChange]); // Handle type change const handleTypeChange = (0, _react.useCallback)(newType => { if (newType === _shadowUtils.SHADOW_TYPES.NONE) { handleShadowChange((0, _shadowUtils.createShadow)(_shadowUtils.SHADOW_TYPES.NONE)); } else { // Start with a basic shadow for non-none types const basicShadow = (0, _shadowUtils.createCustomShadow)({ offsetY: 4, blur: 8 }); handleShadowChange({ ...basicShadow, type: newType }); } }, [handleShadowChange]); // Update shadow parameter const updateShadowParam = (0, _react.useCallback)((index, param, value) => { const shadows = [...shadowDef.shadows]; if (shadows[index]) { shadows[index] = { ...shadows[index], [param]: value }; handleShadowChange({ ...shadowDef, shadows }); } }, [shadowDef, handleShadowChange]); // Add shadow layer const addShadowLayer = (0, _react.useCallback)(() => { const shadows = [...shadowDef.shadows]; shadows.push({ x: 0, y: 4, blur: 8, spread: 0, color: 'rgba(0, 0, 0, 0.15)' }); handleShadowChange({ ...shadowDef, shadows }); }, [shadowDef, handleShadowChange]); // Remove shadow layer const removeShadowLayer = (0, _react.useCallback)(index => { if (shadowDef.shadows.length <= 1) { handleShadowChange((0, _shadowUtils.createShadow)(_shadowUtils.SHADOW_TYPES.NONE)); return; } const shadows = shadowDef.shadows.filter((_, i) => i !== index); handleShadowChange({ ...shadowDef, shadows }); }, [shadowDef, handleShadowChange]); // Apply preset const applyPreset = (0, _react.useCallback)(presetShadow => { handleShadowChange(presetShadow); }, [handleShadowChange]); // Render shadow layer editor const renderShadowLayer = (shadow, index) => { var _shadow$color; return /*#__PURE__*/_react.default.createElement("div", { key: index, className: "p-3 bg-gray-50 dark:bg-gray-700 rounded border mb-2" }, /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center justify-between mb-2" }, /*#__PURE__*/_react.default.createElement("span", { className: "text-xs font-medium text-gray-600 dark:text-gray-400" }, "Shadow Layer ", index + 1), shadowDef.shadows.length > 1 && /*#__PURE__*/_react.default.createElement("button", { onClick: () => removeShadowLayer(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 }))), /*#__PURE__*/_react.default.createElement("div", { className: "grid grid-cols-2 gap-2 mb-2" }, /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("label", { className: "block text-xs text-gray-600 dark:text-gray-400 mb-1" }, "X:"), /*#__PURE__*/_react.default.createElement("input", { type: "number", value: shadow.x || 0, onChange: e => updateShadowParam(index, 'x', parseInt(e.target.value) || 0), className: "w-full px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded", disabled: disabled })), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("label", { className: "block text-xs text-gray-600 dark:text-gray-400 mb-1" }, "Y:"), /*#__PURE__*/_react.default.createElement("input", { type: "number", value: shadow.y || 0, onChange: e => updateShadowParam(index, 'y', parseInt(e.target.value) || 0), className: "w-full px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded", disabled: disabled })), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("label", { className: "block text-xs text-gray-600 dark:text-gray-400 mb-1" }, "Blur:"), /*#__PURE__*/_react.default.createElement("input", { type: "number", value: shadow.blur || 0, min: "0", onChange: e => updateShadowParam(index, 'blur', Math.max(0, parseInt(e.target.value) || 0)), className: "w-full px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded", disabled: disabled })), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("label", { className: "block text-xs text-gray-600 dark:text-gray-400 mb-1" }, "Spread:"), /*#__PURE__*/_react.default.createElement("input", { type: "number", value: shadow.spread || 0, onChange: e => updateShadowParam(index, 'spread', parseInt(e.target.value) || 0), className: "w-full px-2 py-1 text-sm border border-gray-300 dark:border-gray-600 rounded", disabled: disabled }))), /*#__PURE__*/_react.default.createElement("div", { className: "mb-2" }, /*#__PURE__*/_react.default.createElement("label", { className: "block text-xs text-gray-600 dark:text-gray-400 mb-1" }, "Color:"), /*#__PURE__*/_react.default.createElement("div", { className: "flex items-center gap-2" }, /*#__PURE__*/_react.default.createElement("input", { type: "color", value: (_shadow$color = shadow.color) !== null && _shadow$color !== void 0 && _shadow$color.includes('rgba') ? '#000000' : shadow.color || '#000000', onChange: e => updateShadowParam(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: shadow.color || 'rgba(0, 0, 0, 0.15)', onChange: e => updateShadowParam(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", placeholder: "rgba(0, 0, 0, 0.15)", disabled: disabled }))), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("label", { className: "flex items-center gap-2 cursor-pointer" }, /*#__PURE__*/_react.default.createElement("input", { type: "checkbox", checked: shadow.inset || false, onChange: e => updateShadowParam(index, 'inset', e.target.checked), className: "rounded", disabled: disabled }), /*#__PURE__*/_react.default.createElement("span", { className: "text-xs text-gray-600 dark:text-gray-400" }, "Inner shadow")))); }; // Get current CSS value for preview const previewStyle = { background: '#ffffff', width: '60px', height: '40px', borderRadius: '4px', border: '1px solid #e5e7eb', boxShadow: (0, _shadowUtils.ensureShadowCompatibility)(shadowDef), margin: '10px auto' }; const presets = (0, _shadowUtils.getShadowPresets)(); 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 p-3 bg-gray-100 dark:bg-gray-800 rounded" }, /*#__PURE__*/_react.default.createElement("div", { style: previewStyle }), /*#__PURE__*/_react.default.createElement("div", { className: "text-center text-xs text-gray-500 dark:text-gray-400 mt-1" }, "Preview")), /*#__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: shadowDef.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: _shadowUtils.SHADOW_TYPES.NONE }, "No Shadow"), /*#__PURE__*/_react.default.createElement("option", { value: _shadowUtils.SHADOW_TYPES.BOX_SHADOW }, "Box Shadow"), /*#__PURE__*/_react.default.createElement("option", { value: _shadowUtils.SHADOW_TYPES.DROP_SHADOW }, "Drop Shadow"), /*#__PURE__*/_react.default.createElement("option", { value: _shadowUtils.SHADOW_TYPES.GLOW }, "Glow Effect"), /*#__PURE__*/_react.default.createElement("option", { value: _shadowUtils.SHADOW_TYPES.MULTI_LAYER }, "Multi-layer"))), shadowDef.type !== _shadowUtils.SHADOW_TYPES.NONE && /*#__PURE__*/_react.default.createElement("div", null, /*#__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" }, "Shadow Layers:"), /*#__PURE__*/_react.default.createElement("button", { onClick: addShadowLayer, 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 Layer")), shadowDef.shadows.map((shadow, index) => renderShadowLayer(shadow, index)))), showPresets && /*#__PURE__*/_react.default.createElement("div", { className: "mb-3" }, /*#__PURE__*/_react.default.createElement("button", { onClick: () => setIsPresetsExpanded(!isPresetsExpanded), 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 ${isPresetsExpanded ? 'rotate-90' : ''}`, size: 12 }), "Shadow Presets"), isPresetsExpanded && /*#__PURE__*/_react.default.createElement("div", { className: "mt-2" }, Object.entries(presets).map(([categoryName, categoryPresets]) => /*#__PURE__*/_react.default.createElement("div", { key: categoryName, className: "mb-3" }, /*#__PURE__*/_react.default.createElement("div", { className: "text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider mb-2" }, categoryName), /*#__PURE__*/_react.default.createElement("div", { className: "grid grid-cols-2 gap-2" }, Object.entries(categoryPresets).map(([name, preset]) => /*#__PURE__*/_react.default.createElement("button", { key: name, onClick: () => applyPreset(preset), className: "relative p-3 bg-white dark:bg-gray-700 border border-gray-200 dark:border-gray-600 rounded hover:border-indigo-500 transition-colors", style: { boxShadow: (0, _shadowUtils.shadowToCss)(preset) }, disabled: disabled, title: name.replace(/([A-Z])/g, ' $1').replace(/^./, str => str.toUpperCase()) }, /*#__PURE__*/_react.default.createElement("div", { className: "text-xs font-medium text-gray-700 dark:text-gray-300 capitalize" }, name.replace(/([A-Z])/g, ' $1')))))))))); }; var _default = exports.default = ShadowPicker;