|
|
před 5 dny | |
|---|---|---|
| .. | ||
| src | před 1 měsícem | |
| README.md | před 1 měsícem | |
| README.zh_CN.md | před 1 měsícem | |
| eslint.config.js | před 5 dny | |
| index.html | před 10 měsíci | |
| package.json | před 5 dny | |
| rsbuild.config.ts | před 5 měsíci | |
| tsconfig.json | před 2 měsíci | |
Best practices demo for fixed layout
npx @flowgram.ai/create-app@latest fixed-layout
src/
├── app.tsx # Application entry component
├── editor.tsx # Main editor component
├── index.ts # Module export entry
├── initial-data.ts # Initial data configuration
├── type.d.ts # Global type declarations
│
├── assets/ # Static assets
│ ├── icon-mouse.tsx # Mouse icon component
│ └── icon-pad.tsx # Trackpad icon component
│
├── components/ # Common components library
│ ├── index.ts # Components export entry
│ ├── node-list.tsx # Node list component
│ │
│ ├── agent-adder/ # Agent adder component
│ │ └── index.tsx
│ ├── agent-label/ # Agent label component
│ │ └── index.tsx
│ ├── base-node/ # Base node component
│ │ ├── index.tsx
│ │ └── styles.tsx
│ ├── branch-adder/ # Branch adder component
│ │ ├── index.tsx
│ │ └── styles.tsx
│ ├── drag-node/ # Draggable node component
│ │ ├── index.tsx
│ │ └── styles.tsx
│ ├── node-adder/ # Node adder component
│ │ ├── index.tsx
│ │ ├── styles.tsx
│ │ └── utils.ts
│ ├── selector-box-popover/ # Selection box popover component
│ │ └── index.tsx
│ ├── sidebar/ # Sidebar components
│ │ ├── index.tsx
│ │ ├── sidebar-node-renderer.tsx
│ │ ├── sidebar-provider.tsx
│ │ └── sidebar-renderer.tsx
│ └── tools/ # Toolbar components
│ ├── index.tsx
│ ├── styles.tsx
│ ├── fit-view.tsx # Fit view tool
│ ├── minimap-switch.tsx # Minimap toggle
│ ├── minimap.tsx # Minimap component
│ ├── readonly.tsx # Readonly mode toggle
│ ├── run.tsx # Run tool
│ ├── save.tsx # Save tool
│ ├── switch-vertical.tsx # Vertical layout toggle
│ └── zoom-select.tsx # Zoom selector
│
├── context/ # React Context state management
│ ├── index.ts # Context export entry
│ ├── node-render-context.ts # Node render context
│ └── sidebar-context.ts # Sidebar context
│
├── form-components/ # Form components library
│ ├── index.ts # Export entry for form components
│ ├── feedback.tsx # Feedback component
│ │
│ ├── form-content/ # Form content components
│ │ ├── index.tsx
│ │ └── styles.tsx
│ ├── form-header/ # Form header components
│ │ ├── index.tsx
│ │ ├── styles.tsx
│ │ ├── title-input.tsx
│ │ └── utils.tsx
│ ├── form-inputs/ # Form input components
│ │ ├── index.tsx
│ │ └── styles.tsx
│ ├── form-item/ # Form item component
│ │ ├── index.css
│ │ └── index.tsx
│ ├── form-outputs/ # Form output components
│ │ ├── index.tsx
│ │ └── styles.tsx
│ └── properties-edit/ # Property editing components
│ ├── index.tsx
│ ├── property-edit.tsx
│ └── styles.tsx
│
├── hooks/ # Custom React hooks
│ ├── index.ts # Hooks export entry
│ ├── use-editor-props.ts # Hook for editor properties
│ ├── use-is-sidebar.ts # Hook for sidebar state
│ └── use-node-render-context.ts # Hook for node render context
│
├── nodes/ # Flow node definitions
│ ├── index.ts # Node registry
│ ├── default-form-meta.tsx # Default form metadata
│ │
│ ├── agent/ # Agent node type
│ │ ├── index.ts
│ │ ├── agent.ts
│ │ ├── agent-llm.ts
│ │ ├── agent-memory.ts
│ │ ├── agent-tools.ts
│ │ ├── memory.ts
│ │ └── tool.ts
│ ├── break-loop/ # Break loop node
│ │ ├── index.ts
│ │ └── form-meta.tsx
│ ├── case/ # Case branch node
│ │ ├── index.ts
│ │ └── form-meta.tsx
│ ├── case-default/ # Default case node
│ │ ├── index.ts
│ │ └── form-meta.tsx
│ ├── catch-block/ # Exception catch block node
│ │ ├── index.ts
│ │ └── form-meta.tsx
│ ├── end/ # End node
│ │ ├── index.ts
│ │ └── form-meta.tsx
│ ├── if/ # Conditional node
│ │ └── index.ts
│ ├── if-block/ # Conditional block node
│ │ ├── index.ts
│ │ └── form-meta.tsx
│ ├── llm/ # LLM node
│ │ └── index.ts
│ ├── loop/ # Loop node
│ │ ├── index.ts
│ │ └── form-meta.tsx
│ ├── start/ # Start node
│ │ ├── index.ts
│ │ └── form-meta.tsx
│ ├── switch/ # Switch branch node
│ │ └── index.ts
│ └── trycatch/ # Try-Catch node
│ ├── index.ts
│ └── form-meta.tsx
│
├── plugins/ # Plugin system
│ ├── index.ts # Plugins export entry
│ │
│ ├── clipboard-plugin/ # Clipboard plugin
│ │ └── create-clipboard-plugin.ts
│ ├── group-plugin/ # Group plugin
│ │ ├── index.ts
│ │ ├── group-box-header.tsx
│ │ ├── group-node.tsx
│ │ ├── group-note.tsx
│ │ ├── group-tools.tsx
│ │ ├── icons/
│ │ │ └── index.tsx
│ │ └── multilang-textarea-editor/ # Multi-language textarea editor
│ │ ├── index.css
│ │ ├── index.tsx
│ │ └── base-textarea.tsx
│ └── variable-panel-plugin/ # Variable panel plugin
│ ├── index.ts
│ ├── variable-panel-layer.tsx
│ ├── variable-panel-plugin.ts
│ └── components/
│ ├── full-variable-list.tsx
│ ├── global-variable-editor.tsx
│ └── variable-panel.tsx
│
├── services/ # Services layer
│ ├── index.ts
│ └── custom-service.ts # Custom service
│
├── shortcuts/ # Shortcuts system
│ ├── index.ts
│ ├── constants.ts # Shortcut constants
│ └── utils.ts # Shortcut utilities
│
└── typings/ # Type definitions
├── index.ts # Types export entry
├── json-schema.ts # JSON Schema types
└── node.ts # Node type definitions
This project adopts a layered architecture combined with modular design:
Presentation Layer
Business Logic Layer
Data Layer
// The main editor component uses multiple nested Providers
<FixedLayoutEditorProvider {...editorProps}>
<SidebarProvider>
<EditorRenderer />
<DemoTools />
<SidebarRenderer />
</SidebarProvider>
</FixedLayoutEditorProvider>
Use cases:
FixedLayoutEditorProvider: provides core editor features and stateSidebarProvider: manages sidebar visibility and the selected nodeexport const FlowNodeRegistries: FlowNodeRegistry[] = [
StartNodeRegistry,
EndNodeRegistry,
SwitchNodeRegistry,
LLMNodeRegistry,
// ... more node types
];
Advantages:
plugins: () => [
createMinimapPlugin({...}),
createGroupPlugin({...}),
createClipboardPlugin(),
createVariablePanelPlugin({}),
]
Plugin system highlights:
Widely used in node creation and configuration:
getNodeDefaultRegistry(type) {
return {
type,
meta: {
defaultExpanded: true,
},
};
}
Implemented via the history system:
history: {
enable: true,
enableChangeNode: true,
onApply: debounce((ctx, opt) => {
console.log('auto save: ', ctx.document.toJSON());
}, 100),
}
Reflected in the materials system:
materials: {
components: {
...defaultFixedSemiMaterials,
[FlowRendererKey.ADDER]: NodeAdder,
[FlowRendererKey.BRANCH_ADDER]: BranchAdder,
// Different render strategies can be swapped by key
}
}
The project uses multiple dedicated Contexts to manage different domains of state:
SidebarContext: manages sidebar state
export const SidebarContext = React.createContext<{
visible: boolean;
nodeId?: string;
setNodeId: (node: string | undefined) => void;
}>({ visible: false, setNodeId: () => {} });
NodeRenderContext: manages state related to node rendering
IsSidebarContext: simple boolean state
useEditorProps: centralizes all editor configuration propsuseIsSidebar: determines whether the current environment is the sidebaruseNodeRenderContext: gets the node render contextBase components
BaseNode: base rendering component for all nodesDragNode: node component in drag stateFunctional components
NodeAdder, BranchAdder, AgentAdderContainer components
Sidebar: sidebar container and its subcomponentsTools: toolbar containerThe project defines a complete initial flow dataset, including examples of multiple node types:
fromNodeJSON(node, json) {
return json; // Transform logic on data import
},
toNodeJSON(node, json) {
return json; // Transform logic on data export
}