feat: manually mirror opencoze's code from bytedance

Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
fanlv
2025-07-20 17:36:12 +08:00
commit 890153324f
14811 changed files with 1923430 additions and 0 deletions

View File

@@ -0,0 +1,19 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { useEditorProps } from './use-editor-props';
export { useBaseColor } from './use-base-color';
export { useCustomNodeRender } from './use-custom-node-render';

View File

@@ -0,0 +1,45 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {
ConstantKeys,
FlowDocumentOptions,
useService,
} from '@flowgram-adapter/fixed-layout-editor';
export const BASE_DEFAULT_COLOR = '#BBBFC4';
export const BASE_DEFAULT_ACTIVATED_COLOR = '#5147ff';
export function useBaseColor(): {
baseColor: string;
baseActivatedColor: string;
} {
const options = useService<FlowDocumentOptions>(FlowDocumentOptions);
return {
baseColor:
options.constants?.[ConstantKeys.BASE_COLOR] || BASE_DEFAULT_COLOR,
baseActivatedColor:
options.constants?.[ConstantKeys.BASE_ACTIVATED_COLOR] ||
BASE_DEFAULT_ACTIVATED_COLOR,
};
}
export const DEFAULT_LINE_ATTRS: React.SVGProps<SVGPathElement> = {
stroke: BASE_DEFAULT_COLOR,
fill: 'transparent',
strokeLinecap: 'round',
strokeLinejoin: 'round',
};

View File

@@ -0,0 +1,160 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useCallback, useContext, useMemo } from 'react';
import {
usePlayground,
type FlowNodeEntity,
FlowNodeRenderData,
PlaygroundEntityContext,
type NodeFormProps,
getNodeForm,
} from '@flowgram-adapter/fixed-layout-editor';
import { useObserve } from '@flowgram-adapter/common';
import { getStoreNode } from '../utils';
export interface NodeRenderReturnType {
/**
* 当前节点 (如果是 icon 则会返回它的父节点)
*/
node: FlowNodeEntity;
/**
* 节点是否激活
*/
activated: boolean;
/**
* 节点是否展开
*/
expanded: boolean;
/**
* 鼠标进入, 主要用于控制 activated 状态
*/
onMouseEnter: (e: React.MouseEvent) => void;
/**
* 鼠标离开, 主要用于控制 activated 状态
*/
onMouseLeave: (e: React.MouseEvent) => void;
/**
* 渲染表单,只有节点引擎开启才能使用
*/
form: NodeFormProps<any> | undefined;
/**
* 获取节点的扩展数据
*/
getExtInfo<T = any>(): T;
/**
* 更新节点的扩展数据
* @param extInfo
*/
updateExtInfo<T = any>(extInfo: T): void;
/**
* 展开/收起节点
* @param expanded
*/
toggleExpand(): void;
/**
* 全局 readonly 状态
*/
readonly: boolean;
}
/**
* 自定义 useNodeRender
* 不区分 blockIcon 和 inlineBlocks
*/
export function useCustomNodeRender(
nodeFromProps?: FlowNodeEntity,
): NodeRenderReturnType {
const ctx = useContext<FlowNodeEntity>(PlaygroundEntityContext);
const renderNode = nodeFromProps || ctx;
const renderData =
renderNode.getData<FlowNodeRenderData>(FlowNodeRenderData)!;
const { node } = getStoreNode(renderNode);
const { expanded, activated } = renderData;
const playground = usePlayground();
const onMouseEnter = useCallback(() => {
renderData.toggleMouseEnter();
}, [renderData]);
const onMouseLeave = useCallback(() => {
renderData.toggleMouseLeave();
}, [renderData]);
const toggleExpand = useCallback(() => {
renderData.toggleExpand();
}, [renderData]);
const getExtInfo = useCallback(() => node.getExtInfo() as any, [node]);
const updateExtInfo = useCallback(
(data: any) => {
node.updateExtInfo(data);
},
[node],
);
const form = useMemo(() => getNodeForm(node), [node]);
// Listen FormState change
const formState = useObserve<any>(form?.state);
const { readonly } = playground.config;
return useMemo(
() => ({
node,
activated,
readonly,
expanded,
onMouseEnter,
onMouseLeave,
getExtInfo,
updateExtInfo,
toggleExpand,
get form() {
if (!form) {
return undefined;
}
return {
...form,
get values() {
return form.values!;
},
get state() {
return formState;
},
};
},
}),
[
node,
activated,
readonly,
expanded,
onMouseEnter,
onMouseLeave,
getExtInfo,
updateExtInfo,
toggleExpand,
form,
formState,
],
);
}

View File

@@ -0,0 +1,102 @@
/*
* Copyright 2025 coze-dev Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { useMemo } from 'react';
import { createMinimapPlugin } from '@flowgram-adapter/free-layout-editor';
import {
ConstantKeys,
type FixedLayoutProps,
FlowRendererKey,
} from '@flowgram-adapter/fixed-layout-editor';
import { CustomLinesManager, TreeService } from '../services';
import { createCustomLinesPlugin } from '../plugins';
import { Split } from '../node-registries';
import { BaseNode, Collapse } from '../components';
export const useEditorProps = (data?: any, json?: any) =>
useMemo<FixedLayoutProps>(
() => ({
background: true,
readonly: false,
initialData: data as any,
onDispose() {
console.log('---- Playground Dispose ----');
},
nodeRegistries: [Split],
constants: {
[ConstantKeys.BASE_ACTIVATED_COLOR]: '#5147ff',
[ConstantKeys.INLINE_BLOCKS_PADDING_TOP]: 44,
[ConstantKeys.NODE_SPACING]: 64,
},
materials: {
renderNodes: {
[FlowRendererKey.ADDER]: () => null,
[FlowRendererKey.COLLAPSE]: Collapse,
[FlowRendererKey.BRANCH_ADDER]: () => null,
[FlowRendererKey.DRAG_NODE]: () => null,
},
renderDefaultNode: BaseNode, // 节点渲染
},
onReady(ctx) {
const treeService = ctx.get<TreeService>(TreeService);
treeService.transformSchema(json);
treeService.treeToFlowNodeJson();
// 强制 resize 生效
setTimeout(() => {
ctx.playground.resize();
}, 100);
},
onAllLayersRendered(ctx) {
const linesManager = ctx.get<CustomLinesManager>(CustomLinesManager);
linesManager.initLines();
},
plugins: () => [
/**
* 自定义线条插件
*/
createCustomLinesPlugin({}),
/**
* 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,
}),
],
}),
[],
);