Skip to content

Commit

Permalink
nodelayout port ok,
Browse files Browse the repository at this point in the history
todo:
* resize
* edge
* new type: subgraph
  • Loading branch information
HomunMage committed Jan 12, 2025
1 parent 6014aa7 commit f1eeaff
Show file tree
Hide file tree
Showing 3 changed files with 155 additions and 34 deletions.
181 changes: 151 additions & 30 deletions CustomNode.tsx
Original file line number Diff line number Diff line change
@@ -1,52 +1,173 @@
// Graph/CustomNode.tsx

import React, { useCallback } from 'react';
import { Handle, Position } from '@xyflow/react';
import { Handle, Position, NodeResizeControl, OnResize } from '@xyflow/react';
import ResizeIcon from './ResizeIcon';

interface CustomNodeProps {
id: string;
data: {
label: string;
value: string | number;
};
isConnectable?: boolean;
onNodeDataChange?: (id: string, newData: any) => void;
id: string;
data: {
type: string;
name?: string;
tool?: string;
description?: string;
info?: string;
width?: number;
height?: number;
};
isConnectable?: boolean;
onNodeDataChange?: (id: string, newData: any) => void;
onResize?: (id: string, width: number, height: number) => void;
}


const handleStyle = { left: 10 };
const handleStyle = {
width: 6,
height: 6,
borderRadius: '50%',
background: '#555',
};


const CustomNode: React.FC<CustomNodeProps> = ({ id, data, isConnectable = true, onNodeDataChange }) => {
const CustomNode: React.FC<CustomNodeProps> = ({ id, data, isConnectable = true, onNodeDataChange, onResize }) => {

const onChange = useCallback((evt: React.ChangeEvent<HTMLInputElement>) => {
const newValue = evt.target.value;
onNodeDataChange?.(id, { ...data, value: newValue });
const handleChange = useCallback((evt: React.ChangeEvent<HTMLInputElement | HTMLSelectElement | HTMLTextAreaElement>) => {
const { name, value } = evt.target;
onNodeDataChange?.(id, { ...data, [name]: value });
}, [id, data, onNodeDataChange]);

const handleResize = useCallback<OnResize>(
(_, { width, height }) => {
onResize?.(id, width, height);
},
[id, onResize]
);

return (
<div className="custom-node">
<Handle type="target" position={Position.Top} isConnectable={isConnectable} />

<div>
<label htmlFor="text">Label:</label>
<input
id="text"
className="nodrag"
value={data.value}
onChange={onChange}
/>
</div>
<Handle type="source" position={Position.Bottom} id="a" style={handleStyle} isConnectable={isConnectable} />
<div
className="border border-gray-500 p-2 rounded-xl bg-white overflow-visible relative flex flex-col text-black" // Added text-black here
style={{ width: data.width || 200, height: data.height || 200 }}
>
<NodeResizeControl
className="absolute right-1 bottom-1"
minWidth={200}
minHeight={200}
onResize={handleResize}
>
<ResizeIcon />
</NodeResizeControl>
<Handle
type="target"
position={Position.Left}
isConnectable={isConnectable}
className="absolute left-[-5px] top-1/2 -translate-y-1/2"
style={handleStyle}
/>
<Handle
type="source"
position={Position.Right}
id="a"
isConnectable={isConnectable}
className="absolute right-[-5px] top-1/2 -translate-y-1/2"
style={handleStyle}
/>
<Handle
type="source"
position={Position.Top}
id="true"
isConnectable={isConnectable}
className="absolute top-[-5px] left-1/2 -translate-x-1/2 bg-green-500"
style={handleStyle}
/>
<Handle
type="source"
position={Position.Bottom}
id="b"
id="false"
isConnectable={isConnectable}
className="absolute bottom-[-5px] left-1/2 -translate-x-1/2 bg-red-500"
style={handleStyle}
/>

<div className="flex flex-col h-full flex-grow">
<div>
<label htmlFor="type" className="block text-xs">
Type:
</label>
<select
id="type"
name="type"
defaultValue={data.type}
onChange={handleChange}
className="nodrag w-full bg-white border border-gray-300 rounded focus:outline-none"
>
<option value="START">START</option>
<option value="STEP">STEP</option>
<option value="TOOL">TOOL</option>
<option value="CONDITION">CONDITION</option>
<option value="INFO">INFO</option>
</select>
</div>
{data.type !== 'START' && (
<>
{['STEP', 'CONDITION', 'INFO'].includes(data.type) && (
<div>
<label htmlFor="name" className="block text-xs">
Name:
</label>
<input
id="name"
name="name"
defaultValue={data.name}
onChange={handleChange}
className="nodrag w-full bg-white border border-gray-300 rounded focus:outline-none"
/>
</div>
)}
{data.type === 'STEP' && (
<div>
<label htmlFor="tool" className="block text-xs">
Tool:
</label>
<input
id="tool"
name="tool"
defaultValue={data.tool}
onChange={handleChange}
className="nodrag w-full bg-white border border-gray-300 rounded focus:outline-none"
/>
</div>
)}
{['STEP', 'TOOL', 'CONDITION', 'INFO'].includes(data.type) && (
<div className="flex-grow">
<label htmlFor="description" className="block text-xs">
Description:
</label>
<textarea
id="description"
name="description"
defaultValue={data.description}
onChange={handleChange}
className="nodrag w-full h-full resize-none bg-white border border-gray-300 rounded focus:outline-none"
/>
</div>
)}
{data.type === 'INFO' && (
<div>
<label htmlFor="info" className="block text-xs">
Question:
</label>
<input
id="info"
name="info"
defaultValue={data.info}
onChange={handleChange}
className="nodrag w-full h-8 bg-white border border-gray-300 rounded focus:outline-none"
/>
</div>
)}
</>
)}
</div>
</div>
);
};

export default CustomNode;
export default React.memo(CustomNode);
2 changes: 1 addition & 1 deletion GraphApp.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ const GraphApp: React.FC = () => {
const handleAddNode = useCallback(() => {
if (contextMenu && contextMenu.type === 'panel') {
const newPosition = screenToFlowPosition({ x: contextMenu.mouseX, y: contextMenu.mouseY });
const newNodeId = String(currentGraph.serial_number + 1);
const newNodeId = String(currentGraph.serial_number + 1);
const newNode = {
id: newNodeId,
type: 'custom',
Expand Down
6 changes: 3 additions & 3 deletions svgResize.tsx → ResizeIcon.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// svgResize.tsx
// ResizeIcon.tsx

function svgResize(): JSX.Element {
function ResizeIcon(): JSX.Element {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand All @@ -23,4 +23,4 @@ function svgResize(): JSX.Element {
);
}

export default svgResize;
export default ResizeIcon;

0 comments on commit f1eeaff

Please sign in to comment.