import { useMemo } from 'react'; import { createMinimapPlugin } from '@flowgram.ai/minimap-plugin'; import { createGroupPlugin } from '@flowgram.ai/group-plugin'; import { defaultFixedSemiMaterials } from '@flowgram.ai/fixed-semi-materials'; import { FixedLayoutProps, FlowDocumentJSON, FlowLayoutDefault, FlowRendererKey, ShortcutsRegistry, ConstantKeys, } from '@flowgram.ai/fixed-layout-editor'; import { type FlowNodeRegistry } from '../typings'; import { shortcutGetter } from '../shortcuts'; import { CustomService } from '../services'; import { GroupBoxHeader, GroupNode } from '../plugins/group-plugin'; import { createSyncVariablePlugin, createClipboardPlugin } from '../plugins'; import { SelectorBoxPopover } from '../components/selector-box-popover'; import NodeAdder from '../components/node-adder'; import BranchAdder from '../components/branch-adder'; import { BaseNode } from '../components/base-node'; import { DragNode } from '../components'; export function useEditorProps( initialData: FlowDocumentJSON, nodeRegistries: FlowNodeRegistry[] ): FixedLayoutProps { return useMemo( () => ({ /** * Whether to enable the background */ background: true, /** * Whether it is read-only or not, the node cannot be dragged in read-only mode */ readonly: false, /** * Initial data * 初始化数据 */ initialData, /** * Node registries * 节点注册 */ nodeRegistries, /** * Get the default node registry, which will be merged with the 'nodeRegistries' * 提供默认的节点注册,这个会和 nodeRegistries 做合并 */ getNodeDefaultRegistry(type) { return { type, meta: { /** * Default expanded * 默认展开所有节点 */ defaultExpanded: true, }, }; }, /** * 节点数据转换, 由 ctx.document.fromJSON 调用 * Node data transformation, called by ctx.document.fromJSON * @param node * @param json */ fromNodeJSON(node, json) { return json; }, /** * 节点数据转换, 由 ctx.document.toJSON 调用 * Node data transformation, called by ctx.document.toJSON * @param node * @param json */ toNodeJSON(node, json) { return json; }, /** * Set default layout */ defaultLayout: FlowLayoutDefault.VERTICAL_FIXED_LAYOUT, // or FlowLayoutDefault.HORIZONTAL_FIXED_LAYOUT /** * Style config */ constants: { // [ConstantKeys.NODE_SPACING]: 24, // [ConstantKeys.INLINE_SPACING_BOTTOM]: 24, // [ConstantKeys.INLINE_BLOCKS_INLINE_SPACING_BOTTOM]: 13, // [ConstantKeys.ROUNDED_LINE_X_RADIUS]: 8, // [ConstantKeys.ROUNDED_LINE_Y_RADIUS]: 10, // [ConstantKeys.INLINE_BLOCKS_INLINE_SPACING_TOP]: 23, // [ConstantKeys.INLINE_BLOCKS_PADDING_BOTTOM]: 30, // [ConstantKeys.COLLAPSED_SPACING]: 10, [ConstantKeys.BASE_COLOR]: '#B8BCC1', [ConstantKeys.BASE_ACTIVATED_COLOR]: '#82A7FC', }, /** * SelectBox config */ selectBox: { SelectorBoxPopover, }, // Config shortcuts shortcuts: (registry: ShortcutsRegistry, ctx) => { registry.addHandlers(...shortcutGetter.map((getter) => getter(ctx))); }, /** * Drag/Drop config */ dragdrop: { /** * Callback when drag drop */ onDrop: (ctx, dropData) => { // console.log( // '>>> onDrop: ', // dropData.dropNode.id, // dropData.dragNodes.map(n => n.id), // ); }, canDrop: (ctx, dropData) => // console.log( // '>>> canDrop: ', // dropData.isBranch, // dropData.dropNode.id, // dropData.dragNodes.map(n => n.id), // ); true, }, /** * Redo/Undo enable */ history: { enable: true, enableChangeNode: true, // Listen Node engine data change onApply(ctx, opt) { // Listen change to trigger auto save // console.log('auto save: ', ctx.document.toJSON(), opt); }, }, /** * Node engine enable, you can configure formMeta in the FlowNodeRegistry */ nodeEngine: { enable: true, }, /** * Variable engine enable */ variableEngine: { enable: true, }, /** * Materials, components can be customized based on the key * @see https://github.com/bytedance/flowgram.ai/blob/main/packages/materials/fixed-semi-materials/src/components/index.tsx * 可以通过 key 自定义 UI 组件 */ materials: { components: { ...defaultFixedSemiMaterials, [FlowRendererKey.ADDER]: NodeAdder, // Node Add Button [FlowRendererKey.BRANCH_ADDER]: BranchAdder, // Branch Add Button [FlowRendererKey.DRAG_NODE]: DragNode, // Component in node dragging }, renderDefaultNode: BaseNode, // node render renderTexts: { 'loop-end-text': 'Loop End', 'loop-traverse-text': 'Loop', 'try-start-text': 'Try Start', 'try-end-text': 'Try End', 'catch-text': 'Catch Error', }, }, /** * Bind custom service */ onBind: ({ bind }) => { bind(CustomService).toSelf().inSingletonScope(); }, /** * Playground init */ onInit: (ctx) => { /** * Data can also be dynamically loaded via fromJSON * 也可以通过 fromJSON 动态加载数据 */ // ctx.document.fromJSON(initialData) console.log('---- Playground Init ----'); }, /** * Playground render */ onAllLayersRendered: (ctx) => { setTimeout(() => { ctx.playground.config.fitView(ctx.document.root.bounds.pad(30)); }, 10); console.log(ctx.document.toString()); // Get the document tree }, /** * Playground dispose */ onDispose: () => { console.log('---- Playground Dispose ----'); }, plugins: () => [ /** * Minimap plugin * 缩略图插件 */ createMinimapPlugin({ disableLayer: true, enableDisplayAllNodes: true, canvasStyle: { canvasWidth: 182, canvasHeight: 102, canvasPadding: 50, canvasBackground: 'rgba(245, 245, 245, 1)', canvasBorderRadius: 10, viewportBackground: 'rgba(235, 235, 235, 1)', viewportBorderRadius: 4, viewportBorderColor: 'rgba(201, 201, 201, 1)', viewportBorderWidth: 1, viewportBorderDashLength: 2, nodeColor: 'rgba(255, 255, 255, 1)', nodeBorderRadius: 2, nodeBorderWidth: 0.145, nodeBorderColor: 'rgba(6, 7, 9, 0.10)', overlayColor: 'rgba(255, 255, 255, 0)', }, inactiveDebounceTime: 1, }), /** * Group plugin * 分组插件 */ createGroupPlugin({ components: { GroupBoxHeader, GroupNode, }, }), /** * Variable plugin * 变量插件 */ createSyncVariablePlugin({}), /** * Clipboard plugin * 剪切板插件 */ createClipboardPlugin(), ], }), [] ); }