diff --git a/client/src/components/UMLClassNode.tsx b/client/src/components/UMLClassNode.tsx index 44315a6..909dc1a 100644 --- a/client/src/components/UMLClassNode.tsx +++ b/client/src/components/UMLClassNode.tsx @@ -1,7 +1,8 @@ import React, { useState, useEffect, useRef } from 'react'; import { Handle, Position, NodeProps } from '@xyflow/react'; +import { memo } from 'react'; +import { NodeResizer, NodeResizeControl } from '@xyflow/react'; -// Define types for the node data and props interface UMLNodeData { label?: string; attributes?: string[]; @@ -14,7 +15,7 @@ interface UMLNodeData { interface UMLNodeProps extends NodeProps {} -const UMLClassNode: React.FC = ({ data, id }) => { +const UMLClassNode = ({ data, id }) => { const [label, setLabel] = useState(data.label || 'ClassName'); const [attributes, setAttributes] = useState(data.attributes?.join('\n') || ''); const [methods, setMethods] = useState(data.methods?.join('\n') || ''); @@ -24,53 +25,26 @@ const UMLClassNode: React.FC = ({ data, id }) => { const methodsRef = useRef(null); const labelRef = useRef(null); - const [nodeWidth, setNodeWidth] = useState(200); // Initial minimum width + const [nodeWidth, setNodeWidth] = useState(200); // Initial width - // Function to measure the width of text using canvas - const measureTextWidth = (text: string, font: string): number => { - const canvas = document.createElement('canvas'); - const context = canvas.getContext('2d'); - if (!context) return 0; - context.font = font; - const metrics = context.measureText(text); - return metrics.width; - }; useEffect(() => { - // Adjust the height of text areas - if (attributesRef.current) { - attributesRef.current.style.height = 'auto'; - attributesRef.current.style.height = `${attributesRef.current.scrollHeight}px`; - } - if (methodsRef.current) { - methodsRef.current.style.height = 'auto'; - methodsRef.current.style.height = `${methodsRef.current.scrollHeight}px`; - } - - // Initialize maxWidth with the minimum width + // Dynamically adjust the width based on content let maxWidth = 150; - - // Define font settings - const fontSize = 14; // Adjust font size if needed + const fontSize = 14; const fontFamily = 'Arial, sans-serif'; const font = `${fontSize}px ${fontFamily}`; - - // Measure width of the label let labelWidth = 0; if (labelRef.current) { const labelText = labelRef.current.value; labelWidth = measureTextWidth(labelText, font); } - - // Measure the maximum width required by attributes let attributesMaxWidth = 0; const attributesLines = attributes.split('\n'); attributesLines.forEach(line => { const lineWidth = measureTextWidth(line, font); attributesMaxWidth = Math.max(attributesMaxWidth, lineWidth); }); - - // Measure the maximum width required by methods let methodsMaxWidth = 0; const methodsLines = methods.split('\n'); methodsLines.forEach(line => { @@ -78,15 +52,20 @@ const UMLClassNode: React.FC = ({ data, id }) => { methodsMaxWidth = Math.max(methodsMaxWidth, lineWidth); }); - // Determine the maximum width required maxWidth = Math.max(maxWidth, labelWidth, attributesMaxWidth, methodsMaxWidth); - - // Add padding to the calculated width - const padding = 30; // Adjust padding as needed + const padding = 30; setNodeWidth(maxWidth + padding); }, [label, attributes, methods]); - // Handlers for input changes + const measureTextWidth = (text: string, font: string): number => { + const canvas = document.createElement('canvas'); + const context = canvas.getContext('2d'); + if (!context) return 0; + context.font = font; + const metrics = context.measureText(text); + return metrics.width; + }; + const handleLabelChange = (e) => { const newLabel = e.target.value; setLabel(newLabel); @@ -105,147 +84,179 @@ const UMLClassNode: React.FC = ({ data, id }) => { data.updateNodeData?.(id, { methods: newMethods.split('\n') }); }; + const controlStyle = { + background: 'transparent', + border: 'none', + }; + + return ( -
+ <> +
- - -
-
-