npm package: @ooopenlab/quiz-form-fields
Description: Form field type definitions and components for SuperQuiz modules
Author: OOOpen Lab
Latest version: 1.0.0

# 測驗表單欄位程式庫

用於建立測驗編輯器和表單的可重複使用表單欄位元件。

## 概述

此程式庫提供一系列可重複使用的表單欄位元件，用於不同的測驗模組。所有元件都遵循一致的 API 和樣式方法。

## 元件

### TextInput
具有驗證和錯誤處理的基本文字輸入元件。

```typescript
import { TextInput } from '@ooopenlab/quiz-form-fields';

<TextInput
  label="測驗標題"
  value={title}
  onChange={setTitle}
  required={true}
  maxLength={50}
  placeholder="輸入測驗標題..."
/>
```

### Textarea
具有自動調整大小選項的多行文字輸入元件。

```typescript
import { Textarea } from '@ooopenlab/quiz-form-fields';

<Textarea
  label="描述"
  value={description}
  onChange={setDescription}
  rows={4}
  autoResize={true}
  maxLength={200}
/>
```

## 元件屬性

所有元件都擴展 `BaseFormFieldProps`：

```typescript
interface BaseFormFieldProps {
  label?: string;
  value?: any;
  onChange?: (value: any) => void;
  required?: boolean;
  disabled?: boolean;
  error?: string;
  placeholder?: string;
  className?: string;
}
```

## 計畫中的元件

- `Select` - 下拉選擇
- `NumberInput` - 具有最小/最大驗證的數值輸入
- `ColorPicker` - 具有預設值的顏色選擇
- `ImageUploader` - 具有預覽的檔案上傳
- `RichTextEditor` - 所見即所得文字編輯器

## 與模組系統的使用

表單欄位會根據模組欄位定義自動渲染：

```typescript
// 在模組定義中
private getCoverFields(): FormField[] {
  return [
    {
      type: 'text',
      label: '測驗標題',
      key: 'title',
      required: true,
      validation: {
        max: 50,
        message: '標題不能超過 50 個字元'
      }
    }
  ];
}
```

表單渲染器會根據 `type` 欄位自動使用適當的元件。

### 發現可用欄位（FieldType Registry）

主程式的 ModalEditor 透過一組既定的欄位型別字串來對應實作元件。為了讓模組與 CLI 能「知道有哪些欄位可用」，本庫提供了統一的型別與查詢 API：

```ts
import { type FieldType, listFieldTypes, isFieldTypeSupported } from '@ooopenlab/quiz-form-fields';

const allTypes: FieldType[] = listFieldTypes(); // ['color','image','tab',...]

function needs(type: string) {
  if (!isFieldTypeSupported(type)) throw new Error(`不支援的欄位型別: ${type}`);
  // OK to use
}
```

同時，`@ooopenlab/quiz-modules` 也將 `FormField.type` 鎖定為 `FieldType`，避免輸入不存在的欄位型別。

## 樣式

元件使用 CSS 類別進行樣式設定：
- `.form-field` - 容器包裝器
- `.form-label` - 標籤樣式
- `.form-input` - 輸入元素樣式
- `.form-error` - 錯誤訊息樣式

## 依賴規則與循環依賴預防

### 允許的依賴關係

1. **quiz-form-fields** (`type:ui`)：
   - ✅ 可以使用 `@ooopenlab/quiz-shared`（工具和常數）
   - 🚫 **不可依賴 quiz-modules 或其他業務邏輯程式庫**
   - 🚫 **不可依賴同層級的 UI 程式庫**

### 依賴規則

```typescript
// ✅ 正確使用方式
import { debounce, sanitizeHtml, QUIZ_CONSTANTS } from '@ooopenlab/quiz-shared';
import React, { useState } from 'react'; // 標準 React

// 🚫 避免的依賴模式
// import { SomeModule } from '@ooopenlab/quiz-modules'; // 避免依賴上層業務邏輯
// import { OtherUILib } from '@ooopenlab/other-ui-lib'; // 避免依賴同層級 UI 程式庫
```

### 架構設計原則

1. **純 UI 元件**：
   - 只負責視覺呈現和使用者互動
   - 不包含業務邏輯
   - 透過 props 接收資料和回調

2. **可重複使用**：
   - 元件設計要通用，不綁定特定業務場景
   - 透過配置參數支援不同使用情境
   - 保持 API 穩定性

3. **依賴最小化**：
   - 只依賴必要的共用工具（quiz-shared）
   - 避免引入過多外部依賴
   - 保持輕量級

### 防止循環依賴的檢查清單

- [ ] 新元件只使用 quiz-shared 中的工具
- [ ] 不在元件中寫入業務邏輯
- [ ] 不直接引用 quiz-modules 的任何內容
- [ ] 使用 `nx graph --focus=quiz-form-fields` 檢查依賴
- [ ] 確保 tags 正確設定為 `"type:ui"`
- [ ] 元件保持無狀態或最小狀態

### 與上層模組的整合

```typescript
// quiz-modules 中使用 quiz-form-fields 的正確方式
import { TextInput } from '@ooopenlab/quiz-form-fields';

export class SomeModule {
  getCoverComponent(): ModuleComponent {
    return {
      name: 'cover',
      fields: [
        {
          type: 'text',
          component: TextInput, // 引用 UI 元件
          // ... 業務邏輯配置
        }
      ]
    };
  }
}
```

## 檔案結構

```
libs/quiz-form-fields/
├── src/
│   ├── types.ts                    # 類型定義
│   ├── components/
│   │   ├── TextInput.tsx          # 文字輸入元件
│   │   └── Textarea.tsx           # 文字區域元件
│   └── index.ts                   # 公開 API 匯出
├── project.json                   # NX 專案設定
└── README.md                     # 此檔案
```