free-layout-workflow-editor
v1.1.6
Published
React 工作流自由布局编辑器(NPM 包)。开箱即用,内置默认节点、插件、侧边栏与工具栏,支持类型安全扩展与二次开发。
Downloads
33
Readme
free-layout-workflow-editor
React 工作流自由布局编辑器(NPM 包)。开箱即用,内置默认节点、插件、侧边栏与工具栏,支持类型安全扩展与二次开发。
安装(Installation)
# 推荐
pnpm add free-layout-workflow-editor
# 或者
npm i free-layout-workflow-editor
yarn add free-layout-workflow-editor- peerDependencies:
react >= 18,react-dom >= 18 - 样式已在组件内自动引入:
@flowgram.ai/free-layout-editor/index.css、@douyinfe/semi-ui/dist/css/semi.min.css、free-layout-workflow-editor/dist/styles/index.css,一般无需手动再引入。
快速开始(Quick Start)
import React from 'react'
import {
WorkflowEditor,
defaultNodeRegistries,
type FlowDocumentJSON
} from 'free-layout-workflow-editor'
const INITIAL_X: number = 180
const INITIAL_Y: number = 180
const data: FlowDocumentJSON = {
nodes: [
{
id: 'start_0',
type: 'start',
meta: { position: { x: INITIAL_X, y: INITIAL_Y } },
data: { title: 'Start' }
},
{
id: 'end_0',
type: 'end',
meta: { position: { x: INITIAL_X + 600, y: INITIAL_Y } },
data: { title: 'End' }
}
],
edges: [{ sourceNodeID: 'start_0', targetNodeID: 'end_0' }]
}
export default function App(): JSX.Element {
return (
<div style={{ height: 600 }}>
<WorkflowEditor initialData={data} registries={defaultNodeRegistries} />
</div>
)
}导出(Exports)
- 默认导出:
WorkflowEditor - 具名导出:
- 核心组件与类型:
WorkflowEditor(同默认导出)type WorkflowEditorPropstype WorkflowEditorRef- 编辑器实例引用类型type ToolbarSlots
- 节点注册与类型:
defaultNodeRegistries- 默认节点注册列表type FlowNodeRegistry- 节点注册类型type FlowDocumentJSON- 文档数据类型type FlowNodeJSON- 节点数据类型type FlowNodeMeta- 节点元数据类型
- 表单相关(用于自定义节点表单):
type FormRenderProps- 表单渲染Props类型type FormMeta- 表单元数据类型type FieldRenderProps- 字段渲染Props类型Field- 表单字段组件FormHeader- 表单头部组件FormContent- 表单内容容器FormInputs- 表单输入组件FormItem- 表单项组件Feedback- 反馈提示组件
- 公共组件:
BaseNode- 基础节点组件
- 上下文:
SidebarContext- 侧边栏上下文IsSidebarContext- 是否在侧边栏标志NodeRenderContext- 节点渲染上下文
- Hooks:
useNodeRenderContext- 获取节点渲染上下文useIsSidebar- 判断是否在侧边栏中
- 核心组件与类型:
主要属性(Props 概览)
interface WorkflowEditorProps {
initialData: FlowDocumentJSON
readonly?: boolean
// 节点注册与渲染扩展
registries?: FlowNodeRegistry[]
overrideDefaultRegistries?: boolean
renderNodes?: NonNullable<FreeLayoutProps['materials']>['renderNodes']
renderDefaultNode?: NonNullable<FreeLayoutProps['materials']>['renderDefaultNode']
// 工具栏插槽
showDefaultToolbar?: boolean
toolbarSlots?: ToolbarSlots
minimapDefaultVisible?: boolean
// 插件与服务扩展
extendPlugins?: (defaults: Plugin[], ctx: FreeLayoutPluginContext) => Plugin[]
bindServices?: (bind: PluginBindConfig['bind']) => void
// 事件覆盖(与默认并行调用)
onInit?: NonNullable<FreeLayoutProps['onInit']>
onAllLayersRendered?: NonNullable<FreeLayoutProps['onAllLayersRendered']>
onDispose?: NonNullable<FreeLayoutProps['onDispose']>
onContentChange?: NonNullable<FreeLayoutProps['onContentChange']>
// 其它 FreeLayoutProps 透传覆盖
editorOverrides?: Partial<FreeLayoutProps>
}获取编辑器实例(Using Ref)
通过 ref 可以获取 WorkflowEditor 的实例,从而访问编辑器的数据和上下文。
基本用法
import { useRef } from 'react'
import { WorkflowEditor, WorkflowEditorRef } from 'free-layout-workflow-editor'
function App() {
const editorRef = useRef<WorkflowEditorRef>(null)
const handleSave = () => {
// 获取当前工作流数据
const data = editorRef.current?.getData()
console.log('工作流数据:', data)
// 保存到服务器
// saveToServer(data)
}
return (
<div>
<button onClick={handleSave}>保存工作流</button>
<WorkflowEditor ref={editorRef} initialData={initialData} />
</div>
)
}WorkflowEditorRef API
getData(): FlowDocumentJSON | null- 获取当前工作流的完整数据(JSON格式)getPlayground(): Playground | null- 获取编辑器的 Playground 实例getContext(): FreeLayoutPluginContext | null- 获取编辑器的插件上下文
完整示例
import { useRef } from 'react'
import { WorkflowEditor, WorkflowEditorRef } from 'free-layout-workflow-editor'
function App() {
const editorRef = useRef<WorkflowEditorRef>(null)
// 保存工作流
const handleSave = async () => {
const data = editorRef.current?.getData()
if (!data) return
await fetch('/api/workflow/save', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(data)
})
}
// 导出工作流
const handleExport = () => {
const data = editorRef.current?.getData()
if (!data) return
const blob = new Blob([JSON.stringify(data, null, 2)], {
type: 'application/json'
})
const url = URL.createObjectURL(blob)
const a = document.createElement('a')
a.href = url
a.download = 'workflow.json'
a.click()
URL.revokeObjectURL(url)
}
// 重置缩放
const handleResetZoom = () => {
const playground = editorRef.current?.getPlayground()
if (playground) {
playground.config.zoom = 1
}
}
return (
<div>
<button onClick={handleSave}>保存</button>
<button onClick={handleExport}>导出</button>
<button onClick={handleResetZoom}>重置缩放</button>
<WorkflowEditor ref={editorRef} initialData={initialData} />
</div>
)
}查看 docs/ref-usage.md 获取更详细的使用指南。
资源与构建(Assets & Bundlers)
- 组件产物会从
dist/assets/引用图标资源(jpg/png/svg 等)。 - v1 及以上版本已在构建中复制图片资源,并在包内提供对应相对路径,常见打包器(Rspack/Webpack/Vite)可直接解析。
- 若你的项目使用原生
esbuild,请确保为静态资源配置 loader,例如:
// esbuild 示例
require('esbuild').build({
// ...其他配置
loader: {
'.png': 'file',
'.jpg': 'file',
'.jpeg': 'file',
'.svg': 'file',
'.gif': 'file',
'.webp': 'file',
'.ico': 'file'
}
})自定义节点表单
概述
点击节点时弹出的右侧侧边栏内容由节点的 formMeta.render 函数定义。你可以通过注册自定义节点来完全控制侧边栏的显示内容。
基本示例
import {
FormHeader,
FormContent,
FormInputs,
Field,
type FlowNodeRegistry,
type FormRenderProps
} from 'free-layout-workflow-editor';
import { Input, Divider } from '@douyinfe/semi-ui';
// 自定义表单渲染
const CustomFormRender = ({ form }: FormRenderProps) => (
<>
<FormHeader />
<FormContent>
{/* 自定义配置区域 */}
<Field name="customField">
{({ field }) => (
<div>
<label>自定义字段</label>
<Input
value={field.value}
onChange={field.onChange}
/>
</div>
)}
</Field>
<Divider />
{/* 复用默认的输入表单 */}
<FormInputs />
</FormContent>
</>
);
// 自定义节点注册
export const MyCustomNodeRegistry: FlowNodeRegistry = {
type: 'my-custom-node',
info: {
icon: '/icons/custom.svg',
description: '我的自定义节点'
},
onAdd() {
return {
id: `custom_${Date.now()}`,
type: 'my-custom-node',
data: {
title: '自定义节点',
customField: ''
}
};
},
formMeta: {
render: CustomFormRender
}
};
// 使用自定义节点
<WorkflowEditor
initialData={data}
registries={[
...defaultNodeRegistries,
MyCustomNodeRegistry
]}
/>可复用的组件
包导出了以下组件供你在自定义表单中使用:
FormHeader- 包含节点图标、标题编辑、菜单等FormContent- 提供统一的内容容器和滚动FormInputs- 默认的输入参数表单FormItem- 统一的表单项布局Feedback- 错误/警告提示
数据同步
使用 Field 组件修改数据时,变更会自动同步到画布:
import { Field } from '@flowgram.ai/free-layout-editor';
<Field name="title">
{({ field }) => (
<input
value={field.value}
onChange={(e) => field.onChange(e.target.value)}
/>
)}
</Field>完整文档
查看 CUSTOM_NODE_FORM.md 获取详细的自定义节点表单指南和完整示例。
参考示例
项目源码中的节点实现可作为参考:
src/nodes/http/- HTTP节点(复杂表单)src/nodes/code/- 代码节点(代码编辑器)src/nodes/variable/- 变量节点(简单表单)src/nodes/loop/- 循环节点(嵌套子画布)
