material-component-dev
form-materialsパッケージ内で、新しい部品(物料组件)を開発するための手順やガイドを提供し、効率的な開発を支援するSkill。
📜 元の英語説明(参考)
FlowGram 物料组件开发指南 - 用于在 form-materials 包中创建新的物料组件
🇯🇵 日本人クリエイター向け解説
form-materialsパッケージ内で、新しい部品(物料组件)を開発するための手順やガイドを提供し、効率的な開発を支援するSkill。
※ jpskill.com 編集部が日本のビジネス現場向けに補足した解説です。Skill本体の挙動とは独立した参考情報です。
下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o material-component-dev.zip https://jpskill.com/download/17661.zip && unzip -o material-component-dev.zip && rm material-component-dev.zip
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/17661.zip -OutFile "$d\material-component-dev.zip"; Expand-Archive "$d\material-component-dev.zip" -DestinationPath $d -Force; ri "$d\material-component-dev.zip"
完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。
💾 手動でダウンロードしたい(コマンドが難しい人向け)
- 1. 下の青いボタンを押して
material-component-dev.zipをダウンロード - 2. ZIPファイルをダブルクリックで解凍 →
material-component-devフォルダができる - 3. そのフォルダを
C:\Users\あなたの名前\.claude\skills\(Win)または~/.claude/skills/(Mac)へ移動 - 4. Claude Code を再起動
⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。
🎯 このSkillでできること
下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。
📦 インストール方法 (3ステップ)
- 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
- 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
- 3. 展開してできたフォルダを、ホームフォルダの
.claude/skills/に置く- · macOS / Linux:
~/.claude/skills/ - · Windows:
%USERPROFILE%\.claude\skills\
- · macOS / Linux:
Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。
詳しい使い方ガイドを見る →- 最終更新
- 2026-05-18
- 取得日時
- 2026-05-18
- 同梱ファイル
- 1
📖 Skill本文(日本語訳)
※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。
FlowGram Material Component Development
概述
本 SKILL は、FlowGram プロジェクトの @flowgram.ai/form-materials パッケージで新しい物料コンポーネントを作成する方法を指導することを目的としています。
核心原則
1. コンポーネントの場所
- ✅ 既存のパッケージで作成:
packages/materials/form-materials/src/components/の下に直接コンポーネントディレクトリを作成します。 - ❌ 個別にパッケージを分割しない: 新しい npm パッケージを作成せず、簡潔さを保ちます。
2. コード品質
- ✅ named export を使用: すべてのエクスポートで named export を使用して、tree shake のパフォーマンスを向上させます。
- ❌ 単体テストを書かない: Storybook を使用して手動でテストします。
- ✅ 型チェックを通過:
yarn ts-checkを必ず通過させます。 - ✅ コード規約に準拠: プロジェクトの ESLint ルールに従います。
3. 物料設計
- ✅ 簡潔さを保つ: 必要な props のみを保持し、非コア機能の構成項目は追加しません。
- ✅ 機能の単一性: 1 つの物料は 1 つのことのみを行います。
- ✅ 内部依存関係を使用: FlowGram 内部のコンポーネントと型を優先的に使用します。
4. 技術スタック
- UI コンポーネントライブラリ:
@douyinfe/semi-ui - コードエディタ:
JsonCodeEditor、CodeEditorなど、../code-editorから - 型定義:
IJsonSchemaは@flowgram.ai/json-schemaから(外部のjson-schemaパッケージは使用しません) - React: UMD グローバル参照エラーを避けるために、明示的に
import Reactします。
開発フロー
Step 1: コンポーネント構造の計画
コンポーネントの以下を決定します。
- 機能: コンポーネントが解決する問題
- Props インターフェース: コアで必須の props のみを保持
- 命名: PascalCase を使用し、機能を明確に記述
Step 2: ディレクトリ構造の作成
mkdir -p packages/materials/form-materials/src/components/{コンポーネント名}/utils
典型的な構造:
packages/materials/form-materials/src/components/{コンポーネント名}/
├── index.tsx # エクスポートファイル (named export)
├── {コンポーネント名}.tsx # メインコンポーネント
├── {補助コンポーネント}.tsx # オプションの補助コンポーネント
└── utils/ # オプションのユーティリティ関数
└── *.ts
Step 3: コンポーネントの実装
3.1 ユーティリティ関数(必要な場合)
// utils/helper.ts
/**
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
* SPDX-License-Identifier: MIT
*/
export function helperFunction(input: string): Output {
// 実装ロジック
}
3.2 補助コンポーネント(必要な場合)
// 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) {
// 実装
}
3.3 メインコンポーネント
// 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 - ✅ Semi UI コンポーネントの使用
- ✅ React.FC ではなく function 宣言を使用
- ✅ Props は簡潔にし、コア機能のみを保持
- ✅ Named export
3.4 エクスポートファイル
// 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';
Step 4: form-materials のメインエントリポイントでエクスポート
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';
Step 5: Storybook Story の作成
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 = {};
Step 6: 型チェックの実行
cd packages/materials/form-materials
yarn ts-check
すべての型チェックが通過することを確認します。
Step 7: 開発環境を起動してテスト
2 つの Terminal を開きます。
Terminal 1 - パッケージのコンパイルを監視:
rush build:watch
Terminal 2 - Storybook の起動:
cd apps/demo-materials
yarn dev
http://localhost:6006/ にアクセスし、コンポーネントを見つけてテストします。
常见问题
Q1: React 参照エラー
エラーメッセージ:
error TS2686: 'React' refers to a UMD global, but the current file is a module.
解決策: ファイルの先頭に以下を追加します。
import React from 'react';
Q2: コンポーネントがエクスポートされていない
エラーメッセージ:
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
Q3: 型が見つからない
エラーメッセージ:
Cannot find module '@flowgram.ai/json-schema' or its corresponding type declarations.
解決策:
type IJsonSchemaを使用し、type JSONSchema7は使用しないjson-schemaからではなく、@flowgram.ai/json-schemaからインポート
Q4: CodeEditor に height 属性がない
エラーメッセージ:
Property 'height' does not exist on type 'CodeE
(原文はここで切り捨てられています) 📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開
FlowGram Material Component Development
概述
本 SKILL 用于指导在 FlowGram 项目的 @flowgram.ai/form-materials 包中创建新的物料组件。
核心原则
1. 组件位置
- ✅ 在现有包中创建:直接在
packages/materials/form-materials/src/components/下创建组件目录 - ❌ 不要单独拆包:不创建新的 npm 包,保持简洁
2. 代码质量
- ✅ 使用 named export:所有导出使用 named export 提高 tree shake 性能
- ❌ 不写单元测试:通过 Storybook 进行手动测试
- ✅ 通过类型检查:必须通过
yarn ts-check - ✅ 符合代码规范:遵循项目 ESLint 规则
3. 物料设计
- ✅ 保持精简:只保留必要的 props,不添加非核心功能配置项
- ✅ 功能单一:一个物料只做一件事
- ✅ 使用内部依赖:优先使用 FlowGram 内部的组件和类型
4. 技术栈
- UI 组件库:
@douyinfe/semi-ui - 代码编辑器:
JsonCodeEditor,CodeEditor等来自../code-editor - 类型定义:
IJsonSchema来自@flowgram.ai/json-schema(不使用外部的json-schema包) - React:必须显式
import React避免 UMD 全局引用错误
开发流程
Step 1: 规划组件结构
确定组件的:
- 功能:组件要解决什么问题
- Props 接口:只保留核心必需的 props
- 命名:使用 PascalCase,清晰描述功能
Step 2: 创建目录结构
mkdir -p packages/materials/form-materials/src/components/{组件名}/utils
典型结构:
packages/materials/form-materials/src/components/{组件名}/
├── index.tsx # 导出文件 (named export)
├── {组件名}.tsx # 主组件
├── {辅助组件}.tsx # 可选的辅助组件
└── utils/ # 可选的工具函数
└── *.ts
Step 3: 实现组件
3.1 工具函数(如需要)
// utils/helper.ts
/**
* Copyright (c) 2025 Bytedance Ltd. and/or its affiliates
* SPDX-License-Identifier: MIT
*/
export function helperFunction(input: string): Output {
// 实现逻辑
}
3.2 辅助组件(如需要)
// 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) {
// 实现
}
3.3 主组件
// 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 - ✅ 使用 Semi UI 组件
- ✅ 使用 function 声明而非 React.FC
- ✅ Props 精简,只保留核心功能
- ✅ Named export
3.4 导出文件
// 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';
Step 4: 在 form-materials 主入口导出
编辑 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';
Step 5: 创建 Storybook Story
在 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 = {};
Step 6: 运行类型检查
cd packages/materials/form-materials
yarn ts-check
确保通过所有类型检查。
Step 7: 启动开发环境测试
开启两个 Terminal:
Terminal 1 - 监听包编译:
rush build:watch
Terminal 2 - 启动 Storybook:
cd apps/demo-materials
yarn dev
访问 http://localhost:6006/,找到你的组件进行测试。
常见问题
Q1: React 引用错误
错误信息:
error TS2686: 'React' refers to a UMD global, but the current file is a module.
解决方案: 在文件顶部添加:
import React from 'react';
Q2: 组件未导出
错误信息:
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
Q3: 类型找不到
错误信息:
Cannot find module '@flowgram.ai/json-schema' or its corresponding type declarations.
解决方案:
- 使用
type IJsonSchema而非type JSONSchema7 - 从
@flowgram.ai/json-schema导入而非json-schema
Q4: CodeEditor 没有 height 属性
错误信息:
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/下创建 - [ ] 使用 named export
- [ ] 通过
yarn ts-check类型检查 - [ ] Props 精简,只保留核心功能
- [ ] 在 Storybook 中可以正常显示和使用
- [ ] 功能正常,无明显 bug
- [ ] 代码符合 FlowGram 代码规范
最佳实践
1. 组件设计
- 单一职责:一个组件只做一件事
- Props 精简:避免过度配置
- 命名清晰:组件名和 Props 名要清晰易懂
2. 代码风格
- 使用 TypeScript:充分利用类型系统
- 显式导入:明确导入所需的依赖
- 注释适度:关键逻辑添加注释
3. UI 一致性
- 使用 Semi UI:保持 UI 风格一致
- 响应式设计:考虑不同屏幕尺寸
- 错误处理:友好的错误提示
4. 性能优化
- Named export:支持 tree shaking
- 按需加载:避免不必要的依赖
- 合理使用 memo:必要时使用 React.memo
示例参考
完整示例请参考:
packages/materials/form-materials/src/components/json-schema-creator/apps/demo-materials/src/stories/components/json-schema-creator.stories.tsx