1
This commit is contained in:
parent
40d0ba918f
commit
a59bd47cd0
@ -13,12 +13,12 @@ export const EndEventNodeDefinition: BaseNodeDefinition = {
|
|||||||
|
|
||||||
// 渲染配置(配置驱动)
|
// 渲染配置(配置驱动)
|
||||||
renderConfig: {
|
renderConfig: {
|
||||||
shape: 'rounded-rect',
|
shape: 'ellipse',
|
||||||
size: { width: 80, height: 48 },
|
size: { width: 120, height: 50 },
|
||||||
icon: {
|
icon: {
|
||||||
type: 'emoji',
|
type: 'emoji',
|
||||||
content: '⏹️',
|
content: '⏹️',
|
||||||
size: 32
|
size: 24
|
||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
primary: '#ef4444',
|
primary: '#ef4444',
|
||||||
|
|||||||
@ -13,12 +13,12 @@ export const StartEventNodeDefinition: BaseNodeDefinition = {
|
|||||||
|
|
||||||
// 渲染配置(配置驱动)
|
// 渲染配置(配置驱动)
|
||||||
renderConfig: {
|
renderConfig: {
|
||||||
shape: 'rounded-rect',
|
shape: 'ellipse',
|
||||||
size: { width: 80, height: 48 },
|
size: { width: 120, height: 50 },
|
||||||
icon: {
|
icon: {
|
||||||
type: 'emoji',
|
type: 'emoji',
|
||||||
content: '▶️',
|
content: '▶️',
|
||||||
size: 32
|
size: 24
|
||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
primary: '#10b981',
|
primary: '#10b981',
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Handle, Position, NodeProps } from '@xyflow/react';
|
import { Handle, Position, NodeProps } from '@xyflow/react';
|
||||||
import type { FlowNodeData } from '../../types';
|
import type { FlowNodeData } from '../../types';
|
||||||
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BaseNode - shadcn/ui 风格节点
|
* BaseNode - shadcn/ui 风格节点
|
||||||
@ -16,32 +17,29 @@ const BaseNode: React.FC<NodeProps> = ({ data, selected }) => {
|
|||||||
|
|
||||||
const config = definition.renderConfig;
|
const config = definition.renderConfig;
|
||||||
|
|
||||||
// 获取输出字段简要信息
|
// 渲染输出字段标签
|
||||||
const getOutputsSummary = () => {
|
const renderOutputSection = () => {
|
||||||
if (!nodeData.outputs || nodeData.outputs.length === 0) {
|
if (!nodeData.outputs || nodeData.outputs.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return nodeData.outputs.map(output => output.name).join(', ');
|
return (
|
||||||
};
|
<div className="space-y-2">
|
||||||
|
{/* 输出标签 - 靠左 */}
|
||||||
// shadcn 风格容器类名
|
<div className="text-xs text-muted-foreground font-medium">输出</div>
|
||||||
const getContainerClass = () => {
|
{/* 输出字段标签 */}
|
||||||
// 基础样式 - shadcn card 风格
|
<div className="flex flex-wrap gap-1.5">
|
||||||
// 使用 items-start 让图标和文本顶部对齐
|
{nodeData.outputs.map((output, index) => (
|
||||||
const baseClass = `
|
<code
|
||||||
relative inline-flex items-start gap-2 px-3 py-2
|
key={index}
|
||||||
bg-background border border-border
|
className="text-xs px-2 py-1 bg-secondary text-secondary-foreground rounded-md font-mono inline-flex items-center"
|
||||||
rounded-lg shadow-sm
|
title={output.title || output.description}
|
||||||
transition-all duration-200
|
>
|
||||||
hover:shadow-md hover:border-primary/50
|
{output.name}
|
||||||
`;
|
</code>
|
||||||
|
))}
|
||||||
// 选中状态 - shadcn 的 ring 效果
|
</div>
|
||||||
const selectedClass = selected
|
</div>
|
||||||
? 'border-primary shadow-md ring-2 ring-ring ring-offset-2 ring-offset-background'
|
);
|
||||||
: '';
|
|
||||||
|
|
||||||
return `${baseClass} ${selectedClass}`;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// 图标容器 - shadcn 风格
|
// 图标容器 - shadcn 风格
|
||||||
@ -51,20 +49,20 @@ const BaseNode: React.FC<NodeProps> = ({ data, selected }) => {
|
|||||||
<div
|
<div
|
||||||
className="
|
className="
|
||||||
flex items-center justify-center
|
flex items-center justify-center
|
||||||
rounded-md
|
rounded-lg
|
||||||
transition-transform duration-200
|
transition-all duration-200
|
||||||
group-hover:scale-110
|
group-hover:scale-105
|
||||||
flex-shrink-0
|
flex-shrink-0
|
||||||
mt-0.5
|
shadow-sm
|
||||||
"
|
"
|
||||||
style={{
|
style={{
|
||||||
width: '32px',
|
width: '36px',
|
||||||
height: '32px',
|
height: '36px',
|
||||||
background: `linear-gradient(135deg, ${config.theme.primary}, ${config.theme.secondary})`,
|
background: `linear-gradient(135deg, ${config.theme.primary}, ${config.theme.secondary})`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className="text-white text-base leading-none"
|
className="text-white text-lg leading-none"
|
||||||
>
|
>
|
||||||
{config.icon.content}
|
{config.icon.content}
|
||||||
</span>
|
</span>
|
||||||
@ -76,9 +74,9 @@ const BaseNode: React.FC<NodeProps> = ({ data, selected }) => {
|
|||||||
|
|
||||||
// shadcn 风格连接点
|
// shadcn 风格连接点
|
||||||
const handleClass = `
|
const handleClass = `
|
||||||
!w-2.5 !h-2.5 !rounded-full !border-2 !border-background
|
!w-3 !h-3 !rounded-full !border-2 !border-background
|
||||||
transition-all duration-200
|
transition-all duration-200
|
||||||
hover:!w-3 hover:!h-3
|
hover:!w-3.5 hover:!h-3.5 hover:!shadow-md
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const getHandleStyle = () => ({
|
const getHandleStyle = () => ({
|
||||||
@ -107,50 +105,73 @@ const BaseNode: React.FC<NodeProps> = ({ data, selected }) => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 椭圆形节点(开始/结束)使用特殊布局
|
||||||
|
const isEllipse = config.shape === 'ellipse';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="group">
|
<div className="group relative">
|
||||||
<div className={getContainerClass()}>
|
{/* 输入连接点 */}
|
||||||
{/* 输入连接点 */}
|
{config.handles.input && (
|
||||||
{config.handles.input && (
|
<Handle
|
||||||
<Handle
|
type="target"
|
||||||
type="target"
|
position={Position.Left}
|
||||||
position={Position.Left}
|
className={handleClass}
|
||||||
className={handleClass}
|
style={getHandleStyle()}
|
||||||
style={getHandleStyle()}
|
/>
|
||||||
/>
|
)}
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 图标 */}
|
{/* 使用 shadcn Card 组件 */}
|
||||||
{renderIcon()}
|
<Card
|
||||||
|
className={`
|
||||||
{/* 标签和输出信息 - 垂直布局 */}
|
${isEllipse ? 'rounded-full px-6 py-3' : 'min-w-[240px] max-w-[420px]'}
|
||||||
<div className="flex flex-col gap-0.5 min-w-0">
|
${selected ? 'ring-2 ring-primary ring-offset-2 ring-offset-background' : ''}
|
||||||
{/* 节点名称 */}
|
transition-all duration-200
|
||||||
<div className="text-sm font-medium text-foreground whitespace-nowrap">
|
hover:shadow-lg hover:border-primary/50
|
||||||
{nodeData.label || definition.nodeName}
|
`}
|
||||||
|
>
|
||||||
|
{isEllipse ? (
|
||||||
|
// 椭圆形节点:紧凑布局,图标+文字居中
|
||||||
|
<div className="flex items-center justify-center gap-3 px-2">
|
||||||
|
{renderIcon()}
|
||||||
|
<span className="text-sm font-semibold whitespace-nowrap">
|
||||||
|
{nodeData.label || definition.nodeName}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
) : (
|
||||||
|
// 普通节点:使用 Card 的标准布局
|
||||||
|
<>
|
||||||
|
<CardHeader className="pb-3">
|
||||||
|
{/* 图标 + 标题 */}
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
{renderIcon()}
|
||||||
|
<CardTitle className="text-base">
|
||||||
|
{nodeData.label || definition.nodeName}
|
||||||
|
</CardTitle>
|
||||||
|
</div>
|
||||||
|
</CardHeader>
|
||||||
|
|
||||||
{/* 输出能力简要信息 */}
|
{/* 输出部分 */}
|
||||||
{getOutputsSummary() && (
|
{renderOutputSection() && (
|
||||||
<div className="text-[10px] text-muted-foreground">
|
<CardContent className="pt-0">
|
||||||
输出:{getOutputsSummary()}
|
{renderOutputSection()}
|
||||||
</div>
|
</CardContent>
|
||||||
)}
|
)}
|
||||||
</div>
|
</>
|
||||||
|
|
||||||
{/* 输出连接点 */}
|
|
||||||
{config.handles.output && (
|
|
||||||
<Handle
|
|
||||||
type="source"
|
|
||||||
position={Position.Right}
|
|
||||||
className={handleClass}
|
|
||||||
style={getHandleStyle()}
|
|
||||||
/>
|
|
||||||
)}
|
)}
|
||||||
|
</Card>
|
||||||
|
|
||||||
{/* 配置徽章 */}
|
{/* 输出连接点 */}
|
||||||
{renderBadge()}
|
{config.handles.output && (
|
||||||
</div>
|
<Handle
|
||||||
|
type="source"
|
||||||
|
position={Position.Right}
|
||||||
|
className={handleClass}
|
||||||
|
style={getHandleStyle()}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 配置徽章 */}
|
||||||
|
{renderBadge()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -72,7 +72,7 @@ export interface NodeSize {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 节点形状
|
// 节点形状
|
||||||
export type NodeShape = 'circle' | 'rounded-rect' | 'rect' | 'diamond';
|
export type NodeShape = 'circle' | 'rounded-rect' | 'rect' | 'diamond' | 'ellipse';
|
||||||
|
|
||||||
// 图标配置
|
// 图标配置
|
||||||
export interface IconConfig {
|
export interface IconConfig {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user