Skill 寫法圖鑑

react-flow-node-ts

Microsoft | 設計與前端 | 原文 | MIT

建立帶 TypeScript 型別與 Zustand 整合的 React Flow 自訂 node 元件

中文翻譯

---
name: react-flow-node-ts
description: 建立帶有 TypeScript 型別、handle 並整合 Zustand 的 React Flow node 元件。適用於為 React Flow 畫布建立自訂 node、製作視覺化工作流程編輯器,或實作以 node 為基礎的 UI 元件。
license: MIT
metadata:
  author: Microsoft
  version: "1.0.0"
---

# React Flow Node

依照既有模式建立 React Flow node 元件,包含正確的 TypeScript 型別和 store 整合。

## 快速開始

從 [assets/](assets/) 複製範本,並替換 placeholder:
- `{{NodeName}}` → PascalCase 元件名稱(例如 `VideoNode`)
- `{{nodeType}}` → kebab-case 型別識別字(例如 `video-node`)
- `{{NodeData}}` → Data interface 名稱(例如 `VideoNodeData`)

## 範本

- [assets/template.tsx](assets/template.tsx) - Node 元件
- [assets/types.template.ts](assets/types.template.ts) - TypeScript 型別定義

## Node 元件模式

```tsx
export const MyNode = memo(function MyNode({
  id,
  data,
  selected,
  width,
  height,
}: MyNodeProps) {
  const updateNode = useAppStore((state) => state.updateNode);
  const canvasMode = useAppStore((state) => state.canvasMode);
  
  return (
    <>
      <NodeResizer isVisible={selected && canvasMode === 'editing'} />
      <div className="node-container">
        <Handle type="target" position={Position.Top} />
        {/* Node content */}
        <Handle type="source" position={Position.Bottom} />
      </div>
    </>
  );
});
```

## 型別定義模式

```typescript
export interface MyNodeData extends Record<string, unknown> {
  title: string;
  description?: string;
}

export type MyNode = Node<MyNodeData, 'my-node'>;
```

## 整合步驟

1. 把型別加到 `src/frontend/src/types/index.ts`
2. 在 `src/frontend/src/components/nodes/` 建立元件
3. 從 `src/frontend/src/components/nodes/index.ts` export
4. 在 `src/frontend/src/store/app-store.ts` 加上預設值
5. 在畫布的 `nodeTypes` 註冊
6. 加到 AddBlockMenu 和 ConnectMenu

英文原文

---
name: react-flow-node-ts
description: Create React Flow node components with TypeScript types, handles, and Zustand integration. Use when building custom nodes for React Flow canvas, creating visual workflow editors, or implementing node-based UI components.
license: MIT
metadata:
  author: Microsoft
  version: "1.0.0"
---

# React Flow Node

Create React Flow node components following established patterns with proper TypeScript types and store integration.

## Quick Start

Copy templates from [assets/](assets/) and replace placeholders:
- `{{NodeName}}` → PascalCase component name (e.g., `VideoNode`)
- `{{nodeType}}` → kebab-case type identifier (e.g., `video-node`)
- `{{NodeData}}` → Data interface name (e.g., `VideoNodeData`)

## Templates

- [assets/template.tsx](assets/template.tsx) - Node component
- [assets/types.template.ts](assets/types.template.ts) - TypeScript definitions

## Node Component Pattern

```tsx
export const MyNode = memo(function MyNode({
  id,
  data,
  selected,
  width,
  height,
}: MyNodeProps) {
  const updateNode = useAppStore((state) => state.updateNode);
  const canvasMode = useAppStore((state) => state.canvasMode);
  
  return (
    <>
      <NodeResizer isVisible={selected && canvasMode === 'editing'} />
      <div className="node-container">
        <Handle type="target" position={Position.Top} />
        {/* Node content */}
        <Handle type="source" position={Position.Bottom} />
      </div>
    </>
  );
});
```

## Type Definition Pattern

```typescript
export interface MyNodeData extends Record<string, unknown> {
  title: string;
  description?: string;
}

export type MyNode = Node<MyNodeData, 'my-node'>;
```

## Integration Steps

1. Add type to `src/frontend/src/types/index.ts`
2. Create component in `src/frontend/src/components/nodes/`
3. Export from `src/frontend/src/components/nodes/index.ts`
4. Add defaults in `src/frontend/src/store/app-store.ts`
5. Register in canvas `nodeTypes`
6. Add to AddBlockMenu and ConnectMenu