skill_name: material-component-dev description: FlowGram 物料组件开发指南 - 用于在 form-materials 包中创建新的物料组件 version: 1.0.0
本 SKILL 用于指导在 FlowGram 项目的 @flowgram.ai/form-materials 包中创建新的物料组件。
packages/materials/form-materials/src/components/ 下创建组件目录yarn ts-check@douyinfe/semi-uiJsonCodeEditor, CodeEditor 等来自 ../code-editorIJsonSchema 来自 @flowgram.ai/json-schema(不使用外部的 json-schema 包)import React 避免 UMD 全局引用错误确定组件的:
mkdir -p packages/materials/form-materials/src/components/{组件名}/utils
典型结构:
packages/materials/form-materials/src/components/{组件名}/
├── index.tsx # 导出文件 (named export)
├── {组件名}.tsx # 主组件
├── {辅助组件}.tsx # 可选的辅助组件
└── utils/ # 可选的工具函数
└── *.ts
// utils/helper.ts
/**
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
* SPDX-License-Identifier: MIT
*/
export function helperFunction(input: string): Output {
// 实现逻辑
}
// modal.tsx
/**
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
* SPDX-License-Identifier: MIT
*/
import React, { useState } from 'react';
import { Modal, Typography } from '@douyinfe/semi-ui';
interface ModalProps {
visible: boolean;
onClose: () => void;
onConfirm: (data: SomeType) => void;
}
export function MyModal({ visible, onClose, onConfirm }: ModalProps) {
// 实现
}
// my-component.tsx
/**
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
* SPDX-License-Identifier: MIT
*/
import React, { useState } from 'react';
import { Button } from '@douyinfe/semi-ui';
import type { IJsonSchema } from '@flowgram.ai/json-schema';
export interface MyComponentProps {
/** 核心功能的回调 */
onSomething?: (data: SomeType) => void;
}
// 使用 named export,不使用 default export
export function MyComponent({ onSomething }: MyComponentProps) {
const [visible, setVisible] = useState(false);
return (
<>
<Button onClick={() => setVisible(true)}>
操作文本
</Button>
{/* 其他组件 */}
</>
);
}
关键点:
import React// index.tsx
/**
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
* SPDX-License-Identifier: MIT
*/
export { MyComponent } from './my-component';
export type { MyComponentProps } from './my-component';
编辑 packages/materials/form-materials/src/components/index.ts:
export {
// ... 其他组件按字母序
MyComponent,
// ... 继续其他组件
type MyComponentProps,
// ... 继续其他类型
} from './components';
然后编辑 packages/materials/form-materials/src/index.ts,确保新组件在主导出列表中:
export {
// ... 其他组件按字母序
MyComponent,
// ...
type MyComponentProps,
// ...
} from './components';
在 apps/demo-materials/src/stories/components/ 创建 Story:
// my-component.stories.tsx
/**
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
* SPDX-License-Identifier: MIT
*/
import React, { useState } from 'react';
import type { Meta, StoryObj } from 'storybook-react-rsbuild';
import { MyComponent } from '@flowgram.ai/form-materials';
import type { SomeType } from '@flowgram.ai/json-schema';
const MyComponentDemo: React.FC = () => {
const [result, setResult] = useState<SomeType | null>(null);
return (
<div style={{ padding: '20px' }}>
<h2>My Component Demo</h2>
<MyComponent
onSomething={(data) => {
console.log('Generated data:', data);
setResult(data);
}}
/>
{result && (
<div style={{ marginTop: '20px' }}>
<h3>结果:</h3>
<pre style={{
background: '#f5f5f5',
padding: '16px',
borderRadius: '4px',
overflow: 'auto'
}}>
{JSON.stringify(result, null, 2)}
</pre>
</div>
)}
</div>
);
};
const meta: Meta<typeof MyComponentDemo> = {
title: 'Form Components/MyComponent',
component: MyComponentDemo,
parameters: {
layout: 'centered',
docs: {
description: {
component: '组件功能描述',
},
},
},
tags: ['autodocs'],
};
export default meta;
type Story = StoryObj<typeof meta>;
export const Default: Story = {};
cd packages/materials/form-materials
yarn ts-check
确保通过所有类型检查。
开启两个 Terminal:
Terminal 1 - 监听包编译:
rush build:watch
Terminal 2 - 启动 Storybook:
cd apps/demo-materials
yarn dev
访问 http://localhost:6006/,找到你的组件进行测试。
错误信息:
error TS2686: 'React' refers to a UMD global, but the current file is a module.
解决方案: 在文件顶部添加:
import React from 'react';
错误信息:
Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined.
解决方案: 检查以下文件的导出:
components/{组件名}/index.tsxcomponents/index.tssrc/index.ts错误信息:
Cannot find module '@flowgram.ai/json-schema' or its corresponding type declarations.
解决方案:
type IJsonSchema 而非 type JSONSchema7@flowgram.ai/json-schema 导入而非 json-schema错误信息:
Property 'height' does not exist on type 'CodeEditorPropsType'.
解决方案: 使用外层 div 设置高度:
<div style={{ minHeight: 300 }}>
<JsonCodeEditor value={value} onChange={onChange} />
</div>
packages/materials/form-materials/src/components/ 下创建yarn ts-check 类型检查完整示例请参考:
packages/materials/form-materials/src/components/json-schema-creator/apps/demo-materials/src/stories/components/json-schema-creator.stories.tsx