/** * Copyright (c) 2025 Bytedance Ltd. and/or its affiliates * SPDX-License-Identifier: MIT */ import React from 'react'; import { Field, FlowNodeRegistry } from '@flowgram.ai/free-layout-editor'; import { SubCanvasRender, createContainerNodePlugin } from '@flowgram.ai/free-container-plugin'; import { provideBatchInputEffect, createBatchOutputsFormPlugin, type IFlowRefValue, DisplayOutputs, } from '@flowgram.ai/form-materials'; import { FreeFormMetaStoryBuilder, FormHeader } from '../../free-form-meta-story-builder'; const BatchVariableSelector = React.lazy(() => import('@flowgram.ai/form-materials').then((module) => ({ default: module.BatchVariableSelector, })) ); const BatchOutputs = React.lazy(() => import('@flowgram.ai/form-materials').then((module) => ({ default: module.BatchOutputs, })) ); type BatchOutputsValueType = Record; const createLoopRegistry = (): FlowNodeRegistry => ({ type: 'custom', meta: { isContainer: true, size: { width: 500, height: 260, }, padding: () => ({ top: 160, bottom: 40, left: 50, right: 50, }), }, formMeta: { render: () => ( <>
Loop input (select array variable):
name="loopFor" defaultValue={{ type: 'ref', content: ['start_0', 'arr', 'arr_obj'] }} > {({ field }) => ( field.onChange({ type: 'ref', content: val })} /> )}
Loop outputs (collected into arrays):
name="loopOutputs" defaultValue={{ names: { type: 'ref', content: ['variable_0', 'name'] }, }} > {({ field }) => ( field.onChange(val)} /> )}
Generated output variables:
), effect: { loopFor: provideBatchInputEffect, }, plugins: [ createBatchOutputsFormPlugin({ outputKey: 'loopOutputs', inferTargetKey: 'outputs' }), ], }, }); const createLoopRegistryWithInfer = (): FlowNodeRegistry => ({ type: 'custom', meta: { isContainer: true, size: { width: 500, height: 260, }, padding: () => ({ top: 160, bottom: 40, left: 50, right: 50, }), }, formMeta: { render: () => ( <>
Loop input:
name="loopFor" defaultValue={{ type: 'ref', content: ['start_0', 'arr', 'arr_obj'] }} > {({ field }) => ( field.onChange({ type: 'ref', content: val })} /> )}
Loop outputs (with schema inference):
name="loopOutputs" defaultValue={{ items: { type: 'ref', content: ['variable_0', 'item_name'] }, values: { type: 'ref', content: ['variable_0', 'item_index'] }, }} > {({ field }) => ( field.onChange(val)} /> )}
Output variables (check Debug panel for inferred schema):
), effect: { loopFor: provideBatchInputEffect, }, plugins: [ createBatchOutputsFormPlugin({ outputKey: 'loopOutputs', inferTargetKey: 'outputs' }), ], }, }); export const BasicStory = () => ( ({ ...props, nodeRegistries: [ ...(props.nodeRegistries || []).filter((r) => r.type !== 'custom'), createLoopRegistry(), ], })} plugins={(ctx) => [createContainerNodePlugin({})]} /> ); export const WithInferSchemaStory = () => ( ({ ...props, nodeRegistries: [ ...(props.nodeRegistries || []).filter((r) => r.type !== 'custom'), createLoopRegistryWithInfer(), ], })} plugins={(ctx) => [createContainerNodePlugin({})]} /> );