396 lines
6.7 KiB
Markdown
396 lines
6.7 KiB
Markdown
# DramaLing 組件設計規範
|
||
|
||
## 設計原則
|
||
|
||
### 1. 一致性 (Consistency)
|
||
- 所有組件遵循統一的設計語言
|
||
- 相同功能使用相同的交互模式
|
||
- 保持視覺元素的一致性
|
||
|
||
### 2. 可訪問性 (Accessibility)
|
||
- 符合 WCAG 2.1 AA 標準
|
||
- 支援鍵盤導航
|
||
- 適當的 ARIA 標籤
|
||
|
||
### 3. 響應式 (Responsive)
|
||
- Mobile-first 設計
|
||
- 適配各種螢幕尺寸
|
||
- 觸控友好的交互
|
||
|
||
## 核心組件庫
|
||
|
||
### 基礎組件 (Base Components)
|
||
|
||
#### Button 按鈕
|
||
```typescript
|
||
// 變體 (Variants)
|
||
- default: 主要操作
|
||
- destructive: 危險操作
|
||
- outline: 次要操作
|
||
- secondary: 輔助操作
|
||
- ghost: 最小化操作
|
||
- link: 連結樣式
|
||
|
||
// 尺寸 (Sizes)
|
||
- sm: 小型 (h-9 px-3)
|
||
- default: 預設 (h-10 px-4)
|
||
- lg: 大型 (h-11 px-8)
|
||
- icon: 圖標按鈕 (h-10 w-10)
|
||
|
||
// 狀態 (States)
|
||
- hover: 懸停效果
|
||
- active: 點擊效果
|
||
- disabled: 禁用狀態
|
||
- loading: 載入中
|
||
```
|
||
|
||
#### Input 輸入框
|
||
```typescript
|
||
// 類型 (Types)
|
||
- text: 文字輸入
|
||
- email: 郵箱輸入
|
||
- password: 密碼輸入
|
||
- search: 搜尋輸入
|
||
- textarea: 多行輸入
|
||
|
||
// 狀態 (States)
|
||
- default: 預設
|
||
- focus: 聚焦
|
||
- error: 錯誤
|
||
- disabled: 禁用
|
||
```
|
||
|
||
#### Card 卡片
|
||
```typescript
|
||
// 結構
|
||
- CardHeader
|
||
- CardTitle
|
||
- CardDescription
|
||
- CardContent
|
||
- CardFooter
|
||
|
||
// 變體
|
||
- default: 預設卡片
|
||
- elevated: 陰影卡片
|
||
- outlined: 邊框卡片
|
||
```
|
||
|
||
### 業務組件 (Business Components)
|
||
|
||
#### FlashCard 詞卡組件
|
||
```typescript
|
||
interface FlashCardProps {
|
||
word: string
|
||
translation: string
|
||
example: string
|
||
difficulty: 1 | 2 | 3 | 4 | 5
|
||
isFlipped?: boolean
|
||
onFlip?: () => void
|
||
onRate?: (rating: number) => void
|
||
}
|
||
|
||
// 設計規格
|
||
- 尺寸: 350px × 200px (桌面), 100% × 250px (手機)
|
||
- 翻轉動畫: 0.6s ease-in-out
|
||
- 陰影: 0 4px 6px rgba(0, 0, 0, 0.1)
|
||
- 圓角: 12px
|
||
```
|
||
|
||
#### StudyProgress 學習進度
|
||
```typescript
|
||
interface StudyProgressProps {
|
||
totalCards: number
|
||
reviewedCards: number
|
||
newCards: number
|
||
date: Date
|
||
}
|
||
|
||
// 視覺元素
|
||
- 進度環: 圓形進度指示器
|
||
- 統計數字: 大字體顯示
|
||
- 趨勢圖標: 上升/下降箭頭
|
||
```
|
||
|
||
#### ReviewCard 複習卡片
|
||
```typescript
|
||
interface ReviewCardProps {
|
||
flashcard: FlashCard
|
||
mode: 'flip' | 'quiz' | 'type'
|
||
onAnswer: (correct: boolean) => void
|
||
}
|
||
|
||
// 交互模式
|
||
- flip: 點擊翻轉查看答案
|
||
- quiz: 選擇題模式
|
||
- type: 輸入答案模式
|
||
```
|
||
|
||
### 佈局組件 (Layout Components)
|
||
|
||
#### Navigation 導航欄
|
||
```typescript
|
||
// 桌面版
|
||
- Logo (左側)
|
||
- 主導航 (中間)
|
||
- 用戶選單 (右側)
|
||
|
||
// 手機版
|
||
- Logo (左側)
|
||
- 漢堡選單 (右側)
|
||
- 抽屜式導航
|
||
```
|
||
|
||
#### Sidebar 側邊欄
|
||
```typescript
|
||
// 內容區塊
|
||
- 用戶資訊
|
||
- 主要導航
|
||
- 次要功能
|
||
- 設定連結
|
||
|
||
// 收合狀態
|
||
- 展開: 240px 寬度
|
||
- 收合: 60px 寬度 (僅圖標)
|
||
```
|
||
|
||
#### Container 容器
|
||
```typescript
|
||
// 寬度斷點
|
||
- sm: 640px
|
||
- md: 768px
|
||
- lg: 1024px
|
||
- xl: 1280px
|
||
- 2xl: 1536px
|
||
|
||
// 內邊距
|
||
- 手機: 16px
|
||
- 平板: 24px
|
||
- 桌面: 32px
|
||
```
|
||
|
||
## 交互模式
|
||
|
||
### 載入狀態
|
||
```typescript
|
||
// Skeleton 骨架屏
|
||
- 用於內容載入
|
||
- 保持佈局穩定
|
||
- 漸進式顯示
|
||
|
||
// Spinner 旋轉載入
|
||
- 用於操作等待
|
||
- 中心顯示
|
||
- 半透明遮罩
|
||
|
||
// Progress Bar 進度條
|
||
- 用於長時間操作
|
||
- 顯示具體進度
|
||
- 可取消操作
|
||
```
|
||
|
||
### 空狀態
|
||
```typescript
|
||
// 設計元素
|
||
- 插圖或圖標
|
||
- 標題文字
|
||
- 描述文字
|
||
- 行動按鈕
|
||
|
||
// 場景
|
||
- 無數據
|
||
- 搜尋無結果
|
||
- 錯誤狀態
|
||
- 成功狀態
|
||
```
|
||
|
||
### 錯誤處理
|
||
```typescript
|
||
// Toast 通知
|
||
- 位置: 右上角
|
||
- 持續: 3-5 秒
|
||
- 可關閉
|
||
|
||
// Alert 警告
|
||
- 內嵌顯示
|
||
- 不同級別 (info, warning, error, success)
|
||
- 可包含操作
|
||
|
||
// Error Boundary
|
||
- 全頁錯誤
|
||
- 提供重試選項
|
||
- 友好的錯誤信息
|
||
```
|
||
|
||
## 動畫規範
|
||
|
||
### 時長 (Duration)
|
||
```css
|
||
--animation-fast: 150ms
|
||
--animation-base: 250ms
|
||
--animation-slow: 350ms
|
||
--animation-slower: 500ms
|
||
```
|
||
|
||
### 緩動函數 (Easing)
|
||
```css
|
||
--ease-in: cubic-bezier(0.4, 0, 1, 1)
|
||
--ease-out: cubic-bezier(0, 0, 0.2, 1)
|
||
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1)
|
||
--ease-bounce: cubic-bezier(0.68, -0.55, 0.265, 1.55)
|
||
```
|
||
|
||
### 常用動畫
|
||
```typescript
|
||
// Fade 淡入淡出
|
||
@keyframes fadeIn {
|
||
from { opacity: 0; }
|
||
to { opacity: 1; }
|
||
}
|
||
|
||
// Slide 滑動
|
||
@keyframes slideUp {
|
||
from { transform: translateY(10px); opacity: 0; }
|
||
to { transform: translateY(0); opacity: 1; }
|
||
}
|
||
|
||
// Scale 縮放
|
||
@keyframes scaleIn {
|
||
from { transform: scale(0.95); opacity: 0; }
|
||
to { transform: scale(1); opacity: 1; }
|
||
}
|
||
|
||
// Flip 翻轉
|
||
@keyframes flip {
|
||
from { transform: rotateY(0); }
|
||
to { transform: rotateY(180deg); }
|
||
}
|
||
```
|
||
|
||
## 圖標系統
|
||
|
||
### 圖標庫
|
||
使用 Lucide React 圖標庫
|
||
|
||
### 常用圖標映射
|
||
```typescript
|
||
const icons = {
|
||
// 導航
|
||
home: Home,
|
||
dashboard: LayoutDashboard,
|
||
cards: Layers,
|
||
|
||
// 操作
|
||
add: Plus,
|
||
edit: Edit,
|
||
delete: Trash2,
|
||
save: Save,
|
||
|
||
// 狀態
|
||
success: CheckCircle,
|
||
error: XCircle,
|
||
warning: AlertTriangle,
|
||
info: Info,
|
||
|
||
// 學習
|
||
study: BookOpen,
|
||
review: RefreshCw,
|
||
star: Star,
|
||
trophy: Trophy,
|
||
}
|
||
```
|
||
|
||
### 尺寸規範
|
||
```typescript
|
||
// 圖標尺寸
|
||
- xs: 12px
|
||
- sm: 16px
|
||
- md: 20px (預設)
|
||
- lg: 24px
|
||
- xl: 32px
|
||
```
|
||
|
||
## 表單設計
|
||
|
||
### 表單佈局
|
||
```typescript
|
||
// 垂直佈局 (預設)
|
||
Label
|
||
Input
|
||
Helper Text / Error Message
|
||
|
||
// 水平佈局 (適合簡短標籤)
|
||
Label | Input | Helper
|
||
```
|
||
|
||
### 驗證規則
|
||
```typescript
|
||
// 即時驗證
|
||
- onBlur: 失焦時驗證
|
||
- onChange: 輸入時驗證 (僅錯誤修正)
|
||
|
||
// 錯誤顯示
|
||
- 紅色邊框
|
||
- 錯誤圖標
|
||
- 錯誤信息文字
|
||
|
||
// 成功顯示
|
||
- 綠色勾選圖標
|
||
- 可選的成功信息
|
||
```
|
||
|
||
## 響應式斷點
|
||
|
||
### 斷點定義
|
||
```css
|
||
/* 手機 */
|
||
@media (max-width: 639px) { }
|
||
|
||
/* 平板 */
|
||
@media (min-width: 640px) and (max-width: 1023px) { }
|
||
|
||
/* 桌面 */
|
||
@media (min-width: 1024px) { }
|
||
|
||
/* 大屏 */
|
||
@media (min-width: 1280px) { }
|
||
```
|
||
|
||
### 適配策略
|
||
1. **內容優先**: 確保核心內容在所有設備上可讀
|
||
2. **觸控優化**: 手機端增加點擊區域 (最小 44×44px)
|
||
3. **佈局調整**: 網格系統自動適配
|
||
4. **功能降級**: 複雜交互在手機端簡化
|
||
|
||
## 暗色模式
|
||
|
||
### 設計考量
|
||
- 使用 CSS 變數實現主題切換
|
||
- 保持足夠的對比度
|
||
- 避免純黑背景 (使用 #0a0a0a)
|
||
- 調整陰影透明度
|
||
|
||
### 實作方式
|
||
```typescript
|
||
// 自動檢測系統主題
|
||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||
|
||
// 手動切換
|
||
const toggleTheme = () => {
|
||
document.documentElement.classList.toggle('dark')
|
||
localStorage.setItem('theme', isDark ? 'dark' : 'light')
|
||
}
|
||
```
|
||
|
||
## 性能優化
|
||
|
||
### 組件優化
|
||
- 使用 React.memo 避免不必要的重渲染
|
||
- 實施虛擬滾動對於長列表
|
||
- 延遲載入非關鍵組件
|
||
- 圖片懶加載和優化
|
||
|
||
### 樣式優化
|
||
- 使用 Tailwind JIT 模式
|
||
- 移除未使用的 CSS
|
||
- 合併相似的樣式類
|
||
- 使用 CSS-in-JS 僅在需要時 |