1540 lines
37 KiB
Markdown
1540 lines
37 KiB
Markdown
# DramaLing UI/UX 設計規範
|
||
|
||
## 設計理念
|
||
|
||
DramaLing詞彙學習系統採用**清新、直觀、專注學習**的設計理念,致力於創造無障礙且引人入勝的學習體驗。設計強調**簡潔性、一致性和互動性**,讓用戶能夠專注於學習內容本身。
|
||
|
||
---
|
||
|
||
## 1. 視覺設計系統
|
||
|
||
### 1.1 顏色系統
|
||
|
||
#### 主要顏色調色板
|
||
```css
|
||
/* 主色調 - 藍色系統 */
|
||
--primary-default: #3B82F6; /* 主要按鈕、鏈接 */
|
||
--primary-hover: #2563EB; /* 懸停狀態 */
|
||
--primary-light: #EFF6FF; /* 淺色背景 */
|
||
|
||
/* 語義顏色 */
|
||
--success: #10B981; /* 正確答案、成功狀態 */
|
||
--warning: #F59E0B; /* 警告、提示 */
|
||
--error: #EF4444; /* 錯誤、失敗狀態 */
|
||
--info: #8B5CF6; /* 資訊提示 */
|
||
|
||
/* 中性色系 */
|
||
--gray-50: #F9FAFB; /* 最淺背景 */
|
||
--gray-100: #F3F4F6; /* 卡片背景 */
|
||
--gray-200: #E5E7EB; /* 邊框、分隔線 */
|
||
--gray-300: #D1D5DB; /* 次要邊框 */
|
||
--gray-500: #6B7280; /* 次要文字 */
|
||
--gray-600: #4B5563; /* 主要文字 */
|
||
--gray-700: #374151; /* 標題文字 */
|
||
--gray-900: #111827; /* 強調文字 */
|
||
```
|
||
|
||
#### 顏色使用規範
|
||
- **主色調藍色**: 用於主要動作按鈕、導航高亮、進度指示
|
||
- **成功綠色**: 正確答案回饋、完成狀態、積極反饋
|
||
- **錯誤紅色**: 錯誤答案回饋、警告信息、負面反饋
|
||
- **警告黃色**: 提示信息、注意事項、中性反饋
|
||
- **中性灰色**: 文字內容、背景、邊框等
|
||
|
||
### 1.2 字體系統
|
||
|
||
#### 字體家族
|
||
```css
|
||
font-family: 'Inter', 'Noto Sans TC', 'system-ui', 'sans-serif';
|
||
```
|
||
|
||
#### 字體尺寸階層
|
||
```css
|
||
/* 標題層級 */
|
||
.text-3xl { font-size: 1.875rem; } /* 主頁面標題 */
|
||
.text-2xl { font-size: 1.5rem; } /* 區塊標題 */
|
||
.text-xl { font-size: 1.25rem; } /* 子標題 */
|
||
.text-lg { font-size: 1.125rem; } /* 大號正文 */
|
||
|
||
/* 正文層級 */
|
||
.text-base { font-size: 1rem; } /* 標準正文 */
|
||
.text-sm { font-size: 0.875rem; } /* 小號文字 */
|
||
.text-xs { font-size: 0.75rem; } /* 標籤、說明文字 */
|
||
```
|
||
|
||
#### 字重規範
|
||
```css
|
||
.font-bold { font-weight: 700; } /* 標題、重點強調 */
|
||
.font-semibold { font-weight: 600; } /* 副標題、按鈕文字 */
|
||
.font-medium { font-weight: 500; } /* 導航、標籤 */
|
||
.font-normal { font-weight: 400; } /* 正文內容 */
|
||
```
|
||
|
||
### 1.3 間距系統
|
||
|
||
#### 間距單位
|
||
```css
|
||
/* 基礎間距單位:4px */
|
||
.space-y-1 { margin: 4px 0; } /* 緊密間距 */
|
||
.space-y-2 { margin: 8px 0; } /* 小間距 */
|
||
.space-y-3 { margin: 12px 0; } /* 標準間距 */
|
||
.space-y-4 { margin: 16px 0; } /* 中等間距 */
|
||
.space-y-6 { margin: 24px 0; } /* 大間距 */
|
||
.space-y-8 { margin: 32px 0; } /* 區塊間距 */
|
||
|
||
/* 內邊距 */
|
||
.p-2 { padding: 8px; } /* 小內距 */
|
||
.p-3 { padding: 12px; } /* 標準內距 */
|
||
.p-4 { padding: 16px; } /* 中等內距 */
|
||
.p-6 { padding: 24px; } /* 大內距 */
|
||
.p-8 { padding: 32px; } /* 大型容器內距 */
|
||
```
|
||
|
||
### 1.4 圓角系統
|
||
|
||
```css
|
||
.rounded-md { border-radius: 6px; } /* 小元素:按鈕、輸入框 */
|
||
.rounded-lg { border-radius: 8px; } /* 標準元素:卡片、容器 */
|
||
.rounded-xl { border-radius: 12px; } /* 大元素:主要卡片 */
|
||
.rounded-full { border-radius: 50%; } /* 圓形:頭像、標籤 */
|
||
```
|
||
|
||
---
|
||
|
||
## 2. 組件設計規範
|
||
|
||
### 2.1 按鈕設計系統
|
||
|
||
#### 主要按鈕 (Primary Button)
|
||
```tsx
|
||
<button className="
|
||
px-6 py-3
|
||
bg-primary text-white
|
||
rounded-lg
|
||
hover:bg-primary-hover
|
||
transition-colors
|
||
font-medium
|
||
disabled:opacity-50
|
||
disabled:cursor-not-allowed
|
||
">
|
||
主要動作
|
||
</button>
|
||
```
|
||
|
||
#### 次要按鈕 (Secondary Button)
|
||
```tsx
|
||
<button className="
|
||
px-6 py-3
|
||
bg-gray-200 text-gray-700
|
||
rounded-lg
|
||
hover:bg-gray-300
|
||
transition-colors
|
||
font-medium
|
||
">
|
||
次要動作
|
||
</button>
|
||
```
|
||
|
||
#### 危險按鈕 (Danger Button)
|
||
```tsx
|
||
<button className="
|
||
px-4 py-2
|
||
bg-red-600 text-white
|
||
rounded-lg
|
||
hover:bg-red-700
|
||
transition-colors
|
||
font-medium
|
||
">
|
||
刪除/危險動作
|
||
</button>
|
||
```
|
||
|
||
#### 模式切換按鈕 (Mode Toggle)
|
||
```tsx
|
||
<button className={`
|
||
px-3 py-2
|
||
rounded-md
|
||
transition-colors
|
||
${isActive
|
||
? 'bg-primary text-white'
|
||
: 'text-gray-600 hover:text-gray-900'
|
||
}
|
||
`}>
|
||
模式名稱
|
||
</button>
|
||
```
|
||
|
||
### 2.2 卡片設計系統
|
||
|
||
#### 主要內容卡片
|
||
```tsx
|
||
<div className="
|
||
bg-white
|
||
rounded-xl
|
||
shadow-lg
|
||
p-8
|
||
hover:shadow-xl
|
||
transition-shadow
|
||
">
|
||
{/* 卡片內容 */}
|
||
</div>
|
||
```
|
||
|
||
#### 資訊展示卡片
|
||
```tsx
|
||
<div className="
|
||
bg-gray-50
|
||
rounded-lg
|
||
p-4
|
||
border border-gray-200
|
||
">
|
||
{/* 資訊內容 */}
|
||
</div>
|
||
```
|
||
|
||
#### 狀態回饋卡片
|
||
```tsx
|
||
{/* 成功狀態 */}
|
||
<div className="
|
||
bg-green-50
|
||
border border-green-200
|
||
rounded-lg
|
||
p-6
|
||
">
|
||
{/* 成功內容 */}
|
||
</div>
|
||
|
||
{/* 錯誤狀態 */}
|
||
<div className="
|
||
bg-red-50
|
||
border border-red-200
|
||
rounded-lg
|
||
p-6
|
||
">
|
||
{/* 錯誤內容 */}
|
||
</div>
|
||
|
||
{/* 警告狀態 */}
|
||
<div className="
|
||
bg-yellow-50
|
||
border border-yellow-200
|
||
rounded-lg
|
||
p-6
|
||
">
|
||
{/* 警告內容 */}
|
||
</div>
|
||
```
|
||
|
||
### 2.3 輸入組件設計
|
||
|
||
#### 文字輸入框
|
||
```tsx
|
||
<input className="
|
||
w-full
|
||
px-4 py-3
|
||
border border-gray-300
|
||
rounded-lg
|
||
focus:ring-2 focus:ring-primary focus:border-transparent
|
||
outline-none
|
||
placeholder-gray-400
|
||
" />
|
||
```
|
||
|
||
#### 下拉選單
|
||
```tsx
|
||
<select className="
|
||
w-full
|
||
p-2
|
||
border border-gray-300
|
||
rounded-md
|
||
focus:ring-blue-500 focus:border-blue-500
|
||
bg-white
|
||
">
|
||
<option>選項</option>
|
||
</select>
|
||
```
|
||
|
||
#### 複選框/單選框
|
||
```tsx
|
||
<input type="checkbox" className="
|
||
w-4 h-4
|
||
text-blue-600
|
||
bg-gray-100
|
||
border-gray-300
|
||
rounded
|
||
focus:ring-blue-500
|
||
" />
|
||
```
|
||
|
||
### 2.4 標籤和徽章系統
|
||
|
||
#### 難度等級標籤
|
||
```tsx
|
||
{/* A1-A2 基礎等級 */}
|
||
<span className="
|
||
text-xs px-2 py-1
|
||
rounded-full
|
||
bg-green-100 text-green-700
|
||
">
|
||
CEFR A2
|
||
</span>
|
||
|
||
{/* B1-B2 中級等級 */}
|
||
<span className="
|
||
text-xs px-2 py-1
|
||
rounded-full
|
||
bg-yellow-100 text-yellow-700
|
||
">
|
||
CEFR B1
|
||
</span>
|
||
|
||
{/* C1-C2 高級等級 */}
|
||
<span className="
|
||
text-xs px-2 py-1
|
||
rounded-full
|
||
bg-red-100 text-red-700
|
||
">
|
||
CEFR C1
|
||
</span>
|
||
```
|
||
|
||
#### 詞性標籤
|
||
```tsx
|
||
<span className="
|
||
text-sm
|
||
bg-gray-100 text-gray-600
|
||
px-2 py-1
|
||
rounded
|
||
">
|
||
noun
|
||
</span>
|
||
```
|
||
|
||
#### 同義詞標籤
|
||
```tsx
|
||
<span className="
|
||
text-xs
|
||
bg-blue-100 text-blue-700
|
||
px-2 py-1
|
||
rounded-full
|
||
">
|
||
synonym
|
||
</span>
|
||
```
|
||
|
||
---
|
||
|
||
## 3. 交互設計模式
|
||
|
||
### 3.1 學習模式設計
|
||
|
||
#### 模式切換器設計原則
|
||
- **視覺清晰**: 當前選中模式使用主色調高亮
|
||
- **狀態一致**: 所有模式按鈕使用相同的設計語言
|
||
- **響應迅速**: 切換模式時即時更新UI狀態
|
||
- **分組合理**: 相關功能模式在視覺上聚集
|
||
|
||
```tsx
|
||
{/* 學習模式切換器 */}
|
||
<div className="bg-white rounded-lg shadow-sm p-1 inline-flex flex-wrap">
|
||
{modes.map(mode => (
|
||
<button
|
||
key={mode.id}
|
||
onClick={() => setMode(mode.id)}
|
||
className={`
|
||
px-3 py-2 rounded-md transition-colors
|
||
${currentMode === mode.id
|
||
? 'bg-primary text-white'
|
||
: 'text-gray-600 hover:text-gray-900'
|
||
}
|
||
`}
|
||
>
|
||
{mode.label}
|
||
</button>
|
||
))}
|
||
</div>
|
||
```
|
||
|
||
### 3.2 進度指示設計
|
||
|
||
#### 學習進度條
|
||
```tsx
|
||
<div className="mb-8">
|
||
{/* 進度資訊 */}
|
||
<div className="flex justify-between items-center mb-2">
|
||
<span className="text-sm text-gray-600">進度</span>
|
||
<div className="flex items-center gap-4">
|
||
<span className="text-sm text-gray-600">
|
||
{currentIndex + 1} / {total}
|
||
</span>
|
||
<div className="text-sm">
|
||
<span className="text-green-600 font-semibold">{correct}</span>
|
||
<span className="text-gray-500">/</span>
|
||
<span className="text-gray-600">{total}</span>
|
||
{total > 0 && (
|
||
<span className="text-blue-600 ml-2">
|
||
({Math.round((correct / total) * 100)}%)
|
||
</span>
|
||
)}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 進度條 */}
|
||
<div className="w-full bg-gray-200 rounded-full h-2">
|
||
<div
|
||
className="bg-primary h-2 rounded-full transition-all"
|
||
style={{ width: `${((currentIndex + 1) / total) * 100}%` }}
|
||
/>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### 3.3 狀態回饋設計
|
||
|
||
#### 答案回饋模式
|
||
```tsx
|
||
{/* 正確回饋 */}
|
||
<div className="
|
||
p-6 rounded-lg
|
||
bg-green-50 border border-green-200
|
||
">
|
||
<p className="font-semibold text-left text-xl mb-4 text-green-700">
|
||
正確!
|
||
</p>
|
||
{/* 回饋內容 */}
|
||
</div>
|
||
|
||
{/* 錯誤回饋 */}
|
||
<div className="
|
||
p-6 rounded-lg
|
||
bg-red-50 border border-red-200
|
||
">
|
||
<p className="font-semibold text-left text-xl mb-4 text-red-700">
|
||
錯誤!
|
||
</p>
|
||
<div className="mb-4">
|
||
<p className="text-gray-700 text-left">
|
||
正確答案是:<strong className="text-lg">{correctAnswer}</strong>
|
||
</p>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
#### 載入狀態設計
|
||
```tsx
|
||
{/* 按鈕載入狀態 */}
|
||
<button disabled className="
|
||
flex items-center justify-center gap-2
|
||
bg-primary text-white
|
||
px-4 py-2 rounded-lg
|
||
opacity-50 cursor-not-allowed
|
||
">
|
||
<div className="w-4 h-4 border-2 border-white border-t-transparent rounded-full animate-spin" />
|
||
<span>載入中...</span>
|
||
</button>
|
||
|
||
{/* 頁面載入狀態 */}
|
||
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 flex items-center justify-center">
|
||
<div className="text-gray-500 text-lg">載入中...</div>
|
||
</div>
|
||
```
|
||
|
||
### 3.4 互動式元素設計
|
||
|
||
#### 點擊式詞彙分析
|
||
```tsx
|
||
{/* 高價值詞彙 - 綠色邊框 + 星星 */}
|
||
<span className="
|
||
cursor-pointer transition-all duration-200 rounded relative
|
||
mx-0.5 px-1 py-0.5
|
||
bg-green-100 border-2 border-green-400
|
||
hover:bg-green-200 hover:shadow-sm
|
||
transform hover:-translate-y-0.5
|
||
">
|
||
{word}
|
||
<span className="absolute -top-1 -right-1 text-xs">⭐</span>
|
||
</span>
|
||
|
||
{/* 高價值片語 - 黃色邊框 + 星星 */}
|
||
<span className="
|
||
cursor-pointer transition-all duration-200 rounded relative
|
||
mx-0.5 px-1 py-0.5
|
||
bg-yellow-100 border-2 border-yellow-400
|
||
hover:bg-yellow-200 hover:shadow-sm
|
||
transform hover:-translate-y-0.5
|
||
">
|
||
{phrase}
|
||
<span className="absolute -top-1 -right-1 text-xs">⭐</span>
|
||
</span>
|
||
|
||
{/* 普通詞彙 - 藍色邊框 */}
|
||
<span className="
|
||
cursor-pointer transition-all duration-200 rounded
|
||
mx-0.5 px-1 py-0.5
|
||
bg-blue-100 border-2 border-blue-300
|
||
hover:bg-blue-200 hover:shadow-sm
|
||
">
|
||
{word}
|
||
</span>
|
||
```
|
||
|
||
#### 詞彙詳情彈窗
|
||
```tsx
|
||
<div className="
|
||
fixed z-20
|
||
bg-white border border-gray-300
|
||
rounded-lg shadow-lg
|
||
p-4 w-80 max-w-sm
|
||
" style={{
|
||
left: `${position.x}px`,
|
||
top: `${position.y}px`,
|
||
transform: 'translate(-50%, -100%)'
|
||
}}>
|
||
{/* 標題區 */}
|
||
<div className="flex items-center justify-between mb-3">
|
||
<h3 className="text-lg font-bold text-gray-900">{word}</h3>
|
||
<button className="text-gray-400 hover:text-gray-600">✕</button>
|
||
</div>
|
||
|
||
{/* 高價值標記 */}
|
||
{isHighValue && (
|
||
<div className="bg-green-50 border border-green-200 rounded-lg p-3 mb-3">
|
||
<div className="flex items-center gap-2">
|
||
<div className="text-green-600 text-lg">🎯</div>
|
||
<div className="text-sm font-medium text-green-800">重點學習詞彙</div>
|
||
</div>
|
||
</div>
|
||
)}
|
||
|
||
{/* 詞彙資訊 */}
|
||
<div className="space-y-3">
|
||
{/* 詞性和發音 */}
|
||
<div className="flex items-center gap-4">
|
||
<span className="text-sm bg-gray-100 px-2 py-1 rounded">
|
||
{partOfSpeech}
|
||
</span>
|
||
<span className="text-sm text-gray-600">{pronunciation}</span>
|
||
<AudioPlayer text={word} />
|
||
</div>
|
||
|
||
{/* 翻譯 */}
|
||
<div>
|
||
<div className="text-sm font-medium text-gray-700">翻譯</div>
|
||
<div className="text-base text-gray-900">{translation}</div>
|
||
</div>
|
||
|
||
{/* 定義 */}
|
||
<div>
|
||
<div className="text-sm font-medium text-gray-700">定義</div>
|
||
<div className="text-sm text-gray-600">{definition}</div>
|
||
</div>
|
||
|
||
{/* 保存按鈕 */}
|
||
<div className="pt-3 border-t border-gray-200">
|
||
<button className="
|
||
w-full
|
||
bg-blue-600 text-white
|
||
py-2 px-4
|
||
rounded-lg
|
||
text-sm font-medium
|
||
hover:bg-blue-700
|
||
transition-colors
|
||
flex items-center justify-center gap-2
|
||
">
|
||
<span>💾</span>
|
||
<span>保存到詞卡</span>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### 2.2 學習卡片設計
|
||
|
||
#### 翻卡記憶卡片
|
||
```tsx
|
||
{/* 卡片容器 */}
|
||
<div className="card-container" style={{ height: `${cardHeight}px` }}>
|
||
<div className={`card ${isFlipped ? 'flipped' : ''}`}>
|
||
{/* 正面 */}
|
||
<div className="card-front">
|
||
<div className="
|
||
bg-white rounded-xl shadow-lg
|
||
cursor-pointer hover:shadow-xl transition-shadow
|
||
p-8
|
||
">
|
||
{/* 標題區 */}
|
||
<div className="flex justify-between items-start mb-6">
|
||
<h2 className="text-2xl font-bold text-gray-900">翻卡記憶</h2>
|
||
<span className="bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full">
|
||
{difficulty}
|
||
</span>
|
||
</div>
|
||
|
||
{/* 單字展示 */}
|
||
<div className="flex-1 flex items-center justify-center mt-6">
|
||
<div className="bg-gray-50 rounded-lg p-8 w-full text-center">
|
||
<h3 className="text-4xl font-bold text-gray-900 mb-6">{word}</h3>
|
||
<div className="flex items-center justify-center gap-3">
|
||
<span className="text-lg text-gray-500">{pronunciation}</span>
|
||
<AudioPlayer text={word} />
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
{/* 背面 */}
|
||
<div className="card-back">
|
||
<div className="bg-white rounded-xl shadow-lg p-6">
|
||
<div className="space-y-4">
|
||
{/* 定義區塊 */}
|
||
<div className="bg-gray-50 rounded-lg p-4">
|
||
<h3 className="font-semibold text-gray-900 mb-2 text-left">定義</h3>
|
||
<p className="text-gray-700 text-left">{definition}</p>
|
||
</div>
|
||
|
||
{/* 例句區塊 */}
|
||
<div className="bg-gray-50 rounded-lg p-4">
|
||
<h3 className="font-semibold text-gray-900 mb-2 text-left">例句</h3>
|
||
<div className="relative">
|
||
<p className="text-gray-700 italic mb-2 text-left pr-12">"{example}"</p>
|
||
<div className="absolute bottom-0 right-0">
|
||
<AudioPlayer text={example} />
|
||
</div>
|
||
</div>
|
||
<p className="text-gray-600 text-sm text-left">"{exampleTranslation}"</p>
|
||
</div>
|
||
|
||
{/* 同義詞區塊 */}
|
||
<div className="bg-gray-50 rounded-lg p-4">
|
||
<h3 className="font-semibold text-gray-900 mb-2 text-left">同義詞</h3>
|
||
<div className="flex flex-wrap gap-2">
|
||
{synonyms.map((synonym, index) => (
|
||
<span key={index} className="
|
||
bg-white text-gray-700
|
||
px-3 py-1
|
||
rounded-full text-sm
|
||
border border-gray-200
|
||
">
|
||
{synonym}
|
||
</span>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
#### 3D翻卡動畫CSS
|
||
```css
|
||
.card-container {
|
||
perspective: 1000px;
|
||
transition: height 0.3s ease;
|
||
overflow: visible;
|
||
position: relative;
|
||
}
|
||
|
||
.card {
|
||
position: relative;
|
||
width: 100%;
|
||
height: 100%;
|
||
text-align: center;
|
||
transition: transform 0.6s ease;
|
||
transform-style: preserve-3d;
|
||
}
|
||
|
||
.card.flipped {
|
||
transform: rotateY(180deg);
|
||
}
|
||
|
||
.card-front, .card-back {
|
||
position: absolute;
|
||
width: 100%;
|
||
height: 100%;
|
||
backface-visibility: hidden;
|
||
display: flex;
|
||
align-items: stretch;
|
||
justify-content: center;
|
||
top: 0;
|
||
left: 0;
|
||
}
|
||
|
||
.card-back {
|
||
transform: rotateY(180deg);
|
||
}
|
||
```
|
||
|
||
### 3.3 測驗模式設計
|
||
|
||
#### 選擇題設計
|
||
```tsx
|
||
<div className="space-y-3 mb-6">
|
||
{options.map((option, idx) => (
|
||
<button
|
||
key={idx}
|
||
onClick={() => handleAnswer(option)}
|
||
disabled={showResult}
|
||
className={`
|
||
w-full p-4 text-left
|
||
rounded-lg border-2 transition-all
|
||
${showResult
|
||
? option === correctAnswer
|
||
? 'border-green-500 bg-green-50 text-green-700'
|
||
: option === selectedAnswer
|
||
? 'border-red-500 bg-red-50 text-red-700'
|
||
: 'border-gray-200 bg-gray-50 text-gray-500'
|
||
: 'border-gray-200 hover:border-blue-300 hover:bg-blue-50'
|
||
}
|
||
`}
|
||
>
|
||
{option}
|
||
</button>
|
||
))}
|
||
</div>
|
||
```
|
||
|
||
#### 填空題設計
|
||
```tsx
|
||
{/* 句子中的填空輸入 */}
|
||
<input
|
||
type="text"
|
||
value={answer}
|
||
onChange={(e) => setAnswer(e.target.value)}
|
||
disabled={showResult}
|
||
className={`
|
||
inline-block px-2 py-1 text-center
|
||
bg-transparent focus:outline-none
|
||
disabled:bg-gray-100
|
||
${answer
|
||
? 'border-b-2 border-blue-500'
|
||
: 'border-b-2 border-dashed border-gray-400 focus:border-blue-400 focus:border-solid'
|
||
}
|
||
`}
|
||
style={{
|
||
width: `${Math.max(100, Math.max(targetWord.length * 12, answer.length * 12 + 20))}px`
|
||
}}
|
||
/>
|
||
```
|
||
|
||
### 3.4 例句重組設計
|
||
|
||
#### 重組區域設計
|
||
```tsx
|
||
{/* 答案區域 */}
|
||
<div className="
|
||
relative min-h-[120px]
|
||
bg-gray-50 rounded-lg p-4
|
||
border-2 border-dashed border-gray-300
|
||
">
|
||
{arrangedWords.length === 0 ? (
|
||
<div className="absolute inset-0 flex items-center justify-center text-gray-400 text-lg">
|
||
答案區
|
||
</div>
|
||
) : (
|
||
<div className="flex flex-wrap gap-2">
|
||
{arrangedWords.map((word, index) => (
|
||
<div
|
||
key={index}
|
||
className="
|
||
inline-flex items-center
|
||
bg-blue-100 text-blue-800
|
||
px-3 py-2 rounded-full
|
||
text-lg font-medium
|
||
cursor-pointer hover:bg-blue-200
|
||
transition-colors
|
||
"
|
||
onClick={() => removeWord(word)}
|
||
>
|
||
{word}
|
||
<span className="ml-2 text-blue-600 hover:text-blue-800">×</span>
|
||
</div>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
|
||
{/* 可用單字區域 */}
|
||
<div className="bg-white border border-gray-200 rounded-lg p-4 min-h-[80px]">
|
||
{shuffledWords.length === 0 ? (
|
||
<div className="text-center text-gray-400">所有單字都已使用</div>
|
||
) : (
|
||
<div className="flex flex-wrap gap-2">
|
||
{shuffledWords.map((word, index) => (
|
||
<button
|
||
key={index}
|
||
onClick={() => selectWord(word)}
|
||
className="
|
||
bg-gray-100 text-gray-800
|
||
px-3 py-2 rounded-full
|
||
text-lg font-medium
|
||
cursor-pointer hover:bg-gray-200
|
||
active:bg-gray-300
|
||
transition-colors select-none
|
||
"
|
||
>
|
||
{word}
|
||
</button>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 布局設計規範
|
||
|
||
### 4.1 頁面布局模式
|
||
|
||
#### 學習頁面布局
|
||
```tsx
|
||
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100">
|
||
{/* 導航欄 */}
|
||
<Navigation showExitLearning={true} onExitLearning={handleExit} />
|
||
|
||
{/* 主要內容區 */}
|
||
<div className="max-w-4xl mx-auto px-4 py-8">
|
||
{/* 進度條 */}
|
||
<ProgressBar />
|
||
|
||
{/* 模式切換器 */}
|
||
<ModeSelector />
|
||
|
||
{/* 學習內容 */}
|
||
<LearningContent />
|
||
|
||
{/* 導航按鈕 */}
|
||
<NavigationButtons />
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
#### 內容頁面布局
|
||
```tsx
|
||
<div className="min-h-screen bg-gray-50">
|
||
<Navigation />
|
||
|
||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
|
||
{/* 頁面標題 */}
|
||
<h1 className="text-3xl font-bold mb-8">頁面標題</h1>
|
||
|
||
{/* 內容區塊 */}
|
||
<div className="max-w-4xl mx-auto space-y-6">
|
||
{/* 內容卡片 */}
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### 4.2 響應式設計
|
||
|
||
#### 斷點系統
|
||
```css
|
||
/* 小屏幕 (手機) */
|
||
sm: '640px'
|
||
|
||
/* 中等屏幕 (平板) */
|
||
md: '768px'
|
||
|
||
/* 大屏幕 (桌面) */
|
||
lg: '1024px'
|
||
|
||
/* 超大屏幕 */
|
||
xl: '1280px'
|
||
```
|
||
|
||
#### 響應式組件範例
|
||
```tsx
|
||
{/* 網格布局響應式 */}
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||
{/* 項目 */}
|
||
</div>
|
||
|
||
{/* 導航響應式 */}
|
||
<div className="hidden md:flex space-x-6">
|
||
{/* 桌面版導航 */}
|
||
</div>
|
||
<div className="md:hidden">
|
||
{/* 手機版導航 */}
|
||
</div>
|
||
|
||
{/* 文字大小響應式 */}
|
||
<h1 className="text-2xl md:text-3xl font-bold">標題</h1>
|
||
```
|
||
|
||
---
|
||
|
||
## 5. 互動設計原則
|
||
|
||
### 5.1 微互動設計
|
||
|
||
#### 懸停效果
|
||
```tsx
|
||
{/* 卡片懸停 */}
|
||
<div className="
|
||
bg-white rounded-xl shadow-lg
|
||
hover:shadow-xl
|
||
transition-shadow duration-300
|
||
">
|
||
{/* 內容 */}
|
||
</div>
|
||
|
||
{/* 按鈕懸停 */}
|
||
<button className="
|
||
bg-primary text-white
|
||
hover:bg-primary-hover
|
||
transform hover:scale-105
|
||
transition-all duration-200
|
||
">
|
||
按鈕
|
||
</button>
|
||
|
||
{/* 詞彙懸停 */}
|
||
<span className="
|
||
cursor-pointer
|
||
hover:bg-blue-200 hover:shadow-sm
|
||
transform hover:-translate-y-0.5
|
||
transition-all duration-200
|
||
">
|
||
詞彙
|
||
</span>
|
||
```
|
||
|
||
#### 動畫效果
|
||
```tsx
|
||
{/* 載入動畫 */}
|
||
<div className="animate-spin w-4 h-4 border-2 border-white border-t-transparent rounded-full" />
|
||
|
||
{/* 淡入動畫 */}
|
||
<div className="animate-fadeIn opacity-0 animate-fade-in">
|
||
{/* 內容 */}
|
||
</div>
|
||
|
||
{/* 滑入動畫 */}
|
||
<div className="transform translate-x-full animate-slide-in">
|
||
{/* 內容 */}
|
||
</div>
|
||
```
|
||
|
||
### 5.2 狀態管理原則
|
||
|
||
#### 視覺狀態指示
|
||
```tsx
|
||
{/* 禁用狀態 */}
|
||
<button className="
|
||
opacity-50 cursor-not-allowed
|
||
bg-gray-300 text-gray-500
|
||
">
|
||
禁用按鈕
|
||
</button>
|
||
|
||
{/* 選中狀態 */}
|
||
<div className="
|
||
border-2
|
||
${isSelected
|
||
? 'border-blue-500 bg-blue-50'
|
||
: 'border-gray-200'
|
||
}
|
||
">
|
||
{/* 內容 */}
|
||
</div>
|
||
|
||
{/* 錯誤狀態 */}
|
||
<div className="
|
||
border-red-400 bg-red-50
|
||
text-red-700
|
||
">
|
||
{/* 錯誤內容 */}
|
||
</div>
|
||
```
|
||
|
||
### 5.3 回饋設計模式
|
||
|
||
#### 即時回饋
|
||
```tsx
|
||
{/* 成功提示 */}
|
||
<div className="
|
||
fixed bottom-4 right-4
|
||
bg-green-600 text-white
|
||
px-4 py-3 rounded-lg shadow-lg
|
||
animate-slide-up
|
||
">
|
||
✅ 操作成功
|
||
</div>
|
||
|
||
{/* 錯誤提示 */}
|
||
<div className="
|
||
fixed bottom-4 right-4
|
||
bg-red-600 text-white
|
||
px-4 py-3 rounded-lg shadow-lg
|
||
animate-slide-up
|
||
">
|
||
❌ 操作失敗
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## 6. 特殊組件設計
|
||
|
||
### 6.1 模態對話框設計
|
||
|
||
#### 標準模態框
|
||
```tsx
|
||
{/* 遮罩層 */}
|
||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||
{/* 模態內容 */}
|
||
<div className="bg-white rounded-lg p-6 max-w-md w-full mx-4">
|
||
{/* 標題 */}
|
||
<h3 className="text-lg font-semibold mb-4">對話框標題</h3>
|
||
|
||
{/* 內容 */}
|
||
<div className="mb-4">
|
||
{/* 對話框內容 */}
|
||
</div>
|
||
|
||
{/* 按鈕區 */}
|
||
<div className="flex gap-2">
|
||
<button className="flex-1 px-4 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50">
|
||
取消
|
||
</button>
|
||
<button className="flex-1 px-4 py-2 bg-primary text-white rounded-md hover:bg-primary-hover">
|
||
確認
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
#### 圖片預覽模態框
|
||
```tsx
|
||
<div
|
||
className="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50"
|
||
onClick={closeModal}
|
||
>
|
||
<div className="relative max-w-4xl max-h-[90vh] mx-4">
|
||
<img
|
||
src={imageUrl}
|
||
alt="放大圖片"
|
||
className="max-w-full max-h-full rounded-lg"
|
||
/>
|
||
<button
|
||
onClick={closeModal}
|
||
className="
|
||
absolute top-4 right-4
|
||
bg-black bg-opacity-50 text-white
|
||
p-2 rounded-full
|
||
hover:bg-opacity-75
|
||
"
|
||
>
|
||
✕
|
||
</button>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
### 6.2 導航設計
|
||
|
||
#### 學習導航按鈕
|
||
```tsx
|
||
<div className="flex gap-4 mt-6">
|
||
{/* 上一張按鈕 */}
|
||
<button
|
||
onClick={handlePrevious}
|
||
disabled={isFirst}
|
||
className="
|
||
flex-1 py-3
|
||
bg-gray-500 text-white
|
||
rounded-lg
|
||
disabled:opacity-50 disabled:cursor-not-allowed
|
||
hover:bg-gray-600
|
||
transition-colors font-medium
|
||
"
|
||
>
|
||
上一張
|
||
</button>
|
||
|
||
{/* 下一張按鈕 */}
|
||
<button
|
||
onClick={handleNext}
|
||
className="
|
||
flex-1 py-3
|
||
bg-primary text-white
|
||
rounded-lg
|
||
hover:bg-primary-dark
|
||
transition-colors font-medium
|
||
"
|
||
>
|
||
{isLast ? '完成' : '下一張'}
|
||
</button>
|
||
</div>
|
||
```
|
||
|
||
### 6.3 錯誤報告組件
|
||
|
||
```tsx
|
||
{/* 錯誤報告按鈕 */}
|
||
<div className="flex justify-end mb-2">
|
||
<button
|
||
onClick={openReportModal}
|
||
className="px-3 py-2 rounded-md transition-colors text-gray-600 hover:text-gray-900"
|
||
>
|
||
🚩 回報錯誤
|
||
</button>
|
||
</div>
|
||
|
||
{/* 錯誤報告模態框 */}
|
||
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
||
<div className="bg-white rounded-lg p-6 max-w-md w-full mx-4">
|
||
<h3 className="text-lg font-semibold mb-4">回報錯誤</h3>
|
||
|
||
<div className="mb-4">
|
||
<p className="text-sm text-gray-600 mb-2">單字:{word}</p>
|
||
</div>
|
||
|
||
<div className="mb-4">
|
||
<label className="block text-sm font-medium text-gray-700 mb-2">
|
||
錯誤類型
|
||
</label>
|
||
<select className="
|
||
w-full p-2
|
||
border border-gray-300 rounded-md
|
||
focus:ring-blue-500 focus:border-blue-500
|
||
">
|
||
<option value="">請選擇錯誤類型</option>
|
||
<option value="translation">翻譯錯誤</option>
|
||
<option value="definition">定義錯誤</option>
|
||
<option value="pronunciation">發音錯誤</option>
|
||
<option value="example">例句錯誤</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div className="flex gap-2">
|
||
<button className="flex-1 px-4 py-2 border border-gray-300 text-gray-700 rounded-md hover:bg-gray-50">
|
||
取消
|
||
</button>
|
||
<button className="flex-1 px-4 py-2 bg-red-600 text-white rounded-md hover:bg-red-700">
|
||
送出回報
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## 7. 設計令牌 (Design Tokens)
|
||
|
||
### 7.1 間距令牌
|
||
```css
|
||
/* 基礎間距單位:4px */
|
||
--spacing-1: 4px; /* gap-1, p-1, m-1 */
|
||
--spacing-2: 8px; /* gap-2, p-2, m-2 */
|
||
--spacing-3: 12px; /* gap-3, p-3, m-3 */
|
||
--spacing-4: 16px; /* gap-4, p-4, m-4 */
|
||
--spacing-6: 24px; /* gap-6, p-6, m-6 */
|
||
--spacing-8: 32px; /* gap-8, p-8, m-8 */
|
||
|
||
/* 布局間距 */
|
||
--layout-xs: 16px; /* 小型組件間距 */
|
||
--layout-sm: 24px; /* 中型組件間距 */
|
||
--layout-md: 32px; /* 標準組件間距 */
|
||
--layout-lg: 48px; /* 大型區塊間距 */
|
||
--layout-xl: 64px; /* 頁面區塊間距 */
|
||
```
|
||
|
||
### 7.2 陰影令牌
|
||
```css
|
||
/* 陰影系統 */
|
||
--shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05); /* 輕微陰影 */
|
||
--shadow: 0 1px 3px 0 rgb(0 0 0 / 0.1); /* 標準陰影 */
|
||
--shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1); /* 中等陰影 */
|
||
--shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1); /* 大陰影(卡片) */
|
||
--shadow-xl: 0 20px 25px -5px rgb(0 0 0 / 0.1); /* 超大陰影(懸停) */
|
||
```
|
||
|
||
### 7.3 過渡動畫令牌
|
||
```css
|
||
/* 過渡時間 */
|
||
--transition-fast: 150ms; /* 快速回饋 */
|
||
--transition-normal: 300ms; /* 標準過渡 */
|
||
--transition-slow: 500ms; /* 慢速動畫 */
|
||
|
||
/* 過渡函數 */
|
||
--ease-out: cubic-bezier(0, 0, 0.2, 1);
|
||
--ease-in: cubic-bezier(0.4, 0, 1, 1);
|
||
--ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);
|
||
```
|
||
|
||
---
|
||
|
||
## 8. 組件使用指南
|
||
|
||
### 8.1 按鈕組件使用
|
||
|
||
#### 使用場景對照表
|
||
| 按鈕類型 | 使用場景 | CSS類別 |
|
||
|---------|----------|---------|
|
||
| Primary | 主要動作(保存、確認、下一步) | `bg-primary text-white hover:bg-primary-hover` |
|
||
| Secondary | 次要動作(取消、重置) | `bg-gray-200 text-gray-700 hover:bg-gray-300` |
|
||
| Danger | 危險動作(刪除、清除) | `bg-red-600 text-white hover:bg-red-700` |
|
||
| Success | 成功動作(完成、提交) | `bg-success text-white hover:bg-green-600` |
|
||
|
||
#### 按鈕尺寸規範
|
||
```tsx
|
||
{/* 大型按鈕 - 主要動作 */}
|
||
<button className="px-6 py-3 text-base">大按鈕</button>
|
||
|
||
{/* 標準按鈕 - 一般動作 */}
|
||
<button className="px-4 py-2 text-sm">標準按鈕</button>
|
||
|
||
{/* 小型按鈕 - 次要動作 */}
|
||
<button className="px-3 py-1 text-xs">小按鈕</button>
|
||
```
|
||
|
||
### 8.2 卡片組件使用
|
||
|
||
#### 主要內容卡片
|
||
- **用途**: 主要學習內容、重要信息展示
|
||
- **特點**: 大陰影、圓角、懸停效果
|
||
- **樣式**: `bg-white rounded-xl shadow-lg hover:shadow-xl`
|
||
|
||
#### 資訊展示卡片
|
||
- **用途**: 次要信息、詳細說明
|
||
- **特點**: 淺色背景、邊框、適中內距
|
||
- **樣式**: `bg-gray-50 rounded-lg p-4 border border-gray-200`
|
||
|
||
#### 狀態回饋卡片
|
||
- **用途**: 答案回饋、操作結果
|
||
- **特點**: 狀態色彩、邊框強調
|
||
- **樣式**: `bg-green-50 border border-green-200` (成功)
|
||
|
||
### 8.3 表單組件使用
|
||
|
||
#### 輸入框設計
|
||
```tsx
|
||
<input className="
|
||
w-full px-4 py-3
|
||
border border-gray-300 rounded-lg
|
||
focus:ring-2 focus:ring-primary focus:border-transparent
|
||
outline-none
|
||
placeholder-gray-400
|
||
" />
|
||
```
|
||
|
||
#### 選擇器設計
|
||
```tsx
|
||
<select className="
|
||
w-full p-2
|
||
border border-gray-300 rounded-md
|
||
focus:ring-blue-500 focus:border-blue-500
|
||
bg-white
|
||
">
|
||
<option>選項</option>
|
||
</select>
|
||
```
|
||
|
||
---
|
||
|
||
## 9. 可訪問性設計
|
||
|
||
### 9.1 語義化HTML
|
||
```tsx
|
||
{/* 使用適當的語義標籤 */}
|
||
<main role="main">
|
||
<section aria-labelledby="learning-section">
|
||
<h2 id="learning-section">學習區塊</h2>
|
||
{/* 內容 */}
|
||
</section>
|
||
</main>
|
||
|
||
{/* 按鈕語義 */}
|
||
<button
|
||
type="button"
|
||
aria-label="播放音頻"
|
||
aria-pressed={isPlaying}
|
||
>
|
||
{isPlaying ? <Pause /> : <Play />}
|
||
</button>
|
||
```
|
||
|
||
### 9.2 鍵盤導航
|
||
```tsx
|
||
{/* 支援鍵盤操作 */}
|
||
<input
|
||
onKeyDown={(e) => {
|
||
if (e.key === 'Enter') {
|
||
handleSubmit();
|
||
}
|
||
if (e.key === 'Escape') {
|
||
handleCancel();
|
||
}
|
||
}}
|
||
/>
|
||
```
|
||
|
||
### 9.3 焦點管理
|
||
```tsx
|
||
{/* 明確的焦點樣式 */}
|
||
<button className="
|
||
focus:ring-2 focus:ring-primary focus:ring-offset-2
|
||
focus:outline-none
|
||
">
|
||
按鈕
|
||
</button>
|
||
```
|
||
|
||
---
|
||
|
||
## 10. 動畫設計規範
|
||
|
||
### 10.1 頁面過渡
|
||
```css
|
||
/* 頁面淡入 */
|
||
@keyframes fadeIn {
|
||
from { opacity: 0; }
|
||
to { opacity: 1; }
|
||
}
|
||
|
||
/* 滑動進入 */
|
||
@keyframes slideIn {
|
||
from { transform: translateX(100%); }
|
||
to { transform: translateX(0); }
|
||
}
|
||
|
||
/* 放大進入 */
|
||
@keyframes scaleIn {
|
||
from { transform: scale(0.9); opacity: 0; }
|
||
to { transform: scale(1); opacity: 1; }
|
||
}
|
||
```
|
||
|
||
### 10.2 互動動畫
|
||
```css
|
||
/* 懸停上升效果 */
|
||
.hover-lift {
|
||
transition: transform 0.2s ease;
|
||
}
|
||
.hover-lift:hover {
|
||
transform: translateY(-2px);
|
||
}
|
||
|
||
/* 點擊回饋 */
|
||
.click-feedback {
|
||
transition: transform 0.1s ease;
|
||
}
|
||
.click-feedback:active {
|
||
transform: scale(0.98);
|
||
}
|
||
```
|
||
|
||
### 10.3 卡片翻轉動畫
|
||
```css
|
||
.card-flip-container {
|
||
perspective: 1000px;
|
||
}
|
||
|
||
.card-flip {
|
||
transition: transform 0.6s ease;
|
||
transform-style: preserve-3d;
|
||
}
|
||
|
||
.card-flip.flipped {
|
||
transform: rotateY(180deg);
|
||
}
|
||
|
||
.card-flip-front,
|
||
.card-flip-back {
|
||
backface-visibility: hidden;
|
||
position: absolute;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.card-flip-back {
|
||
transform: rotateY(180deg);
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 11. 設計一致性檢查清單
|
||
|
||
### 11.1 視覺一致性
|
||
- [ ] 所有按鈕使用統一的顏色和尺寸系統
|
||
- [ ] 卡片陰影和圓角保持一致
|
||
- [ ] 文字層級和間距符合設計系統
|
||
- [ ] 狀態顏色使用語義化且一致
|
||
|
||
### 11.2 交互一致性
|
||
- [ ] 相同功能的組件使用相同的交互模式
|
||
- [ ] 懸停和點擊效果在所有組件中保持一致
|
||
- [ ] 載入狀態使用統一的視覺表現
|
||
- [ ] 錯誤處理採用一致的回饋方式
|
||
|
||
### 11.3 內容一致性
|
||
- [ ] 標題層級結構合理且一致
|
||
- [ ] 說明文字使用統一的語調和格式
|
||
- [ ] 圖標使用保持一致的視覺風格
|
||
- [ ] 操作流程邏輯清晰且可預測
|
||
|
||
---
|
||
|
||
## 12. 實現指南
|
||
|
||
### 12.1 新組件開發流程
|
||
|
||
1. **設計審查**: 確認設計符合系統規範
|
||
2. **組件拆分**: 識別可重用的設計模式
|
||
3. **樣式實現**: 使用設計令牌和預定義類別
|
||
4. **互動測試**: 驗證各種狀態和過渡效果
|
||
5. **響應式測試**: 確保在不同設備上的表現
|
||
6. **可訪問性測試**: 驗證鍵盤導航和屏幕閱讀器支援
|
||
|
||
### 12.2 設計系統維護
|
||
|
||
#### 新增設計元素流程
|
||
1. **需求評估**: 確認是否需要新的設計模式
|
||
2. **一致性檢查**: 與現有系統的兼容性
|
||
3. **文檔更新**: 更新設計規範文檔
|
||
4. **團隊同步**: 與開發團隊同步新的設計規範
|
||
|
||
#### 設計令牌更新
|
||
1. **修改tailwind.config.ts**: 更新顏色、間距等令牌
|
||
2. **組件更新**: 更新受影響的組件實現
|
||
3. **測試驗證**: 確保變更不會破壞現有設計
|
||
4. **文檔同步**: 更新設計規範文檔
|
||
|
||
---
|
||
|
||
## 13. 最佳實踐
|
||
|
||
### 13.1 用戶體驗原則
|
||
|
||
#### 學習流程設計
|
||
- **循序漸進**: 從簡單到複雜的學習模式安排
|
||
- **即時回饋**: 每個操作都有明確的視覺回饋
|
||
- **進度可視**: 清晰的進度指示和成就感
|
||
- **錯誤友好**: 錯誤狀態提供建設性的指導
|
||
|
||
#### 認知負荷管理
|
||
- **視覺層次**: 使用大小、顏色、間距建立清晰的信息層次
|
||
- **內容聚焦**: 每個頁面專注於單一主要任務
|
||
- **減少選擇**: 避免過多的同時選項,使用漸進式披露
|
||
|
||
### 13.2 技術實現最佳實踐
|
||
|
||
#### CSS組織
|
||
```tsx
|
||
{/* 使用Tailwind的組合類別 */}
|
||
const buttonClass = `
|
||
px-6 py-3
|
||
bg-primary text-white
|
||
rounded-lg
|
||
hover:bg-primary-hover
|
||
transition-colors
|
||
font-medium
|
||
disabled:opacity-50
|
||
disabled:cursor-not-allowed
|
||
`;
|
||
|
||
{/* 條件式樣式 */}
|
||
const cardClass = `
|
||
border rounded-lg p-4 transition-all duration-200
|
||
${isSelected
|
||
? 'border-blue-500 bg-blue-50 shadow-sm'
|
||
: 'border-gray-200 bg-white hover:border-gray-300'
|
||
}
|
||
`;
|
||
```
|
||
|
||
#### 響應式設計模式
|
||
```tsx
|
||
{/* 移動優先的響應式設計 */}
|
||
<div className="
|
||
grid grid-cols-1 gap-4
|
||
md:grid-cols-2 md:gap-6
|
||
lg:grid-cols-3 lg:gap-8
|
||
">
|
||
{/* 內容 */}
|
||
</div>
|
||
|
||
{/* 條件式顯示 */}
|
||
<div className="hidden md:flex space-x-6">
|
||
{/* 桌面版內容 */}
|
||
</div>
|
||
<div className="md:hidden">
|
||
{/* 手機版內容 */}
|
||
</div>
|
||
```
|
||
|
||
---
|
||
|
||
## 14. 組件庫結構
|
||
|
||
### 14.1 基礎組件
|
||
```
|
||
/components
|
||
├── ui/
|
||
│ ├── Button.tsx # 基礎按鈕組件
|
||
│ ├── Card.tsx # 基礎卡片組件
|
||
│ ├── Modal.tsx # 模態對話框
|
||
│ ├── Input.tsx # 輸入組件
|
||
│ ├── Badge.tsx # 徽章標籤
|
||
│ └── Progress.tsx # 進度條
|
||
├── layout/
|
||
│ ├── Navigation.tsx # 導航組件
|
||
│ ├── PageHeader.tsx # 頁面標題
|
||
│ └── Container.tsx # 容器組件
|
||
└── learning/
|
||
├── FlipCard.tsx # 翻卡組件
|
||
├── QuizCard.tsx # 測驗卡片
|
||
├── AudioPlayer.tsx # 音頻播放器
|
||
└── VoiceRecorder.tsx # 語音錄製
|
||
```
|
||
|
||
### 14.2 設計系統文件結構
|
||
```
|
||
/design-system
|
||
├── tokens/
|
||
│ ├── colors.ts # 顏色令牌
|
||
│ ├── spacing.ts # 間距令牌
|
||
│ ├── typography.ts # 字體令牌
|
||
│ └── shadows.ts # 陰影令牌
|
||
├── components/
|
||
│ ├── Button.stories.tsx # 按鈕故事書
|
||
│ ├── Card.stories.tsx # 卡片故事書
|
||
│ └── ...
|
||
└── guidelines/
|
||
├── accessibility.md # 可訪問性指南
|
||
├── responsive.md # 響應式設計指南
|
||
└── animation.md # 動畫設計指南
|
||
```
|
||
|
||
---
|
||
|
||
## 15. 設計演進記錄
|
||
|
||
### 15.1 當前版本特色
|
||
- **清新漸層背景**: 營造舒適的學習氛圍
|
||
- **3D翻卡效果**: 增強學習的互動體驗
|
||
- **智能狀態回饋**: 即時的學習成果反饋
|
||
- **多模式學習**: 適應不同學習偏好的設計
|
||
|
||
### 15.2 設計改進方向
|
||
- **暗色主題支援**: 提供夜間學習模式
|
||
- **個人化界面**: 根據用戶偏好調整界面
|
||
- **更豐富的動畫**: 增加學習過程的趣味性
|
||
- **無障礙優化**: 進一步提升可訪問性
|
||
|
||
---
|
||
|
||
**文件版本**: 1.0
|
||
**建立日期**: 2025-09-20
|
||
**維護者**: DramaLing 設計團隊
|
||
**適用範圍**: DramaLing 詞彙學習系統全產品線 |